blob: ba7d80b4df22324edb804d000317303eeabe8fd6 [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 Li25fc6d12010-09-28 17:22:51 -07006import os, sys, shutil, tempfile, re, ConfigParser, glob, inspect
lmr5d73e2f2009-10-09 20:46:36 +00007import common
8
9
Eric Li25fc6d12010-09-28 17:22:51 -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 Li25fc6d12010-09-28 17:22:51 -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 Li25fc6d12010-09-28 17:22:51 -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 Li25fc6d12010-09-28 17:22:51 -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 Li25fc6d12010-09-28 17:22:51 -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 Li25fc6d12010-09-28 17:22:51 -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 Li25fc6d12010-09-28 17:22:51 -0700279 self.cdrom_cd1 = os.path.join(KVM_TEST_DIR, self.cdrom_cd1)
280 self.cdrom_cd1_mount = tempfile.mkdtemp(prefix='cdrom_cd1_', dir='/tmp')
281 if self.medium == 'nfs':
282 self.nfs_mount = tempfile.mkdtemp(prefix='nfs_', dir='/tmp')
lmr5d73e2f2009-10-09 20:46:36 +0000283
Eric Li25fc6d12010-09-28 17:22:51 -0700284 self.floppy = os.path.join(KVM_TEST_DIR, self.floppy)
285 if not os.path.isdir(os.path.dirname(self.floppy)):
286 os.makedirs(os.path.dirname(self.floppy))
287
288 self.image_path = KVM_TEST_DIR
lmree1e40f2010-06-10 15:32:27 +0000289 self.kernel_path = os.path.join(self.image_path, self.kernel)
290 self.initrd_path = os.path.join(self.image_path, self.initrd)
291
lmr5d73e2f2009-10-09 20:46:36 +0000292
Eric Li25fc6d12010-09-28 17:22:51 -0700293 def _setattr(self, key):
lmr5d73e2f2009-10-09 20:46:36 +0000294 """
Eric Li25fc6d12010-09-28 17:22:51 -0700295 Populate class attributes with contents of environment variables.
296
297 Example: KVM_TEST_medium will populate self.medium.
298
299 @param key: Name of the class attribute we desire to have.
lmr5d73e2f2009-10-09 20:46:36 +0000300 """
Eric Li25fc6d12010-09-28 17:22:51 -0700301 env_name = 'KVM_TEST_%s' % key
302 value = os.environ.get(env_name, '')
303 setattr(self, key, value)
lmr5d73e2f2009-10-09 20:46:36 +0000304
lmr5d73e2f2009-10-09 20:46:36 +0000305
Eric Li25fc6d12010-09-28 17:22:51 -0700306 def render_answer_file(self):
307 # Replace KVM_TEST_CDKEY (in the unattended file) with the cdkey
308 # provided for this test and replace the KVM_TEST_MEDIUM with
309 # the tree url or nfs address provided for this test.
310 unattended_contents = open(self.unattended_file).read()
311 dummy_cdkey_re = r'\bKVM_TEST_CDKEY\b'
312 real_cdkey = os.environ.get('KVM_TEST_cdkey')
313 if re.search(dummy_cdkey_re, unattended_contents):
314 if real_cdkey:
315 unattended_contents = re.sub(dummy_cdkey_re, real_cdkey,
316 unattended_contents)
lmree1e40f2010-06-10 15:32:27 +0000317 else:
Eric Li25fc6d12010-09-28 17:22:51 -0700318 print ("WARNING: 'cdkey' required but not specified for "
319 "this unattended installation")
lmr0ac82102010-06-18 13:40:32 +0000320
Eric Li25fc6d12010-09-28 17:22:51 -0700321 dummy_medium_re = r'\bKVM_TEST_MEDIUM\b'
322 if self.medium == "cdrom":
323 content = "cdrom"
324 elif self.medium == "url":
325 content = "url --url %s" % self.url
326 elif self.medium == "nfs":
327 content = "nfs --server=%s --dir=%s" % (self.nfs_server,
328 self.nfs_dir)
329 else:
330 raise SetupError("Unexpected installation medium %s" % self.url)
lmrb010c7e2010-02-24 11:54:30 +0000331
Eric Li25fc6d12010-09-28 17:22:51 -0700332 unattended_contents = re.sub(dummy_medium_re, content,
333 unattended_contents)
lmrb010c7e2010-02-24 11:54:30 +0000334
Eric Li25fc6d12010-09-28 17:22:51 -0700335 def replace_virtio_key(contents, dummy_re, env):
336 """
337 Replace a virtio dummy string with contents.
lmrb010c7e2010-02-24 11:54:30 +0000338
Eric Li25fc6d12010-09-28 17:22:51 -0700339 If install_virtio is not set, replace it with a dummy string.
lmr5d73e2f2009-10-09 20:46:36 +0000340
Eric Li25fc6d12010-09-28 17:22:51 -0700341 @param contents: Contents of the unattended file
342 @param dummy_re: Regular expression used to search on the.
343 unattended file contents.
344 @param env: Name of the environment variable.
345 """
346 dummy_path = "C:"
347 driver = os.environ.get(env, '')
lmr5d73e2f2009-10-09 20:46:36 +0000348
Eric Li25fc6d12010-09-28 17:22:51 -0700349 if re.search(dummy_re, contents):
350 if self.install_virtio == "yes":
351 if driver.endswith("msi"):
352 driver = 'msiexec /passive /package ' + driver
353 else:
354 try:
355 # Let's escape windows style paths properly
356 drive, path = driver.split(":")
357 driver = drive + ":" + re.escape(path)
358 except:
359 pass
360 contents = re.sub(dummy_re, driver, contents)
361 else:
362 contents = re.sub(dummy_re, dummy_path, contents)
363 return contents
364
365 vdict = {r'\bKVM_TEST_STORAGE_DRIVER_PATH\b':
366 'KVM_TEST_virtio_storage_path',
367 r'\bKVM_TEST_NETWORK_DRIVER_PATH\b':
368 'KVM_TEST_virtio_network_path',
369 r'\bKVM_TEST_VIRTIO_NETWORK_INSTALLER\b':
370 'KVM_TEST_virtio_network_installer_path'}
371
372 for vkey in vdict:
373 unattended_contents = replace_virtio_key(unattended_contents,
374 vkey, vdict[vkey])
375
376 print "Unattended install contents:"
377 print unattended_contents
378 return unattended_contents
379
380
381 def setup_boot_disk(self):
382 answer_contents = self.render_answer_file()
383
384 if self.unattended_file.endswith('.sif'):
385 dest_fname = 'winnt.sif'
386 setup_file = 'winnt.bat'
387 boot_disk = FloppyDisk(self.floppy)
388 boot_disk.setup_answer_file(dest_fname, answer_contents)
389 setup_file_path = os.path.join(self.unattended_dir, setup_file)
390 boot_disk.copy_to(setup_file_path)
391 if self.install_virtio == "yes":
392 boot_disk.setup_virtio_win2003(self.virtio_floppy,
393 self.virtio_oemsetup_id)
394 boot_disk.copy_to(self.finish_program)
395
396 elif self.unattended_file.endswith('.ks'):
397 # Red Hat kickstart install
398 dest_fname = 'ks.cfg'
399 if self.cdrom_unattended:
400 boot_disk = CdromDisk(self.cdrom_unattended)
401 elif self.floppy:
402 boot_disk = FloppyDisk(self.floppy)
403 else:
404 raise SetupError("Neither cdrom_unattended nor floppy set "
405 "on the config file, please verify")
406 boot_disk.setup_answer_file(dest_fname, answer_contents)
407
408 elif self.unattended_file.endswith('.xml'):
409 if self.tftp:
410 # SUSE autoyast install
411 dest_fname = "autoinst.xml"
412 if self.cdrom_unattended:
413 boot_disk = CdromDisk(self.cdrom_unattended)
414 elif self.floppy:
415 boot_disk = FloppyDisk(self.floppy)
416 else:
417 raise SetupError("Neither cdrom_unattended nor floppy set "
418 "on the config file, please verify")
419 boot_disk.setup_answer_file(dest_fname, answer_contents)
420
421 else:
422 # Windows unattended install
423 dest_fname = "autounattend.xml"
424 boot_disk = FloppyDisk(self.floppy)
425 boot_disk.setup_answer_file(dest_fname, answer_contents)
426 if self.install_virtio == "yes":
427 boot_disk.setup_virtio_win2008(self.virtio_floppy)
428 boot_disk.copy_to(self.finish_program)
429
430 else:
431 raise SetupError('Unknown answer file %s' %
432 self.unattended_file)
433
434 boot_disk.close()
lmr5d73e2f2009-10-09 20:46:36 +0000435
436
437 def setup_pxe_boot(self):
438 """
439 Sets up a PXE boot environment using the built in qemu TFTP server.
440 Copies the PXE Linux bootloader pxelinux.0 from the host (needs the
441 pxelinux package or equivalent for your distro), and vmlinuz and
442 initrd.img files from the CD to a directory that qemu will serve trough
443 TFTP to the VM.
444 """
Eric Li25fc6d12010-09-28 17:22:51 -0700445 print "Setting up PXE boot using TFTP root %s" % self.tftp
lmr5d73e2f2009-10-09 20:46:36 +0000446
447 pxe_file = None
448 pxe_paths = ['/usr/lib/syslinux/pxelinux.0',
449 '/usr/share/syslinux/pxelinux.0']
450 for path in pxe_paths:
451 if os.path.isfile(path):
452 pxe_file = path
453 break
454
455 if not pxe_file:
456 raise SetupError('Cannot find PXE boot loader pxelinux.0. Make '
457 'sure pxelinux or equivalent package for your '
458 'distro is installed.')
459
Eric Li25fc6d12010-09-28 17:22:51 -0700460 pxe_dest = os.path.join(self.tftp, 'pxelinux.0')
lmr5d73e2f2009-10-09 20:46:36 +0000461 shutil.copyfile(pxe_file, pxe_dest)
462
lmrb010c7e2010-02-24 11:54:30 +0000463 try:
Eric Li25fc6d12010-09-28 17:22:51 -0700464 m_cmd = ('mount -t iso9660 -v -o loop,ro %s %s' %
465 (self.cdrom_cd1, self.cdrom_cd1_mount))
466 run(m_cmd, info='Could not mount CD image %s.' % self.cdrom_cd1)
lmr5d73e2f2009-10-09 20:46:36 +0000467
Eric Li25fc6d12010-09-28 17:22:51 -0700468 pxe_dir = os.path.join(self.cdrom_cd1_mount, self.pxe_dir)
lmra29a5cb2010-03-18 02:39:34 +0000469 pxe_image = os.path.join(pxe_dir, self.pxe_image)
470 pxe_initrd = os.path.join(pxe_dir, self.pxe_initrd)
lmr5d73e2f2009-10-09 20:46:36 +0000471
lmrb010c7e2010-02-24 11:54:30 +0000472 if not os.path.isdir(pxe_dir):
473 raise SetupError('The ISO image does not have a %s dir. The '
474 'script assumes that the cd has a %s dir '
475 'where to search for the vmlinuz image.' %
lmra29a5cb2010-03-18 02:39:34 +0000476 (self.pxe_dir, self.pxe_dir))
lmr5d73e2f2009-10-09 20:46:36 +0000477
lmrb010c7e2010-02-24 11:54:30 +0000478 if not os.path.isfile(pxe_image) or not os.path.isfile(pxe_initrd):
479 raise SetupError('The location %s is lacking either a vmlinuz '
480 'or a initrd.img file. Cannot find a PXE '
lmra29a5cb2010-03-18 02:39:34 +0000481 'image to proceed.' % self.pxe_dir)
lmr5d73e2f2009-10-09 20:46:36 +0000482
Eric Li25fc6d12010-09-28 17:22:51 -0700483 tftp_image = os.path.join(self.tftp, 'vmlinuz')
484 tftp_initrd = os.path.join(self.tftp, 'initrd.img')
lmrb010c7e2010-02-24 11:54:30 +0000485 shutil.copyfile(pxe_image, tftp_image)
486 shutil.copyfile(pxe_initrd, tftp_initrd)
lmr5d73e2f2009-10-09 20:46:36 +0000487
lmrb010c7e2010-02-24 11:54:30 +0000488 finally:
Eric Li25fc6d12010-09-28 17:22:51 -0700489 cleanup(self.cdrom_cd1_mount)
lmr5d73e2f2009-10-09 20:46:36 +0000490
Eric Li25fc6d12010-09-28 17:22:51 -0700491 pxe_config_dir = os.path.join(self.tftp, 'pxelinux.cfg')
lmr5d73e2f2009-10-09 20:46:36 +0000492 if not os.path.isdir(pxe_config_dir):
493 os.makedirs(pxe_config_dir)
494 pxe_config_path = os.path.join(pxe_config_dir, 'default')
495
496 pxe_config = open(pxe_config_path, 'w')
497 pxe_config.write('DEFAULT pxeboot\n')
498 pxe_config.write('TIMEOUT 20\n')
499 pxe_config.write('PROMPT 0\n')
500 pxe_config.write('LABEL pxeboot\n')
501 pxe_config.write(' KERNEL vmlinuz\n')
lmr5d73e2f2009-10-09 20:46:36 +0000502 pxe_config.write(' APPEND initrd=initrd.img %s\n' %
503 self.kernel_args)
504 pxe_config.close()
505
506 print "PXE boot successfuly set"
507
lmrb010c7e2010-02-24 11:54:30 +0000508
lmree1e40f2010-06-10 15:32:27 +0000509 def setup_url(self):
510 """
Eric Li25fc6d12010-09-28 17:22:51 -0700511 Download the vmlinuz and initrd.img from URL.
lmree1e40f2010-06-10 15:32:27 +0000512 """
513 print "Downloading the vmlinuz and initrd.img"
514 os.chdir(self.image_path)
515
516 kernel_fetch_cmd = "wget -q %s/isolinux/%s" % (self.url, self.kernel)
517 initrd_fetch_cmd = "wget -q %s/isolinux/%s" % (self.url, self.initrd)
518
519 if os.path.exists(self.kernel):
520 os.unlink(self.kernel)
521 if os.path.exists(self.initrd):
522 os.unlink(self.initrd)
523
Eric Li25fc6d12010-09-28 17:22:51 -0700524 run(kernel_fetch_cmd, info="Could not fetch vmlinuz from %s" % self.url)
525 run(initrd_fetch_cmd, info=("Could not fetch initrd.img from %s" %
526 self.url))
527 print "Download of vmlinuz and initrd.img finished"
lmree1e40f2010-06-10 15:32:27 +0000528
lmree1e40f2010-06-10 15:32:27 +0000529
530 def setup_nfs(self):
531 """
532 Copy the vmlinuz and initrd.img from nfs.
533 """
534 print "Copying the vmlinuz and initrd.img from nfs"
535
Eric Li25fc6d12010-09-28 17:22:51 -0700536 m_cmd = ("mount %s:%s %s -o ro" %
537 (self.nfs_server, self.nfs_dir, self.nfs_mount))
538 run(m_cmd, info='Could not mount nfs server')
lmree1e40f2010-06-10 15:32:27 +0000539
540 try:
Eric Li25fc6d12010-09-28 17:22:51 -0700541 kernel_fetch_cmd = ("cp %s/isolinux/%s %s" %
542 (self.nfs_mount, self.kernel, self.image_path))
543 run(kernel_fetch_cmd, info=("Could not copy the vmlinuz from %s" %
544 self.nfs_mount))
545 initrd_fetch_cmd = ("cp %s/isolinux/%s %s" %
546 (self.nfs_mount, self.initrd, self.image_path))
547 run(initrd_fetch_cmd, info=("Could not copy the initrd.img from "
548 "%s" % self.nfs_mount))
lmree1e40f2010-06-10 15:32:27 +0000549 finally:
Eric Li25fc6d12010-09-28 17:22:51 -0700550 cleanup(self.nfs_mount)
lmr5d73e2f2009-10-09 20:46:36 +0000551
552
553 def setup(self):
Eric Li25fc6d12010-09-28 17:22:51 -0700554 """
555 Configure the environment for unattended install.
556
557 Uses an appropriate strategy according to each install model.
558 """
lmr5d73e2f2009-10-09 20:46:36 +0000559 print "Starting unattended install setup"
Eric Li25fc6d12010-09-28 17:22:51 -0700560 print
lmr5d73e2f2009-10-09 20:46:36 +0000561
562 print "Variables set:"
Eric Li25fc6d12010-09-28 17:22:51 -0700563 for member in inspect.getmembers(self):
564 name, value = member
565 attribute = getattr(self, name)
566 if not (name.startswith("__") or callable(attribute) or not value):
567 print " %s: %s" % (name, value)
568 print
lmr5d73e2f2009-10-09 20:46:36 +0000569
Eric Li25fc6d12010-09-28 17:22:51 -0700570 if self.unattended_file and (self.floppy or self.cdrom_unattended):
571 self.setup_boot_disk()
lmree1e40f2010-06-10 15:32:27 +0000572 if self.medium == "cdrom":
Eric Li25fc6d12010-09-28 17:22:51 -0700573 if self.tftp:
lmree1e40f2010-06-10 15:32:27 +0000574 self.setup_pxe_boot()
575 elif self.medium == "url":
576 self.setup_url()
577 elif self.medium == "nfs":
578 self.setup_nfs()
579 else:
580 raise SetupError("Unexpected installation method %s" %
Eric Li25fc6d12010-09-28 17:22:51 -0700581 self.medium)
lmr5d73e2f2009-10-09 20:46:36 +0000582 print "Unattended install setup finished successfuly"
583
584
585if __name__ == "__main__":
586 os_install = UnattendedInstall()
587 os_install.setup()