Esempio n. 1
0
 def _copy_file(self, file_path, target_file_path):
     if not os.path.isfile(file_path):
         return False
     # make sure the output folder exists
     make_directories(os.path.dirname(target_file_path))
     shutil.copy(file_path, target_file_path)
     return True
Esempio n. 2
0
    def _write_interface_rename_config(self, root, ifname_option_values, overwrite):
        """Write systemd configuration .link file for interface renaming.
        :param root: path to the root of the target system
        :type root: str
        :param ifname_option_values: list of ifname boot option values
        :type ifname_option_values: list(str)
        :param overwrite: overwrite existing configuration file
        :type overwrite: bool
        """

        if ifname_option_values:
            target_system_dir = join_paths(root, self.SYSTEMD_NETWORK_CONFIG_DIR)
            make_directories(target_system_dir)

        for ifname_value in ifname_option_values:
            iface, mac = ifname_value.split(":", 1)
            content = self.INTERFACE_RENAME_FILE_CONTENT_TEMPLATE.format(mac, iface)
            config_file = self.INTERFACE_RENAME_FILE_TEMPLATE.format(iface)
            config_file_path = join_paths(self.SYSTEMD_NETWORK_CONFIG_DIR, config_file)
            _write_config_file(
                root,
                config_file_path,
                content,
                "Cannot write {} configuration file for ifname={} option.".format(
                    config_file_path, ifname_value),
                overwrite
            )
Esempio n. 3
0
    def take_screenshot(self, name=None):
        """Take a screenshot of the whole screen (works even with multiple displays).

        :param name: optional name for the screenshot that will be appended to the filename,
                     after the standard prefix & screenshot number
        :type name: str or NoneType
        """
        # Make sure the screenshot directory exists.
        make_directories(constants.SCREENSHOTS_DIRECTORY)

        if name is None:
            screenshot_filename = "screenshot-%04d.png" % self._screenshot_index
        else:
            screenshot_filename = "screenshot-%04d-%s.png" % (
                self._screenshot_index, name)

        fn = os.path.join(constants.SCREENSHOTS_DIRECTORY, screenshot_filename)

        root_window = self.current_window.get_window()
        pixbuf = Gdk.pixbuf_get_from_window(root_window, 0, 0,
                                            root_window.get_width(),
                                            root_window.get_height())
        pixbuf.savev(fn, 'png', [], [])
        log.info("%s taken", screenshot_filename)
        self._screenshot_index += 1
Esempio n. 4
0
    def _copy_pem_files(self, input_folder, output_folder, not_empty=True):
        """Copy all pem files from input_folder to output_folder.

        Files with the pem extension are generally encryption keys and certificates.
        If output_folder does not exist, it & any parts of its path will
        be created.

        :param str input_folder: input folder for the pem files
        :param str output_folder: output folder where to copy the pem files
        :return: False if the input directory does not exists or is empty,
                 True after all pem files have be successfully copied
        :rtype: bool
        """
        # check the input folder exists
        if not os.path.isdir(input_folder):
            return False
        # optionally check the input folder is not empty
        if not_empty and not os.listdir(input_folder):
            return False
        # make sure the output folder exist
        make_directories(output_folder)
        # transfer all the pem files in the input folder
        for pem_file_path in glob.glob(os.path.join(input_folder, "*.pem")):
            shutil.copy(pem_file_path, output_folder)
        # if we got this far the pem copy operation was a success
        return True
Esempio n. 5
0
    def _fill_var_subdirectories(self):
        """Add subdirectories to /var

        Once 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.

        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.
        """
        make_directories(self._sysroot + '/var/lib')
        self._create_tmpfiles('/var/home')
        self._create_tmpfiles('/var/roothome')
        self._create_tmpfiles('/var/lib/rpm')
        self._create_tmpfiles('/var/opt')
        self._create_tmpfiles('/var/srv')
        self._create_tmpfiles('/var/usrlocal')
        self._create_tmpfiles('/var/mnt')
        self._create_tmpfiles('/var/media')
        self._create_tmpfiles('/var/spool')
        self._create_tmpfiles('/var/spool/mail')
Esempio n. 6
0
    def _write_repo_file(self, repo_name, content):
        """Write the specified content into a repo file."""
        repo_dir = join_paths(self._sysroot, "etc/yum.repos.d/")
        make_directories(repo_dir)

        repo_path = join_paths(repo_dir, repo_name + ".repo")
        with open(repo_path, "w") as f:
            f.write(content.strip() + "\n")
    def test_repository_with_metadata(self):
        """Test with one driver disk repository."""
        with tempfile.TemporaryDirectory() as d:
            make_directories(join_paths(d, "DD-1"))
            make_directories(join_paths(d, "DD-1", "repodata"))
            touch(join_paths(d, "DD-1", "x.rpm"))

            (r, *rs) = generate_driver_disk_repositories(d)

            assert rs == []
            assert r.name == "DD-1"
            assert r.url == "file://{}/DD-1".format(d)
Esempio n. 8
0
    def _setup_internal_bindmount(self,
                                  src,
                                  dest=None,
                                  src_physical=True,
                                  bind_ro=False,
                                  recurse=True):
        """Internal API for setting up bind mounts between the physical root and sysroot

        Also ensures we track them in self._internal_mounts so we can cleanly unmount them.

        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.

        :param src: Source path, will be prefixed with physical or sysroot
        :param dest: Destination, will be prefixed with sysroot (defaults to same as src)
        :param src_physical: Prefix src with physical root
        :param bind_ro: Make mount read-only
        :param recurse: Use --rbind to recurse, otherwise plain --bind
        """
        # Default to the same basename
        if dest is None:
            dest = src

        # Almost all of our mounts go from physical to sysroot
        if src_physical:
            src = self._physroot + src
        else:
            src = self._sysroot + src

        # Canonicalize dest to the full path
        dest = self._sysroot + dest

        if bind_ro:
            safe_exec_with_redirect("mount", ["--bind", src, src])
            safe_exec_with_redirect("mount",
                                    ["--bind", "-o", "remount,ro", src, src])
        else:
            # Create missing directories for user defined mount points
            if not os.path.exists(dest):
                make_directories(dest)

            # Recurse for non-ro binds so we pick up sub-mounts
            # like /sys/firmware/efi/efivars.
            if recurse:
                bindopt = '--rbind'
            else:
                bindopt = '--bind'
            safe_exec_with_redirect("mount", [bindopt, src, dest])

        self._internal_mounts.append(src if bind_ro else dest)
Esempio n. 9
0
    def test_get_os_relase_value(self):
        """Test the get_release_value function."""
        with tempfile.TemporaryDirectory() as root:
            # prepare paths
            make_directories(root + "/usr/lib")
            make_directories(root + "/etc")

            # no file
            with self.assertLogs(level="DEBUG") as cm:
                version = util.get_os_release_value("VERSION_ID", root)

            msg = "VERSION_ID not found in os-release files"
            assert any(map(lambda x: msg in x, cm.output))
            assert version is None

            # backup file only
            with open(root + "/usr/lib/os-release", "w") as f:
                f.write(
                    "# blah\nVERSION_ID=foo256bar  \n VERSION_ID = wrong\n\n")
            version = util.get_os_release_value("VERSION_ID", root)
            assert version == "foo256bar"
            assert util.get_os_release_value("PLATFORM_ID", root) is None

            # main file and backup too
            with open(root + "/etc/os-release", "w") as f:
                f.write("# blah\nVERSION_ID=more-important\n")
            version = util.get_os_release_value("VERSION_ID", root)
            assert version == "more-important"

            # both, main file twice
            with open(root + "/etc/os-release", "w") as f:
                f.write(
                    "# blah\nVERSION_ID=more-important\nVERSION_ID=not-reached\n \n"
                )
            version = util.get_os_release_value("VERSION_ID", root)
            assert version == "more-important"

            # quoted values
            with open(root + "/etc/os-release", "w") as f:
                f.write(
                    "PRETTY_NAME=\"Fedora 32\"\nPLATFORM_ID='platform:f32'\n")
            assert util.get_os_release_value("PRETTY_NAME",
                                             root) == "Fedora 32"
            assert util.get_os_release_value("PLATFORM_ID",
                                             root) == "platform:f32"

            # no files
            os.remove(root + "/usr/lib/os-release")
            os.remove(root + "/etc/os-release")
            version = util.get_os_release_value("VERSION_ID", root)
            assert version is None
Esempio n. 10
0
    def test_make_directories(self):
        """Test make_directories"""

        with tempfile.TemporaryDirectory() as tmpdir:

            # don't fail if directory path already exists
            make_directories('/')
            make_directories('/tmp')

            # create a path and test it exists
            test_folder = "test_mkdir_chain"
            test_paths = [
                "foo", "foo/bar/baz", "", "čřščščřščř", "asdasd asdasd",
                "! spam"
            ]

            # join with the toplevel test folder and the folder for this test
            test_paths = [
                os.path.join(str(tmpdir), test_folder, p) for p in test_paths
            ]

            # create the folders and check that they exist
            for p in test_paths:
                make_directories(p)
                assert os.path.exists(p)

            # try to create them again - all the paths should already exist
            # and the make_directories function needs to handle that
            # without a traceback
            for p in test_paths:
                make_directories(p)
    def _create_tar(self, files):
        """Create a new tarball."""
        # Create the content.
        for path in files:
            file_path = join_paths(self.directory, path)
            make_directories(os.path.dirname(file_path))
            touch(file_path)

        # Create a local tarball.
        with tarfile.open(self.tarball, "w") as tar:
            for path in files:
                tar.add(join_paths(self.directory, path), path)

            tar.list()

        # Set up the configuration data.
        self.data.url = "file://" + self.tarball
Esempio n. 12
0
    def _do_mount(self):
        """Set up the installation source."""
        log.debug("Trying to mount the content of HMC media drive.")

        # Test the SE/HMC file access.
        if execWithRedirect("/usr/sbin/lshmc", []):
            raise SourceSetupError(
                "The content of HMC media drive couldn't be accessed.")

        # Make sure that the directories exists.
        make_directories(self._target_mount)

        # Mount the device.
        if execWithRedirect("/usr/bin/hmcdrvfs", [self._target_mount]):
            raise SourceSetupError(
                "The content of HMC media drive couldn't be mounted.")

        log.debug("We are ready to use the HMC at %s.", self._target_mount)
    def _create_image(self, files, mount_task_cls):
        """Create a fake image."""
        # Create the image.
        touch(self.image)

        # Set up the configuration data.
        self.data.url = "file://" + self.image

        # Set up the mount point.
        os.makedirs(self.mount_point)

        for path in files:
            file_path = join_paths(self.mount_point, path)
            make_directories(os.path.dirname(file_path))
            touch(file_path)

        mount_task = mount_task_cls()
        mount_task.run.return_value = self.mount_point
Esempio n. 14
0
    def _copy_file_to_root(self, root, config_file, overwrite=False, follow_symlinks=True):
        """Copy the file to target system.

        :param root: path to the root of the target system
        :type root: str
        :param config_file: path of the file
        :type config_file: str
        :param overwrite: overwrite existing configuration file
        :type overwrite: bool
        """
        if not os.path.isfile(config_file):
            return
        fpath = os.path.normpath(root + config_file)
        if (os.path.isfile(fpath) or os.path.islink(fpath)) and not overwrite:
            return
        if not os.path.isdir(os.path.dirname(fpath)):
            make_directories(os.path.dirname(fpath))
        shutil.copy(config_file, fpath, follow_symlinks=follow_symlinks)
Esempio n. 15
0
    def _set_up_fips(self):
        """Set up FIPS in the target system."""
        log.debug("Copying the crypto policy.")

        # Create /etc/crypto-policies.
        src = "/etc/crypto-policies/"
        dst = join_paths(self._sysroot, src)
        make_directories(dst)

        # Copy the config file.
        src = "/etc/crypto-policies/config"
        dst = join_paths(self._sysroot, src)
        shutil.copyfile(src, dst)

        # Log the file content on the target system.
        util.execWithRedirect("/bin/cat", [dst])

        # Copy the back-ends.
        src = "/etc/crypto-policies/back-ends/"
        dst = join_paths(self._sysroot, src)
        shutil.copytree(src, dst, symlinks=True)

        # Log the directory content on the target system.
        util.execWithRedirect("/bin/ls", ["-l", dst])
Esempio n. 16
0
def dracut_eject(device):
    """
    Use dracut shutdown hook to eject media after the system is shutdown.
    This is needed because we are running from the squashfs.img on the media
    so ejecting too early will crash the installer.
    """
    if not device:
        return

    try:
        if not os.path.exists(DRACUT_SHUTDOWN_EJECT):
            make_directories(os.path.dirname(DRACUT_SHUTDOWN_EJECT))
            f = open_with_perm(DRACUT_SHUTDOWN_EJECT, "w", 0o755)
            f.write("#!/bin/sh\n")
            f.write("# Created by Anaconda\n")
        else:
            f = open(DRACUT_SHUTDOWN_EJECT, "a")

        f.write("eject %s\n" % (device, ))
        f.close()
        log.info("Wrote dracut shutdown eject hook for %s", device)
    except OSError as e:
        log.error("Error writing dracut shutdown eject hook for %s: %s",
                  device, e)
    def test_repositories(self):
        """Test with multiple driver disk repositories."""
        with tempfile.TemporaryDirectory() as d:
            make_directories(join_paths(d, "DD-1"))
            touch(join_paths(d, "DD-1", "x.rpm"))

            make_directories(join_paths(d, "DD-2"))
            touch(join_paths(d, "DD-2", "y.rpm"))

            make_directories(join_paths(d, "DD-3"))
            touch(join_paths(d, "DD-3", "z.rpm"))

            (r1, r2, r3, *rs) = generate_driver_disk_repositories(d)

            assert rs == []
            assert r1.name == "DD-1"
            assert r1.url == "file://{}/DD-1".format(d)

            assert r2.name == "DD-2"
            assert r2.url == "file://{}/DD-2".format(d)

            assert r3.name == "DD-3"
            assert r3.url == "file://{}/DD-3".format(d)
Esempio n. 18
0
def create_user(username,
                password=False,
                is_crypted=False,
                lock=False,
                homedir=None,
                uid=None,
                gid=None,
                groups=None,
                shell=None,
                gecos="",
                root=None):
    """Create a new user on the system with the given name.

    :param str username: The username for the new user to be created.
    :param str password: The password. See is_crypted 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)
    :param bool is_crypted: Is the password already encrypted? Defaults to False.
    :param bool lock: Is the new account locked by default?
                      Defaults to False.
    :param str homedir: The home directory for the new user.
                        Defaults to /home/<name>.
    :param int uid: The UID for the new user.
                    If none is given, the next available one is used.
    :param int gid: The GID for the new user.
                    If none is given, the next available one is used.
    :param 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
    :param str shell: The shell for the new user.
                      If none is given, the login.defs default is used.
    :param str gecos: The GECOS information (full name, office, phone, etc.).
                      Defaults to "".
    :param str root: The directory of the system to create the new user in.
                     The homedir option will be interpreted relative to this.
                     Defaults to conf.target.system_root.
    """

    # resolve the optional arguments that need a default that can't be
    # reasonably set in the function signature
    if not homedir:
        homedir = "/home/" + username

    if groups is None:
        groups = []

    if root is None:
        root = conf.target.system_root

    if check_user_exists(username, root):
        raise ValueError("User %s already exists" % username)

    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 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 gid:
        if not _getgrgid(gid, root) and not any(one_gid[1] == str(gid)
                                                for one_gid in group_gids):
            create_group(username, gid=gid, root=root)

        args.extend(['-g', str(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 = _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:
            create_group(group_name, gid=gid, root=root)
        group_list.append(group_name)

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

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

    # 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 != Path("/"):
        make_directories(str(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 shell:
        args.extend(["-s", shell])

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

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

    args.append(username)
    with _ensure_login_defs(root):
        status = util.execWithRedirect("useradd", args)

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

    if not mk_homedir:
        log.info(
            "Home directory for the user %s already existed, "
            "fixing the owner and SELinux context.", username)
        _reown_homedir(root, homedir, username)

    set_user_password(username, password, is_crypted, lock, root)
 def test_empty_repository(self):
     """Test with empty driver disk repositories."""
     with tempfile.TemporaryDirectory() as d:
         make_directories(join_paths(d, "DD-1"))
         assert generate_driver_disk_repositories(d) == []
Esempio n. 20
0
 def _create_logs_directory(self):
     """Create directory for Anaconda logs on the install target"""
     make_directories(join_paths(self._sysroot, TARGET_LOG_DIR))
Esempio n. 21
0
 def _make_dir(self, root, name, uid, gid):
     make_directories(root + name)
     os.chown(root + name, uid, gid)
Esempio n. 22
0
    from pyanaconda.anaconda import Anaconda
    anaconda = Anaconda()

    # reset python's default SIGINT handler
    signal.signal(signal.SIGINT, signal.SIG_IGN)
    signal.signal(signal.SIGTERM, lambda num, frame: sys.exit(1))

    # synchronously-delivered signals such as SIGSEGV and SIGILL cannot be
    # handled properly from python, so install signal handlers from the C
    # function in isys.
    isys.installSyncSignalHandlers()

    setup_environment()

    # make sure we have /var/log soon, some programs fail to start without it
    path.make_directories("/var/log")

    # Create a PID file. The exit handler, installed later, will clean it up.
    pidfile = pid.PidFile(pidname='anaconda',
                          register_term_signal_handler=False)

    try:
        pidfile.create()
    except pid.PidFileError as e:
        log.error("Unable to create %s, exiting", pidfile.filename)

        # If we had a $DISPLAY at start and zenity is available, we may be
        # running in a live environment and we can display an error dialog.
        # Otherwise just print an error.
        if flags.preexisting_x11 and os.access("/usr/bin/zenity", os.X_OK):
            # The module-level _() calls are ok here because the language may