Esempio n. 1
0
def get_snapshot_device(request, devicetree):
    """Get the ThinLV snapshot device.

    :param request: a snapshot request
    :param devicetree: a device tree to look up devices
    :return: a model of the ThinLV snapshot
    """
    snap_name = request.name.replace('-', '--')
    origin = request.origin.replace('-', '--').replace('/', '-')
    origin_dev = devicetree.get_device_by_name(origin)
    log.debug("Snapshot: name %s has origin %s", request.name, origin_dev)

    if origin_dev is None:
        raise KickstartParseError(_("Snapshot: origin \"%s\" doesn't exists!")
                                  % request.origin, lineno=request.lineno)

    if not origin_dev.is_thin_lv:
        raise KickstartParseError(_("Snapshot: origin \"%(origin)s\" of snapshot "
                                    "\"%(name)s\" is not a valid thin LV device.")
                                  % {"origin": request.origin, "name": request.name},
                                  lineno=request.lineno)

    if devicetree.get_device_by_name("%s-%s" % (origin_dev.vg.name, snap_name)):
        raise KickstartParseError(_("Snapshot %s already exists.") % request.name,
                                  lineno=request.lineno)
    try:
        return LVMLogicalVolumeDevice(
            name=request.name,
            parents=[origin_dev.pool],
            seg_type="thin",
            origin=origin_dev
        )
    except ValueError as e:
        raise KickstartParseError(str(e), lineno=request.lineno)
Esempio n. 2
0
def verify_s390_constraints(storage, constraints, report_error, report_warning):
    """ Verify constraints for s390x.

        Prevent users from installing on s390x with (a) no /boot volume, (b) the
        root volume on LVM, (c) the root volume not restricted to a single PV,
        and (d) LDL DASD disks.

        NOTE: There is not really a way for users to create a / volume
        restricted to a single PV.  The backend support is there, but there are
        no UI hook-ups to drive that functionality, but I do not personally
        care.  --dcantrell

        :param storage: a storage to check
        :param constraints: a dictionary of constraints
        :param report_error: a function for error reporting
        :param report_warning: a function for warning reporting
    """
    if not arch.is_s390():
        return

    root = storage.fsset.root_device
    if '/boot' not in storage.mountpoints and root:
        if root.type == 'lvmlv' and not root.single_pv:
            report_error(_("This platform requires /boot on a dedicated "
                           "partition or logical volume. If you do not "
                           "want a /boot volume, you must place / on a "
                           "dedicated non-LVM partition."))

    for disk in storage.disks:
        if disk.type == "dasd" and blockdev.s390.dasd_is_ldl(disk.name):
            report_error(_("The LDL DASD disk {name} ({busid}) cannot be used "
                           "for the installation. Please format it.")
                         .format(name="/dev/" + disk.name, busid=disk.busid))
Esempio n. 3
0
    def is_valid_stage2_device(self, device, linux=True, non_linux=False):
        valid = super().is_valid_stage2_device(device, linux, non_linux)

        # If the stage2 device is on a raid1, check that the stage1 device is also redundant,
        # either by also being part of an array or by being a disk (which is expanded
        # to every disk in the array by install_targets).
        if self.stage1_device and self.stage2_device and \
                self.stage2_device.type == "mdarray" and \
                self.stage2_device.level in self.stage2_raid_levels and \
                self.stage1_device.type != "mdarray":
            if not self.stage1_device.is_disk:
                msg = _("boot loader stage2 device %(stage2dev)s is on a multi-disk array, "
                        "but boot loader stage1 device %(stage1dev)s is not. "
                        "A drive failure in %(stage2dev)s could render the system unbootable.") % \
                        {"stage1dev": self.stage1_device.name,
                         "stage2dev": self.stage2_device.name}
                self.warnings.append(msg)
            elif not self.stage2_device.depends_on(self.stage1_device):
                msg = _("boot loader stage2 device %(stage2dev)s is on a multi-disk array, "
                        "but boot loader stage1 device %(stage1dev)s is not part of this array. "
                        "The stage1 boot loader will only be installed to a single drive.") % \
                        {"stage1dev": self.stage1_device.name,
                         "stage2dev": self.stage2_device.name}
                self.warnings.append(msg)

        return valid
def validate_mountpoint(mountpoint, used_mountpoints, strict=True):
    if strict:
        fake_mountpoints = []
    else:
        fake_mountpoints = ["swap", "biosboot", "prepboot"]

    if mountpoint in used_mountpoints:
        return _("That mount point is already in use. Try something else?")
    elif not mountpoint:
        return _("Please enter a valid mount point.")
    elif mountpoint in system_mountpoints:
        return _("That mount point is invalid. Try something else?")
    elif (lowerASCII(mountpoint) not in fake_mountpoints and
          ((len(mountpoint) > 1 and mountpoint.endswith("/")) or
           not mountpoint.startswith("/") or
           " " in mountpoint or
           re.search(r'/\.*/', mountpoint) or
           re.search(r'/\.+$', mountpoint))):
        # - does not end with '/' unless mountpoint _is_ '/'
        # - starts with '/' except for "swap", &c
        # - does not contain spaces
        # - does not contain pairs of '/' enclosing zero or more '.'
        # - does not end with '/' followed by one or more '.'
        return _("That mount point is invalid. Try something else?")
    else:
        return ""
    def refresh(self, mountpoint, device, checkbox_text = "", snapshots=False, bootpart = False):
        """ Show confirmation dialog with the optional checkbox. If the
            `checkbox_text` for the checkbox is not set then the checkbox
            will not be showed.

            :param str mountpoint: Mountpoint for device.
            :param str device: Name of the device.
            :param str checkbox_text: Text for checkbox. If nothing set do
                                      not display the checkbox.
            :param bool snapshot: If true warn user he's going to delete snapshots too.
        """
        super().refresh()
        label = self.builder.get_object("confirmLabel")

        if checkbox_text:
            self._optional_checkbox.set_label(checkbox_text)
        else:
            self._optional_checkbox.hide()

        if mountpoint:
            txt = "%s (%s)" % (mountpoint, device)
        else:
            txt = device

        if bootpart:
            label_text = _("%s may be a system boot partition! Deleting it may break other operating systems. Are you sure you want to delete it?") % txt
        elif not snapshots:
            label_text = _("Are you sure you want to delete all of the data on %s?") % txt
        else:
            label_text = _("Are you sure you want to delete all of the data on %s, including snapshots and/or subvolumes?") % txt

        label.set_text(label_text)
Esempio n. 6
0
def verify_swap(storage, constraints, report_error, report_warning):
    """ Verify the existence of swap.

    :param storage: a storage to check
    :param constraints: a dictionary of constraints
    :param report_error: a function for error reporting
    :param report_warning: a function for warning reporting
    """
    swaps = storage.fsset.swap_devices

    if not swaps:
        installed = util.total_memory()
        required = Size("%s MiB" % (constraints[STORAGE_MIN_RAM] + isys.NO_SWAP_EXTRA_RAM))

        if not constraints[STORAGE_SWAP_IS_RECOMMENDED]:
            if installed < required:
                report_warning(_("You have not specified a swap partition. "
                                 "%(requiredMem)s of memory is recommended to continue "
                                 "installation without a swap partition, but you only "
                                 "have %(installedMem)s.")
                               % {"requiredMem": required, "installedMem": installed})
        else:
            if installed < required:
                report_error(_("You have not specified a swap partition. "
                               "%(requiredMem)s of memory is required to continue "
                               "installation without a swap partition, but you only "
                               "have %(installedMem)s.")
                             % {"requiredMem": required, "installedMem": installed})
            else:
                report_warning(_("You have not specified a swap partition. "
                                 "Although not strictly required in all cases, "
                                 "it will significantly improve performance "
                                 "for most installations."))
Esempio n. 7
0
    def _main_loop_handleException(self, dump_info):
        """
        Helper method with one argument only so that it can be registered
        with run_in_loop to run on idle or called from a handler.

        :type dump_info: an instance of the meh.DumpInfo class

        """

        ty = dump_info.exc_info.type
        value = dump_info.exc_info.value

        if (issubclass(ty, blivet.errors.StorageError) and value.hardware_fault) \
                or (issubclass(ty, OSError) and value.errno == errno.EIO):
            # hardware fault or '[Errno 5] Input/Output error'
            hw_error_msg = _("The installation was stopped due to what "
                             "seems to be a problem with your hardware. "
                             "The exact error message is:\n\n%s.\n\n "
                             "The installer will now terminate.") % str(value)
            self.intf.messageWindow(_("Hardware error occurred"), hw_error_msg)
            sys.exit(0)
        elif isinstance(value, blivet.errors.UnusableConfigurationError):
            sys.exit(0)
        elif isinstance(value, NonInteractiveError):
            sys.exit(0)
        else:
            super().handleException(dump_info)
            return False
Esempio n. 8
0
    def run_dasdfmt_dialog(self, dasd_formatting):
        """Do DASD formatting if user agrees."""
        # Prepare text of the dialog.
        text = ""
        text += _("The following unformatted or LDL DASDs have been "
                  "detected on your system. You can choose to format them "
                  "now with dasdfmt or cancel to leave them unformatted. "
                  "Unformatted DASDs cannot be used during installation.\n\n")

        text += dasd_formatting.dasds_summary + "\n\n"

        text += _("Warning: All storage changes made using the installer will "
                  "be lost when you choose to format.\n\nProceed to run dasdfmt?\n")

        # Run the dialog.
        question_window = YesNoDialog(text)
        ScreenHandler.push_screen_modal(question_window)
        if not question_window.answer:
            return None

        print(_("This may take a moment."), flush=True)

        # Do the DASD formatting.
        dasd_formatting.report.connect(self._show_dasdfmt_report)
        dasd_formatting.run(self.storage, self.data)
        dasd_formatting.report.disconnect(self._show_dasdfmt_report)

        self.update_disks()
Esempio n. 9
0
    def status(self):
        kickstart_timezone = self._timezone_module.proxy.Timezone

        if kickstart_timezone:
            return _("%s timezone") % kickstart_timezone
        else:
            return _("Timezone is not set.")
Esempio n. 10
0
    def initialize(self, actions):
        for (i, action) in enumerate(actions, start=1):
            mountpoint = ""

            if action.type in [ACTION_TYPE_DESTROY, ACTION_TYPE_RESIZE]:
                typeString = """<span foreground='red'>%s</span>""" % \
                        escape_markup(action.type_desc.title())
            else:
                typeString = """<span foreground='green'>%s</span>""" % \
                        escape_markup(action.type_desc.title())
                if action.obj == ACTION_OBJECT_FORMAT:
                    mountpoint = getattr(action.device.format, "mountpoint", "")

            if hasattr(action.device, "description"):
                desc = _("%(description)s (%(deviceName)s)") % {"deviceName": action.device.name,
                                                                "description": action.device.description}
                serial = action.device.serial
            elif hasattr(action.device, "disk"):
                desc = _("%(deviceName)s on %(container)s") % {"deviceName": action.device.name,
                                                               "container": action.device.disk.description}
                serial = action.device.disk.serial
            else:
                desc = action.device.name
                serial = action.device.serial

            self._store.append([i,
                                typeString,
                                action.object_type_string,
                                desc,
                                mountpoint,
                                serial])
Esempio n. 11
0
    def on_updown_ampm_clicked(self, *args):
        self._stop_and_maybe_start_time_updating()

        if self._amPmLabel.get_text() == _("AM"):
            self._amPmLabel.set_text(_("PM"))
        else:
            self._amPmLabel.set_text(_("AM"))
Esempio n. 12
0
    def show_all(self):
        super().show_all()
        from pyanaconda.installation import doInstall, doConfiguration
        from pyanaconda.threading import threadMgr, AnacondaThread

        thread_args = (self.storage, self.payload, self.data, self.instclass)

        threadMgr.add(AnacondaThread(name=THREAD_INSTALL, target=doInstall, args=thread_args))

        # This will run until we're all done with the install thread.
        self._update_progress()

        threadMgr.add(AnacondaThread(name=THREAD_CONFIGURATION, target=doConfiguration, args=thread_args))

        # This will run until we're all done with the configuration thread.
        self._update_progress()

        util.ipmi_report(IPMI_FINISHED)

        if self.instclass.eula_path:
            # Notify user about the EULA (if any).
            print(_("Installation complete"))
            print('')
            print(_("Use of this product is subject to the license agreement found at:"))
            print(self.instclass.eula_path)
            print('')

        # kickstart install, continue automatically if reboot or shutdown selected
        if flags.automatedInstall and self.data.reboot.action in [KS_REBOOT, KS_SHUTDOWN]:
            # Just pretend like we got input, and our input doesn't care
            # what it gets, it just quits.
            raise ExitMainLoop()
Esempio n. 13
0
    def refresh(self, args=None):
        """ Refresh screen. """
        self._load_new_devices()
        NormalTUISpoke.refresh(self, args)

        self._container = ListColumnContainer(1, columns_width=78, spacing=1)

        summary = self._summary_text()
        self.window.add_with_separator(TextWidget(summary))
        hostname = _("Host Name: %s\n") % self._network_module.proxy.Hostname
        self.window.add_with_separator(TextWidget(hostname))
        current_hostname = _("Current host name: %s\n") % self._network_module.proxy.GetCurrentHostname()
        self.window.add_with_separator(TextWidget(current_hostname))

        # if we have any errors, display them
        while len(self.errors) > 0:
            self.window.add_with_separator(TextWidget(self.errors.pop()))

        dialog = Dialog(_("Host Name"))
        self._container.add(TextWidget(_("Set host name")), callback=self._set_hostname_callback, data=dialog)

        for dev_name in self.supported_devices:
            text = (_("Configure device %s") % dev_name)
            self._container.add(TextWidget(text), callback=self._configure_network_interface, data=dev_name)

        self.window.add_with_separator(self._container)
Esempio n. 14
0
    def _activated_device_msg(self, devname):
        msg = _("Wired (%(interface_name)s) connected\n") \
              % {"interface_name": devname}

        ipv4config = nm.nm_device_ip_config(devname, version=4)
        ipv6config = nm.nm_device_ip_config(devname, version=6)

        if ipv4config and ipv4config[0]:
            addr_str, prefix, gateway_str = ipv4config[0][0]
            netmask_str = network.prefix2netmask(prefix)
            dnss_str = ",".join(ipv4config[1])
        else:
            addr_str = dnss_str = gateway_str = netmask_str = ""

        msg += _(" IPv4 Address: %(addr)s Netmask: %(netmask)s Gateway: %(gateway)s\n") % \
               {"addr": addr_str, "netmask": netmask_str, "gateway": gateway_str}
        msg += _(" DNS: %s\n") % dnss_str

        if ipv6config and ipv6config[0]:
            for ipv6addr in ipv6config[0]:
                addr_str, prefix, gateway_str = ipv6addr
                # Do not display link-local addresses
                if not addr_str.startswith("fe80:"):
                    msg += _(" IPv6 Address: %(addr)s/%(prefix)d\n") % \
                           {"addr": addr_str, "prefix": prefix}

        return msg
Esempio n. 15
0
def verify_root(storage, constraints, report_error, report_warning):
    """ Verify the root.

    :param storage: a storage to check
    :param constraints: a dictionary of constraints
    :param report_error: a function for error reporting
    :param report_warning: a function for warning reporting
    """
    root = storage.fsset.root_device

    if root:
        if root.size < constraints[STORAGE_MIN_ROOT]:
            report_warning(_("Your root partition is less than %(size)s "
                             "which is usually too small to install "
                             "%(product)s.")
                           % {'size': constraints[STORAGE_MIN_ROOT],
                              'product': productName})
    else:
        report_error(_("You have not defined a root partition (/), "
                       "which is required for installation of %s"
                       " to continue.") % (productName,))

    if storage.root_device and storage.root_device.format.exists:
        e = storage.must_format(storage.root_device)
        if e:
            report_error(e)
Esempio n. 16
0
    def _summary_text(self):
        """Return summary of current timezone & NTP configuration.

        :returns: current status
        :rtype: str
        """
        msg = ""
        # timezone
        kickstart_timezone = self._timezone_module.proxy.Timezone
        timezone_msg = _("not set")
        if kickstart_timezone:
            timezone_msg = kickstart_timezone

        msg += _("Timezone: %s\n") % timezone_msg

        # newline section separator
        msg += "\n"

        # NTP
        msg += _("NTP servers:")
        if self._ntp_servers:
            for status in format_ntp_status_list(self._ntp_servers):
                msg += "\n%s" % status
        else:
            msg += _("not configured")

        return msg
Esempio n. 17
0
def verify_partition_format_sizes(storage, constraints, report_error, report_warning):
    """ Verify that the size of the device is allowed by the format used.

    :param storage: a storage to check
    :param constraints: a dictionary of constraints
    :param report_error: a function for error reporting
    :param report_warning: a function for warning reporting
    """
    # storage.mountpoints is a property that returns a new dict each time, so
    # iterating over it is thread-safe.
    filesystems = storage.mountpoints

    for (mount, device) in filesystems.items():
        problem = filesystems[mount].check_size()
        if problem < 0:
            report_error(_("Your %(mount)s partition is too small for "
                           "%(format)s formatting (allowable size is "
                           "%(minSize)s to %(maxSize)s)")
                         % {"mount": mount, "format": device.format.name,
                            "minSize": device.min_size, "maxSize": device.max_size})
        elif problem > 0:
            report_error(_("Your %(mount)s partition is too large for "
                           "%(format)s formatting (allowable size is "
                           "%(minSize)s to %(maxSize)s)")
                         % {"mount": mount, "format": device.format.name,
                            "minSize": device.min_size, "maxSize": device.max_size})
Esempio n. 18
0
 def prompt(self, args=None):
     """ Customize default prompt. """
     prompt = NormalTUISpoke.prompt(self, args)
     prompt.set_message(_("Please select the timezone. Use numbers or type names directly"))
     # TRANSLATORS: 'b' to go back
     prompt.add_option(C_('TUI|Spoke Navigation|Time Settings', 'b'), _("back to region list"))
     return prompt
Esempio n. 19
0
    def refresh(self, args=None):
        super().refresh(args)

        self._container = ListColumnContainer(1, columns_width=78, spacing=1)

        # check if the storage refresh thread is running
        if threadMgr.get(THREAD_STORAGE_WATCHER):
            # storage refresh is running - just report it
            # so that the user can refresh until it is done
            # TODO: refresh once the thread is done ?
            message = _(PAYLOAD_STATUS_PROBING_STORAGE)
            self.window.add_with_separator(TextWidget(message))

        # check if there are any mountable devices
        if self._mountable_devices:
            for d in self._mountable_devices:
                self._container.add(TextWidget(d[1]),
                                    callback=self._select_mountable_device,
                                    data=d[0])

            self.window.add_with_separator(self._container)

        else:
            message = _("No mountable devices found")
            self.window.add_with_separator(TextWidget(message))
Esempio n. 20
0
 def prompt(self, args=None):
     """ Customize default prompt. """
     prompt = NormalTUISpoke.prompt(self, args)
     prompt.set_message(_("Please select language support to install"))
     # TRANSLATORS: 'b' to go back
     prompt.add_option(C_("TUI|Spoke Navigation|Language Support", "b"), _("to return to language list"))
     return prompt
Esempio n. 21
0
    def check(self):
        """Check configured storage against software selections.  When this
           method is complete (which should be pretty quickly), the following
           attributes are available for inspection:

           success       -- A simple boolean defining whether there's enough
                            space or not.
           error_message -- If unsuccessful, an error message describing the
                            situation.  This message is suitable for putting
                            in the info bar at the bottom of a Hub.
        """
        free = self._calculate_free_space()
        needed = self._calculate_needed_space()
        log.info("fs space: %s  needed: %s", free, needed)

        if free > needed:
            result = True
            message = ""
        else:
            result = False
            deficit = self._calculate_deficit(needed)

            if deficit:
                message = _("Not enough space in file systems for the current software selection. "
                            "An additional {} is needed.").format(deficit)
            else:
                message = _("Not enough space in file systems for the current software selection.")

        self.success = result
        self.error_message = message
        return result
Esempio n. 22
0
def _find_existing_installations(devicetree):
    """Find existing GNU/Linux installations on devices from the device tree.

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

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

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

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

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

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

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

    return roots
Esempio n. 23
0
    def parse(self, args):
        tg = super().parse(args)

        if tg.iface:
            if not network.wait_for_network_devices([tg.iface]):
                raise KickstartParseError(lineno=self.lineno,
                        msg=_("Network interface \"%(nic)s\" required by iSCSI \"%(iscsiTarget)s\" target is not up.") %
                             {"nic": tg.iface, "iscsiTarget": tg.target})

        mode = blivet.iscsi.iscsi.mode
        if mode == "none":
            if tg.iface:
                network_proxy = NETWORK.get_proxy()
                activated_ifaces = network_proxy.GetActivatedInterfaces()
                blivet.iscsi.iscsi.create_interfaces(activated_ifaces)
        elif ((mode == "bind" and not tg.iface)
              or (mode == "default" and tg.iface)):
            raise KickstartParseError(lineno=self.lineno,
                    msg=_("iscsi --iface must be specified (binding used) either for all targets or for none"))

        try:
            blivet.iscsi.iscsi.add_target(tg.ipaddr, tg.port, tg.user,
                                          tg.password, tg.user_in,
                                          tg.password_in,
                                          target=tg.target,
                                          iface=tg.iface)
            iscsi_log.info("added iscsi target %s at %s via %s", tg.target, tg.ipaddr, tg.iface)
        except (IOError, ValueError) as e:
            raise KickstartParseError(lineno=self.lineno, msg=str(e))

        return tg
Esempio n. 24
0
    def _do_check(self):
        self.clear_errors()
        StorageCheckHandler.errors = []
        StorageCheckHandler.warnings = []

        # We can't overwrite the main Storage instance because all the other
        # spokes have references to it that would get invalidated, but we can
        # achieve the same effect by updating/replacing a few key attributes.
        self.storage.devicetree._devices = self._storage_playground.devicetree._devices
        self.storage.devicetree._actions = self._storage_playground.devicetree._actions
        self.storage.devicetree._hidden = self._storage_playground.devicetree._hidden
        self.storage.devicetree.names = self._storage_playground.devicetree.names
        self.storage.roots = self._storage_playground.roots

        # set up bootloader and check the configuration
        try:
            configure_storage(self.storage, interactive=True)
        except BootloaderConfigurationError as e:
            StorageCheckHandler.errors = str(e).split("\n")
            reset_bootloader(self.storage)

        StorageCheckHandler.checkStorage(self)

        if self.errors:
            self.set_warning(_("Error checking storage configuration.  <a href=\"\">Click for details</a> or press Done again to continue."))
        elif self.warnings:
            self.set_warning(_("Warning checking storage configuration.  <a href=\"\">Click for details</a> or press Done again to continue."))

        # on_info_bar_clicked requires self._error to be set, so set it to the
        # list of all errors and warnings that storage checking found.
        self._error = "\n".join(self.errors + self.warnings)

        return self._error == ""
Esempio n. 25
0
    def parse(self, args):
        """Parse the command.

        Do any glob expansion now, since we need to have the real
        list of disks available before the execute methods run.
        """
        retval = super().parse(args)

        # Set the default type.
        if self.type is None:
            self.type = CLEARPART_TYPE_NONE

        # Check the disk label.
        if self.disklabel and self.disklabel not in DiskLabel.get_platform_label_types():
            raise KickstartParseError(_("Disklabel \"{}\" given in clearpart command is not "
                                        "supported on this platform.").format(self.disklabel),
                                      lineno=self.lineno)

        # Get the disks names to clear.
        self.drives = get_device_names(self.drives, disks_only=True, lineno=self.lineno,
                                       msg=_("Disk \"{}\" given in clearpart command does "
                                             "not exist."))

        # Get the devices names to clear.
        self.devices = get_device_names(self.devices, disks_only=False, lineno=self.lineno,
                                        msg=_("Device \"{}\" given in clearpart device list "
                                              "does not exist."))

        return retval
Esempio n. 26
0
    def _update_action_buttons(self, row):
        obj = PartStoreRow(*row)
        device = self.storage.devicetree.get_device_by_id(obj.id)

        # Disks themselves may be editable in certain ways, but they are never
        # shrinkable.
        self._preserveButton.set_sensitive(obj.editable)
        self._shrinkButton.set_sensitive(obj.editable and not device.is_disk)
        self._deleteButton.set_sensitive(obj.editable)
        self._resizeSlider.set_visible(False)

        if not obj.editable:
            return

        # If the selected filesystem does not support shrinking, make that
        # button insensitive.
        self._shrinkButton.set_sensitive(device.resizable)

        if device.resizable:
            self._setup_slider(device, Size(obj.target))

        # Then, disable the button for whatever action is currently selected.
        # It doesn't make a lot of sense to allow clicking that.
        if obj.action == _(PRESERVE):
            self._preserveButton.set_sensitive(False)
        elif obj.action == _(SHRINK):
            self._shrinkButton.set_sensitive(False)
            self._resizeSlider.set_visible(True)
        elif obj.action == _(DELETE):
            self._deleteButton.set_sensitive(False)
Esempio n. 27
0
    def _activated_device_msg(self, devname):
        msg = _("Wired (%(interface_name)s) connected\n") \
              % {"interface_name": devname}

        device = self.nm_client.get_device_by_iface(devname)
        if device:
            ipv4config = device.get_ip4_config()
            if ipv4config:
                addresses = ipv4config.get_addresses()
                if addresses:
                    a0 = addresses[0]
                    addr_str = a0.get_address()
                    prefix = a0.get_prefix()
                    netmask_str = network.prefix_to_netmask(prefix)
                gateway_str = ipv4config.get_gateway() or ''
                dnss_str = ",".join(ipv4config.get_nameservers())
            else:
                addr_str = dnss_str = gateway_str = netmask_str = ""
            msg += _(" IPv4 Address: %(addr)s Netmask: %(netmask)s Gateway: %(gateway)s\n") % \
                {"addr": addr_str, "netmask": netmask_str, "gateway": gateway_str}
            msg += _(" DNS: %s\n") % dnss_str

            ipv6config = device.get_ip6_config()
            if ipv6config:
                for address in ipv6config.get_addresses():
                    addr_str = address.get_address()
                    prefix = address.get_prefix()
                    # Do not display link-local addresses
                    if not addr_str.startswith("fe80:"):
                        msg += _(" IPv6 Address: %(addr)s/%(prefix)d\n") % \
                            {"addr": addr_str, "prefix": prefix}
        return msg
Esempio n. 28
0
def download_escrow_certificate(url):
    """Download the escrow certificate.

    :param url: an URL of the certificate
    :return: a content of the certificate
    """
    # Do we need a network connection?
    if not url.startswith("/") and not url.startswith("file:"):
        network_proxy = NETWORK.get_proxy()

        if not network_proxy.Connected:
            raise KickstartError(_("Escrow certificate %s requires the network.") % url)

    # Download the certificate.
    log.info("Downloading an escrow certificate from: %s", url)

    try:
        request = util.requests_session().get(url, verify=True)
    except requests.exceptions.SSLError as e:
        raise KickstartError(_("SSL error while downloading the escrow certificate:\n\n%s") % e)
    except requests.exceptions.RequestException as e:
        raise KickstartError(_("The following error was encountered while downloading the "
                               "escrow certificate:\n\n%s") % e)

    try:
        certificate = request.content
    finally:
        request.close()

    return certificate
Esempio n. 29
0
    def connectToView(self):
        """Attempt to connect to self.vncconnecthost"""

        maxTries = 10
        self.log.info(_("Attempting to connect to vnc client on host %s..."), self.vncconnecthost)

        if self.vncconnectport != "":
            hostarg = self.vncconnecthost + ":" + self.vncconnectport
        else:
            hostarg = self.vncconnecthost

        vncconfigcommand = [self.root + "/usr/bin/vncconfig", "-display", ":%s" % constants.X_DISPLAY_NUMBER, "-connect", hostarg]

        for _i in range(maxTries):
            vncconfp = util.startProgram(vncconfigcommand, stdout=subprocess.PIPE, stderr=subprocess.PIPE)  # vncconfig process
            err = vncconfp.communicate()[1].decode("utf-8")

            if err == '':
                self.log.info(_("Connected!"))
                return True
            elif err.startswith("connecting") and err.endswith("failed\n"):
                self.log.info(_("Will try to connect again in 15 seconds..."))
                time.sleep(15)
                continue
            else:
                log.critical(err)
                util.ipmi_abort(scripts=self.anaconda.ksdata.scripts)
                sys.exit(1)
        self.log.error(P_("Giving up attempting to connect after %d try!\n",
                          "Giving up attempting to connect after %d tries!\n",
                          maxTries), maxTries)
        return False
Esempio n. 30
0
 def status(self):
     if self._error:
         return _("Error setting up software source")
     elif not self.ready:
         return _("Processing...")
     else:
         return self._repo_status()
Esempio n. 31
0
    def preInstall(self):
        """ 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 util.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 = util.execWithRedirect("mount", ["--make-rprivate", "/"])
            if rc == 0:
                rc = util.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 = os.statvfs(INSTALL_TREE)
            self.source_size = source.f_frsize * (source.f_blocks -
                                                  source.f_bfree)
Esempio n. 32
0
 def status(self):
     return _("testing status...")
Esempio n. 33
0
 def prompt(self, args=None):
     return Prompt(_("Installation complete. Press %s to quit") % Prompt.ENTER)
Esempio n. 34
0
 def prompt(self, args=None):
     """ Customize default prompt. """
     prompt = NormalTUISpoke.prompt(self, args)
     prompt.set_message(_("Please select language support to install"))
     prompt.add_option(PROMPT_BACK_KEY, _(PROMPT_BACK_DESCRIPTION))
     return prompt
Esempio n. 35
0
    try:
        pidfile.create()
    except pid.PidFileError as e:
        log.error("Unable to create %s, exiting", pidfile.filename)

        # If we had a $DISPLAY at start and zenity is available, we may be
        # running in a live environment and we can display an error dialog.
        # Otherwise just print an error.
        if flags.preexisting_x11 and os.access("/usr/bin/zenity", os.X_OK):
            # The module-level _() calls are ok here because the language may
            # be set from the live environment in this case, and anaconda's
            # language setup hasn't happened yet.
            # pylint: disable=found-_-in-module-class
            util.execWithRedirect("zenity",
                                  ["--error", "--title", _("Unable to create PID file"), "--text",
                                   _("Anaconda is unable to create %s because the file"
                                     " already exists. Anaconda is already running, or "
                                     "a previous instance of anaconda has crashed.")
                                   % pidfile.filename])
        else:
            print("%s already exists, exiting" % pidfile.filename)

        util.ipmi_report(constants.IPMI_FAILED)
        sys.exit(1)

    # add our own additional signal handlers
    signal.signal(signal.SIGHUP, start_debugger)

    anaconda.opts = opts
Esempio n. 36
0
 def _show_no_network_warning(self):
     self.set_warning(_("You need to set up networking first if you "\
                        "want to use NTP"))
Esempio n. 37
0
    def _parse_subscription_json(cls, subscription_json):
        """Parse the JSON into list of AttachedSubscription instances.

        The expected JSON is at top level a list of rather complex dictionaries,
        with each dictionary describing a single subscription that has been attached
        to the system.

        :param str subscription_json: JSON describing what subscriptions have been attached
        :return: list of attached subscriptions
        :rtype: list of AttachedSubscription instances
        """
        attached_subscriptions = []
        try:
            subscriptions = json.loads(subscription_json)
        except json.decoder.JSONDecodeError:
            log.warning("subscription: failed to parse GetPools() JSON output")
            # empty attached subscription list is better than an installation
            # ending crash
            return []
        # find the list of subscriptions
        consumed_subscriptions = subscriptions.get("consumed", [])
        log.debug("subscription: parsing %d attached subscriptions",
                  len(consumed_subscriptions))
        # split the list of subscriptions into separate subscription dictionaries
        for subscription_info in consumed_subscriptions:
            attached_subscription = AttachedSubscription()
            # user visible product name
            attached_subscription.name = subscription_info.get(
                "subscription_name", _("product name unknown"))

            # subscription support level
            # - this does *not* seem to directly correlate to system purpose SLA attribute
            attached_subscription.service_level = subscription_info.get(
                "service_level", _("unknown"))

            # SKU
            # - looks like productId == SKU in this JSON output
            attached_subscription.sku = subscription_info.get(
                "sku", _("unknown"))

            # contract number
            attached_subscription.contract = subscription_info.get(
                "contract", _("not available"))

            # subscription start date
            # - convert the raw date data from JSON to something more readable
            start_date = subscription_info.get("starts", _("unknown"))
            attached_subscription.start_date = cls._pretty_date(start_date)

            # subscription end date
            # - convert the raw date data from JSON to something more readable
            end_date = subscription_info.get("ends", _("unknown"))
            attached_subscription.end_date = cls._pretty_date(end_date)

            # consumed entitlements
            # - this seems to correspond to the toplevel "quantity" key,
            #   not to the pool-level "consumed" key for some reason
            #   *or* the pool-level "quantity" key
            quantity_string = int(subscription_info.get("quantity_used", 1))
            attached_subscription.consumed_entitlement_count = quantity_string
            # add attached subscription to the list
            attached_subscriptions.append(attached_subscription)
        # return the list of attached subscriptions
        return attached_subscriptions
Esempio n. 38
0
    def initialize(self):
        NormalSpoke.initialize(self)
        self.initialize_start()

        # We consider user creation requested if there was at least one user
        # in the DBus module user list at startup.
        # We also remember how the user was called so that we can clear it
        # in a reasonably safe way & if it was cleared.
        self._user_list = get_user_list(self._users_module, add_default=True)
        self._user_requested = False
        self._requested_user_cleared = False
        # if user has a name, it's an actual user that has been requested,
        # rather than a default user added by us
        if self.user.name:
            self._user_requested = True

        # gather references to relevant GUI objects

        # entry fields
        self._fullname_entry = self.builder.get_object("fullname_entry")
        self._username_entry = self.builder.get_object("username_entry")
        self._password_entry = self.builder.get_object("password_entry")
        self._password_confirmation_entry = self.builder.get_object(
            "password_confirmation_entry")
        # check boxes
        self._admin_checkbox = self.builder.get_object("admin_checkbox")
        self._password_required_checkbox = self.builder.get_object(
            "password_required_checkbox")
        # advanced user configration dialog button
        self._advanced_button = self.builder.get_object("advanced_button")
        # password checking status bar & label
        self._password_bar = self.builder.get_object("password_bar")
        self._password_label = self.builder.get_object("password_label")

        # Install the password checks:
        # - Has a password been specified?
        # - If a password has been specified and there is data in the confirm box, do they match?
        # - How strong is the password?
        # - Does the password contain non-ASCII characters?

        # Setup the password checker for password checking
        self._checker = input_checking.PasswordChecker(
            initial_password_content=self.password,
            initial_password_confirmation_content=self.password_confirmation,
            policy=input_checking.get_policy(self.data, "user"))
        # configure the checker for password checking
        self.checker.username = self.username
        self.checker.secret_type = constants.SecretType.PASSWORD
        # remove any placeholder texts if either password or confirmation field changes content from initial state
        self.checker.password.changed_from_initial_state.connect(
            self.remove_placeholder_texts)
        self.checker.password_confirmation.changed_from_initial_state.connect(
            self.remove_placeholder_texts)
        # connect UI updates to check results
        self.checker.checks_done.connect(self._checks_done)

        # username and full name checks
        self._username_check = input_checking.UsernameCheck()
        self._fullname_check = input_checking.FullnameCheck()
        # empty username is considered a success so that the user can leave
        # the spoke without filling it in
        self._username_check.success_if_username_empty = True
        # check that the password is not empty
        self._empty_check = input_checking.PasswordEmptyCheck()
        # check that the content of the password field & the conformation field are the same
        self._confirm_check = input_checking.PasswordConfirmationCheck()
        # check password validity, quality and strength
        self._validity_check = input_checking.PasswordValidityCheck()
        # connect UI updates to validity check results
        self._validity_check.result.password_score_changed.connect(
            self.set_password_score)
        self._validity_check.result.status_text_changed.connect(
            self.set_password_status)
        # check if the password contains non-ascii characters
        self._ascii_check = input_checking.PasswordASCIICheck()
        # Skip the empty and validity password checks if no username is set
        self._empty_check.skip = True
        self._validity_check.skip = True

        # register the individual checks with the checker in proper order
        # 0) is the username and fullname valid ?
        # 1) is the password non-empty ?
        # 2) are both entered passwords the same ?
        # 3) is the password valid according to the current password checking policy ?
        # 4) is the password free of non-ASCII characters ?
        self.checker.add_check(self._username_check)
        self.checker.add_check(self._fullname_check)
        self.checker.add_check(self._empty_check)
        self.checker.add_check(self._confirm_check)
        self.checker.add_check(self._validity_check)
        self.checker.add_check(self._ascii_check)

        self.guesser = {self.username_entry: True}

        # Configure levels for the password bar
        self.password_bar.add_offset_value("low", 2)
        self.password_bar.add_offset_value("medium", 3)
        self.password_bar.add_offset_value("high", 4)

        # Modify the GUI based on the kickstart and policy information
        # This needs to happen after the input checks have been created, since
        # the Gtk signal handlers use the input check variables.
        password_set_message = _("The password was set by kickstart.")
        if self.password_kickstarted:
            self.password_required = True
            self.password_entry.set_placeholder_text(password_set_message)
            self.password_confirmation_entry.set_placeholder_text(
                password_set_message)
        elif not self.checker.policy.emptyok:
            # Policy is that a non-empty password is required
            self.password_required = True

        if not self.checker.policy.emptyok:
            # User isn't allowed to change whether password is required or not
            self.password_required_checkbox.set_sensitive(False)

        self._advanced_user_dialog = AdvancedUserDialog(self)
        self._advanced_user_dialog.initialize()

        # set the visibility of the password entries
        set_password_visibility(self.password_entry, False)
        set_password_visibility(self.password_confirmation_entry, False)

        # report that we are done
        self.initialize_done()
Esempio n. 39
0
    def __init__(self, fullscreen=False, decorated=False):
        """Create a new anaconda main window.

          :param bool fullscreen: if True, fullscreen the window, if false maximize
        """
        super().__init__()

        # Remove the title bar, resize controls and other stuff if the window manager
        # allows it and decorated is set to False. Otherwise, it has no effect.
        self.set_decorated(decorated)

        # Hide the titlebar when maximized if the window manager allows it.
        # This makes anaconda look full-screenish but without covering parts
        # needed to interact with the window manager, like the GNOME top bar.
        self.set_hide_titlebar_when_maximized(True)

        # The Anaconda and Initial Setup windows might sometimes get decorated with
        # a titlebar which contains the __init__.py header text by default.
        # As all Anaconda and Initial Setup usually have a very distinct title text
        # inside the window, the titlebar text is redundant and should be disabled.
        self.set_title(_(WINDOW_TITLE_TEXT))

        # Set the icon used in the taskbar of window managers that have a taskbar
        # The "anaconda" icon is part of fedora-logos
        self.set_icon_name("anaconda")

        # Treat an attempt to close the window the same as hitting quit
        self.connect("delete-event", self._on_delete_event)

        # Create a black, 50% opacity pixel that will be scaled to fit the lightbox overlay
        # The confusing list of unnamed parameters is:
        # bytes, colorspace (there is no other colorspace), has-alpha,
        # bits-per-sample (has to be 8), width, height,
        # rowstride (bytes between row starts, but we only have one row)
        self._transparent_base = GdkPixbuf.Pixbuf.new_from_bytes(
            Bytes.new([0, 0, 0, 127]), GdkPixbuf.Colorspace.RGB, True, 8, 1, 1,
            1)

        # Contain everything in an overlay so the window can be overlayed with the transparency
        # for the lightbox effect
        self._overlay = Gtk.Overlay()
        self._overlay_img = None
        self._overlay.connect("get-child-position",
                              self._on_overlay_get_child_position)

        self._overlay_depth = 0

        # Create a stack and a list of what's been added to the stack
        # Double the stack transition duration since the default 200ms is too
        # quick to get the point across
        self._stack = Gtk.Stack(transition_duration=400)
        self._stack_contents = set()

        # Create an accel group for the F12 accelerators added after window transitions
        self._accel_group = Gtk.AccelGroup()
        self.add_accel_group(self._accel_group)

        # Make the window big
        if fullscreen:
            self.fullscreen()
        else:
            self.maximize()

        self._overlay.add(self._stack)
        self.add(self._overlay)
        self.show_all()

        self._current_action = None

        # Help button mnemonics handling
        self._mnemonic_signal = None
        # we have a sensible initial value, just in case
        self._saved_help_button_label = _("Help!")

        # Apply the initial language attributes
        self._language = None
        self.reapply_language()

        # Keybinder from GI needs to be initialized before use
        Keybinder.init()
        Keybinder.bind("<Shift>Print", self._handle_print_screen, [])

        self._screenshot_index = 0
Esempio n. 40
0
 def run(self):
     if self.MESSAGE:
         self.builder.get_object("quit_message").set_label(_(self.MESSAGE))
     rc = self.window.run()
     return rc
Esempio n. 41
0
def status_message(nm_client):
    """A short string describing which devices are connected."""

    msg = _("Unknown")

    if not nm_client:
        msg = _("Status not available")
        return msg

    state = nm_client.get_state()
    if state == NM.State.CONNECTING:
        msg = _("Connecting...")
    elif state == NM.State.DISCONNECTING:
        msg = _("Disconnecting...")
    else:
        active_devs = [d for d in get_activated_devices(nm_client)
                       if not is_libvirt_device(d.get_ip_iface() or d.get_iface())]
        if active_devs:

            slaves = {}
            ssids = {}
            nonslaves = []

            # first find slaves and wireless aps
            for device in active_devs:
                device_slaves = []
                if hasattr(device, 'get_slaves'):
                    device_slaves = [slave_dev.get_iface() for slave_dev in device.get_slaves()]
                iface = device.get_iface()
                slaves[iface] = device_slaves
                if device.get_device_type() == NM.DeviceType.WIFI:
                    ssid = ""
                    ap = device.get_active_access_point()
                    if ap:
                        ssid = ap.get_ssid().get_data().decode()
                    ssids[iface] = ssid
            all_slaves = set(itertools.chain.from_iterable(slaves.values()))
            nonslaves = [dev for dev in active_devs if dev.get_iface() not in all_slaves]

            if len(nonslaves) == 1:
                device = nonslaves[0]
                iface = device.get_ip_iface() or device.get_iface()
                device_type = device.get_device_type()
                if device_type_is_supported_wired(device_type):
                    msg = _("Wired (%(interface_name)s) connected") \
                          % {"interface_name": iface}
                elif device_type == NM.DeviceType.WIFI:
                    msg = _("Wireless connected to %(access_point)s") \
                          % {"access_point": ssids[iface]}
                elif device_type == NM.DeviceType.BOND:
                    msg = _("Bond %(interface_name)s (%(list_of_slaves)s) connected") \
                          % {"interface_name": iface,
                             "list_of_slaves": ",".join(slaves[iface])}
                elif device_type == NM.DeviceType.TEAM:
                    msg = _("Team %(interface_name)s (%(list_of_slaves)s) connected") \
                          % {"interface_name": iface,
                             "list_of_slaves": ",".join(slaves[iface])}
                elif device_type == NM.DeviceType.BRIDGE:
                    msg = _("Bridge %(interface_name)s (%(list_of_slaves)s) connected") \
                          % {"interface_name": iface,
                             "list_of_slaves": ",".join(slaves[iface])}
                elif device_type == NM.DeviceType.VLAN:
                    parent = device.get_parent()
                    vlanid = device.get_vlan_id()
                    msg = _("VLAN %(interface_name)s (%(parent_device)s, ID %(vlanid)s) connected") \
                        % {"interface_name": iface, "parent_device": parent, "vlanid": vlanid}
            elif len(nonslaves) > 1:
                devlist = []
                for device in nonslaves:
                    iface = device.get_ip_iface() or device.get_iface()
                    device_type = device.get_device_type()
                    if device_type_is_supported_wired(device_type):
                        devlist.append("%s" % iface)
                    elif device_type == NM.DeviceType.WIFI:
                        devlist.append("%s" % ssids[iface])
                    elif device_type == NM.DeviceType.BOND:
                        devlist.append("%s (%s)" % (iface, ",".join(slaves[iface])))
                    elif device_type == NM.DeviceType.TEAM:
                        devlist.append("%s (%s)" % (iface, ",".join(slaves[iface])))
                    elif device_type == NM.DeviceType.BRIDGE:
                        devlist.append("%s (%s)" % (iface, ",".join(slaves[iface])))
                    elif device_type == NM.DeviceType.VLAN:
                        devlist.append("%s" % iface)
                msg = _("Connected: %(list_of_interface_names)s") % {"list_of_interface_names": ", ".join(devlist)}
        else:
            msg = _("Not connected")

    if not get_supported_devices():
        msg = _("No network devices available")

    return msg
Esempio n. 42
0
 def _show_no_ntp_server_warning(self):
     self.set_warning(_("You have no working NTP server configured"))
Esempio n. 43
0
    def _check_nfs_server(self, user_input, report_func):
        if ":" not in user_input or len(user_input.split(":")) != 2:
            report_func(_("Server must be specified as SERVER:/PATH"))
            return False

        return True
Esempio n. 44
0
 def _noDisksHandler(self, exn):
     message = _("An error has occurred - no valid devices were found on "
                 "which to create new file systems.  Please check your "
                 "hardware for the cause of this problem.")
     self.ui.showError(message)
     return ERROR_RAISE
Esempio n. 45
0
    def refresh(self, args=None):
        NormalTUISpoke.refresh(self, args)

        msg = _("Please select new root password. You will have to type it twice.")
        self.window.add_with_separator(TextWidget(msg))
Esempio n. 46
0
    def _passwordCryptErrorHandler(self, exn):
        message = _(
            "Unable to encrypt password: unsupported algorithm %s") % exn.algo

        self.ui.showError(message)
        return ERROR_RAISE
Esempio n. 47
0
 def status(self):
     if self._l12_module.Language:
         return localization.get_english_name(self._selected)
     else:
         return _("Language is not set.")
Esempio n. 48
0
def setup_display(anaconda, options):
    """Setup the display for the installation environment.

    :param anaconda: instance of the Anaconda class
    :param options: command line/boot options
    """

    try:
        xtimeout = int(options.xtimeout)
    except ValueError:
        log.warning("invalid inst.xtimeout option value: %s", options.xtimeout)
        xtimeout = constants.X_TIMEOUT

    vnc_server = vnc.VncServer()  # The vnc Server object.
    vnc_server.anaconda = anaconda
    vnc_server.timeout = xtimeout

    anaconda.display_mode = options.display_mode
    anaconda.interactive_mode = not options.noninteractive

    if options.vnc:
        flags.usevnc = True
        if not anaconda.gui_mode:
            log.info(
                "VNC requested via boot/CLI option, switching Anaconda to GUI mode."
            )
            anaconda.display_mode = constants.DisplayModes.GUI
        vnc_server.password = options.vncpassword

        # Only consider vncconnect when vnc is a param
        if options.vncconnect:
            cargs = options.vncconnect.split(":")
            vnc_server.vncconnecthost = cargs[0]
            if len(cargs) > 1 and len(cargs[1]) > 0:
                if len(cargs[1]) > 0:
                    vnc_server.vncconnectport = cargs[1]

    if options.xdriver:
        write_xdriver(options.xdriver, root="/")

    if flags.rescue_mode:
        return

    if anaconda.ksdata.vnc.enabled:
        flags.usevnc = True
        if not anaconda.gui_mode:
            log.info(
                "VNC requested via kickstart, switching Anaconda to GUI mode.")
            anaconda.display_mode = constants.DisplayModes.GUI

        if vnc_server.password == "":
            vnc_server.password = anaconda.ksdata.vnc.password

        if vnc_server.vncconnecthost == "":
            vnc_server.vncconnecthost = anaconda.ksdata.vnc.host

        if vnc_server.vncconnectport == "":
            vnc_server.vncconnectport = anaconda.ksdata.vnc.port

    if anaconda.gui_mode:
        mods = (tup[1] for tup in pkgutil.iter_modules(pyanaconda.ui.__path__,
                                                       "pyanaconda.ui."))
        if "pyanaconda.ui.gui" not in mods:
            stdout_log.warning(
                "Graphical user interface not available, falling back to text mode"
            )
            anaconda.display_mode = constants.DisplayModes.TUI
            flags.usevnc = False
            flags.vncquestion = False

    # check if VNC can be started
    vnc_can_be_started, vnc_error_messages = check_vnc_can_be_started(anaconda)
    if not vnc_can_be_started:
        # VNC can't be started - disable the VNC question and log
        # all the errors that prevented VNC from being started
        flags.vncquestion = False
        for error_message in vnc_error_messages:
            stdout_log.warning(error_message)

    # Should we try to start Xorg?
    want_x = anaconda.gui_mode and not (flags.preexisting_x11 or flags.usevnc)

    # X on a headless (e.g. s390) system? Nonsense!
    if want_x and blivet.arch.is_s390():
        stdout_log.warning(
            _("Running on a headless system. Starting text mode."))
        anaconda.display_mode = constants.DisplayModes.TUI
        anaconda.gui_startup_failed = True
        time.sleep(2)
        want_x = False

    # Is Xorg is actually available?
    if want_x and not os.access("/usr/bin/Xorg", os.X_OK):
        stdout_log.warning(
            _("Graphical installation is not available. "
              "Starting text mode."))
        time.sleep(2)
        anaconda.display_mode = constants.DisplayModes.TUI
        want_x = False

    if anaconda.tui_mode and flags.vncquestion:
        # we prefer vnc over text mode, so ask about that
        message = _("Text mode provides a limited set of installation "
                    "options. It does not offer custom partitioning for "
                    "full control over the disk layout. Would you like "
                    "to use VNC mode instead?")
        ask_vnc_question(anaconda, vnc_server, message)
        if not anaconda.ksdata.vnc.enabled:
            # user has explicitly specified text mode
            flags.vncquestion = False

    anaconda.log_display_mode()
    startup_utils.check_memory(anaconda, options)

    # check_memory may have changed the display mode
    want_x = want_x and (anaconda.gui_mode)
    if want_x:
        try:
            start_x11(xtimeout)
            do_startup_x11_actions()
        except (OSError, RuntimeError) as e:
            log.warning("X startup failed: %s", e)
            stdout_log.warning("X startup failed, falling back to text mode")
            anaconda.display_mode = constants.DisplayModes.TUI
            anaconda.gui_startup_failed = True
            time.sleep(2)

        if not anaconda.gui_startup_failed:
            do_extra_x11_actions(options.runres, gui_mode=anaconda.gui_mode)

    if anaconda.tui_mode and anaconda.gui_startup_failed and flags.vncquestion and not anaconda.ksdata.vnc.enabled:
        message = _(
            "X was unable to start on your machine. Would you like to start VNC to connect to "
            "this computer from another computer and perform a graphical installation or continue "
            "with a text mode installation?")
        ask_vnc_question(anaconda, vnc_server, message)

    # if they want us to use VNC do that now
    if anaconda.gui_mode and flags.usevnc:
        vnc_server.startServer()
        do_startup_x11_actions()

    # with X running we can initialize the UI interface
    anaconda.initInterface()
Esempio n. 49
0
def validate_device_factory_request(storage, request: DeviceFactoryRequest):
    """Validate the given device info.

    :param storage: an instance of Blivet
    :param request: a device factory request to validate
    :return: an error message
    """
    device = storage.devicetree.resolve_device(request.device_spec)
    device_type = request.device_type
    reformat = request.reformat
    fs_type = request.format_type
    encrypted = request.device_encrypted
    raid_level = get_raid_level_by_name(request.device_raid_level)
    mount_point = request.mount_point
    label = request.label
    num_disk = len(request.disks)

    changed_label = label != getattr(device.format, "label", "")
    changed_fstype = fs_type != device.format.type

    if changed_label or changed_fstype:
        error = validate_label(label, get_format(fs_type))
        if error:
            return error

    is_format_mountable = get_format(fs_type).mountable
    changed_mount_point = mount_point != getattr(device.format, "mountpoint",
                                                 "")

    if reformat and is_format_mountable and not mount_point:
        return _("Please enter a mount point.")

    if changed_mount_point and mount_point:
        error = validate_mount_point(mount_point, storage.mountpoints.keys())
        if error:
            return error

    supported_types = (devicefactory.DEVICE_TYPE_PARTITION,
                       devicefactory.DEVICE_TYPE_MD)

    if mount_point == "/boot/efi" and device_type not in supported_types:
        return _("/boot/efi must be on a device of type {type} or {another}"
                 ).format(type=_(
                     DEVICE_TEXT_MAP[devicefactory.DEVICE_TYPE_PARTITION]),
                          another=_(
                              DEVICE_TEXT_MAP[devicefactory.DEVICE_TYPE_MD]))

    if device_type != devicefactory.DEVICE_TYPE_PARTITION and \
            fs_type in PARTITION_ONLY_FORMAT_TYPES:
        return _("{fs} must be on a device of type {type}").format(
            fs=fs_type,
            type=_(DEVICE_TEXT_MAP[devicefactory.DEVICE_TYPE_PARTITION]))

    if mount_point and encrypted and mount_point.startswith("/boot"):
        return _("{} cannot be encrypted").format(mount_point)

    if encrypted and fs_type in PARTITION_ONLY_FORMAT_TYPES:
        return _("{} cannot be encrypted").format(fs_type)

    if mount_point == "/" and device.format.exists and not reformat:
        return _("You must create a new file system on the root device.")

    if (raid_level is not None or device_type == devicefactory.DEVICE_TYPE_MD) and \
            raid_level not in get_supported_raid_levels(device_type):
        return _("Device does not support RAID level selection {}.").format(
            raid_level)

    if raid_level is not None:
        error = validate_raid_level(raid_level, num_disk)
        if error:
            return error

    return None
Esempio n. 50
0
    def is_valid_stage1_device(self, device, early=False):
        """ Return True if the device is a valid stage1 target device.

            Also collect lists of errors and warnings.

            The criteria for being a valid stage1 target device vary from
            platform to platform. On some platforms a disk with an msdos
            disklabel is a valid stage1 target, while some platforms require
            a special device. Some examples of these special devices are EFI
            system partitions on EFI machines, PReP boot partitions on
            iSeries, and Apple bootstrap partitions on Mac.

            The 'early' keyword argument is a boolean flag indicating whether
            or not this check is being performed at a point where the mountpoint
            cannot be expected to be set for things like EFI system partitions.
        """
        self.errors = []
        self.warnings = []
        valid = True
        constraint = platform.boot_stage1_constraint_dict

        if device is None:
            return False

        log.debug("Is %s a valid stage1 target device?", device.name)

        if not self._device_type_match(device, constraint["device_types"]):
            log.debug("stage1 device cannot be of type %s", device.type)
            return False

        if _is_on_sw_iscsi(device):
            if not _is_on_ibft(device):
                if conf.bootloader.nonibft_iscsi_boot:
                    log.debug("stage1 device on non-iBFT iSCSI disk allowed "
                              "by boot option inst.iscsi.nonibftboot")
                else:
                    log.debug(
                        "stage1 device cannot be on an non-iBFT iSCSI disk")
                    self.errors.append(
                        _("Boot loader stage1 device cannot be on "
                          "an iSCSI disk which is not configured in iBFT."))
                    return False

        description = self.device_description(device)

        if self.stage2_is_valid_stage1 and device == self.stage2_device:
            # special case
            valid = (self.stage2_is_preferred_stage1
                     and self.is_valid_stage2_device(device))

            # we'll be checking stage2 separately so don't duplicate messages
            self.warnings = []
            return valid

        if device.protected:
            valid = False

        if not self._is_valid_disklabel(device,
                                        disklabel_types=self.disklabel_types):
            valid = False

        if not self._is_valid_size(device, desc=description):
            valid = False

        if not self._is_valid_location(
                device, max_end=constraint["max_end"], desc=description):
            valid = False

        if not self._is_valid_md(device,
                                 raid_levels=constraint["raid_levels"],
                                 metadata=constraint["raid_metadata"],
                                 member_types=constraint["raid_member_types"],
                                 desc=description):
            valid = False

        if not self.stage2_bootable and not getattr(device, "bootable", True):
            log.warning("%s not bootable", device.name)

        # XXX does this need to be here?
        if getattr(device.format, "label", None) in ("ANACONDA", "LIVE"):
            log.info("ignoring anaconda boot disk")
            valid = False

        if early:
            mountpoints = []
        else:
            mountpoints = constraint["mountpoints"]

        if not self._is_valid_format(device,
                                     format_types=constraint["format_types"],
                                     mountpoints=mountpoints,
                                     desc=description):
            valid = False

        if not self.encryption_support and device.encrypted:
            self.errors.append(
                _("%s cannot be on an encrypted block "
                  "device.") % description)
            valid = False

        log.debug("is_valid_stage1_device(%s) returning %s", device.name,
                  valid)
        return valid
Esempio n. 51
0
 def description(self):
     """Get description of this source."""
     return _("Local media via SE/HMC")
Esempio n. 52
0
    def _update_subscription_state(self):
        """Update state of the subscription related part of the spoke.

        Update state of the part of the spoke, that shows data about the
        currently attached subscriptions.
        """
        # authentication method
        if self.authentication_method == AuthenticationMethod.USERNAME_PASSWORD:
            method_string = _("Registered with account {}").format(
                self.subscription_request.account_username)
        else:  # org + key
            method_string = _("Registered with organization {}").format(
                self.subscription_request.organization)
        self._method_status_label.set_text(method_string)

        # final syspurpose data

        # role
        final_role_string = _("Role: {}").format(self.system_purpose_data.role)
        self._role_status_label.set_text(final_role_string)

        # SLA
        final_sla_string = _("SLA: {}").format(self.system_purpose_data.sla)
        self._sla_status_label.set_text(final_sla_string)

        # usage
        final_usage_string = _("Usage: {}").format(
            self.system_purpose_data.usage)
        self._usage_status_label.set_text(final_usage_string)

        # Insights
        # - this strings are referring to the desired target system state,
        #   the installation environment itself is not expected to be
        #   connected to Insights
        if self._subscription_module.InsightsEnabled:
            insights_string = _("Connected to Red Hat Insights")
        else:
            insights_string = _("Not connected to Red Hat Insights")
        self._insights_status_label.set_text(insights_string)

        # get attached subscriptions as a list of structs
        attached_subscriptions = self._subscription_module.AttachedSubscriptions
        # turn the structs to more useful AttachedSubscription instances
        attached_subscriptions = AttachedSubscription.from_structure_list(
            attached_subscriptions)

        # check how many we have & set the subscription status string accordingly
        subscription_count = len(attached_subscriptions)
        if subscription_count == 0:
            subscription_string = _(
                "No subscriptions are attached to the system")
        elif subscription_count == 1:
            subscription_string = _("1 subscription attached to the system")
        else:
            subscription_string = _("{} subscriptions attached to the system"
                                    ).format(subscription_count)

        self._attached_subscriptions_label.set_text(subscription_string)

        # populate the attached subscriptions listbox
        populate_attached_subscriptions_listbox(self._subscriptions_listbox,
                                                attached_subscriptions)
Esempio n. 53
0
    def is_valid_stage2_device(self, device, linux=True, non_linux=False):
        """ Return True if the device is suitable as a stage2 target device.

            Also collect lists of errors and warnings.
        """
        self.errors = []
        self.warnings = []
        valid = True

        if device is None:
            return False

        log.debug("Is %s a valid stage2 target device?", device.name)

        if device.protected:
            valid = False

        if _is_on_sw_iscsi(device):
            if not _is_on_ibft(device):
                if conf.bootloader.nonibft_iscsi_boot:
                    log.info(
                        "%s on non-iBFT iSCSI disk allowed by boot option inst.nonibftiscsiboot",
                        self.stage2_description)
                else:
                    self.errors.append(
                        _("%(bootloader_stage2_description)s cannot be on "
                          "an iSCSI disk which is not configured in iBFT.") % {
                              "bootloader_stage2_description":
                              self.stage2_description
                          })
                    valid = False

        if not self._device_type_match(device, self.stage2_device_types):
            self.errors.append(
                _("%(desc)s cannot be of type %(type)s") % {
                    "desc": _(self.stage2_description),
                    "type": device.type
                })
            valid = False

        if not self._is_valid_disklabel(device,
                                        disklabel_types=self.disklabel_types):
            valid = False

        if not self._is_valid_size(device, desc=_(self.stage2_description)):
            valid = False

        if self.stage2_max_end and not self._is_valid_location(
                device,
                max_end=self.stage2_max_end,
                desc=_(self.stage2_description)):
            valid = False

        if not self._is_valid_partition(device,
                                        primary=self.stage2_must_be_primary):
            valid = False

        if not self._is_valid_md(device,
                                 raid_levels=self.stage2_raid_levels,
                                 metadata=self.stage2_raid_metadata,
                                 member_types=self.stage2_raid_member_types,
                                 desc=_(self.stage2_description)):
            valid = False

        if linux and \
           not self._is_valid_format(device,
                                     format_types=self.stage2_format_types,
                                     mountpoints=self.stage2_mountpoints,
                                     desc=_(self.stage2_description)):
            valid = False

        non_linux_format_types = platform._non_linux_format_types
        if non_linux and \
           not self._is_valid_format(device,
                                     format_types=non_linux_format_types):
            valid = False

        if not self.encryption_support and device.encrypted:
            self.errors.append(
                _("%s cannot be on an encrypted block "
                  "device.") % _(self.stage2_description))
            valid = False

        log.debug("is_valid_stage2_device(%s) returning %s", device.name,
                  valid)
        return valid
Esempio n. 54
0
 def preInstall(self):
     """ Perform pre-installation tasks. """
     super().preInstall()
     progressQ.send_message(_("Installing software") + (" %d%%") % (0, ))
Esempio n. 55
0
    def install(self):
        mainctx = create_new_context()
        mainctx.push_thread_default()

        cancellable = None
        gi.require_version("OSTree", "1.0")
        gi.require_version("RpmOstree", "1.0")
        from gi.repository import OSTree, RpmOstree
        ostreesetup = self.data.ostreesetup
        log.info("executing ostreesetup=%r", ostreesetup)

        # Initialize the filesystem - this will create the repo as well
        self._safeExecWithRedirect("ostree",
                                   ["admin", "--sysroot=" + util.getTargetPhysicalRoot(),
                                   "init-fs", util.getTargetPhysicalRoot()])

        # Here, we use the physical root as sysroot, because we haven't
        # yet made a deployment.
        sysroot_file = Gio.File.new_for_path(util.getTargetPhysicalRoot())
        sysroot = OSTree.Sysroot.new(sysroot_file)
        sysroot.load(cancellable)
        repo = sysroot.get_repo(None)[1]
        # We don't support resuming from interrupted installs
        repo.set_disable_fsync(True)

        self._remoteOptions = {}

        if hasattr(ostreesetup, 'nogpg') and ostreesetup.nogpg:
            self._remoteOptions['gpg-verify'] = Variant('b', False)

        if flags.noverifyssl:
            self._remoteOptions['tls-permissive'] = Variant('b', True)

        repo.remote_change(None, OSTree.RepoRemoteChange.ADD_IF_NOT_EXISTS,
                           ostreesetup.remote, ostreesetup.url,
                           Variant('a{sv}', self._remoteOptions),
                           cancellable)

        # Variable substitute the ref: https://pagure.io/atomic-wg/issue/299
        ref = RpmOstree.varsubst_basearch(ostreesetup.ref)

        progressQ.send_message(_("Starting pull of %(branchName)s from %(source)s") % \
                               {"branchName": ref, "source": ostreesetup.remote})

        progress = OSTree.AsyncProgress.new()
        progress.connect('changed', self._pullProgressCb)

        pull_opts = {'refs': Variant('as', [ref])}
        # If we're doing a kickstart, we can at least use the content as a reference:
        # See <https://github.com/rhinstaller/anaconda/issues/1117>
        # The first path here is used by <https://pagure.io/fedora-lorax-templates>
        # and the second by <https://github.com/projectatomic/rpm-ostree-toolbox/>
        if OSTree.check_version(2017, 8):
            for path in ['/ostree/repo', '/install/ostree/repo']:
                if os.path.isdir(path + '/objects'):
                    pull_opts['localcache-repos'] = Variant('as', [path])
                    break

        try:
            repo.pull_with_options(ostreesetup.remote,
                                   Variant('a{sv}', pull_opts),
                                   progress, cancellable)
        except GError as e:
            exn = PayloadInstallError("Failed to pull from repository: %s" % e)
            log.error(str(exn))
            if errors.errorHandler.cb(exn) == errors.ERROR_RAISE:
                progressQ.send_quit(1)
                util.ipmi_abort(scripts=self.data.scripts)
                sys.exit(1)

        log.info("ostree pull: %s", progress.get_status() or "")
        progressQ.send_message(_("Preparing deployment of %s") % (ref, ))

        # Now that we have the data pulled, delete the remote for now.
        # This will allow a remote configuration defined in the tree
        # (if any) to override what's in the kickstart.  Otherwise,
        # we'll re-add it in post.  Ideally, ostree would support a
        # pull without adding a remote, but that would get quite
        # complex.
        repo.remote_delete(self.data.ostreesetup.remote, None)

        self._safeExecWithRedirect("ostree",
                                   ["admin", "--sysroot=" + util.getTargetPhysicalRoot(),
                                   "os-init", ostreesetup.osname])

        admin_deploy_args = ["admin", "--sysroot=" + util.getTargetPhysicalRoot(),
                             "deploy", "--os=" + ostreesetup.osname]

        admin_deploy_args.append(ostreesetup.remote + ':' + ref)

        log.info("ostree admin deploy starting")
        progressQ.send_message(_("Deployment starting: %s") % (ref, ))
        self._safeExecWithRedirect("ostree", admin_deploy_args)
        log.info("ostree admin deploy complete")
        progressQ.send_message(_("Deployment complete: %s") % (ref, ))

        # Reload now that we've deployed, find the path to the new deployment
        sysroot.load(None)
        deployments = sysroot.get_deployments()
        assert len(deployments) > 0
        deployment = deployments[0]
        deployment_path = sysroot.get_deployment_directory(deployment)
        util.setSysroot(deployment_path.get_path())

        try:
            self._copyBootloaderData()
        except (OSError, RuntimeError) as e:
            exn = PayloadInstallError("Failed to copy bootloader data: %s" % e)
            log.error(str(exn))
            if errors.errorHandler.cb(exn) == errors.ERROR_RAISE:
                progressQ.send_quit(1)
                util.ipmi_abort(scripts=self.data.scripts)
                sys.exit(1)

        mainctx.pop_thread_default()
Esempio n. 56
0
    def startServer(self):
        self.log.info(_("Starting VNC..."))
        network.wait_for_connectivity()

        # Lets call it from here for now.
        try:
            self.initialize()
        except (socket.herror, dbus.DBusException, ValueError) as e:
            stdoutLog.critical("Could not initialize the VNC server: %s", e)
            util.ipmi_abort(scripts=self.anaconda.ksdata.scripts)
            sys.exit(1)

        if self.password and (len(self.password) < 6
                              or len(self.password) > 8):
            self.changeVNCPasswdWindow()

        if not self.password:
            SecurityTypes = "None"
            rfbauth = "0"
        else:
            SecurityTypes = "VncAuth"
            rfbauth = self.pw_file
            # Create the password file.
            self.setVNCPassword()

        # Lets start the xvnc.
        xvnccommand = [
            XVNC_BINARY_NAME,
            ":%s" % constants.X_DISPLAY_NUMBER, "-depth", "16", "-br",
            "IdleTimeout=0", "-auth", "/dev/null", "-once",
            "DisconnectClients=false",
            "desktop=%s" % (self.desktop, ),
            "SecurityTypes=%s" % SecurityTypes,
            "rfbauth=%s" % rfbauth
        ]

        try:
            util.startX(xvnccommand,
                        output_redirect=self.openlogfile(),
                        timeout=self.timeout)
        except OSError:
            stdoutLog.critical("Could not start the VNC server.  Aborting.")
            util.ipmi_abort(scripts=self.anaconda.ksdata.scripts)
            sys.exit(1)

        self.log.info(_("The VNC server is now running."))

        # Lets tell the user what we are going to do.
        if self.vncconnecthost != "":
            self.log.warning(
                _("\n\nYou chose to connect to a listening vncviewer. \n"
                  "This does not require a password to be set.  If you \n"
                  "set a password, it will be used in case the connection \n"
                  "to the vncviewer is unsuccessful\n\n"))
        elif self.password == "":
            self.log.warning(
                _("\n\nWARNING!!! VNC server running with NO PASSWORD!\n"
                  "You can use the vncpassword=PASSWORD boot option\n"
                  "if you would like to secure the server.\n\n"))
        elif self.password != "":
            self.log.warning(
                _("\n\nYou chose to execute vnc with a password. \n\n"))
        else:
            self.log.warning(_("\n\nUnknown Error.  Aborting. \n\n"))
            util.ipmi_abort(scripts=self.anaconda.ksdata.scripts)
            sys.exit(1)

        # Lets try to configure the vnc server to whatever the user specified
        if self.vncconnecthost != "":
            connected = self.connectToView()
            if not connected:
                self.VNCListen()
        else:
            self.VNCListen()

        # Start vncconfig for copy/paste
        self.startVncConfig()
Esempio n. 57
0
 def prompt(self, args=None):
     prompt = super().prompt(args)
     # TRANSLATORS: 's' to rescan devices
     prompt.add_option(C_('TUI|Spoke Navigation|Partitioning', 's'),
                       _("rescan devices"))
     return prompt
Esempio n. 58
0
 def refresh(self, args=None):
     """Refresh the window."""
     super().refresh(args)
     self.window.add(TextWidget(_(WARNING_SMT_ENABLED_TUI)))
Esempio n. 59
0
def parseKickstart(handler, f, strict_mode=False, pass_to_boss=False):
    # preprocessing the kickstart file has already been handled in initramfs.

    ksparser = AnacondaKSParser(handler)
    kswarnings = []
    showwarning = warnings.showwarning

    def ksshowwarning(message,
                      category,
                      filename,
                      lineno,
                      file=None,
                      line=None):
        # Print the warning with default function.
        showwarning(message, category, filename, lineno, file, line)
        # Collect pykickstart warnings.
        if issubclass(category, KickstartParseWarning):
            kswarnings.append(message)

    try:
        # Process warnings differently in this part.
        with warnings.catch_warnings():

            # Set up the warnings module.
            warnings.showwarning = ksshowwarning
            warnings.simplefilter("always", category=KickstartParseWarning)

            # Parse the kickstart file in DBus modules.
            if pass_to_boss:
                boss = BOSS.get_proxy()
                report = KickstartReport.from_structure(
                    boss.ReadKickstartFile(f))
                for warn in report.warning_messages:
                    warnings.warn(warn.message, KickstartParseWarning)
                if not report.is_valid():
                    message = "\n\n".join(map(str, report.error_messages))
                    raise KickstartError(message)

            # Parse the kickstart file in anaconda.
            ksparser.readKickstart(f)

            # Process pykickstart warnings in the strict mode:
            if strict_mode and kswarnings:
                raise KickstartError(
                    "Please modify your kickstart file to fix the warnings "
                    "or remove the `ksstrict` option.")

    except KickstartError as e:
        # We do not have an interface here yet, so we cannot use our error
        # handling callback.
        parsing_log.error(e)

        # Print kickstart warnings in the strict mode.
        if strict_mode and kswarnings:
            print(
                _("\nSome warnings occurred during reading the kickstart file:"
                  ))
            for w in kswarnings:
                print(str(w).strip())

        # Print an error and terminate.
        print(
            _("\nAn error occurred during reading the kickstart file:"
              "\n%s\n\nThe installer will now terminate.") % str(e).strip())

        util.ipmi_report(IPMI_ABORTED)
        time.sleep(10)
        sys.exit(1)
Esempio n. 60
0
def check_memory(anaconda, options, display_mode=None):
    """Check is the system has enough RAM for installation.

    :param anaconda: instance of the Anaconda class
    :param options: command line/boot options
    :param display_mode: a display mode to use for the check
                         (graphical mode usually needs more RAM, etc.)
    """

    from pyanaconda import isys

    reason_strict = _("%(product_name)s requires %(needed_ram)s MB of memory to "
                      "install, but you only have %(total_ram)s MB on this machine.\n")
    reason_graphical = _("The %(product_name)s graphical installer requires %(needed_ram)s "
                         "MB of memory, but you only have %(total_ram)s MB.\n")

    reboot_extra = _('\n'
                     'Press [Enter] to reboot your system.\n')
    livecd_title = _("Not enough RAM")
    livecd_extra = _(" Try the text mode installer by running:\n\n"
                     "'/usr/bin/liveinst -T'\n\n from a root terminal.")
    nolivecd_extra = _(" Starting text mode.")

    # skip the memory check in rescue mode
    if options.rescue:
        return

    if not display_mode:
        display_mode = anaconda.display_mode

    reason = reason_strict
    total_ram = int(isys.total_memory() / 1024)
    needed_ram = int(isys.MIN_RAM)
    graphical_ram = int(isys.MIN_GUI_RAM)

    # count the squashfs.img in if it is kept in RAM
    if not util.persistent_root_image():
        needed_ram += isys.SQUASHFS_EXTRA_RAM
        graphical_ram += isys.SQUASHFS_EXTRA_RAM

    log.info("check_memory(): total:%s, needed:%s, graphical:%s",
             total_ram, needed_ram, graphical_ram)

    if not options.memcheck:
        log.warning("CHECK_MEMORY DISABLED")
        return

    reason_args = {"product_name": product.productName,
                   "needed_ram": needed_ram,
                   "total_ram": total_ram}
    if needed_ram > total_ram:
        if options.liveinst:
            # pylint: disable=logging-not-lazy
            stdout_log.warning(reason % reason_args)
            gtk_warning(livecd_title, reason % reason_args)
        else:
            reason += reboot_extra
            print(reason % reason_args)
            print(_("The installation cannot continue and the system will be rebooted"))
            print(_("Press ENTER to continue"))
            input()

        util.ipmi_report(constants.IPMI_ABORTED)
        sys.exit(1)

    # override display mode if machine cannot nicely run X
    if display_mode != constants.DisplayModes.TUI and not flags.usevnc:
        needed_ram = graphical_ram
        reason_args["needed_ram"] = graphical_ram
        reason = reason_graphical

        if needed_ram > total_ram:
            if options.liveinst:
                reason += livecd_extra
                # pylint: disable=logging-not-lazy
                stdout_log.warning(reason % reason_args)
                title = livecd_title
                gtk_warning(title, reason % reason_args)
                util.ipmi_report(constants.IPMI_ABORTED)
                sys.exit(1)
            else:
                reason += nolivecd_extra
                # pylint: disable=logging-not-lazy
                stdout_log.warning(reason % reason_args)
                anaconda.display_mode = constants.DisplayModes.TUI
                time.sleep(2)