class NewInstaller(object): def __init__(self, conn, cfg): object.__init__(self) self.conn = conn self.cfg = cfg self.machine = MachineHandler(self.conn) self.cursor = StatementCursor(self.conn) self.target = None self.installer = None self._mounted = None self._bootstrapped = None self.debmirror = self.cfg.get('debrepos', 'http_mirror') def _check_target(self): if not self.target: raise Error, 'no target specified' def _check_installer(self): if not self.installer: raise Error, 'no installer available' def _check_mounted(self): self._check_target() if not self._mounted: raise Error, 'target not mounted' def _check_bootstrap(self): self._check_mounted() if not self._bootstrapped: raise Error, 'target not bootstrapped' def set_machine(self, machine): self.machine.set_machine(machine) try: logfile = os.environ['LOGFILE'] except KeyError: logfile = '/paellalog/paella-install-%s.log' % machine os.environ['LOGFILE'] = logfile os.environ['PAELLA_MACHINE'] = machine def make_filesystems(self): device = self.machine.array_hack(self.machine.current.machine_type) all_fsmounts = self.machine.get_installable_fsmounts() env = CurrentEnvironment(self.conn, self.machine.current.machine) for row in all_fsmounts: pdev = device + str(row.partition) if row.mnt_name in env.keys(): print '%s held' % row.mnt_name else: print 'making filesystem for', row.mnt_name make_filesystem(pdev, row.fstype) def set_target(self, target): self.target = target def _pdev(self, device, partition): return device + str(partition) def ready_target(self): self._check_target() makepaths(self.target) device = self.machine.array_hack(self.machine.current.machine_type) clause = Eq('filesystem', self.machine.current.filesystem) clause &= Gt('partition', '0') table = 'filesystem_mounts natural join mounts' mounts = self.cursor.select(table=table, clause=clause, order='mnt_point') if mounts[0].mnt_point != '/': raise Error, 'bad set of mounts', mounts pdev = self._pdev(device, mounts[0].partition) print 'mounting target', pdev, self.target runlog('mount %s %s' % (pdev, self.target)) for mnt in mounts[1:]: tpath = os.path.join(self.target, mnt.mnt_point[1:]) makepaths(tpath) pdev = self._pdev(device, mnt.partition) runlog('mount %s %s' % (pdev, tpath)) self._mounted = True def setup_installer(self): profile = self.machine.current.profile self.installer = ProfileInstaller(self.conn, self.cfg) self.installer.set_profile(profile) self.suite = self.installer.suite def organize_disks(self): return self.machine.check_machine_disks(self.machine.current.machine_type) def partition_disks(self): disks = self.organize_disks() for diskname in disks: for device in disks[diskname]: self._partition_disk(diskname, device) if len(disks[diskname]) > 1: ndev = len(disks[diskname]) print 'doing raid setup on %s' % diskname fs = self.machine.current.filesystem print fs pnums = [r.partition for r in self.machine.get_installable_fsmounts(fs)] for p in pnums: mdadm = 'mdadm --create /dev/md%d' % p mdadm = '%s --force -l1 -n%d ' % (mdadm, ndev) devices = ['%s%s' % (d, p) for d in disks[diskname]] command = mdadm + ' '.join(devices) print command yesman = 'bash -c "yes | %s"' % command print yesman os.system(yesman) print 'doing raid setup on %s' % str(disks[diskname]) mdstat = file('/proc/mdstat').read() while mdstat.find('resync') > -1: sleep(10) mdstat = file('/proc/mdstat').read() def _partition_disk(self, diskname, device): print 'partitioning', diskname, device dump = self.machine.make_partition_dump(diskname, device) i, o = os.popen2('sfdisk %s' % device) i.write(dump) i.close() def bootstrap_target(self): self._check_mounted() self._check_installer() runlog(debootstrap(self.suite, self.target, self.debmirror)) self._bootstrapped = True def ready_base_for_install(self): self._check_bootstrap() self._check_installer() fstab = self.machine.make_fstab() ready_base_for_install(self.target, self.cfg, self.suite, fstab) def install_to_target(self): os.environ['DEBIAN_FRONTEND'] = 'noninteractive' self._check_target() self._check_installer() self.installer.set_target(self.target) self.installer.process() def post_install(self): print 'post_install' modules = self.machine.get_modules() print 'installing modules', modules setup_modules(self.target, modules) print 'modules installed' kernel = self.machine.current.kernel print 'installing kernel', kernel install_kernel(kernel, self.target) print 'kernel installed' def install(self, machine, target): self.set_machine(machine) self.partition_disks() self.make_filesystems() self.setup_installer() self.set_target(target) self.ready_target() self.bootstrap_target() self.ready_base_for_install() self.install_to_target() self.post_install()
class ChrootInstaller(BaseInstaller): # we may need more __init__ args later def __init__(self, conn): BaseInstaller.__init__(self, conn) self._bootstrapped = False self._install_finished = False self._processes = [ 'ready_target', 'bootstrap', 'mount_target_proc', 'mount_target_sys', 'make_device_entries', 'mount_target_devpts', 'apt_sources_installer', 'ready_base_for_install', 'pre_install', 'install', 'post_install', 'apt_sources_final', 'umount_target_sys', 'umount_target_proc' ] # pre_install is unmapped # post_install is unmapped self._process_map = dict( ready_target=self.create_target_directory, bootstrap=self.bootstrap_target, mount_target_proc=self.mount_target_proc, mount_target_sys=self.mount_target_sys, make_device_entries=self.make_device_entries, mount_target_devpts=self.mount_target_devpts, apt_sources_installer=self.apt_sources_installer, ready_base_for_install=self.ready_base_for_install, install=self.install, apt_sources_final=self.apt_sources_final, umount_target_sys=self.umount_target_sys, umount_target_proc=self.umount_target_proc) # this is only used in the machine installer self.mtypedata = {} # the default script for the chroot installer is None def make_script(self, procname): return None def set_logfile(self, logfile): BaseInstaller.set_logfile(self, logfile) self.log.info('-' * 30) msg = '%s initialized' % self.__class__.__name__ self.log.info(msg) self.log.info('-' * 30) @requires_target_set def set_profile(self, profile): self.installer = ProfileInstaller(self) self.installer.mtypedata.update(self.mtypedata) self.installer.set_profile(profile) self.set_suite(self.installer.suite) @requires_target_exists def _bootstrap_with_tarball(self, suite): suite_path = path(self.defenv.get('installer', 'suite_storage')) filename = '%s.tar.gz' % suite basefile = suite_path / filename taropts = '-xzf' if not basefile.exists(): filename = '%s.tar' % suite basefile = suite_path / filename taropts = '-xf' cmd = 'tar -C %s %s %s' % (self.target, taropts, basefile) # if cmd returns nonzero, runlog will raise an error runlog(cmd) # we need to do certain things here that debootstrap # does for us, like copy /etc/resolv.conf self._bootstrapped = True @requires_target_exists def _bootstrap_with_debootstrap(self, suite): mirror = self.defenv.get('installer', 'http_mirror') cmd = debootstrap(suite, self.target, mirror) # if cmd returns nonzero, runlog will raise an error runlog(cmd) self._bootstrapped = True @requires_suite_set def bootstrap_target(self): if not self.target.exists(): self.target.mkdir() if not self.target.isdir(): raise InstallTargetError, "%s is not a directory" % self.target if self.defenv.getboolean('installer', 'bootstrap_target'): self.log.info('bootstrapping with debootstrap') self._bootstrap_with_debootstrap(self.base_suite) else: self.log.info('bootstrapping with premade tarball') self._bootstrap_with_tarball(self.base_suite) # here we add the apt keys that are needed aptkeys = AptKeyHandler(self.conn) keys = self.defenv.get_list('archive_keys', 'installer') for key in keys: row = aptkeys.get_row(key) filename = self.target / ('%s.key' % key) if filename.exists(): raise RuntimeError, "%s already exists" % filename keyfile = file(filename, 'w') keyfile.write(row.data) keyfile.close() #self.chroot('apt-key add %s.key' % key) self.chroot(['apt-key', 'add', '%s.key' % key]) os.remove(filename) if filename.exists(): raise RuntimeError, "%s wasn't deleted" % filename self.log.info('added key %s (%s) to apt' % (key, row.keyid)) @requires_bootstrap def make_device_entries(self): self.log.info('nothing done for make_device_entries yet') @requires_bootstrap def apt_sources_installer(self): make_sources_list(self.conn, self.target, self.suite) @requires_install_complete def apt_sources_final(self): sourceslist = self.target / 'etc/apt/sources.list' sourceslist_installer = path('%s.installer' % sourceslist) os.rename(sourceslist, sourceslist_installer) make_official_sources_list(self.conn, self.target, self.suite) # this is probably not useful anymore # it still has a purpose in the machine installer - # it sets up the mdadm.conf file with the raid devices it creates # if it creates any. @requires_bootstrap def ready_base_for_install(self): # update the package lists #self.chroot('apt-get -y update') self.chroot(['apt-get', '-y', 'update']) # common method for mounting /proc and /sys # here fs is either 'proc' or 'sys' or 'devpts' def _mount_target_virtfs(self, fs): fstype = dict(proc='proc', sys='sysfs', devpts='devpts') target = self.target / fs if fs == 'devpts': target = self.target / 'dev' / 'pts' if not target.isdir(): target.mkdir() #cmd = 'mount -t %s none %s' % (fstype[fs], target) cmd = ['mount', '-t', fstype[fs], 'none', str(target)] runlog(cmd) def _umount_target_virtfs(self, fs): # work around binfmt-support /proc locking # found this idea while messing around in live-helper target = self.target / fs if fs == 'proc': binfmt_misc = self.target / 'proc/sys/fs/binfmt_misc' status = binfmt_misc / 'status' if status.exists(): self.log.info('Unmounting /proc/sys/fs/binfmt_misc in chroot') #cmd = 'umount %s' % binfmt cmd = ['umount', str(binfmt_misc)] runlog(cmd) if fs == 'devpts': target = self.target / 'dev' / 'pts' #cmd = 'umount %s' % target cmd = ['umount', str(target)] runlog(cmd) def _target_proc_mounted(self): testfile = self.target / 'proc/version' return testfile.isfile() def _target_sys_mounted(self): testdir = self.target / 'sys/kernel' return testdir.isdir() @requires_bootstrap def mount_target_proc(self): self._mount_target_virtfs('proc') @requires_bootstrap def mount_target_sys(self): self._mount_target_virtfs('sys') def mount_target_devpts(self): self._mount_target_virtfs('devpts') @requires_target_proc_mounted def umount_target_proc(self): self._umount_target_virtfs('proc') @requires_target_sys_mounted def umount_target_sys(self): self._umount_target_virtfs('sys') def umount_target_devpts(self): self._umount_target_virtfs('devpts') @requires_target_proc_mounted @requires_target_sys_mounted @requires_installer_set def install(self): self.installer.run_all_processes() self._install_finished = True def log_all_processes_finished(self): self.log.info('-' * 30) self.log.info('%s processes finished' % self.__class__.__name__) self.log.info('-' * 30) def save_logfile_in_target(self): install_log = self.target / 'root/paella/install.log' self.mainlog.filename.copyfile(install_log)
class ChrootInstaller(BaseChrootInstaller): def __init__(self, conn, logfile=None): BaseChrootInstaller.__init__(self, conn) self.conn = conn self.cursor = StatementCursor(self.conn) self._mounted = None self._installer_ready = False self._base_ready = False if logfile is None: self.set_logfile(logfile) if logfile is False: pass def _check_base_ready(self): if not self._base_ready: raise InstallError, 'base is not ready for install.' def set_profile(self, profile): self.profile = profile def ready_target(self): self._check_target_exists() def setup_installer(self): self.installer = ProfileInstaller(self.conn) self.installer.log = self.log self.installer.set_profile(self.profile) self.suite = self.installer.suite self._installer_ready = True def bootstrap_target(self): self._bootstrap_target() self._check_bootstrap() def ready_base_for_install(self): self._check_bootstrap() fstab = '#unconfigured for chroot install\n' ready_base_for_install(self.target, self.defenv, self.suite, fstab) self._mount_target_proc() self._check_target_proc() cmd = self.command('apt-get', '-y update', chroot=True) runvalue = runlog(cmd) if runvalue: raise InstallError, 'problem updating the apt lists.' if os.environ.has_key('FAKE_START_STOP_DAEMON'): make_fake_start_stop_daemon(self.target) self._base_ready = True def install_to_target(self): self._check_base_ready() os.environ['DEBIAN_FRONTEND'] = 'noninteractive' self.installer.set_target(self.target) self.installer.process() def post_install(self): self._umount_target_proc() if os.environ.has_key('FAKE_START_STOP_DAEMON'): remove_fake_start_stop_daemon(self.target) def install(self, profile, target): self.set_profile(profile) self.setup_installer() self.set_target(target) self.ready_target() self.bootstrap_target() self.ready_base_for_install() self.install_to_target() self.post_install()
class NewInstaller(object): def __init__(self, conn, cfg): object.__init__(self) self.conn = conn self.cfg = cfg self.machine = MachineHandler(self.conn) self.cursor = StatementCursor(self.conn) self.target = None self.installer = None self._mounted = None self._bootstrapped = None self.debmirror = self.cfg.get('debrepos', 'http_mirror') def _check_target(self): if not self.target: raise Error, 'no target specified' def _check_installer(self): if not self.installer: raise Error, 'no installer available' def _check_mounted(self): self._check_target() if not self._mounted: raise Error, 'target not mounted' def _check_bootstrap(self): self._check_mounted() if not self._bootstrapped: raise Error, 'target not bootstrapped' def set_machine(self, machine): self.machine.set_machine(machine) try: logfile = os.environ['LOGFILE'] except KeyError: logfile = '/paellalog/paella-install-%s.log' % machine os.environ['LOGFILE'] = logfile os.environ['PAELLA_MACHINE'] = machine def make_filesystems(self): device = self.machine.array_hack(self.machine.current.machine_type) all_fsmounts = self.machine.get_installable_fsmounts() env = CurrentEnvironment(self.conn, self.machine.current.machine) for row in all_fsmounts: pdev = device + str(row.partition) if row.mnt_name in env.keys(): print '%s held' % row.mnt_name else: print 'making filesystem for', row.mnt_name make_filesystem(pdev, row.fstype) def set_target(self, target): self.target = target def _pdev(self, device, partition): return device + str(partition) def ready_target(self): self._check_target() makepaths(self.target) device = self.machine.array_hack(self.machine.current.machine_type) clause = Eq('filesystem', self.machine.current.filesystem) clause &= Gt('partition', '0') table = 'filesystem_mounts natural join mounts' mounts = self.cursor.select(table=table, clause=clause, order='mnt_point') if mounts[0].mnt_point != '/': raise Error, 'bad set of mounts', mounts pdev = self._pdev(device, mounts[0].partition) print 'mounting target', pdev, self.target runlog('mount %s %s' % (pdev, self.target)) for mnt in mounts[1:]: tpath = os.path.join(self.target, mnt.mnt_point[1:]) makepaths(tpath) pdev = self._pdev(device, mnt.partition) runlog('mount %s %s' % (pdev, tpath)) self._mounted = True def setup_installer(self): profile = self.machine.current.profile self.installer = ProfileInstaller(self.conn, self.cfg) self.installer.set_profile(profile) self.suite = self.installer.suite def organize_disks(self): return self.machine.check_machine_disks( self.machine.current.machine_type) def partition_disks(self): disks = self.organize_disks() for diskname in disks: for device in disks[diskname]: self._partition_disk(diskname, device) if len(disks[diskname]) > 1: ndev = len(disks[diskname]) print 'doing raid setup on %s' % diskname fs = self.machine.current.filesystem print fs pnums = [ r.partition for r in self.machine.get_installable_fsmounts(fs) ] for p in pnums: mdadm = 'mdadm --create /dev/md%d' % p mdadm = '%s --force -l1 -n%d ' % (mdadm, ndev) devices = ['%s%s' % (d, p) for d in disks[diskname]] command = mdadm + ' '.join(devices) print command yesman = 'bash -c "yes | %s"' % command print yesman os.system(yesman) print 'doing raid setup on %s' % str(disks[diskname]) mdstat = file('/proc/mdstat').read() while mdstat.find('resync') > -1: sleep(10) mdstat = file('/proc/mdstat').read() def _partition_disk(self, diskname, device): print 'partitioning', diskname, device dump = self.machine.make_partition_dump(diskname, device) i, o = os.popen2('sfdisk %s' % device) i.write(dump) i.close() def bootstrap_target(self): self._check_mounted() self._check_installer() runlog(debootstrap(self.suite, self.target, self.debmirror)) self._bootstrapped = True def ready_base_for_install(self): self._check_bootstrap() self._check_installer() fstab = self.machine.make_fstab() ready_base_for_install(self.target, self.cfg, self.suite, fstab) def install_to_target(self): os.environ['DEBIAN_FRONTEND'] = 'noninteractive' self._check_target() self._check_installer() self.installer.set_target(self.target) self.installer.process() def post_install(self): print 'post_install' modules = self.machine.get_modules() print 'installing modules', modules setup_modules(self.target, modules) print 'modules installed' kernel = self.machine.current.kernel print 'installing kernel', kernel install_kernel(kernel, self.target) print 'kernel installed' def install(self, machine, target): self.set_machine(machine) self.partition_disks() self.make_filesystems() self.setup_installer() self.set_target(target) self.ready_target() self.bootstrap_target() self.ready_base_for_install() self.install_to_target() self.post_install()
class NewInstaller(object): def __init__(self, conn, cfg): object.__init__(self) self.conn = conn self.cfg = cfg self.machine = MachineHandler(self.conn) self.cursor = StatementCursor(self.conn) self.target = None self.installer = None self._mounted = None self._bootstrapped = None self.debmirror = self.cfg.get("debrepos", "http_mirror") self._raid_setup = False self._raid_drives = {} def _check_target(self): if not self.target: raise Error, "no target specified" def _check_installer(self): if not self.installer: raise Error, "no installer available" def _check_mounted(self): self._check_target() if not self._mounted: raise Error, "target not mounted" def _check_bootstrap(self): self._check_mounted() if not self._bootstrapped: raise Error, "target not bootstrapped" def set_machine(self, machine): self.machine.set_machine(machine) try: logfile = os.environ["LOGFILE"] except KeyError: logfile = "/paellalog/paella-install-%s.log" % machine os.environ["LOGFILE"] = logfile os.environ["PAELLA_MACHINE"] = machine def make_filesystems(self): device = self.machine.array_hack(self.machine.current.machine_type) mddev = False if device == "/dev/md": mdnum = 0 mddev = True all_fsmounts = self.machine.get_installable_fsmounts() env = CurrentEnvironment(self.conn, self.machine.current.machine) for row in all_fsmounts: if mddev: pdev = "/dev/md%d" % mdnum mdnum += 1 else: pdev = device + str(row.partition) if row.mnt_name in env.keys(): print "%s held" % row.mnt_name else: print "making filesystem for", row.mnt_name make_filesystem(pdev, row.fstype) def set_target(self, target): self.target = target def _pdev(self, device, partition): return device + str(partition) def ready_target(self): self._check_target() makepaths(self.target) device = self.machine.array_hack(self.machine.current.machine_type) clause = Eq("filesystem", self.machine.current.filesystem) clause &= Gt("partition", "0") table = "filesystem_mounts natural join mounts" mounts = self.cursor.select(table=table, clause=clause, order="mnt_point") if mounts[0].mnt_point != "/": raise Error, "bad set of mounts", mounts mddev = False mdnum = 0 if device == "/dev/md": mddev = True pdev = "/dev/md0" mdnum += 1 else: pdev = self._pdev(device, mounts[0].partition) print "mounting target", pdev, self.target clause &= Neq("mnt_point", "/") mounts = self.cursor.select(table=table, clause=clause, order="ord") runlog("mount %s %s" % (pdev, self.target)) for mnt in mounts: tpath = os.path.join(self.target, mnt.mnt_point[1:]) makepaths(tpath) if mddev: pdev = "/dev/md%d" % mdnum else: pdev = self._pdev(device, mnt.partition) mdnum += 1 runlog("mount %s %s" % (pdev, tpath)) self._mounted = True def setup_installer(self): profile = self.machine.current.profile self.installer = ProfileInstaller(self.conn, self.cfg) self.installer.set_profile(profile) self.suite = self.installer.suite def organize_disks(self): return self.machine.check_machine_disks(self.machine.current.machine_type) def partition_disks(self): disks = self.organize_disks() for diskname in disks: for device in disks[diskname]: self._partition_disk(diskname, device) if len(disks[diskname]) > 1: self._raid_setup = True self._raid_drives[diskname] = disks[diskname] ndev = len(disks[diskname]) print "doing raid setup on %s" % diskname fs = self.machine.current.filesystem print fs pnums = [r.partition for r in self.machine.get_installable_fsmounts(fs)] mdnum = 0 for p in pnums: mdadm = "mdadm --create /dev/md%d" % mdnum mdadm = "%s --force -l1 -n%d " % (mdadm, ndev) devices = ["%s%s" % (d, p) for d in disks[diskname]] command = mdadm + " ".join(devices) print command yesman = 'bash -c "yes | %s"' % command print yesman os.system(yesman) mdnum += 1 print "doing raid setup on %s" % str(disks[diskname]) mdstat = file("/proc/mdstat").read() while mdstat.find("resync") > -1: sleep(10) mdstat = file("/proc/mdstat").read() def _partition_disk(self, diskname, device): print "partitioning", diskname, device dump = self.machine.make_partition_dump(diskname, device) i, o = os.popen2("sfdisk %s" % device) i.write(dump) i.close() def bootstrap_target(self): self._check_mounted() self._check_installer() runlog(debootstrap(self.suite, self.target, self.debmirror)) self._bootstrapped = True def ready_base_for_install(self): self._check_bootstrap() self._check_installer() fstab = self.machine.make_fstab() ready_base_for_install(self.target, self.cfg, self.suite, fstab) if self._raid_setup: mdpath = join(self.target, "etc/mdadm") makepaths(mdpath) mdconf = file(join(mdpath, "mdadm.conf"), "w") for diskname in self._raid_drives: devices = ["%s*" % d for d in self._raid_drives[diskname]] line = "DEVICE %s" % " ".join(devices) mdconf.write(line + "\n") arrdata = commands.getoutput("mdadm -E -s") mdconf.write(arrdata + "\n") mdconf.write("\n") mdconf.close() def install_to_target(self): os.environ["DEBIAN_FRONTEND"] = "noninteractive" self._check_target() self._check_installer() self.installer.set_target(self.target) self.installer.process() def post_install(self): print "post_install" modules = self.machine.get_modules() print "installing modules", modules setup_modules(self.target, modules) print "modules installed" kernel = self.machine.current.kernel print "installing kernel", kernel install_kernel(kernel, self.target) print "kernel installed" def install(self, machine, target): self.set_machine(machine) self.partition_disks() self.make_filesystems() self.setup_installer() self.set_target(target) self.ready_target() self.bootstrap_target() self.ready_base_for_install() self.install_to_target() self.post_install()
class ChrootInstaller(object): def __init__(self, conn, cfg): object.__init__(self) self.conn = conn self.cfg = cfg self.cursor = StatementCursor(self.conn) self.target = None self.installer = None self._mounted = None self._bootstrapped = None self.debmirror = self.cfg.get("debrepos", "http_mirror") def _check_target(self): if not self.target: raise Error, "no target specified" def _check_installer(self): if not self.installer: raise Error, "no installer available" def _check_bootstrap(self): self._check_target() if not self._bootstrapped: raise Error, "target not bootstrapped" def set_target(self, target): self.target = target def set_profile(self, profile): self.profile = profile def ready_target(self): self._check_target() def setup_installer(self): self.installer = ProfileInstaller(self.conn, self.cfg) self.installer.set_profile(self.profile) self.suite = get_suite(self.conn, self.profile) def bootstrap_target(self): self._check_target() self._check_installer() runlog(debootstrap(self.suite, self.target, self.debmirror)) self._bootstrapped = True def ready_base_for_install(self): self._check_bootstrap() self._check_installer() fstab = "#unconfigured for chroot install\n" ready_base_for_install(self.target, self.cfg, self.suite, fstab) def install_to_target(self): os.environ["DEBIAN_FRONTEND"] = "noninteractive" self._check_target() self._check_installer() self.installer.set_target(self.target) self.installer.process() def post_install(self): print "post_install" kernel = self.machine.current.kernel print "installing kernel", kernel install_kernel(kernel, self.target) print "kernel installed" def install(self, profile, target): self.set_profile(profile) self.setup_installer() self.set_target(target) self.ready_target() self.bootstrap_target() self.ready_base_for_install() self.install_to_target()
class NewInstaller(object): def __init__(self, conn, cfg): object.__init__(self) self.conn = conn self.cfg = cfg self.machine = MachineHandler(self.conn) self.cursor = StatementCursor(self.conn) self.target = None self.installer = None self._mounted = None self._bootstrapped = None self.debmirror = self.cfg.get('debrepos', 'http_mirror') def _check_target(self): if not self.target: raise Error, 'no target specified' def _check_installer(self): if not self.installer: raise Error, 'no installer available' def _check_mounted(self): self._check_target() if not self._mounted: raise Error, 'target not mounted' def _check_bootstrap(self): self._check_mounted() if not self._bootstrapped: raise Error, 'target not bootstrapped' def set_machine(self, machine): self.machine.set_machine(machine) try: logfile = os.environ['LOGFILE'] except KeyError: logfile = '/var/log/paella-install-%s.log' % machine os.environ['LOGFILE'] = logfile def make_filesystems(self): device = self.machine.array_hack(self.machine.current.machine_type) all_fsmounts = self.machine.get_installable_fsmounts() env = CurrentEnvironment(self.conn, self.machine.current.machine) for row in all_fsmounts: pdev = device + str(row.partition) if row.mnt_name in env.keys(): print '%s held' % row.mnt_name else: print 'making filesystem for', row.mnt_name make_filesystem(pdev, row.fstype) def set_target(self, target): self.target = target def _pdev(self, device, partition): return device + str(partition) def ready_target(self): self._check_target() makepaths(self.target) device = self.machine.array_hack(self.machine.current.machine_type) clause = Eq('filesystem', self.machine.current.filesystem) clause &= Gt('partition', '0') table = 'filesystem_mounts natural join mounts' mounts = self.cursor.select(table=table, clause=clause, order='mnt_point') if mounts[0].mnt_point != '/': raise Error, 'bad set of mounts', mounts pdev = self._pdev(device, mounts[0].partition) print 'mounting target', pdev, self.target runlog('mount %s %s' % (pdev, self.target)) for mnt in mounts[1:]: tpath = os.path.join(self.target, mnt.mnt_point[1:]) makepaths(tpath) pdev = self._pdev(device, mnt.partition) runlog('mount %s %s' % (pdev, tpath)) self._mounted = True def apt_update_target(self): raise Error, "deprecated --don't do this anymore" os.system('chroot %s apt-get -y update' % self.target) def setup_installer(self): profile = self.machine.current.profile self.installer = ProfileInstaller(self.conn, self.cfg) self.installer.set_profile(profile) self.suite = self.installer.suite def partition_disks(self): clause = Eq('machine_type', self.machine.current.machine_type) disk_rows = self.cursor.select(table='machine_disks', clause=clause) for row in disk_rows: print 'partitioning', row.diskname, row.device dump = self.machine.make_partition_dump(row.diskname, row.device) i, o = os.popen2('sfdisk %s' % row.device) i.write(dump) i.close() def bootstrap_target(self): self._check_mounted() self._check_installer() runlog(debootstrap(self.suite, self.target, self.debmirror)) self._bootstrapped = True def ready_base_for_install(self): self._check_bootstrap() self._check_installer() fstab = self.machine.make_fstab() ready_base_for_install(self.target, self.cfg, self.suite, fstab) def install_to_target(self): os.environ['DEBIAN_FRONTEND'] = 'noninteractive' self._check_target() self._check_installer() self.installer.set_target(self.target) self.installer.process() def post_install(self): print 'post_install' kernel = self.machine.current.kernel print 'installing kernel', kernel install_kernel(kernel, self.target) print 'kernel installed' def install(self, machine, target): self.set_machine(machine) self.partition_disks() self.make_filesystems() self.setup_installer() self.set_target(target) self.ready_target() self.bootstrap_target() self.ready_base_for_install() self.install_to_target() self.post_install()
class ChrootInstaller(BaseChrootInstaller): # we may need more __init__ args later def __init__(self, conn): BaseChrootInstaller.__init__(self, conn) self._bootstrapped = False self._install_finished = False self._processes = [ 'ready_target', 'bootstrap', 'mount_target_proc', 'mount_target_sys', 'make_device_entries', 'mount_target_devpts', 'apt_sources_installer', 'ready_base_for_install', 'pre_install', 'install', 'post_install', 'apt_sources_final', 'umount_target_sys', 'umount_target_proc', 'umount_target_devpts' ] # pre_install is unmapped # post_install is unmapped self._process_map = dict(ready_target=self.create_target_directory, bootstrap=self.bootstrap_target, mount_target_proc=self.mount_target_proc, mount_target_sys=self.mount_target_sys, make_device_entries=self.make_device_entries, mount_target_devpts=self.mount_target_devpts, apt_sources_installer=self.apt_sources_installer, ready_base_for_install=self.ready_base_for_install, install=self.install, apt_sources_final=self.apt_sources_final, umount_target_sys=self.umount_target_sys, umount_target_proc=self.umount_target_proc, umount_target_devpts=self.umount_target_devpts ) # this is only used in the machine installer self.machine_data = {} # the default script for the chroot installer is None def make_script(self, procname): return None def set_logfile(self, logfile): BaseInstaller.set_logger(self, filename=logfile) self.log.info('-'*30) msg = '%s initialized' % self.__class__.__name__ self.log.info(msg) self.log.info('-'*30) def set_profile(self, profile): self.check_target_set() self.installer = ProfileInstaller(self) if os.environ.has_key('DEBUG'): self.log.info("ChrootInstaller.machine_data: %s" % self.machine_data) self.installer.machine_data.update(self.machine_data) if os.environ.has_key('DEBUG'): self.log.info("ProfileInstaller.machine_data: %s" % self.installer.machine_data) self.installer.set_profile(profile) self.set_suite(self.installer.suite) def _bootstrap_with_tarball(self, suite): self.check_target_exists() suite_path = path(self.defenv.get('installer', 'suite_storage')) arch = get_architecture() filename = '%s-%s.tar.gz' % (suite, arch) basefile = suite_path / filename taropts = '-xzf' # we normally expect a tar.gz # but we'll check for a plain tar also if not basefile.exists(): filename = '%s-%s.tar' % (suite, arch) basefile = suite_path / filename taropts = '-xf' if not basefile.exists(): # We don't really want to ruin an install # by not having a tarball, so we log a warning # and proceed with a debootstrap. msg = "base tarball not found, reverting to debootstrap" self.log.warn(msg) self._bootstrap_with_debootstrap(suite) else: #cmd = 'tar -C %s %s %s' % (self.target, taropts, basefile) cmd = ['tar', '-C', str(self.target), taropts, str(basefile)] # if cmd returns nonzero, runlog will raise an error runlog(cmd) # we need to do certain things after extraction # that debootstrap does for us, # like copy /etc/resolv.conf to the target. # these things should be done in the # ready_base_for_install process # this is now done in post_process #self._bootstrapped = True def _bootstrap_with_debootstrap(self, suite): self.check_target_exists() mirror = self.defenv.get('installer', 'http_mirror') # debug stuff cmd = debootstrap(suite, self.target, mirror) # if cmd returns nonzero, runlog will raise an error runlog(cmd) # this is now done in post_process #self._bootstrapped = True def bootstrap_target(self): self.check_suite_set() if not self.target.exists(): self.target.mkdir() if not self.target.isdir(): raise InstallTargetError, "%s is not a directory" % self.target if self.defenv.getboolean('installer', 'bootstrap_target'): self.log.info('bootstrapping with debootstrap') self._bootstrap_with_debootstrap(self.base_suite) else: self.log.info('bootstrapping with premade tarball') self._bootstrap_with_tarball(self.base_suite) # here we add the apt keys that are needed # we should probably split this part off into # another process. This step needs to be done # before the ready_base_for_install process, or # at least at the beginning of that process. aptkeys = AptKeyHandler(self.conn) keys = self.defenv.get_list('archive_keys', 'installer') for key in keys: try: row = aptkeys.get_row(key) except NoAptKeyError: msg = "There's no apt key named %s in the database" % key self.log.error(msg) raise UnsatisfiedRequirementsError , msg filename = self.target / ('%s.key' % key) if filename.exists(): msg = "%s already exists" % filename self.log.error(msg) raise RuntimeError , msg keyfile = file(filename, 'w') keyfile.write(row.data) keyfile.close() self.chroot(['apt-key', 'add', '%s.key' % key]) os.remove(filename) if filename.exists(): msg = "%s wasn't deleted" % filename self.log.error(msg) raise RuntimeError , msg self.log.info('added key %s (%s) to apt' % (key, row.keyid)) def make_device_entries(self): self.check_bootstrap() self.log.info('nothing done for make_device_entries yet') def apt_sources_installer(self): self.check_bootstrap() make_sources_list(self.conn, self.target, self.suite) def apt_sources_final(self): self.check_install_complete() sourceslist = self.target / 'etc/apt/sources.list' sourceslist_installer = path('%s.installer' % sourceslist) os.rename(sourceslist, sourceslist_installer) make_official_sources_list(self.conn, self.target, self.suite) def ready_base_for_install(self): """This gets the base that was either debootstrapped or extracted ready to install packages. Since the install hasn't happened yet, replacing files like /etc/resolv.conf and the package lists shouldn't affect anything. the apt_sources_installer process is called right before this one, so there should be an appropriate sources.list to update packages with. """ self.check_bootstrap() # 'copy' /etc/resolv.conf to target resolvconf = file('/etc/resolv.conf').read() target_resolvconf = self.target / 'etc/resolv.conf' target_resolvconf.write_text(resolvconf) # update the package lists self.chroot(['apt-get', '-y', 'update']) # common method for mounting /proc and /sys # here fs is either 'proc' or 'sys' or 'devpts' def _mount_target_virtfs(self, fs): fstype = dict(proc='proc', sys='sysfs', devpts='devpts') target = self.target / fs if fs == 'devpts': target = self.target / 'dev' / 'pts' if not target.isdir(): self.log.info('creating %s' % target) target.mkdir() #cmd = 'mount -t %s none %s' % (fstype[fs], target) cmd = ['mount', '-t', fstype[fs], 'none', str(target)] runlog(cmd) def _umount_target_virtfs(self, fs): self.log.info('running umount for %s' % fs) # work around binfmt-support /proc locking # found this idea while messing around in live-helper target = self.target / fs if fs == 'proc': binfmt_misc = self.target / 'proc/sys/fs/binfmt_misc' status = binfmt_misc / 'status' if status.exists(): self.log.info('Unmounting /proc/sys/fs/binfmt_misc in chroot') #cmd = 'umount %s' % binfmt cmd = ['umount', str(binfmt_misc)] runlog(cmd) # hack to stop mdadm on target mdstat = self.target / 'proc/mdstat' if mdstat.isfile(): mdadm_initscript = self.target / 'etc/init.d/mdadm' if mdadm_initscript.isfile(): self.log.info("Stopping mdadm from running on target.") cmd = ['chroot', self.target, '/etc/init.d/mdadm', 'stop'] runlog(cmd) if fs == 'devpts': target = self.target / 'dev' / 'pts' #cmd = 'umount %s' % target cmd = ['umount', str(target)] runlog(cmd) def _target_proc_mounted(self): testfile = self.target / 'proc/version' return testfile.isfile() def _target_sys_mounted(self): testdir = self.target / 'sys/kernel' return testdir.isdir() def mount_target_proc(self): self.check_bootstrap() self._mount_target_virtfs('proc') def mount_target_sys(self): self.check_bootstrap() self._mount_target_virtfs('sys') def mount_target_devpts(self): self.check_bootstrap() self._mount_target_virtfs('devpts') def umount_target_proc(self): self.check_target_proc_mounted() self._umount_target_virtfs('proc') def umount_target_sys(self): self.check_target_sys_mounted() self._umount_target_virtfs('sys') def umount_target_devpts(self): self._umount_target_virtfs('devpts') def install(self): self.check_target_proc_mounted() self.check_target_sys_mounted() self.check_installer_set() self.installer.run_all_processes() # this is now done in post_process #self._install_finished = True def log_all_processes_finished(self): self.log.info('-'*30) self.log.info('%s processes finished' % self.__class__.__name__) self.log.info('-'*30) def save_logfile_in_target(self): install_log = self.target / 'root/paella/install.log' self.mainlog.filename.copyfile(install_log) # if scripts are hooked into certain processes, we # need to mark those processes as being completed # in order for other processes to be run. def post_process(self, procname): name = self.__class__.__name__ self.log.info('%s(%s) post_process' % (name, procname)) if procname == 'bootstrap': self.log.info('%s marking %s finished' % (name, procname)) self._bootstrapped = True elif procname == 'install': self.log.info('%s marking %s finished' % (name, procname)) self._install_finished = True
class ChrootInstaller(BaseChrootInstaller): def __init__(self, conn, logfile=None): BaseChrootInstaller.__init__(self, conn) self.conn = conn self.cursor = StatementCursor(self.conn) self._mounted = None self._installer_ready = False self._base_ready = False if logfile is None: self.set_logfile(logfile) if logfile and type(logfile) is str: if not os.environ.has_key('PAELLA_LOGFILE'): os.environ['PAELLA_LOGFILE'] = logfile self.set_logfile(logfile) if logfile is False: pass def _check_base_ready(self): if not self._base_ready: raise InstallError, 'base is not ready for install.' def set_profile(self, profile): self.profile = profile def ready_target(self): self._check_target_exists() def setup_installer(self): self.installer = ProfileInstaller(self.conn) self.installer.log = self.log self.installer.set_profile(self.profile) self.suite = self.installer.suite self._installer_ready = True def bootstrap_target(self): self._bootstrap_target() self._check_bootstrap() def ready_base_for_install(self): self._check_bootstrap() fstab = '#unconfigured for chroot install\n' ready_base_for_install(self.target, self.conn, self.suite, fstab) self._mount_target_proc() self._check_target_proc() cmd = self.command('apt-get', '-y update', chroot=True) runvalue = runlog(cmd) if runvalue: raise InstallError, 'problem updating the apt lists.' if os.environ.has_key('FAKE_START_STOP_DAEMON'): make_fake_start_stop_daemon(self.target) self._base_ready = True def install_to_target(self): self._check_base_ready() os.environ['DEBIAN_FRONTEND'] = 'noninteractive' self.installer.set_target(self.target) self.installer.process() def post_install(self): self._umount_target_proc() if os.environ.has_key('FAKE_START_STOP_DAEMON'): remove_fake_start_stop_daemon(self.target) def install(self, profile, target): self.set_profile(profile) self.setup_installer() self.set_target(target) self.ready_target() self.bootstrap_target() self.ready_base_for_install() self.install_to_target() self.post_install()
class NewInstaller(object): def __init__(self, conn, cfg): object.__init__(self) self.conn = conn self.cfg = cfg self.machine = MachineHandler(self.conn) self.cursor = StatementCursor(self.conn) self.target = None self.installer = None self._mounted = None self._bootstrapped = None self.debmirror = self.cfg.get('debrepos', 'http_mirror') self._raid_setup = False self._raid_drives = {} def _check_target(self): if not self.target: raise Error, 'no target specified' def _check_installer(self): if not self.installer: raise Error, 'no installer available' def _check_mounted(self): self._check_target() if not self._mounted: raise Error, 'target not mounted' def _check_bootstrap(self): self._check_mounted() if not self._bootstrapped: raise Error, 'target not bootstrapped' def set_machine(self, machine): self.machine.set_machine(machine) try: logfile = os.environ['LOGFILE'] except KeyError: logfile = '/paellalog/paella-install-%s.log' % machine os.environ['LOGFILE'] = logfile os.environ['PAELLA_MACHINE'] = machine def make_filesystems(self): device = self.machine.array_hack(self.machine.current.machine_type) mddev = False if device == '/dev/md': mdnum = 0 mddev = True all_fsmounts = self.machine.get_installable_fsmounts() env = CurrentEnvironment(self.conn, self.machine.current.machine) for row in all_fsmounts: if mddev: pdev = '/dev/md%d' % mdnum mdnum += 1 else: pdev = device + str(row.partition) if row.mnt_name in env.keys(): print '%s held' % row.mnt_name else: print 'making filesystem for', row.mnt_name make_filesystem(pdev, row.fstype) def set_target(self, target): self.target = target def _pdev(self, device, partition): return device + str(partition) def ready_target(self): self._check_target() makepaths(self.target) device = self.machine.array_hack(self.machine.current.machine_type) clause = Eq('filesystem', self.machine.current.filesystem) clause &= Gt('partition', '0') table = 'filesystem_mounts natural join mounts' mounts = self.cursor.select(table=table, clause=clause, order='mnt_point') if mounts[0].mnt_point != '/': raise Error, 'bad set of mounts', mounts mddev = False mdnum = 0 if device == '/dev/md': mddev = True pdev = '/dev/md0' mdnum += 1 else: pdev = self._pdev(device, mounts[0].partition) print 'mounting target', pdev, self.target clause &= Neq('mnt_point', '/') mounts = self.cursor.select(table=table, clause=clause, order='ord') runlog('mount %s %s' % (pdev, self.target)) for mnt in mounts: tpath = os.path.join(self.target, mnt.mnt_point[1:]) makepaths(tpath) if mddev: pdev = '/dev/md%d' % mdnum else: pdev = self._pdev(device, mnt.partition) mdnum += 1 runlog('mount %s %s' % (pdev, tpath)) self._mounted = True def setup_installer(self): profile = self.machine.current.profile self.installer = ProfileInstaller(self.conn, self.cfg) self.installer.set_profile(profile) self.suite = self.installer.suite def organize_disks(self): return self.machine.check_machine_disks( self.machine.current.machine_type) def partition_disks(self): disks = self.organize_disks() for diskname in disks: for device in disks[diskname]: self._partition_disk(diskname, device) if len(disks[diskname]) > 1: self._raid_setup = True self._raid_drives[diskname] = disks[diskname] ndev = len(disks[diskname]) print 'doing raid setup on %s' % diskname fs = self.machine.current.filesystem print fs pnums = [ r.partition for r in self.machine.get_installable_fsmounts(fs) ] mdnum = 0 for p in pnums: mdadm = 'mdadm --create /dev/md%d' % mdnum mdadm = '%s --force -l1 -n%d ' % (mdadm, ndev) devices = ['%s%s' % (d, p) for d in disks[diskname]] command = mdadm + ' '.join(devices) print command yesman = 'bash -c "yes | %s"' % command print yesman os.system(yesman) mdnum += 1 print 'doing raid setup on %s' % str(disks[diskname]) mdstat = file('/proc/mdstat').read() while mdstat.find('resync') > -1: sleep(10) mdstat = file('/proc/mdstat').read() def _partition_disk(self, diskname, device): print 'partitioning', diskname, device dump = self.machine.make_partition_dump(diskname, device) i, o = os.popen2('sfdisk %s' % device) i.write(dump) i.close() def bootstrap_target(self): self._check_mounted() self._check_installer() runlog(debootstrap(self.suite, self.target, self.debmirror)) self._bootstrapped = True def _make_generic_devices(self, devices): here = os.getcwd() os.chdir(join(self.target, 'dev')) for dev in devices: runlog('echo making device %s with MAKEDEV' % dev) runlog('./MAKEDEV %s' % dev) os.chdir(here) def make_disk_devices(self): devices = map(basename, self.machine.get_disk_devices()) self._make_generic_devices(devices) def make_tty_devices(self): self._make_generic_devices(['console']) def make_input_devices(self): self._make_generic_devices(['input']) def make_generic_devices(self): #devices = ['std', 'console', 'pty', 'tap', 'sg', 'input', 'audio'] self._make_generic_devices(['generic']) def ready_base_for_install(self): self._check_bootstrap() self._check_installer() fstab = self.machine.make_fstab() ready_base_for_install(self.target, self.cfg, self.suite, fstab) self.make_generic_devices() self.make_disk_devices() if self._raid_setup: mdpath = join(self.target, 'etc/mdadm') makepaths(mdpath) mdconfname = join(mdpath, 'mdadm.conf') mdconf = file(mdconfname, 'w') for diskname in self._raid_drives: devices = ['%s*' % d for d in self._raid_drives[diskname]] line = 'DEVICE %s' % ' '.join(devices) mdconf.write(line + '\n') mdconf.close() mdconf = file(mdconfname, 'a') arrdata = commands.getoutput('mdadm -E --config=%s -s' % mdconfname) mdconf.write(arrdata + '\n') mdconf.write('\n') mdconf.close() def install_to_target(self): os.environ['DEBIAN_FRONTEND'] = 'noninteractive' self._check_target() self._check_installer() self.installer.set_target(self.target) self.installer.process() def post_install(self): print 'post_install' modules = self.machine.get_modules() print 'installing modules', modules setup_modules(self.target, modules) print 'modules installed' kernel = self.machine.current.kernel print 'installing kernel', kernel install_kernel(kernel, self.target) print 'kernel installed' def install(self, machine, target): self.set_machine(machine) self.partition_disks() self.make_filesystems() self.setup_installer() self.set_target(target) self.ready_target() self.bootstrap_target() self.ready_base_for_install() self.install_to_target() self.post_install()
class InstallerTools(object): def __init__(self): object.__init__(self) self.cfg = PaellaConfig() self.conn = InstallerConnection() self.profile = os.environ['PAELLA_PROFILE'] self.target = os.environ['PAELLA_TARGET'] self.machine = None self.trait = None self.suite = get_suite(self.conn, self.profile) self.pr = Profile(self.conn) self.pr.set_profile(self.profile) self.traitlist = self.pr.make_traitlist() self.pe = ProfileEnvironment(self.conn, self.profile) self.tp = TraitParent(self.conn, self.suite) self.fm = Family(self.conn) self.tr = Trait(self.conn, self.suite) self.families = list( self.fm.get_related_families(self.pr.get_families())) self._envv = None self.default = DefaultEnvironment(self.conn) #self.installer = TraitInstaller(self.conn, self.suite) self.installer = ProfileInstaller(self.conn) self.installer.set_logfile() self.installer.set_profile(self.profile) self.installer.set_target(self.target) if os.environ.has_key('PAELLA_MACHINE'): self.machine = os.environ['PAELLA_MACHINE'] if os.environ.has_key('PAELLA_TRAIT'): self.set_trait(os.environ['PAELLA_TRAIT']) def env(self): env = RefDict(self.tp.Environment()) env.update(self.pr.get_family_data()) env.update(self.pr.get_profile_data()) return env def set_trait(self, trait): self.trait = trait self.tp.set_trait(trait) self.tr.set_trait(trait) self.parents = self.tr.parents() self._envv = self.env() tinstaller = self.installer.installer tinstaller.set_trait(trait) self.packages = tinstaller.traitpackage.packages() self.templates = tinstaller.traittemplate.templates() def get(self, key): if self._envv is None: raise Error, 'need to set trait first' return self._envv.dereference(key) def install_modules(self, name): modules = str2list(self.get(name)) print 'installing modules', modules, 'to %s/etc/modules' % self.target setup_modules(self.target, modules) def remove_packages(self, packages=None): if packages is None: packages = self.packages if len(packages): if hasattr(packages[0], 'package'): packages = [p.package for p in packages] package_list = ' '.join(packages) command = 'apt-get -y remove %s' % package_list self.installer.run('remove', command, proc=True)
class InstallerTools(object): def __init__(self): object.__init__(self) self.cfg = PaellaConfig() self.conn = InstallerConnection() self.profile = os.environ['PAELLA_PROFILE'] self.target = path(os.environ['PAELLA_TARGET']) self.machine = None self.trait = None self.suite = get_suite(self.conn, self.profile) self.pr = Profile(self.conn) self.pr.set_profile(self.profile) self.traitlist = self.pr.make_traitlist() self.pe = ProfileEnvironment(self.conn, self.profile) self.tp = TraitParent(self.conn, self.suite) self.fm = Family(self.conn) self.tr = Trait(self.conn, self.suite) self.families = list(self.fm.get_related_families(self.pr.get_families())) self._envv = None self.default = DefaultEnvironment(self.conn) #self.installer = TraitInstaller(self.conn, self.suite) self.installer = ProfileInstaller(self.conn) self.installer.set_logfile() self.installer.set_profile(self.profile) self.installer.set_target(self.target) if os.environ.has_key('PAELLA_MACHINE'): self.machine = os.environ['PAELLA_MACHINE'] if os.environ.has_key('PAELLA_TRAIT'): self.set_trait(os.environ['PAELLA_TRAIT']) # this needs updating for machine type data def env(self): env = TemplatedEnvironment(self.tp.Environment()) env.update(self.pr.get_family_data()) env.update(self.pr.get_profile_data()) return env def set_trait(self, trait): self.trait = trait self.tp.set_trait(trait) self.tr.set_trait(trait) self.parents = self.tr.parents() self._envv = self.env() tinstaller = self.installer.installer tinstaller.set_trait(trait) self.packages = tinstaller.traitpackage.packages() self.templates = tinstaller.traittemplate.templates() def get(self, key): if self._envv is None: raise Error, 'need to set trait first' return self._envv.dereference(key) def lget(self, key): key = '_'.join([self.trait, key]) return self.get(key) def install_modules(self, name): modules = str2list(self.get(name)) print 'installing modules', modules, 'to %s/etc/modules' % self.target setup_modules(self.target, modules) def remove_packages(self, packages=None): if packages is None: packages = self.packages if len(packages): if hasattr(packages[0], 'package'): packages = [p.package for p in packages] package_list = ' '.join(packages) command = 'apt-get -y remove %s' % package_list self.installer.run('remove', command, proc=True) def chroot_command(self, cmd): return 'chroot %s %s' % (self.target, cmd)
class NewInstaller(object): def __init__(self, conn, cfg): object.__init__(self) self.conn = conn self.cfg = cfg self.defenv = DefaultEnvironment(self.conn) self.machine = MachineHandler(self.conn) self.cursor = StatementCursor(self.conn) self.target = None self.installer = None self._mounted = None self._bootstrapped = None self.debmirror = self.cfg.get('debrepos', 'http_mirror') self._raid_setup = False self._raid_drives = {} self._enable_bad_hacks = False if self.cfg.is_it_true('installer', 'enable_bad_hacks'): self._enable_bad_hacks = True def set_logfile(self, logfile): env = os.environ if logfile is None: if env.has_key('PAELLA_LOGFILE'): self.logfile = env['PAELLA_LOGFILE'] elif env.has_key('LOGFILE'): self.logfile = env['LOGFILE'] elif self.defenv.has_option('installer', 'default_logfile'): self.logfile = self.defenv.get('installer', 'default_logfile') else: raise InstallSetupError, 'There is no log file defined, giving up.' else: self.logfile = logfile logdir = os.path.dirname(self.logfile) if logdir: makepaths(os.path.dirname(self.logfile)) format = '%(name)s - %(asctime)s - %(levelname)s: %(message)s' self.log = Log('paella-installer', self.logfile, format) def _check_target(self): if not self.target: raise Error, 'no target specified' def _check_installer(self): if not self.installer: raise Error, 'no installer available' def _check_mounted(self): self._check_target() if not self._mounted: raise InstallError, 'target not mounted' def _check_bootstrap(self): self._check_mounted() if not self._bootstrapped: raise Error, 'target not bootstrapped' def set_machine(self, machine): self.machine.set_machine(machine) try: logfile = os.environ['LOGFILE'] except KeyError: logfile = '/paellalog/paella-install-%s.log' % machine os.environ['LOGFILE'] = logfile os.environ['PAELLA_MACHINE'] = machine disklogpath = join(dirname(logfile), 'disklog') if not os.path.isdir(disklogpath): makepaths(disklogpath) self.disklogpath = disklogpath self.curenv = CurrentEnvironment(self.conn, self.machine.current.machine) self.set_logfile(logfile) def check_if_mounted(self, device): mounts = file('/proc/mounts') for line in file: if line.startswith(device): return True return False def unmount_device(self, device): mounted = os.system('umount %s' % device) def make_filesystems(self): device = self.machine.array_hack(self.machine.current.machine_type) mddev = False if device == '/dev/md': mdnum = 0 mddev = True all_fsmounts = self.machine.get_installable_fsmounts() env = CurrentEnvironment(self.conn, self.machine.current.machine) for row in all_fsmounts: if mddev: pdev = '/dev/md%d' % mdnum mdnum += 1 else: pdev = device + str(row.partition) if row.mnt_name in env.keys(): print '%s held' % row.mnt_name elif row.fstype == 'swap': runlog('echo making swap on %s' % pdev) runlog('mkswap %s' % pdev) else: print 'making filesystem for', row.mnt_name make_filesystem(pdev, row.fstype) def set_target(self, target): self.target = target def _pdev(self, device, partition): return device + str(partition) def _mount_target_proc(self): self._check_bootstrap() tproc = join(self.target, 'proc') cmd = 'mount --bind /proc %s' % tproc runvalue = runlog(cmd) if runvalue: raise InstallError, 'problem mounting target /proc at %s' % tproc else: self._proc_mounted = True def _umount_target_proc(self): tproc = join(self.target, 'proc') cmd = 'umount %s' % tproc runvalue = runlog(cmd) if runvalue: raise InstallError, 'problem unmounting target /proc at %s' % tproc else: self._proc_mounted = False def ready_target(self): self._check_target() makepaths(self.target) device = self.machine.array_hack(self.machine.current.machine_type) clause = Eq('filesystem', self.machine.current.filesystem) clause &= Gt('partition', '0') table = 'filesystem_mounts natural join mounts' mounts = self.cursor.select(table=table, clause=clause, order='mnt_point') if mounts[0].mnt_point != '/': raise Error, 'bad set of mounts', mounts mddev = False mdnum = 0 if device == '/dev/md': mddev = True pdev = '/dev/md0' mdnum += 1 else: pdev = self._pdev(device, mounts[0].partition) runlog('echo mounting target %s to %s ' % (pdev, self.target)) clause &= Neq('mnt_point', '/') mounts = self.cursor.select(table=table, clause=clause, order='ord') mountable = [mount for mount in mounts if mount.fstype != 'swap'] runlog('mount %s %s' % (pdev, self.target)) for mnt in mountable: tpath = os.path.join(self.target, mnt.mnt_point[1:]) makepaths(tpath) if mddev: pdev = '/dev/md%d' % mdnum else: pdev = self._pdev(device, mnt.partition) mdnum += 1 runlog('mount %s %s' % (pdev, tpath)) self._mounted = True def setup_installer(self): profile = self.machine.current.profile self.installer = ProfileInstaller(self.conn) self.installer.log = self.log self.installer.set_profile(profile) self.suite = self.installer.suite def organize_disks(self): return self.machine.check_machine_disks( self.machine.current.machine_type) def _setup_disks(self, diskname, disks=None): if disks is None: disks = self.organize_disks() devices = disks[diskname] def setup_disks(self): disks = self.organize_disks() disknames = disks.keys() if not len(disknames): self._setup_disk_fai('default', '/dev/hda') else: if len(disknames) > 1: #this isn't really handled yet self.partition_disks() self.make_filesystems() else: devices = disks[disknames[0]] if len(devices) > 1: #this is a raid setup self.partition_disks() self.make_filesystems() elif len(devices) == 1: self._setup_disk_fai(self.machine.current.filesystem, devices[0]) else: self._setup_disk_fai('default', '/dev/hda') def _setup_disk_fai(self, filesystem, device): disk_config = self.machine.make_disk_config_info(device) fileid, disk_config_path = tempfile.mkstemp('paella', 'diskinfo') disk_config_file = file(disk_config_path, 'w') disk_config_file.write(disk_config) disk_config_file.close() script = '/usr/lib/paella/scripts/setup_harddisks_fai' options = '-X -f %s' % disk_config_path env = 'env LOGDIR=%s diskvar=%s' % (self.disklogpath, join(self.disklogpath, 'diskvar')) command = '%s %s %s' % (env, script, options) runlog(command) def _setup_raid_drives(self, diskname, devices): self._raid_setup = True self._raid_drives[diskname] = devices for device in devices: self._partition_disk(diskname, device) ndev = len(devices) print 'doing raid setup on %s' % diskname fs = self.machine.current.filesystem print fs pnums = [ r.partition for r in self.machine.get_installable_fsmounts(fs) ] mdnum = 0 for p in pnums: mdadm = 'mdadm --create /dev/md%d' % mdnum mdadm = '%s --force -l1 -n%d ' % (mdadm, ndev) devices = ['%s%s' % (d, p) for d in devices] command = mdadm + ' '.join(devices) print command yesman = 'bash -c "yes | %s"' % command print yesman os.system(yesman) mdnum += 1 print 'doing raid setup on %s' % str(devices) mdstat = file('/proc/mdstat').read() while mdstat.find('resync') > -1: sleep(10) mdstat = file('/proc/mdstat').read() def partition_disks(self): disks = self.organize_disks() for diskname in disks: for device in disks[diskname]: self._partition_disk(diskname, device) if len(disks[diskname]) > 1: self._raid_setup = True self._raid_drives[diskname] = disks[diskname] ndev = len(disks[diskname]) print 'doing raid setup on %s' % diskname fs = self.machine.current.filesystem print fs pnums = [ r.partition for r in self.machine.get_installable_fsmounts(fs) ] mdnum = 0 for p in pnums: mdadm = 'mdadm --create /dev/md%d' % mdnum mdadm = '%s --force -l1 -n%d ' % (mdadm, ndev) devices = ['%s%s' % (d, p) for d in disks[diskname]] command = mdadm + ' '.join(devices) print command yesman = 'bash -c "yes | %s"' % command print yesman os.system(yesman) mdnum += 1 print 'doing raid setup on %s' % str(disks[diskname]) mdstat = file('/proc/mdstat').read() while mdstat.find('resync') > -1: sleep(10) mdstat = file('/proc/mdstat').read() def _partition_disk(self, diskname, device): print 'partitioning', diskname, device dump = self.machine.make_partition_dump(diskname, device) i, o = os.popen2('sfdisk %s' % device) i.write(dump) i.close() def extract_basebootstrap(self): self._check_mounted() self._check_installer() runlog('echo extracting premade base tarball') suite_path = self.cfg.get('installer', 'suite_storage') basefile = join(suite_path, '%s.tar' % self.suite) runvalue = runlog('tar -C %s -xf %s' % (self.target, basefile)) if runvalue: raise Error, 'problems extracting %s' % basefile self._bootstrapped = True def bootstrap_target(self): self._check_mounted() self._check_installer() runlog(debootstrap(self.suite, self.target, self.debmirror)) self._bootstrapped = True def _make_generic_devices(self, devices): here = os.getcwd() os.chdir(join(self.target, 'dev')) for dev in devices: runlog('echo making device %s with MAKEDEV' % dev) runlog('./MAKEDEV %s' % dev) os.chdir(here) def _extract_devices_tarball(self): dtball = self.cfg.get('installer', 'devices_tarball') devpath = join(self.target, 'dev') cmd = 'tar -C %s -xf %s' % (devpath, dtball) runvalue = runlog(cmd) if runvalue: raise Error, 'problem extracting devices tarball' def make_disk_devices(self): devices = map(basename, self.machine.get_disk_devices()) self._make_generic_devices(devices) def make_tty_devices(self): self._make_generic_devices(['console']) def make_input_devices(self): self._make_generic_devices(['input']) def make_generic_devices(self): #devices = ['std', 'console', 'pty', 'tap', 'sg', 'input', 'audio'] self._make_generic_devices(['generic']) def ready_base_for_install(self): self._check_bootstrap() self._check_installer() fstab = self.machine.make_fstab() ready_base_for_install(self.target, self.cfg, self.suite, fstab) if self.cfg.is_it_true('installer', 'use_devices_tarball'): runlog('echo extracting devices tarball') self._extract_devices_tarball() else: runlog('echo using MAKEDEV to make devices') self.make_generic_devices() self.make_disk_devices() if self._raid_setup: mdpath = join(self.target, 'etc/mdadm') makepaths(mdpath) mdconfname = join(mdpath, 'mdadm.conf') mdconf = file(mdconfname, 'w') for diskname in self._raid_drives: devices = ['%s*' % d for d in self._raid_drives[diskname]] line = 'DEVICE %s' % ' '.join(devices) mdconf.write(line + '\n') mdconf.close() mdconf = file(mdconfname, 'a') arrdata = commands.getoutput('mdadm -E --config=%s -s' % mdconfname) mdconf.write(arrdata + '\n') mdconf.write('\n') mdconf.close() self._mount_target_proc() def install_to_target(self): os.environ['DEBIAN_FRONTEND'] = 'noninteractive' self._check_target() self._check_installer() self.installer.set_target(self.target) self.installer.process() def post_install(self): print 'post_install' modules = self.machine.get_modules() print 'installing modules', modules setup_modules(self.target, modules) print 'modules installed' kernel = self.machine.current.kernel print 'installing kernel', kernel install_kernel(kernel, self.target) print 'kernel installed' def install(self, machine, target): self.set_machine(machine) if self._enable_bad_hacks: self.setup_disks() else: self.partition_disks() self.make_filesystems() self.setup_installer() self.set_target(target) self.ready_target() if self.cfg.is_it_true('installer', 'bootstrap_target'): self.bootstrap_target() else: self.extract_basebootstrap() self.ready_base_for_install() self.install_to_target() self.post_install()
class MachineInstaller(BaseChrootInstaller): def __init__(self, conn): BaseChrootInstaller.__init__(self, conn) self.machine = MachineHandler(self.conn) self.processes = DEFAULT_PROCESSES self._process_map = { 'setup_disks': self.setup_disks, 'mount_target': self.mount_target, 'bootstrap': self.bootstrap_target, 'make_device_entries': self.make_device_entries, 'apt_sources_installer': self.setup_apt_sources_installer, 'ready_base': self.ready_base_for_install, 'mount_target_proc': self.mount_target_proc, 'install': self.install_to_target, 'install_fstab': self.install_fstab, 'install_modules': self.install_modules, 'install_kernel': self.install_kernel, 'apt_sources_final': self.setup_apt_sources_final, 'umount_target_proc': self.umount_target_proc } self.helper = None def process(self): mach = self.machine.current.machine self.log.info('Starting machine install process for %s' % mach) for proc in self.processes: self.log.info('processing %s for machine %s' % (proc, mach)) self.run_process(proc) self.log.info('processed %s for machine %s' % (proc, mach)) self.log.info('Ending machine install process for %s' % mach) def _make_script(self, name): script = self.machine.get_script(name) if script is not None: return make_script(name, script, '/') else: return None def run_process(self, proc): info = self.log.info self.start_process(proc) script = self._make_script(proc) mtype = self.machine.current.machine_type if script is None: info('No script for process %s on machine type %s' % (proc, mtype)) if proc in self._process_map: info('Running default process %s' % proc) self._process_map[proc]() else: info('Nothing to do for process %s' % proc) else: self.log.info('%s script exists for %s' % (proc, mtype)) self.run_process_script(proc, script) self.finish_process(proc) def start_process(self, proc): self._check_target() if proc == 'bootstrap': self._check_target_exists() def finish_process(self, proc): if proc == 'mount_target': self._mounted = True self.log.info('Target should be mounted now.') elif proc == 'bootstrap': self.log.info('Target should be bootstrapped now.') self._bootstrapped = True def _runscript(self, script, name, info): self.log.info(info['start']) runvalue = self.run(name, script, chroot=False) os.remove(script) self.log.info(info['done']) return runvalue def run_process_script(self, proc, script): info = scriptinfo(proc) if self._runscript(script, proc, info): raise InstallError, 'Error running script %s' % proc def _check_mounted(self): self._check_target_exists() if not self._mounted: raise InstallError, 'target not mounted' def _check_bootstrap(self): self._check_mounted() BaseChrootInstaller._check_bootstrap(self) def set_machine(self, machine): self.machine.set_machine(machine) try: logfile = os.environ['LOGFILE'] except KeyError: logfile = '/paellalog/paella-install-%s.log' % machine os.environ['PAELLA_LOGFILE'] = logfile # this needs to be removed sometime os.environ['LOGFILE'] = logfile os.environ['PAELLA_MACHINE'] = machine disklogpath = join(dirname(logfile), 'disklog-%s' % machine) if not os.path.isdir(disklogpath): makepaths(disklogpath) self.disklogpath = disklogpath self.curenv = CurrentEnvironment(self.conn, self.machine.current.machine) self.set_logfile(logfile) self.log.info('Machine Installer set machine to %s' % machine) self.mtypedata = self.machine.mtype.get_machine_type_data() def install(self, machine, target): self.set_machine(machine) self.setup_installer() self.set_target(target) makepaths(target) self.log.info('Installer set to install %s to %s' % (machine, target)) self.helper = MachineInstallerHelper(self) self.helper.curenv = self.curenv self.process() def setup_installer(self): machine = self.machine.current.machine profile = self.machine.current.profile self.log.info('Setting up profile installer for %s' % machine) self.installer = ProfileInstaller(self.conn) self.installer.log = self.log self.installer.mtypedata = self.mtypedata self.installer.set_profile(profile) self.suite = self.installer.suite self._installer_ready = True self.log.info('Profile installer ready for %s' % machine) def setup_disks(self): "this is a default process" self.helper.setup_disks() def mount_target(self): "this is a default process" self._check_target() makepaths(self.target) device = self.machine.array_hack() #mounts = self.machine.get_ordered_fsmounts() mounts = self.machine.get_installable_fsmounts() mount_target(self.target, mounts, device) self._mounted = True def bootstrap_target(self): "this is a default process" self.helper.bootstrap_target() def make_device_entries(self): "this is a default process" if self.defenv.is_it_true('installer', 'use_devices_tarball'): runlog('echo extracting devices tarball') self._extract_devices_tarball() else: runlog('echo using MAKEDEV to make generic devices') self.make_generic_devices() self.make_disk_devices() def setup_apt_sources_installer(self): "this is a default process" make_sources_list(self.conn, self.target, self.suite) def ready_base_for_install(self): "this is a default process" set_root_passwd(self.target, myline) make_interfaces_simple(self.target) devices = self.helper.get_raid_devices() if devices: create_mdadm_conf(self.target, devices) def mount_target_proc(self): "this is a default process" echo('mounting target /proc') mount_target_proc(self.target) def install_to_target(self): "this is a default process" os.environ['DEBIAN_FRONTEND'] = 'noninteractive' self._check_target() self._check_installer() self.installer.set_target(self.target) self.installer.process() def install_modules(self): "this is a default process" modules = self.machine.get_modules() setup_modules(self.target, modules) def install_kernel(self): "this is a default process" kernel = self.machine.current.kernel echo('installing kernel %s' % kernel) install_kernel(kernel, self.target) def setup_apt_sources_final(self): "this is a default process" make_official_sources_list(self.conn, self.target, self.suite) def install_fstab(self): "this is a default process" fstab = self.machine.make_fstab() make_fstab(fstab, self.target) def umount_target_proc(self): "this is a default process" echo('unmounting target /proc') mount_target_proc(self.target, umount=True) def _extract_devices_tarball(self): dtball = self.defenv.get('installer', 'devices_tarball') devpath = join(self.target, 'dev') runvalue = extract_tarball(devpath, dtball) if runvalue: raise Error, 'problem extracting devices tarball' def make_generic_devices(self): makedev(self.target, ['generic']) def make_disk_devices(self): devices = map(basename, self.machine.get_disk_devices()) makedev(self.target, devices)
class ChrootInstaller(object): def __init__(self, conn, cfg): object.__init__(self) self.conn = conn self.cfg = cfg self.cursor = StatementCursor(self.conn) self.target = None self.installer = None self._mounted = None self._bootstrapped = None self.debmirror = self.cfg.get('debrepos', 'http_mirror') def _check_target(self): if not self.target: raise Error, 'no target specified' def _check_installer(self): if not self.installer: raise Error, 'no installer available' def _check_bootstrap(self): self._check_target() if not self._bootstrapped: raise Error, 'target not bootstrapped' def set_target(self, target): self.target = target def set_profile(self, profile): self.profile = profile def ready_target(self): self._check_target() def setup_installer(self): self.installer = ProfileInstaller(self.conn, self.cfg) self.installer.set_profile(self.profile) self.suite = get_suite(self.conn, self.profile) def bootstrap_target(self): self._check_target() self._check_installer() runlog(debootstrap(self.suite, self.target, self.debmirror)) self._bootstrapped = True def ready_base_for_install(self): self._check_bootstrap() self._check_installer() fstab = '#unconfigured for chroot install\n' ready_base_for_install(self.target, self.cfg, self.suite, fstab) def install_to_target(self): os.environ['DEBIAN_FRONTEND'] = 'noninteractive' self._check_target() self._check_installer() self.installer.set_target(self.target) self.installer.process() def post_install(self): print 'post_install' kernel = self.machine.current.kernel print 'installing kernel', kernel install_kernel(kernel, self.target) print 'kernel installed' def install(self, profile, target): self.set_profile(profile) self.setup_installer() self.set_target(target) self.ready_target() self.bootstrap_target() self.ready_base_for_install() self.install_to_target()
class NewInstaller(object): def __init__(self, conn, cfg): object.__init__(self) self.conn = conn self.cfg = cfg self.machine = MachineHandler(self.conn) self.cursor = StatementCursor(self.conn) self.target = None self.installer = None self._mounted = None self._bootstrapped = None self.debmirror = self.cfg.get('debrepos', 'http_mirror') self._raid_setup = False self._raid_drives = {} def _check_target(self): if not self.target: raise Error, 'no target specified' def _check_installer(self): if not self.installer: raise Error, 'no installer available' def _check_mounted(self): self._check_target() if not self._mounted: raise Error, 'target not mounted' def _check_bootstrap(self): self._check_mounted() if not self._bootstrapped: raise Error, 'target not bootstrapped' def set_machine(self, machine): self.machine.set_machine(machine) try: logfile = os.environ['LOGFILE'] except KeyError: logfile = '/paellalog/paella-install-%s.log' % machine os.environ['LOGFILE'] = logfile os.environ['PAELLA_MACHINE'] = machine def make_filesystems(self): device = self.machine.array_hack(self.machine.current.machine_type) mddev = False if device == '/dev/md': mdnum = 0 mddev = True all_fsmounts = self.machine.get_installable_fsmounts() env = CurrentEnvironment(self.conn, self.machine.current.machine) for row in all_fsmounts: if mddev: pdev = '/dev/md%d' % mdnum mdnum += 1 else: pdev = device + str(row.partition) if row.mnt_name in env.keys(): print '%s held' % row.mnt_name else: print 'making filesystem for', row.mnt_name make_filesystem(pdev, row.fstype) def set_target(self, target): self.target = target def _pdev(self, device, partition): return device + str(partition) def ready_target(self): self._check_target() makepaths(self.target) device = self.machine.array_hack(self.machine.current.machine_type) clause = Eq('filesystem', self.machine.current.filesystem) clause &= Gt('partition', '0') table = 'filesystem_mounts natural join mounts' mounts = self.cursor.select(table=table, clause=clause, order='mnt_point') if mounts[0].mnt_point != '/': raise Error, 'bad set of mounts', mounts mddev = False mdnum = 0 if device == '/dev/md': mddev = True pdev = '/dev/md0' mdnum += 1 else: pdev = self._pdev(device, mounts[0].partition) print 'mounting target', pdev, self.target clause &= Neq('mnt_point', '/') mounts = self.cursor.select(table=table, clause=clause, order='ord') runlog('mount %s %s' % (pdev, self.target)) for mnt in mounts: tpath = os.path.join(self.target, mnt.mnt_point[1:]) makepaths(tpath) if mddev: pdev = '/dev/md%d' % mdnum else: pdev = self._pdev(device, mnt.partition) mdnum += 1 runlog('mount %s %s' % (pdev, tpath)) self._mounted = True def setup_installer(self): profile = self.machine.current.profile self.installer = ProfileInstaller(self.conn, self.cfg) self.installer.set_profile(profile) self.suite = self.installer.suite def organize_disks(self): return self.machine.check_machine_disks(self.machine.current.machine_type) def partition_disks(self): disks = self.organize_disks() for diskname in disks: for device in disks[diskname]: self._partition_disk(diskname, device) if len(disks[diskname]) > 1: self._raid_setup = True self._raid_drives[diskname] = disks[diskname] ndev = len(disks[diskname]) print 'doing raid setup on %s' % diskname fs = self.machine.current.filesystem print fs pnums = [r.partition for r in self.machine.get_installable_fsmounts(fs)] mdnum = 0 for p in pnums: mdadm = 'mdadm --create /dev/md%d' % mdnum mdadm = '%s --force -l1 -n%d ' % (mdadm, ndev) devices = ['%s%s' % (d, p) for d in disks[diskname]] command = mdadm + ' '.join(devices) print command yesman = 'bash -c "yes | %s"' % command print yesman os.system(yesman) mdnum += 1 print 'doing raid setup on %s' % str(disks[diskname]) mdstat = file('/proc/mdstat').read() while mdstat.find('resync') > -1: sleep(10) mdstat = file('/proc/mdstat').read() def _partition_disk(self, diskname, device): print 'partitioning', diskname, device dump = self.machine.make_partition_dump(diskname, device) i, o = os.popen2('sfdisk %s' % device) i.write(dump) i.close() def bootstrap_target(self): self._check_mounted() self._check_installer() runlog(debootstrap(self.suite, self.target, self.debmirror)) self._bootstrapped = True def _make_generic_devices(self, devices): here = os.getcwd() os.chdir(join(self.target, 'dev')) for dev in devices: runlog('echo making device %s with MAKEDEV' % dev) runlog('./MAKEDEV %s' % dev) os.chdir(here) def make_disk_devices(self): devices = map(basename, self.machine.get_disk_devices()) self._make_generic_devices(devices) def make_tty_devices(self): self._make_generic_devices(['console']) def make_input_devices(self): self._make_generic_devices(['input']) def make_generic_devices(self): #devices = ['std', 'console', 'pty', 'tap', 'sg', 'input', 'audio'] self._make_generic_devices(['generic']) def ready_base_for_install(self): self._check_bootstrap() self._check_installer() fstab = self.machine.make_fstab() ready_base_for_install(self.target, self.cfg, self.suite, fstab) self.make_generic_devices() self.make_disk_devices() if self._raid_setup: mdpath = join(self.target, 'etc/mdadm') makepaths(mdpath) mdconfname = join(mdpath, 'mdadm.conf') mdconf = file(mdconfname, 'w') for diskname in self._raid_drives: devices = ['%s*' % d for d in self._raid_drives[diskname]] line = 'DEVICE %s' % ' '.join(devices) mdconf.write(line + '\n') mdconf.close() mdconf = file(mdconfname, 'a') arrdata = commands.getoutput('mdadm -E --config=%s -s' % mdconfname) mdconf.write(arrdata + '\n') mdconf.write('\n') mdconf.close() def install_to_target(self): os.environ['DEBIAN_FRONTEND'] = 'noninteractive' self._check_target() self._check_installer() self.installer.set_target(self.target) self.installer.process() def post_install(self): print 'post_install' modules = self.machine.get_modules() print 'installing modules', modules setup_modules(self.target, modules) print 'modules installed' kernel = self.machine.current.kernel print 'installing kernel', kernel install_kernel(kernel, self.target) print 'kernel installed' def install(self, machine, target): self.set_machine(machine) self.partition_disks() self.make_filesystems() self.setup_installer() self.set_target(target) self.ready_target() self.bootstrap_target() self.ready_base_for_install() self.install_to_target() self.post_install()
class ChrootInstaller(BaseInstaller): # we may need more __init__ args later def __init__(self, conn): BaseInstaller.__init__(self, conn) self._bootstrapped = False self._install_finished = False self._processes = [ 'ready_target', 'bootstrap', 'mount_target_proc', 'mount_target_sys', 'make_device_entries', 'mount_target_devpts', 'apt_sources_installer', 'ready_base_for_install', 'pre_install', 'install', 'post_install', 'apt_sources_final', 'umount_target_sys', 'umount_target_proc' ] # pre_install is unmapped # post_install is unmapped self._process_map = dict(ready_target=self.create_target_directory, bootstrap=self.bootstrap_target, mount_target_proc=self.mount_target_proc, mount_target_sys=self.mount_target_sys, make_device_entries=self.make_device_entries, mount_target_devpts=self.mount_target_devpts, apt_sources_installer=self.apt_sources_installer, ready_base_for_install=self.ready_base_for_install, install=self.install, apt_sources_final=self.apt_sources_final, umount_target_sys=self.umount_target_sys, umount_target_proc=self.umount_target_proc ) # this is only used in the machine installer self.mtypedata = {} # the default script for the chroot installer is None def make_script(self, procname): return None def set_logfile(self, logfile): BaseInstaller.set_logfile(self, logfile) self.log.info('-'*30) msg = '%s initialized' % self.__class__.__name__ self.log.info(msg) self.log.info('-'*30) @requires_target_set def set_profile(self, profile): self.installer = ProfileInstaller(self) self.installer.mtypedata.update(self.mtypedata) self.installer.set_profile(profile) self.set_suite(self.installer.suite) @requires_target_exists def _bootstrap_with_tarball(self, suite): suite_path = path(self.defenv.get('installer', 'suite_storage')) filename = '%s.tar.gz' % suite basefile = suite_path / filename taropts = '-xzf' if not basefile.exists(): filename = '%s.tar' % suite basefile = suite_path / filename taropts = '-xf' cmd = 'tar -C %s %s %s' % (self.target, taropts, basefile) # if cmd returns nonzero, runlog will raise an error runlog(cmd) # we need to do certain things here that debootstrap # does for us, like copy /etc/resolv.conf self._bootstrapped = True @requires_target_exists def _bootstrap_with_debootstrap(self, suite): mirror = self.defenv.get('installer', 'http_mirror') cmd = debootstrap(suite, self.target, mirror) # if cmd returns nonzero, runlog will raise an error runlog(cmd) self._bootstrapped = True @requires_suite_set def bootstrap_target(self): if not self.target.exists(): self.target.mkdir() if not self.target.isdir(): raise InstallTargetError, "%s is not a directory" % self.target if self.defenv.getboolean('installer', 'bootstrap_target'): self.log.info('bootstrapping with debootstrap') self._bootstrap_with_debootstrap(self.base_suite) else: self.log.info('bootstrapping with premade tarball') self._bootstrap_with_tarball(self.base_suite) # here we add the apt keys that are needed aptkeys = AptKeyHandler(self.conn) keys = self.defenv.get_list('archive_keys', 'installer') for key in keys: row = aptkeys.get_row(key) filename = self.target / ('%s.key' % key) if filename.exists(): raise RuntimeError, "%s already exists" % filename keyfile = file(filename, 'w') keyfile.write(row.data) keyfile.close() #self.chroot('apt-key add %s.key' % key) self.chroot(['apt-key', 'add', '%s.key' % key]) os.remove(filename) if filename.exists(): raise RuntimeError, "%s wasn't deleted" % filename self.log.info('added key %s (%s) to apt' % (key, row.keyid)) @requires_bootstrap def make_device_entries(self): self.log.info('nothing done for make_device_entries yet') @requires_bootstrap def apt_sources_installer(self): make_sources_list(self.conn, self.target, self.suite) @requires_install_complete def apt_sources_final(self): sourceslist = self.target / 'etc/apt/sources.list' sourceslist_installer = path('%s.installer' % sourceslist) os.rename(sourceslist, sourceslist_installer) make_official_sources_list(self.conn, self.target, self.suite) # this is probably not useful anymore # it still has a purpose in the machine installer - # it sets up the mdadm.conf file with the raid devices it creates # if it creates any. @requires_bootstrap def ready_base_for_install(self): # update the package lists #self.chroot('apt-get -y update') self.chroot(['apt-get', '-y', 'update']) # common method for mounting /proc and /sys # here fs is either 'proc' or 'sys' or 'devpts' def _mount_target_virtfs(self, fs): fstype = dict(proc='proc', sys='sysfs', devpts='devpts') target = self.target / fs if fs == 'devpts': target = self.target / 'dev' / 'pts' if not target.isdir(): target.mkdir() #cmd = 'mount -t %s none %s' % (fstype[fs], target) cmd = ['mount', '-t', fstype[fs], 'none', str(target)] runlog(cmd) def _umount_target_virtfs(self, fs): # work around binfmt-support /proc locking # found this idea while messing around in live-helper target = self.target / fs if fs == 'proc': binfmt_misc = self.target / 'proc/sys/fs/binfmt_misc' status = binfmt_misc / 'status' if status.exists(): self.log.info('Unmounting /proc/sys/fs/binfmt_misc in chroot') #cmd = 'umount %s' % binfmt cmd = ['umount', str(binfmt_misc)] runlog(cmd) if fs == 'devpts': target = self.target / 'dev' / 'pts' #cmd = 'umount %s' % target cmd = ['umount', str(target)] runlog(cmd) def _target_proc_mounted(self): testfile = self.target / 'proc/version' return testfile.isfile() def _target_sys_mounted(self): testdir = self.target / 'sys/kernel' return testdir.isdir() @requires_bootstrap def mount_target_proc(self): self._mount_target_virtfs('proc') @requires_bootstrap def mount_target_sys(self): self._mount_target_virtfs('sys') def mount_target_devpts(self): self._mount_target_virtfs('devpts') @requires_target_proc_mounted def umount_target_proc(self): self._umount_target_virtfs('proc') @requires_target_sys_mounted def umount_target_sys(self): self._umount_target_virtfs('sys') def umount_target_devpts(self): self._umount_target_virtfs('devpts') @requires_target_proc_mounted @requires_target_sys_mounted @requires_installer_set def install(self): self.installer.run_all_processes() self._install_finished = True def log_all_processes_finished(self): self.log.info('-'*30) self.log.info('%s processes finished' % self.__class__.__name__) self.log.info('-'*30) def save_logfile_in_target(self): install_log = self.target / 'root/paella/install.log' self.mainlog.filename.copyfile(install_log)
class MachineInstaller(BaseChrootInstaller): def __init__(self, conn): BaseChrootInstaller.__init__(self, conn) self.machine = MachineHandler(self.conn) self.processes = DEFAULT_PROCESSES self._process_map = { 'setup_disks' : self.setup_disks, 'mount_target' : self.mount_target, 'bootstrap' : self.bootstrap_target, 'make_device_entries' : self.make_device_entries, 'apt_sources_installer' : self.setup_apt_sources_installer, 'ready_base' : self.ready_base_for_install, 'mount_target_proc' : self.mount_target_proc, 'install' : self.install_to_target, 'install_fstab' : self.install_fstab, 'install_modules' : self.install_modules, 'install_kernel' : self.install_kernel, 'apt_sources_final' : self.setup_apt_sources_final, 'umount_target_proc' : self.umount_target_proc } self.helper = None def process(self): mach = self.machine.current.machine self.log.info('Starting machine install process for %s' % mach) for proc in self.processes: self.log.info('processing %s for machine %s' % (proc, mach)) self.run_process(proc) self.log.info('processed %s for machine %s' % (proc, mach)) self.log.info('Ending machine install process for %s' % mach) def _make_script(self, name): script = self.machine.get_script(name) if script is not None: return make_script(name, script, '/') else: return None def run_process(self, proc): info = self.log.info self.start_process(proc) script = self._make_script(proc) mtype = self.machine.current.machine_type if script is None: info('No script for process %s on machine type %s' % (proc, mtype)) if proc in self._process_map: info('Running default process %s' % proc) self._process_map[proc]() else: info('Nothing to do for process %s' % proc) else: self.log.info('%s script exists for %s' % (proc, mtype)) self.run_process_script(proc, script) self.finish_process(proc) def start_process(self, proc): self._check_target() if proc == 'bootstrap': self._check_target_exists() def finish_process(self, proc): if proc == 'mount_target': self._mounted = True self.log.info('Target should be mounted now.') elif proc == 'bootstrap': self.log.info('Target should be bootstrapped now.') self._bootstrapped = True def _runscript(self, script, name, info): self.log.info(info['start']) runvalue = self.run(name, script, chroot=False) os.remove(script) self.log.info(info['done']) return runvalue def run_process_script(self, proc, script): info = scriptinfo(proc) if self._runscript(script, proc, info): raise InstallError, 'Error running script %s' % proc def _check_mounted(self): self._check_target_exists() if not self._mounted: raise InstallError, 'target not mounted' def _check_bootstrap(self): self._check_mounted() BaseChrootInstaller._check_bootstrap(self) def set_machine(self, machine): self.machine.set_machine(machine) try: logfile = os.environ['LOGFILE'] except KeyError: logfile = '/paellalog/paella-install-%s.log' % machine os.environ['PAELLA_LOGFILE'] = logfile # this needs to be removed sometime os.environ['LOGFILE'] = logfile os.environ['PAELLA_MACHINE'] = machine disklogpath = join(dirname(logfile), 'disklog-%s' % machine) if not os.path.isdir(disklogpath): makepaths(disklogpath) self.disklogpath = disklogpath self.curenv = CurrentEnvironment(self.conn, self.machine.current.machine) self.set_logfile(logfile) self.log.info('Machine Installer set machine to %s' % machine) self.mtypedata = self.machine.mtype.get_machine_type_data() def install(self, machine, target): self.set_machine(machine) self.setup_installer() self.set_target(target) makepaths(target) self.log.info('Installer set to install %s to %s' % (machine, target)) self.helper = MachineInstallerHelper(self) self.helper.curenv = self.curenv self.process() def setup_installer(self): machine = self.machine.current.machine profile = self.machine.current.profile self.log.info('Setting up profile installer for %s' % machine) self.installer = ProfileInstaller(self.conn) self.installer.log = self.log self.installer.mtypedata = self.mtypedata self.installer.set_profile(profile) self.suite = self.installer.suite self._installer_ready = True self.log.info('Profile installer ready for %s' % machine) def setup_disks(self): "this is a default process" self.helper.setup_disks() def mount_target(self): "this is a default process" self._check_target() makepaths(self.target) device = self.machine.array_hack() #mounts = self.machine.get_ordered_fsmounts() mounts = self.machine.get_installable_fsmounts() mount_target(self.target, mounts, device) self._mounted = True def bootstrap_target(self): "this is a default process" self.helper.bootstrap_target() def make_device_entries(self): "this is a default process" if self.defenv.is_it_true('installer', 'use_devices_tarball'): runlog('echo extracting devices tarball') self._extract_devices_tarball() else: runlog('echo using MAKEDEV to make generic devices') self.make_generic_devices() self.make_disk_devices() def setup_apt_sources_installer(self): "this is a default process" make_sources_list(self.defenv, self.target, self.suite) def ready_base_for_install(self): "this is a default process" set_root_passwd(self.target, myline) make_interfaces_simple(self.target) devices = self.helper.get_raid_devices() if devices: create_mdadm_conf(self.target, devices) def mount_target_proc(self): "this is a default process" echo('mounting target /proc') mount_target_proc(self.target) def install_to_target(self): "this is a default process" os.environ['DEBIAN_FRONTEND'] = 'noninteractive' self._check_target() self._check_installer() self.installer.set_target(self.target) self.installer.process() def install_modules(self): "this is a default process" modules = self.machine.get_modules() setup_modules(self.target, modules) def install_kernel(self): "this is a default process" kernel = self.machine.current.kernel echo('installing kernel %s' % kernel) install_kernel(kernel, self.target) def setup_apt_sources_final(self): "this is a default process" make_official_sources_list(self.defenv, self.target, self.suite) def install_fstab(self): "this is a default process" fstab = self.machine.make_fstab() make_fstab(fstab, self.target) def umount_target_proc(self): "this is a default process" echo('unmounting target /proc') mount_target_proc(self.target, umount=True) def _extract_devices_tarball(self): dtball = self.defenv.get('installer', 'devices_tarball') devpath = join(self.target, 'dev') runvalue = extract_tarball(devpath, dtball) if runvalue: raise Error, 'problem extracting devices tarball' def make_generic_devices(self): makedev(self.target, ['generic']) def make_disk_devices(self): devices = map(basename, self.machine.get_disk_devices()) makedev(self.target, devices)
class NewInstaller(object): def __init__(self, conn, cfg): object.__init__(self) self.conn = conn self.cfg = cfg self.defenv = DefaultEnvironment(self.conn) self.machine = MachineHandler(self.conn) self.cursor = StatementCursor(self.conn) self.target = None self.installer = None self._mounted = None self._bootstrapped = None self.debmirror = self.cfg.get('debrepos', 'http_mirror') self._raid_setup = False self._raid_drives = {} self._enable_bad_hacks = False if self.cfg.is_it_true('installer', 'enable_bad_hacks'): self._enable_bad_hacks = True def set_logfile(self, logfile): env = os.environ if logfile is None: if env.has_key('PAELLA_LOGFILE'): self.logfile = env['PAELLA_LOGFILE'] elif env.has_key('LOGFILE'): self.logfile = env['LOGFILE'] elif self.defenv.has_option('installer', 'default_logfile'): self.logfile = self.defenv.get('installer', 'default_logfile') else: raise InstallSetupError, 'There is no log file defined, giving up.' else: self.logfile = logfile logdir = os.path.dirname(self.logfile) if logdir: makepaths(os.path.dirname(self.logfile)) format = '%(name)s - %(asctime)s - %(levelname)s: %(message)s' self.log = Log('paella-installer', self.logfile, format) def _check_target(self): if not self.target: raise Error, 'no target specified' def _check_installer(self): if not self.installer: raise Error, 'no installer available' def _check_mounted(self): self._check_target() if not self._mounted: raise InstallError, 'target not mounted' def _check_bootstrap(self): self._check_mounted() if not self._bootstrapped: raise Error, 'target not bootstrapped' def set_machine(self, machine): self.machine.set_machine(machine) try: logfile = os.environ['LOGFILE'] except KeyError: logfile = '/paellalog/paella-install-%s.log' % machine os.environ['LOGFILE'] = logfile os.environ['PAELLA_MACHINE'] = machine disklogpath = join(dirname(logfile), 'disklog') if not os.path.isdir(disklogpath): makepaths(disklogpath) self.disklogpath = disklogpath self.curenv = CurrentEnvironment(self.conn, self.machine.current.machine) self.set_logfile(logfile) def check_if_mounted(self, device): mounts = file('/proc/mounts') for line in file: if line.startswith(device): return True return False def unmount_device(self, device): mounted = os.system('umount %s' % device) def make_filesystems(self): device = self.machine.array_hack(self.machine.current.machine_type) mddev = False if device == '/dev/md': mdnum = 0 mddev = True all_fsmounts = self.machine.get_installable_fsmounts() env = CurrentEnvironment(self.conn, self.machine.current.machine) for row in all_fsmounts: if mddev: pdev = '/dev/md%d' % mdnum mdnum += 1 else: pdev = device + str(row.partition) if row.mnt_name in env.keys(): print '%s held' % row.mnt_name elif row.fstype == 'swap': runlog('echo making swap on %s' % pdev) runlog('mkswap %s' % pdev) else: print 'making filesystem for', row.mnt_name make_filesystem(pdev, row.fstype) def set_target(self, target): self.target = target def _pdev(self, device, partition): return device + str(partition) def _mount_target_proc(self): self._check_bootstrap() tproc = join(self.target, 'proc') cmd = 'mount --bind /proc %s' % tproc runvalue = runlog(cmd) if runvalue: raise InstallError, 'problem mounting target /proc at %s' % tproc else: self._proc_mounted = True def _umount_target_proc(self): tproc = join(self.target, 'proc') cmd = 'umount %s' % tproc runvalue = runlog(cmd) if runvalue: raise InstallError, 'problem unmounting target /proc at %s' % tproc else: self._proc_mounted = False def ready_target(self): self._check_target() makepaths(self.target) device = self.machine.array_hack(self.machine.current.machine_type) clause = Eq('filesystem', self.machine.current.filesystem) clause &= Gt('partition', '0') table = 'filesystem_mounts natural join mounts' mounts = self.cursor.select(table=table, clause=clause, order='mnt_point') if mounts[0].mnt_point != '/': raise Error, 'bad set of mounts', mounts mddev = False mdnum = 0 if device == '/dev/md': mddev = True pdev = '/dev/md0' mdnum += 1 else: pdev = self._pdev(device, mounts[0].partition) runlog('echo mounting target %s to %s ' % (pdev, self.target)) clause &= Neq('mnt_point', '/') mounts = self.cursor.select(table=table, clause=clause, order='ord') mountable = [mount for mount in mounts if mount.fstype != 'swap'] runlog('mount %s %s' % (pdev, self.target)) for mnt in mountable: tpath = os.path.join(self.target, mnt.mnt_point[1:]) makepaths(tpath) if mddev: pdev = '/dev/md%d' % mdnum else: pdev = self._pdev(device, mnt.partition) mdnum += 1 runlog('mount %s %s' % (pdev, tpath)) self._mounted = True def setup_installer(self): profile = self.machine.current.profile self.installer = ProfileInstaller(self.conn) self.installer.log = self.log self.installer.set_profile(profile) self.suite = self.installer.suite def organize_disks(self): return self.machine.check_machine_disks(self.machine.current.machine_type) def _setup_disks(self, diskname, disks=None): if disks is None: disks = self.organize_disks() devices = disks[diskname] def setup_disks(self): disks = self.organize_disks() disknames = disks.keys() if not len(disknames): self._setup_disk_fai('default', '/dev/hda') else: if len(disknames) > 1: #this isn't really handled yet self.partition_disks() self.make_filesystems() else: devices = disks[disknames[0]] if len(devices) > 1: #this is a raid setup self.partition_disks() self.make_filesystems() elif len(devices) == 1: self._setup_disk_fai(self.machine.current.filesystem, devices[0]) else: self._setup_disk_fai('default', '/dev/hda') def _setup_disk_fai(self, filesystem, device): disk_config = self.machine.make_disk_config_info(device) fileid, disk_config_path = tempfile.mkstemp('paella', 'diskinfo') disk_config_file = file(disk_config_path, 'w') disk_config_file.write(disk_config) disk_config_file.close() script = '/usr/lib/paella/scripts/setup_harddisks_fai' options = '-X -f %s' % disk_config_path env = 'env LOGDIR=%s diskvar=%s' % (self.disklogpath, join(self.disklogpath, 'diskvar')) command = '%s %s %s' % (env, script, options) runlog(command) def _setup_raid_drives(self, diskname, devices): self._raid_setup = True self._raid_drives[diskname] = devices for device in devices: self._partition_disk(diskname, device) ndev = len(devices) print 'doing raid setup on %s' % diskname fs = self.machine.current.filesystem print fs pnums = [r.partition for r in self.machine.get_installable_fsmounts(fs)] mdnum = 0 for p in pnums: mdadm = 'mdadm --create /dev/md%d' % mdnum mdadm = '%s --force -l1 -n%d ' % (mdadm, ndev) devices = ['%s%s' % (d, p) for d in devices] command = mdadm + ' '.join(devices) print command yesman = 'bash -c "yes | %s"' % command print yesman os.system(yesman) mdnum += 1 print 'doing raid setup on %s' % str(devices) mdstat = file('/proc/mdstat').read() while mdstat.find('resync') > -1: sleep(10) mdstat = file('/proc/mdstat').read() def partition_disks(self): disks = self.organize_disks() for diskname in disks: for device in disks[diskname]: self._partition_disk(diskname, device) if len(disks[diskname]) > 1: self._raid_setup = True self._raid_drives[diskname] = disks[diskname] ndev = len(disks[diskname]) print 'doing raid setup on %s' % diskname fs = self.machine.current.filesystem print fs pnums = [r.partition for r in self.machine.get_installable_fsmounts(fs)] mdnum = 0 for p in pnums: mdadm = 'mdadm --create /dev/md%d' % mdnum mdadm = '%s --force -l1 -n%d ' % (mdadm, ndev) devices = ['%s%s' % (d, p) for d in disks[diskname]] command = mdadm + ' '.join(devices) print command yesman = 'bash -c "yes | %s"' % command print yesman os.system(yesman) mdnum += 1 print 'doing raid setup on %s' % str(disks[diskname]) mdstat = file('/proc/mdstat').read() while mdstat.find('resync') > -1: sleep(10) mdstat = file('/proc/mdstat').read() def _partition_disk(self, diskname, device): print 'partitioning', diskname, device dump = self.machine.make_partition_dump(diskname, device) i, o = os.popen2('sfdisk %s' % device) i.write(dump) i.close() def extract_basebootstrap(self): self._check_mounted() self._check_installer() runlog('echo extracting premade base tarball') suite_path = self.cfg.get('installer', 'suite_storage') basefile = join(suite_path, '%s.tar' % self.suite) runvalue = runlog('tar -C %s -xf %s' % (self.target, basefile)) if runvalue: raise Error, 'problems extracting %s' % basefile self._bootstrapped = True def bootstrap_target(self): self._check_mounted() self._check_installer() runlog(debootstrap(self.suite, self.target, self.debmirror)) self._bootstrapped = True def _make_generic_devices(self, devices): here = os.getcwd() os.chdir(join(self.target, 'dev')) for dev in devices: runlog('echo making device %s with MAKEDEV' % dev) runlog('./MAKEDEV %s' % dev) os.chdir(here) def _extract_devices_tarball(self): dtball = self.cfg.get('installer', 'devices_tarball') devpath = join(self.target, 'dev') cmd = 'tar -C %s -xf %s' % (devpath, dtball) runvalue = runlog(cmd) if runvalue: raise Error, 'problem extracting devices tarball' def make_disk_devices(self): devices = map(basename, self.machine.get_disk_devices()) self._make_generic_devices(devices) def make_tty_devices(self): self._make_generic_devices(['console']) def make_input_devices(self): self._make_generic_devices(['input']) def make_generic_devices(self): #devices = ['std', 'console', 'pty', 'tap', 'sg', 'input', 'audio'] self._make_generic_devices(['generic']) def ready_base_for_install(self): self._check_bootstrap() self._check_installer() fstab = self.machine.make_fstab() ready_base_for_install(self.target, self.cfg, self.suite, fstab) if self.cfg.is_it_true('installer', 'use_devices_tarball'): runlog('echo extracting devices tarball') self._extract_devices_tarball() else: runlog('echo using MAKEDEV to make devices') self.make_generic_devices() self.make_disk_devices() if self._raid_setup: mdpath = join(self.target, 'etc/mdadm') makepaths(mdpath) mdconfname = join(mdpath, 'mdadm.conf') mdconf = file(mdconfname, 'w') for diskname in self._raid_drives: devices = ['%s*' % d for d in self._raid_drives[diskname]] line = 'DEVICE %s' % ' '.join(devices) mdconf.write(line + '\n') mdconf.close() mdconf = file(mdconfname, 'a') arrdata = commands.getoutput('mdadm -E --config=%s -s' % mdconfname) mdconf.write(arrdata + '\n') mdconf.write('\n') mdconf.close() self._mount_target_proc() def install_to_target(self): os.environ['DEBIAN_FRONTEND'] = 'noninteractive' self._check_target() self._check_installer() self.installer.set_target(self.target) self.installer.process() def post_install(self): print 'post_install' modules = self.machine.get_modules() print 'installing modules', modules setup_modules(self.target, modules) print 'modules installed' kernel = self.machine.current.kernel print 'installing kernel', kernel install_kernel(kernel, self.target) print 'kernel installed' def install(self, machine, target): self.set_machine(machine) if self._enable_bad_hacks: self.setup_disks() else: self.partition_disks() self.make_filesystems() self.setup_installer() self.set_target(target) self.ready_target() if self.cfg.is_it_true('installer', 'bootstrap_target'): self.bootstrap_target() else: self.extract_basebootstrap() self.ready_base_for_install() self.install_to_target() self.post_install()