Пример #1
0
def makeResolvConf(instPath):
    """Make the resolv.conf file in the chroot."""
    if flags.imageInstall:
        return

    if not os.access("/etc/resolv.conf", os.R_OK):
        return

    if os.access("%s/etc/resolv.conf" %(instPath,), os.R_OK):
        f = open("%s/etc/resolv.conf" %(instPath,), "r")
        buf = f.read()
        f.close()
    else:
        buf = ""

    # already have a nameserver line, don't worry about it
    if buf.find("nameserver") != -1:
        return

    f = open("/etc/resolv.conf", "r")
    buf = f.read()
    f.close()

    # no nameserver, we can't do much about it
    if buf.find("nameserver") == -1:
        return

    shutil.copyfile("%s/etc/resolv.conf" %(instPath,),
                    "%s/etc/resolv.conf.bak" %(instPath,))
    f = open("%s/etc/resolv.conf" %(instPath,), "w+")
    f.write(buf)
    f.close()
Пример #2
0
def makeResolvConf(instPath):
    """Make the resolv.conf file in the chroot."""
    if flags.imageInstall:
        return

    if not os.access("/etc/resolv.conf", os.R_OK):
        return

    if os.access("%s/etc/resolv.conf" % (instPath, ), os.R_OK):
        f = open("%s/etc/resolv.conf" % (instPath, ), "r")
        buf = f.read()
        f.close()
    else:
        buf = ""

    # already have a nameserver line, don't worry about it
    if buf.find("nameserver") != -1:
        return

    f = open("/etc/resolv.conf", "r")
    buf = f.read()
    f.close()

    # no nameserver, we can't do much about it
    if buf.find("nameserver") == -1:
        return

    shutil.copyfile("%s/etc/resolv.conf" % (instPath, ),
                    "%s/etc/resolv.conf.bak" % (instPath, ))
    f = open("%s/etc/resolv.conf" % (instPath, ), "w+")
    f.write(buf)
    f.close()
Пример #3
0
def write_timezone_config(timezone, root):
    """
    Write timezone configuration for the system specified by root.

    :param timezone: ksdata.timezone object
    :param root: path to the root
    :raise: TimezoneConfigError

    """

    # we want to create a relative symlink
    tz_file = "/usr/share/zoneinfo/" + timezone.timezone
    rooted_tz_file = os.path.normpath(root + tz_file)
    relative_path = os.path.normpath("../" + tz_file)
    link_path = os.path.normpath(root + "/etc/localtime")

    if not os.access(rooted_tz_file, os.R_OK):
        log.error("Timezone to be linked (%s) doesn't exist", rooted_tz_file)
    else:
        try:
            # os.symlink fails if link_path exists, so try to remove it first
            os.remove(link_path)
        except OSError:
            pass

        try:
            os.symlink(relative_path, link_path)
        except OSError as oserr:
            log.error("Error when symlinking timezone (from %s): %s",
                      rooted_tz_file, oserr.strerror)

    if arch.isS390():
        # there is no HW clock on s390(x)
        return

    try:
        fobj = open(os.path.normpath(root + "/etc/adjtime"), "r")
        lines = fobj.readlines()
        fobj.close()
    except IOError:
        lines = ["0.0 0 0.0\n", "0\n"]

    try:
        with open(os.path.normpath(root + "/etc/adjtime"), "w") as fobj:
            fobj.write(lines[0])
            fobj.write(lines[1])
            if timezone.isUtc:
                fobj.write("UTC\n")
            else:
                fobj.write("LOCAL\n")
    except IOError as ioerr:
        msg = "Error while writing /etc/adjtime file: %s" % ioerr.strerror
        raise TimezoneConfigError(msg)
def write_timezone_config(timezone, root):
    """
    Write timezone configuration for the system specified by root.

    :param timezone: ksdata.timezone object
    :param root: path to the root
    :raise: TimezoneConfigError

    """

    # we want to create a relative symlink
    tz_file = "/usr/share/zoneinfo/" + timezone.timezone
    rooted_tz_file = os.path.normpath(root + tz_file)
    relative_path = os.path.normpath("../" + tz_file)
    link_path = os.path.normpath(root + "/etc/localtime")

    if not os.access(rooted_tz_file, os.R_OK):
        log.error("Timezone to be linked (%s) doesn't exist", rooted_tz_file)
    else:
        try:
            # os.symlink fails if link_path exists, so try to remove it first
            os.remove(link_path)
        except OSError:
            pass

        try:
            os.symlink(relative_path, link_path)
        except OSError as oserr:
            log.error("Error when symlinking timezone (from %s): %s",
                      rooted_tz_file, oserr.strerror)

    if arch.isS390():
        # there is no HW clock on s390(x)
        return

    try:
        fobj = open(os.path.normpath(root + "/etc/adjtime"), "r")
        lines = fobj.readlines()
        fobj.close()
    except IOError:
        lines = ["0.0 0 0.0\n", "0\n"]

    try:
        with open(os.path.normpath(root + "/etc/adjtime"), "w") as fobj:
            fobj.write(lines[0])
            fobj.write(lines[1])
            if timezone.isUtc:
                fobj.write("UTC\n")
            else:
                fobj.write("LOCAL\n")
    except IOError as ioerr:
        msg = "Error while writing /etc/adjtime file: %s" % ioerr.strerror
        raise TimezoneConfigError(msg)
Пример #5
0
def makeFStab(instPath=""):
    if os.access("/proc/mounts", os.R_OK):
        f = open("/proc/mounts", "r")
        buf = f.read()
        f.close()
    else:
        buf = ""

    try:
        f = open(instPath + "/etc/fstab", "a")
        if buf:
            f.write(buf)
        f.close()
    except IOError as e:
        log.info("failed to write /etc/fstab: %s", e)
Пример #6
0
def isLpaeAvailable():
    with open("/proc/cpuinfo", "r") as fobj:
        for line in fobj:
            if line.startswith("Features") and "lpae" in line.split():
                return True

    return False
Пример #7
0
    def write(self, filename=None, use_tmp=True):
        """ passing filename will override the filename passed to init.
        """
        filename = filename or self.filename
        if not filename:
            return None

        if use_tmp:
            tmpf = tempfile.NamedTemporaryFile(mode="w", delete=False)
            tmpf.write(str(self))
            tmpf.close()

            # Move the temporary file (with 0600 permissions) over the top of the
            # original and preserve the original's permissions
            filename = os.path.realpath(filename)
            if os.path.exists(filename):
                m = os.stat(filename).st_mode
            else:
                m = int('0100644', 8)
            shutil.move(tmpf.name, filename)
            eintr_retry_call(os.chmod, filename, m)
        else:
            # write directly to the file
            with open(filename, "w") as fobj:
                fobj.write(str(self))
Пример #8
0
def total_memory():
    """Returns total system memory in kB (given to us by /proc/meminfo)"""

    with open("/proc/meminfo", "r") as fobj:
        for line in fobj:
            if not line.startswith("MemTotal"):
                # we are only interested in the MemTotal: line
                continue

            fields = line.split()
            if len(fields) != 3:
                log.error("unknown format for MemTotal line in /proc/meminfo: %s", line.rstrip())
                raise RuntimeError("unknown format for MemTotal line in /proc/meminfo: %s" % line.rstrip())

            try:
                memsize = int(fields[1])
            except ValueError:
                log.error("ivalid value of MemTotal /proc/meminfo: %s", fields[1])
                raise RuntimeError("ivalid value of MemTotal /proc/meminfo: %s" % fields[1])

            # Because /proc/meminfo only gives us the MemTotal (total physical
            # RAM minus the kernel binary code), we need to round this
            # up. Assuming every machine has the total RAM MB number divisible
            # by 128.
            memsize /= 1024
            memsize = (memsize / 128 + 1) * 128
            memsize *= 1024

            log.info("%d kB (%d MB) are available", memsize, memsize / 1024)
            return memsize

        log.error("MemTotal: line not found in /proc/meminfo")
        raise RuntimeError("MemTotal: line not found in /proc/meminfo")
Пример #9
0
def load_firmware_language(lang, text_mode=False):
    """
    Procedure that loads firmware language information (if any). It stores the
    information in the given ksdata.lang object and sets the $LANG environment
    variable.

    This method must be run before any other threads are started.

    :param lang: ksdata.lang object
    :return: None
    :rtype: None

    """

    if lang.lang and lang.seen:
        # set in kickstart, do not override
        return

    try:
        n = "/sys/firmware/efi/efivars/PlatformLang-8be4df61-93ca-11d2-aa0d-00e098032b8c"
        d = open(n, 'r', 0).read()
    except IOError:
        return

    # the contents of the file are:
    # 4-bytes of attribute data that we don't care about
    # NUL terminated ASCII string like 'en-US'.
    if len(d) < 10:
        log.debug("PlatformLang was too short")
        return
    d = d[4:]
    if d[2] != '-':
        log.debug("PlatformLang was malformed")
        return

    # they use - and we use _, so fix it...
    d = d[:2] + '_' + d[3:-1]

    # UEFI 2.3.1 Errata C specifies 2 aliases in common use that
    # aren't part of RFC 4646, but are allowed in PlatformLang.
    # Because why make anything simple?
    if d.startswith('zh_chs'):
        d = 'zh_Hans'
    elif d.startswith('zh_cht'):
        d = 'zh_Hant'
    d += '.UTF-8'

    if not is_supported_locale(d):
        log.debug("PlatformLang was '%s', which is unsupported.", d)
        return

    locales = get_language_locales(d)
    if not locales:
        log.debug("No locales found for the PlatformLang '%s'.", d)
        return

    log.debug("Using UEFI PlatformLang '%s' ('%s') as our language.", d, locales[0])
    setup_locale(locales[0], lang, text_mode)

    os.environ["LANG"] = locales[0] # pylint: disable=environment-modify
Пример #10
0
def get_servers_from_config(conf_file_path=NTP_CONFIG_FILE,
                            srv_regexp=SRV_LINE_REGEXP):
    """
    Goes through the chronyd's configuration file looking for lines starting
    with 'server'.

    :return: servers found in the chronyd's configuration
    :rtype: list

    """

    pools = list()
    servers = list()

    try:
        with open(conf_file_path, "r") as conf_file:
            for line in conf_file:
                match = srv_regexp.match(line)
                if match:
                    if match.group(1) == "pool":
                        pools.append(match.group(2))
                    else:
                        servers.append(match.group(2))

    except IOError as ioerr:
        msg = "Cannot open config file %s for reading (%s)" % (conf_file_path,
                                                               ioerr.strerror)
        raise NTPconfigError(msg)

    return (pools, servers)
Пример #11
0
def isLpaeAvailable():
    with open("/proc/cpuinfo", "r") as fobj:
        for line in fobj:
            if line.startswith("Features") and "lpae" in line.split():
                return True

    return False
Пример #12
0
def load_firmware_language(lang):
    """
    Procedure that loads firmware language information (if any). It stores the
    information in the given ksdata.lang object and sets the $LANG environment
    variable.

    This method must be run before any other threads are started.

    :param lang: ksdata.lang object
    :return: None
    :rtype: None

    """

    if lang.lang and lang.seen:
        # set in kickstart, do not override
        return

    try:
        n = "/sys/firmware/efi/efivars/PlatformLang-8be4df61-93ca-11d2-aa0d-00e098032b8c"
        d = open(n, 'r', 0).read()
    except IOError:
        return

    # the contents of the file are:
    # 4-bytes of attribute data that we don't care about
    # NUL terminated ASCII string like 'en-US'.
    if len(d) < 10:
        log.debug("PlatformLang was too short")
        return
    d = d[4:]
    if d[2] != '-':
        log.debug("PlatformLang was malformed")
        return

    # they use - and we use _, so fix it...
    d = d[:2] + '_' + d[3:-1]

    # UEFI 2.3.1 Errata C specifies 2 aliases in common use that
    # aren't part of RFC 4646, but are allowed in PlatformLang.
    # Because why make anything simple?
    if d.startswith('zh_chs'):
        d = 'zh_Hans'
    elif d.startswith('zh_cht'):
        d = 'zh_Hant'
    d += '.UTF-8'

    if not is_supported_locale(d):
        log.debug("PlatformLang was '%s', which is unsupported.", d)
        return

    locales = get_language_locales(d)
    if not locales:
        log.debug("No locales found for the PlatformLang '%s'.", d)
        return

    log.debug("Using UEFI PlatformLang '%s' ('%s') as our language.", d, locales[0])
    setup_locale(locales[0], lang)

    os.environ["LANG"] = locales[0] # pylint: disable=environment-modify
Пример #13
0
def get_servers_from_config(conf_file_path=NTP_CONFIG_FILE,
                            srv_regexp=SRV_LINE_REGEXP):
    """
    Goes through the chronyd's configuration file looking for lines starting
    with 'server'.

    :return: servers found in the chronyd's configuration
    :rtype: list

    """

    pools = list()
    servers = list()

    try:
        with open(conf_file_path, "r") as conf_file:
            for line in conf_file:
                match = srv_regexp.match(line)
                if match:
                    if match.group(1) == "pool":
                        pools.append(match.group(2))
                    else:
                        servers.append(match.group(2))

    except IOError as ioerr:
        msg = "Cannot open config file %s for reading (%s)" % (conf_file_path,
                                                               ioerr.strerror)
        raise NTPconfigError(msg)

    return (pools, servers)
Пример #14
0
    def dumpState(self):
        from meh import ExceptionInfo
        from meh.dump import ReverseExceptionDump
        from inspect import stack as _stack
        from traceback import format_stack

        # Skip the frames for dumpState and the signal handler.
        stack = _stack()[2:]
        stack.reverse()
        exn = ReverseExceptionDump(ExceptionInfo(None, None, stack),
                                   self.mehConfig)

        # gather up info on the running threads
        threads = "\nThreads\n-------\n"
        for thread_id, frame in sys._current_frames().items():
            threads += "\nThread %s\n" % (thread_id,)
            threads += "".join(format_stack(frame))

        # dump to a unique file
        (fd, filename) = mkstemp(prefix="anaconda-tb-", dir="/tmp")
        dump_text = exn.traceback_and_object_dump(self)
        dump_text += threads
        dump_text_bytes = dump_text.encode("utf-8")
        iutil.eintr_retry_call(os.write, fd, dump_text_bytes)
        iutil.eintr_ignore(os.close, fd)

        # append to a given file
        with open("/tmp/anaconda-tb-all.log", "a+") as f:
            f.write("--- traceback: %s ---\n" % filename)
            f.write(dump_text + "\n")
    def preInstall(self, packages=None, groups=None):
        super(DNFPayload, self).preInstall(packages, groups)
        self.requiredPackages += ["dnf"]
        if packages:
            self.requiredPackages += packages
        self.requiredGroups = groups

        # Write the langpacks config
        pyanaconda.iutil.mkdirChain(DNF_PLUGINCONF_DIR)
        langs = [self.data.lang.lang] + self.data.lang.addsupport

        # Start with the file in /etc, if one exists. Otherwise make an empty config
        if os.path.exists(_DNF_TARGET_LANGPACK_CONF):
            shutil.copy2(_DNF_TARGET_LANGPACK_CONF,
                         _DNF_INSTALLER_LANGPACK_CONF)
        else:
            with open(_DNF_INSTALLER_LANGPACK_CONF, "w") as f:
                f.write("[main]\n")

        # langpacks.conf is an INI style config file, read it and
        # add or change the enabled and langpack_locales entries without
        # changing anything else.
        keys = [("langpack_locales", "langpack_locales=" + ", ".join(langs)),
                ("enabled", "enabled=1")]
        simple_replace(_DNF_INSTALLER_LANGPACK_CONF, keys)
Пример #16
0
def simple_replace(fname, keys, add=True, add_comment="# Added by Anaconda"):
    """ Replace lines in a file, optionally adding if missing.

    :param str fname: Filename to operate on
    :param list keys: List of (key, string) tuples to search and replace
    :param bool add: When True add strings that were not replaced

    This will read all the lines in a file, looking for ones that start
    with keys and replacing the line with the associated string. The string
    should be a COMPLETE replacement for the line, not just a value.

    When add is True any keys that haven't been found will be appended
    to the end of the file along with the add_comment.
    """
    # Helper to return the line or the first matching key's string
    def _replace(l):
        r = [s for k,s in keys if l.startswith(k)]
        if r:
            return r[0]
        else:
            return l

    # Replace lines that match any of the keys
    with open(fname, "r") as f:
        lines = [_replace(l.strip()) for l in f]

    # Add any strings that weren't already in the file
    if add:
        append = [s for k,s in keys if not any(l.startswith(k) for l in lines)]
        if append:
            lines += [add_comment]
            lines += append

    write_tmpfile(fname, "\n".join(lines)+"\n")
Пример #17
0
    def setUserSshKey(self, username, key, **kwargs):
        childpid = self._prepareChroot(kwargs.get("root", iutil.getSysroot()))

        if childpid == 0:
            user = self.admin.lookupUserByName(username)
            if not user:
                log.error("setUserSshKey: user %s does not exist", username)
                os._exit(1)

            homedir = user.get(libuser.HOMEDIRECTORY)[0]
            if not os.path.exists(homedir):
                log.error("setUserSshKey: home directory for %s does not exist", username)
                os._exit(1)

            sshdir = os.path.join(homedir, ".ssh")
            if not os.path.isdir(sshdir):
                os.mkdir(sshdir, 0o700)
                iutil.eintr_retry_call(os.chown, sshdir, user.get(libuser.UIDNUMBER)[0], user.get(libuser.GIDNUMBER)[0])

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

            # Only change mode and ownership if we created it
            if not authfile_existed:
                iutil.eintr_retry_call(os.chmod, authfile, 0o600)
                iutil.eintr_retry_call(os.chown, authfile, user.get(libuser.UIDNUMBER)[0], user.get(libuser.GIDNUMBER)[0])
                iutil.execWithRedirect("restorecon", ["-r", sshdir])
            os._exit(0)
        else:
            return self._finishChroot(childpid)
    def dumpState(self):
        from meh import ExceptionInfo
        from meh.dump import ReverseExceptionDump
        from inspect import stack as _stack
        from traceback import format_stack

        # Skip the frames for dumpState and the signal handler.
        stack = _stack()[2:]
        stack.reverse()
        exn = ReverseExceptionDump(ExceptionInfo(None, None, stack),
                                   self.mehConfig)

        # gather up info on the running threads
        threads = "\nThreads\n-------\n"

        # Every call to sys._current_frames() returns a new dict, so it is not
        # modified when threads are created or destroyed. Iterating over it is
        # thread safe.
        for thread_id, frame in sys._current_frames().items():
            threads += "\nThread %s\n" % (thread_id, )
            threads += "".join(format_stack(frame))

        # dump to a unique file
        (fd, filename) = mkstemp(prefix="anaconda-tb-", dir="/tmp")
        dump_text = exn.traceback_and_object_dump(self)
        dump_text += threads
        dump_text_bytes = dump_text.encode("utf-8")
        iutil.eintr_retry_call(os.write, fd, dump_text_bytes)
        iutil.eintr_ignore(os.close, fd)

        # append to a given file
        with open("/tmp/anaconda-tb-all.log", "a+") as f:
            f.write("--- traceback: %s ---\n" % filename)
            f.write(dump_text + "\n")
Пример #19
0
    def write(self, filename=None, use_tmp=True):
        """ passing filename will override the filename passed to init.
        """
        filename = filename or self.filename
        if not filename:
            return None

        if use_tmp:
            tmpf = tempfile.NamedTemporaryFile(mode="w", delete=False)
            tmpf.write(str(self))
            tmpf.close()

            # Move the temporary file (with 0600 permissions) over the top of the
            # original and preserve the original's permissions
            filename = os.path.realpath(filename)
            if os.path.exists(filename):
                m = os.stat(filename).st_mode
            else:
                m = int('0100644', 8)
            shutil.move(tmpf.name, filename)
            eintr_retry_call(os.chmod, filename, m)
        else:
            # write directly to the file
            with open(filename, "w") as fobj:
                fobj.write(str(self))
Пример #20
0
    def _groupExists(self, group_name, root):
        """Returns whether a group with the given name already exists."""
        with open(root + "/etc/group", "r") as f:
            for line in f:
                if line.split(":")[0] == group_name:
                    return True

        return False
Пример #21
0
    def _groupExists(self, group_name, root):
        """Returns whether a group with the given name already exists."""
        with open(root + "/etc/group", "r") as f:
            for line in f:
                if line.split(":")[0] == group_name:
                    return True

        return False
Пример #22
0
def getMediaId(path):
    if os.access("%s/.discinfo" % path, os.R_OK):
        f = open("%s/.discinfo" % path)
        newStamp = f.readline().strip()
        f.close()

        return newStamp
    else:
        return None
Пример #23
0
def getMediaId(path):
    if os.access("%s/.discinfo" % path, os.R_OK):
        f = open("%s/.discinfo" % path)
        newStamp = f.readline().strip()
        f.close()

        return newStamp
    else:
        return None
Пример #24
0
    def _ensureLoginDefs(self, root):
        """Runs a command after creating /etc/login.defs, if necessary.

           groupadd and useradd need login.defs to exist in the chroot, and if
           someone is doing a cloud image install or some kind of --nocore thing
           it may not. An empty one is ok, though. If it's missing, create it,
           run the command, then clean it up.
        """
        login_defs_path = root + '/etc/login.defs'
        if not os.path.exists(login_defs_path):
            open(login_defs_path, "w").close()
            login_defs_created = True
        else:
            login_defs_created = False

        yield

        if login_defs_created:
            os.unlink(login_defs_path)
Пример #25
0
    def _ensureLoginDefs(self, root):
        """Runs a command after creating /etc/login.defs, if necessary.

           groupadd and useradd need login.defs to exist in the chroot, and if
           someone is doing a cloud image install or some kind of --nocore thing
           it may not. An empty one is ok, though. If it's missing, create it,
           run the command, then clean it up.
        """
        login_defs_path = root + "/etc/login.defs"
        if not os.path.exists(login_defs_path):
            open(login_defs_path, "w").close()
            login_defs_created = True
        else:
            login_defs_created = False

        yield

        if login_defs_created:
            os.unlink(login_defs_path)
Пример #26
0
    def _getTreeInfo(self, url, proxy_url, sslverify):
        """ Retrieve treeinfo and return the path to the local file.

            :param baseurl: url of the repo
            :type baseurl: string
            :param proxy_url: Optional full proxy URL of or ""
            :type proxy_url: string
            :param sslverify: True if SSL certificate should be verified
            :type sslverify: bool
            :returns: Path to retrieved .treeinfo file or None
            :rtype: string or None
        """
        if not url:
            return None

        log.debug("retrieving treeinfo from %s (proxy: %s ; sslverify: %s)",
                  url, proxy_url, sslverify)

        proxies = {}
        if proxy_url:
            try:
                proxy = ProxyString(proxy_url)
                proxies = {"http": proxy.url, "https": proxy.url}
            except ProxyStringError as e:
                log.info("Failed to parse proxy for _getTreeInfo %s: %s",
                         proxy_url, e)

        response = None
        headers = {"user-agent": USER_AGENT}
        try:
            response = self._session.get("%s/.treeinfo" % url,
                                         headers=headers,
                                         proxies=proxies,
                                         verify=sslverify)
        except requests.exceptions.RequestException as e:
            try:
                response = self._session.get("%s/treeinfo" % url,
                                             headers=headers,
                                             proxies=proxies,
                                             verify=sslverify)
            except requests.exceptions.RequestException as e:
                log.info("Error downloading treeinfo: %s", e)
                self.verbose_errors.append(str(e))
                response = None

        if response:
            # write the local treeinfo file
            with open("/tmp/.treeinfo", "w") as f:
                f.write(response.text)

            # and also return the treeinfo contents as a string
            return response.text
        else:
            return None
Пример #27
0
def isIsoImage(path):
    try:
        with open(path, "rb") as isoFile:
            for blockNum in range(16, 100):
                isoFile.seek(blockNum * ISO_BLOCK_SIZE + 1)
                if isoFile.read(5) == "CD001":
                    return True
    except IOError:
        pass

    return False
Пример #28
0
def isIsoImage(path):
    try:
        with open(path, "rb") as isoFile:
            for blockNum in range(16, 100):
                isoFile.seek(blockNum * ISO_BLOCK_SIZE + 1)
                if isoFile.read(5) == b"CD001":
                    return True
    except IOError:
        pass

    return False
Пример #29
0
    def _getpwnam(self, user_name, root):
        """Like pwd.getpwnam, but is able to use a different root.

           Also just returns the pwd structure as a list, because of laziness.
        """
        with open(root + "/etc/passwd", "r") as f:
            for line in f:
                fields = line.split(":")
                if fields[0] == user_name:
                    return fields

        return None
Пример #30
0
    def _getgrnam(self, group_name, root):
        """Like grp.getgrnam, but able to use a different root.

            Just returns the grp structure as a list, same reason as above.
        """
        with open(root + "/etc/group", "r") as f:
            for line in f:
                fields = line.split(":")
                if fields[0] == group_name:
                    return fields

        return None
Пример #31
0
    def _getgrnam(self, group_name, root):
        """Like grp.getgrnam, but able to use a different root.

            Just returns the grp structure as a list, same reason as above.
        """
        with open(root + "/etc/group", "r") as f:
            for line in f:
                fields = line.split(":")
                if fields[0] == group_name:
                    return fields

        return None
Пример #32
0
 def writeXdriver(self, root=None):
     # this should go away at some point, but until it does, we
     # need to keep it around.
     if self.xdriver is None:
         return
     if root is None:
         root = iutil.getSysroot()
     if not os.path.isdir("%s/etc/X11" %(root,)):
         os.makedirs("%s/etc/X11" %(root,), mode=0o755)
     f = open("%s/etc/X11/xorg.conf" %(root,), 'w')
     f.write('Section "Device"\n\tIdentifier "Videocard0"\n\tDriver "%s"\nEndSection\n' % self.xdriver)
     f.close()
Пример #33
0
    def _getpwnam(self, user_name, root):
        """Like pwd.getpwnam, but is able to use a different root.

           Also just returns the pwd structure as a list, because of laziness.
        """
        with open(root + "/etc/passwd", "r") as f:
            for line in f:
                fields = line.split(":")
                if fields[0] == user_name:
                    return fields

        return None
    def _writeDNFRepo(self, repo, repo_path):
        """ Write a repo object to a DNF repo.conf file

            :param repo: DNF repository object
            :param string repo_path: Path to write the repo to
            :raises: PayloadSetupError if the repo doesn't have a url
        """
        with open(repo_path, "w") as f:
            f.write("[%s]\n" % repo.id)
            f.write("name=%s\n" % repo.id)
            if self.isRepoEnabled(repo.id):
                f.write("enabled=1\n")
            else:
                f.write("enabled=0\n")

            if repo.mirrorlist:
                f.write("mirrorlist=%s\n" % repo.mirrorlist)
            elif repo.metalink:
                f.write("metalink=%s\n" % repo.metalink)
            elif repo.baseurl:
                f.write("baseurl=%s\n" % repo.baseurl[0])
            else:
                f.close()
                os.unlink(repo_path)
                raise packaging.PayloadSetupError(
                    "repo %s has no baseurl, mirrorlist or metalink", repo.id)

            # kickstart repo modifiers
            ks_repo = self.getAddOnRepo(repo.id)
            if not ks_repo:
                return

            if ks_repo.noverifyssl:
                f.write("sslverify=0\n")

            if ks_repo.proxy:
                try:
                    proxy = ProxyString(ks_repo.proxy)
                    f.write("proxy=%s\n" % proxy.url)
                except ProxyStringError as e:
                    log.error(
                        "Failed to parse proxy for _writeInstallConfig %s: %s",
                        ks_repo.proxy, e)

            if ks_repo.cost:
                f.write("cost=%d\n" % ks_repo.cost)

            if ks_repo.includepkgs:
                f.write("include=%s\n" % ",".join(ks_repo.includepkgs))

            if ks_repo.excludepkgs:
                f.write("exclude=%s\n" % ",".join(ks_repo.excludepkgs))
Пример #35
0
    def read(self, filename=None):
        """ passing filename will override the filename passed to init.

            save the lines into self._lines and the key/value pairs into
            self.info
        """
        filename = filename or self.filename
        with open(filename) as f:
            for line in f:
                self._lines.append(line)
                key, value, _comment = self._parseline(line)
                if key:
                    self.info[key] = value
Пример #36
0
    def write(self, filename=None, use_tmp=True):
        """ passing filename will override the filename passed to init.
        """
        filename = filename or self.filename
        if not filename:
            return None

        if use_tmp:
            write_tmpfile(filename, str(self))
        else:
            # write directly to the file
            with open(filename, "w") as fobj:
                fobj.write(str(self))
Пример #37
0
    def read(self, filename=None):
        """ passing filename will override the filename passed to init.

            save the lines into self._lines and the key/value pairs into
            self.info
        """
        filename = filename or self.filename
        with open(filename) as f:
            for line in f:
                self._lines.append(line)
                key, value, _comment = self._parseline(line)
                if key:
                    self.info[key] = value
Пример #38
0
    def _writeModuleBlacklist(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

        iutil.mkdirChain(iutil.getSysroot() + "/etc/modprobe.d")
        with open(iutil.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)
Пример #39
0
    def write(self, filename=None, use_tmp=True):
        """ passing filename will override the filename passed to init.
        """
        filename = filename or self.filename
        if not filename:
            return None

        if use_tmp:
            write_tmpfile(filename, str(self))
        else:
            # write directly to the file
            with open(filename, "w") as fobj:
                fobj.write(str(self))
    def write(self):
        if self.desktop:
            with open(iutil.getSysroot() + "/etc/sysconfig/desktop", "w") as f:
                f.write("DESKTOP=%s\n" % self.desktop)

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

        default_target = iutil.getSysroot() + '/etc/systemd/system/default.target'
        if os.path.islink(default_target):
            os.unlink(default_target)
        os.symlink('/lib/systemd/system/%s' % RUNLEVELS[self.runlevel],
                   default_target)
Пример #41
0
def get_firmware_language(text_mode=False):
    """
    Procedure that returns the firmware language information (if any).

    :param boot text_mode: if the locale is being setup for text mode
    :return: the firmware language translated into a locale string, or None
    :rtype: str
    """

    try:
        n = "/sys/firmware/efi/efivars/PlatformLang-8be4df61-93ca-11d2-aa0d-00e098032b8c"
        d = open(n, 'r').read()
    except IOError:
        return None

    # the contents of the file are:
    # 4-bytes of attribute data that we don't care about
    # NUL terminated ASCII string like 'en-US'.
    if len(d) < 10:
        log.debug("PlatformLang was too short")
        return None
    d = d[4:]
    if d[2] != '-':
        log.debug("PlatformLang was malformed")
        return None

    # they use - and we use _, so fix it...
    d = d[:2] + '_' + d[3:-1]

    # UEFI 2.3.1 Errata C specifies 2 aliases in common use that
    # aren't part of RFC 4646, but are allowed in PlatformLang.
    # Because why make anything simple?
    if d.startswith('zh_chs'):
        d = 'zh_Hans'
    elif d.startswith('zh_cht'):
        d = 'zh_Hant'
    d += '.UTF-8'

    if not is_supported_locale(d):
        log.debug("PlatformLang was '%s', which is unsupported.", d)
        return None

    locales = get_language_locales(d)
    if not locales:
        log.debug("No locales found for the PlatformLang '%s'.", d)
        return None

    log.debug("Using UEFI PlatformLang '%s' ('%s') as our language.", d,
              locales[0])
    return locales[0]
 def writeXdriver(self, root=None):
     # this should go away at some point, but until it does, we
     # need to keep it around.
     if self.xdriver is None:
         return
     if root is None:
         root = iutil.getSysroot()
     if not os.path.isdir("%s/etc/X11" % (root, )):
         os.makedirs("%s/etc/X11" % (root, ), mode=0o755)
     f = open("%s/etc/X11/xorg.conf" % (root, ), 'w')
     f.write(
         'Section "Device"\n\tIdentifier "Videocard0"\n\tDriver "%s"\nEndSection\n'
         % self.xdriver)
     f.close()
Пример #43
0
    def _writeDNFRepo(self, repo, repo_path):
        """ Write a repo object to a DNF repo.conf file

            :param repo: DNF repository object
            :param string repo_path: Path to write the repo to
            :raises: PayloadSetupError if the repo doesn't have a url
        """
        with open(repo_path, "w") as f:
            f.write("[%s]\n" % repo.id)
            f.write("name=%s\n" % repo.id)
            if self.isRepoEnabled(repo.id):
                f.write("enabled=1\n")
            else:
                f.write("enabled=0\n")

            if repo.mirrorlist:
                f.write("mirrorlist=%s\n" % repo.mirrorlist)
            elif repo.metalink:
                f.write("metalink=%s\n" % repo.metalink)
            elif repo.baseurl:
                f.write("baseurl=%s\n" % repo.baseurl[0])
            else:
                f.close()
                os.unlink(repo_path)
                raise packaging.PayloadSetupError("repo %s has no baseurl, mirrorlist or metalink", repo.id)

            # kickstart repo modifiers
            ks_repo = self.getAddOnRepo(repo.id)
            if not ks_repo:
                return

            if ks_repo.noverifyssl:
                f.write("sslverify=0\n")

            if ks_repo.proxy:
                try:
                    proxy = ProxyString(ks_repo.proxy)
                    f.write("proxy=%s\n" % proxy.url)
                except ProxyStringError as e:
                    log.error("Failed to parse proxy for _writeInstallConfig %s: %s",
                              ks_repo.proxy, e)

            if ks_repo.cost:
                f.write("cost=%d\n" % ks_repo.cost)

            if ks_repo.includepkgs:
                f.write("include=%s\n" % ",".join(ks_repo.includepkgs))

            if ks_repo.excludepkgs:
                f.write("exclude=%s\n" % ",".join(ks_repo.excludepkgs))
Пример #44
0
    def _getTreeInfo(self, url, proxy_url, sslverify):
        """ Retrieve treeinfo and return the path to the local file.

            :param baseurl: url of the repo
            :type baseurl: string
            :param proxy_url: Optional full proxy URL of or ""
            :type proxy_url: string
            :param sslverify: True if SSL certificate should be verified
            :type sslverify: bool
            :returns: Path to retrieved .treeinfo file or None
            :rtype: string or None
        """
        if not url:
            return None

        log.debug("retrieving treeinfo from %s (proxy: %s ; sslverify: %s)",
                  url, proxy_url, sslverify)

        proxies = {}
        if proxy_url:
            try:
                proxy = ProxyString(proxy_url)
                proxies = {"http": proxy.url,
                           "https": proxy.url}
            except ProxyStringError as e:
                log.info("Failed to parse proxy for _getTreeInfo %s: %s",
                         proxy_url, e)

        response = None
        headers = {"user-agent": USER_AGENT}
        try:
            response = self._session.get("%s/.treeinfo" % url, headers=headers, proxies=proxies, verify=sslverify)
        except requests.exceptions.RequestException as e:
            try:
                response = self._session.get("%s/treeinfo" % url, headers=headers, proxies=proxies, verify=sslverify)
            except requests.exceptions.RequestException as e:
                log.info("Error downloading treeinfo: %s", e)
                self.verbose_errors.append(str(e))
                response = None

        if response:
            # write the local treeinfo file
            with open("/tmp/.treeinfo", "w") as f:
                f.write(response.text)

            # and also return the treeinfo contents as a string
            return response.text
        else:
            return None
Пример #45
0
def createLuserConf(instPath, algoname='sha512'):
    """ Writes a libuser.conf for instPath.

        This must be called before User() is instantiated the first time
        so that libuser.admin will use the temporary config file.
    """

    # If LIBUSER_CONF is not set, create a new temporary file
    if "LIBUSER_CONF" not in os.environ:
        (fp, fn) = tempfile.mkstemp(prefix="libuser.")
        log.info("created new libuser.conf at %s with instPath=\"%s\"", fn,
                 instPath)
        fd = os.fdopen(fp, "w")
        # This is only ok if createLuserConf is first called before threads are started
        os.environ["LIBUSER_CONF"] = fn  # pylint: disable=environment-modify
    else:
        fn = os.environ["LIBUSER_CONF"]
        log.info("Clearing libuser.conf at %s", fn)
        fd = open(fn, "w")

    buf = """
[defaults]
skeleton = %(instPath)s/etc/skel
mailspooldir = %(instPath)s/var/mail
crypt_style = %(algo)s
modules = files shadow
create_modules = files shadow
[files]
directory = %(instPath)s/etc
[shadow]
directory = %(instPath)s/etc
""" % {
        "instPath": instPath,
        "algo": algoname
    }

    # Import login.defs if installed
    if os.path.exists(os.path.normpath(instPath + "/etc/login.defs")):
        buf += """
[import]
login_defs = %(instPath)s/etc/login.defs
""" % {
            "instPath": instPath
        }

    fd.write(buf)
    fd.close()

    return fn
Пример #46
0
def get_firmware_language(text_mode=False):
    """
    Procedure that returns the firmware language information (if any).

    :param boot text_mode: if the locale is being setup for text mode
    :return: the firmware language translated into a locale string, or None
    :rtype: str
    """

    try:
        n = "/sys/firmware/efi/efivars/PlatformLang-8be4df61-93ca-11d2-aa0d-00e098032b8c"
        d = open(n, 'r').read()
    except IOError:
        return None

    # the contents of the file are:
    # 4-bytes of attribute data that we don't care about
    # NUL terminated ASCII string like 'en-US'.
    if len(d) < 10:
        log.debug("PlatformLang was too short")
        return None
    d = d[4:]
    if d[2] != '-':
        log.debug("PlatformLang was malformed")
        return None

    # they use - and we use _, so fix it...
    d = d[:2] + '_' + d[3:-1]

    # UEFI 2.3.1 Errata C specifies 2 aliases in common use that
    # aren't part of RFC 4646, but are allowed in PlatformLang.
    # Because why make anything simple?
    if d.startswith('zh_chs'):
        d = 'zh_Hans'
    elif d.startswith('zh_cht'):
        d = 'zh_Hant'
    d += '.UTF-8'

    if not is_supported_locale(d):
        log.debug("PlatformLang was '%s', which is unsupported.", d)
        return None

    locales = get_language_locales(d)
    if not locales:
        log.debug("No locales found for the PlatformLang '%s'.", d)
        return None

    log.debug("Using UEFI PlatformLang '%s' ('%s') as our language.", d, locales[0])
    return locales[0]
Пример #47
0
    def _getgrgid(self, gid, root):
        """Like grp.getgrgid, but able to use a different root.

           Just returns the fields as a list of strings.
        """
        # Conver the probably-int GID to a string
        gid = str(gid)

        with open(root + "/etc/group", "r") as f:
            for line in f:
                fields = line.split(":")
                if fields[2] == gid:
                    return fields

        return None
Пример #48
0
    def updateRemote(self, remote_syslog):
        """Updates the location of remote rsyslogd to forward to.

        Requires updating rsyslogd config and restarting rsyslog
        """
        # Import here instead of at the module level to avoid an import loop
        from pyanaconda.iutil import open   # pylint: disable=redefined-builtin

        TEMPLATE = "*.* @@%s\n"

        self.remote_syslog = remote_syslog
        with open(self.SYSLOG_CFGFILE, 'a') as cfgfile:
            forward_line = TEMPLATE % remote_syslog
            cfgfile.write(forward_line)
        self.restartSyslog()
Пример #49
0
    def _writeModuleBlacklist(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

        iutil.mkdirChain(iutil.getSysroot() + "/etc/modprobe.d")
        with open(
                iutil.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)
Пример #50
0
    def updateRemote(self, remote_syslog):
        """Updates the location of remote rsyslogd to forward to.

        Requires updating rsyslogd config and restarting rsyslog
        """
        # Import here instead of at the module level to avoid an import loop
        from pyanaconda.iutil import open  # pylint: disable=redefined-builtin

        TEMPLATE = "*.* @@%s\n"

        self.remote_syslog = remote_syslog
        with open(self.SYSLOG_CFGFILE, 'a') as cfgfile:
            forward_line = TEMPLATE % remote_syslog
            cfgfile.write(forward_line)
        self.restartSyslog()
Пример #51
0
    def _getgrgid(self, gid, root):
        """Like grp.getgrgid, but able to use a different root.

           Just returns the fields as a list of strings.
        """
        # Conver the probably-int GID to a string
        gid = str(gid)

        with open(root + "/etc/group", "r") as f:
            for line in f:
                fields = line.split(":")
                if fields[2] == gid:
                    return fields

        return None
Пример #52
0
    def setupVirtio(self):
        """Setup virtio rsyslog logging.
        """
        # Import here instead of at the module level to avoid an import loop
        from pyanaconda.iutil import open   # pylint: disable=redefined-builtin

        TEMPLATE = "*.* %s;anaconda_syslog\n"

        vport = flags.cmdline.get('virtiolog') or self.VIRTIO_PORT

        if not os.access(vport, os.W_OK):
            return

        with open(self.SYSLOG_CFGFILE, 'a') as cfgfile:
            cfgfile.write(TEMPLATE % (vport,))
        self.restartSyslog()
Пример #53
0
    def setVNCPassword(self):
        """Set the vnc server password. Output to file. """

        r, w = os.pipe()
        password_string = "%s\n" % self.password
        iutil.eintr_retry_call(os.write, w, password_string.encode("utf-8"))

        with open(self.pw_file, "wb") as pw_file:
            # the -f option makes sure vncpasswd does not ask for the password again
            rc = iutil.execWithRedirect("vncpasswd", ["-f"],
                    stdin=r, stdout=pw_file, binary_output=True, log_output=False)

            iutil.eintr_ignore(os.close, r)
            iutil.eintr_ignore(os.close, w)

        return rc
Пример #54
0
    def setupVirtio(self):
        """Setup virtio rsyslog logging.
        """
        # Import here instead of at the module level to avoid an import loop
        from pyanaconda.iutil import open  # pylint: disable=redefined-builtin

        TEMPLATE = "*.* %s;anaconda_syslog\n"

        vport = flags.cmdline.get('virtiolog') or self.VIRTIO_PORT

        if not os.access(vport, os.W_OK):
            return

        with open(self.SYSLOG_CFGFILE, 'a') as cfgfile:
            cfgfile.write(TEMPLATE % (vport, ))
        self.restartSyslog()
Пример #55
0
def _writeKS(ksdata):
    import os

    path = iutil.getSysroot() + "/root/anaconda-ks.cfg"

    # Clear out certain sensitive information that kickstart doesn't have a
    # way of representing encrypted.
    for obj in [ksdata.autopart] + ksdata.logvol.dataList() + \
               ksdata.partition.dataList() + ksdata.raid.dataList():
        obj.passphrase = ""

    with open(path, "w") as f:
        f.write(str(ksdata))

    # Make it so only root can read - could have passwords
    iutil.eintr_retry_call(os.chmod, path, 0o600)
Пример #56
0
def write_language_configuration(lang, root):
    """
    Write language configuration to the $root/etc/locale.conf file.

    :param lang: ksdata.lang object
    :param root: path to the root of the installed system

    """

    try:
        fpath = os.path.normpath(root + LOCALE_CONF_FILE_PATH)
        with open(fpath, "w") as fobj:
            fobj.write('LANG="%s"\n' % lang.lang)
    except IOError as ioerr:
        msg = "Cannot write language configuration file: %s" % ioerr.strerror
        raise LocalizationConfigError(msg)
Пример #57
0
def write_language_configuration(lang, root):
    """
    Write language configuration to the $root/etc/locale.conf file.

    :param lang: ksdata.lang object
    :param root: path to the root of the installed system

    """

    try:
        fpath = os.path.normpath(root + LOCALE_CONF_FILE_PATH)
        with open(fpath, "w") as fobj:
            fobj.write('LANG="%s"\n' % lang.lang)
    except IOError as ioerr:
        msg = "Cannot write language configuration file: %s" % ioerr.strerror
        raise LocalizationConfigError(msg)