Browse code

Adding partitioning support in kickstart configuation

* Ability to specicy partitions layout in the ks configuration file.
* Example of the configration:
"partitions": [
{"mountpoint": "/", "size": 0, "filesystem": "ext4"},
{"mountpoint": "/boot", "size": 128, "filesystem": "ext4"},
{"mountpoint": "/root", "size": 128, "filesystem": "ext4"},
{"size": 128, "filesystem": "swap"}
]
* Constrains:
1. You should have one and only one root mount point.
2. No mount point under /boot directory

Change-Id: If3bb9ca0d2862f497868160878cf0ffc2a61403d
Reviewed-on: http://photon-jenkins.eng.vmware.com/135
Reviewed-by: Sharath George
Tested-by: jenkins-photon <wangnan2015@hotmail.com>

mbassiouny authored on 2015/11/16 01:26:08
Showing 12 changed files
... ...
@@ -1,7 +1,7 @@
1 1
 Summary:	Default file system
2 2
 Name:		filesystem
3 3
 Version:	7.5
4
-Release:	10%{?dist}
4
+Release:	11%{?dist}
5 5
 License:	GPLv3
6 6
 Group:		System Environment/Base
7 7
 Vendor:		VMware, Inc.
... ...
@@ -294,16 +294,8 @@ EOF
294 294
 #
295 295
 #	8.2. Creating the /etc/fstab File
296 296
 #
297
-cat > %{buildroot}/etc/fstab <<- "EOF"
298
-#	Begin /etc/fstab
299
-#	hdparm -I /dev/sda | grep NCQ --> can use barrier
300
-#system		mnt-pt		type		options			dump fsck
301
-/dev/sda1	/		    ext4	    defaults,barrier,noatime,noacl,data=ordered 1 1
302
-/dev/cdrom      /mnt/cdrom      iso9660     ro,noauto              0   0
303
-# /dev/sda2	swap		swap		pri=1			0 0
304
-#	mount points
305
-#	End /etc/fstab
306
-EOF
297
+touch %{buildroot}/etc/fstab
298
+
307 299
 #
308 300
 #	8.3.2. Configuring Linux Module Load Order
309 301
 #
... ...
@@ -469,6 +461,8 @@ ln -sv ../usr/lib/os-release %{buildroot}/etc/os-release
469 469
 /usr/local/lib64
470 470
 %endif
471 471
 %changelog
472
+*   Mon Nov 16 2015 Mahmoud Bassiouny <mbassiouny@vmware.com> 7.5-11
473
+-   Removing /etc/fstab mount entries.
472 474
 *   Mon Nov 16 2015 Sharath George <sharathg@vmware.com> 7.5-10
473 475
 -   Removint /opt from filesystem.
474 476
 *   Fri Oct 02 2015 Vinay Kulkarni <kulkarniv@vmware.com> 7.5-9
... ...
@@ -2,7 +2,7 @@
2 2
 Summary:       Kernel
3 3
 Name:          linux-esx
4 4
 Version:       4.2.0
5
-Release:       7%{?dist}
5
+Release:       8%{?dist}
6 6
 License:       GPLv2
7 7
 URL:           http://www.kernel.org/
8 8
 Group:         System Environment/Kernel
... ...
@@ -78,7 +78,7 @@ cp -r Documentation/*        %{buildroot}%{_defaultdocdir}/linux-esx-%{version}
78 78
 cat > %{buildroot}/boot/%{name}-%{version}-%{release}.cfg << "EOF"
79 79
 # GRUB Environment Block
80 80
 photon_cmdline=init=/lib/systemd/systemd rcupdate.rcu_expedited=1 rootfstype=ext4 rw systemd.show_status=0 quiet nordrand noreplace-smp cpu_init_udelay=0 plymouth.enable=0
81
-photon_linux=/boot/vmlinuz-esx-%{version}
81
+photon_linux=vmlinuz-esx-%{version}
82 82
 EOF
83 83
 
84 84
 # cleanup dangling symlinks
... ...
@@ -120,6 +120,8 @@ ln -sf %{name}-%{version}-%{release}.cfg /boot/photon.cfg
120 120
 /usr/src/%{name}-headers-%{version}-%{release}
121 121
 
122 122
 %changelog
123
+*   Fri Nov 13 2015 Mahmoud Bassiouny <mbassiouny@vmware.com> 4.2.0-8
124
+-   Change the linux image directory.
123 125
 *   Tue Nov 10 2015 Alexey Makhalov <amakhalov@vmware.com> 4.2.0-7
124 126
 -   Get LAPIC timer frequency from HV, skip boot time calibration.
125 127
 -   .config: + dummy net driver (M).
... ...
@@ -2,7 +2,7 @@
2 2
 Summary:        Kernel
3 3
 Name:        linux
4 4
 Version:    4.2.0
5
-Release:    3%{?dist}
5
+Release:    4%{?dist}
6 6
 License:    GPLv2
7 7
 URL:        http://www.kernel.org/
8 8
 Group:        System Environment/Kernel
... ...
@@ -82,8 +82,8 @@ cp -r Documentation/*        %{buildroot}%{_defaultdocdir}/%{name}-%{version}
82 82
 cat > %{buildroot}/boot/%{name}-%{version}-%{release}.cfg << "EOF"
83 83
 # GRUB Environment Block
84 84
 photon_cmdline=init=/lib/systemd/systemd rootfstype=ext4 ro loglevel=3 quiet plymouth.enable=0
85
-photon_linux=/boot/vmlinuz-%{version}
86
-photon_initrd=/boot/initrd.img-no-kmods
85
+photon_linux=vmlinuz-%{version}
86
+photon_initrd=initrd.img-no-kmods
87 87
 EOF
88 88
 
89 89
 #    Cleanup dangling symlinks
... ...
@@ -139,6 +139,8 @@ ln -sf %{name}-%{version}-%{release}.cfg /boot/photon.cfg
139 139
 /lib/modules/%{version}/kernel/sound
140 140
 
141 141
 %changelog
142
+*   Fri Nov 13 2015 Mahmoud Bassiouny <mbassiouny@vmware.com> 4.2.0-4
143
+-   Change the linux image directory.
142 144
 *	Wed Nov 11 2015 Harish Udaiya Kumar <hudaiyakumar@vmware.com> 4.2.0-3
143 145
 - 	Added the build essential files in the dev sub-package.
144 146
 *	Mon Nov 09 2015 Vinay Kulkarni <kulkarniv@vmware.com> 4.2.0-2
... ...
@@ -126,16 +126,21 @@ class Installer(object):
126 126
             # install grub
127 127
             try:
128 128
                 if self.install_config['boot'] == 'bios':
129
-                    process = subprocess.Popen([self.setup_grub_command, '-w', self.photon_root, "bios", self.install_config['disk']['disk'], self.install_config['disk']['root']], stdout=self.output)
129
+                    process = subprocess.Popen([self.setup_grub_command, '-w', self.photon_root, "bios", self.install_config['disk']['disk'], self.install_config['disk']['root'], self.install_config['disk']['boot'], self.install_config['disk']['bootdirectory']], stdout=self.output)
130 130
                 elif self.install_config['boot'] == 'efi':
131
-                    process = subprocess.Popen([self.setup_grub_command, '-w', self.photon_root, "efi", self.install_config['disk']['disk'], self.install_config['disk']['root']], stdout=self.output)
131
+                    process = subprocess.Popen([self.setup_grub_command, '-w', self.photon_root, "efi", self.install_config['disk']['disk'], self.install_config['disk']['root'], self.install_config['disk']['boot'], self.install_config['disk']['bootdirectory']], stdout=self.output)
132 132
             except:
133 133
                 #install bios if variable is not set.
134
-                process = subprocess.Popen([self.setup_grub_command, '-w', self.photon_root, "bios", self.install_config['disk']['disk'], self.install_config['disk']['root']], stdout=self.output)
134
+                process = subprocess.Popen([self.setup_grub_command, '-w', self.photon_root, "bios", self.install_config['disk']['disk'], self.install_config['disk']['root'], self.install_config['disk']['boot'], self.install_config['disk']['bootdirectory']], stdout=self.output)
135 135
 
136 136
             retval = process.wait()
137 137
 
138
-        process = subprocess.Popen([self.unmount_disk_command, '-w', self.photon_root], stdout=self.output)
138
+            self.update_fstab()
139
+
140
+        command = [self.unmount_disk_command, '-w', self.photon_root]
141
+        if not self.install_config['iso_system']:
142
+            command.extend(self.generate_partitions_param(reverse = True))
143
+        process = subprocess.Popen(command, stdout=self.output)
139 144
         retval = process.wait()
140 145
 
141 146
         if self.iso_installer:
... ...
@@ -264,10 +269,56 @@ class Installer(object):
264 264
         else:
265 265
             self.copy_rpms()
266 266
 
267
+    def update_fstab(self):
268
+        fstab_file = open(os.path.join(self.photon_root, "etc/fstab"), "w")
269
+        fstab_file.write("#system\tmnt-pt\ttype\toptions\tdump\tfsck\n")
270
+
271
+        for partition in self.install_config['disk']['partitions']:
272
+            options = 'defaults'
273
+            dump = 1
274
+            fsck = 2
275
+
276
+            if 'mountpoint' in partition and partition['mountpoint'] == '/':
277
+                options = options + ',barrier,noatime,noacl,data=ordered'
278
+                fsck = 1
279
+            
280
+            if partition['filesystem'] == 'swap':
281
+                mountpoint = 'swap'
282
+                dump = 0
283
+                fsck = 0
284
+            else:
285
+                mountpoint = partition['mountpoint']
286
+
287
+            fstab_file.write("{}\t{}\t{}\t{}\t{}\t{}\n".format(
288
+                partition['path'],
289
+                mountpoint,
290
+                partition['filesystem'],
291
+                options,
292
+                dump,
293
+                fsck
294
+                ))
295
+
296
+        fstab_file.close()
297
+
298
+    def generate_partitions_param(self, reverse = False):
299
+        if reverse:
300
+            step = -1
301
+        else:
302
+            step = 1
303
+        params = []
304
+        for partition in self.install_config['disk']['partitions'][::step]:
305
+            if partition["filesystem"] == "swap":
306
+                continue
307
+
308
+            params.extend(['--partitionmountpoint', partition["path"], partition["mountpoint"]])
309
+        return params
310
+
267 311
     def initialize_system(self):
268 312
         #Setup the disk
269 313
         if (not self.install_config['iso_system']):
270
-            process = subprocess.Popen([self.mount_command, '-w', self.photon_root, self.install_config['disk']['root']], stdout=self.output)
314
+            command = [self.mount_command, '-w', self.photon_root]
315
+            command.extend(self.generate_partitions_param())
316
+            process = subprocess.Popen(command, stdout=self.output)
271 317
             retval = process.wait()
272 318
         
273 319
         self.copy_files()
... ...
@@ -21,11 +21,24 @@ LOGFILE=/var/log/"${PRGNAME}-${LOGFILE}"	#	set log file name
21 21
 [ ${EUID} -eq 0 ]	|| fail "${PRGNAME}: Need to be root user: FAILURE"
22 22
 > ${LOGFILE}		#	clear/initialize logfile
23 23
 
24
-# Check if passing a partition
25
-if [ $# -eq 1 ] 
26
-	then
27
-		PARTITION=$1
28
-fi
24
+while [[ $# > 0 ]]
25
+do
26
+    key="$1"
27
+    shift
28
+ 
29
+    case $key in
30
+        -p|--partitionmountpoint)
31
+        PARTITION="$1"
32
+        MOUNTPOINT="$2"
33
+        shift 2
29 34
 
30
-run_command "Mounting HD" "mount -v -t ext4 ${PARTITION} ${BUILDROOT}" "${LOGFILE}"
35
+        # make sure the directory exists
36
+        run_command "Making Directory" "mkdir -p ${BUILDROOT}${MOUNTPOINT}" "${LOGFILE}"
37
+        run_command "Mounting Partition" "mount -v ${PARTITION} ${BUILDROOT}${MOUNTPOINT}" "${LOGFILE}"
38
+    ;;
39
+    *)
40
+        # unknown option
41
+    ;;
42
+    esac
43
+done
31 44
 
... ...
@@ -6,11 +6,11 @@
6 6
 #      Author:  sharathg@vmware.com             #
7 7
 #     Options:                                  #
8 8
 #################################################
9
-#	Overview
10
-#		This is a precursor for the vmware build system.
11
-#		This assumes that an empty hard disk is attached to the build VM.
12
-#		The path to this empty disk is specified in the HDD variable in config.inc
13
-#	End
9
+#    Overview
10
+#        This is a precursor for the vmware build system.
11
+#        This assumes that an empty hard disk is attached to the build VM.
12
+#        The path to this empty disk is specified in the HDD variable in config.inc
13
+#    End
14 14
 #
15 15
 
16 16
 grub_efi_install()
... ...
@@ -39,30 +39,32 @@ grub_mbr_install()
39 39
     $grubInstallCmd --force --boot-directory=$BUILDROOT/boot "$HDD"
40 40
 }
41 41
 
42
-set -o errexit		# exit if error...insurance ;)
43
-set -o nounset		# exit if variable not initalized
44
-set +h			# disable hashall
45
-PRGNAME=${0##*/}	# script name minus the path
46
-source config.inc		#	configuration parameters
47
-source function.inc		#	commonn functions
48
-LOGFILE=/var/log/"${PRGNAME}-${LOGFILE}"	#	set log file name
49
-#LOGFILE=/dev/null		#	uncomment to disable log file
50
-ARCH=$(uname -m)	# host architecture
51
-[ ${EUID} -eq 0 ]	|| fail "${PRGNAME}: Need to be root user: FAILURE"
52
-> ${LOGFILE}		#	clear/initialize logfile
42
+set -o errexit        # exit if error...insurance ;)
43
+set -o nounset        # exit if variable not initalized
44
+set +h            # disable hashall
45
+PRGNAME=${0##*/}    # script name minus the path
46
+source config.inc        #    configuration parameters
47
+source function.inc        #    commonn functions
48
+LOGFILE=/var/log/"${PRGNAME}-${LOGFILE}"    #    set log file name
49
+ARCH=$(uname -m)    # host architecture
50
+[ ${EUID} -eq 0 ]    || fail "${PRGNAME}: Need to be root user: FAILURE"
51
+> ${LOGFILE}        #    clear/initialize logfile
53 52
 
54 53
 # Check if passing a HHD and partition
55
-if [ $# -eq 3 ] 
56
-	then
54
+if [ $# -eq 5 ] 
55
+    then
57 56
         BOOTMODE=$1
58
-	HDD=$2
59
-	PARTITION=$3
57
+    HDD=$2
58
+    ROOT_PARTITION_PATH=$3
59
+    BOOT_PARTITION_PATH=$4
60
+    BOOT_DIRECTORY=$5
60 61
 fi
61 62
 
62 63
 #
63
-#	Install grub2.
64
+#    Install grub2.
64 65
 #
65
-UUID=$(blkid -s UUID -o value $PARTITION)
66
+UUID=$(blkid -s UUID -o value $ROOT_PARTITION_PATH)
67
+BOOT_UUID=$(blkid -s UUID -o value $BOOT_PARTITION_PATH)
66 68
 
67 69
 grubInstallCmd=""
68 70
 mkdir -p $BUILDROOT/boot/grub2
... ...
@@ -91,10 +93,11 @@ cat > $BUILDROOT/boot/grub2/grub.cfg << EOF
91 91
 
92 92
 function set_rootpartition {
93 93
     if [ "\$photon_initrd" ]; then
94
-        set rootpartition=UUID=\$photon_uuid
94
+        set rootpartition=UUID=$UUID
95 95
     else
96
-        regexp -s dev '.{2}(.)' \$root
97
-        regexp -s part '.*(.)' \$root
96
+        search -n -u $UUID -s rootpartition_device
97
+        regexp -s dev '.{2}(.)' \$rootpartition_device
98
+        regexp -s part '.*(.)' \$rootpartition_device
98 99
         regexp -s char '.{'\$dev'}(.)' abcdefghij
99 100
         set rootpartition=/dev/sd\$char\$part
100 101
     fi
... ...
@@ -102,9 +105,8 @@ function set_rootpartition {
102 102
 
103 103
 set default=0
104 104
 set timeout=5
105
-set photon_uuid=$UUID
106
-search -n -u \$photon_uuid -s
107
-loadfont /boot/grub2/unifont.pf2
105
+search -n -u $BOOT_UUID -s
106
+loadfont "$BOOT_DIRECTORY"grub2/unifont.pf2
108 107
 
109 108
 insmod gfxterm
110 109
 insmod vbe
... ...
@@ -117,14 +119,14 @@ gfxpayload=keep
117 117
 
118 118
 terminal_output gfxterm
119 119
 
120
-set theme=/boot/grub2/themes/photon/theme.txt
121
-load_env -f /boot/photon.cfg
120
+set theme="$BOOT_DIRECTORY"grub2/themes/photon/theme.txt
121
+load_env -f "$BOOT_DIRECTORY"photon.cfg
122 122
 set_rootpartition
123 123
 
124 124
 menuentry "Photon" {
125
-    linux \$photon_linux root=\$rootpartition \$photon_cmdline
125
+    linux "$BOOT_DIRECTORY"\$photon_linux root=\$rootpartition \$photon_cmdline
126 126
     if [ "\$photon_initrd" ]; then
127
-        initrd \$photon_initrd
127
+        initrd "$BOOT_DIRECTORY"\$photon_initrd
128 128
     fi
129 129
 }
130 130
 # End /boot/grub2/grub.cfg
... ...
@@ -134,4 +136,3 @@ EOF
134 134
 rm -rf "$BUILDROOT"/tools
135 135
 rm -rf "$BUILDROOT"/RPMS
136 136
 
137
-#umount $BUILDROOT
... ...
@@ -20,11 +20,30 @@ LOGFILE=/var/log/"${PRGNAME}-${LOGFILE}"	#	set log file name
20 20
 #LOGFILE=/dev/null		#	uncomment to disable log file
21 21
 [ ${EUID} -eq 0 ] 	|| fail "${PRGNAME}: Need to be root user: FAILURE"
22 22
 [ -z ${BUILDROOT} ]		&& fail "${PRGNAME}: BUILDROOT not set: FAILURE"
23
-if mountpoint ${BUILDROOT}/run	>/dev/null 2>&1; then umount ${BUILDROOT}/run; fi
24
-if mountpoint ${BUILDROOT}/sys	>/dev/null 2>&1; then umount ${BUILDROOT}/sys; fi
25
-if mountpoint ${BUILDROOT}/proc	>/dev/null 2>&1; then umount ${BUILDROOT}/proc; fi
26
-if mountpoint ${BUILDROOT}/dev/pts	>/dev/null 2>&1; then umount ${BUILDROOT}/dev/pts; fi
27
-if mountpoint ${BUILDROOT}/dev	>/dev/null 2>&1; then umount ${BUILDROOT}/dev; fi
28 23
 
29
-if mountpoint ${BUILDROOT}	>/dev/null 2>&1; then umount ${BUILDROOT}; fi
24
+if mountpoint ${BUILDROOT}/run >/dev/null 2>&1; then umount ${BUILDROOT}/run; fi
25
+if mountpoint ${BUILDROOT}/sys >/dev/null 2>&1; then umount ${BUILDROOT}/sys; fi
26
+if mountpoint ${BUILDROOT}/proc    >/dev/null 2>&1; then umount ${BUILDROOT}/proc; fi
27
+if mountpoint ${BUILDROOT}/dev/pts >/dev/null 2>&1; then umount ${BUILDROOT}/dev/pts; fi
28
+if mountpoint ${BUILDROOT}/dev >/dev/null 2>&1; then umount ${BUILDROOT}/dev; fi
29
+
30
+while [[ $# > 0 ]]
31
+do
32
+    key="$1"
33
+    shift
34
+ 
35
+    case $key in
36
+        -p|--partitionmountpoint)
37
+        PARTITION="$1"
38
+        MOUNTPOINT="$2"
39
+        shift 2
40
+
41
+        # make sure the directory exists
42
+        if mountpoint ${BUILDROOT}${MOUNTPOINT} >/dev/null 2>&1; then umount ${BUILDROOT}${MOUNTPOINT}; fi
43
+    ;;
44
+    *)
45
+        # unknown option
46
+    ;;
47
+    esac
48
+done
30 49
 exit 0
... ...
@@ -17,71 +17,103 @@ LOG_NOTICE  = 5
17 17
 LOG_INFO    = 6
18 18
 LOG_DEBUG   = 7
19 19
 
20
-def partition_disk(disk, docker_partition_size = None, swap_partition_size = None):
20
+default_partitions = [
21
+                        {"mountpoint": "/", "size": 0, "filesystem": "ext4"},
22
+                    ]
23
+
24
+def partition_compare(p1, p2):
25
+    if 'mountpoint' in p1 and 'mountpoint' in p2:
26
+        if len(p1['mountpoint']) == len(p2['mountpoint']):
27
+            return cmp(p1['mountpoint'], p2['mountpoint'])
28
+        return len(p1['mountpoint']) - len(p2['mountpoint'])
29
+    return 0
30
+
31
+def partition_disk(disk, partitions):
21 32
     partitions_data = {}
22 33
     partitions_data['disk'] = disk
23
-
24
-    root_partition_number = 2
25
-    curr_partition_number = root_partition_number
26
-    partitions_data['root'] = disk + `root_partition_number`
27
-
28
-    if docker_partition_size != None:
29
-        docker_partition_number = curr_partition_number + 1
30
-        curr_partition_number = curr_partition_number + 1
31
-        partitions_data['docker'] = disk + `docker_partition_number`
32
-
33
-    if swap_partition_size != None:
34
-        swap_partition_number = curr_partition_number + 1
35
-        curr_partition_number = curr_partition_number + 1
36
-        partitions_data['swap'] = disk + `swap_partition_number`
37
-
34
+    partitions_data['partitions'] = partitions
38 35
     output = open(os.devnull, 'w')
39 36
 
40 37
     # Clear the disk
41
-    process = subprocess.Popen(['sgdisk', '-o', '-g', partitions_data['disk']], stdout = output)
38
+    process = subprocess.Popen(['sgdisk', '-o', '-g', disk], stdout = output)
42 39
     retval = process.wait()
43 40
     if retval != 0:
44
-    	return None
45
-
46
-
47
-    partition_cmd = ['sgdisk', '-n', '1::+2M']
48
-    if swap_partition_size != None:
49
-        partition_cmd.extend(['-n', '{}:-{}M'.format(swap_partition_number, swap_partition_size)])
50
-    if docker_partition_size != None:
51
-        partition_cmd.extend(['-n', '{}:-{}M'.format(docker_partition_number, docker_partition_size)])       
52
-    partition_cmd.extend(['-n', `root_partition_number`, '-p', partitions_data['disk']])
41
+        log(LOG_ERROR, "Failed clearing disk {0}".format(disk))
42
+        return None
53 43
 
44
+    # Partitioning the disk
45
+    extensible_partition = None
46
+    partitions_count = len(partitions)
47
+    partition_number = 1
48
+    # Adding the bios partition
49
+    partition_cmd = ['sgdisk', '-n', `partitions_count + 1` + ':-2M:']
50
+    # Adding the known size partitions
51
+    for partition in partitions:
52
+        if partition['size'] == 0:
53
+            # Can not have more than 1 extensible partition 
54
+            if extensible_partition != None:
55
+                log(LOG_ERROR, "Can not have more than 1 extensible partition")
56
+                return None
57
+            extensible_partition = partition
58
+        else:
59
+            partition_cmd.extend(['-n', '{}::+{}M'.format(partition_number, partition['size'])])
60
+        
61
+        partition['partition_number'] = partition_number 
62
+        partition['path'] = disk + `partition_number`
63
+        partition_number = partition_number + 1
64
+
65
+    # Adding the last extendible partition
66
+    if extensible_partition:
67
+        partition_cmd.extend(['-n', `extensible_partition['partition_number']`])
68
+
69
+    partition_cmd.extend(['-p', disk])
70
+
71
+    # Run the partitioning command
54 72
     process = subprocess.Popen(partition_cmd, stdout = output)
55 73
     retval = process.wait()
56 74
     if retval != 0:
75
+        log(LOG_ERROR, "Faild partition disk, command: {0}". format(partition_cmd))
57 76
         return None
58 77
 
59 78
     # Add the grub flags
60
-    process = subprocess.Popen(['sgdisk', '-t1:ef02', partitions_data['disk']], stdout = output)
79
+    process = subprocess.Popen(['sgdisk', '-t' + `partitions_count + 1` + ':ef02', disk], stdout = output)
61 80
     retval = process.wait()
62 81
     if retval != 0:
82
+        log(LOG_ERROR, "Failed to setup grub partition")
63 83
         return None
64 84
 
65
-    # format the file system
66
-    process = subprocess.Popen(['mkfs', '-t', 'ext4', partitions_data['root']], stdout = output)
67
-    retval = process.wait()
68
-    if retval != 0:
85
+    # Format the filesystem
86
+    for partition in partitions:
87
+        if "mountpoint" in partition:
88
+            if partition['mountpoint'] == '/':
89
+                partitions_data['root'] = partition['path']
90
+            elif partition['mountpoint'] == '/boot':
91
+                partitions_data['boot'] = partition['path']
92
+                partitions_data['bootdirectory'] = '/'
93
+        if partition['filesystem'] == "swap":
94
+            process = subprocess.Popen(['mkswap', partition['path']], stdout = output)
95
+            retval = process.wait()
96
+            if retval != 0:
97
+                log(LOG_ERROR, "Failed to create swap partition @ {}".format(partition['path']))
98
+                return None
99
+        else:
100
+            process = subprocess.Popen(['mkfs', '-t', partition['filesystem'], partition['path']], stdout = output)
101
+            retval = process.wait()
102
+            if retval != 0:
103
+                log(LOG_ERROR, "Failed to format {} partition @ {}".format(partition['filesystem'], partition['path']))
104
+                return None
105
+
106
+    # Check if there is no root partition
107
+    if not 'root' in partitions_data:
108
+        log(LOG_ERROR, "There is no partition assigned to root '/'")
69 109
         return None
70 110
 
71
-    # format the docker partition
72
-    if docker_partition_size != None:
73
-        process = subprocess.Popen(['mkfs', '-t', 'ext4', partitions_data['docker']], stdout = output)
74
-        retval = process.wait()
75
-        if retval != 0:
76
-            return None 
77
-
78
-    # format the swap partition
79
-    if swap_partition_size != None:
80
-        process = subprocess.Popen(['mkswap', partitions_data['swap']], stdout = output)
81
-        retval = process.wait()
82
-        if retval != 0:
83
-            return None
84
-    	
111
+    if not 'boot' in partitions_data:
112
+        partitions_data['boot'] = partitions_data['root']
113
+        partitions_data['bootdirectory'] = '/boot/'
114
+
115
+    partitions.sort(lambda p1,p2: partition_compare(p1, p2))
116
+	
85 117
     return partitions_data
86 118
 
87 119
 def replace_string_in_file(filename,  search_string,  replace_string):
... ...
@@ -8,10 +8,8 @@ enabled = True
8 8
 def execute(name, ks_config, config, root):
9 9
 
10 10
 	if ks_config:
11
-		docker_partition_size = None
12
-		swap_partition_size = None
13
-		if 'docker_partition_size' in ks_config:
14
-			docker_partition_size = ks_config['docker_partition_size']
15
-		if 'swap_partition_size' in ks_config:
16
-			swap_partition_size = ks_config['swap_partition_size']
17
-		config['disk'] = commons.partition_disk(ks_config['disk'], docker_partition_size, swap_partition_size)
11
+		if 'partitions' in ks_config:
12
+			partitions = ks_config['partitions']
13
+		else:
14
+			partitions = commons.default_partitions
15
+		config['disk'] = commons.partition_disk(ks_config['disk'], partitions)
... ...
@@ -77,8 +77,13 @@ def create_vmdk_and_partition(config, vmdk_path):
77 77
             count += 1
78 78
         elif line.startswith("ROOT_PARTITION="):
79 79
             partitions_data['root'] = line.replace("ROOT_PARTITION=", "").strip()
80
+            partitions_data['boot'] = partitions_data['root']
81
+            partitions_data['bootdirectory'] = '/boot/'
80 82
             count += 1
81 83
 
84
+    if count == 2:
85
+        partitions_data['partitions'] = [{'path': partitions_data['root'], 'mountpoint': '/', 'filesystem': 'ext4'}]
86
+
82 87
     return partitions_data, count == 2
83 88
 
84 89
 def create_rpm_list_to_copy_in_iso(build_install_option, output_data_path):
... ...
@@ -6,6 +6,12 @@
6 6
             "text": "VMware123!"
7 7
         },
8 8
     "disk": "/dev/sda",
9
+    "partitions": [
10
+                        {"mountpoint": "/", "size": 0, "filesystem": "ext4"},
11
+                        {"mountpoint": "/boot", "size": 128, "filesystem": "ext4"},
12
+                        {"mountpoint": "/root", "size": 128, "filesystem": "ext4"},
13
+                        {"size": 128, "filesystem": "swap"}
14
+                    ],
9 15
     "type": "minimal",
10 16
     "additional_packages": ["vim"],
11 17
     "postinstall": [
... ...
@@ -50,7 +50,7 @@ class SelectDisk(object):
50 50
 
51 51
         # Do the partitioning
52 52
         self.window.clearerror()
53
-        partitions_data = modules.commons.partition_disk(self.devices[device_index].path)
53
+        partitions_data = modules.commons.partition_disk(self.devices[device_index].path, modules.commons.default_partitions)
54 54
         if partitions_data == None:
55 55
             self.window.adderror('Partitioning failed, you may try again')
56 56
         else: