def initInterface(self, addon_paths=None): if self._intf: raise RuntimeError("Second attempt to initialize the InstallInterface") if self.displayMode == 'g': from pyanaconda.ui.gui import GraphicalUserInterface # Run the GUI in non-fullscreen mode, so live installs can still # use the window manager self._intf = GraphicalUserInterface(self.storage, self.payload, self.instClass, gui_lock=self.gui_initialized, fullscreen=False) # needs to be refreshed now we know if gui or tui will take place addon_paths = addons.collect_addon_paths(constants.ADDON_PATHS, ui_subdir="gui") elif self.displayMode in ['t', 'c']: # text and command line are the same from pyanaconda.ui.tui import TextUserInterface self._intf = TextUserInterface(self.storage, self.payload, self.instClass) # needs to be refreshed now we know if gui or tui will take place addon_paths = addons.collect_addon_paths(constants.ADDON_PATHS, ui_subdir="tui") else: raise RuntimeError("Unsupported displayMode: %s" % self.displayMode) if addon_paths: self._intf.update_paths(addon_paths)
def __init__(self, cli_args): """Initialize the Initial Setup text UI. :param cli_args: command line arguments parsed by Argparse """ TextUserInterface.__init__(self, None, None, get_product_title, is_final(), quitMessage=QUIT_MESSAGE) self.multi_tty_handler = None self._use_multi_tty_handler = not cli_args.no_multi_tty # In some case, such as when running Initial Setup directly # in console or from an SSH session script, we should not # start the multi TTY handler and just run in the single # local console. if self._use_multi_tty_handler: # redirect stdin and stdout to custom pipes # stdin stdin_fd, tui_stdin_fd = os.pipe() sys.stdin = os.fdopen(stdin_fd, "r") # stdout tui_stdout_fd, stdout_fd = os.pipe() sys.stdout = os.fdopen(stdout_fd, "w") sys.stdout.reconfigure(line_buffering=True) # instantiate and start the multi TTY handler self.multi_tty_handler = MultipleTTYHandler(tui_stdin_fd=tui_stdin_fd, tui_stdout_fd=tui_stdout_fd) # start the multi-tty handler threading.threadMgr.add( threading.AnacondaThread(name="initial_setup_multi_tty_thread", target=self.multi_tty_handler.run) )
def initInterface(self): if self._intf: raise RuntimeError("Second attempt to initialize the InstallInterface") if self.gui_mode: from pyanaconda.ui.gui import GraphicalUserInterface # Run the GUI in non-fullscreen mode, so live installs can still # use the window manager self._intf = GraphicalUserInterface(self.storage, self.payload, gui_lock=self.gui_initialized, fullscreen=False, decorated=self.decorated) # needs to be refreshed now we know if gui or tui will take place addon_paths = addons.collect_addon_paths(constants.ADDON_PATHS, ui_subdir="gui") elif self.tui_mode: # TUI and noninteractive TUI are the same in this regard from pyanaconda.ui.tui import TextUserInterface self._intf = TextUserInterface(self.storage, self.payload) # needs to be refreshed now we know if gui or tui will take place addon_paths = addons.collect_addon_paths(constants.ADDON_PATHS, ui_subdir="tui") elif not self.display_mode: raise RuntimeError("Display mode not set.") else: # this should generally never happen, as display_mode now won't let # and invalid value to be set, but let's leave it here just in case # something ultra crazy happens raise RuntimeError("Unsupported display mode: %s" % self.display_mode) if addon_paths: self._intf.update_paths(addon_paths)
def setup(self, data): TextUserInterface.setup(self, data) # Make sure custom getpass() from multi-tty handler is used instead of regular getpass. # This needs to be done as the default getpass() implementation cant work with arbitrary # consoles and always defaults to /dev/tty for input. configuration = App.get_configuration() configuration.password_function = self.multi_tty_handler.custom_getpass
def initInterface(self): if self._intf: raise RuntimeError("Second attempt to initialize the InstallInterface") if self.gui_mode: from pyanaconda.ui.gui import GraphicalUserInterface # Run the GUI in non-fullscreen mode, so live installs can still # use the window manager self._intf = GraphicalUserInterface(None, self.payload, gui_lock=self.gui_initialized, fullscreen=False) # needs to be refreshed now we know if gui or tui will take place addon_paths = addons.collect_addon_paths(constants.ADDON_PATHS, ui_subdir="gui") elif self.tui_mode: # TUI and noninteractive TUI are the same in this regard from pyanaconda.ui.tui import TextUserInterface self._intf = TextUserInterface(None, self.payload) # needs to be refreshed now we know if gui or tui will take place addon_paths = addons.collect_addon_paths(constants.ADDON_PATHS, ui_subdir="tui") elif not self.display_mode: raise RuntimeError("Display mode not set.") else: # this should generally never happen, as display_mode now won't let # and invalid value to be set, but let's leave it here just in case # something ultra crazy happens raise RuntimeError("Unsupported display mode: %s" % self.display_mode) if addon_paths: self._intf.update_paths(addon_paths)
def initInterface(self, addon_paths=None): if self._intf: raise RuntimeError( "Second attempt to initialize the InstallInterface") if self.displayMode == 'g': from pyanaconda.ui.gui import GraphicalUserInterface # Run the GUI in non-fullscreen mode, so live installs can still # use the window manager self._intf = GraphicalUserInterface(self.storage, self.payload, self.instClass, gui_lock=self.gui_initialized, fullscreen=False) # needs to be refreshed now we know if gui or tui will take place addon_paths = addons.collect_addon_paths(constants.ADDON_PATHS, ui_subdir="gui") elif self.displayMode in ['t', 'c']: # text and command line are the same from pyanaconda.ui.tui import TextUserInterface self._intf = TextUserInterface(self.storage, self.payload, self.instClass) # needs to be refreshed now we know if gui or tui will take place addon_paths = addons.collect_addon_paths(constants.ADDON_PATHS, ui_subdir="tui") else: raise RuntimeError("Unsupported displayMode: %s" % self.displayMode) if addon_paths: self._intf.update_paths(addon_paths)
def __init__(self, storage, payload, instclass): TextUserInterface.__init__(self, storage, payload, instclass, product_title, is_final, quitMessage=QUIT_MESSAGE) # redirect stdin and stdout to custom pipes # stdin stdin_fd, tui_stdin_fd = os.pipe() sys.stdin = os.fdopen(stdin_fd, "r") # stdout tui_stdout_fd, stdout_fd = os.pipe() sys.stdout = os.fdopen(stdout_fd, "w") # instantiate and start the multi TTY handler self.multi_tty_handler = MultipleTTYHandler( tui_stdin_fd=tui_stdin_fd, tui_stdout_fd=tui_stdout_fd) # start the multi-tty handler threading.threadMgr.add( threading.AnacondaThread(name="initial_setup_multi_tty_thread", target=self.multi_tty_handler.run))
def setup(self, data): TextUserInterface.setup(self, data) # Make sure custom getpass() from multi-tty handler is used instead of regular getpass. # This needs to be done as the default getpass() implementation cant work with arbitrary # consoles and always defaults to /dev/tty for input. screen_scheduler = App.get_scheduler() io_manager = screen_scheduler.io_manager io_manager.set_pass_func(self.multi_tty_handler.custom_getpass)
def __init__(self, storage, payload, instclass): TextUserInterface.__init__(self, storage, payload, instclass, product_title, is_final, quitMessage=QUIT_MESSAGE)
def tui_test(self, proxy_getter): # Create the interface. from pyanaconda.ui.tui import TextUserInterface self.interface = TextUserInterface(self.storage, self.payload) # Check the hubs from pyanaconda.ui.tui.hubs.summary import SummaryHub self.assertEqual(self.hubs, [SummaryHub]) # Check the actions classes. self.assertEqual(self._get_action_class_names(), [ "UnsupportedHardwareSpoke", "KernelWarningSpoke", "SummaryHub", "ProgressSpoke" ]) # Check the Summary hub. self.assertEqual( self._get_category_names(SummaryHub), { 'CustomizationCategory': [], 'LocalizationCategory': ['LangSpoke', 'TimeSpoke'], 'SoftwareCategory': ['SoftwareSpoke', 'SourceSpoke'], 'SystemCategory': ['NetworkSpoke', 'ShellSpoke', 'StorageSpoke'], 'UserSettingsCategory': ['PasswordSpoke', 'UserSpoke'] }) # Force us to always decide order of standalone spokes based on priority not by name. # This will ordering errors easier to spot. self._check_spokes_priority_uniqueness()
def initInterface(self): if self._intf: raise RuntimeError( "Second attempt to initialize the InstallInterface") # this boot option is meant to be temporary, so just check it directly # from kernel boot command line like this if "webui" in kernel_arguments: from pyanaconda.ui.webui import CockpitUserInterface self._intf = CockpitUserInterface( None, self.payload, "webui.remote" in kernel_arguments) # needs to be refreshed now we know if gui or tui will take place # FIXME - what about Cockpit based addons ? addon_paths = [] elif self.gui_mode: from pyanaconda.ui.gui import GraphicalUserInterface # Run the GUI in non-fullscreen mode, so live installs can still # use the window manager self._intf = GraphicalUserInterface(None, self.payload, gui_lock=self.gui_initialized, fullscreen=False) # needs to be refreshed now we know if gui or tui will take place addon_paths = collect_addon_ui_paths(ADDON_PATHS, "gui") elif self.tui_mode: # TUI and noninteractive TUI are the same in this regard from pyanaconda.ui.tui import TextUserInterface self._intf = TextUserInterface(None, self.payload) # needs to be refreshed now we know if gui or tui will take place addon_paths = collect_addon_ui_paths(ADDON_PATHS, "tui") elif not self.display_mode: raise RuntimeError("Display mode not set.") else: # this should generally never happen, as display_mode now won't let # and invalid value to be set, but let's leave it here just in case # something ultra crazy happens raise RuntimeError("Unsupported display mode: %s" % self.display_mode) if addon_paths: self._intf.update_paths(addon_paths)
def tui_test(self): # Create the interface. from pyanaconda.ui.tui import TextUserInterface self.interface = TextUserInterface(self.storage, self.payload) # Check the hubs from pyanaconda.ui.tui.hubs.summary import SummaryHub self.assertEqual(self.hubs, [SummaryHub]) # Check the actions classes. self.assertEqual(self._get_action_class_names(), [ "UnsupportedHardwareSpoke", "SummaryHub", "ProgressSpoke" ]) # Check the Summary hub. self.assertEqual(self._get_category_names(SummaryHub), { 'CustomizationCategory': [], 'LocalizationCategory': [ 'LangSpoke', 'TimeSpoke' ], 'SoftwareCategory': [ 'SoftwareSpoke', 'SourceSpoke' ], 'SystemCategory': [ 'NetworkSpoke', 'PartTypeSpoke', 'ShellSpoke', 'StorageSpoke' ], 'UserSettingsCategory': [ 'PasswordSpoke', 'UserSpoke' ] })
def __init__(self, storage, payload, instclass): TextUserInterface.__init__(self, storage, payload, instclass, product_title, is_final, quitMessage = QUIT_MESSAGE)
class Anaconda(object): def __init__(self): self._display_mode = None self._interactive_mode = True self.gui_startup_failed = False self._intf = None self.ksdata = None self.methodstr = None self.additional_repos = None self.opts = None self._payload = None self.proxy = None self.mehConfig = None # Data for inhibiting the screensaver self.dbus_session_connection = None self.dbus_inhibit_id = None # This is used to synchronize Gtk.main calls between the graphical # interface and error dialogs. Whoever gets to their initialization code # first will lock gui_initializing self.gui_initialized = threading.Lock() # Create class for launching our dbus session self._dbus_launcher = None def set_from_opts(self, opts): """Load argument to variables from self.opts.""" self.opts = opts self.proxy = opts.proxy self.methodstr = opts.method self.additional_repos = opts.addRepo @property def dbus_launcher(self): if not self._dbus_launcher: self._dbus_launcher = AnacondaDBusLauncher() return self._dbus_launcher @property def payload(self): # Try to find the payload class. First try the install # class. If it doesn't give us one, fall back to the default. if not self._payload: if self.ksdata.ostreesetup.seen: if FlatpakPayload.is_available(): from pyanaconda.payload.rpmostreepayload import RPMOSTreePayloadWithFlatpaks klass = RPMOSTreePayloadWithFlatpaks else: from pyanaconda.payload.rpmostreepayload import RPMOSTreePayload klass = RPMOSTreePayload elif self.opts.liveinst: from pyanaconda.payload.livepayload import LiveImagePayload klass = LiveImagePayload elif self.ksdata.method.method == "liveimg": from pyanaconda.payload.livepayload import LiveImageKSPayload klass = LiveImageKSPayload else: from pyanaconda.payload.dnfpayload import DNFPayload klass = DNFPayload self._payload = klass(self.ksdata) return self._payload @staticmethod def get_protected_devices(opts): specs = [] # methodstr and stage2 become strings in ways that pylint can't figure out # pylint: disable=unsubscriptable-object if opts.method and SourceFactory.is_harddrive(opts.method): specs.append(opts.method[3:].split(":", 3)[0]) if opts.stage2 and SourceFactory.is_harddrive(opts.stage2): specs.append(opts.stage2[3:].split(":", 3)[0]) for additional_repo in opts.addRepo: _name, repo_url = Anaconda._get_additional_repo_name( additional_repo) if SourceFactory.is_harddrive(repo_url): specs.append(repo_url[3:].split(":", 3)[0]) # zRAM swap devices need to be protected for zram_dev in glob("/dev/zram*"): specs.append(zram_dev) return specs @staticmethod def _get_additional_repo_name(repo): try: name, rest = repo.split(',', maxsplit=1) except ValueError: raise RuntimeError( "addrepo boot option has incorrect format. Correct format is: " "inst.addrepo=<name>,<url>") from None return name, rest @property def display_mode(self): return self._display_mode @display_mode.setter def display_mode(self, new_mode): if isinstance(new_mode, DisplayModes): if self._display_mode: old_mode = self._display_mode log.debug("changing display mode from %s to %s", old_mode.value, new_mode.value) else: log.debug("setting display mode to %s", new_mode.value) self._display_mode = new_mode else: # unknown mode name - ignore & log an error log.error("tried to set an unknown display mode name: %s", new_mode.value) @property def interactive_mode(self): return self._interactive_mode @interactive_mode.setter def interactive_mode(self, value): if self._interactive_mode != value: self._interactive_mode = value if value: log.debug("working in interative mode") else: log.debug("working in noninteractive mode") @property def gui_mode(self): """Report if Anaconda should run with the GUI.""" return self._display_mode == DisplayModes.GUI @property def tui_mode(self): """Report if Anaconda should run with the TUI.""" return self._display_mode == DisplayModes.TUI def log_display_mode(self): if not self.display_mode: log.error("Display mode is not set!") return log.info("Display mode is set to '%s %s'.", constants.INTERACTIVE_MODE_NAME[self.interactive_mode], constants.DISPLAY_MODE_NAME[self.display_mode]) def add_additional_repositories_to_ksdata(self): from pyanaconda.kickstart import RepoData for add_repo in self.additional_repos: name, repo_url = self._get_additional_repo_name(add_repo) try: source = SourceFactory.parse_repo_cmdline_string(repo_url) except PayloadSourceTypeUnrecognized: log.error( "Type for additional repository %s is not recognized!", add_repo) return repo = RepoData(name=name, baseurl=repo_url, install=False) if source.is_nfs or source.is_http or source.is_https or source.is_ftp \ or source.is_file: repo.enabled = True elif source.is_harddrive: repo.enabled = True repo.partition = source.partition repo.iso_path = source.path repo.baseurl = "file://" else: log.error( "Source type %s for additional repository %s is not supported!", source.source_type.value, add_repo) continue self._check_repo_name_uniqueness(repo) self.ksdata.repo.dataList().append(repo) def _check_repo_name_uniqueness(self, repo): """Log if we are adding repository with already used name In automatic kickstart installation this will result in using the first defined repo. """ if repo in self.ksdata.repo.dataList(): log.warning( "Repository name %s is not unique. Only the first repo will be used!", repo.name) def dumpState(self): from meh import ExceptionInfo from meh.dump import ReverseExceptionDump from inspect import stack as _stack from traceback import format_stack # Skip the frames for dumpState and the signal handler. stack = _stack()[2:] stack.reverse() exn = ReverseExceptionDump(ExceptionInfo(None, None, stack), self.mehConfig) # gather up info on the running threads threads = "\nThreads\n-------\n" # Every call to sys._current_frames() returns a new dict, so it is not # modified when threads are created or destroyed. Iterating over it is # thread safe. for thread_id, frame in sys._current_frames().items(): threads += "\nThread %s\n" % (thread_id, ) threads += "".join(format_stack(frame)) # dump to a unique file (fd, filename) = mkstemp(prefix="anaconda-tb-", dir="/tmp") dump_text = exn.traceback_and_object_dump(self) dump_text += threads dump_text_bytes = dump_text.encode("utf-8") os.write(fd, dump_text_bytes) os.close(fd) # append to a given file with open("/tmp/anaconda-tb-all.log", "a+") as f: f.write("--- traceback: %s ---\n" % filename) f.write(dump_text + "\n") @property def intf(self): """The user interface.""" return self._intf def initInterface(self): if self._intf: raise RuntimeError( "Second attempt to initialize the InstallInterface") if self.gui_mode: from pyanaconda.ui.gui import GraphicalUserInterface # Run the GUI in non-fullscreen mode, so live installs can still # use the window manager self._intf = GraphicalUserInterface(None, self.payload, gui_lock=self.gui_initialized, fullscreen=False) # needs to be refreshed now we know if gui or tui will take place addon_paths = addons.collect_addon_paths(constants.ADDON_PATHS, ui_subdir="gui") elif self.tui_mode: # TUI and noninteractive TUI are the same in this regard from pyanaconda.ui.tui import TextUserInterface self._intf = TextUserInterface(None, self.payload) # needs to be refreshed now we know if gui or tui will take place addon_paths = addons.collect_addon_paths(constants.ADDON_PATHS, ui_subdir="tui") elif not self.display_mode: raise RuntimeError("Display mode not set.") else: # this should generally never happen, as display_mode now won't let # and invalid value to be set, but let's leave it here just in case # something ultra crazy happens raise RuntimeError("Unsupported display mode: %s" % self.display_mode) if addon_paths: self._intf.update_paths(addon_paths)
class Anaconda(object): def __init__(self): from pyanaconda import desktop self._bootloader = None self.desktop = desktop.Desktop() self.dir = None self._display_mode = None self._interactive_mode = True self.gui_startup_failed = False self.id = None self._instClass = None self._intf = None self.isHeadless = False self.ksdata = None self.methodstr = None self.additional_repos = None self.opts = None self._payload = None self.proxy = None self.decorated = False self.stage2 = None self._storage = None self.updateSrc = None self.mehConfig = None # *sigh* we still need to be able to write this out self.xdriver = None # Data for inhibiting the screensaver self.dbus_session_connection = None self.dbus_inhibit_id = None # This is used to synchronize Gtk.main calls between the graphical # interface and error dialogs. Whoever gets to their initialization code # first will lock gui_initializing self.gui_initialized = threading.Lock() # Create class for launching our dbus session self._dbus_launcher = None def set_from_opts(self, opts): """Load argument to variables from self.opts.""" self.opts = opts self.decorated = opts.decorated self.proxy = opts.proxy self.updateSrc = opts.updateSrc self.methodstr = opts.method self.stage2 = opts.stage2 self.additional_repos = opts.addRepo @property def dbus_launcher(self): if not self._dbus_launcher: self._dbus_launcher = AnacondaDBusLauncher() return self._dbus_launcher @property def bootloader(self): if not self._bootloader: self._bootloader = get_bootloader() return self._bootloader @property def instClass(self): if not self._instClass: from pyanaconda.installclass import factory # Get install class by name. if self.ksdata.anaconda.installclass.seen: name = self.ksdata.anaconda.installclass.name self._instClass = factory.get_install_class_by_name(name) # Or just find the best one. else: self._instClass = factory.get_best_install_class() return self._instClass def _getInterface(self): return self._intf def _setInterface(self, v): # "lambda cannot contain assignment" self._intf = v def _delInterface(self): del self._intf intf = property(_getInterface, _setInterface, _delInterface) @property def payload(self): # Try to find the payload class. First try the install # class. If it doesn't give us one, fall back to the default. if not self._payload: from pyanaconda.flags import flags if self.ksdata.ostreesetup.seen: from pyanaconda.payload.rpmostreepayload import RPMOSTreePayload klass = RPMOSTreePayload elif flags.livecdInstall: from pyanaconda.payload.livepayload import LiveImagePayload klass = LiveImagePayload elif self.ksdata.method.method == "liveimg": from pyanaconda.payload.livepayload import LiveImageKSPayload klass = LiveImageKSPayload else: from pyanaconda.payload.dnfpayload import DNFPayload klass = DNFPayload self._payload = klass(self.ksdata) return self._payload @property def protected(self): specs = [] if os.path.exists("/run/initramfs/livedev") and \ stat.S_ISBLK(os.stat("/run/initramfs/livedev")[stat.ST_MODE]): specs.append(os.readlink("/run/initramfs/livedev")) # methodstr and stage2 become strings in ways that pylint can't figure out # pylint: disable=unsubscriptable-object if self.methodstr and SourceFactory.is_harddrive(self.methodstr): specs.append(self.methodstr[3:].split(":", 3)[0]) if self.stage2 and SourceFactory.is_harddrive(self.stage2): specs.append(self.stage2[3:].split(":", 3)[0]) for additional_repo in self.additional_repos: _name, repo_url = self._get_additional_repo_name(additional_repo) if SourceFactory.is_harddrive(repo_url): specs.append(repo_url[3:].split(":", 3)[0]) # zRAM swap devices need to be protected for zram_dev in glob("/dev/zram*"): specs.append(zram_dev) return specs @staticmethod def _get_additional_repo_name(repo): name, rest = repo.split(',', maxsplit=1) return name, rest @property def storage(self): if not self._storage: from pyanaconda.storage.osinstall import InstallerStorage import blivet.arch self._storage = InstallerStorage(ksdata=self.ksdata) self._set_storage_defaults(self._storage) if blivet.arch.is_s390(): self._load_plugin_s390() return self._storage @property def display_mode(self): return self._display_mode @display_mode.setter def display_mode(self, new_mode): if isinstance(new_mode, DisplayModes): if self._display_mode: old_mode = self._display_mode log.debug("changing display mode from %s to %s", old_mode.value, new_mode.value) else: log.debug("setting display mode to %s", new_mode.value) self._display_mode = new_mode else: # unknown mode name - ignore & log an error log.error("tried to set an unknown display mode name: %s", new_mode.value) @property def interactive_mode(self): return self._interactive_mode @interactive_mode.setter def interactive_mode(self, value): if self._interactive_mode != value: self._interactive_mode = value if value: log.debug("working in interative mode") else: log.debug("working in noninteractive mode") @property def gui_mode(self): """Report if Anaconda should run with the GUI.""" return self._display_mode == DisplayModes.GUI @property def tui_mode(self): """Report if Anaconda should run with the TUI.""" return self._display_mode == DisplayModes.TUI def log_display_mode(self): if not self.display_mode: log.error("Display mode is not set!") return log.info("Display mode is set to '%s %s'.", constants.INTERACTIVE_MODE_NAME[self.interactive_mode], constants.DISPLAY_MODE_NAME[self.display_mode]) def add_additional_repositories_to_ksdata(self): from pyanaconda.kickstart import RepoData for add_repo in self.additional_repos: name, repo_url = self._get_additional_repo_name(add_repo) try: source = SourceFactory.parse_repo_cmdline_string(repo_url) except PayloadSourceTypeUnrecognized: log.error( "Type for additional repository %s is not recognized!", add_repo) return repo = RepoData(name=name, baseurl=repo_url, install=False) if source.is_nfs or source.is_http or source.is_https or source.is_ftp \ or source.is_file: repo.enabled = True elif source.is_harddrive: repo.enabled = True repo.partition = source.partition repo.iso_path = source.path repo.baseurl = "file://" else: log.error( "Source type %s for additional repository %s is not supported!", source.source_type.value, add_repo) continue self._check_repo_name_uniqueness(repo) self.ksdata.repo.dataList().append(repo) def _check_repo_name_uniqueness(self, repo): """Log if we are adding repository with already used name In automatic kickstart installation this will result in using the first defined repo. """ if repo in self.ksdata.repo.dataList(): log.warning( "Repository name %s is not unique. Only the first repo will be used!", repo.name) 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 _load_plugin_s390(self): # Make sure s390 plugin is loaded. import gi gi.require_version("BlockDev", "2.0") from gi.repository import BlockDev as blockdev # Is the plugin loaded? We are done then. if "s390" in blockdev.get_available_plugin_names(): return # Otherwise, load the plugin. plugin = blockdev.PluginSpec() plugin.name = blockdev.Plugin.S390 plugin.so_name = None blockdev.reinit([plugin], reload=False) def dumpState(self): from meh import ExceptionInfo from meh.dump import ReverseExceptionDump from inspect import stack as _stack from traceback import format_stack # Skip the frames for dumpState and the signal handler. stack = _stack()[2:] stack.reverse() exn = ReverseExceptionDump(ExceptionInfo(None, None, stack), self.mehConfig) # gather up info on the running threads threads = "\nThreads\n-------\n" # Every call to sys._current_frames() returns a new dict, so it is not # modified when threads are created or destroyed. Iterating over it is # thread safe. for thread_id, frame in sys._current_frames().items(): threads += "\nThread %s\n" % (thread_id, ) threads += "".join(format_stack(frame)) # dump to a unique file (fd, filename) = mkstemp(prefix="anaconda-tb-", dir="/tmp") dump_text = exn.traceback_and_object_dump(self) dump_text += threads dump_text_bytes = dump_text.encode("utf-8") os.write(fd, dump_text_bytes) os.close(fd) # append to a given file with open("/tmp/anaconda-tb-all.log", "a+") as f: f.write("--- traceback: %s ---\n" % filename) f.write(dump_text + "\n") def initInterface(self, addon_paths=None): if self._intf: raise RuntimeError( "Second attempt to initialize the InstallInterface") if self.gui_mode: from pyanaconda.ui.gui import GraphicalUserInterface # Run the GUI in non-fullscreen mode, so live installs can still # use the window manager self._intf = GraphicalUserInterface(self.storage, self.payload, self.instClass, gui_lock=self.gui_initialized, fullscreen=False, decorated=self.decorated) # needs to be refreshed now we know if gui or tui will take place addon_paths = addons.collect_addon_paths(constants.ADDON_PATHS, ui_subdir="gui") elif self.tui_mode: # TUI and noninteractive TUI are the same in this regard from pyanaconda.ui.tui import TextUserInterface self._intf = TextUserInterface(self.storage, self.payload, self.instClass) # needs to be refreshed now we know if gui or tui will take place addon_paths = addons.collect_addon_paths(constants.ADDON_PATHS, ui_subdir="tui") elif not self.display_mode: raise RuntimeError("Display mode not set.") else: # this should generally never happen, as display_mode now won't let # and invalid value to be set, but let's leave it here just in case # something ultra crazy happens raise RuntimeError("Unsupported display mode: %s" % self.display_mode) if addon_paths: self._intf.update_paths(addon_paths) def writeXdriver(self, root=None): # this should go away at some point, but until it does, we # need to keep it around. if self.xdriver is None: return if root is None: root = util.getSysroot() if not os.path.isdir("%s/etc/X11" % (root, )): os.makedirs("%s/etc/X11" % (root, ), mode=0o755) f = open("%s/etc/X11/xorg.conf" % (root, ), 'w') f.write( 'Section "Device"\n\tIdentifier "Videocard0"\n\tDriver "%s"\nEndSection\n' % self.xdriver) f.close()
class Anaconda(object): def __init__(self): from pyanaconda import desktop self._bootloader = None self.canReIPL = False self.desktop = desktop.Desktop() self.dir = None self.displayMode = None self.gui_startup_failed = False self.id = None self._instClass = None self._intf = None self.isHeadless = False self.ksdata = None self.mediaDevice = None self.methodstr = None self.opts = None self._payload = None self.proxy = None self.proxyUsername = None self.proxyPassword = None self.reIPLMessage = None self.rescue_mount = True self.rootParts = None self.stage2 = None self._storage = None self.updateSrc = None self.mehConfig = None # *sigh* we still need to be able to write this out self.xdriver = None # Data for inhibiting the screensaver self.dbus_session_connection = None self.dbus_inhibit_id = None # This is used to synchronize Gtk.main calls between the graphical # interface and error dialogs. Whoever gets to their initialization code # first will lock gui_initializing self.gui_initialized = threading.Lock() @property def bootloader(self): if not self._bootloader: self._bootloader = get_bootloader() return self._bootloader @property def instClass(self): if not self._instClass: from pyanaconda.installclass import DefaultInstall self._instClass = DefaultInstall() return self._instClass def _getInterface(self): return self._intf def _setInterface(self, v): # "lambda cannot contain assignment" self._intf = v def _delInterface(self): del self._intf intf = property(_getInterface, _setInterface, _delInterface) @property def payload(self): # Try to find the packaging payload class. First try the install # class. If it doesn't give us one, fall back to the default. if not self._payload: klass = self.instClass.getBackend() if not klass: from pyanaconda.flags import flags if self.ksdata.ostreesetup.seen: from pyanaconda.packaging.rpmostreepayload import RPMOSTreePayload klass = RPMOSTreePayload elif flags.livecdInstall: from pyanaconda.packaging.livepayload import LiveImagePayload klass = LiveImagePayload elif self.ksdata.method.method == "liveimg": from pyanaconda.packaging.livepayload import LiveImageKSPayload klass = LiveImageKSPayload else: from pyanaconda.packaging.dnfpayload import DNFPayload klass = DNFPayload self._payload = klass(self.ksdata) return self._payload @property def protected(self): specs = [] if os.path.exists("/run/initramfs/livedev") and \ stat.S_ISBLK(os.stat("/run/initramfs/livedev")[stat.ST_MODE]): specs.append(os.readlink("/run/initramfs/livedev")) # methodstr and stage2 become strings in ways that pylint can't figure out # pylint: disable=unsubscriptable-object if self.methodstr and self.methodstr.startswith("hd:"): specs.append(self.methodstr[3:].split(":", 3)[0]) if self.stage2 and self.stage2.startswith("hd:"): specs.append(self.stage2[3:].split(":", 3)[0]) # zRAM swap devices need to be protected for zram_dev in glob("/dev/zram*"): specs.append(zram_dev) return specs @property def storage(self): if not self._storage: import blivet import blivet.arch import gi gi.require_version("BlockDev", "1.0") from gi.repository import BlockDev as blockdev self._storage = blivet.Blivet(ksdata=self.ksdata) if self.instClass.defaultFS: self._storage.setDefaultFSType(self.instClass.defaultFS) if blivet.arch.isS390(): # want to make sure s390 plugin is loaded if "s390" not in blockdev.get_available_plugin_names(): plugin = blockdev.PluginSpec() plugin.name = blockdev.Plugin.S390 plugin.so_name = None blockdev.reinit([plugin], reload=False) return self._storage def dumpState(self): from meh import ExceptionInfo from meh.dump import ReverseExceptionDump from inspect import stack as _stack from traceback import format_stack # Skip the frames for dumpState and the signal handler. stack = _stack()[2:] stack.reverse() exn = ReverseExceptionDump(ExceptionInfo(None, None, stack), self.mehConfig) # gather up info on the running threads threads = "\nThreads\n-------\n" # Every call to sys._current_frames() returns a new dict, so it is not # modified when threads are created or destroyed. Iterating over it is # thread safe. for thread_id, frame in sys._current_frames().items(): threads += "\nThread %s\n" % (thread_id, ) threads += "".join(format_stack(frame)) # dump to a unique file (fd, filename) = mkstemp(prefix="anaconda-tb-", dir="/tmp") dump_text = exn.traceback_and_object_dump(self) dump_text += threads dump_text_bytes = dump_text.encode("utf-8") os.write(fd, dump_text_bytes) os.close(fd) # append to a given file with open("/tmp/anaconda-tb-all.log", "a+") as f: f.write("--- traceback: %s ---\n" % filename) f.write(dump_text + "\n") def initInterface(self, addon_paths=None): if self._intf: raise RuntimeError( "Second attempt to initialize the InstallInterface") if self.displayMode == 'g': from pyanaconda.ui.gui import GraphicalUserInterface # Run the GUI in non-fullscreen mode, so live installs can still # use the window manager self._intf = GraphicalUserInterface(self.storage, self.payload, self.instClass, gui_lock=self.gui_initialized, fullscreen=False) # needs to be refreshed now we know if gui or tui will take place addon_paths = addons.collect_addon_paths(constants.ADDON_PATHS, ui_subdir="gui") elif self.displayMode in ['t', 'c']: # text and command line are the same from pyanaconda.ui.tui import TextUserInterface self._intf = TextUserInterface(self.storage, self.payload, self.instClass) # needs to be refreshed now we know if gui or tui will take place addon_paths = addons.collect_addon_paths(constants.ADDON_PATHS, ui_subdir="tui") else: raise RuntimeError("Unsupported displayMode: %s" % self.displayMode) if addon_paths: self._intf.update_paths(addon_paths) def writeXdriver(self, root=None): # this should go away at some point, but until it does, we # need to keep it around. if self.xdriver is None: return if root is None: root = iutil.getSysroot() if not os.path.isdir("%s/etc/X11" % (root, )): os.makedirs("%s/etc/X11" % (root, ), mode=0o755) f = open("%s/etc/X11/xorg.conf" % (root, ), 'w') f.write( 'Section "Device"\n\tIdentifier "Videocard0"\n\tDriver "%s"\nEndSection\n' % self.xdriver) f.close()
class Anaconda(object): def __init__(self): import desktop from flags import flags self._bootloader = None self.canReIPL = False self.desktop = desktop.Desktop() self.dir = None self.displayMode = None self.extraModules = [] self.id = None self._instClass = None self._intf = None self.isHeadless = False self.ksdata = None self.mediaDevice = None self.methodstr = None self._network = None self.opts = None self._payload = None self.proxy = None self.proxyUsername = None self.proxyPassword = None self.reIPLMessage = None self.rescue = False self.rescue_mount = True self.rootParts = None self.stage2 = None self._storage = None self.updateSrc = None self.mehConfig = None # *sigh* we still need to be able to write this out self.xdriver = None @property def bootloader(self): if not self._bootloader: self._bootloader = get_bootloader() return self._bootloader @property def instClass(self): if not self._instClass: from installclass import DefaultInstall self._instClass = DefaultInstall() return self._instClass def _getInterface(self): return self._intf def _setInterface(self, v): # "lambda cannot contain assignment" self._intf = v def _delInterface(self): del self._intf intf = property(_getInterface, _setInterface, _delInterface) @property def network(self): if not self._network: import network self._network = network.Network() return self._network @property def payload(self): # Try to find the packaging payload class. First try the install # class. If it doesn't give us one, fall back to the default. if not self._payload: klass = self.instClass.getBackend() if not klass: from flags import flags if self.ksdata.ostreesetup: from pyanaconda.packaging.ostreepayload import OSTreePayload klass = OSTreePayload elif flags.livecdInstall: from pyanaconda.packaging.livepayload import LiveImagePayload klass = LiveImagePayload elif self.ksdata.method.method == "liveimg": from pyanaconda.packaging.livepayload import LiveImageKSPayload klass = LiveImageKSPayload else: from pyanaconda.packaging.yumpayload import YumPayload klass = YumPayload self._payload = klass(self.ksdata) return self._payload @property def protected(self): import stat specs = [] if os.path.exists("/run/initramfs/livedev") and \ stat.S_ISBLK(os.stat("/run/initramfs/livedev")[stat.ST_MODE]): specs.append(os.readlink("/run/initramfs/livedev")) if self.methodstr and self.methodstr.startswith("hd:"): specs.append(self.methodstr[3:].split(":", 3)[0]) if self.stage2 and self.stage2.startswith("hd:"): specs.append(self.stage2[3:].split(":", 3)[0]) return specs @property def storage(self): if not self._storage: import blivet self._storage = blivet.Blivet(ksdata=self.ksdata) if self.instClass.defaultFS: self._storage.setDefaultFSType(self.instClass.defaultFS) return self._storage def dumpState(self): from meh import ExceptionInfo from meh.dump import ReverseExceptionDump from inspect import stack as _stack from traceback import format_stack # Skip the frames for dumpState and the signal handler. stack = _stack()[2:] stack.reverse() exn = ReverseExceptionDump(ExceptionInfo(None, None, stack), self.mehConfig) # gather up info on the running threads threads = "\nThreads\n-------\n" for thread_id, frame in sys._current_frames().iteritems(): threads += "\nThread %s\n" % (thread_id, ) threads += "".join(format_stack(frame)) # dump to a unique file (fd, filename) = mkstemp(prefix="anaconda-tb-", dir="/tmp") dump_text = exn.traceback_and_object_dump(self) dump_text += threads dump_text = dump_text.encode("utf-8") os.write(fd, dump_text) os.close(fd) # append to a given file with open("/tmp/anaconda-tb-all.log", "a+") as f: f.write("--- traceback: %s ---\n" % filename) f.write(dump_text + "\n") def initInterface(self, addon_paths=None): if self._intf: raise RuntimeError, "Second attempt to initialize the InstallInterface" if self.displayMode == 'g': from pyanaconda.ui.gui import GraphicalUserInterface self._intf = GraphicalUserInterface(self.storage, self.payload, self.instClass) # needs to be refreshed now we know if gui or tui will take place addon_paths = addons.collect_addon_paths(constants.ADDON_PATHS, ui_subdir="gui") elif self.displayMode in ['t', 'c']: # text and command line are the same from pyanaconda.ui.tui import TextUserInterface self._intf = TextUserInterface(self.storage, self.payload, self.instClass) # needs to be refreshed now we know if gui or tui will take place addon_paths = addons.collect_addon_paths(constants.ADDON_PATHS, ui_subdir="tui") else: raise RuntimeError("Unsupported displayMode: %s" % self.displayMode) if addon_paths: self._intf.update_paths(addon_paths) def writeXdriver(self, root=None): # this should go away at some point, but until it does, we # need to keep it around. if self.xdriver is None: return if root is None: root = ROOT_PATH if not os.path.isdir("%s/etc/X11" % (root, )): os.makedirs("%s/etc/X11" % (root, ), mode=0755) f = open("%s/etc/X11/xorg.conf" % (root, ), 'w') f.write( 'Section "Device"\n\tIdentifier "Videocard0"\n\tDriver "%s"\nEndSection\n' % self.xdriver) f.close() def write(self): import network self.writeXdriver() network.write_sysconfig_network() network.disableIPV6() network.copyConfigToPath(ROOT_PATH) if not self.ksdata: self.instClass.setNetworkOnbootDefault() self.desktop.write()
def test_tui(self, proxy_getter): # Create the interface. from pyanaconda.ui.tui import TextUserInterface self.interface = TextUserInterface(self.storage, self.payload) # Check the hubs from pyanaconda.ui.tui.hubs.summary import SummaryHub self._check_hubs([SummaryHub]) # Check the actions classes. self._check_actions([ "unsupported-hardware-warning", "kernel-warning", "installation-summary", "installation-progress", ]) # Check the Summary hub. self._check_categories( SummaryHub, { 'CustomizationCategory': [], 'LocalizationCategory': [ 'language-configuration', 'date-time-configuration', ], 'SoftwareCategory': [ 'software-selection', 'software-source-configuration', ], 'SystemCategory': [ 'network-configuration', 'storage-configuration', 'shell', ], 'UserSettingsCategory': [ 'root-configuration', 'user-configuration', ] }) # Check the screens. self._check_screens([ # Warnings "unsupported-hardware-warning", "kernel-warning", # Installation 'installation-summary', 'installation-progress', # Localization 'date-time-configuration', 'language-configuration', # Software 'software-selection', 'software-source-configuration', # System 'network-configuration', 'storage-configuration', 'shell', # User settings 'root-configuration', 'user-configuration', ]) # Run general checks on the user interface. self._check_interface()
class Anaconda(object): def __init__(self): from pyanaconda import desktop self._bootloader = None self.canReIPL = False self.desktop = desktop.Desktop() self.dir = None self.displayMode = None self.extraModules = [] self.id = None self._instClass = None self._intf = None self.isHeadless = False self.ksdata = None self.mediaDevice = None self.methodstr = None self.opts = None self._payload = None self.proxy = None self.proxyUsername = None self.proxyPassword = None self.reIPLMessage = None self.rescue = False self.rescue_mount = True self.rootParts = None self.stage2 = None self._storage = None self.updateSrc = None self.mehConfig = None # *sigh* we still need to be able to write this out self.xdriver = None @property def bootloader(self): if not self._bootloader: self._bootloader = get_bootloader() return self._bootloader @property def instClass(self): if not self._instClass: from pyanaconda.installclass import DefaultInstall self._instClass = DefaultInstall() return self._instClass def _getInterface(self): return self._intf def _setInterface(self, v): # "lambda cannot contain assignment" self._intf = v def _delInterface(self): del self._intf intf = property(_getInterface, _setInterface, _delInterface) @property def payload(self): # Try to find the packaging payload class. First try the install # class. If it doesn't give us one, fall back to the default. if not self._payload: klass = self.instClass.getBackend() if not klass: from pyanaconda.flags import flags if flags.livecdInstall: from pyanaconda.packaging.livepayload import LiveImagePayload klass = LiveImagePayload elif self.ksdata.method.method == "liveimg": from pyanaconda.packaging.livepayload import LiveImageKSPayload klass = LiveImageKSPayload elif flags.dnf: try: from pyanaconda.packaging.dnfpayload import DNFPayload klass = DNFPayload except ImportError: log.critical('Importing DNF failed.', exc_info=True) else: from pyanaconda.packaging.yumpayload import YumPayload klass = YumPayload self._payload = klass(self.ksdata) return self._payload @property def protected(self): import stat specs = [] if os.path.exists("/run/initramfs/livedev") and \ stat.S_ISBLK(os.stat("/run/initramfs/livedev")[stat.ST_MODE]): specs.append(os.readlink("/run/initramfs/livedev")) if self.methodstr and self.methodstr.startswith("hd:"): specs.append(self.methodstr[3:].split(":", 3)[0]) if self.stage2 and self.stage2.startswith("hd:"): specs.append(self.stage2[3:].split(":", 3)[0]) return specs @property def storage(self): if not self._storage: import blivet self._storage = blivet.Blivet(ksdata=self.ksdata) if self.instClass.defaultFS: self._storage.setDefaultFSType(self.instClass.defaultFS) return self._storage def dumpState(self): from meh import ExceptionInfo from meh.dump import ReverseExceptionDump from inspect import stack as _stack from traceback import format_stack # Skip the frames for dumpState and the signal handler. stack = _stack()[2:] stack.reverse() exn = ReverseExceptionDump(ExceptionInfo(None, None, stack), self.mehConfig) # gather up info on the running threads threads = "\nThreads\n-------\n" for thread_id, frame in sys._current_frames().iteritems(): threads += "\nThread %s\n" % (thread_id,) threads += "".join(format_stack(frame)) # dump to a unique file (fd, filename) = mkstemp(prefix="anaconda-tb-", dir="/tmp") dump_text = exn.traceback_and_object_dump(self) dump_text += threads dump_text = dump_text.encode("utf-8") os.write(fd, dump_text) os.close(fd) # append to a given file with open("/tmp/anaconda-tb-all.log", "a+") as f: f.write("--- traceback: %s ---\n" % filename) f.write(dump_text + "\n") def initInterface(self, addon_paths=None): if self._intf: raise RuntimeError("Second attempt to initialize the InstallInterface") if self.displayMode == 'g': from pyanaconda.ui.gui import GraphicalUserInterface self._intf = GraphicalUserInterface(self.storage, self.payload, self.instClass) # needs to be refreshed now we know if gui or tui will take place addon_paths = addons.collect_addon_paths(constants.ADDON_PATHS, ui_subdir="gui") elif self.displayMode in ['t', 'c']: # text and command line are the same from pyanaconda.ui.tui import TextUserInterface self._intf = TextUserInterface(self.storage, self.payload, self.instClass) # needs to be refreshed now we know if gui or tui will take place addon_paths = addons.collect_addon_paths(constants.ADDON_PATHS, ui_subdir="tui") else: raise RuntimeError("Unsupported displayMode: %s" % self.displayMode) if addon_paths: self._intf.update_paths(addon_paths) def writeXdriver(self, root = None): # this should go away at some point, but until it does, we # need to keep it around. if self.xdriver is None: return if root is None: root = ROOT_PATH if not os.path.isdir("%s/etc/X11" %(root,)): os.makedirs("%s/etc/X11" %(root,), mode=0755) f = open("%s/etc/X11/xorg.conf" %(root,), 'w') f.write('Section "Device"\n\tIdentifier "Videocard0"\n\tDriver "%s"\nEndSection\n' % self.xdriver) f.close()
class Anaconda(object): def __init__(self): self._display_mode = None self._interactive_mode = True self.gui_startup_failed = False self._intf = None self.ksdata = None self.methodstr = None self.additional_repos = None self.opts = None self._payload = None self.proxy = None self.decorated = False self._storage = None self.mehConfig = None # Data for inhibiting the screensaver self.dbus_session_connection = None self.dbus_inhibit_id = None # This is used to synchronize Gtk.main calls between the graphical # interface and error dialogs. Whoever gets to their initialization code # first will lock gui_initializing self.gui_initialized = threading.Lock() # Create class for launching our dbus session self._dbus_launcher = None def set_from_opts(self, opts): """Load argument to variables from self.opts.""" self.opts = opts self.decorated = opts.decorated self.proxy = opts.proxy self.methodstr = opts.method self.additional_repos = opts.addRepo @property def dbus_launcher(self): if not self._dbus_launcher: self._dbus_launcher = AnacondaDBusLauncher() return self._dbus_launcher @property def payload(self): # Try to find the payload class. First try the install # class. If it doesn't give us one, fall back to the default. if not self._payload: if self.ksdata.ostreesetup.seen: from pyanaconda.payload.rpmostreepayload import RPMOSTreePayload klass = RPMOSTreePayload elif self.opts.liveinst: from pyanaconda.payload.livepayload import LiveImagePayload klass = LiveImagePayload elif self.ksdata.method.method == "liveimg": from pyanaconda.payload.livepayload import LiveImageKSPayload klass = LiveImageKSPayload else: from pyanaconda.payload.dnfpayload import DNFPayload klass = DNFPayload self._payload = klass(self.ksdata) return self._payload @staticmethod def get_protected_devices(opts): specs = [] # methodstr and stage2 become strings in ways that pylint can't figure out # pylint: disable=unsubscriptable-object if opts.method and SourceFactory.is_harddrive(opts.method): specs.append(opts.method[3:].split(":", 3)[0]) if opts.stage2 and SourceFactory.is_harddrive(opts.stage2): specs.append(opts.stage2[3:].split(":", 3)[0]) for additional_repo in opts.addRepo: _name, repo_url = Anaconda._get_additional_repo_name(additional_repo) if SourceFactory.is_harddrive(repo_url): specs.append(repo_url[3:].split(":", 3)[0]) # zRAM swap devices need to be protected for zram_dev in glob("/dev/zram*"): specs.append(zram_dev) return specs @staticmethod def _get_additional_repo_name(repo): try: name, rest = repo.split(',', maxsplit=1) except ValueError: raise RuntimeError("addrepo boot option has incorrect format. Correct format is: " "inst.addrepo=<name>,<url>") from None return name, rest @property def storage(self): if not self._storage: from pyanaconda.storage.initialization import create_storage self._storage = create_storage() from pyanaconda.storage.initialization import set_storage_defaults_from_kickstart set_storage_defaults_from_kickstart(self._storage) return self._storage @property def display_mode(self): return self._display_mode @display_mode.setter def display_mode(self, new_mode): if isinstance(new_mode, DisplayModes): if self._display_mode: old_mode = self._display_mode log.debug("changing display mode from %s to %s", old_mode.value, new_mode.value) else: log.debug("setting display mode to %s", new_mode.value) self._display_mode = new_mode else: # unknown mode name - ignore & log an error log.error("tried to set an unknown display mode name: %s", new_mode.value) @property def interactive_mode(self): return self._interactive_mode @interactive_mode.setter def interactive_mode(self, value): if self._interactive_mode != value: self._interactive_mode = value if value: log.debug("working in interative mode") else: log.debug("working in noninteractive mode") @property def gui_mode(self): """Report if Anaconda should run with the GUI.""" return self._display_mode == DisplayModes.GUI @property def tui_mode(self): """Report if Anaconda should run with the TUI.""" return self._display_mode == DisplayModes.TUI def log_display_mode(self): if not self.display_mode: log.error("Display mode is not set!") return log.info("Display mode is set to '%s %s'.", constants.INTERACTIVE_MODE_NAME[self.interactive_mode], constants.DISPLAY_MODE_NAME[self.display_mode]) def add_additional_repositories_to_ksdata(self): from pyanaconda.kickstart import RepoData for add_repo in self.additional_repos: name, repo_url = self._get_additional_repo_name(add_repo) try: source = SourceFactory.parse_repo_cmdline_string(repo_url) except PayloadSourceTypeUnrecognized: log.error("Type for additional repository %s is not recognized!", add_repo) return repo = RepoData(name=name, baseurl=repo_url, install=False) if source.is_nfs or source.is_http or source.is_https or source.is_ftp \ or source.is_file: repo.enabled = True elif source.is_harddrive: repo.enabled = True repo.partition = source.partition repo.iso_path = source.path repo.baseurl = "file://" else: log.error("Source type %s for additional repository %s is not supported!", source.source_type.value, add_repo) continue self._check_repo_name_uniqueness(repo) self.ksdata.repo.dataList().append(repo) def _check_repo_name_uniqueness(self, repo): """Log if we are adding repository with already used name In automatic kickstart installation this will result in using the first defined repo. """ if repo in self.ksdata.repo.dataList(): log.warning("Repository name %s is not unique. Only the first repo will be used!", repo.name) def dumpState(self): from meh import ExceptionInfo from meh.dump import ReverseExceptionDump from inspect import stack as _stack from traceback import format_stack # Skip the frames for dumpState and the signal handler. stack = _stack()[2:] stack.reverse() exn = ReverseExceptionDump(ExceptionInfo(None, None, stack), self.mehConfig) # gather up info on the running threads threads = "\nThreads\n-------\n" # Every call to sys._current_frames() returns a new dict, so it is not # modified when threads are created or destroyed. Iterating over it is # thread safe. for thread_id, frame in sys._current_frames().items(): threads += "\nThread %s\n" % (thread_id,) threads += "".join(format_stack(frame)) # dump to a unique file (fd, filename) = mkstemp(prefix="anaconda-tb-", dir="/tmp") dump_text = exn.traceback_and_object_dump(self) dump_text += threads dump_text_bytes = dump_text.encode("utf-8") os.write(fd, dump_text_bytes) os.close(fd) # append to a given file with open("/tmp/anaconda-tb-all.log", "a+") as f: f.write("--- traceback: %s ---\n" % filename) f.write(dump_text + "\n") @property def intf(self): """The user interface.""" return self._intf def initInterface(self): if self._intf: raise RuntimeError("Second attempt to initialize the InstallInterface") if self.gui_mode: from pyanaconda.ui.gui import GraphicalUserInterface # Run the GUI in non-fullscreen mode, so live installs can still # use the window manager self._intf = GraphicalUserInterface(self.storage, self.payload, gui_lock=self.gui_initialized, fullscreen=False, decorated=self.decorated) # needs to be refreshed now we know if gui or tui will take place addon_paths = addons.collect_addon_paths(constants.ADDON_PATHS, ui_subdir="gui") elif self.tui_mode: # TUI and noninteractive TUI are the same in this regard from pyanaconda.ui.tui import TextUserInterface self._intf = TextUserInterface(self.storage, self.payload) # needs to be refreshed now we know if gui or tui will take place addon_paths = addons.collect_addon_paths(constants.ADDON_PATHS, ui_subdir="tui") elif not self.display_mode: raise RuntimeError("Display mode not set.") else: # this should generally never happen, as display_mode now won't let # and invalid value to be set, but let's leave it here just in case # something ultra crazy happens raise RuntimeError("Unsupported display mode: %s" % self.display_mode) if addon_paths: self._intf.update_paths(addon_paths)
class Anaconda(object): def __init__(self): from pyanaconda import desktop self._bootloader = None self.canReIPL = False self.desktop = desktop.Desktop() self.dir = None self.displayMode = None self.gui_startup_failed = False self.id = None self._instClass = None self._intf = None self.isHeadless = False self.ksdata = None self.mediaDevice = None self.methodstr = None self.opts = None self._payload = None self.proxy = None self.proxyUsername = None self.proxyPassword = None self.reIPLMessage = None self.rescue_mount = True self.rootParts = None self.stage2 = None self._storage = None self.updateSrc = None self.mehConfig = None # *sigh* we still need to be able to write this out self.xdriver = None # Data for inhibiting the screensaver self.dbus_session_connection = None self.dbus_inhibit_id = None # This is used to synchronize Gtk.main calls between the graphical # interface and error dialogs. Whoever gets to their initialization code # first will lock gui_initializing self.gui_initialized = threading.Lock() @property def bootloader(self): if not self._bootloader: self._bootloader = get_bootloader() return self._bootloader @property def instClass(self): if not self._instClass: from pyanaconda.installclass import DefaultInstall self._instClass = DefaultInstall() return self._instClass def _getInterface(self): return self._intf def _setInterface(self, v): # "lambda cannot contain assignment" self._intf = v def _delInterface(self): del self._intf intf = property(_getInterface, _setInterface, _delInterface) @property def payload(self): # Try to find the packaging payload class. First try the install # class. If it doesn't give us one, fall back to the default. if not self._payload: klass = self.instClass.getBackend() if not klass: from pyanaconda.flags import flags if self.ksdata.ostreesetup.seen: from pyanaconda.packaging.rpmostreepayload import RPMOSTreePayload klass = RPMOSTreePayload elif flags.livecdInstall: from pyanaconda.packaging.livepayload import LiveImagePayload klass = LiveImagePayload elif self.ksdata.method.method == "liveimg": from pyanaconda.packaging.livepayload import LiveImageKSPayload klass = LiveImageKSPayload else: from pyanaconda.packaging.dnfpayload import DNFPayload klass = DNFPayload self._payload = klass(self.ksdata) return self._payload @property def protected(self): specs = [] if os.path.exists("/run/initramfs/livedev") and \ stat.S_ISBLK(os.stat("/run/initramfs/livedev")[stat.ST_MODE]): specs.append(os.readlink("/run/initramfs/livedev")) # methodstr and stage2 become strings in ways that pylint can't figure out # pylint: disable=unsubscriptable-object if self.methodstr and self.methodstr.startswith("hd:"): specs.append(self.methodstr[3:].split(":", 3)[0]) if self.stage2 and self.stage2.startswith("hd:"): specs.append(self.stage2[3:].split(":", 3)[0]) # zRAM swap devices need to be protected for zram_dev in glob("/dev/zram*"): specs.append(zram_dev) return specs @property def storage(self): if not self._storage: import blivet import blivet.arch import gi gi.require_version("BlockDev", "1.0") from gi.repository import BlockDev as blockdev self._storage = blivet.Blivet(ksdata=self.ksdata) if self.instClass.defaultFS: self._storage.setDefaultFSType(self.instClass.defaultFS) if blivet.arch.isS390(): # want to make sure s390 plugin is loaded if "s390" not in blockdev.get_available_plugin_names(): plugin = blockdev.PluginSpec() plugin.name = blockdev.Plugin.S390 plugin.so_name = None blockdev.reinit([plugin], reload=False) return self._storage def dumpState(self): from meh import ExceptionInfo from meh.dump import ReverseExceptionDump from inspect import stack as _stack from traceback import format_stack # Skip the frames for dumpState and the signal handler. stack = _stack()[2:] stack.reverse() exn = ReverseExceptionDump(ExceptionInfo(None, None, stack), self.mehConfig) # gather up info on the running threads threads = "\nThreads\n-------\n" # Every call to sys._current_frames() returns a new dict, so it is not # modified when threads are created or destroyed. Iterating over it is # thread safe. for thread_id, frame in sys._current_frames().items(): threads += "\nThread %s\n" % (thread_id,) threads += "".join(format_stack(frame)) # dump to a unique file (fd, filename) = mkstemp(prefix="anaconda-tb-", dir="/tmp") dump_text = exn.traceback_and_object_dump(self) dump_text += threads dump_text_bytes = dump_text.encode("utf-8") os.write(fd, dump_text_bytes) os.close(fd) # append to a given file with open("/tmp/anaconda-tb-all.log", "a+") as f: f.write("--- traceback: %s ---\n" % filename) f.write(dump_text + "\n") def initInterface(self, addon_paths=None): if self._intf: raise RuntimeError("Second attempt to initialize the InstallInterface") if self.displayMode == 'g': from pyanaconda.ui.gui import GraphicalUserInterface # Run the GUI in non-fullscreen mode, so live installs can still # use the window manager self._intf = GraphicalUserInterface(self.storage, self.payload, self.instClass, gui_lock=self.gui_initialized, fullscreen=False) # needs to be refreshed now we know if gui or tui will take place addon_paths = addons.collect_addon_paths(constants.ADDON_PATHS, ui_subdir="gui") elif self.displayMode in ['t', 'c']: # text and command line are the same from pyanaconda.ui.tui import TextUserInterface self._intf = TextUserInterface(self.storage, self.payload, self.instClass) # needs to be refreshed now we know if gui or tui will take place addon_paths = addons.collect_addon_paths(constants.ADDON_PATHS, ui_subdir="tui") else: raise RuntimeError("Unsupported displayMode: %s" % self.displayMode) if addon_paths: self._intf.update_paths(addon_paths) def writeXdriver(self, root=None): # this should go away at some point, but until it does, we # need to keep it around. if self.xdriver is None: return if root is None: root = iutil.getSysroot() if not os.path.isdir("%s/etc/X11" %(root,)): os.makedirs("%s/etc/X11" %(root,), mode=0o755) f = open("%s/etc/X11/xorg.conf" %(root,), 'w') f.write('Section "Device"\n\tIdentifier "Videocard0"\n\tDriver "%s"\nEndSection\n' % self.xdriver) f.close()
class Anaconda(object): def __init__(self): self._display_mode = None self._interactive_mode = True self.gui_startup_failed = False self._intf = None self.ksdata = None self.opts = None self._payload = None self.mehConfig = None # Data for inhibiting the screensaver self.dbus_session_connection = None self.dbus_inhibit_id = None # This is used to synchronize Gtk.main calls between the graphical # interface and error dialogs. Whoever gets to their initialization code # first will lock gui_initializing self.gui_initialized = threading.Lock() # Create class for launching our dbus session self._dbus_launcher = None def set_from_opts(self, opts): """Load argument to variables from self.opts.""" self.opts = opts @property def dbus_launcher(self): if not self._dbus_launcher: self._dbus_launcher = AnacondaDBusLauncher() return self._dbus_launcher @property def payload(self): # Try to find the payload class. First try the install # class. If it doesn't give us one, fall back to the default. if not self._payload: # Get the type of the DBus payload module if any. payload_type = self._get_dbus_payload_type() if payload_type == PAYLOAD_TYPE_RPM_OSTREE: from pyanaconda.payload.rpmostreepayload import RPMOSTreePayload payload = RPMOSTreePayload() elif self.opts.liveinst: from pyanaconda.payload.live import LiveOSPayload payload = LiveOSPayload() elif payload_type == PAYLOAD_TYPE_LIVE_IMAGE: from pyanaconda.payload.live import LiveImagePayload payload = LiveImagePayload() else: from pyanaconda.payload.dnf import DNFPayload payload = DNFPayload(self.ksdata) self._payload = payload return self._payload @staticmethod def _get_dbus_payload_type(): payloads_proxy = PAYLOADS.get_proxy() object_path = payloads_proxy.ActivePayload if not object_path: return None object_proxy = PAYLOADS.get_proxy(object_path) return object_proxy.Type @staticmethod def get_protected_devices(opts): specs = [] # methodstr and stage2 become strings in ways that pylint can't figure out # pylint: disable=unsubscriptable-object if opts.method and SourceFactory.is_harddrive(opts.method): specs.append(opts.method[3:].split(":", 3)[0]) if opts.stage2 and SourceFactory.is_harddrive(opts.stage2): specs.append(opts.stage2[3:].split(":", 3)[0]) for _repo_name, repo_url in opts.addRepo: if SourceFactory.is_harddrive(repo_url): specs.append(repo_url[3:].split(":", 3)[0]) # zRAM swap devices need to be protected for zram_dev in glob("/dev/zram*"): specs.append(zram_dev) return specs @property def display_mode(self): return self._display_mode @display_mode.setter def display_mode(self, new_mode): if isinstance(new_mode, DisplayModes): if self._display_mode: old_mode = self._display_mode log.debug("changing display mode from %s to %s", old_mode.value, new_mode.value) else: log.debug("setting display mode to %s", new_mode.value) self._display_mode = new_mode else: # unknown mode name - ignore & log an error log.error("tried to set an unknown display mode name: %s", new_mode.value) @property def interactive_mode(self): return self._interactive_mode @interactive_mode.setter def interactive_mode(self, value): if self._interactive_mode != value: self._interactive_mode = value if value: log.debug("working in interative mode") else: log.debug("working in noninteractive mode") @property def gui_mode(self): """Report if Anaconda should run with the GUI.""" return self._display_mode == DisplayModes.GUI @property def tui_mode(self): """Report if Anaconda should run with the TUI.""" return self._display_mode == DisplayModes.TUI def log_display_mode(self): if not self.display_mode: log.error("Display mode is not set!") return log.info("Display mode is set to '%s %s'.", constants.INTERACTIVE_MODE_NAME[self.interactive_mode], constants.DISPLAY_MODE_NAME[self.display_mode]) def dumpState(self): from meh import ExceptionInfo from meh.dump import ReverseExceptionDump from inspect import stack as _stack from traceback import format_stack # Skip the frames for dumpState and the signal handler. stack = _stack()[2:] stack.reverse() exn = ReverseExceptionDump(ExceptionInfo(None, None, stack), self.mehConfig) # gather up info on the running threads threads = "\nThreads\n-------\n" # Every call to sys._current_frames() returns a new dict, so it is not # modified when threads are created or destroyed. Iterating over it is # thread safe. for thread_id, frame in sys._current_frames().items(): threads += "\nThread %s\n" % (thread_id, ) threads += "".join(format_stack(frame)) # dump to a unique file (fd, filename) = mkstemp(prefix="anaconda-tb-", dir="/tmp") dump_text = exn.traceback_and_object_dump(self) dump_text += threads dump_text_bytes = dump_text.encode("utf-8") os.write(fd, dump_text_bytes) os.close(fd) # append to a given file with open("/tmp/anaconda-tb-all.log", "a+") as f: f.write("--- traceback: %s ---\n" % filename) f.write(dump_text + "\n") @property def intf(self): """The user interface.""" return self._intf def initInterface(self): if self._intf: raise RuntimeError( "Second attempt to initialize the InstallInterface") # this boot option is meant to be temporary, so just check it directly # from kernel boot command line like this if "webui" in kernel_arguments: from pyanaconda.ui.webui import CockpitUserInterface self._intf = CockpitUserInterface( None, self.payload, "webui.remote" in kernel_arguments) # needs to be refreshed now we know if gui or tui will take place # FIXME - what about Cockpit based addons ? addon_paths = [] elif self.gui_mode: from pyanaconda.ui.gui import GraphicalUserInterface # Run the GUI in non-fullscreen mode, so live installs can still # use the window manager self._intf = GraphicalUserInterface(None, self.payload, gui_lock=self.gui_initialized, fullscreen=False) # needs to be refreshed now we know if gui or tui will take place addon_paths = collect_addon_ui_paths(ADDON_PATHS, "gui") elif self.tui_mode: # TUI and noninteractive TUI are the same in this regard from pyanaconda.ui.tui import TextUserInterface self._intf = TextUserInterface(None, self.payload) # needs to be refreshed now we know if gui or tui will take place addon_paths = collect_addon_ui_paths(ADDON_PATHS, "tui") elif not self.display_mode: raise RuntimeError("Display mode not set.") else: # this should generally never happen, as display_mode now won't let # and invalid value to be set, but let's leave it here just in case # something ultra crazy happens raise RuntimeError("Unsupported display mode: %s" % self.display_mode) if addon_paths: self._intf.update_paths(addon_paths)
class Anaconda(object): def __init__(self): from pyanaconda import desktop self._bootloader = None self.desktop = desktop.Desktop() self.dir = None self._display_mode = None self._interactive_mode = True self.gui_startup_failed = False self.id = None self._instClass = None self._intf = None self.isHeadless = False self.ksdata = None self.methodstr = None self.additional_repos = None self.opts = None self._payload = None self.proxy = None self.decorated = False self.stage2 = None self._storage = None self.updateSrc = None self.mehConfig = None # *sigh* we still need to be able to write this out self.xdriver = None # Data for inhibiting the screensaver self.dbus_session_connection = None self.dbus_inhibit_id = None # This is used to synchronize Gtk.main calls between the graphical # interface and error dialogs. Whoever gets to their initialization code # first will lock gui_initializing self.gui_initialized = threading.Lock() # Create class for launching our dbus session self._dbus_launcher = None def set_from_opts(self, opts): """Load argument to variables from self.opts.""" self.opts = opts self.decorated = opts.decorated self.proxy = opts.proxy self.updateSrc = opts.updateSrc self.methodstr = opts.method self.stage2 = opts.stage2 self.additional_repos = opts.addRepo @property def dbus_launcher(self): if not self._dbus_launcher: self._dbus_launcher = AnacondaDBusLauncher() return self._dbus_launcher @property def bootloader(self): if not self._bootloader: self._bootloader = get_bootloader() return self._bootloader @property def instClass(self): if not self._instClass: from pyanaconda.installclass import factory # Get install class by name. if self.ksdata.anaconda.installclass.seen: name = self.ksdata.anaconda.installclass.name self._instClass = factory.get_install_class_by_name(name) # Or just find the best one. else: self._instClass = factory.get_best_install_class() return self._instClass def _getInterface(self): return self._intf def _setInterface(self, v): # "lambda cannot contain assignment" self._intf = v def _delInterface(self): del self._intf intf = property(_getInterface, _setInterface, _delInterface) @property def payload(self): # Try to find the payload class. First try the install # class. If it doesn't give us one, fall back to the default. if not self._payload: if self.ksdata.ostreesetup.seen: from pyanaconda.payload.rpmostreepayload import RPMOSTreePayload klass = RPMOSTreePayload elif self.opts.liveinst: from pyanaconda.payload.livepayload import LiveImagePayload klass = LiveImagePayload elif self.ksdata.method.method == "liveimg": from pyanaconda.payload.livepayload import LiveImageKSPayload klass = LiveImageKSPayload else: from pyanaconda.payload.dnfpayload import DNFPayload klass = DNFPayload self._payload = klass(self.ksdata) return self._payload @property def protected(self): specs = [] if os.path.exists("/run/initramfs/livedev") and \ stat.S_ISBLK(os.stat("/run/initramfs/livedev")[stat.ST_MODE]): specs.append(os.readlink("/run/initramfs/livedev")) # methodstr and stage2 become strings in ways that pylint can't figure out # pylint: disable=unsubscriptable-object if self.methodstr and SourceFactory.is_harddrive(self.methodstr): specs.append(self.methodstr[3:].split(":", 3)[0]) if self.stage2 and SourceFactory.is_harddrive(self.stage2): specs.append(self.stage2[3:].split(":", 3)[0]) for additional_repo in self.additional_repos: _name, repo_url = self._get_additional_repo_name(additional_repo) if SourceFactory.is_harddrive(repo_url): specs.append(repo_url[3:].split(":", 3)[0]) # zRAM swap devices need to be protected for zram_dev in glob("/dev/zram*"): specs.append(zram_dev) return specs @staticmethod def _get_additional_repo_name(repo): name, rest = repo.split(',', maxsplit=1) return name, rest @property def storage(self): if not self._storage: from pyanaconda.storage.osinstall import InstallerStorage import blivet.arch self._storage = InstallerStorage(ksdata=self.ksdata) self._set_storage_defaults(self._storage) if blivet.arch.is_s390(): self._load_plugin_s390() return self._storage @property def display_mode(self): return self._display_mode @display_mode.setter def display_mode(self, new_mode): if isinstance(new_mode, DisplayModes): if self._display_mode: old_mode = self._display_mode log.debug("changing display mode from %s to %s", old_mode.value, new_mode.value) else: log.debug("setting display mode to %s", new_mode.value) self._display_mode = new_mode else: # unknown mode name - ignore & log an error log.error("tried to set an unknown display mode name: %s", new_mode.value) @property def interactive_mode(self): return self._interactive_mode @interactive_mode.setter def interactive_mode(self, value): if self._interactive_mode != value: self._interactive_mode = value if value: log.debug("working in interative mode") else: log.debug("working in noninteractive mode") @property def gui_mode(self): """Report if Anaconda should run with the GUI.""" return self._display_mode == DisplayModes.GUI @property def tui_mode(self): """Report if Anaconda should run with the TUI.""" return self._display_mode == DisplayModes.TUI def log_display_mode(self): if not self.display_mode: log.error("Display mode is not set!") return log.info("Display mode is set to '%s %s'.", constants.INTERACTIVE_MODE_NAME[self.interactive_mode], constants.DISPLAY_MODE_NAME[self.display_mode]) def add_additional_repositories_to_ksdata(self): from pyanaconda.kickstart import RepoData for add_repo in self.additional_repos: name, repo_url = self._get_additional_repo_name(add_repo) try: source = SourceFactory.parse_repo_cmdline_string(repo_url) except PayloadSourceTypeUnrecognized: log.error("Type for additional repository %s is not recognized!", add_repo) return repo = RepoData(name=name, baseurl=repo_url, install=False) if source.is_nfs or source.is_http or source.is_https or source.is_ftp \ or source.is_file: repo.enabled = True elif source.is_harddrive: repo.enabled = True repo.partition = source.partition repo.iso_path = source.path repo.baseurl = "file://" else: log.error("Source type %s for additional repository %s is not supported!", source.source_type.value, add_repo) continue self._check_repo_name_uniqueness(repo) self.ksdata.repo.dataList().append(repo) def _check_repo_name_uniqueness(self, repo): """Log if we are adding repository with already used name In automatic kickstart installation this will result in using the first defined repo. """ if repo in self.ksdata.repo.dataList(): log.warning("Repository name %s is not unique. Only the first repo will be used!", repo.name) 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 _load_plugin_s390(self): # Make sure s390 plugin is loaded. import gi gi.require_version("BlockDev", "2.0") from gi.repository import BlockDev as blockdev # Is the plugin loaded? We are done then. if "s390" in blockdev.get_available_plugin_names(): return # Otherwise, load the plugin. plugin = blockdev.PluginSpec() plugin.name = blockdev.Plugin.S390 plugin.so_name = None blockdev.reinit([plugin], reload=False) def dumpState(self): from meh import ExceptionInfo from meh.dump import ReverseExceptionDump from inspect import stack as _stack from traceback import format_stack # Skip the frames for dumpState and the signal handler. stack = _stack()[2:] stack.reverse() exn = ReverseExceptionDump(ExceptionInfo(None, None, stack), self.mehConfig) # gather up info on the running threads threads = "\nThreads\n-------\n" # Every call to sys._current_frames() returns a new dict, so it is not # modified when threads are created or destroyed. Iterating over it is # thread safe. for thread_id, frame in sys._current_frames().items(): threads += "\nThread %s\n" % (thread_id,) threads += "".join(format_stack(frame)) # dump to a unique file (fd, filename) = mkstemp(prefix="anaconda-tb-", dir="/tmp") dump_text = exn.traceback_and_object_dump(self) dump_text += threads dump_text_bytes = dump_text.encode("utf-8") os.write(fd, dump_text_bytes) os.close(fd) # append to a given file with open("/tmp/anaconda-tb-all.log", "a+") as f: f.write("--- traceback: %s ---\n" % filename) f.write(dump_text + "\n") def initInterface(self, addon_paths=None): if self._intf: raise RuntimeError("Second attempt to initialize the InstallInterface") if self.gui_mode: from pyanaconda.ui.gui import GraphicalUserInterface # Run the GUI in non-fullscreen mode, so live installs can still # use the window manager self._intf = GraphicalUserInterface(self.storage, self.payload, self.instClass, gui_lock=self.gui_initialized, fullscreen=False, decorated=self.decorated) # needs to be refreshed now we know if gui or tui will take place addon_paths = addons.collect_addon_paths(constants.ADDON_PATHS, ui_subdir="gui") elif self.tui_mode: # TUI and noninteractive TUI are the same in this regard from pyanaconda.ui.tui import TextUserInterface self._intf = TextUserInterface(self.storage, self.payload, self.instClass) # needs to be refreshed now we know if gui or tui will take place addon_paths = addons.collect_addon_paths(constants.ADDON_PATHS, ui_subdir="tui") elif not self.display_mode: raise RuntimeError("Display mode not set.") else: # this should generally never happen, as display_mode now won't let # and invalid value to be set, but let's leave it here just in case # something ultra crazy happens raise RuntimeError("Unsupported display mode: %s" % self.display_mode) if addon_paths: self._intf.update_paths(addon_paths) def writeXdriver(self, root=None): # this should go away at some point, but until it does, we # need to keep it around. if self.xdriver is None: return if root is None: root = util.getSysroot() if not os.path.isdir("%s/etc/X11" %(root,)): os.makedirs("%s/etc/X11" %(root,), mode=0o755) f = open("%s/etc/X11/xorg.conf" %(root,), 'w') f.write('Section "Device"\n\tIdentifier "Videocard0"\n\tDriver "%s"\nEndSection\n' % self.xdriver) f.close()