예제 #1
0
def mountImage(isodir, tree):
    while True:
        if os.path.isfile(isodir):
            image = isodir
        else:
            image = findFirstIsoImage(isodir)
            if image is None:
                exn = MissingImageError()
                if errorHandler.cb(exn) == ERROR_RAISE:
                    raise exn
                else:
                    continue

            image = os.path.normpath("%s/%s" % (isodir, image))

        try:
            blivet.util.mount(image, tree, fstype='iso9660', options="ro")
        except OSError:
            exn = MissingImageError()
            if errorHandler.cb(exn) == ERROR_RAISE:
                raise exn
            else:
                continue
        else:
            break
예제 #2
0
def mountImage(isodir, tree):
    while True:
        if os.path.isfile(isodir):
            image = isodir
        else:
            image = findFirstIsoImage(isodir)
            if image is None:
                exn = MissingImageError()
                if errorHandler.cb(exn) == ERROR_RAISE:
                    raise exn
                else:
                    continue

            image = os.path.normpath("%s/%s" % (isodir, image))

        try:
            blivet.util.mount(image, tree, fstype='iso9660', options="ro")
        except OSError:
            exn = MissingImageError()
            if errorHandler.cb(exn) == ERROR_RAISE:
                raise exn
            else:
                continue
        else:
            break
예제 #3
0
def mountImage(isodir, tree):
    # FIXME: This is duplicated in SetUpHardDriveSourceTask.run
    while True:
        if os.path.isfile(isodir):
            image = isodir
        else:
            image = find_first_iso_image(isodir)
            if image is None:
                exn = MissingImageError()
                if errorHandler.cb(exn) == ERROR_RAISE:
                    raise exn
                else:
                    continue

            image = os.path.normpath("%s/%s" % (isodir, image))

        try:
            blivet.util.mount(image, tree, fstype='iso9660', options="ro")
        except OSError:
            exn = MissingImageError()
            if errorHandler.cb(exn) == ERROR_RAISE:
                raise exn
            else:
                continue
        else:
            break
예제 #4
0
    def run(self, chroot):
        """ Run the kickstart script
            @param chroot directory path to chroot into before execution
        """
        if self.inChroot:
            scriptRoot = chroot
        else:
            scriptRoot = "/"

        (fd, path) = tempfile.mkstemp("", "ks-script-", scriptRoot + "/tmp")

        os.write(fd, self.script.encode("utf-8"))
        os.close(fd)
        os.chmod(path, 0o700)

        # Always log stdout/stderr from scripts.  Using --log just lets you
        # pick where it goes.  The script will also be logged to program.log
        # because of execWithRedirect.
        if self.logfile:
            if self.inChroot:
                messages = "%s/%s" % (scriptRoot, self.logfile)
            else:
                messages = self.logfile

            d = os.path.dirname(messages)
            if not os.path.exists(d):
                os.makedirs(d)
        else:
            # Always log outside the chroot, we copy those logs into the
            # chroot later.
            messages = "/tmp/%s.log" % os.path.basename(path)

        with open(messages, "w") as fp:
            rc = util.execWithRedirect(self.interp,
                                       ["/tmp/%s" % os.path.basename(path)],
                                       stdout=fp,
                                       root=scriptRoot)

        if rc != 0:
            script_log.error(
                "Error code %s running the kickstart script at line %s", rc,
                self.lineno)
            if self.errorOnFail:
                err = ""
                with open(messages, "r") as fp:
                    err = "".join(fp.readlines())

                # Show error dialog even for non-interactive
                flags.ksprompt = True

                errorHandler.cb(ScriptError(self.lineno, err))
                util.ipmi_report(IPMI_ABORTED)
                sys.exit(0)
예제 #5
0
파일: image.py 프로젝트: Sabayon/anaconda
def unmountCD(dev):
    if not dev:
        return

    while True:
        try:
            dev.format.unmount()
        except FSError as e:
            log.error("exception in _unmountCD: %s", e)
            exn = MediaUnmountError()
            errorHandler.cb(exn, dev)
        else:
            break
예제 #6
0
파일: image.py 프로젝트: jjmichaud/anaconda
def unmountCD(dev):
    if not dev:
        return

    while True:
        try:
            dev.format.unmount()
        except FSError as e:
            log.error("exception in _unmountCD: %s", e)
            exn = MediaUnmountError()
            errorHandler.cb(exn, dev)
        else:
            break
예제 #7
0
    def run(self, chroot):
        """ Run the kickstart script
            @param chroot directory path to chroot into before execution
        """
        if self.inChroot:
            scriptRoot = chroot
        else:
            scriptRoot = "/"

        (fd, path) = tempfile.mkstemp("", "ks-script-", scriptRoot + "/tmp")

        os.write(fd, self.script.encode("utf-8"))
        os.close(fd)
        os.chmod(path, 0o700)

        # Always log stdout/stderr from scripts.  Using --log just lets you
        # pick where it goes.  The script will also be logged to program.log
        # because of execWithRedirect.
        if self.logfile:
            if self.inChroot:
                messages = "%s/%s" % (scriptRoot, self.logfile)
            else:
                messages = self.logfile

            d = os.path.dirname(messages)
            if not os.path.exists(d):
                os.makedirs(d)
        else:
            # Always log outside the chroot, we copy those logs into the
            # chroot later.
            messages = "/tmp/%s.log" % os.path.basename(path)

        with open(messages, "w") as fp:
            rc = util.execWithRedirect(self.interp, ["/tmp/%s" % os.path.basename(path)],
                                       stdout=fp,
                                       root=scriptRoot)

        if rc != 0:
            script_log.error("Error code %s running the kickstart script at line %s", rc, self.lineno)
            if self.errorOnFail:
                err = ""
                with open(messages, "r") as fp:
                    err = "".join(fp.readlines())

                # Show error dialog even for non-interactive
                flags.ksprompt = True

                errorHandler.cb(ScriptError(self.lineno, err))
                util.ipmi_report(IPMI_ABORTED)
                sys.exit(0)
예제 #8
0
def reset_storage(storage, scan_all=False, retry=True):
    """Reset the storage model.

    :param storage: an instance of the Blivet's storage object
    :param scan_all: should we scan all devices in the system?
    :param retry: should we allow to retry the reset?
    """
    # Clear the exclusive disks to scan all devices in the system.
    if scan_all:
        disk_select_proxy = STORAGE.get_proxy(DISK_SELECTION)
        disk_select_proxy.SetExclusiveDisks([])

    # Do the reset.
    while True:
        try:
            _reset_storage(storage)
        except StorageError as e:
            # Is the retry allowed?
            if not retry:
                raise
            # Does the user want to retry?
            elif error_handler.cb(e) == ERROR_RAISE:
                raise
            # Retry the storage reset.
            else:
                continue
        else:
            # No need to retry.
            break
예제 #9
0
파일: fsset.py 프로젝트: rvykydal/anaconda
    def turn_on_swap(self, root_path=""):
        """Activate the system's swap space."""
        for device in self.swap_devices:
            if isinstance(device, FileDevice):
                # set up FileDevices' parents now that they are accessible
                target_dir = "%s/%s" % (root_path, device.path)
                parent = get_containing_device(target_dir, self.devicetree)
                if not parent:
                    log.error("cannot determine which device contains "
                              "directory %s", device.path)
                    device.parents = []
                    self.devicetree._remove_device(device)
                    continue
                else:
                    device.parents = [parent]

            while True:
                if device.status and device.format.status:
                    break
                try:
                    device.setup()
                    device.format.setup()
                except (blockdev.SwapOldError, blockdev.SwapSuspendError,
                        blockdev.SwapUnknownError, blockdev.SwapPagesizeError) as e:
                    log.error("Failed to activate swap on '%s': %s", device.name, str(e))
                    break
                except (StorageError, blockdev.BlockDevError) as e:
                    if error_handler.cb(e) == ERROR_RAISE:
                        raise
                else:
                    break
예제 #10
0
def reset_storage(scan_all=False, retry=True):
    """Reset the storage model.

    :param scan_all: should we scan all devices in the system?
    :param retry: should we allow to retry the reset?
    """
    # Clear the exclusive disks to scan all devices in the system.
    if scan_all:
        disk_select_proxy = STORAGE.get_proxy(DISK_SELECTION)
        disk_select_proxy.SetExclusiveDisks([])

    # Scan the devices.
    storage_proxy = STORAGE.get_proxy()

    while True:
        try:
            task_path = storage_proxy.ScanDevicesWithTask()
            task_proxy = STORAGE.get_proxy(task_path)
            sync_run_task(task_proxy)
        except DBusError as e:
            # Is the retry allowed?
            if not retry:
                raise
            # Does the user want to retry?
            elif error_handler.cb(e) == ERROR_RAISE:
                raise
            # Retry the storage reset.
            else:
                continue
        else:
            # No need to retry.
            break

    # Reset the partitioning.
    storage_proxy.ResetPartitioning()
예제 #11
0
    def setup(self):
        super().setup()
        # Mount the live device and copy from it instead of the overlay at /
        osimg_spec = self._get_live_os_image()

        if not osimg_spec:
            raise PayloadSetupError("No live image found!")

        osimg = payload_utils.resolve_device(osimg_spec)
        if not osimg:
            raise PayloadInstallError("Unable to find osimg for {}".format(osimg_spec))

        osimg_path = payload_utils.get_device_path(osimg)
        if not stat.S_ISBLK(os.stat(osimg_path)[stat.ST_MODE]):
            exn = PayloadSetupError("{} is not a valid block device".format(osimg_spec))
            if errorHandler.cb(exn) == ERROR_RAISE:
                raise exn

        rc = payload_utils.mount(osimg_path, INSTALL_TREE, fstype="auto", options="ro")
        if rc != 0:
            raise PayloadInstallError("Failed to mount the install tree")

        # Grab the kernel version list now so it's available after umount
        self._update_kernel_version_list()

        source = os.statvfs(INSTALL_TREE)
        self.source_size = source.f_frsize * (source.f_blocks - source.f_bfree)
예제 #12
0
    def install(self):
        """ Install the payload. """
        self.pct_lock = Lock()
        self.pct = 0
        threadMgr.add(AnacondaThread(name=THREAD_LIVE_PROGRESS,
                                     target=self.progress))

        cmd = "rsync"
        # preserve: permissions, owners, groups, ACL's, xattrs, times,
        #           symlinks, hardlinks
        # go recursively, include devices and special files, don't cross
        # file system boundaries
        args = ["-pogAXtlHrDx", "--exclude", "/dev/", "--exclude", "/proc/",
                "--exclude", "/sys/", "--exclude", "/run/", "--exclude", "/boot/*rescue*",
                "--exclude", "/etc/machine-id", INSTALL_TREE+"/", ROOT_PATH]
        try:
            rc = iutil.execWithRedirect(cmd, args)
        except (OSError, RuntimeError) as e:
            msg = None
            err = str(e)
            log.error(err)
        else:
            err = None
            msg = "%s exited with code %d" % (cmd, rc)
            log.info(msg)

        if err or rc == 12:
            exn = PayloadInstallError(err or msg)
            if errorHandler.cb(exn) == ERROR_RAISE:
                raise exn

        # Wait for progress thread to finish
        with self.pct_lock:
            self.pct = 100
        threadMgr.wait(THREAD_LIVE_PROGRESS)
예제 #13
0
    def setup(self, storage, instClass):
        super().setup(storage, instClass)

        # Mount the live device and copy from it instead of the overlay at /
        osimg = storage.devicetree.get_device_by_path(
            self.data.method.partition)
        if not osimg:
            raise PayloadInstallError("Unable to find osimg for %s" %
                                      self.data.method.partition)

        if not stat.S_ISBLK(os.stat(osimg.path)[stat.ST_MODE]):
            exn = PayloadSetupError("%s is not a valid block device" %
                                    (self.data.method.partition, ))
            if errorHandler.cb(exn) == ERROR_RAISE:
                raise exn
        rc = blivet.util.mount(osimg.path,
                               INSTALL_TREE,
                               fstype="auto",
                               options="ro")
        if rc != 0:
            raise PayloadInstallError("Failed to mount the install tree")

        # Grab the kernel version list now so it's available after umount
        self._updateKernelVersionList()

        source = os.statvfs(INSTALL_TREE)
        self.source_size = source.f_frsize * (source.f_blocks - source.f_bfree)
예제 #14
0
    def turn_on_swap(self, root_path=""):
        """Activate the system's swap space."""
        for device in self.swap_devices:
            if isinstance(device, FileDevice):
                # set up FileDevices' parents now that they are accessible
                target_dir = "%s/%s" % (root_path, device.path)
                parent = get_containing_device(target_dir, self.devicetree)
                if not parent:
                    log.error(
                        "cannot determine which device contains "
                        "directory %s", device.path)
                    device.parents = []
                    self.devicetree._remove_device(device)
                    continue
                else:
                    device.parents = [parent]

            while True:
                if device.status and device.format.status:
                    break
                try:
                    device.setup()
                    device.format.setup()
                except (blockdev.SwapOldError, blockdev.SwapSuspendError,
                        blockdev.SwapUnknownError,
                        blockdev.SwapPagesizeError) as e:
                    log.error("Failed to activate swap on '%s': %s",
                              device.name, str(e))
                    break
                except (StorageError, blockdev.BlockDevError) as e:
                    if error_handler.cb(e) == ERROR_RAISE:
                        raise
                else:
                    break
예제 #15
0
파일: image.py 프로젝트: bcl/anaconda
def mountImageDirectory(method, storage):
    # No need to mount it again.
    if os.path.ismount(ISO_DIR):
        return

    if method.method == "harddrive":
        if method.biospart:
            log.warning("biospart support is not implemented")
            devspec = method.biospart
        else:
            devspec = method.partition

        # FIXME: teach DeviceTree.resolveDevice about biospart
        device = storage.devicetree.resolveDevice(devspec)

        while True:
            try:
                device.setup()
                device.format.setup(mountpoint=ISO_DIR)
            except StorageError as e:
                log.error("couldn't mount ISO source directory: %s", e)
                exn = MediaMountError(str(e), device)
                if errorHandler.cb(exn) == ERROR_RAISE:
                    raise exn
    elif method.method.startswith("nfsiso:"):
        # XXX what if we mount it on ISO_DIR and then create a symlink
        #     if there are no isos instead of the remount?

        # mount the specified directory
        path = method.dir
        if method.dir.endswith(".iso"):
            path = os.path.dirname(method.dir)

        url = "%s:%s" % (method.server, path)

        while True:
            try:
                blivet.util.mount(url,
                                  ISO_DIR,
                                  fstype="nfs",
                                  options=method.options)
            except OSError as e:
                log.error("couldn't mount ISO source directory: %s", e)
                exn = MediaMountError(str(e), device)
                if errorHandler.cb(exn) == ERROR_RAISE:
                    raise exn
예제 #16
0
 def _run(self):
     """Runs the task (callable) assigned to this Task class instance."""
     try:
         # Run the task.
         self._task_cb(*self._task_args, **self._task_kwargs)
     except Exception as e:  # pylint: disable=broad-except
         # Handle an error.
         if errorHandler.cb(e) == ERROR_RAISE:
             raise
예제 #17
0
def mountImageDirectory(method, storage):
    # No need to mount it again.
    if os.path.ismount(ISO_DIR):
        return

    if method.method == "harddrive":
        if method.biospart:
            log.warning("biospart support is not implemented")
            devspec = method.biospart
        else:
            devspec = method.partition

        # FIXME: teach DeviceTree.resolveDevice about biospart
        device = storage.devicetree.resolveDevice(devspec)

        while True:
            try:
                device.setup()
                device.format.setup(mountpoint=ISO_DIR)
            except StorageError as e:
                log.error("couldn't mount ISO source directory: %s", e)
                exn = MediaMountError(str(e), device)
                if errorHandler.cb(exn) == ERROR_RAISE:
                    raise exn
    elif method.method.startswith("nfsiso:"):
        # XXX what if we mount it on ISO_DIR and then create a symlink
        #     if there are no isos instead of the remount?

        # mount the specified directory
        path = method.dir
        if method.dir.endswith(".iso"):
            path = os.path.dirname(method.dir)

        url = "%s:%s" % (method.server, path)

        while True:
            try:
                blivet.util.mount(url, ISO_DIR, fstype="nfs", options=method.options)
            except OSError as e:
                log.error("couldn't mount ISO source directory: %s", e)
                exn = MediaMountError(str(e), device)
                if errorHandler.cb(exn) == ERROR_RAISE:
                    raise exn
예제 #18
0
    def setup(self, storage, instClass):
        super(LiveImagePayload, self).setup(storage, instClass)

        # Mount the live device and copy from it instead of the overlay at /
        osimg = storage.devicetree.getDeviceByPath(self.data.method.partition)
        if not stat.S_ISBLK(os.stat(osimg.path)[stat.ST_MODE]):
            exn = PayloadSetupError("%s is not a valid block device" % (self.data.method.partition,))
            if errorHandler.cb(exn) == ERROR_RAISE:
                raise exn
        blivet.util.mount(osimg.path, INSTALL_TREE, fstype="auto", options="ro")
예제 #19
0
    def install(self):
        """ Install the payload. """

        if self.source_size <= 0:
            raise PayloadInstallError("Nothing to install")

        self.pct_lock = Lock()
        self.pct = 0
        threadMgr.add(
            AnacondaThread(name=THREAD_LIVE_PROGRESS, target=self.progress))

        cmd = "rsync"
        # preserve: permissions, owners, groups, ACL's, xattrs, times,
        #           symlinks, hardlinks
        # go recursively, include devices and special files, don't cross
        # file system boundaries
        args = [
            "-pogAXtlHrDx", "--exclude", "/dev/", "--exclude", "/proc/",
            "--exclude", "/sys/", "--exclude", "/run/", "--exclude",
            "/boot/*rescue*", "--exclude", "/etc/machine-id",
            INSTALL_TREE + "/",
            util.getSysroot()
        ]
        try:
            rc = util.execWithRedirect(cmd, args)
        except (OSError, RuntimeError) as e:
            msg = None
            err = str(e)
            log.error(err)
        else:
            err = None
            msg = "%s exited with code %d" % (cmd, rc)
            log.info(msg)

        if err or rc == 12:
            exn = PayloadInstallError(err or msg)
            if errorHandler.cb(exn) == ERROR_RAISE:
                raise exn

        # Wait for progress thread to finish
        with self.pct_lock:
            self.pct = 100
        threadMgr.wait(THREAD_LIVE_PROGRESS)

        # Live needs to create the rescue image before bootloader is written
        if not os.path.exists(util.getSysroot() + "/usr/sbin/new-kernel-pkg"):
            log.error(
                "new-kernel-pkg does not exist - grubby wasn't installed?  skipping"
            )
            return

        for kernel in self.kernelVersionList:
            log.info("Generating rescue image for %s", kernel)
            util.execInSysroot("new-kernel-pkg", ["--rpmposttrans", kernel])
예제 #20
0
def cryptPassword(password, algo=None):
    salts = {'md5': '$1$', 'sha256': '$5$', 'sha512': '$6$'}
    if algo not in salts:
        algo = 'sha512'

    cryptpw = iutil.encrypt_password(password, salts[algo], 16)
    if cryptpw is None:
        exn = PasswordCryptError(algo=algo)
        if errorHandler.cb(exn) == ERROR_RAISE:
            raise exn

    return cryptpw
예제 #21
0
파일: zipl.py 프로젝트: rvykydal/anaconda
    def install(self, args=None):
        buf = util.execWithCapture("zipl", [], root=util.getSysroot())
        for line in buf.splitlines():
            if line.startswith("Preparing boot device: "):
                # Output here may look like:
                #     Preparing boot device: dasdb (0200).
                #     Preparing boot device: dasdl.
                # We want to extract the device name and pass that.
                name = re.sub(r".+?: ", "", line)
                self.stage1_name = re.sub(r"(\s\(.+\))?\.$", "", name)
            # a limitation of s390x is that the kernel parameter list must not
            # exceed 896 bytes; there is nothing we can do about this, so just
            # catch the error and show it to the user instead of crashing
            elif line.startswith("Error: The length of the parameters "):
                errorHandler.cb(ZIPLError(line))

        if not self.stage1_name:
            raise BootLoaderError("could not find IPL device")

        # do the reipl
        util.reIPL(self.stage1_name)
예제 #22
0
    def install(self, args=None):
        buf = util.execWithCapture("zipl", [], root=conf.target.system_root)
        for line in buf.splitlines():
            if line.startswith("Preparing boot device: "):
                # Output here may look like:
                #     Preparing boot device: dasdb (0200).
                #     Preparing boot device: dasdl.
                # We want to extract the device name and pass that.
                name = re.sub(r".+?: ", "", line)
                self.stage1_name = re.sub(r"(\s\(.+\))?\.$", "", name)
            # a limitation of s390x is that the kernel parameter list must not
            # exceed 896 bytes; there is nothing we can do about this, so just
            # catch the error and show it to the user instead of crashing
            elif line.startswith("Error: The length of the parameters "):
                errorHandler.cb(ZIPLError(line))

        if not self.stage1_name:
            raise BootLoaderError("could not find IPL device")

        # do the reipl
        util.reIPL(self.stage1_name)
예제 #23
0
    def install(self):
        """ Install the payload if it is a tar.
            Otherwise fall back to rsync of INSTALL_TREE
        """
        # If it doesn't look like a tarfile use the super's install()
        if not self.is_tarfile:
            super().install()
            return

        # Use 2x the archive's size to estimate the size of the install
        # This is used to drive the progress display
        self.source_size = os.stat(self.image_path)[stat.ST_SIZE] * 2

        self.pct_lock = Lock()
        self.pct = 0
        threadMgr.add(
            AnacondaThread(name=THREAD_LIVE_PROGRESS, target=self.progress))

        cmd = "tar"
        # preserve: ACL's, xattrs, and SELinux context
        args = [
            "--selinux", "--acls", "--xattrs", "--xattrs-include", "*",
            "--exclude", "/dev/", "--exclude", "/proc/", "--exclude", "/sys/",
            "--exclude", "/run/", "--exclude", "/boot/*rescue*", "--exclude",
            "/etc/machine-id", "-xaf", self.image_path, "-C",
            util.getSysroot()
        ]
        try:
            rc = util.execWithRedirect(cmd, args)
        except (OSError, RuntimeError) as e:
            msg = None
            err = str(e)
            log.error(err)
        else:
            err = None
            msg = "%s exited with code %d" % (cmd, rc)
            log.info(msg)

        if err:
            exn = PayloadInstallError(err or msg)
            if errorHandler.cb(exn) == ERROR_RAISE:
                raise exn

        # Wait for progress thread to finish
        with self.pct_lock:
            self.pct = 100
        threadMgr.wait(THREAD_LIVE_PROGRESS)

        # Live needs to create the rescue image before bootloader is written
        for kernel in self.kernelVersionList:
            log.info("Generating rescue image for %s", kernel)
            util.execInSysroot("new-kernel-pkg", ["--rpmposttrans", kernel])
    def install(self):
        """ Install the payload if it is a tar.
            Otherwise fall back to rsync of INSTALL_TREE
        """
        # If it doesn't look like a tarfile use the super's install()
        if not self.is_tarfile:
            super(LiveImageKSPayload, self).install()
            return

        # Use 2x the archive's size to estimate the size of the install
        # This is used to drive the progress display
        self.source_size = os.stat(self.image_path)[stat.ST_SIZE] * 2

        self.pct_lock = Lock()
        self.pct = 0
        threadMgr.add(AnacondaThread(name=THREAD_LIVE_PROGRESS,
                                     target=self.progress))

        cmd = "tar"
        # preserve: ACL's, xattrs, and SELinux context
        args = ["--selinux", "--acls", "--xattrs", "--xattrs-include", "*",
                "--exclude", "/dev/", "--exclude", "/proc/",
                "--exclude", "/sys/", "--exclude", "/run/", "--exclude", "/boot/*rescue*",
                "--exclude", "/etc/machine-id", "-xaf", self.image_path, "-C", iutil.getSysroot()]
        try:
            rc = iutil.execWithRedirect(cmd, args)
        except (OSError, RuntimeError) as e:
            msg = None
            err = str(e)
            log.error(err)
        else:
            err = None
            msg = "%s exited with code %d" % (cmd, rc)
            log.info(msg)

        if err:
            exn = PayloadInstallError(err or msg)
            if errorHandler.cb(exn) == ERROR_RAISE:
                raise exn

        # Wait for progress thread to finish
        with self.pct_lock:
            self.pct = 100
        threadMgr.wait(THREAD_LIVE_PROGRESS)

        # Live needs to create the rescue image before bootloader is written
        for kernel in self.kernelVersionList:
            log.info("Generating rescue image for %s", kernel)
            iutil.execInSysroot("new-kernel-pkg",
                                ["--rpmposttrans", kernel])
    def install(self):
        """ Install the payload. """

        if self.source_size <= 0:
            raise PayloadInstallError("Nothing to install")

        self.pct_lock = Lock()
        self.pct = 0
        threadMgr.add(AnacondaThread(name=THREAD_LIVE_PROGRESS,
                                     target=self.progress))

        cmd = "rsync"
        # preserve: permissions, owners, groups, ACL's, xattrs, times,
        #           symlinks, hardlinks
        # go recursively, include devices and special files, don't cross
        # file system boundaries
        args = ["-pogAXtlHrDx", "--exclude", "/dev/", "--exclude", "/proc/",
                "--exclude", "/sys/", "--exclude", "/run/", "--exclude", "/boot/*rescue*",
                "--exclude", "/etc/machine-id", INSTALL_TREE+"/", iutil.getSysroot()]
        try:
            rc = iutil.execWithRedirect(cmd, args)
        except (OSError, RuntimeError) as e:
            msg = None
            err = str(e)
            log.error(err)
        else:
            err = None
            msg = "%s exited with code %d" % (cmd, rc)
            log.info(msg)

        if err or rc == 12:
            exn = PayloadInstallError(err or msg)
            if errorHandler.cb(exn) == ERROR_RAISE:
                raise exn

        # Wait for progress thread to finish
        with self.pct_lock:
            self.pct = 100
        threadMgr.wait(THREAD_LIVE_PROGRESS)

        # Live needs to create the rescue image before bootloader is written
        if not os.path.exists(iutil.getSysroot() + "/usr/sbin/new-kernel-pkg"):
            log.error("new-kernel-pkg does not exist - grubby wasn't installed?  skipping")
            return

        for kernel in self.kernelVersionList:
            log.info("Generating rescue image for %s", kernel)
            iutil.execInSysroot("new-kernel-pkg",
                                ["--rpmposttrans", kernel])
예제 #26
0
    def run_task(self):
        """Run the DBus task."""
        try:
            # Report the progress messages.
            self._task_proxy.ProgressChanged.connect(self._show_message)

            # Run the task.
            sync_run_task(self._task_proxy)
        except DBusError as e:
            # Handle a remote error.
            if errorHandler.cb(e) == ERROR_RAISE:
                raise
        finally:
            # Disconnect from the signal.
            self._task_proxy.ProgressChanged.disconnect()
예제 #27
0
파일: users.py 프로젝트: dougsland/anaconda
def cryptPassword(password, algo=None):
    salts = {'md5': crypt.METHOD_MD5,
             'sha256': crypt.METHOD_SHA256,
             'sha512': crypt.METHOD_SHA512}

    if algo not in salts:
        algo = 'sha512'

    cryptpw = crypt.crypt(password, salts[algo])
    if cryptpw is None:
        exn = PasswordCryptError(algo=algo)
        if errorHandler.cb(exn) == ERROR_RAISE:
            raise exn

    return cryptpw
예제 #28
0
def cryptPassword(password, algo=None):
    salts = {'md5': crypt.METHOD_MD5,
             'sha256': crypt.METHOD_SHA256,
             'sha512': crypt.METHOD_SHA512}

    if algo not in salts:
        algo = 'sha512'

    cryptpw = crypt.crypt(password, salts[algo])
    if cryptpw is None:
        exn = PasswordCryptError(algo=algo)
        if errorHandler.cb(exn) == ERROR_RAISE:
            raise exn

    return cryptpw
예제 #29
0
    def install(self):
        """ Install the payload if it is a tar.
            Otherwise fall back to rsync of INSTALL_TREE
        """
        # If it doesn't look like a tarfile use the super's install()
        if not self.is_tarfile:
            super().install()
            return

        # Use 2x the archive's size to estimate the size of the install
        # This is used to drive the progress display
        self.source_size = os.stat(self.image_path)[stat.ST_SIZE] * 2

        self.pct_lock = Lock()
        self.pct = 0
        threadMgr.add(
            AnacondaThread(name=THREAD_LIVE_PROGRESS, target=self.progress))

        cmd = "tar"
        # preserve: ACL's, xattrs, and SELinux context
        args = [
            "--numeric-owner", "--selinux", "--acls", "--xattrs",
            "--xattrs-include", "*", "--exclude", "dev/*", "--exclude",
            "proc/*", "--exclude", "tmp/*", "--exclude", "sys/*", "--exclude",
            "run/*", "--exclude", "boot/*rescue*", "--exclude", "boot/loader",
            "--exclude", "boot/efi/loader", "--exclude", "etc/machine-id",
            "-xaf", self.image_path, "-C", conf.target.system_root
        ]
        try:
            rc = util.execWithRedirect(cmd, args)
        except (OSError, RuntimeError) as e:
            msg = None
            err = str(e)
            log.error(err)
        else:
            err = None
            msg = "%s exited with code %d" % (cmd, rc)
            log.info(msg)

        if err:
            exn = PayloadInstallError(err or msg)
            if errorHandler.cb(exn) == ERROR_RAISE:
                raise exn

        # Wait for progress thread to finish
        with self.pct_lock:
            self.pct = 100
        threadMgr.wait(THREAD_LIVE_PROGRESS)
예제 #30
0
def crypt_password(password):
    """Crypt a password.

    Process a password with appropriate salted one-way algorithm.

    :param str password: password to be crypted
    :returns: crypted representation of the original password
    :rtype: str
    """
    cryptpw = crypt.crypt(password, crypt.METHOD_SHA512)
    if cryptpw is None:
        exn = PasswordCryptError(algo=crypt.METHOD_SHA512)
        if errorHandler.cb(exn) == ERROR_RAISE:
            raise exn

    return cryptpw
예제 #31
0
    def setup(self):
        """ Check the availability and size of the image.
        """
        super().setup()

        if self.data.liveimg.url.startswith("file://"):
            error = self._setup_file_image()
        else:
            error = self._setup_url_image()

        if error:
            exn = PayloadInstallError(str(error))
            if errorHandler.cb(exn) == ERROR_RAISE:
                raise exn

        log.debug("liveimg size is %s", self._min_size)
예제 #32
0
def turn_on_filesystems(storage, callbacks=None):
    """Perform installer-specific activation of storage configuration.

    :param storage: the storage object
    :type storage: :class:`~.storage.InstallerStorage`
    :param callbacks: callbacks to be invoked when actions are executed
    :type callbacks: return value of the :func:`blivet.callbacks.create_new_callbacks_register`
    """
    storage.devicetree.teardown_all()

    try:
        storage.do_it(callbacks)
    except (FSResizeError, FormatResizeError) as e:
        if error_handler.cb(e) == ERROR_RAISE:
            raise

    storage.turn_on_swap()
예제 #33
0
    def run_task(self):
        """Runs the task (callable) assigned to this Task class instance.

        This method is mainly aimed at lightweight Task subclassing, without the
        need to reimplement the full start() method with all the signal triggers and
        related machinery.
        """
        if self._task:
            try:
                # Run the task.
                self._task(*self._task_args, **self._task_kwargs)
            except Exception as e:  # pylint: disable=broad-except
                # Handle an error.
                if errorHandler.cb(e) == ERROR_RAISE:
                    raise
        else:
            log.error("Task %s callable not set.", self.name)
예제 #34
0
    def setup(self, storage, instClass):
        """ Check the availability and size of the image.
        """
        # This is on purpose, we don't want to call LiveImagePayload's setup method.
        ImagePayload.setup(self, storage, instClass)

        if self.data.method.url.startswith("file://"):
            error = self._setup_file_image()
        else:
            error = self._setup_url_image()

        if error:
            exn = PayloadInstallError(str(error))
            if errorHandler.cb(exn) == ERROR_RAISE:
                raise exn

        log.debug("liveimg size is %s", self._min_size)
    def setup(self, storage, instClass):
        """ Check the availability and size of the image.
        """
        # This is on purpose, we don't want to call LiveImagePayload's setup method.
        ImagePayload.setup(self, storage, instClass)

        if self.data.method.url.startswith("file://"):
            error = self._setup_file_image()
        else:
            error = self._setup_url_image()

        if error:
            exn = PayloadInstallError(str(error))
            if errorHandler.cb(exn) == ERROR_RAISE:
                raise exn

        log.debug("liveimg size is %s", self._min_size)
예제 #36
0
    def setup(self, storage, instClass):
        super(LiveImagePayload, self).setup(storage, instClass)

        # Mount the live device and copy from it instead of the overlay at /
        osimg = storage.devicetree.getDeviceByPath(self.data.method.partition)
        if not stat.S_ISBLK(os.stat(osimg.path)[stat.ST_MODE]):
            exn = PayloadSetupError("%s is not a valid block device" % (self.data.method.partition,))
            if errorHandler.cb(exn) == ERROR_RAISE:
                raise exn
        rc = blivet.util.mount(osimg.path, INSTALL_TREE, fstype="auto", options="ro")
        if rc != 0:
            raise PayloadInstallError("Failed to mount the install tree")

        # Grab the kernel version list now so it's available after umount
        self._updateKernelVersionList()

        source = iutil.eintr_retry_call(os.statvfs, INSTALL_TREE)
        self.source_size = source.f_frsize * (source.f_blocks - source.f_bfree)
예제 #37
0
    def setup(self):
        """ Check the availability and size of the image.
        """
        # This is on purpose, we don't want to call LiveImagePayload's setup method.
        # FIXME: this should be solved on a inheritance level not like this
        Payload.setup(self)

        if self.data.method.url.startswith("file://"):
            error = self._setup_file_image()
        else:
            error = self._setup_url_image()

        if error:
            exn = PayloadInstallError(str(error))
            if errorHandler.cb(exn) == ERROR_RAISE:
                raise exn

        log.debug("liveimg size is %s", self._min_size)
예제 #38
0
def turn_on_filesystems(storage, callbacks=None):
    """Perform installer-specific activation of storage configuration.

    :param storage: the storage object
    :type storage: :class:`~.storage.InstallerStorage`
    :param callbacks: callbacks to be invoked when actions are executed
    :type callbacks: return value of the :func:`blivet.callbacks.create_new_callbacks_register`
    """
    storage.devicetree.teardown_all()

    try:
        storage.do_it(callbacks)
        _setup_bootable_devices(storage)
        storage.dump_state("final")
    except (FSResizeError, FormatResizeError) as e:
        if error_handler.cb(e) == ERROR_RAISE:
            raise

    storage.turn_on_swap()
예제 #39
0
    def _handleMissing(self, exn):
        log.info("%s %s" % (self.__class__.__name__, inspect.stack()[0][3]))
        if self.data.packages.handleMissing == KS_MISSING_IGNORE:
            return

        # If we're doing non-interactive ks install, raise CmdlineError,
        # otherwise the system will just reboot automatically
        if flags.automatedInstall and not flags.ksprompt:
            errtxt = _("CmdlineError: Missing package: %s") % str(exn)
            log.error(errtxt)
            raise CmdlineError(errtxt)
        elif errorHandler.cb(exn) == ERROR_RAISE:
            # The progress bar polls kind of slowly, thus installation could
            # still continue for a bit before the quit message is processed.
            # Let's sleep forever to prevent any further actions and wait for
            # the main thread to quit the process.
            progressQ.send_quit(1)
            while True:
                time.sleep(100000)
예제 #40
0
    def setup(self, storage, instClass):
        super(LiveImagePayload, self).setup(storage, instClass)

        # Mount the live device and copy from it instead of the overlay at /
        osimg = storage.devicetree.getDeviceByPath(self.data.method.partition)
        if not stat.S_ISBLK(os.stat(osimg.path)[stat.ST_MODE]):
            exn = PayloadSetupError("%s is not a valid block device" %
                                    (self.data.method.partition, ))
            if errorHandler.cb(exn) == ERROR_RAISE:
                raise exn
        rc = blivet.util.mount(osimg.path,
                               INSTALL_TREE,
                               fstype="auto",
                               options="ro")
        if rc != 0:
            raise PayloadInstallError("Failed to mount the install tree")

        source = iutil.eintr_retry_call(os.statvfs, INSTALL_TREE)
        self.source_size = source.f_frsize * (source.f_blocks - source.f_bfree)
예제 #41
0
    def install(self):
        progress_message(N_('Starting package installation process'))

        # Get the packages configuration and selection data.
        configuration = self.get_packages_configuration()
        selection = self.get_packages_selection()

        # Add the rpm macros to the global transaction environment
        task = SetRPMMacrosTask(configuration)
        task.run()

        try:
            # Resolve packages.
            task = ResolvePackagesTask(self._dnf_manager, selection)
            task.run()
        except NonCriticalInstallationError as e:
            # FIXME: This is a temporary workaround.
            # Allow users to handle the error. If they don't want
            # to continue with the installation, raise a different
            # exception to make sure that we will not run the error
            # handler again.
            if error_handler.cb(e) == ERROR_RAISE:
                raise InstallationError(str(e)) from e

        # Set up the download location.
        task = PrepareDownloadLocationTask(self._dnf_manager)
        task.run()

        # Download the packages.
        task = DownloadPackagesTask(self._dnf_manager)
        task.progress_changed_signal.connect(self._progress_cb)
        task.run()

        # Install the packages.
        task = InstallPackagesTask(self._dnf_manager)
        task.progress_changed_signal.connect(self._progress_cb)
        task.run()

        # Clean up the download location.
        task = CleanUpDownloadLocationTask(self._dnf_manager)
        task.run()
예제 #42
0
    def setup(self, storage, instClass):
        """ Check the availability and size of the image.
        """
        # This is on purpose, we don't want to call LiveImagePayload's setup method.
        ImagePayload.setup(self, storage, instClass)

        self._proxies = {}
        if self.data.method.proxy:
            try:
                proxy = ProxyString(self.data.method.proxy)
                self._proxies = {"http": proxy.url,
                                 "https": proxy.url}
            except ProxyStringError as e:
                log.info("Failed to parse proxy for liveimg --proxy=\"%s\": %s",
                         self.data.method.proxy, e)

        error = None
        try:
            req = urllib.urlopen(self.data.method.url, proxies=self._proxies)
        except IOError as e:
            log.error("Error opening liveimg: %s", e)
            error = e
        else:
            # If it is a http request we need to check the code
            method = self.data.method.url.split(":", 1)[0]
            if method.startswith("http") and req.getcode() != 200:
                error = "http request returned %s" % req.getcode()

        if error:
            exn = PayloadInstallError(str(error))
            if errorHandler.cb(exn) == ERROR_RAISE:
                raise exn

        # At this point we know we can get the image and what its size is
        # Make a guess as to minimum size needed:
        # Enough space for image and image * 3
        if req.info().get("content-length"):
            self._min_size = int(req.info().get("content-length")) * 4

        log.debug("liveimg size is %s", self._min_size)
예제 #43
0
파일: users.py 프로젝트: rtruxal/anaconda
def cryptPassword(password, algo=None):
    salts = {"md5": "$1$", "sha256": "$5$", "sha512": "$6$"}
    saltlen = 2

    if algo is None:
        algo = "sha512"

    if algo == "md5" or algo == "sha256" or algo == "sha512":
        saltlen = 16

    saltstr = salts[algo]

    for _i in range(saltlen):
        saltstr = saltstr + random.choice(string.ascii_letters + string.digits + "./")

    cryptpw = crypt.crypt(password, saltstr)
    if cryptpw is None:
        exn = PasswordCryptError(algo=algo)
        if errorHandler.cb(exn) == ERROR_RAISE:
            raise exn

    return cryptpw
예제 #44
0
def install_boot_loader(storage):
    """Do the final write of the boot loader.

    :param storage: an instance of the storage
    """
    log.debug("Installing the boot loader.")

    stage1_device = storage.bootloader.stage1_device
    log.info("boot loader stage1 target device is %s", stage1_device.name)

    stage2_device = storage.bootloader.stage2_device
    log.info("boot loader stage2 target device is %s", stage2_device.name)

    # FIXME: do this from elsewhere?
    storage.bootloader.set_boot_args(storage)

    try:
        storage.bootloader.write()
    except BootLoaderError as e:
        log.error("bootloader.write failed: %s", e)
        if errorHandler.cb(e) == ERROR_RAISE:
            raise
예제 #45
0
    def setup(self, storage):
        super().setup(storage)

        # Mount the live device and copy from it instead of the overlay at /
        osimg = storage.devicetree.get_device_by_path(self.data.method.partition)
        if not osimg:
            raise PayloadInstallError("Unable to find osimg for %s" % self.data.method.partition)

        if not stat.S_ISBLK(os.stat(osimg.path)[stat.ST_MODE]):
            exn = PayloadSetupError("%s is not a valid block device" %
                                    (self.data.method.partition,))
            if errorHandler.cb(exn) == ERROR_RAISE:
                raise exn
        rc = payload_utils.mount(osimg.path, INSTALL_TREE, fstype="auto", options="ro")
        if rc != 0:
            raise PayloadInstallError("Failed to mount the install tree")

        # Grab the kernel version list now so it's available after umount
        self._update_kernel_version_list()

        source = os.statvfs(INSTALL_TREE)
        self.source_size = source.f_frsize * (source.f_blocks - source.f_bfree)
예제 #46
0
파일: utils.py 프로젝트: rvykydal/anaconda
def try_populate_devicetree(devicetree):
    """
    Try to populate the given devicetree while catching errors and dealing with
    some special ones in a nice way (giving user chance to do something about
    them).

    :param devicetree: devicetree to try to populate
    :type decicetree: :class:`blivet.devicetree.DeviceTree`

    """

    while True:
        try:
            devicetree.populate()
        except StorageError as e:
            if errorHandler.cb(e) == ERROR_RAISE:
                raise
            else:
                continue
        else:
            break

    return
예제 #47
0
def cryptPassword(password, algo=None):
    salts = {'md5': '$1$', 'sha256': '$5$', 'sha512': '$6$'}
    saltlen = 2

    if algo is None:
        algo = 'sha512'

    if algo == 'md5' or algo == 'sha256' or algo == 'sha512':
        saltlen = 16

    saltstr = salts[algo]

    for _i in range(saltlen):
        saltstr = saltstr + random.choice(string.ascii_letters +
                                          string.digits + './')

    cryptpw = crypt.crypt(password, saltstr)
    if cryptpw is None:
        exn = PasswordCryptError(algo=algo)
        if errorHandler.cb(exn) == ERROR_RAISE:
            raise exn

    return cryptpw
예제 #48
0
def reset_storage(storage, scan_all=False, teardown=False, retry=True):
    """Reset the storage model.

    :param storage: an instance of the Blivet's storage object
    :param scan_all: should we scan all devices in the system?
    :param teardown: should we teardown devices in the current device tree?
    :param retry: should we allow to retry the reset?
    """
    # Deactivate all devices.
    if teardown:
        try:
            storage.devicetree.teardown_all()
        except Exception:  # pylint: disable=broad-except
            log_exception_info(log.error, "Failure tearing down device tree.")

    # Clear the exclusive disks to scan all devices in the system.
    if scan_all:
        disk_select_proxy = STORAGE.get_proxy(DISK_SELECTION)
        disk_select_proxy.SetExclusiveDisks([])

    # Do the reset.
    while True:
        try:
            _reset_storage(storage)
        except StorageError as e:
            # Is the retry allowed?
            if not retry:
                raise
            # Does the user want to retry?
            elif error_handler.cb(e) == ERROR_RAISE:
                raise
            # Retry the storage reset.
            else:
                continue
        else:
            # No need to retry.
            break
예제 #49
0
def findFirstIsoImage(path):
    """
    Find the first iso image in path
    This also supports specifying a specific .iso image

    Returns the basename of the image
    """
    try:
        os.stat(path)
    except OSError:
        return None

    arch = _arch

    if os.path.isfile(path) and path.endswith(".iso"):
        files = [os.path.basename(path)]
        path = os.path.dirname(path)
    else:
        files = os.listdir(path)

    for fn in files:
        what = path + '/' + fn
        log.debug("Checking %s", what)
        if not isys.isIsoImage(what):
            continue

        log.debug("mounting %s on /mnt/install/cdimage", what)
        try:
            blivet.util.mount(what, "/mnt/install/cdimage", fstype="iso9660", options="ro")
        except OSError:
            continue

        if not os.access("/mnt/install/cdimage/.discinfo", os.R_OK):
            blivet.util.umount("/mnt/install/cdimage")
            continue

        log.debug("Reading .discinfo")
        f = open("/mnt/install/cdimage/.discinfo")
        f.readline() # skip timestamp
        f.readline() # skip release description
        discArch = f.readline().strip() # read architecture
        f.close()

        log.debug("discArch = %s", discArch)
        if discArch != arch:
            log.warning("findFirstIsoImage: architectures mismatch: %s, %s",
                        discArch, arch)
            blivet.util.umount("/mnt/install/cdimage")
            continue

        # If there's no repodata, there's no point in trying to
        # install from it.
        if not os.access("/mnt/install/cdimage/repodata", os.R_OK):
            log.warning("%s doesn't have repodata, skipping", what)
            blivet.util.umount("/mnt/install/cdimage")
            continue

        # warn user if images appears to be wrong size
        if os.stat(what)[stat.ST_SIZE] % 2048:
            log.warning("%s appears to be corrupted", what)
            exn = InvalidImageSizeError("size is not a multiple of 2048 bytes", what)
            if errorHandler.cb(exn) == ERROR_RAISE:
                raise exn

        log.info("Found disc at %s", fn)
        blivet.util.umount("/mnt/install/cdimage")
        return fn

    return None
    def preInstall(self, *args, **kwargs):
        """ Get image and loopback mount it.

            This is called after partitioning is setup, we now have space to
            grab the image. If it is a network source Download it to sysroot
            and provide feedback during the download (using urlgrabber
            callback).

            If it is a file:// source then use the file directly.
        """
        error = None
        if self.data.method.url.startswith("file://"):
            self.image_path = self.data.method.url[7:]
        else:
            error = self._preInstall_url_image()

        if error:
            exn = PayloadInstallError(str(error))
            if errorHandler.cb(exn) == ERROR_RAISE:
                raise exn

        # Used to make install progress % look correct
        self._adj_size = os.stat(self.image_path)[stat.ST_SIZE]

        if self.data.method.checksum:
            progressQ.send_message(_("Checking image checksum"))
            sha256 = hashlib.sha256()
            with open(self.image_path, "rb") as f:
                while True:
                    data = f.read(1024*1024)
                    if not data:
                        break
                    sha256.update(data)
            filesum = sha256.hexdigest()
            log.debug("sha256 of %s is %s", self.data.method.url, filesum)

            if lowerASCII(self.data.method.checksum) != filesum:
                log.error("%s does not match checksum.", self.data.method.checksum)
                exn = PayloadInstallError("Checksum of image does not match")
                if errorHandler.cb(exn) == ERROR_RAISE:
                    raise exn

        # If this looks like a tarfile, skip trying to mount it
        if self.is_tarfile:
            return

        # Mount the image and check to see if it is a LiveOS/*.img
        # style squashfs image. If so, move it to IMAGE_DIR and mount the real
        # root image on INSTALL_TREE
        rc = blivet.util.mount(self.image_path, INSTALL_TREE, fstype="auto", options="ro")
        if rc != 0:
            log.error("mount error (%s) with %s", rc, self.image_path)
            exn = PayloadInstallError("mount error %s" % rc)
            if errorHandler.cb(exn) == ERROR_RAISE:
                raise exn

        # Nothing more to mount
        if not os.path.exists(INSTALL_TREE+"/LiveOS"):
            self._updateKernelVersionList()
            return

        # Mount the first .img in the directory on INSTALL_TREE
        img_files = glob.glob(INSTALL_TREE+"/LiveOS/*.img")
        if img_files:
            # move the mount to IMAGE_DIR
            os.makedirs(IMAGE_DIR, 0o755)
            # work around inability to move shared filesystems
            rc = iutil.execWithRedirect("mount",
                                        ["--make-rprivate", "/"])
            if rc == 0:
                rc = iutil.execWithRedirect("mount",
                                            ["--move", INSTALL_TREE, IMAGE_DIR])
            if rc != 0:
                log.error("error %s moving mount", rc)
                exn = PayloadInstallError("mount error %s" % rc)
                if errorHandler.cb(exn) == ERROR_RAISE:
                    raise exn

            img_file = IMAGE_DIR+"/LiveOS/"+os.path.basename(sorted(img_files)[0])
            rc = blivet.util.mount(img_file, INSTALL_TREE, fstype="auto", options="ro")
            if rc != 0:
                log.error("mount error (%s) with %s", rc, img_file)
                exn = PayloadInstallError("mount error %s with %s" % (rc, img_file))
                if errorHandler.cb(exn) == ERROR_RAISE:
                    raise exn

            self._updateKernelVersionList()

            source = iutil.eintr_retry_call(os.statvfs, INSTALL_TREE)
            self.source_size = source.f_frsize * (source.f_blocks - source.f_bfree)
예제 #51
0
    def preInstall(self, *args, **kwargs):
        """ Download image and loopback mount it.

            This is called after partitioning is setup, we now have space
            to grab the image. Download it to ROOT_PATH and provide feedback
            during the download (using urlgrabber callback).
        """
        # Setup urlgrabber and call back to download image to ROOT_PATH
        progress = URLGrabberProgress()
        ugopts = {"ssl_verify_peer": not self.data.method.noverifyssl,
                  "ssl_verify_host": not self.data.method.noverifyssl,
                  "proxies" : self._proxies,
                  "progress_obj" : progress,
                  "copy_local" : True}

        error = None
        try:
            ug = URLGrabber()
            ug.urlgrab(self.data.method.url, self.image_path, **ugopts)
        except URLGrabError as e:
            log.error("Error downloading liveimg: %s", e)
            error = e
        else:
            if not os.path.exists(self.image_path):
                error = "Failed to download %s, file doesn't exist" % self.data.method.url
                log.error(error)

        if error:
            exn = PayloadInstallError(str(error))
            if errorHandler.cb(exn) == ERROR_RAISE:
                raise exn

        # Used to make install progress % look correct
        self._adj_size = os.stat(self.image_path)[stat.ST_SIZE]

        if self.data.method.checksum:
            progressQ.send_message(_("Checking image checksum"))
            sha256 = hashlib.sha256()
            with open(self.image_path, "rb") as f:
                while True:
                    data = f.read(1024*1024)
                    if not data:
                        break
                    sha256.update(data)
            filesum = sha256.hexdigest()
            log.debug("sha256 of %s is %s", self.data.method.url, filesum)

            if lowerASCII(self.data.method.checksum) != filesum:
                log.error("%s does not match checksum.", self.data.method.checksum)
                exn = PayloadInstallError("Checksum of image does not match")
                if errorHandler.cb(exn) == ERROR_RAISE:
                    raise exn

        # Mount the image and check to see if it is a LiveOS/*.img
        # style squashfs image. If so, move it to IMAGE_DIR and mount the real
        # root image on INSTALL_TREE
        blivet.util.mount(self.image_path, INSTALL_TREE, fstype="auto", options="ro")
        if os.path.exists(INSTALL_TREE+"/LiveOS"):
            # Find the first .img in the directory and mount that on INSTALL_TREE
            img_files = glob.glob(INSTALL_TREE+"/LiveOS/*.img")
            if img_files:
                img_file = os.path.basename(sorted(img_files)[0])

                # move the mount to IMAGE_DIR
                os.makedirs(IMAGE_DIR, 0755)
                # work around inability to move shared filesystems
                iutil.execWithRedirect("mount",
                                       ["--make-rprivate", "/"])
                iutil.execWithRedirect("mount",
                                       ["--move", INSTALL_TREE, IMAGE_DIR])
                blivet.util.mount(IMAGE_DIR+"/LiveOS/"+img_file, INSTALL_TREE,
                                  fstype="auto", options="ro")
예제 #52
0
파일: image.py 프로젝트: zhangsju/anaconda
def findFirstIsoImage(path):
    """
    Find the first iso image in path
    This also supports specifying a specific .iso image

    Returns the basename of the image
    """
    try:
        os.stat(path)
    except OSError:
        return None

    arch = _arch
    mount_path = "/mnt/install/cdimage"
    discinfo_path = os.path.join(mount_path, ".discinfo")

    if os.path.isfile(path) and path.endswith(".iso"):
        files = [os.path.basename(path)]
        path = os.path.dirname(path)
    else:
        files = os.listdir(path)

    for fn in files:
        what = os.path.join(path, fn)
        log.debug("Checking %s", what)
        if not isys.isIsoImage(what):
            continue

        log.debug("mounting %s on %s", what, mount_path)
        try:
            blivet.util.mount(what, mount_path, fstype="iso9660", options="ro")
        except OSError:
            continue

        if not os.access(discinfo_path, os.R_OK):
            blivet.util.umount(mount_path)
            continue

        log.debug("Reading .discinfo")
        disc_info = DiscInfo()

        try:
            disc_info.load(discinfo_path)
            disc_arch = disc_info.arch
        except Exception as ex:  # pylint: disable=broad-except
            log.warning(".discinfo file can't be loaded: %s", ex)
            continue

        log.debug("discArch = %s", disc_arch)
        if disc_arch != arch:
            log.warning("findFirstIsoImage: architectures mismatch: %s, %s",
                        disc_arch, arch)
            blivet.util.umount(mount_path)
            continue

        # If there's no repodata, there's no point in trying to
        # install from it.
        if not _check_repodata(mount_path):
            log.warning("%s doesn't have repodata, skipping", what)
            blivet.util.umount(mount_path)
            continue

        # warn user if images appears to be wrong size
        if os.stat(what)[stat.ST_SIZE] % 2048:
            log.warning("%s appears to be corrupted", what)
            exn = InvalidImageSizeError("size is not a multiple of 2048 bytes", what)
            if errorHandler.cb(exn) == ERROR_RAISE:
                raise exn

        log.info("Found disc at %s", fn)
        blivet.util.umount(mount_path)
        return fn

    return None
예제 #53
0
파일: fsset.py 프로젝트: rvykydal/anaconda
    def mount_filesystems(self, root_path="", read_only=None, skip_root=False):
        """Mount the system's filesystems.

        :param str root_path: the root directory for this filesystem
        :param read_only: read only option str for this filesystem
        :type read_only: str or None
        :param bool skip_root: whether to skip mounting the root filesystem
        """
        devices = list(self.mountpoints.values()) + self.swap_devices
        devices.extend([self.dev, self.devshm, self.devpts, self.sysfs,
                        self.proc, self.selinux, self.usb, self.run])
        if isinstance(_platform, EFI):
            devices.append(self.efivars)
        devices.sort(key=lambda d: getattr(d.format, "mountpoint", ""))

        for device in devices:
            if not device.format.mountable or not device.format.mountpoint:
                continue

            if skip_root and device.format.mountpoint == "/":
                continue

            options = device.format.options
            if "noauto" in options.split(","):
                continue

            if device.format.type == "bind" and device not in [self.dev, self.run]:
                # set up the DirectoryDevice's parents now that they are
                # accessible
                #
                # -- bind formats' device and mountpoint are always both
                #    under the chroot. no exceptions. none, damn it.
                target_dir = "%s/%s" % (root_path, device.path)
                parent = get_containing_device(target_dir, self.devicetree)
                if not parent:
                    log.error("cannot determine which device contains "
                              "directory %s", device.path)
                    device.parents = []
                    self.devicetree._remove_device(device)
                    continue
                else:
                    device.parents = [parent]

            try:
                device.setup()
            except Exception as e:  # pylint: disable=broad-except
                log_exception_info(fmt_str="unable to set up device %s", fmt_args=[device])
                if error_handler.cb(e) == ERROR_RAISE:
                    raise
                else:
                    continue

            if read_only:
                options = "%s,%s" % (options, read_only)

            try:
                device.format.setup(options=options,
                                    chroot=root_path)
            except Exception as e:  # pylint: disable=broad-except
                log_exception_info(log.error, "error mounting %s on %s", [device.path, device.format.mountpoint])
                if error_handler.cb(e) == ERROR_RAISE:
                    raise

        self.active = True