def time_initialize(timezone, storage, bootloader): """ 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: ksdata.timezone object :param storage: blivet.Blivet instance :param bootloader: bootloader.Bootloader instance """ if arch.is_s390(): # nothing to do on s390(x) were hwclock doesn't exist return if not timezone.isUtc and not flags.automatedInstall: # if set in the kickstart, no magic needed here threadMgr.wait(THREAD_STORAGE) ntfs_devs = filter(lambda dev: dev.format.name == "ntfs", storage.devices) timezone.isUtc = not bootloader.has_windows(ntfs_devs) cmd = "hwclock" args = ["--hctosys"] if timezone.isUtc: args.append("--utc") else: args.append("--localtime") iutil.execWithRedirect(cmd, args)
def recreateInitrds(self, force=False): """ Recreate the initrds by calling new-kernel-pkg This needs to be done after all configuration files have been written, since dracut depends on some of them. :param force: Always recreate, default is to only do it on first call :type force: bool :returns: None """ if not force and self._createdInitrds: return for kernel in self.kernelVersionList: log.info("recreating initrd for %s", kernel) if not flags.imageInstall: iutil.execWithRedirect("new-kernel-pkg", ["--mkinitrd", "--dracut", "--depmod", "--update", kernel], root=ROOT_PATH) else: # hostonly is not sensible for disk image installations # using /dev/disk/by-uuid/ is necessary due to disk image naming iutil.execWithRedirect("dracut", ["-N", "--persistent-policy", "by-uuid", "-f", "/boot/initramfs-%s.img" % kernel, kernel], root=ROOT_PATH) self._createdInitrds = True
def runShell(screen=None, msg=""): if screen: screen.suspend() print if msg: print(msg) if flags.imageInstall: print(_("Run %s to unmount the system when you are finished.") % ANACONDA_CLEANUP) else: print(_("When finished please exit from the shell and your " "system will reboot.")) print proc = None if os.path.exists("/usr/bin/firstaidkit-qs"): iutil.execWithRedirect("/usr/bin/firstaidkit-qs", []) if proc is None or proc.returncode != 0: if os.path.exists("/bin/bash"): iutil.execConsole() else: print(_("Unable to find /bin/sh to execute! Not starting shell")) time.sleep(5) if screen: screen.finish()
def _startLldpad(self): if self.lldpadStarted: return iutil.execWithRedirect("lldpad", [ "-d" ], stdout = "/dev/tty5", stderr="/dev/tty5") self.lldpadStarted = True
def setUserPassword(self, username, password, isCrypted, lock, algo=None, root="/"): # Only set the password if it is a string, including the empty string. # Otherwise leave it alone (defaults to locked for new users) and reset sp_lstchg if password or password == "": if password == "": log.info("user account %s setup with no password", username) elif not isCrypted: password = cryptPassword(password, algo) if lock: password = "******" + password log.info("user account %s locked", username) proc = iutil.startProgram(["chpasswd", "-R", root, "-e"], stdin=subprocess.PIPE) proc.communicate( ("%s:%s\n" % (username, password)).encode("utf-8")) if proc.returncode != 0: raise OSError( "Unable to set password for new user: status=%s" % proc.returncode) # Reset sp_lstchg to an empty string. On systems with no rtc, this # field can be set to 0, which has a special meaning that the password # must be reset on the next login. iutil.execWithRedirect("chage", ["-R", root, "-d", "", username])
def input(self, args, key): """Override input so that we can launch the VNC password spoke""" try: keyid = int(key) - 1 if 0 <= keyid < len(self._choices): choice = self._choices[keyid] if choice == _(USETEXT): self._usevnc = False else: self._usevnc = True newspoke = VNCPassSpoke(self.app, self.data, self.storage, self.payload, self.instclass) self.app.switch_screen_modal(newspoke) self.apply() self.close() return INPUT_PROCESSED except ValueError: pass if key.lower() == _('q'): d = YesNoDialog(self.app, _(self.app.quit_message)) self.app.switch_screen_modal(d) if d.answer: from pyanaconda.flags import can_touch_runtime_system if can_touch_runtime_system("reboot"): execWithRedirect("systemctl", ["--no-wall", "reboot"]) else: sys.exit(1) else: return key
def runShell(screen=None, msg=""): if screen: screen.suspend() print() if msg: print(msg) if flags.imageInstall: print(_("Run %s to unmount the system when you are finished.") % ANACONDA_CLEANUP) else: print(_("When finished please exit from the shell and your " "system will reboot.")) print() proc = None if os.path.exists("/usr/bin/firstaidkit-qs"): iutil.execWithRedirect("/usr/bin/firstaidkit-qs", []) if proc is None or proc.returncode != 0: if os.path.exists("/bin/bash"): iutil.execConsole() else: print(_("Unable to find /bin/sh to execute! Not starting shell")) time.sleep(5) if screen: screen.finish()
def udev_get_block_devices(): # Wait for scsi adapters to be done with scanning their busses (#583143) iutil.execWithRedirect("modprobe", ["scsi_wait_scan"], stdout="/dev/tty5", stderr="/dev/tty5") iutil.execWithRedirect("rmmod", ["scsi_wait_scan"], stdout="/dev/tty5", stderr="/dev/tty5") udev_settle() entries = [] for path in udev_enumerate_block_devices(): entry = udev_get_block_device(path) if entry: if entry["name"].startswith("md"): # mdraid is really braindead, when a device is stopped # it is no longer usefull in anyway (and we should not # probe it) yet it still sticks around, see bug rh523387 state = None state_file = "/sys/%s/md/array_state" % entry["sysfs_path"] if os.access(state_file, os.R_OK): state = open(state_file).read().strip() if state == "clear": continue entries.append(entry) return entries
def setUserSshKey(self, username, key, **kwargs): childpid = self._prepareChroot(kwargs.get("root", iutil.getSysroot())) if childpid == 0: user = self.admin.lookupUserByName(username) if not user: log.error("setUserSshKey: user %s does not exist", username) os._exit(1) homedir = user.get(libuser.HOMEDIRECTORY)[0] if not os.path.exists(homedir): log.error("setUserSshKey: home directory for %s does not exist", username) os._exit(1) sshdir = os.path.join(homedir, ".ssh") if not os.path.isdir(sshdir): os.mkdir(sshdir, 0o700) iutil.eintr_retry_call(os.chown, sshdir, user.get(libuser.UIDNUMBER)[0], user.get(libuser.GIDNUMBER)[0]) authfile = os.path.join(sshdir, "authorized_keys") authfile_existed = os.path.exists(authfile) with open(authfile, "a") as f: f.write(key + "\n") # Only change mode and ownership if we created it if not authfile_existed: iutil.eintr_retry_call(os.chmod, authfile, 0o600) iutil.eintr_retry_call(os.chown, authfile, user.get(libuser.UIDNUMBER)[0], user.get(libuser.GIDNUMBER)[0]) iutil.execWithRedirect("restorecon", ["-r", sshdir]) os._exit(0) else: return self._finishChroot(childpid)
def recreateInitrds(self, force=False): """ Recreate the initrds by calling new-kernel-pkg This needs to be done after all configuration files have been written, since dracut depends on some of them. :param force: Always recreate, default is to only do it on first call :type force: bool :returns: None """ if not force and self._createdInitrds: return for kernel in self.kernelVersionList: log.info("recreating initrd for %s", kernel) if not flags.imageInstall: iutil.execWithRedirect( "new-kernel-pkg", ["--mkinitrd", "--dracut", "--depmod", "--update", kernel], root=ROOT_PATH) else: # hostonly is not sensible for disk image installations # using /dev/disk/by-uuid/ is necessary due to disk image naming iutil.execWithRedirect("dracut", [ "-N", "--persistent-policy", "by-uuid", "-f", "/boot/initramfs-%s.img" % kernel, kernel ], root=ROOT_PATH) self._createdInitrds = True
def input(self, args, key): """Override input so that we can launch the VNC password spoke""" try: keyid = int(key) - 1 if 0 <= keyid < len(self._choices): choice = self._choices[keyid] if choice == _(USETEXT): self._usevnc = False else: self._usevnc = True newspoke = VNCPassSpoke(self.app, self.data, self.storage, self.payload, self.instclass) self.app.switch_screen_modal(newspoke) self.apply() self.close() return INPUT_PROCESSED except ValueError: pass # TRANSLATORS: 'q' to quit if key.lower() == C_('TUI|Spoke Navigation', 'q'): d = YesNoDialog(self.app, _(self.app.quit_message)) self.app.switch_screen_modal(d) if d.answer: ipmi_abort(scripts=self.data.scripts) if can_touch_runtime_system("Quit and Reboot"): execWithRedirect("systemctl", ["--no-wall", "reboot"]) else: sys.exit(1) else: return super(AskVNCSpoke, self).input(args, key)
def exec_with_redirect_test(self): """Test execWithRedirect.""" # correct calling should return rc==0 self.assertEqual(iutil.execWithRedirect('ls', []), 0) # incorrect calling should return rc!=0 self.assertNotEqual(iutil.execWithRedirect('ls', ['--asdasd']), 0)
def input(self, args, key): """Override input so that we can launch the VNC password spoke""" try: keyid = int(key) - 1 if 0 <= keyid < len(self._choices): choice = self._choices[keyid] if choice == _(USETEXT): self._usevnc = False else: self._usevnc = True newspoke = VNCPassSpoke(self.app, self.data, self.storage, self.payload, self.instclass) self.app.switch_screen_modal(newspoke) self.apply() self.close() return INPUT_PROCESSED except ValueError: pass # TRANSLATORS: 'q' to quit if key.lower() == C_('TUI|Spoke Navigation', 'q'): d = YesNoDialog(self.app, _(self.app.quit_message)) self.app.switch_screen_modal(d) if d.answer: iutil.ipmi_report(IPMI_ABORTED) if can_touch_runtime_system("Quit and Reboot"): execWithRedirect("systemctl", ["--no-wall", "reboot"]) else: exit(1) else: return key
def setUserSshKey(self, username, key, **kwargs): root = kwargs.get("root", iutil.getSysroot()) pwent = self._getpwnam(username, root) if not pwent: raise ValueError("setUserSshKey: user %s does not exist" % username) homedir = root + pwent[5] if not os.path.exists(homedir): log.error("setUserSshKey: home directory for %s does not exist", username) raise ValueError("setUserSshKey: home directory for %s does not exist" % username) uid = pwent[2] gid = pwent[3] sshdir = os.path.join(homedir, ".ssh") if not os.path.isdir(sshdir): os.mkdir(sshdir, 0o700) os.chown(sshdir, int(uid), int(gid)) authfile = os.path.join(sshdir, "authorized_keys") authfile_existed = os.path.exists(authfile) with iutil.open_with_perm(authfile, "a", 0o600) as f: f.write(key + "\n") # Only change ownership if we created it if not authfile_existed: os.chown(authfile, int(uid), int(gid)) iutil.execWithRedirect("restorecon", ["-r", sshdir])
def setUserSshKey(self, username, key, **kwargs): root = kwargs.get("root", iutil.getSysroot()) pwent = self._getpwnam(username, root) if not pwent: raise ValueError("setUserSshKey: user %s does not exist" % username) homedir = root + pwent[5] if not os.path.exists(homedir): log.error("setUserSshKey: home directory for %s does not exist", username) raise ValueError( "setUserSshKey: home directory for %s does not exist" % username) uid = pwent[2] gid = pwent[3] sshdir = os.path.join(homedir, ".ssh") if not os.path.isdir(sshdir): os.mkdir(sshdir, 0o700) os.chown(sshdir, int(uid), int(gid)) authfile = os.path.join(sshdir, "authorized_keys") authfile_existed = os.path.exists(authfile) with iutil.open_with_perm(authfile, "a", 0o600) as f: f.write(key + "\n") # Only change ownership if we created it if not authfile_existed: os.chown(authfile, int(uid), int(gid)) iutil.execWithRedirect("restorecon", ["-r", sshdir])
def execute(self, storage, ksdata, instClass, users, payload): """ Execute the addon :param storage: Blivet storage object :param ksdata: Kickstart data object :param instClass: Anaconda installclass object :param users: Anaconda users object :param payload: object managing packages and environment groups for the installation """ if not self.enabled: return log.info("Executing docker addon") # This gets called after installation, before initramfs regeneration and kickstart %post scripts. execWithRedirect("mount", ["-o", "bind", getSysroot()+"/var/lib/docker", "/var/lib/docker"]) execWithRedirect("mount", ["-o", "bind", getSysroot()+"/etc/docker", "/etc/docker"]) # Start up the docker daemon log.debug("Starting docker daemon") docker_cmd = ["docker", "daemon"] if ksdata.selinux.selinux: docker_cmd += ["--selinux-enabled"] # Add storage specific arguments to the command docker_cmd += self.storage.docker_cmd(storage, ksdata, instClass, users) docker_cmd += ["--ip-forward=false", "--iptables=false"] docker_cmd += self.extra_args docker_proc = startProgram(docker_cmd, stdout=open("/tmp/docker-daemon.log", "w"), reset_lang=True) log.debug("Running docker commands") script = AnacondaKSScript(self.content, inChroot=False, logfile="/tmp/docker-addon.log") script.run("/") # Kill the docker process log.debug("Shutting down docker daemon") docker_proc.kill() log.debug("Writing docker configs") self.storage.write_configs(storage, ksdata, instClass, users) # Rewrite the OPTIONS entry with the extra args and/or storage specific changes try: docker_cfg = SimpleConfigFile(getSysroot()+"/etc/sysconfig/docker") docker_cfg.read() options = self.storage.options(docker_cfg.get("OPTIONS")) if self.save_args: log.info("Adding extra args to docker OPTIONS") options += " " + " ".join(self.extra_args) docker_cfg.set(("OPTIONS", options)) docker_cfg.write() except IOError as e: log.error("Error updating OPTIONS in /etc/sysconfig/docker: %s", e) # Copy the log files to the system dstdir = "/var/log/anaconda/" os.makedirs(dstdir, exist_ok=True) for l in ["docker-daemon.log", "docker-addon.log"]: shutil.copy2("/tmp/"+l, dstdir+l)
def input(self, args, key): """Move along home.""" run_shell() if not flags.imageInstall: iutil.execWithRedirect("systemctl", ["--no-wall", "reboot"]) return INPUT_PROCESSED
def execute(self, storage, ksdata, instClass, users): if self.enabled: action = "enable" else: action = "disable" iutil.execWithRedirect("systemctl", [action, "kdump.service"], root=ROOT_PATH)
def _startLldpad(self): if self.lldpadStarted: return iutil.execWithRedirect("lldpad", ["-d"], stdout="/dev/tty5", stderr="/dev/tty5") self.lldpadStarted = True
def has_fcoe(): global _fcoe_module_loaded if not _fcoe_module_loaded: iutil.execWithRedirect("modprobe", [ "fcoe" ], stdout = "/dev/tty5", stderr="/dev/tty5") _fcoe_module_loaded = True return os.access("/sys/module/fcoe", os.X_OK)
def updateSysClock(self): args = ["--hctosys"] if self.c.selected(): args.append("--utc") iutil.execWithRedirect("hwclock", args) self.g.setTimer(500) self.updateClock()
def execute(self, storage, ksdata, instClass, users): """ Execute the addon :param storage: Blivet storage object :param ksdata: Kickstart data object :param instClass: Anaconda installclass object :param users: Anaconda users object """ log.info("Executing docker addon") # This gets called after installation, before initramfs regeneration and kickstart %post scripts. execWithRedirect("mount", ["-o", "bind", getSysroot()+"/var/lib/docker", "/var/lib/docker"]) execWithRedirect("mount", ["-o", "bind", getSysroot()+"/etc/docker", "/etc/docker"]) # Start up the docker daemon log.debug("Starting docker daemon") dm_fs = "dm.fs=%s" % self.fstype pool_name = "dm.thinpooldev=/dev/mapper/%s-docker--pool" % self.vgname docker_cmd = ["docker", "daemon"] if ksdata.selinux.selinux: docker_cmd += ["--selinux-enabled"] docker_cmd += ["--storage-driver", "devicemapper", "--storage-opt", dm_fs, "--storage-opt", pool_name, "--ip-forward=false", "--iptables=false"] docker_cmd += self.extra_args docker_proc = startProgram(docker_cmd, stdout=open("/tmp/docker-daemon.log", "w"), reset_lang=True) log.debug("Running docker commands") script = AnacondaKSScript(self.content, inChroot=False, logfile="/tmp/docker-addon.log") script.run("/") # Kill the docker process log.debug("Shutting down docker daemon") docker_proc.kill() log.debug("Writing docker configs") with open(getSysroot()+"/etc/sysconfig/docker-storage", "w") as fp: fp.write('DOCKER_STORAGE_OPTIONS="--storage-driver devicemapper ' '--storage-opt %s --storage-opt %s"\n' % (dm_fs, pool_name)) with open(getSysroot()+"/etc/sysconfig/docker-storage-setup", "a") as fp: fp.write("VG=%s\n" % self.vgname) # Rewrite the OPTIONS entry with the extra args, if requested. if self.extra_args and self.save_args: try: docker_cfg = SimpleConfigFile(getSysroot()+"/etc/sysconfig/docker") docker_cfg.read() options = docker_cfg.get("OPTIONS")+" " + " ".join(self.extra_args) docker_cfg.set(("OPTIONS", options)) docker_cfg.write() except IOError as e: log.error("Error updating OPTIONS in /etc/sysconfig/docker: %s", e) # Copy the log files to the system dstdir = "/var/log/anaconda/" os.makedirs(dstdir, exist_ok=True) for l in ["docker-daemon.log", "docker-addon.log"]: shutil.copy2("/tmp/"+l, dstdir+l)
def preShutdown(self): # A crude hack for 7.2; forcibly recursively unmount # everything we put in the sysroot. There is something going # on inside either blivet (or systemd?) that's causing mounts inside # /mnt/sysimage/ostree/deploy/$x/sysroot/ostree/deploy # which is not what we want. for (src, dest) in reversed(self._binds): # Also intentionally ignore errors here iutil.execWithRedirect("umount", ['-R', dest if dest else src])
def has_fcoe(): global _fcoe_module_loaded if not _fcoe_module_loaded: iutil.execWithRedirect("modprobe", ["fcoe"], stdout="/dev/tty5", stderr="/dev/tty5") _fcoe_module_loaded = True return os.access("/sys/module/fcoe", os.X_OK)
def apply(self): if flags.automatedInstall and self.data.reboot.action in [ KS_REBOOT, KS_SHUTDOWN ]: iutil.execWithRedirect("systemctl", ["--no-wall", "reboot"]) if not flags.automatedInstall or not self.data.reboot.action in [ KS_REBOOT, KS_SHUTDOWN ]: run_shell()
def set_x_resolution(runres): """Set X server screen resolution. :param str runres: a resolution specification string """ try: log.info("Setting the screen resolution to: %s.", runres) iutil.execWithRedirect("xrandr", ["-d", ":1", "-s", runres]) except RuntimeError: log.error("The X resolution was not set") iutil.execWithRedirect("xrandr", ["-d", ":1", "-q"])
def delete_interfaces(self): if not self.ifaces: return None for iscsi_iface_name in self.ifaces: #iscsiadm -m iface -I iface0 --op=delete iutil.execWithRedirect("iscsiadm", ["-m", "iface", "-I", iscsi_iface_name, "--op=delete"], stdout="/dev/tty5", stderr="/dev/tty5") self.ifaces = {}
def execute(self, storage, ksdata, instClass, users): # the KdumpSpoke should run only if requested if not flags.cmdline.getbool("kdump_addon", default=False): return if self.enabled: action = "enable" else: action = "disable" iutil.execWithRedirect("systemctl", [action, "kdump.service"], root=iutil.getSysroot())
def execute(self, storage, ksdata, instClass, users): # Write out the config file with open(os.path.normpath(ROOT_PATH + CONFIG_FILE), "w") as fobj: fobj.write("%s" % self.content) if self.enabled: action = "enable" else: action = "disable" iutil.execWithRedirect("systemctl", [action, "kdump.service"], root=ROOT_PATH)
def _stabilize(self, intf = None): if intf: w = intf.waitWindow(_("Connecting to FCoE SAN"), _("Connecting to FCoE SAN")) # I have no clue how long we need to wait, this ought to do the trick time.sleep(10) iutil.execWithRedirect("udevadm", [ "settle" ], stdout = "/dev/tty5", stderr="/dev/tty5") if intf: w.pop()
def execute(self, storage, ksdata, instClass, users, payload): # the KdumpSpoke should run only if requested if not flags.cmdline.getbool("kdump_addon", default=False): return if self.enabled: action = "enable" else: action = "disable" iutil.execWithRedirect("systemctl", [action, "kdump.service"], root=iutil.getSysroot())
def _stabilize(self, intf=None): if intf: w = intf.waitWindow(_("Connecting to FCoE SAN"), _("Connecting to FCoE SAN")) # I have no clue how long we need to wait, this ought to do the trick time.sleep(10) iutil.execWithRedirect("udevadm", ["settle"], stdout="/dev/tty5", stderr="/dev/tty5") if intf: w.pop()
def has_fcoe(): global _fcoe_module_loaded if not _fcoe_module_loaded: iutil.execWithRedirect("modprobe", [ "fcoe" ], stdout = "/dev/tty5", stderr="/dev/tty5") _fcoe_module_loaded = True if "bnx2x" in iutil.lsmod(): log.info("fcoe: loading bnx2fc") iutil.execWithRedirect("modprobe", [ "bnx2fc" ], stdout = "/dev/tty5", stderr="/dev/tty5") return os.access("/sys/module/fcoe", os.X_OK)
def do_extra_x11_actions(runres, gui_mode): """Perform X11 actions not related to startup. :param str runres: a resolution specification string :param display_mode: an Anaconda display mode """ if runres and gui_mode and not flags.usevnc: set_x_resolution(runres) # Load the system-wide Xresources iutil.execWithRedirect("xrdb", ["-nocpp", "-merge", "/etc/X11/Xresources"]) start_spice_vd_agent()
def postInstall(self): """ Perform post-installation tasks. """ progressQ.send_message(_("Performing post-installation setup tasks")) blivet.util.umount(INSTALL_TREE) super(LiveImagePayload, self).postInstall() # Live needs to create the rescue image before bootloader is written for kernel in self.kernelVersionList: log.info("Generating rescue image for %s", kernel) iutil.execWithRedirect("new-kernel-pkg", ["--rpmposttrans", kernel], root=ROOT_PATH)
def addSan(self, nic, dcb=False, intf=None): if not has_fcoe(): raise IOError, _("FCoE not available") log.info("Activating FCoE SAN attached to %s, dcb: %s" % (nic, dcb)) iutil.execWithRedirect("ip", ["link", "set", nic, "up"], stdout="/dev/tty5", stderr="/dev/tty5") if dcb: self._startLldpad() iutil.execWithRedirect("dcbtool", ["sc", nic, "dcb", "on"], stdout="/dev/tty5", stderr="/dev/tty5") iutil.execWithRedirect( "dcbtool", ["sc", nic, "app:fcoe", "e:1", "a:1", "w:1"], stdout="/dev/tty5", stderr="/dev/tty5") iutil.execWithRedirect("fipvlan", [nic, "-c", "-s"], stdout="/dev/tty5", stderr="/dev/tty5") else: f = open("/sys/module/fcoe/parameters/create", "w") f.write(nic) f.close() self._stabilize(intf) self.nics.append((nic, dcb))
def addSan(self, nic, dcb=False, intf=None): if not has_fcoe(): raise IOError, _("FCoE not available") log.info("Activating FCoE SAN attached to %s, dcb: %s" % (nic, dcb)) iutil.execWithRedirect("ip", [ "link", "set", nic, "up" ], stdout = "/dev/tty5", stderr="/dev/tty5") if dcb: self._startLldpad() iutil.execWithRedirect("dcbtool", [ "sc", nic, "dcb", "on" ], stdout = "/dev/tty5", stderr="/dev/tty5") iutil.execWithRedirect("dcbtool", [ "sc", nic, "app:fcoe", "e:1", "a:1", "w:1" ], stdout = "/dev/tty5", stderr="/dev/tty5") iutil.execWithRedirect("fipvlan", [ nic, "-c", "-s" ], stdout = "/dev/tty5", stderr="/dev/tty5") else: f = open("/sys/module/fcoe/parameters/create", "w") f.write(nic) f.close() self._stabilize(intf) self.nics.append((nic, dcb))
def _recreateInitrds(self, force=False): if not force and self._createdInitrds: return for kernel in self.kernelVersionList: log.info("recreating initrd for %s" % kernel) iutil.execWithRedirect("new-kernel-pkg", ["--mkinitrd", "--dracut", "--depmod", "--install", kernel], root=ROOT_PATH) iutil.execWithRedirect("new-kernel-pkg", ["--rpmposttrans", kernel], root=ROOT_PATH) self._createdInitrds = True
def postInstall(self): """ Perform post-installation tasks. """ progressQ.send_message(_("Performing post-installation setup tasks")) blivet.util.umount(INSTALL_TREE) super(LiveImagePayload, self).postInstall() # Live needs to create the rescue image before bootloader is written for kernel in self.kernelVersionList: log.info("Generating rescue image for %s", kernel) iutil.execWithRedirect("new-kernel-pkg", ["--rpmposttrans", kernel], root=ROOT_PATH) # Make sure the new system has a machine-id, it won't boot without it if not os.path.exists(ROOT_PATH + "/etc/machine-id"): iutil.execWithRedirect("systemd-machine-id-setup", [], root=ROOT_PATH)
def input(self, args, key): """Override any input so we can launch rescue mode.""" try: keyid = int(key) - 1 except ValueError: pass if keyid == 3: # quit/reboot d = YesNoDialog(self.app, _(self.app.quit_message)) self.app.switch_screen_modal(d) if d.answer: iutil.execWithRedirect("systemctl", ["--no-wall", "reboot"]) elif keyid == 2: # skip to/run shell run_shell() elif (keyid == 1 or keyid == 0): # user chose 0 (continue/rw-mount) or 1 (ro-mount) # decrypt any luks devices self._unlock_devices() # this sleep may look pointless, but it seems necessary, in # order for some task to complete; otherwise no existing # installations are discovered. IOW, this is a hack. time.sleep(2) # attempt to find previous installations roots = find_existing_installations(self.storage.devicetree) if len(roots) == 1: self._root = roots[0] elif len(roots) > 1: # have to prompt user for which root to mount rootspoke = RootSpoke(self.app, self.data, self.storage, self.payload, self.instclass, roots) self.app.switch_screen_modal(rootspoke) self._root = rootspoke.root # if only one root detected, or user has chosen which root # to mount, go ahead and do that newspoke = RescueMountSpoke(self.app, self.data, self.storage, self.payload, self.instclass, keyid, self._root) self.app.switch_screen_modal(newspoke) self.close() else: # user entered some invalid number choice return key return INPUT_PROCESSED
def input(self, args, key): """Override any input so we can launch rescue mode.""" try: keyid = int(key) - 1 except ValueError: pass if keyid == 3: # quit/reboot d = YesNoDialog(self.app, _(self.app.quit_message)) self.app.switch_screen_modal(d) if d.answer: iutil.execWithRedirect("systemctl", ["--no-wall", "reboot"]) elif keyid == 2: # skip to/run shell run_shell() elif (keyid == 1 or keyid == 0): # user chose 0 (continue/rw-mount) or 1 (ro-mount) # decrypt any luks devices self._unlock_devices() # this sleep may look pointless, but it seems necessary, in # order for some task to complete; otherwise no existing # installations are discovered. IOW, this is a hack. time.sleep(2) # attempt to find previous installations roots = findExistingInstallations(self.storage.devicetree) if len(roots) == 1: self._root = roots[0] elif len(roots) > 1: # have to prompt user for which root to mount rootspoke = RootSpoke(self.app, self.data, self.storage, self.payload, self.instclass, roots) self.app.switch_screen_modal(rootspoke) self._root = rootspoke.root # if only one root detected, or user has chosen which root # to mount, go ahead and do that newspoke = RescueMountSpoke(self.app, self.data, self.storage, self.payload, self.instclass, keyid, self._root) self.app.switch_screen_modal(newspoke) self.close() else: # user entered some invalid number choice return key return INPUT_PROCESSED
def _safeExecWithRedirect(self, cmd, argv, **kwargs): """Like iutil.execWithRedirect, but treat errors as fatal""" rc = iutil.execWithRedirect(cmd, argv, **kwargs) if rc != 0: exn = PayloadInstallError("%s %s exited with code %d" % (cmd, argv, rc)) if errors.errorHandler.cb(exn) == errors.ERROR_RAISE: raise exn
def luks_add_key(device, new_passphrase=None, new_key_file=None, passphrase=None, key_file=None): params = ["-q"] p = os.pipe() if passphrase: os.write(p[1], "%s\n" % passphrase) elif key_file and os.path.isfile(key_file): params.extend(["--key-file", key_file]) else: raise CryptoError("luks_add_key requires either a passphrase or a key file") params.extend(["luksAddKey", device]) if new_passphrase: os.write(p[1], "%s\n" % new_passphrase) elif new_key_file and os.path.isfile(new_key_file): params.append("%s" % new_key_file) else: raise CryptoError("luks_add_key requires either a passphrase or a key file to add") os.close(p[1]) rc = iutil.execWithRedirect("cryptsetup", params, stdin = p[0], stdout = "/dev/tty5", stderr = "/dev/tty5") os.close(p[0]) if rc: raise CryptoError("luks add key failed with errcode %d" % (rc,))
def swapoff(device): rc = iutil.execWithRedirect("swapoff", [device], stderr = "/dev/tty5", stdout = "/dev/tty5") if rc: raise SwapError("swapoff failed for '%s'" % device)
def _try_to_load_keymap(keymap): """ Method that tries to load keymap and returns boolean indicating if it was successfull or not. It can be used to test if given string is VConsole keymap or not, but in case it is given valid keymap, IT REALLY LOADS IT!. :type keymap: string :raise KeyboardConfigError: if loadkeys command is not available :return: True if given string was a valid keymap and thus was loaded, False otherwise """ # BUG: systemd-localed should be able to tell us if we are trying to # activate invalid keymap. Then we will be able to get rid of this # fuction ret = 0 try: ret = iutil.execWithRedirect("loadkeys", [keymap]) except OSError as oserr: msg = "'loadkeys' command not available (%s)" % oserr.strerror raise KeyboardConfigError(msg) return ret == 0
def createGroup(self, group_name, **kwargs): """Create a new user on the system with the given name. Optional kwargs: :keyword int gid: The GID for the new user. If none is given, the next available one is used. :keyword str root: The directory of the system to create the new user in. homedir will be interpreted relative to this. Defaults to iutil.getSysroot(). """ root = kwargs.get("root", iutil.getSysroot()) if self._getgrnam(group_name, root): raise ValueError("Group %s already exists" % group_name) args = ["-R", root] if kwargs.get("gid") is not None: args.extend(["-g", str(kwargs["gid"])]) args.append(group_name) with self._ensureLoginDefs(root): status = iutil.execWithRedirect("groupadd", args) if status == 4: raise ValueError("GID %s already exists" % kwargs.get("gid")) elif status == 9: raise ValueError("Group %s already exists" % group_name) elif status != 0: raise OSError("Unable to create group %s: status=%s" % (group_name, status))
def doMigrate(self, intf=None): if not self.exists: raise FSError("filesystem has not been created") if not self.migratable or not self.migrate: return if not os.path.exists(self.device): raise FSError("device does not exist") argv = self._defaultMigrateOptions[:] argv.append(self.device) try: rc = iutil.execWithRedirect(self.migratefsProg, argv, stdout="/dev/tty5", stderr="/dev/tty5") except Exception as e: raise FSMigrateError("filesystem migration failed: %s" % e, self.device) if rc: raise FSMigrateError("filesystem migration failed: %s" % rc, self.device) # the other option is to actually replace this instance with an # instance of the new filesystem type. self._type = self.migrationTarget
def loadModule(self): """Load whatever kernel module is required to support this filesystem.""" global kernel_filesystems if not self._modules or self.mountType in kernel_filesystems: return for module in self._modules: try: rc = iutil.execWithRedirect("modprobe", [module], stdout="/dev/tty5", stderr="/dev/tty5") except Exception as e: log.error("Could not load kernel module %s: %s" % (module, e)) self._supported = False return if rc: log.error("Could not load kernel module %s" % module) self._supported = False return # If we successfully loaded a kernel module, for this filesystem, we # also need to update the list of supported filesystems. kernel_filesystems = get_kernel_filesystems()
def swapoff(device): rc = iutil.execWithRedirect("swapoff", [device], stderr="/dev/tty5", stdout="/dev/tty5") if rc: raise SwapError("swapoff failed for '%s'" % device)
def install(self): """ Install the payload. """ self.pct_lock = Lock() self.pct = 0 threadMgr.add(AnacondaThread(name=THREAD_LIVE_PROGRESS, target=self.progress)) cmd = "rsync" # preserve: permissions, owners, groups, ACL's, xattrs, times, # symlinks, hardlinks # go recursively, include devices and special files, don't cross # file system boundaries args = ["-pogAXtlHrDx", "--exclude", "/dev/", "--exclude", "/proc/", "--exclude", "/sys/", "--exclude", "/run/", "--exclude", "/boot/*rescue*", "--exclude", "/etc/machine-id", INSTALL_TREE+"/", ROOT_PATH] try: rc = iutil.execWithRedirect(cmd, args) except (OSError, RuntimeError) as e: msg = None err = str(e) log.error(err) else: err = None msg = "%s exited with code %d" % (cmd, rc) log.info(msg) if err or rc == 12: exn = PayloadInstallError(err or msg) if errorHandler.cb(exn) == ERROR_RAISE: raise exn # Wait for progress thread to finish with self.pct_lock: self.pct = 100 threadMgr.wait(THREAD_LIVE_PROGRESS)