예제 #1
0
    def _set_default_boot_target(self):
        """Set the default systemd target for the system."""
        if not os.path.exists(util.getSysroot() + "/etc/systemd/system"):
            log.error("systemd is not installed -- can't set default target")
            return

        # If the target was already set, we don't have to continue.
        services_proxy = SERVICES.get_proxy()
        if services_proxy.DefaultTarget:
            log.debug("The default target is already set.")
            return

        try:
            import rpm
        except ImportError:
            log.info("failed to import rpm -- not adjusting default runlevel")
        else:
            ts = rpm.TransactionSet(util.getSysroot())

            # XXX one day this might need to account for anaconda's display mode
            if ts.dbMatch("provides", 'service(graphical-login)').count() and \
               not flags.usevnc:
                # We only manipulate the ksdata.  The symlink is made later
                # during the config write out.
                services_proxy.SetDefaultTarget(GRAPHICAL_TARGET)
            else:
                services_proxy.SetDefaultTarget(TEXT_ONLY_TARGET)
예제 #2
0
파일: zipl.py 프로젝트: rvykydal/anaconda
    def update_bls_args(self, image, args):
        machine_id_path = util.getSysroot() + "/etc/machine-id"
        if not os.access(machine_id_path, os.R_OK):
            log.error("failed to read machine-id file")
            return

        with open(machine_id_path, "r") as fd:
            machine_id = fd.readline().strip()

        bls_dir = "%s%s/loader/entries/" % (util.getSysroot(), self.boot_dir)

        if image.kernel == "vmlinuz-0-rescue-" + machine_id:
            bls_path = "%s%s-0-rescue.conf" % (bls_dir, machine_id)
        else:
            bls_path = "%s%s-%s.conf" % (bls_dir, machine_id, image.version)

        if not os.access(bls_path, os.W_OK):
            log.error("failed to update boot args in BLS file %s", bls_path)
            return

        with open(bls_path, "r") as bls:
            lines = bls.readlines()
            for i, line in enumerate(lines):
                if line.startswith("options "):
                    lines[i] = "options %s\n" % (args)

        with open(bls_path, "w") as bls:
            bls.writelines(lines)
예제 #3
0
    def prepare_mount_targets(self, storage):
        """ Prepare the ostree root """
        ostreesetup = self.data.ostreesetup

        # Currently, blivet sets up mounts in the physical root.
        # We used to unmount them and remount them in the sysroot, but
        # since 664ef7b43f9102aa9332d0db5b7d13f8ece436f0 we now just set up
        # bind mounts.

        # Make /usr readonly like ostree does at runtime normally
        self._setup_internal_bindmount('/usr', bind_ro=True, src_physical=False)

        # Explicitly do API mounts; some of these may be tracked by blivet, but
        # we'll skip them below.
        api_mounts = ["/dev", "/proc", "/run", "/sys"]
        for path in api_mounts:
            self._setup_internal_bindmount(path)

        # Handle /var; if the admin didn't specify a mount for /var, we need
        # to do the default ostree one.
        # https://github.com/ostreedev/ostree/issues/855
        var_root = '/ostree/deploy/' + ostreesetup.osname + '/var'
        if storage.mountpoints.get("/var") is None:
            self._setup_internal_bindmount(var_root, dest='/var', recurse=False)
        else:
            # Otherwise, bind it
            self._setup_internal_bindmount('/var', recurse=False)

        # Now that we have /var, start filling in any directories that may be
        # required later there. We explicitly make /var/lib, since
        # systemd-tmpfiles doesn't have a --prefix-only=/var/lib. We rely on
        # 80-setfilecons.ks to set the label correctly.
        util.mkdirChain(util.getSysroot() + '/var/lib')
        # Next, run tmpfiles to make subdirectories of /var. We need this for
        # both mounts like /home (really /var/home) and %post scripts might
        # want to write to e.g. `/srv`, `/root`, `/usr/local`, etc. The
        # /var/lib/rpm symlink is also critical for having e.g. `rpm -qa` work
        # in %post. We don't iterate *all* tmpfiles because we don't have the
        # matching NSS configuration inside Anaconda, and we can't "chroot" to
        # get it because that would require mounting the API filesystems in the
        # target.
        for varsubdir in ('home', 'roothome', 'lib/rpm', 'opt', 'srv',
                          'usrlocal', 'mnt', 'media', 'spool', 'spool/mail'):
            self._safe_exec_with_redirect("systemd-tmpfiles",
                                          ["--create", "--boot", "--root=" + util.getSysroot(),
                                           "--prefix=/var/" + varsubdir])

        # Handle mounts like /boot (except avoid /boot/efi; we just need the
        # toplevel), and any admin-specified points like /home (really
        # /var/home). Note we already handled /var above. Avoid recursion since
        # sub-mounts will be in the list too.  We sort by length as a crude
        # hack to try to simulate the tree relationship; it looks like this
        # is handled in blivet in a different way.
        for mount in sorted(storage.mountpoints, key=len):
            if mount in ('/', '/var') or mount in api_mounts:
                continue
            self._setup_internal_bindmount(mount, recurse=False)

        # And finally, do a nonrecursive bind for the sysroot
        self._setup_internal_bindmount("/", dest="/sysroot", recurse=False)
예제 #4
0
파일: grub2.py 프로젝트: rvykydal/anaconda
    def write_defaults(self):
        defaults_file = "%s%s" % (util.getSysroot(), self.defaults_file)
        defaults = open(defaults_file, "w+")
        defaults.write("GRUB_TIMEOUT=%d\n" % self.timeout)
        defaults.write("GRUB_DISTRIBUTOR=\"$(sed 's, release .*$,,g' /etc/system-release)\"\n")
        defaults.write("GRUB_DEFAULT=saved\n")
        defaults.write("GRUB_DISABLE_SUBMENU=true\n")
        if self.console and self.has_serial_console:
            defaults.write("GRUB_TERMINAL=\"serial console\"\n")
            defaults.write("GRUB_SERIAL_COMMAND=\"%s\"\n" % self.serial_command)
        else:
            defaults.write("GRUB_TERMINAL_OUTPUT=\"%s\"\n" % self.terminal_type)

        # this is going to cause problems for systems containing multiple
        # linux installations or even multiple boot entries with different
        # boot arguments
        log.info("bootloader.py: used boot args: %s ", self.boot_args)
        defaults.write("GRUB_CMDLINE_LINUX=\"%s\"\n" % self.boot_args)
        defaults.write("GRUB_DISABLE_RECOVERY=\"true\"\n")
        #defaults.write("GRUB_THEME=\"/boot/grub2/themes/system/theme.txt\"\n")

        if self.use_bls and os.path.exists(util.getSysroot() + "/usr/sbin/new-kernel-pkg"):
            log.warning("BLS support disabled due new-kernel-pkg being present")
            self.use_bls = False

        if self.use_bls:
            defaults.write("GRUB_ENABLE_BLSCFG=true\n")
        defaults.close()
예제 #5
0
    def execute(self):
        unit_name = "initial-setup.service"
        services_proxy = SERVICES.get_proxy()
        setup_on_boot = services_proxy.SetupOnBoot

        if setup_on_boot == SETUP_ON_BOOT_DISABLED:
            log.debug("The %s service will be disabled.", unit_name)
            util.disable_service(unit_name)
            # Also tell the screen access manager, so that the fact that post installation tools
            # should be disabled propagates to the user interaction config file.
            screen_access.sam.post_install_tools_disabled = True
            return

        if not os.path.exists(os.path.join(util.getSysroot(), "lib/systemd/system/", unit_name)):
            log.debug("The %s service will not be started on first boot, because "
                      "it's unit file is not installed.", unit_name)
            return

        if setup_on_boot == SETUP_ON_BOOT_RECONFIG:
            log.debug("The %s service will run in the reconfiguration mode.", unit_name)
            # write the reconfig trigger file
            f = open(os.path.join(util.getSysroot(), "etc/reconfigSys"), "w+")
            f.close()

        log.debug("The %s service will be enabled.", unit_name)
        util.enable_service(unit_name)
예제 #6
0
파일: kexec.py 프로젝트: zhangsju/anaconda
def setup_kexec():
    """ Setup kexec to use the new kernel and default bootloader entry

        This uses grubby to determine the bootloader arguments from the default entry,
        and then sets up kexec so that reboot will use the new kernel and initrd instead
        of doing a full reboot.

        .. note::
            Once kexec is called there is nothing else to do, the reboot code already handles
            having kexec setup.
    """
    try:
        boot_info = run_grubby()
    except GrubbyInfoError:
        # grubby couldn't find a default entry, use the first one instead
        try:
            boot_info = run_grubby(["--info", "ALL"])
        except GrubbyInfoError:
            # Grubby can't get the bootloader's info, kexec won't work.
            log.error("kexec reboot setup failed, grubby could not get bootloader info.")
            return

    # Copy the kernel and initrd to /tmp/
    shutil.copy2(getSysroot() + boot_info.kernel, "/tmp/vmlinuz-kexec-reboot")
    shutil.copy2(getSysroot() + boot_info.initrd, "/tmp/initrd-kexec-reboot")

    append = "root=%s %s" % (boot_info.root, boot_info.args)
    args = ["--initrd", "/tmp/initrd-kexec-reboot", "--append", append, "-l", "/tmp/vmlinuz-kexec-reboot"]
    try:
        rc = execWithRedirect("kexec", args)
    except OSError as e:
        log.error("setup_kexec failed: %s", e)
    if rc != 0:
        log.error("setup_kexec failed with rc=%d: See program.log for output", rc)
예제 #7
0
파일: rescue.py 프로젝트: rvykydal/anaconda
    def mount_root(self, root):
        """Mounts selected root and runs scripts."""
        # mount root fs
        try:
            mount_existing_system(self._storage.fsset, root.device, read_only=self.ro)
            log.info("System has been mounted under: %s", util.getSysroot())
        except StorageError as e:
            log.error("Mounting system under %s failed: %s", util.getSysroot(), e)
            self.status = RescueModeStatus.MOUNT_FAILED
            return False

        # turn on swap
        if not conf.target.is_image or not self.ro:
            try:
                self._storage.turn_on_swap()
            except StorageError:
                log.error("Error enabling swap.")

        # turn on selinux also
        if conf.security.selinux:
            # we have to catch the possible exception, because we
            # support read-only mounting
            try:
                fd = open("%s/.autorelabel" % util.getSysroot(), "w+")
                fd.close()
            except IOError as e:
                log.warning("Error turning on selinux: %s", e)

        # set a libpath to use mounted fs
        libdirs = os.environ.get("LD_LIBRARY_PATH", "").split(":")
        mounted = ["/mnt/sysimage%s" % ldir for ldir in libdirs]
        util.setenv("LD_LIBRARY_PATH", ":".join(libdirs + mounted))

        # do we have bash?
        try:
            if os.access("/usr/bin/bash", os.R_OK):
                os.symlink("/usr/bin/bash", "/bin/bash")
        except OSError as e:
            log.error("Error symlinking bash: %s", e)

        # make resolv.conf in chroot
        if not self.ro:
            self._storage.make_mtab()
            try:
                makeResolvConf(util.getSysroot())
            except(OSError, IOError) as e:
                log.error("Error making resolv.conf: %s", e)

        # create /etc/fstab in ramdisk so it's easier to work with RO mounted fs
        makeFStab()

        # run %post if we've mounted everything
        if not self.ro and self._scripts:
            runPostScripts(self._scripts)

        self.status = RescueModeStatus.MOUNTED
        return True
예제 #8
0
    def sysroot_test(self):
        self.assertEqual(util.getTargetPhysicalRoot(), "/mnt/sysimage")
        self.assertEqual(util.getSysroot(), "/mnt/sysimage")

        util.setSysroot("/what/ever")
        self.assertEqual(util.getTargetPhysicalRoot(), "/mnt/sysimage")
        self.assertEqual(util.getSysroot(), "/what/ever")

        util.setSysroot(None)
        self.assertEqual(util.getTargetPhysicalRoot(), "/mnt/sysimage")
        self.assertEqual(util.getSysroot(), "/mnt/sysimage")
예제 #9
0
    def _write_module_blacklist(self):
        """Copy modules from modprobe.blacklist=<module> on cmdline to
        /etc/modprobe.d/anaconda-blacklist.conf so that modules will
        continue to be blacklisted when the system boots.
        """
        if "modprobe.blacklist" not in flags.cmdline:
            return

        util.mkdirChain(util.getSysroot() + "/etc/modprobe.d")
        with open(util.getSysroot() + "/etc/modprobe.d/anaconda-blacklist.conf", "w") as f:
            f.write("# Module blacklists written by anaconda\n")
            for module in flags.cmdline["modprobe.blacklist"].split():
                f.write("blacklist %s\n" % module)
예제 #10
0
    def write(self):
        """Write the desktop & default target settings to disk."""
        if self.desktop:
            with open(util.getSysroot() + "/etc/sysconfig/desktop", "w") as f:
                f.write("DESKTOP=%s\n" % self.desktop)

        if not os.path.isdir(util.getSysroot() + '/etc/systemd/system'):
            log.warning("There is no /etc/systemd/system directory, cannot update default.target!")
            return

        default_target = util.getSysroot() + '/etc/systemd/system/default.target'
        if os.path.islink(default_target):
            os.unlink(default_target)
        os.symlink('/lib/systemd/system/%s' % self.default_target, default_target)
예제 #11
0
    def post_install(self):
        super().post_install()

        gi.require_version("OSTree", "1.0")
        from gi.repository import OSTree
        cancellable = None

        # Following up on the "remote delete" above, we removed the
        # remote from /ostree/repo/config.  But we want it in /etc, so
        # re-add it to /etc/ostree/remotes.d, using the sysroot path.
        #
        # However, we ignore the case where the remote already exists,
        # which occurs when the content itself provides the remote
        # config file.

        # Note here we use the deployment as sysroot, because it's
        # that version of /etc that we want.
        sysroot_file = Gio.File.new_for_path(util.getSysroot())
        sysroot = OSTree.Sysroot.new(sysroot_file)
        sysroot.load(cancellable)
        repo = sysroot.get_repo(None)[1]
        repo.remote_change(sysroot_file,
                           OSTree.RepoRemoteChange.ADD_IF_NOT_EXISTS,
                           self.data.ostreesetup.remote, self.data.ostreesetup.url,
                           Variant('a{sv}', self._remoteOptions),
                           cancellable)

        boot = util.getSysroot() + '/boot'

        # If we're using GRUB2, move its config file, also with a
        # compatibility symlink.
        boot_grub2_cfg = boot + '/grub2/grub.cfg'
        if os.path.isfile(boot_grub2_cfg):
            boot_loader = boot + '/loader'
            target_grub_cfg = boot_loader + '/grub.cfg'
            log.info("Moving %s -> %s", boot_grub2_cfg, target_grub_cfg)
            os.rename(boot_grub2_cfg, target_grub_cfg)
            os.symlink('../loader/grub.cfg', boot_grub2_cfg)

        # Skip kernel args setup for dirinstall, there is no bootloader or rootDevice setup.
        if not conf.target.is_directory:
            # OSTree owns the bootloader configuration, so here we give it
            # the argument list we computed from storage, architecture and
            # such.
            set_kargs_args = ["admin", "instutil", "set-kargs"]
            set_kargs_args.extend(self.storage.bootloader.boot_args)
            set_kargs_args.append("root=" + self.storage.root_device.fstab_spec)
            self._safe_exec_with_redirect("ostree", set_kargs_args, root=util.getSysroot())
예제 #12
0
    def write_out_config_file(self, config_path=None):
        """Write the user interaction config file to persistent storage.
        - we always read the config file from the top level filesystem, as:
        -> on live media the file will be there
        -> on non-live media the config file (if any) will be injected to the top level
        -> filesystem by image generation tools or by an updates/product image

        - on the other hand the "output" config file needs to always end on the installed
          system, so that post installation setup tools (such as Initial Setup or
          Gnome Initial Setup) can use it
        -> therefore we always write the config file to the sysroot path
        """

        if config_path is None:
            config_path = util.getSysroot() + CONFIG_FILE_PATH

        with self._lock:
            new_config_file = not os.path.exists(config_path)
            try:
                with open(config_path, "wt") as f:
                    if new_config_file:
                        # we are creating a new file, so add a header that it was created by Anaconda,
                        # including its version number
                        f.write(self._get_new_config_header())
                    self._config.write(f)
            except OSError:
                log.exception("Can't write user interaction config file.")
예제 #13
0
def write_storage_configuration(storage, sysroot=None):
    """Write the storage configuration to sysroot.

    :param storage: the storage object
    :param sysroot: a path to the target OS installation
    """
    if sysroot is None:
        sysroot = util.getSysroot()

    if not os.path.isdir("%s/etc" % sysroot):
        os.mkdir("%s/etc" % sysroot)

    _write_escrow_packets(storage, sysroot)

    storage.make_mtab()
    storage.fsset.write()
    iscsi.write(sysroot, storage)

    fcoe_proxy = STORAGE.get_proxy(FCOE)
    fcoe_proxy.WriteConfiguration(sysroot)

    if arch.is_s390():
        zfcp_proxy = STORAGE.get_proxy(ZFCP)
        zfcp_proxy.WriteConfiguration(sysroot)

    _write_dasd_conf(storage, sysroot)
예제 #14
0
파일: space.py 프로젝트: zhangsju/anaconda
    def check(self):
        """Check configured storage against software selections.  When this
           method is complete (which should be pretty quickly), the following
           attributes are available for inspection:

           success       -- A simple boolean defining whether there's enough
                            space or not.
           deficit       -- If unsuccessful, how much space the system is
                            short for current software selections.
           error_message -- If unsuccessful, an error message describing the
                            situation.  This message is suitable for putting
                            in the info bar at the bottom of a Hub.
        """
        self.reset()
        stat = os.statvfs(util.getSysroot())
        free = Size(stat.f_bsize * stat.f_bfree)
        needed = self.payload.spaceRequired
        log.info("fs space: %s  needed: %s", free, needed)
        self.success = (free > needed)
        if not self.success:
            dev_required_size = self.payload.requiredDeviceSize(self.storage.root_device.format)
            self.deficit = dev_required_size - self.storage.root_device.size
            self.error_message = _(self.error_template) % self.deficit

        return self.success
예제 #15
0
파일: users.py 프로젝트: rvykydal/anaconda
    def setUserSshKey(self, username, key, **kwargs):
        root = kwargs.get("root", util.getSysroot())

        pwent = self._getpwnam(username, root)
        if not pwent:
            raise ValueError("setUserSshKey: user %s does not exist" % username)

        homedir = root + pwent[5]
        if not os.path.exists(homedir):
            log.error("setUserSshKey: home directory for %s does not exist", username)
            raise ValueError("setUserSshKey: home directory for %s does not exist" % username)

        uid = pwent[2]
        gid = pwent[3]

        sshdir = os.path.join(homedir, ".ssh")
        if not os.path.isdir(sshdir):
            os.mkdir(sshdir, 0o700)
            os.chown(sshdir, int(uid), int(gid))

        authfile = os.path.join(sshdir, "authorized_keys")
        authfile_existed = os.path.exists(authfile)
        with util.open_with_perm(authfile, "a", 0o600) as f:
            f.write(key + "\n")

        # Only change ownership if we created it
        if not authfile_existed:
            os.chown(authfile, int(uid), int(gid))
            util.execWithRedirect("restorecon", ["-r", sshdir])
예제 #16
0
파일: root.py 프로젝트: rvykydal/anaconda
def get_release_string():
    """Identify the installation of a Linux distribution.

    Attempt to identify the installation of a Linux distribution by checking
    a previously mounted filesystem for several files.  The filesystem must
    be mounted under the target physical root.

    :returns: The machine's arch, distribution name, and distribution version
    or None for any parts that cannot be determined
    :rtype: (string, string, string)
    """
    rel_name = None
    rel_ver = None
    sysroot = util.getSysroot()

    try:
        rel_arch = blivet_util.capture_output(["arch"], root=sysroot).strip()
    except OSError:
        rel_arch = None

    filename = "%s/etc/redhat-release" % sysroot
    if os.access(filename, os.R_OK):
        (rel_name, rel_ver) = _release_from_redhat_release(filename)
    else:
        filename = "%s/etc/os-release" % sysroot
        if os.access(filename, os.R_OK):
            (rel_name, rel_ver) = _release_from_os_release(filename)

    return rel_arch, rel_name, rel_ver
예제 #17
0
    def _collect_installation_tasks(self):
        """Collect installation tasks from modules.

        :return: a list of tasks proxies
        """
        tasks = []

        # FIXME: We need to figure out how to handle the sysroot.
        sysroot = util.getSysroot()

        if not self._module_observers:
            log.error("Starting installation without available modules.")

        for observer in self._module_observers:
            # FIXME: This check is here for testing purposes only.
            # Normally, all given modules should be available once
            # we start the installation.
            if not observer.is_service_available:
                log.error("Module %s is not available!", observer.service_name)
                continue

            service_name = observer.service_name
            task_paths = observer.proxy.InstallWithTasks(sysroot)

            for object_path in task_paths:
                log.debug("Getting task %s from module %s", object_path, service_name)
                task_proxy = DBus.get_proxy(service_name, object_path)
                tasks.append(task_proxy)

        return tasks
예제 #18
0
 def write_config_post(self):
     etc_extlinux = os.path.normpath(util.getSysroot() + "/etc/" + self._config_file)
     if not os.access(etc_extlinux, os.R_OK):
         try:
             os.symlink("../boot/%s" % self._config_file, etc_extlinux)
         except OSError as e:
             log.warning("failed to create /etc/extlinux.conf symlink: %s", e)
예제 #19
0
파일: fsset.py 프로젝트: rvykydal/anaconda
 def mk_dev_root(self):
     root = self.root_device
     sysroot = util.getSysroot()
     dev = "%s/%s" % (sysroot, root.path)
     if not os.path.exists("%s/dev/root" % (sysroot,)) and os.path.exists(dev):
         rdev = os.stat(dev).st_rdev
         os.mknod("%s/dev/root" % (sysroot,), stat.S_IFBLK | 0o600, rdev)
예제 #20
0
파일: fsset.py 프로젝트: rvykydal/anaconda
    def write(self):
        """Write out all config files based on the set of filesystems."""
        sysroot = util.getSysroot()
        # /etc/fstab
        fstab_path = os.path.normpath("%s/etc/fstab" % sysroot)
        fstab = self.fstab()
        open(fstab_path, "w").write(fstab)

        # /etc/crypttab
        crypttab_path = os.path.normpath("%s/etc/crypttab" % sysroot)
        crypttab = self.crypttab()
        origmask = os.umask(0o077)
        open(crypttab_path, "w").write(crypttab)
        os.umask(origmask)

        # /etc/mdadm.conf
        mdadm_path = os.path.normpath("%s/etc/mdadm.conf" % sysroot)
        mdadm_conf = self.mdadm_conf()
        if mdadm_conf:
            open(mdadm_path, "w").write(mdadm_conf)

        # /etc/multipath.conf
        if any(d for d in self.devices if d.type == "dm-multipath"):
            copy_to_system("/etc/multipath.conf")
            copy_to_system("/etc/multipath/wwids")
            copy_to_system("/etc/multipath/bindings")
        else:
            log.info("not writing out mpath configuration")
예제 #21
0
파일: users.py 프로젝트: rvykydal/anaconda
    def createGroup(self, group_name, **kwargs):
        """Create a new user on the system with the given name.  Optional kwargs:

           :keyword int gid: The GID for the new user. If none is given, the next available one is used.
           :keyword str root: The directory of the system to create the new user in.
                          homedir will be interpreted relative to this. Defaults
                          to util.getSysroot().
        """
        root = kwargs.get("root", util.getSysroot())

        if self._getgrnam(group_name, root):
            raise ValueError("Group %s already exists" % group_name)

        args = ["-R", root]
        if kwargs.get("gid") is not None:
            args.extend(["-g", str(kwargs["gid"])])

        args.append(group_name)
        with self._ensureLoginDefs(root):
            status = util.execWithRedirect("groupadd", args)

        if status == 4:
            raise ValueError("GID %s already exists" % kwargs.get("gid"))
        elif status == 9:
            raise ValueError("Group %s already exists" % group_name)
        elif status != 0:
            raise OSError("Unable to create group %s: status=%s" % (group_name, status))
예제 #22
0
파일: grub2.py 프로젝트: rvykydal/anaconda
    def write_device_map(self):
        """Write out a device map containing all supported devices."""
        map_path = os.path.normpath(util.getSysroot() + self.device_map_file)
        if os.access(map_path, os.R_OK):
            os.rename(map_path, map_path + ".anacbak")

        devices = self.disks
        if self.stage1_device not in devices:
            devices.append(self.stage1_device)

        for disk in self.stage2_device.disks:
            if disk not in devices:
                devices.append(disk)

        devices = [d for d in devices if d.is_disk]

        if len(devices) == 0:
            return

        dev_map = open(map_path, "w")
        dev_map.write("# this device map was generated by anaconda\n")
        for drive in devices:
            dev_map.write("%s      %s\n" % (self.grub_device_name(drive),
                                            drive.path))
        dev_map.close()
예제 #23
0
파일: root.py 프로젝트: rvykydal/anaconda
def _find_existing_installations(devicetree):
    """Find existing GNU/Linux installations on devices from the device tree.

    :param devicetree: a device tree to find existing installations in
    :return: roots of all found installations
    """
    if not os.path.exists(util.getTargetPhysicalRoot()):
        blivet_util.makedirs(util.getTargetPhysicalRoot())

    sysroot = util.getSysroot()
    roots = []
    direct_devices = (dev for dev in devicetree.devices if dev.direct)
    for device in direct_devices:
        if not device.format.linux_native or not device.format.mountable or \
           not device.controllable:
            continue

        try:
            device.setup()
        except Exception:  # pylint: disable=broad-except
            log_exception_info(log.warning, "setup of %s failed", [device.name])
            continue

        options = device.format.options + ",ro"
        try:
            device.format.mount(options=options, mountpoint=sysroot)
        except Exception:  # pylint: disable=broad-except
            log_exception_info(log.warning, "mount of %s as %s failed", [device.name, device.format.type])
            blivet_util.umount(mountpoint=sysroot)
            continue

        if not os.access(sysroot + "/etc/fstab", os.R_OK):
            blivet_util.umount(mountpoint=sysroot)
            device.teardown()
            continue

        try:
            (architecture, product, version) = get_release_string()
        except ValueError:
            name = _("Linux on %s") % device.name
        else:
            # I'd like to make this finer grained, but it'd be very difficult
            # to translate.
            if not product or not version or not architecture:
                name = _("Unknown Linux")
            elif "linux" in product.lower():
                name = _("%(product)s %(version)s for %(arch)s") % \
                    {"product": product, "version": version, "arch": architecture}
            else:
                name = _("%(product)s Linux %(version)s for %(arch)s") % \
                    {"product": product, "version": version, "arch": architecture}

        (mounts, swaps) = _parse_fstab(devicetree, chroot=sysroot)
        blivet_util.umount(mountpoint=sysroot)
        if not mounts and not swaps:
            # empty /etc/fstab. weird, but I've seen it happen.
            continue
        roots.append(Root(mounts=mounts, swaps=swaps, name=name))

    return roots
예제 #24
0
    def execute(self, storage, ksdata, users, payload):
        """
        The execute method that should make changes to the installed system. It
        is called only once in the post-install setup phase.

        :see: setup
        :param users: information about created users
        :type users: pyanaconda.users.Users instance

        """

        if self.dry_run or not self.profile_id:
            # nothing more to be done in the dry-run mode or if no profile is
            # selected
            return

        target_content_dir = utils.join_paths(getSysroot(),
                                              common.TARGET_CONTENT_DIR)
        utils.ensure_dir_exists(target_content_dir)

        if self.content_type == "datastream":
            shutil.copy2(self.preinst_content_path, target_content_dir)
        elif self.content_type == "rpm":
            # copy the RPM to the target system
            shutil.copy2(self.raw_preinst_content_path, target_content_dir)

            # and install it with yum
            ret = util.execInSysroot("yum", ["-y", "--nogpg", "install",
                                             self.raw_postinst_content_path])
            if ret != 0:
                raise common.ExtractionError("Failed to install content "
                                             "RPM to the target system")
        elif self.content_type == "scap-security-guide":
            # nothing needed
            pass
        else:
            utils.universal_copy(utils.join_paths(common.INSTALLATION_CONTENT_DIR,
                                                  "*"),
                                 target_content_dir)
        if os.path.exists(self.preinst_tailoring_path):
            shutil.copy2(self.preinst_tailoring_path, target_content_dir)

        common.run_oscap_remediate(self.profile_id, self.postinst_content_path,
                                   self.datastream_id, self.xccdf_id,
                                   self.postinst_tailoring_path,
                                   chroot=getSysroot())
예제 #25
0
    def run_task(self):
        """Resolve the sysroot path only right before doing the copy operatio.

        If we just added the sysroot path as an argument, it would be resolved when the
        task queue was created, not when the task is actually executed, which could
        theoretically result in an incorrect path.
        """
        network.copyFileToPath("/etc/resolv.conf", util.getSysroot())
예제 #26
0
 def execute(self, storage, ksdata, users):
     for grp in self.groupList:
         kwargs = grp.__dict__
         kwargs.update({"root": util.getSysroot()})
         try:
             users.createGroup(grp.name, **kwargs)
         except ValueError as e:
             group_log.warning(str(e))
예제 #27
0
    def execute(self, storage, ksdata, users, payload):
        # the KdumpSpoke should run only if requested
        if not flags.cmdline.getbool("kdump_addon", default=False) or not self.enabled:
            return

        action = "enable"

        util.execWithRedirect("systemctl", [action, "kdump.service"], root=util.getSysroot())
예제 #28
0
    def _copy_bootloader_data(self):
        # Copy bootloader data files from the deployment
        # checkout to the target root.  See
        # https://bugzilla.gnome.org/show_bug.cgi?id=726757 This
        # happens once, at installation time.
        # extlinux ships its modules directly in the RPM in /boot.
        # For GRUB2, Anaconda installs device.map there.  We may need
        # to add other bootloaders here though (if they can't easily
        # be fixed to *copy* data into /boot at install time, instead
        # of shipping it in the RPM).
        is_efi = isinstance(self.storage.bootloader, EFIBase)
        physboot = util.getTargetPhysicalRoot() + '/boot'
        ostree_boot_source = util.getSysroot() + '/usr/lib/ostree-boot'
        if not os.path.isdir(ostree_boot_source):
            ostree_boot_source = util.getSysroot() + '/boot'
        for fname in os.listdir(ostree_boot_source):
            srcpath = os.path.join(ostree_boot_source, fname)
            destpath = os.path.join(physboot, fname)

            # We're only copying directories
            if not os.path.isdir(srcpath):
                continue

            # Special handling for EFI; first, we only want to copy
            # the data if the system is actually EFI (simulating grub2-efi
            # being installed).  Second, as it's a mount point that's
            # expected to already exist (so if we used copytree, we'd
            # traceback).  If it doesn't, we're not on a UEFI system,
            # so we don't want to copy the data.
            if fname == 'efi':
                if is_efi:
                    for subname in os.listdir(srcpath):
                        sub_srcpath = os.path.join(srcpath, subname)
                        sub_destpath = os.path.join(destpath, subname)
                        self._safe_exec_with_redirect('cp',
                                                      ['-r', '-p', sub_srcpath, sub_destpath])
            else:
                log.info("Copying bootloader data: %s", fname)
                self._safe_exec_with_redirect('cp', ['-r', '-p', srcpath, destpath])

            # Unfortunate hack, see https://github.com/rhinstaller/anaconda/issues/1188
            efi_grubenv_link = physboot + '/grub2/grubenv'
            if not is_efi and os.path.islink(efi_grubenv_link):
                os.unlink(efi_grubenv_link)
예제 #29
0
    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)])
예제 #30
0
def runPostScripts(scripts):
    postScripts = [s for s in scripts if s.type == KS_SCRIPT_POST]

    if len(postScripts) == 0:
        return

    script_log.info("Running kickstart %%post script(s)")
    for script in postScripts:
        script.run(util.getSysroot())
    script_log.info("All kickstart %%post script(s) have been run")
예제 #31
0
def _find_existing_installations(devicetree):
    """Find existing GNU/Linux installations on devices from the device tree.

    :param devicetree: a device tree to find existing installations in
    :return: roots of all found installations
    """
    if not os.path.exists(util.getTargetPhysicalRoot()):
        blivet_util.makedirs(util.getTargetPhysicalRoot())

    sysroot = util.getSysroot()
    roots = []
    direct_devices = (dev for dev in devicetree.devices if dev.direct)
    for device in direct_devices:
        if not device.format.linux_native or not device.format.mountable or \
           not device.controllable:
            continue

        try:
            device.setup()
        except Exception:  # pylint: disable=broad-except
            log_exception_info(log.warning, "setup of %s failed",
                               [device.name])
            continue

        options = device.format.options + ",ro"
        try:
            device.format.mount(options=options, mountpoint=sysroot)
        except Exception:  # pylint: disable=broad-except
            log_exception_info(log.warning, "mount of %s as %s failed",
                               [device.name, device.format.type])
            blivet_util.umount(mountpoint=sysroot)
            continue

        if not os.access(sysroot + "/etc/fstab", os.R_OK):
            blivet_util.umount(mountpoint=sysroot)
            device.teardown()
            continue

        try:
            (architecture, product, version) = get_release_string()
        except ValueError:
            name = _("Linux on %s") % device.name
        else:
            # I'd like to make this finer grained, but it'd be very difficult
            # to translate.
            if not product or not version or not architecture:
                name = _("Unknown Linux")
            elif "linux" in product.lower():
                name = _("%(product)s %(version)s for %(arch)s") % \
                    {"product": product, "version": version, "arch": architecture}
            else:
                name = _("%(product)s Linux %(version)s for %(arch)s") % \
                    {"product": product, "version": version, "arch": architecture}

        (mounts, swaps) = _parse_fstab(devicetree, chroot=sysroot)
        blivet_util.umount(mountpoint=sysroot)
        if not mounts and not swaps:
            # empty /etc/fstab. weird, but I've seen it happen.
            continue
        roots.append(Root(mounts=mounts, swaps=swaps, name=name))

    return roots
예제 #32
0
 def mactel_config(self):
     if os.path.exists(util.getSysroot() +
                       "/usr/libexec/mactel-boot-setup"):
         rc = util.execInSysroot("/usr/libexec/mactel-boot-setup", [])
         if rc:
             log.error("failed to configure Mac boot loader")
예제 #33
0
 def _calculate_free_space(self):
     """Calculate the available space."""
     stat = os.statvfs(util.getSysroot())
     return Size(stat.f_bsize * stat.f_bfree)
예제 #34
0
    def pre_install(self):
        """Perform pre-installation tasks."""
        util.mkdirChain(util.getSysroot() + "/root")

        self._write_module_blacklist()
예제 #35
0
 def fingerprint_supported(self):
     return (os.path.exists(util.getSysroot() + "/lib64/security/pam_fprintd.so") or
             os.path.exists(util.getSysroot() + "/lib/security/pam_fprintd.so"))
예제 #36
0
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self._min_size = 0
     self._proxies = {}
     self.image_path = util.getSysroot() + "/disk.img"
예제 #37
0
 def mount_filesystems(self, read_only=None, skip_root=False):
     self.fsset.mount_filesystems(root_path=util.getSysroot(),
                                  read_only=read_only,
                                  skip_root=skip_root)
예제 #38
0
 def execute(self):
     localization_proxy = LOCALIZATION.get_proxy()
     task_path = localization_proxy.InstallLanguageWithTask(
         util.getSysroot())
     task_proxy = LOCALIZATION.get_proxy(task_path)
     sync_run_task(task_proxy)
예제 #39
0
    def prepareMountTargets(self, storage):
        """ Prepare the ostree root """
        ostreesetup = self.data.ostreesetup

        # Currently, blivet sets up mounts in the physical root.
        # We used to unmount them and remount them in the sysroot, but
        # since 664ef7b43f9102aa9332d0db5b7d13f8ece436f0 we now just set up
        # bind mounts.

        # Make /usr readonly like ostree does at runtime normally
        self._setupInternalBindmount('/usr', bind_ro=True, src_physical=False)

        # Explicitly do API mounts; some of these may be tracked by blivet, but
        # we'll skip them below.
        api_mounts = ["/dev", "/proc", "/run", "/sys"]
        for path in api_mounts:
            self._setupInternalBindmount(path)

        # Handle /var; if the admin didn't specify a mount for /var, we need
        # to do the default ostree one.
        # https://github.com/ostreedev/ostree/issues/855
        varroot = '/ostree/deploy/' + ostreesetup.osname + '/var'
        if storage.mountpoints.get("/var") is None:
            self._setupInternalBindmount(varroot, dest='/var', recurse=False)
        else:
            # Otherwise, bind it
            self._setupInternalBindmount('/var', recurse=False)

        # Now that we have /var, start filling in any directories that may be
        # required later there. We explicitly make /var/lib, since
        # systemd-tmpfiles doesn't have a --prefix-only=/var/lib. We rely on
        # 80-setfilecons.ks to set the label correctly.
        util.mkdirChain(util.getSysroot() + '/var/lib')
        # Next, run tmpfiles to make subdirectories of /var. We need this for
        # both mounts like /home (really /var/home) and %post scripts might
        # want to write to e.g. `/srv`, `/root`, `/usr/local`, etc. The
        # /var/lib/rpm symlink is also critical for having e.g. `rpm -qa` work
        # in %post. We don't iterate *all* tmpfiles because we don't have the
        # matching NSS configuration inside Anaconda, and we can't "chroot" to
        # get it because that would require mounting the API filesystems in the
        # target.
        for varsubdir in ('home', 'roothome', 'lib/rpm', 'opt', 'srv',
                          'usrlocal', 'mnt', 'media', 'spool', 'spool/mail'):
            self._safeExecWithRedirect("systemd-tmpfiles", [
                "--create", "--boot", "--root=" + util.getSysroot(),
                "--prefix=/var/" + varsubdir
            ])

        # Handle mounts like /boot (except avoid /boot/efi; we just need the
        # toplevel), and any admin-specified points like /home (really
        # /var/home). Note we already handled /var above. Avoid recursion since
        # sub-mounts will be in the list too.  We sort by length as a crude
        # hack to try to simulate the tree relationship; it looks like this
        # is handled in blivet in a different way.
        for mount in sorted(storage.mountpoints, key=len):
            if mount in ('/', '/var') or mount in api_mounts:
                continue
            self._setupInternalBindmount(mount, recurse=False)

        # And finally, do a nonrecursive bind for the sysroot
        self._setupInternalBindmount("/", dest="/sysroot", recurse=False)
예제 #40
0
    def createUser(self, user_name, *args, **kwargs):
        """Create a new user on the system with the given name.  Optional kwargs:

           :keyword str algo: The password algorithm to use in case isCrypted=True.
                              If none is given, the cryptPassword default is used.
           :keyword str gecos: The GECOS information (full name, office, phone, etc.).
                               Defaults to "".
           :keyword groups: A list of group names the user should be added to.
                            Each group name can contain an optional GID in parenthesis,
                            such as "groupName(5000)". Defaults to [].
           :type groups: list of str
           :keyword str homedir: The home directory for the new user.  Defaults to
                                 /home/<name>.
           :keyword bool isCrypted: Is the password kwargs already encrypted?  Defaults
                                    to False.
           :keyword bool lock: Is the new account locked by default?  Defaults to
                               False.
           :keyword str password: The password.  See isCrypted for how this is interpreted.
                                  If the password is "" then the account is created
                                  with a blank password. If None or False the account will
                                  be left in its initial state (locked)
           :keyword str root: The directory of the system to create the new user
                              in.  homedir will be interpreted relative to this.
                              Defaults to util.getSysroot().
           :keyword str shell: The shell for the new user.  If none is given, the
                               login.defs default is used.
           :keyword int uid: The UID for the new user.  If none is given, the next
                             available one is used.
           :keyword int gid: The GID for the new user.  If none is given, the next
                             available one is used.
        """

        root = kwargs.get("root", util.getSysroot())

        if self.checkUserExists(user_name, root):
            raise ValueError("User %s already exists" % user_name)

        args = ["-R", root]

        # Split the groups argument into a list of (username, gid or None) tuples
        # the gid, if any, is a string since that makes things simpler
        group_gids = [
            GROUPLIST_FANCY_PARSE.match(group).groups()
            for group in kwargs.get("groups", [])
        ]

        # If a specific gid is requested:
        #   - check if a group already exists with that GID. i.e., the user's
        #     GID should refer to a system group, such as users. If so, just set
        #     the GID.
        #   - check if a new group is requested with that GID. If so, set the GID
        #     and let the block below create the actual group.
        #   - if neither of those are true, create a new user group with the requested
        #     GID
        # otherwise use -U to create a new user group with the next available GID.
        if kwargs.get("gid", None):
            if not self._getgrgid(kwargs['gid'], root) and \
                    not any(gid[1] == str(kwargs['gid']) for gid in group_gids):
                self.createGroup(user_name, gid=kwargs['gid'], root=root)

            args.extend(['-g', str(kwargs['gid'])])
        else:
            args.append('-U')

        # If any requested groups do not exist, create them.
        group_list = []
        for group_name, gid in group_gids:
            existing_group = self._getgrnam(group_name, root)

            # Check for a bad GID request
            if gid and existing_group and gid != existing_group[2]:
                raise ValueError("Group %s already exists with GID %s" %
                                 (group_name, gid))

            # Otherwise, create the group if it does not already exist
            if not existing_group:
                self.createGroup(group_name, gid=gid, root=root)
            group_list.append(group_name)

        if group_list:
            args.extend(['-G', ",".join(group_list)])

        if kwargs.get("homedir"):
            homedir = kwargs["homedir"]
        else:
            homedir = "/home/" + user_name

        # useradd expects the parent directory tree to exist.
        parent_dir = util.parent_dir(root + homedir)

        # If root + homedir came out to "/", such as if we're creating the sshpw user,
        # parent_dir will be empty. Don't create that.
        if parent_dir:
            util.mkdirChain(parent_dir)

        args.extend(["-d", homedir])

        # Check whether the directory exists or if useradd should create it
        mk_homedir = not os.path.exists(root + homedir)
        if mk_homedir:
            args.append("-m")
        else:
            args.append("-M")

        if kwargs.get("shell"):
            args.extend(["-s", kwargs["shell"]])

        if kwargs.get("uid"):
            args.extend(["-u", str(kwargs["uid"])])

        if kwargs.get("gecos"):
            args.extend(["-c", kwargs["gecos"]])

        args.append(user_name)
        with self._ensureLoginDefs(root):
            status = util.execWithRedirect("useradd", args)

        if status == 4:
            raise ValueError("UID %s already exists" % kwargs.get("uid"))
        elif status == 6:
            raise ValueError("Invalid groups %s" % kwargs.get("groups", []))
        elif status == 9:
            raise ValueError("User %s already exists" % user_name)
        elif status != 0:
            raise OSError("Unable to create user %s: status=%s" %
                          (user_name, status))

        if not mk_homedir:
            try:
                stats = os.stat(root + homedir)
                orig_uid = stats.st_uid
                orig_gid = stats.st_gid

                # Gett the UID and GID of the created user
                pwent = self._getpwnam(user_name, root)

                log.info(
                    "Home directory for the user %s already existed, "
                    "fixing the owner and SELinux context.", user_name)
                # home directory already existed, change owner of it properly
                util.chown_dir_tree(root + homedir, int(pwent[2]),
                                    int(pwent[3]), orig_uid, orig_gid)
                util.execWithRedirect("restorecon", ["-r", root + homedir])
            except OSError as e:
                log.critical(
                    "Unable to change owner of existing home directory: %s",
                    e.strerror)
                raise

        pw = kwargs.get("password", False)
        crypted = kwargs.get("isCrypted", False)
        algo = kwargs.get("algo", None)
        lock = kwargs.get("lock", False)

        self.setUserPassword(user_name, pw, crypted, lock, algo, root)
예제 #41
0
def _parse_fstab(devicetree, chroot=None):
    """Parse /etc/fstab.

    :param devicetree: a device tree
    :param chroot: a path to the target OS installation
    :return: a tuple of a mount dict and swap list
    """
    if not chroot or not os.path.isdir(chroot):
        chroot = util.getSysroot()

    mounts = {}
    swaps = []
    path = "%s/etc/fstab" % chroot
    if not os.access(path, os.R_OK):
        # XXX should we raise an exception instead?
        log.info("cannot open %s for read", path)
        return mounts, swaps

    blkid_tab = BlkidTab(chroot=chroot)
    try:
        blkid_tab.parse()
        log.debug("blkid.tab devs: %s", list(blkid_tab.devices.keys()))
    except Exception:  # pylint: disable=broad-except
        log_exception_info(log.info, "error parsing blkid.tab")
        blkid_tab = None

    crypt_tab = CryptTab(devicetree, blkid_tab=blkid_tab, chroot=chroot)
    try:
        crypt_tab.parse(chroot=chroot)
        log.debug("crypttab maps: %s", list(crypt_tab.mappings.keys()))
    except Exception:  # pylint: disable=broad-except
        log_exception_info(log.info, "error parsing crypttab")
        crypt_tab = None

    with open(path) as f:
        log.debug("parsing %s", path)
        for line in f.readlines():

            (line, _pound, _comment) = line.partition("#")
            fields = line.split(None, 4)

            if len(fields) < 5:
                continue

            (devspec, mountpoint, fstype, options, _rest) = fields

            # find device in the tree
            device = devicetree.resolve_device(devspec,
                                               crypt_tab=crypt_tab,
                                               blkid_tab=blkid_tab,
                                               options=options)

            if device is None:
                continue

            if fstype != "swap":
                mounts[mountpoint] = device
            else:
                swaps.append(device)

    return mounts, swaps
예제 #42
0
 def install(self):
     try:
         self.archive.extractall(path=util.getSysroot())
     except (tarfile.ExtractError, tarfile.CompressionError) as e:
         log.error("extracting tar archive %s: %s", self.image_file, e)
예제 #43
0
def initExceptionHandling(anaconda):
    file_list = [
        "/tmp/anaconda.log", "/tmp/packaging.log", "/tmp/program.log",
        "/tmp/storage.log", "/tmp/ifcfg.log", "/tmp/dnf.librepo.log",
        "/tmp/hawkey.log", "/tmp/lvm.log",
        util.getSysroot() + "/root/install.log", "/proc/cmdline",
        "/root/lorax-packages.log", "/tmp/blivet-gui-utils.log",
        "/tmp/dbus.log"
    ]

    if os.path.exists("/tmp/syslog"):
        file_list.extend(["/tmp/syslog"])

    if anaconda.opts and anaconda.opts.ksfile:
        file_list.extend([anaconda.opts.ksfile])

    config = Config(
        programName="anaconda",
        programVersion=startup_utils.get_anaconda_version_string(),
        programArch=os.uname()[4],
        attrSkipList=[
            "_intf._actions", "_intf._currentAction._xklwrapper",
            "_intf._currentAction._spokes[\"KeyboardSpoke\"]._xkl_wrapper",
            "_intf._currentAction._storage_playground",
            "_intf._currentAction._spokes[\"CustomPartitioningSpoke\"]._storage_playground",
            "_intf._currentAction.language.translations",
            "_intf._currentAction.language.locales",
            "_intf._currentAction._spokes[\"PasswordSpoke\"]._oldweak",
            "_intf._currentAction._spokes[\"PasswordSpoke\"]._password",
            "_intf._currentAction._spokes[\"UserSpoke\"]._password",
            "_intf._currentAction._spokes[\"UserSpoke\"]._oldweak",
            "_intf.storage.bootloader.password", "_intf.storage.data",
            "_intf.storage.ksdata", "_intf.storage.encryption_passphrase",
            "_intf.data", "_bootloader.encrypted_password",
            "_bootloader.password", "payload._groups"
        ],
        localSkipList=[
            "passphrase", "password", "_oldweak", "_password", "try_passphrase"
        ],
        fileList=file_list)

    config.register_callback("lsblk_output",
                             lsblk_callback,
                             attchmnt_only=False)
    config.register_callback("nmcli_dev_list",
                             nmcli_dev_list_callback,
                             attchmnt_only=True)

    # provide extra information for libreport
    config.register_callback("type", lambda: "anaconda", attchmnt_only=True)
    config.register_callback("addons",
                             list_addons_callback,
                             attchmnt_only=False)

    if "/tmp/syslog" not in file_list:
        # no syslog, grab output from journalctl and put it also to the
        # anaconda-tb file
        config.register_callback("journalctl",
                                 journalctl_callback,
                                 attchmnt_only=False)

    if not product.isFinal:
        config.register_callback("release_type",
                                 lambda: "pre-release",
                                 attchmnt_only=True)

    handler = AnacondaExceptionHandler(config, anaconda.intf.meh_interface,
                                       AnacondaReverseExceptionDump,
                                       anaconda.intf.tty_num,
                                       anaconda.gui_initialized,
                                       anaconda.interactive_mode)
    handler.install(anaconda)

    return config
예제 #44
0
 def execute(self):
     localization_proxy = LOCALIZATION.get_proxy()
     keyboard.write_keyboard_config(localization_proxy, util.getSysroot())
예제 #45
0
 def turn_on_swap(self):
     self.fsset.turn_on_swap(root_path=util.getSysroot())
예제 #46
0
def doConfiguration(storage, payload, ksdata):
    """Configure the installed system."""

    configuration_queue = TaskQueue("Configuration queue")
    # connect progress reporting
    configuration_queue.queue_started.connect(
        lambda x: progress_message(x.status_message))
    configuration_queue.task_completed.connect(lambda x: progress_step(x.name))

    # schedule the execute methods of ksdata that require an installed system to be present
    os_config = TaskQueue("Installed system configuration",
                          N_("Configuring installed system"))
    os_config.append(Task("Configure authselect", ksdata.authselect.execute))

    security_proxy = SECURITY.get_proxy()
    security_dbus_tasks = security_proxy.InstallWithTasks(util.getSysroot())
    # add one Task instance per DBUS task
    for dbus_task in security_dbus_tasks:
        task_proxy = SECURITY.get_proxy(dbus_task)
        os_config.append(Task(task_proxy.Name, sync_run_task, (task_proxy, )))

    services_proxy = SERVICES.get_proxy()
    services_dbus_tasks = services_proxy.InstallWithTasks(util.getSysroot())
    # add one Task instance per DBUS task
    for dbus_task in services_dbus_tasks:
        task_proxy = SERVICES.get_proxy(dbus_task)
        os_config.append(Task(task_proxy.Name, sync_run_task, (task_proxy, )))

    # The user interaction config file needs to be synchronized with
    # current state of the Services module.
    os_config.append(
        Task("Synchronize user interaction config file state",
             screen_access.sam.update_config_file_state))

    os_config.append(Task("Configure keyboard", ksdata.keyboard.execute))
    os_config.append(Task("Configure timezone", ksdata.timezone.execute))

    localization_proxy = LOCALIZATION.get_proxy()
    localization_dbus_tasks = localization_proxy.InstallWithTasks(
        util.getSysroot())
    # add one Task instance per DBUS task
    for dbus_task in localization_dbus_tasks:
        task_proxy = LOCALIZATION.get_proxy(dbus_task)
        os_config.append(Task(task_proxy.Name, sync_run_task, (task_proxy, )))

    firewall_proxy = NETWORK.get_proxy(FIREWALL)
    firewall_dbus_task = firewall_proxy.InstallWithTask(util.getSysroot())
    task_proxy = NETWORK.get_proxy(firewall_dbus_task)
    os_config.append(Task(task_proxy.Name, sync_run_task, (task_proxy, )))

    os_config.append(Task("Configure X", ksdata.xconfig.execute))
    configuration_queue.append(os_config)

    # schedule network configuration (if required)
    if conf.system.provides_network_config:
        network_config = TaskQueue("Network configuration",
                                   N_("Writing network configuration"))
        network_config.append(
            Task("Network configuration", ksdata.network.execute, (payload, )))
        configuration_queue.append(network_config)

    # creating users and groups requires some pre-configuration.
    user_config = TaskQueue("User creation", N_("Creating users"))

    users_proxy = USERS.get_proxy()
    users_dbus_tasks = users_proxy.InstallWithTasks(util.getSysroot())
    # add one Task instance per DBUS task
    for dbus_task in users_dbus_tasks:
        task_proxy = USERS.get_proxy(dbus_task)
        user_config.append(Task(task_proxy.Name, sync_run_task,
                                (task_proxy, )))
    configuration_queue.append(user_config)

    # Anaconda addon configuration
    addon_config = TaskQueue("Anaconda addon configuration",
                             N_("Configuring addons"))
    # there is no longer a User class & addons should no longer need it
    # FIXME: drop user class parameter from the API & all known addons
    addon_config.append(
        Task("Configure Anaconda addons", ksdata.addons.execute,
             (storage, ksdata, None, payload)))
    configuration_queue.append(addon_config)

    # Initramfs generation
    generate_initramfs = TaskQueue("Initramfs generation",
                                   N_("Generating initramfs"))
    generate_initramfs.append(
        Task("Generate initramfs", payload.recreate_initrds))

    # This works around 2 problems, /boot on BTRFS and BTRFS installations where the initrd is
    # recreated after the first writeBootLoader call. This reruns it after the new initrd has
    # been created, fixing the kernel root and subvol args and adding the missing initrd entry.
    boot_on_btrfs = isinstance(storage.mountpoints.get("/"), BTRFSDevice)

    bootloader_proxy = STORAGE.get_proxy(BOOTLOADER)
    bootloader_enabled = bootloader_proxy.BootloaderMode != BOOTLOADER_DISABLED

    if isinstance(payload,
                  LiveImagePayload) and boot_on_btrfs and bootloader_enabled:
        generate_initramfs.append(
            Task("Write BTRFS bootloader fix", write_boot_loader,
                 (storage, payload)))

    # Invoking zipl should be the last thing done on a s390x installation (see #1652727).
    if arch.is_s390() and not conf.target.is_directory and bootloader_enabled:
        generate_initramfs.append(
            Task("Rerun zipl", lambda: util.execInSysroot("zipl", [])))

    configuration_queue.append(generate_initramfs)

    # join a realm (if required)
    if ksdata.realm.discovered:
        join_realm = TaskQueue(
            "Realm join",
            N_("Joining realm: %s") % ksdata.realm.discovered)
        join_realm.append(Task("Join a realm", ksdata.realm.execute))
        configuration_queue.append(join_realm)

    post_scripts = TaskQueue("Post installation scripts",
                             N_("Running post-installation scripts"))
    post_scripts.append(
        Task("Run post installation scripts", runPostScripts,
             (ksdata.scripts, )))
    configuration_queue.append(post_scripts)

    # setup kexec reboot if requested
    if flags.flags.kexec:
        kexec_setup = TaskQueue("Kexec setup", N_("Setting up kexec"))
        kexec_setup.append(Task("Setup kexec", setup_kexec))
        configuration_queue.append(kexec_setup)

    # write anaconda related configs & kickstarts
    write_configs = TaskQueue("Write configs and kickstarts",
                              N_("Storing configuration files and kickstarts"))

    # Write the kickstart file to the installed system (or, copy the input
    # kickstart file over if one exists).
    if flags.flags.nosave_output_ks:
        # don't write the kickstart file to the installed system if this has
        # been disabled by the nosave option
        log.warning(
            "Writing of the output kickstart to installed system has been disabled"
            " by the nosave option.")
    else:
        # write anaconda related configs & kickstarts
        write_configs.append(Task("Store kickstarts", _writeKS, (ksdata, )))

    # Write out the user interaction config file.
    #
    # But make sure it's not written out in the image and directory installation mode,
    # as that might result in spokes being inadvertently hidden when the actual installation
    # starts from the generate image or directory contents.
    if conf.target.is_image:
        log.info(
            "Not writing out user interaction config file due to image install mode."
        )
    elif conf.target.is_directory:
        log.info(
            "Not writing out user interaction config file due to directory install mode."
        )
    else:
        write_configs.append(
            Task("Store user interaction config",
                 screen_access.sam.write_out_config_file))

    # only add write_configs to the main queue if we actually store some kickstarts/configs
    if write_configs.task_count:
        configuration_queue.append(write_configs)

    # notify progress tracking about the number of steps
    progress_init(configuration_queue.task_count)
    # log contents of the main task queue
    log.info(configuration_queue.summary)

    # log tasks and queues when they are started
    # - note that we are using generators to add the counter
    queue_counter = util.item_counter(configuration_queue.queue_count)
    task_started_counter = util.item_counter(configuration_queue.task_count)
    task_completed_counter = util.item_counter(configuration_queue.task_count)
    configuration_queue.queue_started.connect(lambda x: log.info(
        "Queue started: %s (%s)", x.name, next(queue_counter)))
    configuration_queue.task_started.connect(lambda x: log.info(
        "Task started: %s (%s)", x.name, next(task_started_counter)))
    configuration_queue.task_completed.connect(
        lambda x: log.debug("Task completed: %s (%s) (%1.1f s)", x.name,
                            next(task_completed_counter), x.elapsed_time))
    # start the task queue
    configuration_queue.start()
    # done
    progress_complete()