def write_storage_configuration(storage, sysroot=None): """Write the storage configuration to sysroot. :param storage: the storage object :param sysroot: a path to the target OS installation """ if sysroot is None: sysroot = util.getSysroot() if not os.path.isdir("%s/etc" % sysroot): os.mkdir("%s/etc" % sysroot) _write_escrow_packets(storage, sysroot) storage.make_mtab() storage.fsset.write() iscsi.write(sysroot, storage) fcoe_proxy = STORAGE.get_proxy(FCOE) fcoe_proxy.WriteConfiguration(sysroot) if arch.is_s390(): zfcp_proxy = STORAGE.get_proxy(ZFCP) zfcp_proxy.WriteConfiguration(sysroot) _write_dasd_conf(storage, sysroot)
def _reset_storage(storage): """Do reset the storage. FIXME: Call the DBus task instead of this function. :param storage: an instance of the Blivet's storage object """ # Set the ignored and exclusive disks. disk_select_proxy = STORAGE.get_proxy(DISK_SELECTION) storage.ignored_disks = disk_select_proxy.IgnoredDisks storage.exclusive_disks = disk_select_proxy.ExclusiveDisks storage.protected_devices = disk_select_proxy.ProtectedDevices storage.disk_images = disk_select_proxy.DiskImages # Reload additional modules. if not conf.target.is_image: iscsi.startup() fcoe_proxy = STORAGE.get_proxy(FCOE) fcoe_proxy.ReloadModule() if arch.is_s390(): zfcp_proxy = STORAGE.get_proxy(ZFCP) zfcp_proxy.ReloadModule() # Do the reset. storage.reset()
def __init__(self, data, storage, payload): super().__init__(data, storage, payload) self.title = N_("Assign mount points") self._container = None self._disk_select_proxy = STORAGE.get_proxy(DISK_SELECTION) self._manual_part_proxy = STORAGE.get_proxy(MANUAL_PARTITIONING) self._mount_info = self._gather_mount_info()
def applyDiskSelection(storage, data, use_names): onlyuse = use_names[:] for disk in (d for d in storage.disks if d.name in onlyuse): onlyuse.extend(d.name for d in disk.ancestors if d.name not in onlyuse and d.is_disk) disk_select_proxy = STORAGE.get_proxy(DISK_SELECTION) disk_select_proxy.SetSelectedDisks(onlyuse) disk_init_proxy = STORAGE.get_proxy(DISK_INITIALIZATION) disk_init_proxy.SetDrivesToClear(use_names)
def teardown_device(device_name): """Close, or tear down, a device. :param device_name: a device name """ device_tree = STORAGE.get_proxy(DEVICE_TREE) device_tree.TeardownDevice(device_name)
def test_evaluation_existing_part_must_exist_rules( proxy_getter, rule_data, ksdata_mock, storage_mock): rules = [ "part /tmp", "part /", ] for rule in rules: rule_data.new_rule(rule) device_tree_mock = STORAGE.get_proxy(DEVICE_TREE) device_tree_mock.GetDeviceMountOptions.return_value = "defaults" device_tree_mock.GetMountPoints.return_value = { "/tmp": "/dev/sda1", "/": "/dev/sda2", } messages = rule_data.eval_rules(ksdata_mock, storage_mock) # partitions exist --> no errors, warnings or additional info assert not messages # no additional mount options specified device_tree_mock.SetDeviceMountOptions.assert_has_calls([ mock.call("/dev/sda1", "defaults"), mock.call("/dev/sda2", "defaults"), ])
def _get_initialization_config(self): """Get the initialization config. FIXME: This is a temporary method. """ config = DiskInitializationConfig() # Update the config. disk_init_proxy = STORAGE.get_proxy(DISK_INITIALIZATION) config.initialization_mode = disk_init_proxy.InitializationMode config.drives_to_clear = disk_init_proxy.DrivesToClear config.devices_to_clear = disk_init_proxy.DevicesToClear config.initialize_labels = disk_init_proxy.InitializeLabelsEnabled config.format_unrecognized = disk_init_proxy.FormatUnrecognizedEnabled config.clear_non_existent = False # Update the disk label. disk_label = disk_init_proxy.DefaultDiskLabel if disk_label and not DiskLabel.set_default_label_type(disk_label): log.warning("%s is not a supported disklabel type on this platform. " "Using default disklabel %s instead.", disk_label, DiskLabel.get_platform_label_types()[0]) return config
def test_canceled_progress(self, proxy_getter, statvfs_mock): """Test the canceled installation progress.""" callback = Mock() with tempfile.TemporaryDirectory() as sysroot: os.mkdir(join_paths(sysroot, "/boot")) os.mkdir(join_paths(sysroot, "/home")) device_tree = STORAGE.get_proxy(DEVICE_TREE) device_tree.GetMountPoints.return_value = { "/": "dev1", "/boot": "dev2", "/home": "dev3", } statvfs_mock.return_value = \ Mock(f_frsize=1024, f_blocks=150, f_bfree=100) progress = InstallationProgress( sysroot=sysroot, callback=callback, installation_size=1024 * 100 ) with progress: time.sleep(2) expected = [ call("Synchronizing writes to disk"), call("Installing software 0%") ] assert callback.call_args_list == expected
def input(self, args, key): """ Grab the choice and update things. """ if not self._container.process_user_input(key): # TRANSLATORS: 's' to rescan devices if key.lower() == C_('TUI|Spoke Navigation|Partitioning', 's'): text = _("Warning: This will revert all changes done so far.\nDo you want to proceed?\n") question_window = YesNoDialog(text) ScreenHandler.push_screen_modal(question_window) if question_window.answer: # unset selected disks temporarily so that # storage_initialize() processes all devices disk_select_proxy = STORAGE.get_proxy(DISK_SELECTION) selected_disks = disk_select_proxy.SelectedDisks disk_select_proxy.SetSelectedDisks([]) print(_("Scanning disks. This may take a moment...")) storage_initialize(self.storage, self.data, self.storage.protected_dev_names) disk_select_proxy.SetSelectedDisks(selected_disks) self.data.mount.clear_mount_data() self._gather_mount_data_info() self.redraw() return InputState.PROCESSED # TRANSLATORS: 'c' to continue elif key.lower() == C_('TUI|Spoke Navigation', 'c'): self.apply() return super().input(args, key) return InputState.PROCESSED
def parse(self, args): """Do not parse anything. Only validate the bootloader module. """ super().parse(args) # Validate the attributes of the bootloader module. bootloader_proxy = STORAGE.get_proxy(BOOTLOADER) # Skip the check if the bootloader instance is not GRUB2: if not isinstance(get_bootloader(), GRUB2): return # Check the location support. if bootloader_proxy.PreferredLocation == BOOTLOADER_LOCATION_PARTITION: raise KickstartParseError( _("GRUB2 does not support installation to a partition."), lineno=self.lineno) # Check the password format. if bootloader_proxy.IsPasswordSet \ and bootloader_proxy.IsPasswordEncrypted \ and not bootloader_proxy.Password.startswith("grub.pbkdf2."): raise KickstartParseError( _("GRUB2 encrypted password must be in grub.pbkdf2 format."), lineno=self.lineno)
def _filter_default_partitions(requests): """Filter default partitions based on the kickstart data. :param requests: a list of requests :return: a customized list of requests """ auto_part_proxy = STORAGE.get_proxy(AUTO_PARTITIONING) skipped_mountpoints = set() skipped_fstypes = set() # Create sets of mountpoints and fstypes to remove from autorequests. if auto_part_proxy.Enabled: # Remove /home if --nohome is selected. if auto_part_proxy.NoHome: skipped_mountpoints.add("/home") # Remove /boot if --noboot is selected. if auto_part_proxy.NoBoot: skipped_mountpoints.add("/boot") # Remove swap if --noswap is selected. if auto_part_proxy.NoSwap: skipped_fstypes.add("swap") # Swap will not be recommended by the storage checker. # TODO: Remove this code from this function. from pyanaconda.storage.checker import storage_checker storage_checker.add_constraint(STORAGE_SWAP_IS_RECOMMENDED, False) # Skip mountpoints we want to remove. return [ req for req in requests if req.mountpoint not in skipped_mountpoints and req.fstype not in skipped_fstypes ]
def _clear_partitions(self, storage): """Clear partitions. :param storage: an instance of Blivet """ disk_init_proxy = STORAGE.get_proxy(DISK_INITIALIZATION) storage.config.clear_part_type = disk_init_proxy.InitializationMode storage.config.clear_part_disks = disk_init_proxy.DrivesToClear storage.config.clear_part_devices = disk_init_proxy.DevicesToClear storage.config.initialize_disks = disk_init_proxy.InitializeLabelsEnabled disk_label = disk_init_proxy.DefaultDiskLabel if disk_label and not DiskLabel.set_default_label_type(disk_label): log.warning( "%s is not a supported disklabel type on this platform. " "Using default disklabel %s instead.", disk_label, DiskLabel.get_platform_label_types()[0]) storage.clear_partitions() # Check the usable disks. if not any(d for d in storage.disks if not d.format.hidden and not d.protected): raise NoDisksError("No usable disks.")
def test_finished_progress(self, proxy_getter, statvfs_mock, sleep_mock): """Test the finished installation progress.""" callback = Mock() with tempfile.TemporaryDirectory() as sysroot: device_tree = STORAGE.get_proxy(DEVICE_TREE) device_tree.GetMountPoints.return_value = { "/": "dev1", "/boot": "dev2", "/home": "dev3", } statvfs_mock.side_effect = [ Mock(f_frsize=1024, f_blocks=150, f_bfree=125), Mock(f_frsize=1024, f_blocks=150, f_bfree=100), Mock(f_frsize=1024, f_blocks=150, f_bfree=75), Mock(f_frsize=1024, f_blocks=150, f_bfree=45), Mock(f_frsize=1024, f_blocks=150, f_bfree=25), Mock(f_frsize=1024, f_blocks=150, f_bfree=0), ] progress = InstallationProgress(sysroot=sysroot, callback=callback, installation_size=1024 * 100) progress._monitor_progress() expected = [ call("Synchronizing writes to disk"), call("Installing software 25%"), call("Installing software 50%"), call("Installing software 80%"), call("Installing software 100%"), ] assert callback.call_args_list == expected
def _set_storage_defaults(self, storage): fstype = None boot_fstype = None # Get the default fstype from a kickstart file. auto_part_proxy = STORAGE.get_proxy(AUTO_PARTITIONING) if auto_part_proxy.Enabled and auto_part_proxy.FilesystemType: fstype = auto_part_proxy.FilesystemType boot_fstype = fstype # Or from an install class. elif self.instClass.defaultFS: fstype = self.instClass.defaultFS boot_fstype = None # Set the default fstype. if fstype: storage.set_default_fstype(fstype) # Set the default boot fstype. if boot_fstype: storage.set_default_boot_fstype(boot_fstype) # Set the default LUKS version. luks_version = self.instClass.default_luks_version if luks_version: storage.set_default_luks_version(luks_version) # Set the default partitioning. storage.set_default_partitioning(self.instClass.default_partitioning)
def setup(self, storage, ksdata, payload): # the kdump addon should run only if requested if not flags.cmdline.getbool("kdump_addon", default=False): return bootloader_proxy = STORAGE.get_proxy(BOOTLOADER) # Clear any existing crashkernel bootloader arguments extra_args = bootloader_proxy.ExtraArguments new_args = [arg for arg in extra_args if not arg.startswith('crashkernel=')] # Copy our reserved amount to the bootloader arguments if self.enabled: # Ensure that the amount is an amount in MB if self.reserveMB[-1] != 'M': self.reserveMB += 'M' new_args.append(' crashkernel=%s' % self.reserveMB) bootloader_proxy.SetExtraArguments(new_args) # Do the same thing with the storage.bootloader.boot_args set if storage.bootloader.boot_args: crashargs = [arg for arg in storage.bootloader.boot_args \ if arg.startswith('crashkernel=')] storage.bootloader.boot_args -= set(crashargs) if self.enabled: storage.bootloader.boot_args.add('crashkernel=%s' % self.reserveMB) ksdata.packages.packageList.append("kexec-tools") if self.enablefadump and os.path.exists(FADUMP_CAPABLE_FILE): storage.bootloader.boot_args.add('fadump=on')
def do_format(self): """Format with a remote task.""" disk_names = [disk.name for disk in self._dasds] task_path = self._dasd_module.FormatWithTask(disk_names) task_proxy = STORAGE.get_proxy(task_path) sync_run_task(task_proxy, callback=self._report_progress)
def reset_storage(storage, scan_all=False, retry=True): """Reset the storage model. :param storage: an instance of the Blivet's storage object :param scan_all: should we scan all devices in the system? :param retry: should we allow to retry the reset? """ # Clear the exclusive disks to scan all devices in the system. if scan_all: disk_select_proxy = STORAGE.get_proxy(DISK_SELECTION) disk_select_proxy.SetExclusiveDisks([]) # Do the reset. while True: try: _reset_storage(storage) except StorageError as e: # Is the retry allowed? if not retry: raise # Does the user want to retry? elif error_handler.cb(e) == ERROR_RAISE: raise # Retry the storage reset. else: continue else: # No need to retry. break
def _filter_default_partitions(requests): """Filter default partitions based on the kickstart data. :param requests: a list of requests :return: a customized list of requests """ auto_part_proxy = STORAGE.get_proxy(AUTO_PARTITIONING) skipped_mountpoints = set() skipped_fstypes = set() # Create sets of mountpoints and fstypes to remove from autorequests. if auto_part_proxy.Enabled: # Remove /home if --nohome is selected. if auto_part_proxy.NoHome: skipped_mountpoints.add("/home") # Remove /boot if --noboot is selected. if auto_part_proxy.NoBoot: skipped_mountpoints.add("/boot") # Remove swap if --noswap is selected. if auto_part_proxy.NoSwap: skipped_fstypes.add("swap") # Swap will not be recommended by the storage checker. # TODO: Remove this code from this function. from pyanaconda.storage.checker import storage_checker storage_checker.set_constraint(STORAGE_SWAP_IS_RECOMMENDED, False) # Skip mountpoints we want to remove. return [ req for req in requests if req.mountpoint not in skipped_mountpoints and req.fstype not in skipped_fstypes ]
def time_initialize(timezone_proxy): """ Try to guess if RTC uses UTC time or not, set timezone.isUtc properly and set system time from RTC using the UTC guess. Guess is done by searching for bootable ntfs devices. :param timezone_proxy: DBus proxy of the timezone module """ if arch.is_s390(): # nothing to do on s390(x) were hwclock doesn't exist return if not timezone_proxy.IsUTC and not flags.automatedInstall: # if set in the kickstart, no magic needed here threadMgr.wait(THREAD_STORAGE) bootloader_proxy = STORAGE.get_proxy(BOOTLOADER) is_utc = not bootloader_proxy.DetectWindows() timezone_proxy.SetIsUTC(is_utc) cmd = "hwclock" args = ["--hctosys"] if timezone_proxy.IsUTC: args.append("--utc") else: args.append("--localtime") util.execWithRedirect(cmd, args)
def _gather_mount_data_info(self): self._mds = OrderedDict() disk_select_proxy = STORAGE.get_proxy(DISK_SELECTION) selected_disks = disk_select_proxy.SelectedDisks for device in self.storage.devicetree.leaves: if not self._is_dev_usable(device, selected_disks): continue fmt = device.format.type for ks_md in self.data.mount.dataList(): if device is self.storage.devicetree.resolve_device(ks_md.device): # already have a configuration for the device in ksdata, # let's just copy it mdrec = MountDataRecorder(device=ks_md.device, mount_point=ks_md.mount_point, format=ks_md.format, reformat=ks_md.reformat) # and make sure the new version is put back self.data.mount.remove_mount_data(ks_md) mdrec.modified = True break else: if device.format.mountable and device.format.mountpoint: mpoint = device.format.mountpoint else: mpoint = None mdrec = MountDataRecorder(device=device.path, mount_point=mpoint, format=fmt, reformat=False) mdrec.orig_format = fmt self._mds[device.name] = mdrec
def _do_mount(self): """Run CD-ROM installation source setup.""" log.debug("Trying to detect CD-ROM automatically") device_tree = STORAGE.get_proxy(DEVICE_TREE) device_name = "" for dev_name in device_tree.FindOpticalMedia(): try: device_data = DeviceData.from_structure( device_tree.GetDeviceData(dev_name)) mount(device_data.path, self._target_mount, "iso9660", "ro") except PayloadSetupError as e: log.debug("Failed to mount %s: %s", dev_name, str(e)) continue if is_valid_install_disk(self._target_mount): device_name = dev_name log.info("using CD-ROM device %s mounted at %s", dev_name, self._target_mount) break else: unmount(self._target_mount) if not device_name: raise SourceSetupError("Found no CD-ROM") return device_name
def _get_initialization_config(self): """Get the initialization config. FIXME: This is a temporary method. """ config = DiskInitializationConfig() # Update the config. disk_init_proxy = STORAGE.get_proxy(DISK_INITIALIZATION) config.initialization_mode = disk_init_proxy.InitializationMode config.drives_to_clear = disk_init_proxy.DrivesToClear config.devices_to_clear = disk_init_proxy.DevicesToClear config.initialize_labels = disk_init_proxy.InitializeLabelsEnabled config.format_unrecognized = disk_init_proxy.FormatUnrecognizedEnabled config.clear_non_existent = False # Update the disk label. disk_label = disk_init_proxy.DefaultDiskLabel if disk_label and not DiskLabel.set_default_label_type(disk_label): log.warning( "%s is not a supported disklabel type on this platform. " "Using default disklabel %s instead.", disk_label, DiskLabel.get_platform_label_types()[0]) return config
def get_mount_points(): """Get mount points in the device tree. :return: a dictionary of mount points and device names """ device_tree = STORAGE.get_proxy(DEVICE_TREE) return device_tree.GetMountPoints()
def __init__(self, data, storage, payload): super().__init__(data, storage, payload) self.title = N_("Select device containing the ISO file") self._container = None self._device_tree = STORAGE.get_proxy(DEVICE_TREE) self._mountable_devices = self._get_mountable_devices() self._device = None
def setup_device(device_name): """Open, or set up, a device. :param device_name: a device name """ device_tree = STORAGE.get_proxy(DEVICE_TREE) device_tree.SetupDevice(device_name)
def _check_space_and_run_dialog(self, partitioning, disks): # User wants to reclaim the space. if self._reclaim_checkbox.get_active(): return RESPONSE_RECLAIM # Get the device tree of the partitioning module. device_tree = STORAGE.get_proxy(partitioning.GetDeviceTree()) # Calculate the required and free space. disk_free = Size(device_tree.GetDiskFreeSpace(disks)) fs_free = Size(device_tree.GetDiskReclaimableSpace(disks)) disks_size = Size(device_tree.GetDiskTotalSpace(disks)) sw_space = Size(self.payload.space_required) auto_swap = suggest_swap_size() log.debug("disk free: %s fs free: %s sw needs: %s auto swap: %s", disk_free, fs_free, sw_space, auto_swap) # We need enough space for the software, the swap and the metadata. # It is not an ideal estimate, but it works. required_space = sw_space + auto_swap + STORAGE_METADATA_RATIO * disk_free # There is enough space to continue. if disk_free >= required_space: return RESPONSE_OK # Ask user what to do. if disks_size >= required_space - auto_swap: dialog = NeedSpaceDialog(self.data, payload=self.payload) dialog.refresh(required_space, sw_space, auto_swap, disk_free, fs_free) else: dialog = NoSpaceDialog(self.data, payload=self.payload) dialog.refresh(required_space, sw_space, auto_swap, disk_free, fs_free) return self.run_lightbox_dialog(dialog)
def _configure_partitioning(self, storage): """Configure the partitioning. :param storage: an instance of Blivet """ log.debug("Executing the automatic partitioning.") # Create the auto partitioning proxy. auto_part_proxy = STORAGE.get_proxy(AUTO_PARTITIONING) # Set the filesystem type. fstype = auto_part_proxy.FilesystemType if fstype: storage.set_default_fstype(fstype) # Set the default pbkdf args. pbkdf_args = self._luks_format_args.get('pbkdf_args', None) if pbkdf_args and not luks_data.pbkdf_args: luks_data.pbkdf_args = pbkdf_args # Set the minimal entropy. min_luks_entropy = self._luks_format_args.get('min_luks_entropy', None) if min_luks_entropy is not None: luks_data.min_entropy = min_luks_entropy # Get the autopart requests. requests = self._get_autopart_requests(storage) # Do the autopart. self._do_autopart(storage, self._scheme, requests, self._encrypted, self._luks_format_args)
def _configure_partitioning(self, storage): """Configure the partitioning. :param storage: an instance of Blivet """ log.debug("Executing the automatic partitioning.") # Create the auto partitioning proxy. auto_part_proxy = STORAGE.get_proxy(AUTO_PARTITIONING) # Set the filesystem type. fstype = auto_part_proxy.FilesystemType if fstype: storage.set_default_fstype(fstype) storage.set_default_boot_fstype(fstype) # Set the default pbkdf args. pbkdf_args = self._luks_format_args.get('pbkdf_args', None) if pbkdf_args and not luks_data.pbkdf_args: luks_data.pbkdf_args = pbkdf_args # Set the minimal entropy. min_luks_entropy = self._luks_format_args.get('min_luks_entropy', None) if min_luks_entropy is not None: luks_data.min_entropy = min_luks_entropy # Get the autopart requests. requests = self._get_autopart_requests(storage) # Do the autopart. self._do_autopart(storage, self._scheme, requests, self._encrypted, self._luks_format_args)
def test_evaluation_add_mount_options_report_only( proxy_getter, rule_data, ksdata_mock, storage_mock): rules = [ "part /tmp --mountoptions=nodev", "part / --mountoptions=noauto", ] messages = get_messages_for_partition_rules( rule_data, ksdata_mock, storage_mock, rules, 1, report_only=True) # two mount options added --> two info messages assert len(messages) == 2 assert messages[0].type == common.MESSAGE_TYPE_INFO assert messages[1].type == common.MESSAGE_TYPE_INFO # newly added mount options should be mentioned in the messages # together with their mount points nodev_found = False noauto_found = False for message in messages: if "'nodev'" in message.text: assert "/tmp" in message.text nodev_found = True elif "'noauto'" in message.text: assert "/" in message.text noauto_found = True assert all([nodev_found, noauto_found]) # no changes should be made device_tree_mock = STORAGE.get_proxy(DEVICE_TREE) device_tree_mock.SetDeviceMountOptions.assert_not_called()
def run(self): """Run the task. :return: list of bindmounts created for internal use :rtype: list of str """ device_tree = STORAGE.get_proxy(DEVICE_TREE) mount_points = device_tree.GetMountPoints() # Make /usr readonly like ostree does at runtime normally self._setup_internal_bindmount('/usr', bind_ro=True, src_physical=False) self._handle_api_mount_points() self._handle_var_mount_point(mount_points) self._fill_var_subdirectories() self._handle_other_mount_points(mount_points) # And finally, do a nonrecursive bind for the sysroot self._setup_internal_bindmount("/", dest="/sysroot", recurse=False) return self._internal_mounts
def _ensure_init_storage(self): """ If a different clearpart type was chosen or mount point assignment was chosen instead, we need to reset/rescan storage to revert all changes done by the previous run of doKickstartStorage() and get everything into the initial state. """ # the only safe options are: # 1) if nothing was set before (self._orig_clearpart_type is None) or if self._orig_clearpart_type == CLEAR_PARTITIONS_DEFAULT: return # 2) mount point assignment was done before and user just wants to tweak it if self._orig_mount_assign and self._do_mount_assign: return # else print(_("Reverting previous configuration. This may take a moment...")) # unset selected disks temporarily so that # storage_initialize() processes all devices disk_select_proxy = STORAGE.get_proxy(DISK_SELECTION) selected_disks = disk_select_proxy.SelectedDisks disk_select_proxy.SetSelectedDisks([]) storage_initialize(self.storage, self.data, self.storage.protected_dev_names) disk_select_proxy.SetSelectedDisks(selected_disks) self.data.mount.clear_mount_data()
def __init__(self, data, storage, payload): """ :see: pyanaconda.ui.common.Spoke.__init__ :param data: data object passed to every spoke to load/store data from/to it :type data: pykickstart.base.BaseHandler :param storage: object storing storage-related information (disks, partitioning, bootloader, etc.) :type storage: blivet.Blivet :param payload: object storing payload-related information :type payload: pyanaconda.payload.Payload """ self._error = None self._back_already_clicked = False self._label_actions = None self._button_reset = None self._button_undo = None self._client = None self._blivetgui = None self._partitioning = None self._device_tree = None self._storage_module = STORAGE.get_proxy() StorageCheckHandler.__init__(self) NormalSpoke.__init__(self, data, storage, payload)
def refresh(self): """ The refresh method that is called every time the spoke is displayed. It should update the UI elements according to the contents of self.data. :see: pyanaconda.ui.common.UIObject.refresh """ for thread_name in [THREAD_EXECUTE_STORAGE, THREAD_STORAGE]: threadMgr.wait(thread_name) if not self._partitioning: # Create the partitioning now. It cannot by done earlier, because # the storage spoke would use it as a default partitioning. self._partitioning = create_partitioning( PARTITIONING_METHOD_BLIVET) self._device_tree = STORAGE.get_proxy( self._partitioning.GetDeviceTree()) self._back_already_clicked = False self._client.initialize(self._partitioning.SendRequest) self._blivetgui.initialize() # if we re-enter blivet-gui spoke, actions from previous visit were # not removed, we need to update number of blivet-gui actions self._blivetgui.set_actions(self._client.get_actions())
def on_login_clicked(self, *args): """Start the login task.""" row = self._find_row_for_login() # Skip, if there is nothing to do. if not row: return # First update widgets. self._set_login_sensitive(False) self._okButton.set_sensitive(False) self._cancelButton.set_sensitive(False) self._loginButton.set_sensitive(False) self._loginConditionNotebook.set_current_page(0) # Get data. portal = self._get_portal() node = self._find_node_for_row(row) _style, credentials = self._get_login_style_and_credentials() # Get the login task. task_path = self._iscsi_module.LoginWithTask( Portal.to_structure(portal), Credentials.to_structure(credentials), Node.to_structure(node)) task_proxy = STORAGE.get_proxy(task_path) # Start the login. async_run_task( task_proxy, lambda task_proxy: self.process_login_result(task_proxy, row)) self._loginSpinner.start() self._loginSpinner.show()
def __init__(self, data): super().__init__(data) self._discovered_nodes = [] self._update_devicetree = False self._authTypeCombo = self.builder.get_object("authTypeCombo") self._authNotebook = self.builder.get_object("authNotebook") self._iscsiNotebook = self.builder.get_object("iscsiNotebook") self._loginButton = self.builder.get_object("loginButton") self._retryLoginButton = self.builder.get_object("retryLoginButton") self._loginAuthTypeCombo = self.builder.get_object( "loginAuthTypeCombo") self._loginAuthNotebook = self.builder.get_object("loginAuthNotebook") self._loginGrid = self.builder.get_object("loginGrid") self._loginConditionNotebook = self.builder.get_object( "loginConditionNotebook") self._configureGrid = self.builder.get_object("configureGrid") self._conditionNotebook = self.builder.get_object("conditionNotebook") self._bindCheckbox = self.builder.get_object("bindCheckbutton") self._startButton = self.builder.get_object("startButton") self._okButton = self.builder.get_object("okButton") self._cancelButton = self.builder.get_object("cancelButton") self._retryButton = self.builder.get_object("retryButton") self._initiatorEntry = self.builder.get_object("initiatorEntry") self._store = self.builder.get_object("nodeStore") self._storeFilter = self.builder.get_object("nodeStoreFiltered") self._discoverySpinner = self.builder.get_object("waitSpinner") self._discoveryErrorLabel = self.builder.get_object( "discoveryErrorLabel") self._discoveredLabel = self.builder.get_object("discoveredLabel") self._loginSpinner = self.builder.get_object("loginSpinner") self._loginErrorLabel = self.builder.get_object("loginErrorLabel") self._iscsi_module = STORAGE.get_proxy(ISCSI)
def find_optical_install_media(): """Find a device with a valid optical install media. Return the first device containing a valid optical install media for this product. FIXME: This is duplicated in SetUpCdromSourceTask.run :return: a device name or None """ device_tree = STORAGE.get_proxy(DEVICE_TREE) for dev in device_tree.FindOpticalMedia(): mountpoint = tempfile.mkdtemp() try: try: payload_utils.mount_device(dev, mountpoint) except MountFilesystemError: continue try: from pyanaconda.modules.payloads.source.utils import is_valid_install_disk if not is_valid_install_disk(mountpoint): continue finally: payload_utils.unmount_device(dev, mountpoint) finally: os.rmdir(mountpoint) return dev return None
def customizeDefaultPartitioning(self, storage, data): # Customize the default partitioning with kickstart data. auto_part_proxy = STORAGE.get_proxy(AUTO_PARTITIONING) skipped_mountpoints = set() skipped_fstypes = set() # Create sets of mountpoints and fstypes to remove from autorequests. if auto_part_proxy.Enabled: # Remove /home if --nohome is selected. if auto_part_proxy.NoHome: skipped_mountpoints.add("/home") # Remove /boot if --noboot is selected. if auto_part_proxy.NoBoot: skipped_mountpoints.add("/boot") # Remove swap if --noswap is selected. if auto_part_proxy.NoSwap: skipped_fstypes.add("swap") # Swap will not be recommended by the storage checker. from pyanaconda.storage_utils import storage_checker storage_checker.add_constraint(STORAGE_SWAP_IS_RECOMMENDED, False) # Skip mountpoints we want to remove. storage.autopart_requests = [ req for req in storage.autopart_requests if req.mountpoint not in skipped_mountpoints and req.fstype not in skipped_fstypes ]
def execute(self, storage, dry_run=False): """Execute the bootloader.""" log.debug("Execute the bootloader with dry run %s.", dry_run) bootloader_proxy = STORAGE.get_proxy(BOOTLOADER) # Skip bootloader for s390x image installation. if blivet.arch.is_s390() \ and conf.target.is_image \ and bootloader_proxy.BootloaderMode == BOOTLOADER_ENABLED: bootloader_proxy.SetBootloaderMode(BOOTLOADER_SKIPPED) # Is the bootloader enabled? if bootloader_proxy.BootloaderMode != BOOTLOADER_ENABLED: storage.bootloader.skip_bootloader = True log.debug("Bootloader is not enabled, skipping.") return # Update the disk list. Disks are already sorted by Blivet. storage.bootloader.set_disk_list([d for d in storage.disks if d.partitioned]) # Apply the settings. self._update_flags(storage, bootloader_proxy) self._apply_args(storage, bootloader_proxy) self._apply_location(storage, bootloader_proxy) self._apply_password(storage, bootloader_proxy) self._apply_timeout(storage, bootloader_proxy) self._apply_drive_order(storage, bootloader_proxy, dry_run=dry_run) self._apply_boot_drive(storage, bootloader_proxy, dry_run=dry_run) # Set the stage2 and stage1 devices. if not dry_run: storage.bootloader.stage2_device = storage.boot_device storage.bootloader.set_stage1_device(storage.devices)
def test_evaluation_add_mount_option_prefix( proxy_getter, rule_data, ksdata_mock, storage_mock): rules = [ "part /tmp --mountoptions=nodev", "part / --mountoptions=noauto", ] mount_options = { "/": "defaults", "/tmp": "defaults,nodevice", } messages = get_messages_for_partition_rules( rule_data, ksdata_mock, storage_mock, rules, mount_options=mount_options) # two mount options added (even though it is a prefix of another one) # --> two info messages assert len(messages) == 2 assert messages[0].type == common.MESSAGE_TYPE_INFO assert messages[1].type == common.MESSAGE_TYPE_INFO # the option should be added even though it is a prefix of another one device_tree_mock = STORAGE.get_proxy(DEVICE_TREE) device_tree_mock.SetDeviceMountOptions.assert_has_calls([ mock.call("/dev/sda1", "defaults,nodevice,nodev"), ])
def __init__(self, data, storage, disks, show_remove=True, set_boot=True): super().__init__(data) self._storage = storage self.disks = [] self._view = self.builder.get_object("disk_tree_view") self._store = self.builder.get_object("disk_store") self._selection = self.builder.get_object("disk_selection") self._summary_label = self.builder.get_object("summary_label") self._set_button = self.builder.get_object("set_as_boot_button") self._remove_button = self.builder.get_object("remove_button") self._bootloader_proxy = STORAGE.get_proxy(BOOTLOADER) self._previousID = None for disk in disks: self._store.append([False, "%s (%s)" % (disk.description, disk.serial), str(disk.size), str(self._storage.get_disk_free_space([disk])), disk.name, disk.id]) self.disks = disks[:] self._update_summary() if not show_remove: self.builder.get_object("remove_button").hide() if not set_boot: self._set_button.hide() if not disks: return # Don't select a boot device if no boot device is asked for. if self._bootloader_proxy.BootloaderMode != BOOTLOADER_ENABLED: return # Set up the default boot device. Use what's in the ksdata if anything, # then fall back to the first device. boot_drive = self._bootloader_proxy.Drive default_id = None if boot_drive: for d in self.disks: if d.name == boot_drive: default_id = d.id if not default_id: default_id = self.disks[0].id # And then select it in the UI. for row in self._store: if row[ID_COL] == default_id: self._previousID = row[ID_COL] row[IS_BOOT_COL] = True break
def configure_storage(storage, data=None, interactive=False): """Setup storage state from the kickstart data. :param storage: an instance of the Blivet's storage object :param data: an instance of kickstart data or None :param interactive: use a task for the interactive partitioning """ auto_part_proxy = STORAGE.get_proxy(AUTO_PARTITIONING) if interactive: task = InteractivePartitioningTask(storage) elif auto_part_proxy.Enabled: luks_version = auto_part_proxy.LUKSVersion or storage.default_luks_version passphrase = auto_part_proxy.Passphrase or storage.encryption_passphrase escrow_cert = storage.get_escrow_certificate(auto_part_proxy.Escrowcert) pbkdf_args = get_pbkdf_args( luks_version=luks_version, pbkdf_type=auto_part_proxy.PBKDF or None, max_memory_kb=auto_part_proxy.PBKDFMemory, iterations=auto_part_proxy.PBKDFIterations, time_ms=auto_part_proxy.PBKDFTime ) luks_format_args = { "passphrase": passphrase, "cipher": auto_part_proxy.Cipher, "luks_version": luks_version, "pbkdf_args": pbkdf_args, "escrow_cert": escrow_cert, "add_backup_passphrase": auto_part_proxy.BackupPassphraseEnabled, "min_luks_entropy": MIN_CREATE_ENTROPY, } task = AutomaticPartitioningTask( storage, auto_part_proxy.Type, auto_part_proxy.Encrypted, luks_format_args ) elif STORAGE.get_proxy(MANUAL_PARTITIONING).Enabled: task = ManualPartitioningTask(storage) else: task = CustomPartitioningTask(storage, data) task.run()
def ignore_nvdimm_blockdevs(): """Add nvdimm devices to be ignored to the ignored disks.""" if conf.target.is_directory: return nvdimm_proxy = STORAGE.get_proxy(NVDIMM) ignored_nvdimm_devs = nvdimm_proxy.GetDevicesToIgnore() if not ignored_nvdimm_devs: return log.debug("Adding NVDIMM devices %s to ignored disks", ",".join(ignored_nvdimm_devs)) disk_select_proxy = STORAGE.get_proxy(DISK_SELECTION) ignored_disks = disk_select_proxy.IgnoredDisks ignored_disks.extend(ignored_nvdimm_devs) disk_select_proxy.SetIgnoredDisks(ignored_disks)
def reset_bootloader(storage): """Reset the bootloader. :param storage: an instance of the Blivet's storage object """ bootloader_proxy = STORAGE.get_proxy(BOOTLOADER) bootloader_proxy.SetDrive(BOOTLOADER_DRIVE_UNSET) storage.bootloader.reset()
def _update_custom_storage(storage, ksdata): """Update kickstart data for custom storage. :param storage: an instance of the storage :param ksdata: an instance of kickstart data """ auto_part_proxy = STORAGE.get_proxy(AUTO_PARTITIONING) manual_part_proxy = STORAGE.get_proxy(MANUAL_PARTITIONING) # Clear out whatever was there before. reset_custom_storage_data(ksdata) # Check if the custom partitioning was used. if auto_part_proxy.Enabled or manual_part_proxy.Enabled: log.debug("Custom partitioning is disabled.") return # FIXME: This is an ugly temporary workaround for UI. PartitioningModule._setup_kickstart_from_storage(ksdata, storage)
def _configure_partitioning(self, storage): """Configure the partitioning. :param storage: an instance of Blivet """ log.debug("Setting up the mount points.") manual_part_proxy = STORAGE.get_proxy(MANUAL_PARTITIONING) # Set up mount points. for mount_data in manual_part_proxy.MountPoints: self._setup_mount_point(storage, mount_data)
def __init__(self): self._dasds = [] self._can_format_unformatted = True self._can_format_ldl = True self._report = Signal() self._report.connect(log.debug) self._last_message = "" self._dasd_module = STORAGE.get_proxy(DASD)
def ignore_oemdrv_disks(): """Ignore disks labeled OEMDRV.""" matched = device_matches("LABEL=OEMDRV", disks_only=True) for oemdrv_disk in matched: disk_select_proxy = STORAGE.get_proxy(DISK_SELECTION) ignored_disks = disk_select_proxy.IgnoredDisks if oemdrv_disk not in ignored_disks: log.info("Adding disk %s labeled OEMDRV to ignored disks.", oemdrv_disk) ignored_disks.append(oemdrv_disk) disk_select_proxy.SetIgnoredDisks(ignored_disks)
def set_storage_defaults_from_kickstart(storage): """Set the storage default values from a kickstart file. FIXME: A temporary workaround for UI. """ # Set the default filesystem types. auto_part_proxy = STORAGE.get_proxy(AUTO_PARTITIONING) fstype = auto_part_proxy.FilesystemType if auto_part_proxy.Enabled and fstype: storage.set_default_fstype(fstype) storage.set_default_boot_fstype(fstype)
def __init__(self, data): super().__init__(data) self._view = self.builder.get_object("disk_tree_view") self._store = self.builder.get_object("disk_store") self._selection = self.builder.get_object("disk_selection") self._summary_label = self.builder.get_object("summary_label") self._set_button = self.builder.get_object("set_as_boot_button") self._remove_button = self.builder.get_object("remove_button") self._bootloader_proxy = STORAGE.get_proxy(BOOTLOADER)
def _update_nvdimm_data(storage): """Update kickstart data for NVDIMM. FIXME: Move the logic to the iSCSI DBus module. :param storage: an instance of the storage """ nvdimm_proxy = STORAGE.get_proxy(NVDIMM) nvdimm_proxy.SetNamespacesToUse([ d.devname for d in storage.disks if isinstance(d, NVDIMMNamespaceDevice) ])
def __init__(self, data, storage, payload): super().__init__(data, storage, payload) self.title = N_("Partitioning Options") self._container = None self._part_type_list = sorted(PARTTYPES.keys()) # remember the original values so that we can detect a change self._disk_init_proxy = STORAGE.get_proxy(DISK_INITIALIZATION) self._orig_init_mode = self._disk_init_proxy.InitializationMode self._manual_part_proxy = STORAGE.get_proxy(MANUAL_PARTITIONING) self._orig_mount_assign = self._manual_part_proxy.Enabled # Create the auto partitioning proxy self._auto_part_proxy = STORAGE.get_proxy(AUTO_PARTITIONING) # default to mount point assignment if it is already (partially) # configured self._do_mount_assign = self._orig_mount_assign if not self._do_mount_assign: self._init_mode = self._disk_init_proxy.InitializationMode else: self._init_mode = CLEAR_PARTITIONS_NONE
def unmark_protected_device(storage, spec): """Unmark a device as protected. :param storage: an instance of the storage :param spec: a specification of the device """ disk_selection_proxy = STORAGE.get_proxy(DISK_SELECTION) protected_devices = disk_selection_proxy.ProtectedDevices if spec in protected_devices: protected_devices.remove(spec) storage.protect_devices(protected_devices) disk_selection_proxy.SetProtectedDevices(protected_devices)
def apply_disk_selection(storage, selected_names): """Apply the disks selection. :param storage: blivet.Blivet instance :param selected_names: a list of selected disk names """ # Get the selected disks. selected_disks = filter_disks_by_names(storage.disks, selected_names) # Get names of their ancestors. ancestor_names = [ ancestor.name for disk in selected_disks for ancestor in disk.ancestors if ancestor.is_disk and ancestor.name not in selected_names ] # Set the disks to select. disk_select_proxy = STORAGE.get_proxy(DISK_SELECTION) disk_select_proxy.SetSelectedDisks(selected_names + ancestor_names) # Set the drives to clear. disk_init_proxy = STORAGE.get_proxy(DISK_INITIALIZATION) disk_init_proxy.SetDrivesToClear(selected_names)
def _update_clearpart(storage): """Update data for clearpart. :param storage: an instance of the storage """ disk_init_proxy = STORAGE.get_proxy(DISK_INITIALIZATION) if disk_init_proxy.InitializationMode == CLEAR_PARTITIONS_NONE: # FIXME: This is an ugly temporary workaround for UI. mode, drives, devices = DiskInitializationModule._find_cleared_devices(storage) disk_init_proxy.SetInitializationMode(mode.value) disk_init_proxy.SetDrivesToClear(drives) disk_init_proxy.SetDevicesToClear(devices)
def eval_rules(self, ksdata, storage, report_only=False): """:see: RuleHandler.eval_rules""" bootloader_proxy = STORAGE.get_proxy(BOOTLOADER) if self._require_password and not bootloader_proxy.password_is_set: # TODO: Anaconda provides a way to set bootloader password: # bootloader_proxy.set_password(...) # We don't support setting the bootloader password yet, # but we shouldn't stop the installation, just because of that. return [RuleMessage(self.__class__, common.MESSAGE_TYPE_WARNING, "boot loader password not set up")] else: return []
def __init__(self, data, storage): super().__init__(data) self._storage = storage self._update_devicetree = False self._fcoe_proxy = STORAGE.get_proxy(FCOE) self._addButton = self.builder.get_object("addButton") self._cancelButton = self.builder.get_object("cancelButton") self._spinner = self.builder.get_object("addSpinner") self._errorBox = self.builder.get_object("errorBox") self._errorLabel = self.builder.get_object("errorLabel") self._nicCombo = self.builder.get_object("nicCombo") self._dcbCheckbox = self.builder.get_object("dcbCheckbox") self._autoCheckbox = self.builder.get_object("autoCheckbox")
def _writeKS(ksdata): path = util.getSysroot() + "/root/anaconda-ks.cfg" # Clear out certain sensitive information that kickstart doesn't have a # way of representing encrypted. for obj in ksdata.logvol.dataList() + ksdata.partition.dataList() + ksdata.raid.dataList(): obj.passphrase = "" # TODO: Don't add sensitive information to kickstart generated by modules. auto_part_proxy = STORAGE.get_proxy(AUTO_PARTITIONING) auto_part_proxy.SetPassphrase("") # Make it so only root can read - could have passwords with util.open_with_perm(path, "w", 0o600) as f: f.write(str(ksdata))
def on_add_clicked(self, *args): """Start the discovery task.""" # First update widgets. self._set_configure_sensitive(False) self._errorBox.hide() # Get the discovery task. task_path = self._fcoe_proxy.DiscoverWithTask(self.nic, self.use_dcb, self.use_auto_vlan) task_proxy = STORAGE.get_proxy(task_path) # Start the discovery. async_run_task(task_proxy, self.process_result) self._spinner.start() self._spinner.show()