Browse code

Clean installer.py and log more error messages.

Change-Id: I8b44aaed9a9361a5e25be9d429dda6efeef2859c
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/4636
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Rui Gu <ruig@vmware.com>

xiaolin-vmware authored on 2018/01/12 09:33:31
Showing 1 changed files
... ...
@@ -1,3 +1,6 @@
1
+"""
2
+Photon installer
3
+"""
1 4
 #    Copyright (C) 2015 vmware inc.
2 5
 #
3 6
 #    Author: Mahmoud Bassiouny <mbassiouny@vmware.com>
... ...
@@ -15,18 +18,22 @@ from window import Window
15 15
 from actionresult import ActionResult
16 16
 
17 17
 class Installer(object):
18
+    """
19
+    Photon installer
20
+    """
21
+    mount_command = "./mk-mount-disk.sh"
22
+    prepare_command = "./mk-prepare-system.sh"
23
+    finalize_command = "./mk-finalize-system.sh"
24
+    chroot_command = "./mk-run-chroot.sh"
25
+    setup_grub_command = "./mk-setup-grub.sh"
26
+    unmount_disk_command = "./mk-unmount-disk.sh"
27
+
18 28
     def __init__(self, install_config, maxy=0, maxx=0, iso_installer=False,
19 29
                  rpm_path="../stage/RPMS", log_path="../stage/LOGS"):
20 30
         self.install_config = install_config
21
-        self.iso_installer = iso_installer
31
+        self.install_config['iso_installer'] = iso_installer
22 32
         self.rpm_path = rpm_path
23 33
         self.log_path = log_path
24
-        self.mount_command = "./mk-mount-disk.sh"
25
-        self.prepare_command = "./mk-prepare-system.sh"
26
-        self.finalize_command = "./mk-finalize-system.sh"
27
-        self.chroot_command = "./mk-run-chroot.sh"
28
-        self.setup_grub_command = "./mk-setup-grub.sh"
29
-        self.unmount_disk_command = "./mk-unmount-disk.sh"
30 34
 
31 35
         if 'working_directory' in self.install_config:
32 36
             self.working_directory = self.install_config['working_directory']
... ...
@@ -34,127 +41,93 @@ class Installer(object):
34 34
             self.working_directory = "/mnt/photon-root"
35 35
         self.photon_root = self.working_directory + "/photon-chroot"
36 36
         self.rpms_tobeinstalled = None
37
-        self.restart_command = "shutdown"
38 37
 
39
-        if self.iso_installer:
38
+        if self.install_config['iso_installer']:
40 39
             self.output = open(os.devnull, 'w')
41
-        else:
42
-            self.output = None
43
-
44
-        if self.iso_installer:
45 40
             #initializing windows
46
-            self.maxy = maxy
47
-            self.maxx = maxx
48
-            self.height = 10
49
-            self.width = 75
50
-            self.progress_padding = 5
51
-
52
-            self.progress_width = self.width - self.progress_padding
53
-            self.starty = (self.maxy - self.height) // 2
54
-            self.startx = (self.maxx - self.width) // 2
55
-            self.window = Window(self.height, self.width, self.maxy, self.maxx,
41
+            height = 10
42
+            width = 75
43
+            progress_padding = 5
44
+
45
+            progress_width = width - progress_padding
46
+            starty = (maxy - height) // 2
47
+            startx = (maxx - width) // 2
48
+            self.window = Window(height, width, maxy, maxx,
56 49
                                  'Installing Photon', False)
57
-            self.progress_bar = ProgressBar(self.starty + 3,
58
-                                            self.startx + self.progress_padding // 2,
59
-                                            self.progress_width)
50
+            self.progress_bar = ProgressBar(starty + 3,
51
+                                            startx + progress_padding // 2,
52
+                                            progress_width)
60 53
 
54
+        else:
55
+            self.output = None
61 56
         signal.signal(signal.SIGINT, self.exit_gracefully)
62 57
 
63
-    # This will be called if the installer interrupted by Ctrl+C or exception
64
-    def exit_gracefully(self, signal1, frame1):
65
-        del signal1
66
-        del frame1
67
-        if self.iso_installer:
68
-            self.progress_bar.hide()
69
-            self.window.addstr(0, 0, 'Oops, Installer got interrupted.\n\n' +
70
-                               'Press any key to get to the bash...')
71
-            self.window.content_window().getch()
72
-
73
-        modules.commons.dump(modules.commons.LOG_FILE_NAME)
74
-        sys.exit(1)
75
-
76 58
     def install(self, params):
59
+        """
60
+        Install photon system and handle exception
61
+        """
77 62
         del params
78 63
         try:
79
-            return self.unsafe_install()
64
+            return self._unsafe_install()
80 65
         except Exception as inst:
81
-            if self.iso_installer:
66
+            if self.install_config['iso_installer']:
82 67
                 modules.commons.log(modules.commons.LOG_ERROR, repr(inst))
83 68
                 self.exit_gracefully(None, None)
84 69
             else:
85 70
                 raise
86 71
 
87
-    def unsafe_install(self):
88
-        self.setup_install_repo()
89
-        self.execute_modules(modules.commons.PRE_INSTALL)
90
-
91
-        self.initialize_system()
92
-        self.install_packages()
93
-        self.enable_network_in_chroot()
94
-        self.finalize_system()
95
-
96
-        if not self.install_config['iso_system']:
97
-            # Execute post installation modules
98
-            self.execute_modules(modules.commons.POST_INSTALL)
99
-            if os.path.exists(modules.commons.KS_POST_INSTALL_LOG_FILE_NAME):
100
-                shutil.copy(modules.commons.KS_POST_INSTALL_LOG_FILE_NAME,
101
-                            self.photon_root + '/var/log/')
102
-
103
-            if self.iso_installer and os.path.isdir("/sys/firmware/efi"):
104
-                self.install_config['boot'] = 'efi'
105
-            # install grub
106
-            if 'boot_partition_number' not in self.install_config['disk']:
107
-                self.install_config['disk']['boot_partition_number'] = 1
72
+    def _unsafe_install(self):
73
+        """
74
+        Install photon system
75
+        """
76
+        self._setup_install_repo()
77
+        self._initialize_system()
78
+        self._install_packages()
79
+        self._enable_network_in_chroot()
80
+        self._finalize_system()
81
+
82
+        self._disable_network_in_chroot()
83
+        self._cleanup_and_exit()
84
+        return ActionResult(True, None)
108 85
 
109
-            try:
110
-                if self.install_config['boot'] == 'bios':
111
-                    process = subprocess.Popen(
112
-                        [self.setup_grub_command, '-w', self.photon_root,
113
-                         "bios", self.install_config['disk']['disk'],
114
-                         self.install_config['disk']['root'],
115
-                         self.install_config['disk']['boot'],
116
-                         self.install_config['disk']['bootdirectory'],
117
-                         str(self.install_config['disk']['boot_partition_number'])],
118
-                        stdout=self.output)
119
-                elif self.install_config['boot'] == 'efi':
120
-                    process = subprocess.Popen(
121
-                        [self.setup_grub_command, '-w', self.photon_root,
122
-                         "efi", self.install_config['disk']['disk'],
123
-                         self.install_config['disk']['root'],
124
-                         self.install_config['disk']['boot'],
125
-                         self.install_config['disk']['bootdirectory'],
126
-                         str(self.install_config['disk']['boot_partition_number'])],
127
-                        stdout=self.output)
128
-            except:
129
-                #install bios if variable is not set.
130
-                process = subprocess.Popen(
131
-                    [self.setup_grub_command, '-w', self.photon_root,
132
-                     "bios", self.install_config['disk']['disk'],
133
-                     self.install_config['disk']['root'],
134
-                     self.install_config['disk']['boot'],
135
-                     self.install_config['disk']['bootdirectory'],
136
-                     str(self.install_config['disk']['boot_partition_number'])],
137
-                    stdout=self.output)
138
-            retval = process.wait()
86
+    def exit_gracefully(self, signal1, frame1):
87
+        """
88
+        This will be called if the installer interrupted by Ctrl+C, exception
89
+        or other failures
90
+        """
91
+        del signal1
92
+        del frame1
93
+        if self.install_config['iso_installer']:
94
+            self.progress_bar.hide()
95
+            self.window.addstr(0, 0, 'Oops, Installer got interrupted.\n\n' +
96
+                               'Press any key to get to the bash...')
97
+            self.window.content_window().getch()
139 98
 
140
-            self.update_fstab()
141
-        self.disable_network_in_chroot()
99
+        modules.commons.dump(modules.commons.LOG_FILE_NAME)
100
+        sys.exit(1)
142 101
 
143
-        command = [self.unmount_disk_command, '-w', self.photon_root]
102
+    def _cleanup_and_exit(self):
103
+        """
104
+        Unmount the disk, eject cd and exit
105
+        """
106
+        command = [Installer.unmount_disk_command, '-w', self.photon_root]
144 107
         if not self.install_config['iso_system']:
145
-            command.extend(self.generate_partitions_param(reverse=True))
108
+            command.extend(self._generate_partitions_param(reverse=True))
146 109
         process = subprocess.Popen(command, stdout=self.output)
147 110
         retval = process.wait()
148
-
149
-        if self.iso_installer:
111
+        if retval != 0:
112
+            modules.commons.log(modules.commons.LOG_ERROR, "Failed to unmount disks")
113
+        if self.install_config['iso_installer']:
150 114
             self.progress_bar.hide()
151 115
             self.window.addstr(0, 0, 'Congratulations, Photon has been installed in {0} secs.\n\n'
152 116
                                'Press any key to continue to boot...'
153 117
                                .format(self.progress_bar.time_elapsed))
154
-            self.eject_cdrom()
155
-        return ActionResult(True, None)
118
+            self._eject_cdrom()
156 119
 
157
-    def copy_rpms(self):
120
+    def _copy_rpms(self):
121
+        """
122
+        Prepare RPM list and copy rpms
123
+        """
158 124
         # prepare the RPMs list
159 125
         json_pkg_to_rpm_map = JsonWrapper(self.install_config["pkg_to_rpm_map_file"])
160 126
         pkg_to_rpm_map = json_pkg_to_rpm_map.read()
... ...
@@ -174,38 +147,70 @@ class Installer(object):
174 174
         for rpm in self.rpms_tobeinstalled:
175 175
             shutil.copy(rpm['path'], self.photon_root + '/RPMS/')
176 176
 
177
-    def copy_files(self):
177
+    def _copy_files(self):
178
+        """
179
+        Copy the rpm files and instal scripts.
180
+        """
178 181
         # Make the photon_root directory if not exits
179 182
         process = subprocess.Popen(['mkdir', '-p', self.photon_root], stdout=self.output)
180 183
         retval = process.wait()
184
+        if retval != 0:
185
+            modules.commons.log(modules.commons.LOG_ERROR, "Fail to create the root directory")
186
+            self.exit_gracefully(None, None)
181 187
 
182 188
         # Copy the installer files
183 189
         process = subprocess.Popen(['cp', '-r', "../installer", self.photon_root],
184 190
                                    stdout=self.output)
185 191
         retval = process.wait()
192
+        if retval != 0:
193
+            modules.commons.log(modules.commons.LOG_ERROR, "Fail to copy install scripts")
194
+            self.exit_gracefully(None, None)
186 195
 
187 196
         # Create the rpms directory
188 197
         process = subprocess.Popen(['mkdir', '-p', self.photon_root + '/RPMS'],
189 198
                                    stdout=self.output)
190 199
         retval = process.wait()
191
-        self.copy_rpms()
192
-
193
-    def bind_installer(self):
200
+        if retval != 0:
201
+            modules.commons.log(modules.commons.LOG_ERROR, "Fail to create the rpms directory")
202
+            self.exit_gracefully(None, None)
203
+        self._copy_rpms()
204
+
205
+    def _bind_installer(self):
206
+        """
207
+        Make the photon_root/installer directory if not exits
208
+        The function finalize_system will access the file /installer/mk-finalize-system.sh
209
+        after chroot to photon_root.
210
+        Bind the /installer folder to self.photon_root/installer, so that after chroot
211
+        to photon_root,
212
+        the file can still be accessed as /installer/mk-finalize-system.sh.
213
+        """
194 214
         # Make the photon_root/installer directory if not exits
195
-        process = subprocess.Popen(['mkdir', '-p', os.path.join(self.photon_root, "installer")],
215
+        if(subprocess.call(['mkdir', '-p',
216
+                            os.path.join(self.photon_root, "installer")]) != 0 or
217
+           subprocess.call(['mount', '--bind', '/installer',
218
+                            os.path.join(self.photon_root, "installer")]) != 0):
219
+            modules.commons.log(modules.commons.LOG_ERROR, "Fail to bind installer")
220
+            self.exit_gracefully(None, None)
221
+    def _unbind_installer(self):
222
+        # unmount the installer directory
223
+        process = subprocess.Popen(['umount', os.path.join(self.photon_root,
224
+                                                           "installer")],
196 225
                                    stdout=self.output)
197 226
         retval = process.wait()
198
-        # The function finalize_system will access the file /installer/mk-finalize-system.sh
199
-        # after chroot to photon_root.
200
-        # Bind the /installer folder to self.photon_root/installer, so that after chroot
201
-        # to photon_root,
202
-        # the file can still be accessed as /installer/mk-finalize-system.sh.
203
-        process = subprocess.Popen(['mount', '--bind', '/installer',
204
-                                    os.path.join(self.photon_root, "installer")],
227
+        if retval != 0:
228
+            modules.commons.log(modules.commons.LOG_ERROR,
229
+                                "Fail to unbind the installer directory")
230
+        # remove the installer directory
231
+        process = subprocess.Popen(['rm', '-rf', os.path.join(self.photon_root, "installer")],
205 232
                                    stdout=self.output)
206 233
         retval = process.wait()
207
-
208
-    def bind_repo_dir(self):
234
+        if retval != 0:
235
+            modules.commons.log(modules.commons.LOG_ERROR,
236
+                                "Fail to remove the installer directory")
237
+    def _bind_repo_dir(self):
238
+        """
239
+        Bind repo dir for tdnf installation
240
+        """
209 241
         rpm_cache_dir = self.photon_root + '/cache/tdnf/photon-iso/rpms'
210 242
         if self.rpm_path.startswith("https://") or self.rpm_path.startswith("http://"):
211 243
             return
... ...
@@ -213,7 +218,11 @@ class Installer(object):
213 213
                 subprocess.call(['mount', '--bind', self.rpm_path, rpm_cache_dir]) != 0):
214 214
             modules.commons.log(modules.commons.LOG_ERROR, "Fail to bind cache rpms")
215 215
             self.exit_gracefully(None, None)
216
-    def unbind_repo_dir(self):
216
+
217
+    def _unbind_repo_dir(self):
218
+        """
219
+        Unbind repo dir after installation
220
+        """
217 221
         rpm_cache_dir = self.photon_root + '/cache/tdnf/photon-iso/rpms'
218 222
         if self.rpm_path.startswith("https://") or self.rpm_path.startswith("http://"):
219 223
             return
... ...
@@ -222,7 +231,10 @@ class Installer(object):
222 222
             modules.commons.log(modules.commons.LOG_ERROR, "Fail to unbind cache rpms")
223 223
             self.exit_gracefully(None, None)
224 224
 
225
-    def update_fstab(self):
225
+    def _update_fstab(self):
226
+        """
227
+        update fstab
228
+        """
226 229
         with open(os.path.join(self.photon_root, "etc/fstab"), "w") as fstab_file:
227 230
             fstab_file.write("#system\tmnt-pt\ttype\toptions\tdump\tfsck\n")
228 231
 
... ...
@@ -253,7 +265,10 @@ class Installer(object):
253 253
             # Add the cdrom entry
254 254
             fstab_file.write("/dev/cdrom\t/mnt/cdrom\tiso9660\tro,noauto\t0\t0\n")
255 255
 
256
-    def generate_partitions_param(self, reverse=False):
256
+    def _generate_partitions_param(self, reverse=False):
257
+        """
258
+        Generate partition param for mount command
259
+        """
257 260
         if reverse:
258 261
             step = -1
259 262
         else:
... ...
@@ -266,84 +281,128 @@ class Installer(object):
266 266
             params.extend(['--partitionmountpoint', partition["path"], partition["mountpoint"]])
267 267
         return params
268 268
 
269
-    def initialize_system(self):
269
+    def _initialize_system(self):
270
+        """
271
+        Prepare the system to install photon
272
+        """
270 273
         #Setup the disk
271 274
         if not self.install_config['iso_system']:
272
-            command = [self.mount_command, '-w', self.photon_root]
273
-            command.extend(self.generate_partitions_param())
275
+            command = [Installer.mount_command, '-w', self.photon_root]
276
+            command.extend(self._generate_partitions_param())
274 277
             process = subprocess.Popen(command, stdout=self.output)
275 278
             retval = process.wait()
279
+            if retval != 0:
280
+                modules.commons.log(modules.commons.LOG_INFO,
281
+                                    "Failed to setup the disk for installation")
282
+                self.exit_gracefully(None, None)
276 283
 
277
-        if self.iso_installer:
278
-            self.bind_installer()
279
-            self.bind_repo_dir()
280
-            process = subprocess.Popen([self.prepare_command, '-w', self.photon_root, 'install'],
284
+        if self.install_config['iso_installer']:
285
+            self._bind_installer()
286
+            self._bind_repo_dir()
287
+            process = subprocess.Popen([Installer.prepare_command, '-w',
288
+                                        self.photon_root, 'install'],
281 289
                                        stdout=self.output)
282 290
             retval = process.wait()
291
+            if retval != 0:
292
+                modules.commons.log(modules.commons.LOG_INFO,
293
+                                    "Failed to bind the installer and repo needed by tdnf")
294
+                self.exit_gracefully(None, None)
283 295
         else:
284
-            self.copy_files()
296
+            self._copy_files()
285 297
             #Setup the filesystem basics
286
-            process = subprocess.Popen([self.prepare_command, '-w', self.photon_root],
298
+            process = subprocess.Popen([Installer.prepare_command, '-w', self.photon_root],
287 299
                                        stdout=self.output)
288 300
             retval = process.wait()
301
+            if retval != 0:
302
+                modules.commons.log(modules.commons.LOG_INFO,
303
+                                    "Failed to setup the file systems basics")
304
+                self.exit_gracefully(None, None)
289 305
 
290
-    def finalize_system(self):
306
+    def _finalize_system(self):
307
+        """
308
+        Finalize the system after the installation
309
+        """
291 310
         #Setup the disk
292
-        process = subprocess.Popen([self.chroot_command, '-w', self.photon_root,
293
-                                    self.finalize_command, '-w', self.photon_root],
311
+        process = subprocess.Popen([Installer.chroot_command, '-w', self.photon_root,
312
+                                    Installer.finalize_command, '-w', self.photon_root],
294 313
                                    stdout=self.output)
295 314
         retval = process.wait()
296
-        if self.iso_installer:
315
+        if retval != 0:
316
+            modules.commons.log(modules.commons.LOG_ERROR,
317
+                                "Fail to setup th target system after the installation")
318
+
319
+        if self.install_config['iso_installer']:
297 320
 
298 321
             modules.commons.dump(modules.commons.LOG_FILE_NAME)
299 322
             shutil.copy(modules.commons.LOG_FILE_NAME, self.photon_root + '/var/log/')
300 323
             shutil.copy(modules.commons.TDNF_LOG_FILE_NAME, self.photon_root +
301 324
                         '/var/log/')
302 325
 
303
-            # unmount the installer directory
304
-            process = subprocess.Popen(['umount', os.path.join(self.photon_root,
305
-                                                               "installer")],
306
-                                       stdout=self.output)
307
-            retval = process.wait()
308
-            # remove the installer directory
309
-            process = subprocess.Popen(['rm', '-rf', os.path.join(self.photon_root, "installer")],
310
-                                       stdout=self.output)
311
-            retval = process.wait()
312
-            self.unbind_repo_dir()
326
+            self._unbind_installer()
327
+            self._unbind_repo_dir()
313 328
             # Disable the swap file
314 329
             process = subprocess.Popen(['swapoff', '-a'], stdout=self.output)
315 330
             retval = process.wait()
331
+            if retval != 0:
332
+                modules.commons.log(modules.commons.LOG_ERROR,
333
+                                    "Fail to swapoff")
316 334
             # remove the tdnf cache directory and the swapfile.
317 335
             process = subprocess.Popen(['rm', '-rf', os.path.join(self.photon_root, "cache")],
318 336
                                        stdout=self.output)
319 337
             retval = process.wait()
338
+            if retval != 0:
339
+                modules.commons.log(modules.commons.LOG_ERROR,
340
+                                    "Fail to remove the cache")
341
+        if not self.install_config['iso_system']:
342
+            # Execute post installation modules
343
+            self._execute_modules(modules.commons.POST_INSTALL)
344
+            if os.path.exists(modules.commons.KS_POST_INSTALL_LOG_FILE_NAME):
345
+                shutil.copy(modules.commons.KS_POST_INSTALL_LOG_FILE_NAME,
346
+                            self.photon_root + '/var/log/')
320 347
 
321
-    def install_package(self, rpm_file_names):
322
-
323
-        rpms = set(rpm_file_names)
324
-        rpm_paths = []
325
-        for root, _, files in os.walk(self.rpm_path):
326
-            for f in files:
327
-                if f in rpms:
328
-                    rpm_paths.append(os.path.join(root, f))
329
-
330
-        # --nodeps is for hosts which do not support rich dependencies
331
-        rpm_params = ['--nodeps', '--root', self.photon_root, '--dbpath',
332
-                      '/var/lib/rpm']
348
+            if self.install_config['iso_installer'] and os.path.isdir("/sys/firmware/efi"):
349
+                self.install_config['boot'] = 'efi'
350
+            # install grub
351
+            if 'boot_partition_number' not in self.install_config['disk']:
352
+                self.install_config['disk']['boot_partition_number'] = 1
333 353
 
334
-        if (('type' in self.install_config and
335
-             (self.install_config['type'] in ['micro', 'minimal'])) or
336
-                self.install_config['iso_system']):
337
-            rpm_params.append('--excludedocs')
354
+            try:
355
+                if self.install_config['boot'] == 'bios':
356
+                    process = subprocess.Popen(
357
+                        [Installer.setup_grub_command, '-w', self.photon_root,
358
+                         "bios", self.install_config['disk']['disk'],
359
+                         self.install_config['disk']['root'],
360
+                         self.install_config['disk']['boot'],
361
+                         self.install_config['disk']['bootdirectory'],
362
+                         str(self.install_config['disk']['boot_partition_number'])],
363
+                        stdout=self.output)
364
+                elif self.install_config['boot'] == 'efi':
365
+                    process = subprocess.Popen(
366
+                        [Installer.setup_grub_command, '-w', self.photon_root,
367
+                         "efi", self.install_config['disk']['disk'],
368
+                         self.install_config['disk']['root'],
369
+                         self.install_config['disk']['boot'],
370
+                         self.install_config['disk']['bootdirectory'],
371
+                         str(self.install_config['disk']['boot_partition_number'])],
372
+                        stdout=self.output)
373
+            except:
374
+                #install bios if variable is not set.
375
+                process = subprocess.Popen(
376
+                    [Installer.setup_grub_command, '-w', self.photon_root,
377
+                     "bios", self.install_config['disk']['disk'],
378
+                     self.install_config['disk']['root'],
379
+                     self.install_config['disk']['boot'],
380
+                     self.install_config['disk']['bootdirectory'],
381
+                     str(self.install_config['disk']['boot_partition_number'])],
382
+                    stdout=self.output)
383
+            retval = process.wait()
338 384
 
339
-        modules.commons.log(modules.commons.LOG_INFO,
340
-                            "installing packages {0}, with params {1}"
341
-                            .format(rpm_paths, rpm_params))
342
-        process = subprocess.Popen(['rpm', '-Uvh'] + rpm_params + rpm_paths,
343
-                                   stderr=subprocess.STDOUT)
344
-        return process.wait()
385
+            self._update_fstab()
345 386
 
346
-    def execute_modules(self, phase):
387
+    def _execute_modules(self, phase):
388
+        """
389
+        Execute the scripts in the modules folder
390
+        """
347 391
         sys.path.append("./modules")
348 392
         modules_paths = glob.glob('modules/m_*.py')
349 393
         for mod_path in modules_paths:
... ...
@@ -378,7 +437,10 @@ class Installer(object):
378 378
 
379 379
             mod.execute(self.install_config, self.photon_root)
380 380
 
381
-    def adjust_packages_for_vmware_virt(self):
381
+    def _adjust_packages_for_vmware_virt(self):
382
+        """
383
+        Install linux_esx on Vmware virtual machine if requested
384
+        """
382 385
         try:
383 386
             if self.install_config['install_linux_esx']:
384 387
                 selected_packages = self.install_config['packages']
... ...
@@ -394,14 +456,17 @@ class Installer(object):
394 394
         except KeyError:
395 395
             pass
396 396
 
397
-    def setup_install_repo(self):
398
-        if self.iso_installer:
397
+    def _setup_install_repo(self):
398
+        """
399
+        Setup the tdnf repo for installation
400
+        """
401
+        if self.install_config['iso_installer']:
399 402
             self.window.show_window()
400 403
             self.progress_bar.initialize('Initializing installation...')
401 404
             self.progress_bar.show()
402 405
             #self.rpm_path = "https://dl.bintray.com/vmware/photon_release_1.0_TP2_x86_64"
403 406
             if self.rpm_path.startswith("https://") or self.rpm_path.startswith("http://"):
404
-                cmdoption = 's/baseurl.*/baseurl={}/g'.format(self.rpm_path.replace('/', '\/'))
407
+                cmdoption = 's/baseurl.*/baseurl={}/g'.format(self.rpm_path.replace('/', r'\/'))
405 408
                 process = subprocess.Popen(['sed', '-i', cmdoption,
406 409
                                             '/etc/yum.repos.d/photon-iso.repo'])
407 410
                 retval = process.wait()
... ...
@@ -409,31 +474,28 @@ class Installer(object):
409 409
                     modules.commons.log(modules.commons.LOG_INFO, "Failed to reset repo")
410 410
                     self.exit_gracefully(None, None)
411 411
 
412
-            cmdoption = ('s/cachedir=\/var/cachedir={}/g'
413
-                         .format(self.photon_root.replace('/', '\/')))
412
+            cmdoption = (r's/cachedir=\/var/cachedir={}/g'
413
+                         .format(self.photon_root.replace('/', r'\/')))
414 414
             process = subprocess.Popen(['sed', '-i', cmdoption, '/etc/tdnf/tdnf.conf'])
415 415
             retval = process.wait()
416 416
             if retval != 0:
417 417
                 modules.commons.log(modules.commons.LOG_INFO, "Failed to reset tdnf cachedir")
418 418
                 self.exit_gracefully(None, None)
419 419
 
420
-    def install_packages(self):
421
-        if self.iso_installer:
422
-            self.tdnf_install_packages()
420
+    def _install_packages(self):
421
+        """
422
+        Install packages using tdnf or rpm command
423
+        """
424
+        if self.install_config['iso_installer']:
425
+            self._tdnf_install_packages()
423 426
         else:
424
-        #install packages
425
-            rpms = []
426
-            for rpm in self.rpms_tobeinstalled:
427
-                # We already installed the filesystem in the preparation
428
-                if rpm['package'] == 'filesystem':
429
-                    continue
430
-                rpms.append(rpm['filename'])
431
-            return_value = self.install_package(rpms)
432
-            if return_value != 0:
433
-                self.exit_gracefully(None, None)
427
+            self._rpm_install_packages()
434 428
 
435
-    def tdnf_install_packages(self):
436
-        self.adjust_packages_for_vmware_virt()
429
+    def _tdnf_install_packages(self):
430
+        """
431
+        Install packages using tdnf command
432
+        """
433
+        self._adjust_packages_for_vmware_virt()
437 434
         selected_packages = self.install_config['packages']
438 435
         state = 0
439 436
         packages_to_install = {}
... ...
@@ -488,7 +550,46 @@ class Installer(object):
488 488
                 self.exit_gracefully(None, None)
489 489
         self.progress_bar.show_loading('Finalizing installation')
490 490
 
491
-    def eject_cdrom(self):
491
+    def _rpm_install_packages(self):
492
+        """
493
+        Install packages using rpm command
494
+        """
495
+        rpms = []
496
+        for rpm in self.rpms_tobeinstalled:
497
+            # We already installed the filesystem in the preparation
498
+            if rpm['package'] == 'filesystem':
499
+                continue
500
+            rpms.append(rpm['filename'])
501
+        rpms = set(rpms)
502
+        rpm_paths = []
503
+        for root, _, files in os.walk(self.rpm_path):
504
+            for file in files:
505
+                if file in rpms:
506
+                    rpm_paths.append(os.path.join(root, file))
507
+
508
+        # --nodeps is for hosts which do not support rich dependencies
509
+        rpm_params = ['--nodeps', '--root', self.photon_root, '--dbpath',
510
+                      '/var/lib/rpm']
511
+
512
+        if (('type' in self.install_config and
513
+             (self.install_config['type'] in ['micro', 'minimal'])) or
514
+                self.install_config['iso_system']):
515
+            rpm_params.append('--excludedocs')
516
+
517
+        modules.commons.log(modules.commons.LOG_INFO,
518
+                            "installing packages {0}, with params {1}"
519
+                            .format(rpm_paths, rpm_params))
520
+        process = subprocess.Popen(['rpm', '-Uvh'] + rpm_params + rpm_paths,
521
+                                   stderr=subprocess.STDOUT)
522
+        return_value = process.wait()
523
+        if return_value != 0:
524
+            self.exit_gracefully(None, None)
525
+
526
+
527
+    def _eject_cdrom(self):
528
+        """
529
+        Eject the cdrom on request
530
+        """
492 531
         eject_cdrom = True
493 532
         if 'ui_install' in self.install_config:
494 533
             self.window.content_window().getch()
... ...
@@ -498,10 +599,16 @@ class Installer(object):
498 498
             process = subprocess.Popen(['eject', '-r'], stdout=self.output)
499 499
             process.wait()
500 500
 
501
-    def enable_network_in_chroot(self):
501
+    def _enable_network_in_chroot(self):
502
+        """
503
+        Enable network in chroot
504
+        """
502 505
         if os.path.exists("/etc/resolv.conf"):
503 506
             shutil.copy("/etc/resolv.conf", self.photon_root + '/etc/.')
504 507
 
505
-    def disable_network_in_chroot(self):
508
+    def _disable_network_in_chroot(self):
509
+        """
510
+        disable network in chroot
511
+        """
506 512
         if os.path.exists(self.photon_root + '/etc/resolv.conf'):
507 513
             os.remove(self.photon_root + '/etc/resolv.conf')