class Installer(object): def __init__(self, chroot_path, environ={}): env = { 'DEBIAN_FRONTEND': 'noninteractive', 'DEBIAN_PRIORITY': 'critical' } env.update(environ) self.chroot = Chroot(chroot_path, environ=env) @staticmethod def _get_packages_priority(packages): """high priority packages must be installed before regular packages APT should handle this, but in some circumstances it chokes... """ HIGH_PRIORITY = ('linux-image') high = [] regular = [] for package in packages: if package.startswith(HIGH_PRIORITY): high.append(package) else: regular.append(package) return high, regular def _install(self, packages, ignore_errors=[], extra_apt_args=[]): high, regular = self._get_packages_priority(packages) lines = [ "#!/bin/sh", "echo", "echo \"Warning: Fake invoke-rc.d called\"" ] fake_invoke_rcd = RevertibleScript( join(self.chroot.path, "usr/sbin/invoke-rc.d"), lines) lines = [ "#!/bin/sh", "echo", "echo \"Warning: Fake start-stop-daemon called\"" ] fake_start_stop = RevertibleScript( join(self.chroot.path, "sbin/start-stop-daemon"), lines) defer_log = "var/lib/update-initramfs.deferred" lines = [ "#!/bin/sh", "echo", "echo \"Warning: Deferring update-initramfs $@\"", "echo \"update-initramfs $@\" >> /%s" % defer_log ] fake_update_initramfs = RevertibleScript( join(self.chroot.path, "usr/sbin/update-initramfs"), lines) fake_initctl = RevertibleInitctl(self.chroot) for packages in (high, regular): if packages: try: args = ['install', '--assume-yes'] args.extend(extra_apt_args) self.chroot.system("apt-get", *(args + packages)) except executil.ExecError, e: def get_last_log(path): log = [] for line in reversed(file(path).readlines()): if line.startswith("Log ended: "): continue if line.startswith("Log started: "): break log.append(line.strip()) log.reverse() return log def get_errors(log, error_str): errors = [] for line in reversed(log): if line == error_str: break errors.append(basename(line).split("_")[0]) return errors log = get_last_log( join(self.chroot.path, "var/log/apt/term.log")) error_str = "Errors were encountered while processing:" if error_str not in log: raise errors = get_errors(log, error_str) ignored_errors = set(errors) & set(ignore_errors) errors = set(errors) - set(ignore_errors) if ignored_errors: print "Warning: ignoring package installation errors (%s)" % " ".join( ignored_errors) if errors: raise fake_update_initramfs.revert() defer_log = join(self.chroot.path, defer_log) if exists(defer_log): kversion = "all" boot_path = join(self.chroot.path, "boot") for f in os.listdir(boot_path): if f.startswith("vmlinuz-"): kversion = f.replace("vmlinuz-", "") break if exists(join(boot_path, "initrd.img-%s" % kversion)): self.chroot.system("update-initramfs -u") else: self.chroot.system("update-initramfs -c -k %s" % kversion) os.remove(defer_log)
class Installer(object): def __init__(self, chroot_path, environ={}): env = {'DEBIAN_FRONTEND': 'noninteractive', 'DEBIAN_PRIORITY': 'critical'} env.update(environ) self.chroot = Chroot(chroot_path, environ=env) @staticmethod def _get_packages_priority(packages): """high priority packages must be installed before regular packages APT should handle this, but in some circumstances it chokes... """ HIGH_PRIORITY = ('linux-image') high = [] regular = [] for package in packages: if package.startswith(HIGH_PRIORITY): high.append(package) else: regular.append(package) return high, regular def _install(self, packages, ignore_errors=[], extra_apt_args=[]): high, regular = self._get_packages_priority(packages) lines = [ "#!/bin/sh", "echo", "echo \"Warning: Fake invoke-rc.d called\"" ] fake_invoke_rcd = RevertibleScript(join(self.chroot.path, "usr/sbin/invoke-rc.d"), lines) lines = [ "#!/bin/sh", "echo", "echo \"Warning: Fake start-stop-daemon called\"" ] fake_start_stop = RevertibleScript(join(self.chroot.path, "sbin/start-stop-daemon"), lines) defer_log = "var/lib/update-initramfs.deferred" lines = [ "#!/bin/sh", "echo", "echo \"Warning: Deferring update-initramfs $@\"", "echo \"update-initramfs $@\" >> /%s" % defer_log ] fake_update_initramfs = RevertibleScript(join(self.chroot.path, "usr/sbin/update-initramfs"), lines) fake_initctl = RevertibleInitctl(self.chroot) for packages in (high, regular): if packages: try: args = ['install', '--force-yes', '--assume-yes'] args.extend(extra_apt_args) self.chroot.system("apt-get", *(args + packages)) except executil.ExecError, e: def get_last_log(path): log = [] for line in reversed(file(path).readlines()): if line.startswith("Log ended: "): continue if line.startswith("Log started: "): break log.append(line.strip()) log.reverse() return log def get_errors(log, error_str): errors = [] for line in reversed(log): if line == error_str: break errors.append(basename(line).split("_")[0]) return errors log = get_last_log(join(self.chroot.path, "var/log/apt/term.log")) error_str = "Errors were encountered while processing:" if error_str not in log: raise errors = get_errors(log, error_str) ignored_errors = set(errors) & set(ignore_errors) errors = set(errors) - set(ignore_errors) if ignored_errors: print "Warning: ignoring package installation errors (%s)" % " ".join(ignored_errors) if errors: raise fake_update_initramfs.revert() defer_log = join(self.chroot.path, defer_log) if exists(defer_log): kversion = "all" boot_path = join(self.chroot.path, "boot") for f in os.listdir(boot_path): if f.startswith("vmlinuz-"): kversion = f.replace("vmlinuz-", "") break if exists(join(boot_path, "initrd.img-%s" % kversion)): self.chroot.system("update-initramfs -u") else: self.chroot.system("update-initramfs -c -k %s" % kversion) os.remove(defer_log)
def system(self, *command): try: _Chroot.system(self, *command) except ExecError, e: return e.exitcode