blob: 1029d1eb5e84bf4b6536843dee304453bda5c57a [file] [log] [blame]
lmr5d73e2f2009-10-09 20:46:36 +00001#!/usr/bin/python
2"""
3Simple script to setup unattended installs on KVM guests.
4"""
5# -*- coding: utf-8 -*-
Eric Li6f27d4f2010-09-29 10:55:17 -07006import os, sys, shutil, tempfile, re, ConfigParser, glob, inspect
lmr5d73e2f2009-10-09 20:46:36 +00007import common
8
9
Eric Li6f27d4f2010-09-29 10:55:17 -070010SCRIPT_DIR = os.path.dirname(sys.modules[__name__].__file__)
11KVM_TEST_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, ".."))
12
13
lmr5d73e2f2009-10-09 20:46:36 +000014class SetupError(Exception):
15 """
16 Simple wrapper for the builtin Exception class.
17 """
18 pass
19
20
Eric Li6f27d4f2010-09-29 10:55:17 -070021def find_command(cmd):
22 """
23 Searches for a command on common paths, error if it can't find it.
24
25 @param cmd: Command to be found.
26 """
27 for dir in ["/usr/local/sbin", "/usr/local/bin",
28 "/usr/sbin", "/usr/bin", "/sbin", "/bin"]:
29 file = os.path.join(dir, cmd)
30 if os.path.exists(file):
31 return file
32 raise ValueError('Missing command: %s' % cmd)
33
34
35def run(cmd, info=None):
36 """
37 Run a command and throw an exception if it fails.
38 Optionally, you can provide additional contextual info.
39
40 @param cmd: Command string.
41 @param reason: Optional string that explains the context of the failure.
42
43 @raise: SetupError if command fails.
44 """
45 print "Running '%s'" % cmd
46 cmd_name = cmd.split(' ')[0]
47 find_command(cmd_name)
48 if os.system(cmd):
49 e_msg = 'Command failed: %s' % cmd
50 if info is not None:
51 e_msg += '. %s' % info
52 raise SetupError(e_msg)
53
54
55def cleanup(dir):
56 """
57 If dir is a mountpoint, do what is possible to unmount it. Afterwards,
58 try to remove it.
59
60 @param dir: Directory to be cleaned up.
61 """
62 print "Cleaning up directory %s" % dir
63 if os.path.ismount(dir):
64 os.system('fuser -k %s' % dir)
65 run('umount %s' % dir, info='Could not unmount %s' % dir)
66 if os.path.isdir(dir):
67 shutil.rmtree(dir)
68
69
70def clean_old_image(image):
71 """
72 Clean a leftover image file from previous processes. If it contains a
73 mounted file system, do the proper cleanup procedures.
74
75 @param image: Path to image to be cleaned up.
76 """
77 if os.path.exists(image):
78 mtab = open('/etc/mtab', 'r')
79 mtab_contents = mtab.read()
80 mtab.close()
81 if image in mtab_contents:
82 os.system('fuser -k %s' % image)
83 os.system('umount %s' % image)
84 os.remove(image)
85
86
87class Disk(object):
88 """
89 Abstract class for Disk objects, with the common methods implemented.
90 """
91 def __init__(self):
92 self.path = None
93
94
95 def setup_answer_file(self, filename, contents):
96 answer_file = open(os.path.join(self.mount, filename), 'w')
97 answer_file.write(contents)
98 answer_file.close()
99
100
101 def copy_to(self, src):
102 dst = os.path.join(self.mount, os.path.basename(src))
103 if os.path.isdir(src):
104 shutil.copytree(src, dst)
105 elif os.path.isfile(src):
106 shutil.copyfile(src, dst)
107
108
109 def close(self):
110 os.chmod(self.path, 0755)
111 cleanup(self.mount)
112 print "Disk %s successfuly set" % self.path
113
114
115class FloppyDisk(Disk):
116 """
117 Represents a 1.44 MB floppy disk. We can copy files to it, and setup it in
118 convenient ways.
119 """
120 def __init__(self, path):
121 print "Creating floppy unattended image %s" % path
122 try:
123 qemu_img_binary = os.environ['KVM_TEST_qemu_img_binary']
124 except KeyError:
125 qemu_img_binary = os.path.join(KVM_TEST_DIR, qemu_img_binary)
126 if not os.path.exists(qemu_img_binary):
127 raise SetupError('The qemu-img binary that is supposed to be used '
128 '(%s) does not exist. Please verify your '
129 'configuration' % qemu_img_binary)
130
131 self.mount = tempfile.mkdtemp(prefix='floppy_', dir='/tmp')
132 self.virtio_mount = None
133 self.path = path
134 clean_old_image(path)
135 if not os.path.isdir(os.path.dirname(path)):
136 os.makedirs(os.path.dirname(path))
137
138 try:
139 c_cmd = '%s create -f raw %s 1440k' % (qemu_img_binary, path)
140 run(c_cmd, info='Could not create floppy image')
141 f_cmd = 'mkfs.msdos -s 1 %s' % path
142 run(f_cmd, info='Error formatting floppy image')
143 m_cmd = 'mount -o loop,rw %s %s' % (path, self.mount)
144 run(m_cmd, info='Could not mount floppy image')
145 except:
146 cleanup(self.mount)
147
148
149 def _copy_virtio_drivers(self, virtio_floppy):
150 """
151 Copy the virtio drivers on the virtio floppy to the install floppy.
152
153 1) Mount the floppy containing the viostor drivers
154 2) Copy its contents to the root of the install floppy
155 """
156 virtio_mount = tempfile.mkdtemp(prefix='virtio_floppy_', dir='/tmp')
157
158 pwd = os.getcwd()
159 try:
160 m_cmd = 'mount -o loop %s %s' % (virtio_floppy, virtio_mount)
161 run(m_cmd, info='Could not mount virtio floppy driver')
162 os.chdir(virtio_mount)
163 path_list = glob.glob('*')
164 for path in path_list:
165 self.copy_to(path)
166 finally:
167 os.chdir(pwd)
168 cleanup(virtio_mount)
169
170
171 def setup_virtio_win2003(self, virtio_floppy, virtio_oemsetup_id):
172 """
173 Setup the install floppy with the virtio storage drivers, win2003 style.
174
175 Win2003 and WinXP depend on the file txtsetup.oem file to install
176 the virtio drivers from the floppy, which is a .ini file.
177 Process:
178
179 1) Copy the virtio drivers on the virtio floppy to the install floppy
180 2) Parse the ini file with config parser
181 3) Modify the identifier of the default session that is going to be
182 executed on the config parser object
183 4) Re-write the config file to the disk
184 """
185 self._copy_virtio_drivers(virtio_floppy)
186 txtsetup_oem = os.path.join(self.mount, 'txtsetup.oem')
187 if not os.path.isfile(txtsetup_oem):
188 raise SetupError('File txtsetup.oem not found on the install '
189 'floppy. Please verify if your floppy virtio '
190 'driver image has this file')
191 parser = ConfigParser.ConfigParser()
192 parser.read(txtsetup_oem)
193 if not parser.has_section('Defaults'):
194 raise SetupError('File txtsetup.oem does not have the session '
195 '"Defaults". Please check txtsetup.oem')
196 default_driver = parser.get('Defaults', 'SCSI')
197 if default_driver != virtio_oemsetup_id:
198 parser.set('Defaults', 'SCSI', virtio_oemsetup_id)
199 fp = open(txtsetup_oem, 'w')
200 parser.write(fp)
201 fp.close()
202
203
204 def setup_virtio_win2008(self, virtio_floppy):
205 """
206 Setup the install floppy with the virtio storage drivers, win2008 style.
207
208 Win2008, Vista and 7 require people to point out the path to the drivers
209 on the unattended file, so we just need to copy the drivers to the
210 driver floppy disk.
211 Process:
212
213 1) Copy the virtio drivers on the virtio floppy to the install floppy
214 """
215 self._copy_virtio_drivers(virtio_floppy)
216
217
218class CdromDisk(Disk):
219 """
220 Represents a CDROM disk that we can master according to our needs.
221 """
222 def __init__(self, path):
223 print "Creating ISO unattended image %s" % path
224 self.mount = tempfile.mkdtemp(prefix='cdrom_unattended_', dir='/tmp')
225 self.path = path
226 clean_old_image(path)
227 if not os.path.isdir(os.path.dirname(path)):
228 os.makedirs(os.path.dirname(path))
229
230
231 def close(self):
232 g_cmd = ('mkisofs -o %s -max-iso9660-filenames '
233 '-relaxed-filenames -D --input-charset iso8859-1 '
234 '%s' % (self.path, self.mount))
235 run(g_cmd, info='Could not generate iso with answer file')
236
237 os.chmod(self.path, 0755)
238 cleanup(self.mount)
239 print "Disk %s successfuly set" % self.path
240
241
lmr5d73e2f2009-10-09 20:46:36 +0000242class UnattendedInstall(object):
243 """
244 Creates a floppy disk image that will contain a config file for unattended
245 OS install. Optionally, sets up a PXE install server using qemu built in
246 TFTP and DHCP servers to install a particular operating system. The
247 parameters to the script are retrieved from environment variables.
248 """
249 def __init__(self):
250 """
251 Gets params from environment variables and sets class attributes.
252 """
Eric Li6f27d4f2010-09-29 10:55:17 -0700253 images_dir = os.path.join(KVM_TEST_DIR, 'images')
254 self.deps_dir = os.path.join(KVM_TEST_DIR, 'deps')
255 self.unattended_dir = os.path.join(KVM_TEST_DIR, 'unattended')
lmr5d73e2f2009-10-09 20:46:36 +0000256
Eric Li6f27d4f2010-09-29 10:55:17 -0700257 attributes = ['kernel_args', 'finish_program', 'cdrom_cd1',
258 'unattended_file', 'medium', 'url', 'kernel', 'initrd',
259 'nfs_server', 'nfs_dir', 'pxe_dir', 'pxe_image',
260 'pxe_initrd', 'install_virtio', 'tftp',
261 'floppy', 'cdrom_unattended']
262 for a in attributes:
263 self._setattr(a)
lmr5d73e2f2009-10-09 20:46:36 +0000264
Eric Li6f27d4f2010-09-29 10:55:17 -0700265 if self.install_virtio == 'yes':
266 v_attributes = ['virtio_floppy', 'virtio_storage_path',
267 'virtio_network_path', 'virtio_oemsetup_id',
268 'virtio_network_installer']
269 for va in v_attributes:
270 self._setattr(va)
lmr5d73e2f2009-10-09 20:46:36 +0000271
Eric Li6f27d4f2010-09-29 10:55:17 -0700272 # Silly attribution just to calm pylint down...
273 self.tftp = self.tftp
274 if self.tftp:
275 self.tftp = os.path.join(KVM_TEST_DIR, self.tftp)
276 if not os.path.isdir(self.tftp):
277 os.makedirs(self.tftp)
lmra29a5cb2010-03-18 02:39:34 +0000278
Eric Lie0493a42010-11-15 13:05:43 -0800279 if self.cdrom_cd1:
280 self.cdrom_cd1 = os.path.join(KVM_TEST_DIR, self.cdrom_cd1)
Eric Li6f27d4f2010-09-29 10:55:17 -0700281 self.cdrom_cd1_mount = tempfile.mkdtemp(prefix='cdrom_cd1_', dir='/tmp')
282 if self.medium == 'nfs':
283 self.nfs_mount = tempfile.mkdtemp(prefix='nfs_', dir='/tmp')
lmr5d73e2f2009-10-09 20:46:36 +0000284
Eric Lie0493a42010-11-15 13:05:43 -0800285 if self.floppy:
286 self.floppy = os.path.join(KVM_TEST_DIR, self.floppy)
287 if not os.path.isdir(os.path.dirname(self.floppy)):
288 os.makedirs(os.path.dirname(self.floppy))
Eric Li6f27d4f2010-09-29 10:55:17 -0700289
290 self.image_path = KVM_TEST_DIR
lmree1e40f2010-06-10 15:32:27 +0000291 self.kernel_path = os.path.join(self.image_path, self.kernel)
292 self.initrd_path = os.path.join(self.image_path, self.initrd)
293
lmr5d73e2f2009-10-09 20:46:36 +0000294
Eric Li6f27d4f2010-09-29 10:55:17 -0700295 def _setattr(self, key):
lmr5d73e2f2009-10-09 20:46:36 +0000296 """
Eric Li6f27d4f2010-09-29 10:55:17 -0700297 Populate class attributes with contents of environment variables.
298
299 Example: KVM_TEST_medium will populate self.medium.
300
301 @param key: Name of the class attribute we desire to have.
lmr5d73e2f2009-10-09 20:46:36 +0000302 """
Eric Li6f27d4f2010-09-29 10:55:17 -0700303 env_name = 'KVM_TEST_%s' % key
304 value = os.environ.get(env_name, '')
305 setattr(self, key, value)
lmr5d73e2f2009-10-09 20:46:36 +0000306
lmr5d73e2f2009-10-09 20:46:36 +0000307
Eric Li6f27d4f2010-09-29 10:55:17 -0700308 def render_answer_file(self):
309 # Replace KVM_TEST_CDKEY (in the unattended file) with the cdkey
310 # provided for this test and replace the KVM_TEST_MEDIUM with
311 # the tree url or nfs address provided for this test.
312 unattended_contents = open(self.unattended_file).read()
313 dummy_cdkey_re = r'\bKVM_TEST_CDKEY\b'
314 real_cdkey = os.environ.get('KVM_TEST_cdkey')
315 if re.search(dummy_cdkey_re, unattended_contents):
316 if real_cdkey:
317 unattended_contents = re.sub(dummy_cdkey_re, real_cdkey,
318 unattended_contents)
Eric Li25fc6d12010-09-28 17:22:51 -0700319 else:
Eric Li6f27d4f2010-09-29 10:55:17 -0700320 print ("WARNING: 'cdkey' required but not specified for "
321 "this unattended installation")
Eric Li25fc6d12010-09-28 17:22:51 -0700322
Eric Li6f27d4f2010-09-29 10:55:17 -0700323 dummy_medium_re = r'\bKVM_TEST_MEDIUM\b'
324 if self.medium == "cdrom":
325 content = "cdrom"
326 elif self.medium == "url":
327 content = "url --url %s" % self.url
328 elif self.medium == "nfs":
329 content = "nfs --server=%s --dir=%s" % (self.nfs_server,
330 self.nfs_dir)
331 else:
332 raise SetupError("Unexpected installation medium %s" % self.url)
Eric Li25fc6d12010-09-28 17:22:51 -0700333
Eric Li6f27d4f2010-09-29 10:55:17 -0700334 unattended_contents = re.sub(dummy_medium_re, content,
335 unattended_contents)
Benson Leung517d95a2010-09-28 18:00:17 -0700336
Eric Li6f27d4f2010-09-29 10:55:17 -0700337 def replace_virtio_key(contents, dummy_re, env):
338 """
339 Replace a virtio dummy string with contents.
Benson Leung517d95a2010-09-28 18:00:17 -0700340
Eric Li6f27d4f2010-09-29 10:55:17 -0700341 If install_virtio is not set, replace it with a dummy string.
Benson Leung517d95a2010-09-28 18:00:17 -0700342
Eric Li6f27d4f2010-09-29 10:55:17 -0700343 @param contents: Contents of the unattended file
344 @param dummy_re: Regular expression used to search on the.
345 unattended file contents.
346 @param env: Name of the environment variable.
347 """
348 dummy_path = "C:"
349 driver = os.environ.get(env, '')
Benson Leung517d95a2010-09-28 18:00:17 -0700350
Eric Li6f27d4f2010-09-29 10:55:17 -0700351 if re.search(dummy_re, contents):
352 if self.install_virtio == "yes":
353 if driver.endswith("msi"):
354 driver = 'msiexec /passive /package ' + driver
355 else:
356 try:
357 # Let's escape windows style paths properly
358 drive, path = driver.split(":")
359 driver = drive + ":" + re.escape(path)
360 except:
361 pass
362 contents = re.sub(dummy_re, driver, contents)
363 else:
364 contents = re.sub(dummy_re, dummy_path, contents)
365 return contents
366
367 vdict = {r'\bKVM_TEST_STORAGE_DRIVER_PATH\b':
368 'KVM_TEST_virtio_storage_path',
369 r'\bKVM_TEST_NETWORK_DRIVER_PATH\b':
370 'KVM_TEST_virtio_network_path',
371 r'\bKVM_TEST_VIRTIO_NETWORK_INSTALLER\b':
372 'KVM_TEST_virtio_network_installer_path'}
373
374 for vkey in vdict:
375 unattended_contents = replace_virtio_key(unattended_contents,
376 vkey, vdict[vkey])
377
378 print "Unattended install contents:"
379 print unattended_contents
380 return unattended_contents
381
382
383 def setup_boot_disk(self):
384 answer_contents = self.render_answer_file()
385
386 if self.unattended_file.endswith('.sif'):
387 dest_fname = 'winnt.sif'
388 setup_file = 'winnt.bat'
389 boot_disk = FloppyDisk(self.floppy)
390 boot_disk.setup_answer_file(dest_fname, answer_contents)
391 setup_file_path = os.path.join(self.unattended_dir, setup_file)
392 boot_disk.copy_to(setup_file_path)
393 if self.install_virtio == "yes":
394 boot_disk.setup_virtio_win2003(self.virtio_floppy,
395 self.virtio_oemsetup_id)
396 boot_disk.copy_to(self.finish_program)
397
398 elif self.unattended_file.endswith('.ks'):
399 # Red Hat kickstart install
400 dest_fname = 'ks.cfg'
401 if self.cdrom_unattended:
402 boot_disk = CdromDisk(self.cdrom_unattended)
403 elif self.floppy:
404 boot_disk = FloppyDisk(self.floppy)
405 else:
406 raise SetupError("Neither cdrom_unattended nor floppy set "
407 "on the config file, please verify")
408 boot_disk.setup_answer_file(dest_fname, answer_contents)
409
410 elif self.unattended_file.endswith('.xml'):
411 if self.tftp:
412 # SUSE autoyast install
413 dest_fname = "autoinst.xml"
414 if self.cdrom_unattended:
415 boot_disk = CdromDisk(self.cdrom_unattended)
416 elif self.floppy:
417 boot_disk = FloppyDisk(self.floppy)
418 else:
419 raise SetupError("Neither cdrom_unattended nor floppy set "
420 "on the config file, please verify")
421 boot_disk.setup_answer_file(dest_fname, answer_contents)
422
423 else:
424 # Windows unattended install
425 dest_fname = "autounattend.xml"
426 boot_disk = FloppyDisk(self.floppy)
427 boot_disk.setup_answer_file(dest_fname, answer_contents)
428 if self.install_virtio == "yes":
429 boot_disk.setup_virtio_win2008(self.virtio_floppy)
430 boot_disk.copy_to(self.finish_program)
431
432 else:
433 raise SetupError('Unknown answer file %s' %
434 self.unattended_file)
435
436 boot_disk.close()
lmr5d73e2f2009-10-09 20:46:36 +0000437
438
439 def setup_pxe_boot(self):
440 """
441 Sets up a PXE boot environment using the built in qemu TFTP server.
442 Copies the PXE Linux bootloader pxelinux.0 from the host (needs the
443 pxelinux package or equivalent for your distro), and vmlinuz and
444 initrd.img files from the CD to a directory that qemu will serve trough
445 TFTP to the VM.
446 """
Eric Li6f27d4f2010-09-29 10:55:17 -0700447 print "Setting up PXE boot using TFTP root %s" % self.tftp
lmr5d73e2f2009-10-09 20:46:36 +0000448
449 pxe_file = None
450 pxe_paths = ['/usr/lib/syslinux/pxelinux.0',
451 '/usr/share/syslinux/pxelinux.0']
452 for path in pxe_paths:
453 if os.path.isfile(path):
454 pxe_file = path
455 break
456
457 if not pxe_file:
458 raise SetupError('Cannot find PXE boot loader pxelinux.0. Make '
459 'sure pxelinux or equivalent package for your '
460 'distro is installed.')
461
Eric Li6f27d4f2010-09-29 10:55:17 -0700462 pxe_dest = os.path.join(self.tftp, 'pxelinux.0')
lmr5d73e2f2009-10-09 20:46:36 +0000463 shutil.copyfile(pxe_file, pxe_dest)
464
lmrb010c7e2010-02-24 11:54:30 +0000465 try:
Eric Li6f27d4f2010-09-29 10:55:17 -0700466 m_cmd = ('mount -t iso9660 -v -o loop,ro %s %s' %
467 (self.cdrom_cd1, self.cdrom_cd1_mount))
468 run(m_cmd, info='Could not mount CD image %s.' % self.cdrom_cd1)
lmr5d73e2f2009-10-09 20:46:36 +0000469
Eric Li6f27d4f2010-09-29 10:55:17 -0700470 pxe_dir = os.path.join(self.cdrom_cd1_mount, self.pxe_dir)
lmra29a5cb2010-03-18 02:39:34 +0000471 pxe_image = os.path.join(pxe_dir, self.pxe_image)
472 pxe_initrd = os.path.join(pxe_dir, self.pxe_initrd)
lmr5d73e2f2009-10-09 20:46:36 +0000473
lmrb010c7e2010-02-24 11:54:30 +0000474 if not os.path.isdir(pxe_dir):
475 raise SetupError('The ISO image does not have a %s dir. The '
476 'script assumes that the cd has a %s dir '
477 'where to search for the vmlinuz image.' %
lmra29a5cb2010-03-18 02:39:34 +0000478 (self.pxe_dir, self.pxe_dir))
lmr5d73e2f2009-10-09 20:46:36 +0000479
lmrb010c7e2010-02-24 11:54:30 +0000480 if not os.path.isfile(pxe_image) or not os.path.isfile(pxe_initrd):
481 raise SetupError('The location %s is lacking either a vmlinuz '
482 'or a initrd.img file. Cannot find a PXE '
lmra29a5cb2010-03-18 02:39:34 +0000483 'image to proceed.' % self.pxe_dir)
lmr5d73e2f2009-10-09 20:46:36 +0000484
Eric Li6f27d4f2010-09-29 10:55:17 -0700485 tftp_image = os.path.join(self.tftp, 'vmlinuz')
486 tftp_initrd = os.path.join(self.tftp, 'initrd.img')
lmrb010c7e2010-02-24 11:54:30 +0000487 shutil.copyfile(pxe_image, tftp_image)
488 shutil.copyfile(pxe_initrd, tftp_initrd)
lmr5d73e2f2009-10-09 20:46:36 +0000489
lmrb010c7e2010-02-24 11:54:30 +0000490 finally:
Eric Li6f27d4f2010-09-29 10:55:17 -0700491 cleanup(self.cdrom_cd1_mount)
lmr5d73e2f2009-10-09 20:46:36 +0000492
Eric Li6f27d4f2010-09-29 10:55:17 -0700493 pxe_config_dir = os.path.join(self.tftp, 'pxelinux.cfg')
lmr5d73e2f2009-10-09 20:46:36 +0000494 if not os.path.isdir(pxe_config_dir):
495 os.makedirs(pxe_config_dir)
496 pxe_config_path = os.path.join(pxe_config_dir, 'default')
497
498 pxe_config = open(pxe_config_path, 'w')
499 pxe_config.write('DEFAULT pxeboot\n')
500 pxe_config.write('TIMEOUT 20\n')
501 pxe_config.write('PROMPT 0\n')
502 pxe_config.write('LABEL pxeboot\n')
503 pxe_config.write(' KERNEL vmlinuz\n')
lmr5d73e2f2009-10-09 20:46:36 +0000504 pxe_config.write(' APPEND initrd=initrd.img %s\n' %
505 self.kernel_args)
506 pxe_config.close()
507
508 print "PXE boot successfuly set"
509
lmrb010c7e2010-02-24 11:54:30 +0000510
lmree1e40f2010-06-10 15:32:27 +0000511 def setup_url(self):
512 """
Eric Li6f27d4f2010-09-29 10:55:17 -0700513 Download the vmlinuz and initrd.img from URL.
lmree1e40f2010-06-10 15:32:27 +0000514 """
515 print "Downloading the vmlinuz and initrd.img"
516 os.chdir(self.image_path)
517
518 kernel_fetch_cmd = "wget -q %s/isolinux/%s" % (self.url, self.kernel)
519 initrd_fetch_cmd = "wget -q %s/isolinux/%s" % (self.url, self.initrd)
520
521 if os.path.exists(self.kernel):
522 os.unlink(self.kernel)
523 if os.path.exists(self.initrd):
524 os.unlink(self.initrd)
525
Eric Li6f27d4f2010-09-29 10:55:17 -0700526 run(kernel_fetch_cmd, info="Could not fetch vmlinuz from %s" % self.url)
527 run(initrd_fetch_cmd, info=("Could not fetch initrd.img from %s" %
528 self.url))
529 print "Download of vmlinuz and initrd.img finished"
lmree1e40f2010-06-10 15:32:27 +0000530
lmree1e40f2010-06-10 15:32:27 +0000531
532 def setup_nfs(self):
533 """
534 Copy the vmlinuz and initrd.img from nfs.
535 """
536 print "Copying the vmlinuz and initrd.img from nfs"
537
Eric Li6f27d4f2010-09-29 10:55:17 -0700538 m_cmd = ("mount %s:%s %s -o ro" %
539 (self.nfs_server, self.nfs_dir, self.nfs_mount))
540 run(m_cmd, info='Could not mount nfs server')
lmree1e40f2010-06-10 15:32:27 +0000541
542 try:
Eric Li6f27d4f2010-09-29 10:55:17 -0700543 kernel_fetch_cmd = ("cp %s/isolinux/%s %s" %
544 (self.nfs_mount, self.kernel, self.image_path))
545 run(kernel_fetch_cmd, info=("Could not copy the vmlinuz from %s" %
546 self.nfs_mount))
547 initrd_fetch_cmd = ("cp %s/isolinux/%s %s" %
548 (self.nfs_mount, self.initrd, self.image_path))
549 run(initrd_fetch_cmd, info=("Could not copy the initrd.img from "
550 "%s" % self.nfs_mount))
lmree1e40f2010-06-10 15:32:27 +0000551 finally:
Eric Li6f27d4f2010-09-29 10:55:17 -0700552 cleanup(self.nfs_mount)
lmr5d73e2f2009-10-09 20:46:36 +0000553
554
555 def setup(self):
Eric Li6f27d4f2010-09-29 10:55:17 -0700556 """
557 Configure the environment for unattended install.
558
559 Uses an appropriate strategy according to each install model.
560 """
lmr5d73e2f2009-10-09 20:46:36 +0000561 print "Starting unattended install setup"
Eric Li6f27d4f2010-09-29 10:55:17 -0700562 print
lmr5d73e2f2009-10-09 20:46:36 +0000563
564 print "Variables set:"
Eric Li6f27d4f2010-09-29 10:55:17 -0700565 for member in inspect.getmembers(self):
566 name, value = member
567 attribute = getattr(self, name)
568 if not (name.startswith("__") or callable(attribute) or not value):
569 print " %s: %s" % (name, value)
570 print
lmr5d73e2f2009-10-09 20:46:36 +0000571
Eric Li6f27d4f2010-09-29 10:55:17 -0700572 if self.unattended_file and (self.floppy or self.cdrom_unattended):
573 self.setup_boot_disk()
lmree1e40f2010-06-10 15:32:27 +0000574 if self.medium == "cdrom":
Eric Li6f27d4f2010-09-29 10:55:17 -0700575 if self.tftp:
lmree1e40f2010-06-10 15:32:27 +0000576 self.setup_pxe_boot()
577 elif self.medium == "url":
578 self.setup_url()
579 elif self.medium == "nfs":
580 self.setup_nfs()
581 else:
582 raise SetupError("Unexpected installation method %s" %
Eric Li6f27d4f2010-09-29 10:55:17 -0700583 self.medium)
lmr5d73e2f2009-10-09 20:46:36 +0000584 print "Unattended install setup finished successfuly"
585
586
587if __name__ == "__main__":
588 os_install = UnattendedInstall()
589 os_install.setup()