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>
... | ... |
@@ -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') |