def maybe_install_packages(self, packages): chroot = ROOT_PATH root = etpSys['rootdir'] install = [] if chroot != root: self._change_entropy_chroot(chroot) try: repo = self._backend.entropy.installed_repository() for package in packages: pkg_id, _pkg_rc = repo.atomMatch(package) if pkg_id == -1: install.append(package) if not install: return updated = self.update_entropy_repositories() if not updated: return # ouch for package in install: progressQ.send_message( _("Installing package: %s") % (package, )) self.install_package(package) finally: if chroot != root: self._change_entropy_chroot(root)
def progress(self): """Monitor the amount of disk space used on the target and source and update the hub's progress bar. """ mountpoints = payload_utils.get_mount_points() last_pct = -1 while self.pct < 100: dest_size = 0 for mnt in mountpoints: mnt_stat = os.statvfs(conf.target.system_root + mnt) dest_size += mnt_stat.f_frsize * (mnt_stat.f_blocks - mnt_stat.f_bfree) if dest_size >= self._adj_size: dest_size -= self._adj_size pct = int(100 * dest_size / self.source_size) if pct != last_pct: with self.pct_lock: self.pct = pct last_pct = pct progressQ.send_message( _("Installing software") + (" %d%%") % (min(100, self.pct), )) sleep(0.777)
def post_install(self): """ Perform post-installation tasks. """ progressQ.send_message(_("Performing post-installation setup tasks")) payload_utils.unmount(INSTALL_TREE, raise_exc=True) super().post_install() # Not using BLS configuration, skip it if os.path.exists(conf.target.system_root + "/usr/sbin/new-kernel-pkg"): return # Remove any existing BLS entries, they will not match the new system's # machine-id or /boot mountpoint. for file in glob.glob(conf.target.system_root + "/boot/loader/entries/*.conf"): log.info("Removing old BLS entry: %s", file) os.unlink(file) # Create new BLS entries for this system for kernel in self.kernel_version_list: log.info("Regenerating BLS info for %s", kernel) util.execInSysroot( "kernel-install", ["add", kernel, "/lib/modules/{0}/vmlinuz".format(kernel)])
def expose(self, topic, percent, subkey, subtopic, subpercent, data, done): if subtopic is None: return msg = "%s %s%%, %s %s%%" % (topic, percent, subtopic, subpercent) progressQ.send_message(msg) log.debug("expose: %s" % msg)
def progress(self): """Monitor the amount of disk space used on the target and source and update the hub's progress bar. """ mountpoints = self.storage.mountpoints.copy() last_pct = -1 while self.pct < 100: dest_size = 0 for mnt in mountpoints: mnt_stat = iutil.eintr_retry_call(os.statvfs, iutil.getSysroot() + mnt) dest_size += mnt_stat.f_frsize * (mnt_stat.f_blocks - mnt_stat.f_bfree) if dest_size >= self._adj_size: dest_size -= self._adj_size pct = int(100 * dest_size / self.source_size) if pct != last_pct: with self.pct_lock: self.pct = pct last_pct = pct progressQ.send_message( _("Installing software") + (" %d%%") % (min(100, self.pct), )) sleep(0.777)
def install(self): packages = self.requiredPackages + self.packages + self.kernelPackages log.info("%s %s: %s" % (self.__class__.__name__, inspect.stack()[0][3], packages)) self._smart.install(packages) self._smart.runSmart('channel', ['--add', 'rpmsys', 'type=rpm-sys', '-y']) # Record installed packages to new generated kickstart file installed_list = self._smart.query( ['--installed', '--show-format=$name\n']) for pkg in installed_list: self.selectPackage(pkg) log.info("taskid %s, %s" % (self.taskid, self.tasks[self.taskid])) (name, description, group) = self.tasks[self.taskid] progressQ.send_message("It takes some time to install extra packages") self._smart.install_group(self._groups, self.linguas_groups) # Record group to new generated kickstart file for group in self._groups: self.selectGroup(group) for lang_group in self.linguas_groups: self.selectGroup(lang_group, optional=True)
def install_group(self, group, linguas_groups=[]): log.debug("group %s, linguas %s" % (group, linguas_groups)) globs = self.complementary_globs(group, linguas_groups).split() available_list = self.query(['--show-format=$source $name $version\n']) log.debug("available %d" % len(available_list)) installed_list = self.query( ['--installed', '--show-format=$source $name $version\n']) log.debug("installed %d" % len(installed_list)) comp_pkgs = [] for installed in installed_list: (installed_src, installed_pkg, installed_ver) = installed.split() for glob in globs: complementary = "%s %s%s %s" % (installed_src, installed_pkg, glob, installed_ver) if complementary in available_list: comp_pkgs.append("%s%s-%s" % (installed_pkg, glob, installed_ver)) if comp_pkgs != []: progressQ.send_message( "%d extra packages will be installed, please wait..." % len(comp_pkgs)) self.install(['--attempt'] + comp_pkgs) installed_list = self.query( ['--installed', '--show-format=$source $name $version\n']) log.debug("installed with group %d" % len(installed_list))
def maybe_install_packages(self, packages): chroot = ROOT_PATH root = etpSys['rootdir'] install = [] if chroot != root: self._change_entropy_chroot(chroot) try: repo = self._backend.entropy.installed_repository() for package in packages: pkg_id, _pkg_rc = repo.atomMatch(package) if pkg_id == -1: install.append(package) if not install: return updated = self.update_entropy_repositories() if not updated: return # ouch for package in install: progressQ.send_message( _("Installing package: %s") % (package,)) self.install_package(package) finally: if chroot != root: self._change_entropy_chroot(root)
def postInstall(self): super(LiveCDCopyBackend, self).postInstall() log.info("Preparing to configure Sabayon (backend postInstall)") self._sabayon_install.spawn_chroot( ["/usr/bin/systemd-machine-id-setup"] ) self._sabayon_install.setup_secureboot() self._sabayon_install.setup_sudo() self._sabayon_install.remove_proprietary_drivers() self._sabayon_install.setup_nvidia_legacy() self._sabayon_install.configure_skel() self._sabayon_install.configure_services() self._sabayon_install.spawn_chroot(["env-update"]) self._sabayon_install.spawn_chroot(["ldconfig"]) if self._packages: log.info("Preparing to install these packages: %s" % ( self._packages,)) self._sabayon_install.setup_entropy_mirrors() self._sabayon_install.maybe_install_packages(self._packages) self._sabayon_install.configure_boot_args() self._sabayon_install.emit_install_done() progressQ.send_message(_("Sabayon configuration complete"))
def postInstall(self): """ Perform post-installation tasks. """ progressQ.send_message(_("Performing post-installation setup tasks")) blivet.util.umount(INSTALL_TREE) super(LiveImagePayload, self).postInstall() self._recreateInitrds()
def progress(self): """Monitor the amount of disk space used on the target and source and update the hub's progress bar. """ source = os.statvfs(INSTALL_TREE) source_size = source.f_frsize * (source.f_blocks - source.f_bfree) mountpoints = self.storage.mountpoints.copy() last_pct = -1 while self.pct < 100: dest_size = 0 for mnt in mountpoints: mnt_stat = os.statvfs(ROOT_PATH + mnt) dest_size += mnt_stat.f_frsize * (mnt_stat.f_blocks - mnt_stat.f_bfree) if dest_size >= self._adj_size: dest_size -= self._adj_size pct = int(100 * dest_size / source_size) if pct != last_pct: with self.pct_lock: self.pct = pct last_pct = pct progressQ.send_message( _("Installing software") + (" %d%%") % (min(100, self.pct), )) sleep(0.777)
def end(self, bytes_read): """ Download complete :param bytes_read: Bytes read so far :type bytes_read: int """ progressQ.send_message(_("Downloading %(url)s (%(pct)d%%)") % {"url": self.url, "pct": 100})
def install(self): progressQ.send_message(_("Starting package installation process")) if self.install_device: self._setupMedia(self.install_device) try: self.checkSoftwareSelection() except packaging.DependencyError as e: if errors.errorHandler.cb(e) == errors.ERROR_RAISE: _failure_limbo() pkgs_to_download = self._base.transaction.install_set log.info("Downloading pacakges.") progressQ.send_message(_("Downloading packages")) self._base.download_packages(pkgs_to_download) log.info("Downloading packages finished.") pre_msg = _("Preparing transaction from installation source") progressQ.send_message(pre_msg) queue = multiprocessing.Queue() process = multiprocessing.Process(target=do_transaction, args=(self._base, queue)) process.start() (token, msg) = queue.get() while token not in ("post", "quit"): if token == "install": msg = _("Installing %s") % msg progressQ.send_message(msg) (token, msg) = queue.get() if token == "quit": _failure_limbo() post_msg = _("Performing post-installation setup tasks") progressQ.send_message(post_msg) process.join()
def install(self): progressQ.send_message(_('Starting package installation process')) # Add the rpm macros to the global transaction environment for macro in self.rpmMacros: rpm.addMacro(macro[0], macro[1]) if self.install_device: self._setupMedia(self.install_device) try: self.checkSoftwareSelection() self._download_location = self._pick_download_location() except packaging.PayloadError as e: if errors.errorHandler.cb(e) == errors.ERROR_RAISE: _failure_limbo() pkgs_to_download = self._base.transaction.install_set log.info('Downloading packages.') progressQ.send_message(_('Downloading packages')) progress = DownloadProgress() try: self._base.download_packages(pkgs_to_download, progress) except dnf.exceptions.DownloadError as e: msg = 'Failed to download the following packages: %s' % str(e) exc = packaging.PayloadInstallError(msg) if errors.errorHandler.cb(exc) == errors.ERROR_RAISE: _failure_limbo() log.info('Downloading packages finished.') pre_msg = _("Preparing transaction from installation source") progressQ.send_message(pre_msg) queue_instance = multiprocessing.Queue() process = multiprocessing.Process(target=do_transaction, args=(self._base, queue_instance)) process.start() (token, msg) = queue_instance.get() while token not in ('post', 'quit'): if token == 'install': msg = _("Installing %s") % msg progressQ.send_message(msg) (token, msg) = queue_instance.get() if token == 'quit': _failure_limbo() post_msg = _("Performing post-installation setup tasks") progressQ.send_message(post_msg) process.join() self._base.close() if os.path.exists(self._download_location): log.info("Cleaning up downloaded packages: %s", self._download_location) shutil.rmtree(self._download_location) else: # Some installation sources, such as NFS, don't need to download packages to # local storage, so the download location might not always exist. So for now # warn about this, at least until the RFE in bug 1193121 is implemented and # we don't have to care about clearing the download location ourselves. log.warning("Can't delete nonexistent download location: %s", self._download_location)
def preInstall(self, packages=None, groups=None): """ Perform pre-installation tasks. """ super(LiveCDCopyBackend, self).preInstall( packages=packages, groups=groups) progressQ.send_message(_("Installing software") + (" %d%%") % (0,)) self._sabayon_install = utils.SabayonInstall(self) self._packages = packages
def postInstall(self): """ Perform post-installation tasks. """ progressQ.send_message(_("Performing post-installation setup tasks")) blivet.util.umount(INSTALL_TREE) super(LiveImagePayload, self).postInstall() # Make sure the new system has a machine-id, it won't boot without it if not os.path.exists(iutil.getSysroot()+"/etc/machine-id"): iutil.execInSysroot("systemd-machine-id-setup", [])
def postInstall(self): """ Perform post-installation tasks. """ progressQ.send_message(_("Performing post-installation setup tasks")) blivet.util.umount(INSTALL_TREE) super().postInstall() # Make sure the new system has a machine-id, it won't boot without it if not os.path.exists(util.getSysroot() + "/etc/machine-id"): util.execInSysroot("systemd-machine-id-setup", [])
def _update(self): msg = _("Downloading %(total_files)s RPMs, " "%(downloaded)s / %(total_size)s (%(percent)d%%) done.") downloaded = Size(sum(self.downloads.values())) vals = { "downloaded": downloaded, "percent": int(100 * downloaded / self.total_size), "total_files": self.total_files, "total_size": self.total_size, } progressQ.send_message(msg % vals)
def cleanup_packages(self): progressQ.send_message(_("Removing install packages...")) packages = [ "app-arch/rpm", "app-admin/anaconda", "app-admin/authconfig", "app-admin/calamares-sabayon", "app-admin/calamares-sabayon-branding", "app-admin/calamares-sabayon-base-modules", "app-admin/calamares", "app-admin/setools", "app-emulation/spice-vdagent", "app-i18n/langtable", "dev-libs/libreport", "dev-libs/libtimezonemap", "dev-libs/satyr", "dev-python/ipy", "dev-python/pyblock", "dev-python/python-bugzilla", "dev-python/python-blivet", "dev-python/python-meh", "dev-python/python-nss", "dev-python/pyparted", "dev-python/sepolgen", "dev-util/pykickstart", "net-misc/fcoe-utils", "net-misc/tightvnc", "sys-apps/policycoreutils", "sys-libs/libsemanage", "sys-libs/libsepol", "libselinux", "sys-process/audit", ] chroot = ROOT_PATH root = etpSys['rootdir'] if chroot != root: self._change_entropy_chroot(chroot) try: repo = self._backend.entropy.installed_repository() for package in packages: pkg_id, _pkg_rc = repo.atomMatch(package) if pkg_id == -1: continue self.remove_package(package) finally: if chroot != root: self._change_entropy_chroot(root)
def _update(self): msg = _('Downloading %(total_files)s RPMs, ' '%(downloaded)s / %(total_size)s (%(percent)d%%) done.') downloaded = Size(sum(self.downloads.values())) vals = { 'downloaded' : downloaded, 'percent' : int(100 * downloaded/self.total_size), 'total_files' : self.total_files, 'total_size' : self.total_size } progressQ.send_message(msg % vals)
def _update(self): msg = _('Downloading %(total_files)s RPMs, ' '%(downloaded)s / %(total_size)s (%(percent)d%%) done.') downloaded = Size(sum(self.downloads.values())) vals = { 'downloaded': downloaded, 'percent': int(100 * downloaded / self.total_size), 'total_files': self.total_files, 'total_size': self.total_size } progressQ.send_message(msg % vals)
def install(self): cancellable = None from gi.repository import OSTree ostreesetup = self.data.ostreesetup log.info("executing ostreesetup=%r" % (ostreesetup, )) # Initialize the filesystem - this will create the repo as well self._safeExecWithRedirect( "ostree", ["admin", "--sysroot=" + ROOT_PATH, "init-fs", ROOT_PATH]) repo_arg = "--repo=" + ROOT_PATH + '/ostree/repo' # Set up the chosen remote remote_args = [repo_arg, "remote", "add"] if ostreesetup.noGpg: remote_args.append("--set=gpg-verify=false") remote_args.extend([ostreesetup.remote, ostreesetup.url]) self._safeExecWithRedirect("ostree", remote_args) sysroot_path = Gio.File.new_for_path(ROOT_PATH) sysroot = OSTree.Sysroot.new(sysroot_path) sysroot.load(cancellable) repo = sysroot.get_repo(None)[1] progressQ.send_message( _("Starting pull of %s from %s") % (ostreesetup.ref, ostreesetup.remote)) progress = OSTree.AsyncProgress.new() progress.connect('changed', self._pullProgressCb) repo.pull(ostreesetup.remote, [ostreesetup.ref], 0, progress, cancellable) self._safeExecWithRedirect( "ostree", ["admin", "--sysroot=" + ROOT_PATH, "os-init", ostreesetup.osname]) admin_deploy_args = [ "admin", "--sysroot=" + ROOT_PATH, "deploy", "--os=" + ostreesetup.osname ] admin_deploy_args.append(ostreesetup.osname + ':' + ostreesetup.ref) log.info("ostree admin deploy starting") self._safeExecWithRedirect("ostree", admin_deploy_args) log.info("ostree admin deploy complete") ostree_sysroot_path = os.path.join(ROOT_PATH, 'ostree/deploy', ostreesetup.osname, 'current') iutil.setSysroot(ostree_sysroot_path)
def _operation_started_callback(self, transaction, operation, progress): """Start of the new operation. :param transaction: the main transaction object :type transaction: Flatpak.Transaction instance :param operation: object describing the operation :type operation: Flatpak.TransactionOperation instance :param progress: object providing progess of the operation :type progress: Flatpak.TransactionProgress instance """ self._log_operation(operation, "started") progressQ.send_message(_("Installing %(flatpak_name)s") % {"flatpak_name": operation.get_ref()})
def postInstall(self): """ Perform post-installation tasks. """ progressQ.send_message(_("Performing post-installation setup tasks")) blivet.util.umount(INSTALL_TREE) super(LiveImagePayload, self).postInstall() # Live needs to create the rescue image before bootloader is written for kernel in self.kernelVersionList: log.info("Generating rescue image for %s", kernel) iutil.execWithRedirect("new-kernel-pkg", ["--rpmposttrans", kernel], root=ROOT_PATH)
def install(self): progressQ.send_message(_('Starting package installation process')) # Add the rpm macros to the global transaction environment for macro in self.rpmMacros: rpm.addMacro(macro[0], macro[1]) if self.install_device: self._setupMedia(self.install_device) try: self.checkSoftwareSelection() self._pick_download_location() except packaging.PayloadError as e: if errors.errorHandler.cb(e) == errors.ERROR_RAISE: _failure_limbo() pkgs_to_download = self._base.transaction.install_set log.info('Downloading pacakges.') progressQ.send_message(_('Downloading packages')) progress = DownloadProgress() try: self._base.download_packages(pkgs_to_download, progress) except dnf.exceptions.DownloadError as e: msg = 'Failed to download the following packages: %s' % str(e) exc = packaging.PayloadInstallError(msg) if errors.errorHandler.cb(exc) == errors.ERROR_RAISE: _failure_limbo() log.info('Downloading packages finished.') pre_msg = _("Preparing transaction from installation source") progressQ.send_message(pre_msg) queue = multiprocessing.Queue() process = multiprocessing.Process(target=do_transaction, args=(self._base, queue)) process.start() (token, msg) = queue.get() while token not in ('post', 'quit'): if token == 'install': msg = _("Installing %s") % msg progressQ.send_message(msg) (token, msg) = queue.get() if token == 'quit': _failure_limbo() post_msg = _("Performing post-installation setup tasks") progressQ.send_message(post_msg) process.join()
def update(self, bytes_read): """ Download update :param bytes_read: Bytes read so far :type bytes_read: int """ if not bytes_read: return pct = min(100, int(100 * bytes_read / self.size)) if pct == self._pct: return self._pct = pct progressQ.send_message(_("Downloading %(url)s (%(pct)d%%)") % {"url": self.url, "pct": pct})
def postInstall(self): """ Perform post-installation tasks. """ progressQ.send_message(_("Performing post-installation setup tasks")) blivet.util.umount(INSTALL_TREE) super(LiveImagePayload, self).postInstall() # Live needs to create the rescue image before bootloader is written for kernel in self.kernelVersionList: log.info("Generating rescue image for %s", kernel) iutil.execWithRedirect("new-kernel-pkg", ["--rpmposttrans", kernel], root=ROOT_PATH) # Make sure the new system has a machine-id, it won't boot without it if not os.path.exists(ROOT_PATH + "/etc/machine-id"): iutil.execWithRedirect("systemd-machine-id-setup", [], root=ROOT_PATH)
def setup_entropy_mirrors(self): progressQ.send_message("%s: %s" % ( _("Reordering Entropy mirrors"), _("can take some time..."),)) chroot = ROOT_PATH root = etpSys['rootdir'] if chroot != root: self._change_entropy_chroot(chroot) try: self._backend.entropy.reorder_mirrors(REPO_NAME) except Exception as err: log.error("Mirror reordering failure: %s" % (err,)) finally: if chroot != root: self._change_entropy_chroot(root)
def postInstall(self): """ Perform post-installation tasks. """ progressQ.send_message(_("Performing post-installation setup tasks")) blivet.util.umount(INSTALL_TREE) super().postInstall() # Make sure the new system has a machine-id, it won't boot without it # (and nor will some of the subsequent commands) if not os.path.exists(util.getSysroot() + "/etc/machine-id"): log.info("Generating machine ID") util.execInSysroot("systemd-machine-id-setup", []) for kernel in self.kernelVersionList: if flags.blscfg: log.info("Regenerating BLS info for %s", kernel) util.execInSysroot("kernel-install", ["add", kernel, "/lib/modules/{0}/vmlinuz".format(kernel)])
def postInstall(self): """ Perform post-installation tasks. """ progressQ.send_message(_("Performing post-installation setup tasks")) blivet.util.umount(INSTALL_TREE) super(LiveImagePayload, self).postInstall() # Live needs to create the rescue image before bootloader is written for kernel in self.kernelVersionList: log.info("Generating rescue image for %s", kernel) iutil.execWithRedirect("new-kernel-pkg", ["--rpmposttrans", kernel], root=ROOT_PATH) # Make sure the new system has a machine-id, it won't boot without it if not os.path.exists(ROOT_PATH+"/etc/machine-id"): iutil.execWithRedirect("systemd-machine-id-setup", [], root=ROOT_PATH)
def preInstall(self, packages=None, groups=None): """ Perform pre-installation tasks. """ super(SmartPayload, self).preInstall(packages, groups) progressQ.send_message(_("Starting package installation process")) log.info("%s %s, %s" % (self.__class__.__name__, inspect.stack()[0][3], self.image)) log.info("%s %s, %s" % (self.__class__.__name__, inspect.stack()[0][3], self.tasks)) if packages: self.requiredPackages += packages self.requiredGroups = groups if self.install_device: self._setupMedia(self.install_device) self.checkSoftwareSelection()
def setup_entropy_mirrors(self): progressQ.send_message("%s: %s" % ( _("Reordering Entropy mirrors"), _("can take some time..."), )) chroot = ROOT_PATH root = etpSys['rootdir'] if chroot != root: self._change_entropy_chroot(chroot) try: self._backend.entropy.reorder_mirrors(REPO_NAME) except Exception as err: log.error("Mirror reordering failure: %s" % (err, )) finally: if chroot != root: self._change_entropy_chroot(root)
def post_install(self): """ Perform post-installation tasks. """ progressQ.send_message(_("Performing post-installation setup tasks")) payload_utils.unmount(INSTALL_TREE, raise_exc=True) super().post_install() # Make sure the new system has a machine-id, it won't boot without it # (and nor will some of the subsequent commands) if not os.path.exists(util.getSysroot() + "/etc/machine-id"): log.info("Generating machine ID") util.execInSysroot("systemd-machine-id-setup", []) for kernel in self.kernel_version_list: if not os.path.exists(util.getSysroot() + "/usr/sbin/new-kernel-pkg"): log.info("Regenerating BLS info for %s", kernel) util.execInSysroot("kernel-install", ["add", kernel, "/lib/modules/{0}/vmlinuz".format(kernel)])
def cleanup_packages(self): progressQ.send_message(_("Removing install packages...")) packages = [ "app-arch/rpm", "app-admin/anaconda", "app-admin/authconfig", "app-admin/calamares-sabayon", "app-admin/calamares-sabayon-branding", "app-admin/calamares-sabayon-base-modules", "app-admin/calamares", "dev-libs/libreport", "dev-libs/satyr", "dev-python/python-blivet", "dev-python/python-meh", "dev-util/pykickstart", "sys-apps/policycoreutils", "sys-libs/libsemanage", "sys-libs/libsepol", "libselinux", "sys-process/audit", ] chroot = ROOT_PATH root = etpSys['rootdir'] if chroot != root: self._change_entropy_chroot(chroot) try: repo = self._backend.entropy.installed_repository() for package in packages: pkg_id, _pkg_rc = repo.atomMatch(package) if pkg_id == -1: continue self.remove_package(package) finally: if chroot != root: self._change_entropy_chroot(root)
def postInstall(self): """ Perform post-installation tasks. """ progressQ.send_message(_("Performing post-installation setup tasks")) blivet.util.umount(INSTALL_TREE) super().postInstall() # Make sure the new system has a machine-id, it won't boot without it # (and nor will some of the subsequent commands) if not os.path.exists(util.getSysroot() + "/etc/machine-id"): log.info("Generating machine ID") util.execInSysroot("systemd-machine-id-setup", []) for kernel in self.kernelVersionList: if flags.blscfg: log.info("Regenerating BLS info for %s", kernel) util.execInSysroot( "kernel-install", ["add", kernel, "/lib/modules/{0}/vmlinuz".format(kernel)])
def update_entropy_repositories(self): progressQ.send_message(_("Downloading software repositories...")) settings = SystemSettings() chroot = ROOT_PATH root = etpSys['rootdir'] if chroot != root: self._change_entropy_chroot(chroot) repos = list(settings['repositories']['available'].keys()) try: # fetch_security = False => avoid spamming stdout try: repo_intf = self._backend.entropy.Repositories( repos, fetch_security=False) except AttributeError as err: log.error("No repositories in repositories.conf") return False except Exception as err: log.error("Unhandled exception: %s" % (err,)) return False try: update_rc = repo_intf.sync() except Exception as err: log.error("Sync error: %s" % (err,)) return False if repo_intf.sync_errors or (update_rc != 0): log.error("Cannot download repositories atm") return False return update_rc == 0 finally: self._backend.entropy.close_repositories() settings.clear() if chroot != root: self._change_entropy_chroot(root)
def update_entropy_repositories(self): progressQ.send_message(_("Downloading software repositories...")) settings = SystemSettings() chroot = ROOT_PATH root = etpSys['rootdir'] if chroot != root: self._change_entropy_chroot(chroot) repos = list(settings['repositories']['available'].keys()) try: # fetch_security = False => avoid spamming stdout try: repo_intf = self._backend.entropy.Repositories( repos, fetch_security=False) except AttributeError as err: log.error("No repositories in repositories.conf") return False except Exception as err: log.error("Unhandled exception: %s" % (err, )) return False try: update_rc = repo_intf.sync() except Exception as err: log.error("Sync error: %s" % (err, )) return False if repo_intf.sync_errors or (update_rc != 0): log.error("Cannot download repositories atm") return False return update_rc == 0 finally: self._backend.entropy.close_repositories() settings.clear() if chroot != root: self._change_entropy_chroot(root)
def post_install(self): """ Perform post-installation tasks. """ progressQ.send_message(_("Performing post-installation setup tasks")) payload_utils.unmount(INSTALL_TREE, raise_exc=True) super().post_install() # Not using BLS configuration, skip it if os.path.exists(conf.target.system_root + "/usr/sbin/new-kernel-pkg"): return # Remove any existing BLS entries, they will not match the new system's # machine-id or /boot mountpoint. for file in glob.glob(conf.target.system_root + "/boot/loader/entries/*.conf"): log.info("Removing old BLS entry: %s", file) os.unlink(file) # Create new BLS entries for this system for kernel in self.kernel_version_list: log.info("Regenerating BLS info for %s", kernel) util.execInSysroot( "kernel-install", ["add", kernel, "/lib/modules/{0}/vmlinuz".format(kernel)]) # Update the bootloader configuration to make sure that the BLS # entries will have the correct kernel cmdline and not the value # taken from /proc/cmdline, that is used to boot the live image. bootloader = STORAGE.get_proxy(BOOTLOADER) if bootloader.IsEFI(): grub_cfg_path = "/etc/grub2-efi.cfg" else: grub_cfg_path = "/etc/grub2.cfg" # TODO: add a method to the bootloader interface that updates the # configuration and avoid having bootloader specific logic here. rc = util.execInSysroot("grub2-mkconfig", ["-o", grub_cfg_path]) if rc: raise BootloaderInstallationError( "failed to write boot loader configuration")
def progress(self): """Monitor the amount of disk space used on the target and source and update the hub's progress bar. """ mount_points = payload_utils.get_mount_points() last_pct = -1 while self.pct < 100: dest_size = self._get_destination_size(mount_points) if dest_size >= self._adj_size: dest_size -= self._adj_size pct = int(100 * dest_size / self.source_size) if pct != last_pct: with self.pct_lock: self.pct = pct last_pct = pct progressQ.send_message(_("Installing software") + (" %d%%") % (min(100, self.pct),)) sleep(0.777)
def progress(self): """Monitor the amount of disk space used on the target and source and update the hub's progress bar. """ mountpoints = self.storage.mountpoints.copy() last_pct = -1 while self.pct < 100: dest_size = 0 for mnt in mountpoints: mnt_stat = iutil.eintr_retry_call(os.statvfs, iutil.getSysroot()+mnt) dest_size += mnt_stat.f_frsize * (mnt_stat.f_blocks - mnt_stat.f_bfree) if dest_size >= self._adj_size: dest_size -= self._adj_size pct = int(100 * dest_size / self.source_size) if pct != last_pct: with self.pct_lock: self.pct = pct last_pct = pct progressQ.send_message(_("Installing software") + (" %d%%") % (min(100, self.pct),)) sleep(0.777)
def _pull_progress_cb(self, asyncProgress): status = asyncProgress.get_status() outstanding_fetches = asyncProgress.get_uint('outstanding-fetches') if status: progressQ.send_message(status) elif outstanding_fetches > 0: bytes_transferred = asyncProgress.get_uint64('bytes-transferred') fetched = asyncProgress.get_uint('fetched') requested = asyncProgress.get_uint('requested') formatted_bytes = format_size_full(bytes_transferred, 0) if requested == 0: percent = 0.0 else: percent = (fetched * 1.0 / requested) * 100 progressQ.send_message( _("Receiving objects: %(percent)d%% " "(%(fetched)d/%(requested)d) %(bytes)s") % { "percent": percent, "fetched": fetched, "requested": requested, "bytes": formatted_bytes }) else: progressQ.send_message(_("Writing objects"))
def progress(self): """Monitor the amount of disk space used on the target and source and update the hub's progress bar. """ source = os.statvfs(INSTALL_TREE) source_size = source.f_frsize * (source.f_blocks - source.f_bfree) mountpoints = self.storage.mountpoints.copy() last_pct = -1 while self.pct < 100: dest_size = 0 for mnt in mountpoints: mnt_stat = os.statvfs(ROOT_PATH+mnt) dest_size += mnt_stat.f_frsize * (mnt_stat.f_blocks - mnt_stat.f_bfree) if dest_size >= self._adj_size: dest_size -= self._adj_size pct = int(100 * dest_size / source_size) if pct != last_pct: with self.pct_lock: self.pct = pct last_pct = pct progressQ.send_message(_("Installing software") + (" %d%%") % (min(100, self.pct),)) sleep(0.777)
def _pullProgressCb(self, asyncProgress): status = asyncProgress.get_status() outstanding_fetches = asyncProgress.get_uint('outstanding-fetches') if status: progressQ.send_message(status) elif outstanding_fetches > 0: bytes_transferred = asyncProgress.get_uint64('bytes-transferred') fetched = asyncProgress.get_uint('fetched') requested = asyncProgress.get_uint('requested') formatted_bytes = GLib.format_size_full(bytes_transferred, 0) if requested == 0: percent = 0.0 else: percent = (fetched*1.0 / requested) * 100 progressQ.send_message("Receiving objects: %d%% (%d/%d) %s" % (percent, fetched, requested, formatted_bytes)) else: progressQ.send_message("Writing objects")
def _pull_progress_cb(self, asyncProgress): status = asyncProgress.get_status() outstanding_fetches = asyncProgress.get_uint('outstanding-fetches') if status: progressQ.send_message(status) elif outstanding_fetches > 0: bytes_transferred = asyncProgress.get_uint64('bytes-transferred') fetched = asyncProgress.get_uint('fetched') requested = asyncProgress.get_uint('requested') formatted_bytes = format_size_full(bytes_transferred, 0) if requested == 0: percent = 0.0 else: percent = (fetched * 1.0 / requested) * 100 progressQ.send_message(_("Receiving objects: %(percent)d%% " "(%(fetched)d/%(requested)d) %(bytes)s") % {"percent": percent, "fetched": fetched, "requested": requested, "bytes": formatted_bytes} ) else: progressQ.send_message(_("Writing objects"))
def install(self): mainctx = GLib.MainContext.new() mainctx.push_thread_default() cancellable = None gi.require_version("OSTree", "1.0") from gi.repository import OSTree ostreesetup = self.data.ostreesetup log.info("executing ostreesetup=%r", ostreesetup) # Initialize the filesystem - this will create the repo as well self._safeExecWithRedirect("ostree", ["admin", "--sysroot=" + iutil.getTargetPhysicalRoot(), "init-fs", iutil.getTargetPhysicalRoot()]) self._sysroot_path = Gio.File.new_for_path(iutil.getTargetPhysicalRoot()) sysroot = OSTree.Sysroot.new(self._sysroot_path) sysroot.load(cancellable) repo = sysroot.get_repo(None)[1] # We don't support resuming from interrupted installs repo.set_disable_fsync(True) self._remoteOptions = {} if hasattr(ostreesetup, 'nogpg') and ostreesetup.nogpg: self._remoteOptions['gpg-verify'] = GLib.Variant('b', False) if flags.noverifyssl: self._remoteOptions['tls-permissive'] = GLib.Variant('b', True) repo.remote_change(None, OSTree.RepoRemoteChange.ADD_IF_NOT_EXISTS, ostreesetup.remote, ostreesetup.url, GLib.Variant('a{sv}', self._remoteOptions), cancellable) progressQ.send_message(_("Starting pull of %(branchName)s from %(source)s") % \ {"branchName": ostreesetup.ref, "source": ostreesetup.remote}) progress = OSTree.AsyncProgress.new() progress.connect('changed', self._pullProgressCb) try: repo.pull(ostreesetup.remote, [ostreesetup.ref], 0, progress, cancellable) except GLib.GError as e: exn = PayloadInstallError("Failed to pull from repository: %s" % e) log.error(str(exn)) if errors.errorHandler.cb(exn) == errors.ERROR_RAISE: progressQ.send_quit(1) iutil.ipmi_report(constants.IPMI_ABORTED) sys.exit(1) progressQ.send_message(_("Preparing deployment of %s") % (ostreesetup.ref, )) # Now that we have the data pulled, delete the remote for now. # This will allow a remote configuration defined in the tree # (if any) to override what's in the kickstart. Otherwise, # we'll re-add it in post. Ideally, ostree would support a # pull without adding a remote, but that would get quite # complex. repo.remote_delete(self.data.ostreesetup.remote, None) self._safeExecWithRedirect("ostree", ["admin", "--sysroot=" + iutil.getTargetPhysicalRoot(), "os-init", ostreesetup.osname]) admin_deploy_args = ["admin", "--sysroot=" + iutil.getTargetPhysicalRoot(), "deploy", "--os=" + ostreesetup.osname] admin_deploy_args.append(ostreesetup.remote + ':' + ostreesetup.ref) log.info("ostree admin deploy starting") progressQ.send_message(_("Deployment starting: %s") % (ostreesetup.ref, )) self._safeExecWithRedirect("ostree", admin_deploy_args) log.info("ostree admin deploy complete") progressQ.send_message(_("Deployment complete: %s") % (ostreesetup.ref, )) # Reload now that we've deployed, find the path to the new deployment sysroot.load(None) deployments = sysroot.get_deployments() assert len(deployments) > 0 deployment = deployments[0] deployment_path = sysroot.get_deployment_directory(deployment) iutil.setSysroot(deployment_path.get_path()) try: self._copyBootloaderData() except (OSError, RuntimeError) as e: exn = PayloadInstallError("Failed to copy bootloader data: %s" % e) log.error(str(exn)) if errors.errorHandler.cb(exn) == errors.ERROR_RAISE: progressQ.send_quit(1) iutil.ipmi_report(constants.IPMI_ABORTED) sys.exit(1) mainctx.pop_thread_default()
def install(self): mainctx = GLib.MainContext.new() mainctx.push_thread_default() cancellable = None gi.require_version("OSTree", "1.0") gi.require_version("RpmOstree", "1.0") from gi.repository import OSTree, RpmOstree ostreesetup = self.data.ostreesetup log.info("executing ostreesetup=%r", ostreesetup) # Initialize the filesystem - this will create the repo as well self._safeExecWithRedirect("ostree", ["admin", "--sysroot=" + iutil.getTargetPhysicalRoot(), "init-fs", iutil.getTargetPhysicalRoot()]) # Here, we use the physical root as sysroot, because we haven't # yet made a deployment. sysroot_file = Gio.File.new_for_path(iutil.getTargetPhysicalRoot()) sysroot = OSTree.Sysroot.new(sysroot_file) sysroot.load(cancellable) repo = sysroot.get_repo(None)[1] # We don't support resuming from interrupted installs repo.set_disable_fsync(True) self._remoteOptions = {} if hasattr(ostreesetup, 'nogpg') and ostreesetup.nogpg: self._remoteOptions['gpg-verify'] = GLib.Variant('b', False) if flags.noverifyssl: self._remoteOptions['tls-permissive'] = GLib.Variant('b', True) repo.remote_change(None, OSTree.RepoRemoteChange.ADD_IF_NOT_EXISTS, ostreesetup.remote, ostreesetup.url, GLib.Variant('a{sv}', self._remoteOptions), cancellable) # Variable substitute the ref: https://pagure.io/atomic-wg/issue/299 ref = RpmOstree.varsubst_basearch(ostreesetup.ref) progressQ.send_message(_("Starting pull of %(branchName)s from %(source)s") % \ {"branchName": ref, "source": ostreesetup.remote}) progress = OSTree.AsyncProgress.new() progress.connect('changed', self._pullProgressCb) pull_opts = {'refs': GLib.Variant('as', [ref])} # If we're doing a kickstart, we can at least use the content as a reference: # See <https://github.com/rhinstaller/anaconda/issues/1117> # The first path here is used by <https://pagure.io/fedora-lorax-templates> # and the second by <https://github.com/projectatomic/rpm-ostree-toolbox/> if OSTree.check_version(2017, 8): for path in ['/ostree/repo', '/install/ostree/repo']: if os.path.isdir(path + '/objects'): pull_opts['localcache-repos'] = GLib.Variant('as', [path]) break try: repo.pull_with_options(ostreesetup.remote, GLib.Variant('a{sv}', pull_opts), progress, cancellable) except GLib.GError as e: exn = PayloadInstallError("Failed to pull from repository: %s" % e) log.error(str(exn)) if errors.errorHandler.cb(exn) == errors.ERROR_RAISE: progressQ.send_quit(1) iutil.ipmi_abort(scripts=self.data.scripts) sys.exit(1) log.info("ostree pull: " + (progress.get_status() or "")) progressQ.send_message(_("Preparing deployment of %s") % (ref, )) # Now that we have the data pulled, delete the remote for now. # This will allow a remote configuration defined in the tree # (if any) to override what's in the kickstart. Otherwise, # we'll re-add it in post. Ideally, ostree would support a # pull without adding a remote, but that would get quite # complex. repo.remote_delete(self.data.ostreesetup.remote, None) self._safeExecWithRedirect("ostree", ["admin", "--sysroot=" + iutil.getTargetPhysicalRoot(), "os-init", ostreesetup.osname]) admin_deploy_args = ["admin", "--sysroot=" + iutil.getTargetPhysicalRoot(), "deploy", "--os=" + ostreesetup.osname] admin_deploy_args.append(ostreesetup.remote + ':' + ref) log.info("ostree admin deploy starting") progressQ.send_message(_("Deployment starting: %s") % (ref, )) self._safeExecWithRedirect("ostree", admin_deploy_args) log.info("ostree admin deploy complete") progressQ.send_message(_("Deployment complete: %s") % (ref, )) # Reload now that we've deployed, find the path to the new deployment sysroot.load(None) deployments = sysroot.get_deployments() assert len(deployments) > 0 deployment = deployments[0] deployment_path = sysroot.get_deployment_directory(deployment) iutil.setSysroot(deployment_path.get_path()) try: self._copyBootloaderData() except (OSError, RuntimeError) as e: exn = PayloadInstallError("Failed to copy bootloader data: %s" % e) log.error(str(exn)) if errors.errorHandler.cb(exn) == errors.ERROR_RAISE: progressQ.send_quit(1) iutil.ipmi_abort(scripts=self.data.scripts) sys.exit(1) mainctx.pop_thread_default()
def preInstall(self, *args, **kwargs): """ Get image and loopback mount it. This is called after partitioning is setup, we now have space to grab the image. If it is a network source Download it to sysroot and provide feedback during the download (using urlgrabber callback). If it is a file:// source then use the file directly. """ error = None if self.data.method.url.startswith("file://"): self.image_path = self.data.method.url[7:] else: error = self._preInstall_url_image() if error: exn = PayloadInstallError(str(error)) if errorHandler.cb(exn) == ERROR_RAISE: raise exn # Used to make install progress % look correct self._adj_size = os.stat(self.image_path)[stat.ST_SIZE] if self.data.method.checksum: progressQ.send_message(_("Checking image checksum")) sha256 = hashlib.sha256() with open(self.image_path, "rb") as f: while True: data = f.read(1024*1024) if not data: break sha256.update(data) filesum = sha256.hexdigest() log.debug("sha256 of %s is %s", self.data.method.url, filesum) if lowerASCII(self.data.method.checksum) != filesum: log.error("%s does not match checksum.", self.data.method.checksum) exn = PayloadInstallError("Checksum of image does not match") if errorHandler.cb(exn) == ERROR_RAISE: raise exn # If this looks like a tarfile, skip trying to mount it if self.is_tarfile: return # Mount the image and check to see if it is a LiveOS/*.img # style squashfs image. If so, move it to IMAGE_DIR and mount the real # root image on INSTALL_TREE rc = blivet.util.mount(self.image_path, INSTALL_TREE, fstype="auto", options="ro") if rc != 0: log.error("mount error (%s) with %s", rc, self.image_path) exn = PayloadInstallError("mount error %s" % rc) if errorHandler.cb(exn) == ERROR_RAISE: raise exn # Nothing more to mount if not os.path.exists(INSTALL_TREE+"/LiveOS"): self._updateKernelVersionList() return # Mount the first .img in the directory on INSTALL_TREE img_files = glob.glob(INSTALL_TREE+"/LiveOS/*.img") if img_files: # move the mount to IMAGE_DIR os.makedirs(IMAGE_DIR, 0o755) # work around inability to move shared filesystems rc = iutil.execWithRedirect("mount", ["--make-rprivate", "/"]) if rc == 0: rc = iutil.execWithRedirect("mount", ["--move", INSTALL_TREE, IMAGE_DIR]) if rc != 0: log.error("error %s moving mount", rc) exn = PayloadInstallError("mount error %s" % rc) if errorHandler.cb(exn) == ERROR_RAISE: raise exn img_file = IMAGE_DIR+"/LiveOS/"+os.path.basename(sorted(img_files)[0]) rc = blivet.util.mount(img_file, INSTALL_TREE, fstype="auto", options="ro") if rc != 0: log.error("mount error (%s) with %s", rc, img_file) exn = PayloadInstallError("mount error %s with %s" % (rc, img_file)) if errorHandler.cb(exn) == ERROR_RAISE: raise exn self._updateKernelVersionList() source = iutil.eintr_retry_call(os.statvfs, INSTALL_TREE) self.source_size = source.f_frsize * (source.f_blocks - source.f_bfree)
def preInstall(self, *args, **kwargs): """ Download image and loopback mount it. This is called after partitioning is setup, we now have space to grab the image. Download it to ROOT_PATH and provide feedback during the download (using urlgrabber callback). """ # Setup urlgrabber and call back to download image to ROOT_PATH progress = URLGrabberProgress() ugopts = {"ssl_verify_peer": not self.data.method.noverifyssl, "ssl_verify_host": not self.data.method.noverifyssl, "proxies" : self._proxies, "progress_obj" : progress, "copy_local" : True} error = None try: ug = URLGrabber() ug.urlgrab(self.data.method.url, self.image_path, **ugopts) except URLGrabError as e: log.error("Error downloading liveimg: %s", e) error = e else: if not os.path.exists(self.image_path): error = "Failed to download %s, file doesn't exist" % self.data.method.url log.error(error) if error: exn = PayloadInstallError(str(error)) if errorHandler.cb(exn) == ERROR_RAISE: raise exn # Used to make install progress % look correct self._adj_size = os.stat(self.image_path)[stat.ST_SIZE] if self.data.method.checksum: progressQ.send_message(_("Checking image checksum")) sha256 = hashlib.sha256() with open(self.image_path, "rb") as f: while True: data = f.read(1024*1024) if not data: break sha256.update(data) filesum = sha256.hexdigest() log.debug("sha256 of %s is %s", self.data.method.url, filesum) if lowerASCII(self.data.method.checksum) != filesum: log.error("%s does not match checksum.", self.data.method.checksum) exn = PayloadInstallError("Checksum of image does not match") if errorHandler.cb(exn) == ERROR_RAISE: raise exn # Mount the image and check to see if it is a LiveOS/*.img # style squashfs image. If so, move it to IMAGE_DIR and mount the real # root image on INSTALL_TREE blivet.util.mount(self.image_path, INSTALL_TREE, fstype="auto", options="ro") if os.path.exists(INSTALL_TREE+"/LiveOS"): # Find the first .img in the directory and mount that on INSTALL_TREE img_files = glob.glob(INSTALL_TREE+"/LiveOS/*.img") if img_files: img_file = os.path.basename(sorted(img_files)[0]) # move the mount to IMAGE_DIR os.makedirs(IMAGE_DIR, 0755) # work around inability to move shared filesystems iutil.execWithRedirect("mount", ["--make-rprivate", "/"]) iutil.execWithRedirect("mount", ["--move", INSTALL_TREE, IMAGE_DIR]) blivet.util.mount(IMAGE_DIR+"/LiveOS/"+img_file, INSTALL_TREE, fstype="auto", options="ro")
def preInstall(self, packages=None, groups=None): """ Perform pre-installation tasks. """ super(LiveImagePayload, self).preInstall(packages=packages, groups=groups) progressQ.send_message(_("Installing software") + (" %d%%") % (0,))
def pre_install(self): """ Perform pre-installation tasks. """ super().pre_install() progressQ.send_message(_("Installing software") + (" %d%%") % (0,))