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 iutil.open_with_perm(authfile, "a", 0o600) as f: f.write(key + "\n") # Only change ownership if we created it if not authfile_existed: 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 runDebug(self, exc_info): if flags.can_touch_runtime_system("switch console") \ and self._intf_tty_num != 1: iutil.vtActivate(1) iutil.eintr_retry_call(os.open, "/dev/console", os.O_RDWR) # reclaim stdin iutil.eintr_ignore(os.dup2, 0, 1) # reclaim stdout iutil.eintr_ignore(os.dup2, 0, 2) # reclaim stderr # ^ # | # +------ dup2 is magic, I tells ya! # bring back the echo import termios si = sys.stdin.fileno() attr = termios.tcgetattr(si) attr[3] = attr[3] & termios.ECHO termios.tcsetattr(si, termios.TCSADRAIN, attr) print("\nEntering debugger...") print("Use 'continue' command to quit the debugger and get back to "\ "the main window") import pdb pdb.post_mortem(exc_info.stack) if flags.can_touch_runtime_system("switch console") \ and self._intf_tty_num != 1: iutil.vtActivate(self._intf_tty_num)
def runDebug(self, exc_info): if flags.can_touch_runtime_system("switch console") and self._intf_tty_num != 1: iutil.vtActivate(1) iutil.eintr_retry_call(os.open, "/dev/console", os.O_RDWR) # reclaim stdin iutil.eintr_ignore(os.dup2, 0, 1) # reclaim stdout iutil.eintr_ignore(os.dup2, 0, 2) # reclaim stderr # ^ # | # +------ dup2 is magic, I tells ya! # bring back the echo import termios si = sys.stdin.fileno() attr = termios.tcgetattr(si) attr[3] = attr[3] & termios.ECHO termios.tcsetattr(si, termios.TCSADRAIN, attr) print("\nEntering debugger...") print("Use 'continue' command to quit the debugger and get back to " "the main window") import pdb pdb.post_mortem(exc_info.stack) if flags.can_touch_runtime_system("switch console") and self._intf_tty_num != 1: iutil.vtActivate(self._intf_tty_num)
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) iutil.eintr_retry_call(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: iutil.eintr_retry_call(os.chown, authfile, int(uid), int(gid)) iutil.execWithRedirect("restorecon", ["-r", sshdir])
def write(self, filename=None, use_tmp=True): """ passing filename will override the filename passed to init. """ filename = filename or self.filename if not filename: return None if use_tmp: tmpf = tempfile.NamedTemporaryFile(mode="w", delete=False) tmpf.write(str(self)) tmpf.close() # Move the temporary file (with 0600 permissions) over the top of the # original and preserve the original's permissions filename = os.path.realpath(filename) if os.path.exists(filename): m = os.stat(filename).st_mode else: m = int('0100644', 8) shutil.move(tmpf.name, filename) eintr_retry_call(os.chmod, filename, m) else: # write directly to the file with open(filename, "w") as fobj: fobj.write(str(self))
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") iutil.eintr_retry_call(os.write, fd, dump_text_bytes) iutil.eintr_ignore(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 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) iutil.eintr_retry_call(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: iutil.eintr_retry_call(os.chown, authfile, int(uid), int(gid)) iutil.execWithRedirect("restorecon", ["-r", sshdir])
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().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 = dump_text.encode("utf-8") iutil.eintr_retry_call(os.write, fd, dump_text) iutil.eintr_retry_call(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 write_tmpfile(filename, data): tmpf = tempfile.NamedTemporaryFile(mode="w", delete=False) tmpf.write(data) tmpf.close() # Move the temporary file (with 0600 permissions) over the top of the # original and preserve the original's permissions filename = os.path.realpath(filename) if os.path.exists(filename): m = os.stat(filename).st_mode else: m = int('0100644', 8) shutil.move(tmpf.name, filename) eintr_retry_call(os.chmod, filename, m)
def _writeKS(ksdata): import os path = iutil.getSysroot() + "/root/anaconda-ks.cfg" # Clear out certain sensitive information that kickstart doesn't have a # way of representing encrypted. for obj in [ksdata.autopart] + ksdata.logvol.dataList() + \ ksdata.partition.dataList() + ksdata.raid.dataList(): obj.passphrase = "" with open(path, "w") as f: f.write(str(ksdata)) # Make it so only root can read - could have passwords iutil.eintr_retry_call(os.chmod, path, 0o600)
def check(self): """Check configured storage against software selections. When this method is complete (which should be pretty quickly), the following attributes are available for inspection: success -- A simple boolean defining whether there's enough space or not. deficit -- If unsuccessful, how much space the system is short for current software selections. error_message -- If unsuccessful, an error message describing the situation. This message is suitable for putting in the info bar at the bottom of a Hub. """ self.reset() stat = iutil.eintr_retry_call(os.statvfs, iutil.getSysroot()) free = Size(stat.f_bsize * stat.f_bfree) needed = self.payload.spaceRequired log.info("fs space: %s needed: %s", free, needed) self.success = (free > needed) if not self.success: dev_required_size = self.payload.requiredDeviceSize(self.storage.rootDevice.format) self.deficit = dev_required_size - self.storage.rootDevice.size self.error_message = _(self.error_template) % self.deficit return self.success
def setup(self, storage, instClass): super(LiveImagePayload, self).setup(storage, instClass) # Mount the live device and copy from it instead of the overlay at / osimg = storage.devicetree.getDeviceByPath(self.data.method.partition) if not osimg: raise PayloadInstallError("Unable to find osimg for %s" % self.data.method.partition) if not stat.S_ISBLK(os.stat(osimg.path)[stat.ST_MODE]): exn = PayloadSetupError("%s is not a valid block device" % (self.data.method.partition, )) if errorHandler.cb(exn) == ERROR_RAISE: raise exn rc = blivet.util.mount(osimg.path, INSTALL_TREE, fstype="auto", options="ro") if rc != 0: raise PayloadInstallError("Failed to mount the install tree") # Grab the kernel version list now so it's available after umount self._updateKernelVersionList() source = iutil.eintr_retry_call(os.statvfs, INSTALL_TREE) self.source_size = source.f_frsize * (source.f_blocks - source.f_bfree)
def progress(self): """Monitor the amount of disk space used on the target and source and update the hub's progress bar. """ mountpoints = self.storage.mountpoints.copy() last_pct = -1 while self.pct < 100: dest_size = 0 for mnt in mountpoints: mnt_stat = iutil.eintr_retry_call(os.statvfs, iutil.getSysroot() + mnt) dest_size += mnt_stat.f_frsize * (mnt_stat.f_blocks - mnt_stat.f_bfree) if dest_size >= self._adj_size: dest_size -= self._adj_size pct = int(100 * dest_size / self.source_size) if pct != last_pct: with self.pct_lock: self.pct = pct last_pct = pct progressQ.send_message( _("Installing software") + (" %d%%") % (min(100, self.pct), )) sleep(0.777)
def setVNCPassword(self): """Set the vnc server password. Output to file. """ r, w = os.pipe() password_string = "%s\n" % self.password iutil.eintr_retry_call(os.write, w, password_string.encode("utf-8")) with open(self.pw_file, "wb") as pw_file: # the -f option makes sure vncpasswd does not ask for the password again rc = iutil.execWithRedirect("vncpasswd", ["-f"], stdin=r, stdout=pw_file, binary_output=True, log_output=False) iutil.eintr_ignore(os.close, r) iutil.eintr_ignore(os.close, w) return rc
def write_tmpfile(filename, data): # Create a temporary in the same directory as the target file to ensure # the new file is on the same filesystem tmpf = tempfile.NamedTemporaryFile(mode="w", delete=False, dir=os.path.dirname(filename) or '.', prefix="." + os.path.basename(filename)) tmpf.write(data) tmpf.close() # Change the permissions (currently 0600) to match the original file if os.path.exists(filename): m = os.stat(filename).st_mode else: m = 0o0644 eintr_retry_call(os.chmod, filename, m) # Move the temporary file over the top of the original os.rename(tmpf.name, filename)
def openlogfile(self): try: fd = iutil.eintr_retry_call(os.open, self.log_file, os.O_RDWR | os.O_CREAT) except OSError as e: sys.stderr.write("error opening %s: %s\n", (self.log_file, e)) fd = None return fd
def _finishChroot(self, childpid): assert childpid > 0 try: status = iutil.eintr_retry_call(os.waitpid, childpid, 0)[1] except OSError as e: log.critical("exception from waitpid: %s %s", e.errno, e.strerror) return False if os.WIFEXITED(status) and (os.WEXITSTATUS(status) == 0): return True else: return False
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 setup(self, storage, instClass): super(LiveImagePayload, self).setup(storage, instClass) # Mount the live device and copy from it instead of the overlay at / osimg = storage.devicetree.getDeviceByPath(self.data.method.partition) if not stat.S_ISBLK(os.stat(osimg.path)[stat.ST_MODE]): exn = PayloadSetupError("%s is not a valid block device" % (self.data.method.partition,)) if errorHandler.cb(exn) == ERROR_RAISE: raise exn rc = blivet.util.mount(osimg.path, INSTALL_TREE, fstype="auto", options="ro") if rc != 0: raise PayloadInstallError("Failed to mount the install tree") # Grab the kernel version list now so it's available after umount self._updateKernelVersionList() source = iutil.eintr_retry_call(os.statvfs, INSTALL_TREE) self.source_size = source.f_frsize * (source.f_blocks - source.f_bfree)
def progress(self): """Monitor the amount of disk space used on the target and source and update the hub's progress bar. """ mountpoints = self.storage.mountpoints.copy() last_pct = -1 while self.pct < 100: dest_size = 0 for mnt in mountpoints: mnt_stat = iutil.eintr_retry_call(os.statvfs, iutil.getSysroot()+mnt) dest_size += mnt_stat.f_frsize * (mnt_stat.f_blocks - mnt_stat.f_bfree) if dest_size >= self._adj_size: dest_size -= self._adj_size pct = int(100 * dest_size / self.source_size) if pct != last_pct: with self.pct_lock: self.pct = pct last_pct = pct progressQ.send_message(_("Installing software") + (" %d%%") % (min(100, self.pct),)) sleep(0.777)
def check(self): """Check configured storage against software selections. When this method is complete (which should be pretty quickly), the following attributes are available for inspection: success -- A simple boolean defining whether there's enough space or not. deficit -- If unsuccessful, how much space the system is short for current software selections. error_message -- If unsuccessful, an error message describing the situation. This message is suitable for putting in the info bar at the bottom of a Hub. """ self.reset() stat = iutil.eintr_retry_call(os.statvfs, iutil.getSysroot()) free = Size(stat.f_bsize * stat.f_bfree) needed = self.payload.spaceRequired log.info("fs space: %s needed: %s", free, needed) self.success = (free >= needed) if not self.success: self.deficit = needed - free self.error_message = _(self.error_template) % self.deficit return self.success
def runDebug(self, exc_info): if flags.can_touch_runtime_system("switch console") \ and self._intf_tty_num != 1: iutil.vtActivate(1) pidfl = "/tmp/vncshell.pid" if os.path.exists(pidfl) and os.path.isfile(pidfl): pf = open(pidfl, "r") for pid in pf.readlines(): if not int(pid) == os.getpid(): os.kill(int(pid), signal.SIGKILL) pf.close() iutil.eintr_retry_call(os.open, "/dev/console", os.O_RDWR) # reclaim stdin iutil.eintr_retry_call(os.dup2, 0, 1) # reclaim stdout iutil.eintr_retry_call(os.dup2, 0, 2) # reclaim stderr # ^ # | # +------ dup2 is magic, I tells ya! # bring back the echo import termios si = sys.stdin.fileno() attr = termios.tcgetattr(si) attr[3] = attr[3] & termios.ECHO termios.tcsetattr(si, termios.TCSADRAIN, attr) print("\nEntering debugger...") print("Use 'continue' command to quit the debugger and get back to "\ "the main window") import pdb pdb.post_mortem(exc_info.stack) if flags.can_touch_runtime_system("switch console") \ and self._intf_tty_num != 1: iutil.vtActivate(self._intf_tty_num)
def preInstall(self, *args, **kwargs): """ Get image and loopback mount it. This is called after partitioning is setup, we now have space to grab the image. If it is a network source Download it to sysroot and provide feedback during the download (using urlgrabber callback). If it is a file:// source then use the file directly. """ error = None if self.data.method.url.startswith("file://"): self.image_path = self.data.method.url[7:] else: error = self._preInstall_url_image() if error: exn = PayloadInstallError(str(error)) if errorHandler.cb(exn) == ERROR_RAISE: raise exn # Used to make install progress % look correct self._adj_size = os.stat(self.image_path)[stat.ST_SIZE] if self.data.method.checksum: progressQ.send_message(_("Checking image checksum")) sha256 = hashlib.sha256() with open(self.image_path, "rb") as f: while True: data = f.read(1024*1024) if not data: break sha256.update(data) filesum = sha256.hexdigest() log.debug("sha256 of %s is %s", self.data.method.url, filesum) if lowerASCII(self.data.method.checksum) != filesum: log.error("%s does not match checksum.", self.data.method.checksum) exn = PayloadInstallError("Checksum of image does not match") if errorHandler.cb(exn) == ERROR_RAISE: raise exn # If this looks like a tarfile, skip trying to mount it if self.is_tarfile: return # Mount the image and check to see if it is a LiveOS/*.img # style squashfs image. If so, move it to IMAGE_DIR and mount the real # root image on INSTALL_TREE rc = blivet.util.mount(self.image_path, INSTALL_TREE, fstype="auto", options="ro") if rc != 0: log.error("mount error (%s) with %s", rc, self.image_path) exn = PayloadInstallError("mount error %s" % rc) if errorHandler.cb(exn) == ERROR_RAISE: raise exn # Nothing more to mount if not os.path.exists(INSTALL_TREE+"/LiveOS"): self._updateKernelVersionList() return # Mount the first .img in the directory on INSTALL_TREE img_files = glob.glob(INSTALL_TREE+"/LiveOS/*.img") if img_files: # move the mount to IMAGE_DIR os.makedirs(IMAGE_DIR, 0o755) # work around inability to move shared filesystems rc = iutil.execWithRedirect("mount", ["--make-rprivate", "/"]) if rc == 0: rc = iutil.execWithRedirect("mount", ["--move", INSTALL_TREE, IMAGE_DIR]) if rc != 0: log.error("error %s moving mount", rc) exn = PayloadInstallError("mount error %s" % rc) if errorHandler.cb(exn) == ERROR_RAISE: raise exn img_file = IMAGE_DIR+"/LiveOS/"+os.path.basename(sorted(img_files)[0]) rc = blivet.util.mount(img_file, INSTALL_TREE, fstype="auto", options="ro") if rc != 0: log.error("mount error (%s) with %s", rc, img_file) exn = PayloadInstallError("mount error %s with %s" % (rc, img_file)) if errorHandler.cb(exn) == ERROR_RAISE: raise exn self._updateKernelVersionList() source = iutil.eintr_retry_call(os.statvfs, INSTALL_TREE) self.source_size = source.f_frsize * (source.f_blocks - source.f_bfree)
def save_servers_to_config(servers, conf_file_path=NTP_CONFIG_FILE, srv_regexp=SRV_LINE_REGEXP, out_file_path=None): """ Replaces the servers defined in the chronyd's configuration file with the given ones. If the out_file is not None, then it is used for the resulting config. :type servers: iterable :param out_file_path: path to the file used for the resulting config """ try: old_conf_file = open(conf_file_path, "r") except IOError as ioerr: msg = "Cannot open config file %s for reading (%s)" % (conf_file_path, ioerr.strerror) raise NTPconfigError(msg) try: if out_file_path: new_conf_file = open(out_file_path, "w") else: (fildes, temp_path) = tempfile.mkstemp() new_conf_file = os.fdopen(fildes, "w") except IOError as ioerr: if out_file_path: msg = "Cannot open new config file %s "\ "for writing (%s)" % (out_file_path, ioerr.strerror) else: msg = "Cannot open temporary file %s "\ "for writing (%s)" % (temp_path, ioerr.strerror) raise NTPconfigError(msg) heading = "# These servers were defined in the installation:\n" #write info about the origin of the following lines new_conf_file.write(heading) #write new servers for server in servers: new_conf_file.write("server " + server + " iburst\n") #copy non-server lines from the old config and skip our heading for line in old_conf_file: if not srv_regexp.match(line) and line != heading: new_conf_file.write(line) old_conf_file.close() new_conf_file.close() if not out_file_path: try: stat = os.stat(conf_file_path) # Use copy rather then move to get the correct selinux context shutil.copy(temp_path, conf_file_path) iutil.eintr_retry_call(os.chmod, conf_file_path, stat.st_mode) os.unlink(temp_path) except OSError as oserr: msg = "Cannot replace the old config with "\ "the new one (%s)" % (oserr.strerror) raise NTPconfigError(msg)
def _tui_wait(msg, desired_entropy): """Tell user we are waiting for entropy""" print(msg) print(_("Entropy can be increased by typing randomly on keyboard")) print(_("After %d minutes, the installation will continue regardless of the " "amount of available entropy") % (MAX_ENTROPY_WAIT / 60)) fd = sys.stdin.fileno() termios_attrs_changed = False try: old = termios.tcgetattr(fd) new = termios.tcgetattr(fd) new[3] = new[3] & ~termios.ICANON & ~termios.ECHO new[6][termios.VMIN] = 1 termios.tcsetattr(fd, termios.TCSANOW, new) termios_attrs_changed = True except termios.error as term_err: if term_err.args[0] == errno.ENOTTY: # "Inappropriate ioctl for device" --> terminal attributes not supported pass else: raise # wait for the entropy to become high enough or time has run out cur_entr = get_current_entropy() secs = 0 while cur_entr < desired_entropy and secs <= MAX_ENTROPY_WAIT: remaining = (MAX_ENTROPY_WAIT - secs) / 60.0 print(_("Available entropy: %(av_entr)s, Required entropy: %(req_entr)s [%(pct)d %%] (%(rem)d %(min)s remaining)") % {"av_entr": cur_entr, "req_entr": desired_entropy, "pct": int((float(cur_entr) / desired_entropy) * 100), "min": P_("minute", "minutes", remaining), "rem": math.ceil(remaining)}) time.sleep(1) cur_entr = get_current_entropy() secs += 1 # print the final state as well print(_("Available entropy: %(av_entr)s, Required entropy: %(req_entr)s [%(pct)d %%]") % {"av_entr": cur_entr, "req_entr": desired_entropy, "pct": int((float(cur_entr) / desired_entropy) * 100)}) if secs <= MAX_ENTROPY_WAIT: print(_("Enough entropy gathered, please stop typing.")) force_cont = False else: print(_("Giving up, time (%d minutes) ran out.") % (MAX_ENTROPY_WAIT / 60)) force_cont = True # we are done # first let the user notice we are done and stop typing time.sleep(5) # and then just read everything from the input buffer and revert the # termios state data = "have something" while sys.stdin in eintr_retry_call(select.select, [sys.stdin], [], [], 0)[0] and data: # just read from stdin and scratch the read data data = sys.stdin.read(1) if termios_attrs_changed: termios.tcsetattr(fd, termios.TCSAFLUSH, old) return force_cont
def save_servers_to_config(servers, conf_file_path=CHRONY_CONFIG_FILE, srv_regexp=SRV_LINE_REGEXP, out_file_path=None): """ Replaces the servers defined in the chronyd's configuration file with the given ones. If the out_file is not None, then it is used for the resulting config. :type servers: iterable :param out_file_path: path to the file used for the resulting config """ try: old_conf_file = open(conf_file_path, "r") except IOError as ioerr: msg = "Cannot open config file %s for reading (%s)" % (conf_file_path, ioerr.strerror) raise NTPconfigError(msg) try: if out_file_path: new_conf_file = open(out_file_path, "w") else: (fildes, temp_path) = tempfile.mkstemp() new_conf_file = os.fdopen(fildes, "w") except IOError as ioerr: if out_file_path: msg = "Cannot open new config file %s "\ "for writing (%s)" % (out_file_path, ioerr.strerror) else: msg = "Cannot open temporary file %s "\ "for writing (%s)" % (temp_path, ioerr.strerror) raise NTPconfigError(msg) heading = "# These servers were defined in the installation:\n" #write info about the origin of the following lines new_conf_file.write(heading) #write new servers for server in servers: new_conf_file.write("server " + server + " iburst\n") #copy non-server lines from the old config and skip our heading for line in old_conf_file: if not srv_regexp.match(line) and line != heading: new_conf_file.write(line) old_conf_file.close() new_conf_file.close() if not out_file_path: try: stat = os.stat(conf_file_path) # Use copy rather then move to get the correct selinux context shutil.copy(temp_path, conf_file_path) iutil.eintr_retry_call(os.chmod, conf_file_path, stat.st_mode) os.unlink(temp_path) except OSError as oserr: msg = "Cannot replace the old config with "\ "the new one (%s)" % (oserr.strerror) raise NTPconfigError(msg)
def _tui_wait(msg, desired_entropy): """Tell user we are waiting for entropy""" print(msg) print(_("Entropy can be increased by typing randomly on keyboard")) print( _("After %d minutes, the installation will continue regardless of the " "amount of available entropy") % (MAX_ENTROPY_WAIT / 60)) fd = sys.stdin.fileno() termios_attrs_changed = False try: old = termios.tcgetattr(fd) new = termios.tcgetattr(fd) new[3] = new[3] & ~termios.ICANON & ~termios.ECHO new[6][termios.VMIN] = 1 termios.tcsetattr(fd, termios.TCSANOW, new) termios_attrs_changed = True except termios.error as term_err: if term_err.args[0] == errno.ENOTTY: # "Inappropriate ioctl for device" --> terminal attributes not supported pass else: raise # wait for the entropy to become high enough or time has run out cur_entr = get_current_entropy() secs = 0 while cur_entr < desired_entropy and secs <= MAX_ENTROPY_WAIT: remaining = (MAX_ENTROPY_WAIT - secs) / 60.0 print( _("Available entropy: %(av_entr)s, Required entropy: %(req_entr)s [%(pct)d %%] (%(rem)d %(min)s remaining)" ) % { "av_entr": cur_entr, "req_entr": desired_entropy, "pct": int((float(cur_entr) / desired_entropy) * 100), "min": P_("minute", "minutes", remaining), "rem": math.ceil(remaining) }) time.sleep(1) cur_entr = get_current_entropy() secs += 1 # print the final state as well print( _("Available entropy: %(av_entr)s, Required entropy: %(req_entr)s [%(pct)d %%]" ) % { "av_entr": cur_entr, "req_entr": desired_entropy, "pct": int((float(cur_entr) / desired_entropy) * 100) }) if secs <= MAX_ENTROPY_WAIT: print(_("Enough entropy gathered, please stop typing.")) force_cont = False else: print( _("Giving up, time (%d minutes) ran out.") % (MAX_ENTROPY_WAIT / 60)) force_cont = True # we are done # first let the user notice we are done and stop typing time.sleep(5) # and then just read everything from the input buffer and revert the # termios state data = "have something" while sys.stdin in eintr_retry_call(select.select, [sys.stdin], [], [], 0)[0] and data: # just read from stdin and scratch the read data data = sys.stdin.read(1) if termios_attrs_changed: termios.tcsetattr(fd, termios.TCSAFLUSH, old) return force_cont