Browse code

python3 cloud image build scrip.

Change-Id: I06558ae79c019f0c5854eb5012137dc1c39abe9a
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/4601
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Divya Thaluru <dthaluru@vmware.com>

xiaolin-vmware authored on 2018/01/06 04:09:44
Showing 2 changed files
... ...
@@ -1,13 +1,13 @@
1
-#!/usr/bin/python2
1
+#!/usr/bin/python3
2 2
 
3 3
 import os
4 4
 import re
5 5
 import shutil
6 6
 import tarfile
7 7
 import fileinput
8
-from optparse import OptionParser
9
-from utils import Utils
8
+from argparse import ArgumentParser
10 9
 import json
10
+from utils import Utils
11 11
 
12 12
 def create_ova_image(raw_image_name, tools_path, build_scripts_path, config):
13 13
     output_path = os.path.dirname(os.path.realpath(raw_image_name))
... ...
@@ -19,15 +19,23 @@ def create_ova_image(raw_image_name, tools_path, build_scripts_path, config):
19 19
             os.remove(os.path.join(output_path, file))
20 20
 
21 21
     vmx_path = output_path + '/photon-ova.vmx'
22
-    utils.replaceandsaveasnewfile(build_scripts_path + '/vmx-template', vmx_path, 'VMDK_IMAGE', output_path + '/photon-ova.vmdk')
22
+    utils.replaceandsaveasnewfile(build_scripts_path + '/vmx-template',
23
+                                  vmx_path, 'VMDK_IMAGE',
24
+                                  output_path + '/photon-ova.vmdk')
23 25
     vixdiskutil_path = tools_path + 'vixdiskutil'
24 26
     vmdk_path = output_path + '/photon-ova.vmdk'
25 27
     ovf_path = output_path + '/photon-ova.ovf'
26 28
     mf_path = output_path + '/photon-ova.mf'
27 29
     ovfinfo_path = build_scripts_path + '/ovfinfo.txt'
28
-    vmdk_capacity = (int(config['size']['root']) + int(config['size']['swap'])) * 1024
29
-    utils.runshellcommand("{} -convert {} -cap {} {}".format(vixdiskutil_path, raw_image_name, vmdk_capacity, vmdk_path))
30
-    utils.runshellcommand("{} -wmeta toolsVersion 2147483647 {}".format(vixdiskutil_path, vmdk_path))
30
+    vmdk_capacity = (int(config['size']['root']) +
31
+                     int(config['size']['swap'])) * 1024
32
+    utils.runshellcommand(
33
+        "{} -convert {} -cap {} {}".format(vixdiskutil_path,
34
+                                           raw_image_name,
35
+                                           vmdk_capacity,
36
+                                           vmdk_path))
37
+    utils.runshellcommand(
38
+        "{} -wmeta toolsVersion 2147483647 {}".format(vixdiskutil_path, vmdk_path))
31 39
 
32 40
     utils.runshellcommand("ovftool {} {}".format(vmx_path, ovf_path))
33 41
     utils.replaceinfile(ovf_path, 'otherGuest', 'other3xLinux64Guest')
... ...
@@ -39,9 +47,9 @@ def create_ova_image(raw_image_name, tools_path, build_scripts_path, config):
39 39
             for line in fileinput.input(ovf_path, inplace=True):
40 40
                 if line.strip() == '</VirtualHardwareSection>':
41 41
                     for ovfinfoline in lines:
42
-                        print ovfinfoline,
42
+                        print(ovfinfoline)
43 43
                 else:
44
-                    print line,
44
+                    print(line)
45 45
 
46 46
     if os.path.exists(mf_path):
47 47
         os.remove(mf_path)
... ...
@@ -54,7 +62,7 @@ def create_ova_image(raw_image_name, tools_path, build_scripts_path, config):
54 54
     rawsplit = os.path.splitext(raw_image_name)
55 55
     ova_name = rawsplit[0] + '.ova'
56 56
 
57
-    ovatar = tarfile.open(ova_name, "w", format = tarfile.USTAR_FORMAT)
57
+    ovatar = tarfile.open(ova_name, "w", format=tarfile.USTAR_FORMAT)
58 58
     for name in ["photon-ova.ovf", "photon-ova.mf", "photon-ova-disk1.vmdk"]:
59 59
         ovatar.add(name, arcname=os.path.basename(name))
60 60
     ovatar.close()
... ...
@@ -65,15 +73,17 @@ def create_ova_image(raw_image_name, tools_path, build_scripts_path, config):
65 65
         for addlversion in config['additionalhwversion']:
66 66
             new_ovf_path = output_path + "/photon-ova-hw{}.ovf".format(addlversion)
67 67
             mf_path = output_path + "/photon-ova-hw{}.mf".format(addlversion)
68
-            utils.replaceandsaveasnewfile(ovf_path, new_ovf_path, "vmx-.*<", "vmx-{}<".format(addlversion))
69
-            out = utils.runshellcommand("openssl sha1 photon-ova-disk1.vmdk photon-ova-hw{}.ovf".format(addlversion))
68
+            utils.replaceandsaveasnewfile(
69
+                ovf_path, new_ovf_path, "vmx-.*<", "vmx-{}<".format(addlversion))
70
+            out = utils.runshellcommand("openssl sha1 photon-ova-disk1.vmdk "
71
+                                        "photon-ova-hw{}.ovf".format(addlversion))
70 72
             with open(mf_path, "w") as source:
71 73
                 source.write(out)
72 74
             temp_name_list = os.path.basename(ova_name).split('-')
73 75
             temp_name_list = temp_name_list[:2] + ["hw{}".format(addlversion)] + temp_name_list[2:]
74 76
             new_ova_name = '-'.join(temp_name_list)
75 77
             new_ova_path = output_path + '/' + new_ova_name
76
-            ovatar = tarfile.open(new_ova_path, "w", format = tarfile.USTAR_FORMAT)
78
+            ovatar = tarfile.open(new_ova_path, "w", format=tarfile.USTAR_FORMAT)
77 79
             for name in [new_ovf_path, mf_path, "photon-ova-disk1.vmdk"]:
78 80
                 ovatar.add(name, arcname=os.path.basename(name))
79 81
             ovatar.close()
... ...
@@ -91,70 +101,81 @@ def create_ova_image(raw_image_name, tools_path, build_scripts_path, config):
91 91
 
92 92
 if __name__ == '__main__':
93 93
     usage = "Usage: %prog [options]"
94
-    parser = OptionParser(usage)
95
-
96
-    parser.add_option("-r", "--raw-image-path",  dest="raw_image_path")
97
-    parser.add_option("-c", "--vmdk-config-path", dest="vmdk_config_path")
98
-    parser.add_option("-w",  "--working-directory",  dest="working_directory")
99
-    parser.add_option("-m",  "--mount-path",  dest="mount_path")
100
-    parser.add_option("-a",  "--additional-rpms-path",  dest="additional_rpms_path")
101
-    parser.add_option("-i",  "--image-name",  dest="image_name")
102
-    parser.add_option("-t",  "--tools-bin-path",  dest="tools_bin_path")
103
-    parser.add_option("-b",  "--build-scripts-path",  dest="build_scripts_path")
104
-    parser.add_option("-s",  "--src-root",  dest="src_root")
105
-
106
-    (options,  args) = parser.parse_args()
94
+    parser = ArgumentParser(usage)
95
+
96
+    parser.add_argument("-r", "--raw-image-path", dest="raw_image_path")
97
+    parser.add_argument("-c", "--vmdk-config-path", dest="vmdk_config_path")
98
+    parser.add_argument("-w", "--working-directory", dest="working_directory")
99
+    parser.add_argument("-m", "--mount-path", dest="mount_path")
100
+    parser.add_argument("-a", "--additional-rpms-path", dest="additional_rpms_path")
101
+    parser.add_argument("-i", "--image-name", dest="image_name")
102
+    parser.add_argument("-t", "--tools-bin-path", dest="tools_bin_path")
103
+    parser.add_argument("-b", "--build-scripts-path", dest="build_scripts_path")
104
+    parser.add_argument("-s", "--src-root", dest="src_root")
105
+
106
+    options = parser.parse_args()
107 107
     utils = Utils()
108 108
     config = utils.jsonread(options.vmdk_config_path)
109
-    print options
109
+    print(options)
110 110
 
111
-    disk_device = (utils.runshellcommand("losetup --show -f {}".format(options.raw_image_path))).rstrip('\n')
111
+    disk_device = (utils.runshellcommand(
112
+        "losetup --show -f {}".format(options.raw_image_path))).rstrip('\n')
112 113
     disk_partitions = utils.runshellcommand("kpartx -as {}".format(disk_device))
113 114
     device_name = disk_device.split('/')[2]
114 115
 
115 116
     if not os.path.exists(options.mount_path):
116 117
         os.mkdir(options.mount_path)
117
-    loop_device_path =  "/dev/mapper/{}p2".format(device_name)
118
+    loop_device_path = "/dev/mapper/{}p2".format(device_name)
118 119
 
119 120
     try:
120
-        print "Generating PARTUUID for the loop device ..."
121
-        partuuidval = (utils.runshellcommand("blkid -s PARTUUID -o value {}".format(loop_device_path))).rstrip('\n')
122
-        uuidval = (utils.runshellcommand("blkid -s UUID -o value {}".format(loop_device_path))).rstrip('\n')
123
-        if (partuuidval == ''):
124
-            sgdiskout = utils.runshellcommand("sgdisk -i 2 {} ".format(disk_device))
125
-            partuuidval = (re.findall(r'Partition unique GUID.*', sgdiskout))[0].split(':')[1].strip(' ').lower()
126
-
127
-        if (partuuidval == ''):
121
+        print("Generating PARTUUID for the loop device ...")
122
+        partuuidval = (utils.runshellcommand(
123
+            "blkid -s PARTUUID -o value {}".format(loop_device_path))).rstrip('\n')
124
+        uuidval = (utils.runshellcommand(
125
+            "blkid -s UUID -o value {}".format(loop_device_path))).rstrip('\n')
126
+        if partuuidval == '':
127
+            sgdiskout = utils.runshellcommand(
128
+                "sgdisk -i 2 {} ".format(disk_device))
129
+            partuuidval = (re.findall(r'Partition unique GUID.*',
130
+                                      sgdiskout))[0].split(':')[1].strip(' ').lower()
131
+
132
+        if partuuidval == '':
128 133
             raise RuntimeError("Cannot generate partuuid")
129 134
 
130 135
         # Mount the loop device
131
-        print "Mounting the loop device for customization ..."
132
-        utils.runshellcommand("mount -t ext4 {} {}".format(loop_device_path, options.mount_path))
136
+        print("Mounting the loop device for customization ...")
137
+        utils.runshellcommand(
138
+            "mount -t ext4 {} {}".format(loop_device_path, options.mount_path))
133 139
         shutil.rmtree(options.mount_path + "/installer", ignore_errors=True)
134 140
         shutil.rmtree(options.mount_path + "/LOGS", ignore_errors=True)
135 141
         # Clear the root password if not set explicitly from the config file
136
-        if (config['password']['text'] != 'PASSWORD'):
137
-            utils.replaceinfile(options.mount_path + "/etc/shadow",'root:.*?:','root:*:')
142
+        if config['password']['text'] != 'PASSWORD':
143
+            utils.replaceinfile(options.mount_path + "/etc/shadow",
144
+                                'root:.*?:', 'root:*:')
138 145
         # Clear machine-id so it gets regenerated on boot
139 146
         open(options.mount_path + "/etc/machine-id", "w").close()
140 147
         os.remove(options.mount_path + "/etc/fstab")
141 148
 
142 149
         f = open(options.mount_path + "/etc/fstab", "w")
143
-        if (uuidval != ''):
150
+        if uuidval != '':
144 151
             f.write("UUID={}    /    ext4    defaults 1 1\n".format(uuidval))
145 152
         else:
146 153
             f.write("PARTUUID={}    /    ext4    defaults 1 1\n".format(partuuidval))
147 154
         f.close()
148
-        utils.replaceinfile(options.mount_path + "/boot/grub/grub.cfg", "rootpartition=PARTUUID=.*$", "rootpartition=PARTUUID={}".format(partuuidval))
155
+        utils.replaceinfile(options.mount_path + "/boot/grub/grub.cfg",
156
+                            "rootpartition=PARTUUID=.*$",
157
+                            "rootpartition=PARTUUID={}".format(partuuidval))
149 158
 
150 159
         if os.path.exists(options.additional_rpms_path):
151
-            print "Installing additional rpms"
160
+            print("Installing additional rpms")
152 161
             os.mkdir(options.mount_path + "/additional_rpms")
153 162
             os.mkdir(options.mount_path + "/var/run")
154
-            utils.copyallfiles(additional_rpms_path, options.mount_path + "/additional_rpms")
155
-            utils.runshellcommand("chroot {} /bin/bash -c 'rpm -i /additional_rpms/*'".format(options.mount_path))
163
+            utils.copyallfiles(options.additional_rpms_path,
164
+                               options.mount_path + "/additional_rpms")
165
+            utils.runshellcommand(
166
+                "chroot {} /bin/bash -c 'rpm -i /additional_rpms/*'".format(options.mount_path))
156 167
             shutil.rmtree(options.mount_path + "/additional_rpms", ignore_errors=True)
157
-            shutil.rmtree(additional_rpms_path, ignore_errors=True)
168
+            shutil.rmtree(options.additional_rpms_path, ignore_errors=True)
158 169
 
159 170
         utils.runshellcommand("mount -o bind /proc {}".format(options.mount_path + "/proc"))
160 171
         utils.runshellcommand("mount -o bind /dev {}".format(options.mount_path + "/dev"))
... ...
@@ -162,28 +183,36 @@ if __name__ == '__main__':
162 162
         utils.runshellcommand("mount -o bind /sys {}".format(options.mount_path + "/sys"))
163 163
 
164 164
         if 'additionalfiles' in config:
165
-            print "  Copying additional files into the raw image ..."
165
+            print("  Copying additional files into the raw image ...")
166 166
             for filetuples in config['additionalfiles']:
167
-                for src,dest in filetuples.iteritems():
168
-		    if (os.path.isdir(options.build_scripts_path + '/' + options.image_name + '/' + src)):
169
-                        shutil.copytree(options.build_scripts_path + '/' + options.image_name + '/' + src, options.mount_path + dest, True)
167
+                for src, dest in filetuples.items():
168
+                    if (os.path.isdir(options.build_scripts_path + '/' +
169
+                                      options.image_name + '/' + src)):
170
+                        shutil.copytree(options.build_scripts_path + '/' +
171
+                                        options.image_name + '/' + src,
172
+                                        options.mount_path + dest, True)
170 173
                     else:
171
-                        shutil.copyfile(options.build_scripts_path + '/' + options.image_name + '/' + src, options.mount_path + dest)
174
+                        shutil.copyfile(options.build_scripts_path + '/' +
175
+                                        options.image_name + '/' + src,
176
+                                        options.mount_path + dest)
172 177
 
173 178
 
174 179
         if 'postinstallscripts' in config:
175
-            print "  Running post install scripts ..."
180
+            print("  Running post install scripts ...")
176 181
             if not os.path.exists(options.mount_path + "/tempscripts"):
177 182
                 os.mkdir(options.mount_path + "/tempscripts")
178 183
             for script in config['postinstallscripts']:
179
-                shutil.copy(options.build_scripts_path + '/' + options.image_name + '/' + script, options.mount_path + "/tempscripts")
184
+                shutil.copy(options.build_scripts_path + '/' +
185
+                            options.image_name + '/' + script,
186
+                            options.mount_path + "/tempscripts")
180 187
             for script in os.listdir(options.mount_path + "/tempscripts"):
181
-                print "     ...running script {}".format(script)
182
-                utils.runshellcommand("chroot {} /bin/bash -c '/tempscripts/{}'".format(options.mount_path, script))
188
+                print("     ...running script {}".format(script))
189
+                utils.runshellcommand(
190
+                    "chroot {} /bin/bash -c '/tempscripts/{}'".format(options.mount_path, script))
183 191
             shutil.rmtree(options.mount_path + "/tempscripts", ignore_errors=True)
184 192
 
185 193
     except Exception as e:
186
-	print e
194
+        print(e)
187 195
 
188 196
     finally:
189 197
         utils.runshellcommand("umount -l {}".format(options.mount_path + "/sys"))
... ...
@@ -195,8 +224,8 @@ if __name__ == '__main__':
195 195
         utils.runshellcommand("umount -l {}".format(options.mount_path))
196 196
 
197 197
         mount_out = utils.runshellcommand("mount")
198
-        print "List of mounted devices:"
199
-        print mount_out
198
+        print("List of mounted devices:")
199
+        print(mount_out)
200 200
 
201 201
         utils.runshellcommand("kpartx -d {}".format(disk_device))
202 202
         utils.runshellcommand("losetup -d {}".format(disk_device))
... ...
@@ -210,39 +239,56 @@ if __name__ == '__main__':
210 210
         img_path = os.path.dirname(os.path.realpath(raw_image))
211 211
         # Rename gce image to disk.raw
212 212
         if options.image_name == "gce":
213
-            print "Renaming the raw file to disk.raw ..."
213
+            print("Renaming the raw file to disk.raw ...")
214 214
             new_name = img_path + '/disk.raw'
215 215
 
216 216
         else:
217
-            new_name = img_path + '/photon-' + options.image_name + '-' + photon_release_ver + '-' + photon_build_num + '.raw'
217
+            new_name = (img_path + '/photon-' + options.image_name +
218
+                        '-' + photon_release_ver + '-' +
219
+                        photon_build_num + '.raw')
218 220
 
219 221
         shutil.move(raw_image, new_name)
220 222
         raw_image = new_name
221 223
 
222 224
         if config['artifacttype'] == 'tgz':
223
-            print "Generating the tar.gz artifact ..."
224
-            tarname = img_path + '/photon-' + options.image_name + '-' + photon_release_ver + '-' + photon_build_num + '.tar.gz'
225
+            print("Generating the tar.gz artifact ...")
226
+            tarname = (img_path + '/photon-' + options.image_name +
227
+                       '-' + photon_release_ver + '-' +
228
+                       photon_build_num + '.tar.gz')
229
+
225 230
             tgzout = tarfile.open(tarname, "w:gz")
226 231
             tgzout.add(raw_image, arcname=os.path.basename(raw_image))
227 232
             tgzout.close()
228 233
         elif config['artifacttype'] == 'xz':
229
-            print "Generating the xz artifact ..."
234
+            print("Generating the xz artifact ...")
230 235
             utils.runshellcommand("xz -z -k {}".format(raw_image))
231
-#            tarname = img_path + '/photon-' + options.image_name + '-' + photon_release_ver + '-' + photon_build_num + '.xz'
236
+#            tarname = img_path + '/photon-' + options.image_name +
237
+#            '-' + photon_release_ver + '-' + photon_build_num +
238
+#            '.xz'
232 239
 #            tgzout = tarfile.open(tarname, "w:xz")
233 240
 #            tgzout.add(raw_image, arcname=os.path.basename(raw_image))
234 241
 #            tgzout.close()
235 242
         elif config['artifacttype'] == 'vhd':
236 243
             relrawpath = os.path.relpath(raw_image, options.src_root)
237
-            vhdname = os.path.dirname(relrawpath) + '/photon-' + options.image_name + '-' + photon_release_ver + '-' + photon_build_num + '.vhd'
238
-            print "Converting raw disk to vhd ..."
239
-            info_output=utils.runshellcommand("docker run -v {}:/mnt:rw anishs/qemu-img info -f raw --output json {}".format(options.src_root, '/mnt/' + relrawpath))
244
+            vhdname = (os.path.dirname(relrawpath) + '/photon-' +
245
+                       options.image_name + '-' + photon_release_ver + '-' +
246
+                       photon_build_num + '.vhd')
247
+            print("Converting raw disk to vhd ...")
248
+            info_output = utils.runshellcommand(
249
+                "docker run -v {}:/mnt:rw anishs/qemu-img info -f raw --output json {}"
250
+                .format(options.src_root, '/mnt/' + relrawpath))
240 251
             mbsize = 1024 * 1024
241 252
             mbroundedsize = ((int(json.loads(info_output)["virtual-size"])/mbsize + 1) * mbsize)
242
-            utils.runshellcommand("docker run -v {}:/mnt:rw anishs/qemu-img resize -f raw {} {}".format(options.src_root, '/mnt/' + relrawpath, mbroundedsize))
243
-            utils.runshellcommand("docker run -v {}:/mnt:rw anishs/qemu-img convert {} -O vpc -o subformat=fixed,force_size {}".format(options.src_root, '/mnt/' + relrawpath, '/mnt/' + vhdname))
253
+            utils.runshellcommand(
254
+                "docker run -v {}:/mnt:rw anishs/qemu-img resize -f raw {} {}"
255
+                .format(options.src_root, '/mnt/' + relrawpath, mbroundedsize))
256
+            utils.runshellcommand(
257
+                "docker run -v {}:/mnt:rw anishs/qemu-img convert {} -O "
258
+                "vpc -o subformat=fixed,force_size {}"
259
+                .format(options.src_root, '/mnt/' + relrawpath, '/mnt/' + vhdname))
244 260
         elif config['artifacttype'] == 'ova':
245
-            create_ova_image(raw_image, options.tools_bin_path, options.build_scripts_path + '/' + options.image_name, config)
261
+            create_ova_image(raw_image, options.tools_bin_path,
262
+                             options.build_scripts_path + '/' + options.image_name, config)
246 263
             if 'customartifacts' in config:
247 264
                 if 'postinstallscripts' in config['customartifacts']:
248 265
                     custom_path = img_path + '/photon-custom'
... ...
@@ -250,34 +296,46 @@ if __name__ == '__main__':
250 250
                         os.mkdir(custom_path)
251 251
                     index = 1
252 252
                     for script in config['customartifacts']['postinstallscripts']:
253
-                        print "Creating custom ova {}...".format(index)
253
+                        print("Creating custom ova {}...".format(index))
254 254
                         if index > 1:
255
-                            raw_image_custom = img_path + "/photon-custom-{}".format(index) + photon_release_ver + '-' + photon_build_num + '.raw'
255
+                            raw_image_custom = (img_path + "/photon-custom-{}".format(index) +
256
+                                                photon_release_ver + '-' +
257
+                                                photon_build_num + '.raw')
256 258
                         else:
257
-                            raw_image_custom = img_path + "/photon-custom-" + photon_release_ver + '-' + photon_build_num + '.raw'
259
+                            raw_image_custom = (img_path + "/photon-custom-" +
260
+                                                photon_release_ver + '-' +
261
+                                                photon_build_num + '.raw')
258 262
                         shutil.move(raw_image, raw_image_custom)
259
-                        disk_device = (utils.runshellcommand("losetup --show -f {}".format(raw_image_custom))).rstrip('\n')
260
-                        disk_partitions = utils.runshellcommand("kpartx -as {}".format(disk_device))
263
+                        disk_device = (
264
+                            utils.runshellcommand(
265
+                                "losetup --show -f {}".format(raw_image_custom))).rstrip('\n')
266
+                        disk_partitions = utils.runshellcommand(
267
+                            "kpartx -as {}".format(disk_device))
261 268
                         device_name = disk_device.split('/')[2]
262
-                        loop_device_path =  "/dev/mapper/{}p2".format(device_name)
269
+                        loop_device_path = "/dev/mapper/{}p2".format(device_name)
263 270
 
264
-                        print "Mounting the loop device for ova customization ..."
265
-                        utils.runshellcommand("mount -t ext4 {} {}".format(loop_device_path, custom_path))
271
+                        print("Mounting the loop device for ova customization ...")
272
+                        utils.runshellcommand(
273
+                            "mount -t ext4 {} {}".format(loop_device_path, custom_path))
266 274
                         if not os.path.exists(custom_path + "/tempscripts"):
267 275
                             os.mkdir(custom_path + "/tempscripts")
268
-                        shutil.copy(options.build_scripts_path + '/' + options.image_name + '/' + script, custom_path + "/tempscripts")
269
-                        print "Running custom ova script {}".format(script)
270
-                        utils.runshellcommand("chroot {} /bin/bash -c '/tempscripts/{}'".format(custom_path, script))
276
+                        shutil.copy(options.build_scripts_path + '/' + options.image_name +
277
+                                    '/' + script, custom_path + "/tempscripts")
278
+                        print("Running custom ova script {}".format(script))
279
+                        utils.runshellcommand("chroot {} /bin/bash -c '/tempscripts/{}'"
280
+                                              .format(custom_path, script))
271 281
                         shutil.rmtree(custom_path + "/tempscripts", ignore_errors=True)
272 282
                         utils.runshellcommand("umount -l {}".format(custom_path))
273 283
 
274 284
                         mount_out = utils.runshellcommand("mount")
275
-                        print "List of mounted devices:"
276
-                        print mount_out
285
+                        print("List of mounted devices:")
286
+                        print(mount_out)
277 287
 
278 288
                         utils.runshellcommand("kpartx -d {}".format(disk_device))
279 289
                         utils.runshellcommand("losetup -d {}".format(disk_device))
280
-                        create_ova_image(raw_image_custom, options.tools_bin_path, options.build_scripts_path + '/' + options.image_name, config)
290
+                        create_ova_image(raw_image_custom, options.tools_bin_path,
291
+                                         options.build_scripts_path + '/' + options.image_name,
292
+                                         config)
281 293
                         raw_image = raw_image_custom
282 294
                         index = index + 1
283 295
 
... ...
@@ -1,5 +1,3 @@
1
-#!/usr/bin/python2
2
-
3 1
 import os
4 2
 import ctypes
5 3
 import ctypes.util
... ...
@@ -8,6 +6,7 @@ import collections
8 8
 import subprocess
9 9
 import fileinput
10 10
 import re
11
+import shutil
11 12
 
12 13
 class Utils(object):
13 14
     def __init__(self):
... ...
@@ -33,45 +32,51 @@ class Utils(object):
33 33
                                     ctypes.c_char_p(flags),
34 34
                                     0)
35 35
         if ret != 0:
36
-            raise RuntimeError("Cannot mount {} : {}".format(source, os.strerror(ctypes.get_errno())))
36
+            raise RuntimeError(
37
+                "Cannot mount {} : {}".format(source, os.strerror(ctypes.get_errno())))
37 38
 
38 39
     def umount(self, destination):
39 40
         ret = self.libcloader.umount(ctypes.c_char_p(destination))
40 41
         if ret != 0:
41
-            raise RuntimeError("Cannot umount {} : {}".format(destination, os.strerror(ctypes.get_errno())))
42
-    
43
-    def jsonread(self, filename):
42
+            raise RuntimeError(
43
+                "Cannot umount {} : {}".format(destination, os.strerror(ctypes.get_errno())))
44
+    @staticmethod
45
+    def jsonread(filename):
44 46
         json_data = open(filename)
45 47
         data = json.load(json_data, object_pairs_hook=collections.OrderedDict)
46 48
         json_data.close()
47 49
         return data
48 50
 
49
-    def runshellcommand(self, cmd, ignore_errors=False):
50
-        print cmd
51
-        command=cmd.split()
51
+    @staticmethod
52
+    def runshellcommand(cmd, ignore_errors=False):
53
+        print(cmd)
54
+        command = cmd.split()
52 55
         p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
53 56
         output, err = p.communicate()
54 57
         rc = p.returncode
55 58
         if not ignore_errors:
56 59
             if rc != 0:
57
-                print err
60
+                print(err)
58 61
                 raise RuntimeError("Cannot run command {}".format(cmd))
59
-        return output
62
+        return output.decode()
60 63
 
61
-    def replaceinfile(self, filename, pattern, sub):
64
+    @staticmethod
65
+    def replaceinfile(filename, pattern, sub):
62 66
         for line in fileinput.input(filename, inplace=True):
63 67
             line = re.sub(pattern, sub, line)
64
-            print line,
68
+            print(line)
65 69
 
66
-    def replaceandsaveasnewfile(self, old_file, new_file, pattern, sub):
70
+    @staticmethod
71
+    def replaceandsaveasnewfile(old_file, new_file, pattern, sub):
67 72
         with open(old_file, "r") as old, open(new_file, "w") as new:
68 73
             for line in old:
69 74
                 line = re.sub(pattern, sub, line)
70 75
                 new.write(line)
71 76
 
72
-    def copyallfiles(self, src, target):
77
+    @staticmethod
78
+    def copyallfiles(src, target):
73 79
         files = os.listdir(src)
74 80
         for file in files:
75 81
             filename = os.path.join(src, file)
76
-            if (os.path.isfile(filename)):
82
+            if os.path.isfile(filename):
77 83
                 shutil.copy(filename, target)