def del_execReadlines_test(self): cmd = [ "python3", "-c", "import sys; print('Truffula trees.'); sys.exit(0)" ] iterator = execReadlines(cmd[0], cmd[1:], callback=lambda p: True) del iterator
def test_execReadlines(self): cmd = [ "python3", "-c", "import sys; print('Truffula trees.'); sys.exit(0)" ] iterator = execReadlines(cmd[0], cmd[1:], callback=lambda p: True, filter_stderr=True) self.assertEqual(list(iterator), ["Truffula trees."])
def novirt_install(opts, disk_img, disk_size, cancel_func=None): """ Use Anaconda to install to a disk image :param opts: options passed to livemedia-creator :type opts: argparse options :param str disk_img: The full path to the disk image to be created :param int disk_size: The size of the disk_img in MiB :param cancel_func: Function that returns True to cancel build :type cancel_func: function This method runs anaconda to create the image and then based on the opts passed creates a qemu disk image or tarfile. """ dirinstall_path = ROOT_PATH # Clean up /tmp/ from previous runs to prevent stale info from being used for path in ["/tmp/yum.repos.d/", "/tmp/yum.cache/"]: if os.path.isdir(path): shutil.rmtree(path) args = ["--kickstart", opts.ks[0], "--cmdline", "--loglevel", "debug"] if opts.anaconda_args: for arg in opts.anaconda_args: args += arg.split(" ", 1) if opts.proxy: args += ["--proxy", opts.proxy] if opts.armplatform: args += ["--armplatform", opts.armplatform] if opts.make_iso or opts.make_fsimage or opts.make_pxe_live: # Make a blank fs image args += ["--dirinstall"] mkext4img(None, disk_img, label=opts.fs_label, size=disk_size * 1024**2) if not os.path.isdir(dirinstall_path): os.mkdir(dirinstall_path) mount(disk_img, opts="loop", mnt=dirinstall_path) elif opts.make_tar or opts.make_oci: # Install under dirinstall_path, make sure it starts clean if os.path.exists(dirinstall_path): shutil.rmtree(dirinstall_path) if opts.make_oci: # OCI installs under /rootfs/ dirinstall_path = joinpaths(dirinstall_path, "rootfs") args += ["--dirinstall", dirinstall_path] else: args += ["--dirinstall"] os.makedirs(dirinstall_path) else: args += ["--image", disk_img] # Create the sparse image mksparse(disk_img, disk_size * 1024**2) log_monitor = LogMonitor(timeout=opts.timeout) args += ["--remotelog", "%s:%s" % (log_monitor.host, log_monitor.port)] cancel_funcs = [log_monitor.server.log_check] if cancel_func is not None: cancel_funcs.append(cancel_func) # Make sure anaconda has the right product and release log.info("Running anaconda.") try: unshare_args = [ "--pid", "--kill-child", "--mount", "--propagation", "unchanged", "anaconda" ] + args for line in execReadlines( "unshare", unshare_args, reset_lang=False, env_add={ "ANACONDA_PRODUCTNAME": opts.project, "ANACONDA_PRODUCTVERSION": opts.releasever }, callback=lambda p: not novirt_cancel_check(cancel_funcs, p)): log.info(line) # Make sure the new filesystem is correctly labeled setfiles_args = [ "-e", "/proc", "-e", "/sys", "/etc/selinux/targeted/contexts/files/file_contexts", "/" ] if "--dirinstall" in args: # setfiles may not be available, warn instead of fail try: execWithRedirect("setfiles", setfiles_args, root=dirinstall_path) except (subprocess.CalledProcessError, OSError) as e: log.warning("Running setfiles on install tree failed: %s", str(e)) else: with PartitionMount(disk_img) as img_mount: if img_mount and img_mount.mount_dir: try: execWithRedirect("setfiles", setfiles_args, root=img_mount.mount_dir) except (subprocess.CalledProcessError, OSError) as e: log.warning( "Running setfiles on install tree failed: %s", str(e)) # For image installs, run fstrim to discard unused blocks. This way # unused blocks do not need to be allocated for sparse image types execWithRedirect("fstrim", [img_mount.mount_dir]) except (subprocess.CalledProcessError, OSError) as e: log.error("Running anaconda failed: %s", e) raise InstallError("novirt_install failed") finally: log_monitor.shutdown() # Move the anaconda logs over to a log directory log_dir = os.path.abspath(os.path.dirname(opts.logfile)) log_anaconda = joinpaths(log_dir, "anaconda") if not os.path.isdir(log_anaconda): os.mkdir(log_anaconda) for l in glob.glob("/tmp/*log") + glob.glob("/tmp/anaconda-tb-*"): shutil.copy2(l, log_anaconda) os.unlink(l) # Make sure any leftover anaconda mounts have been cleaned up if not anaconda_cleanup(dirinstall_path): raise InstallError( "novirt_install cleanup of anaconda mounts failed.") if not opts.make_iso and not opts.make_fsimage and not opts.make_pxe_live: dm_name = os.path.splitext(os.path.basename(disk_img))[0] # Remove device-mapper for partitions and disk log.debug("Removing device-mapper setup on %s", dm_name) for d in sorted(glob.glob("/dev/mapper/" + dm_name + "*"), reverse=True): dm_detach(d) log.debug("Removing loop device for %s", disk_img) loop_detach("/dev/" + get_loop_name(disk_img)) # qemu disk image is used by bare qcow2 images and by Vagrant if opts.image_type: log.info("Converting %s to %s", disk_img, opts.image_type) qemu_args = [] for arg in opts.qemu_args: qemu_args += arg.split(" ", 1) # convert the image to the selected format if "-O" not in qemu_args: qemu_args.extend(["-O", opts.image_type]) qemu_img = tempfile.mktemp(prefix="lmc-disk-", suffix=".img") execWithRedirect("qemu-img", ["convert"] + qemu_args + [disk_img, qemu_img], raise_err=True) if not opts.make_vagrant: execWithRedirect("mv", ["-f", qemu_img, disk_img], raise_err=True) else: # Take the new qcow2 image and package it up for Vagrant compress_args = [] for arg in opts.compress_args: compress_args += arg.split(" ", 1) vagrant_dir = tempfile.mkdtemp(prefix="lmc-tmpdir-") metadata_path = joinpaths(vagrant_dir, "metadata.json") execWithRedirect( "mv", ["-f", qemu_img, joinpaths(vagrant_dir, "box.img")], raise_err=True) if opts.vagrant_metadata: shutil.copy2(opts.vagrant_metadata, metadata_path) else: create_vagrant_metadata(metadata_path) update_vagrant_metadata(metadata_path, disk_size) if opts.vagrantfile: shutil.copy2(opts.vagrantfile, joinpaths(vagrant_dir, "vagrantfile")) log.info("Creating Vagrant image") rc = mktar(vagrant_dir, disk_img, opts.compression, compress_args, selinux=False) if rc: raise InstallError("novirt_install mktar failed: rc=%s" % rc) shutil.rmtree(vagrant_dir) elif opts.make_tar: compress_args = [] for arg in opts.compress_args: compress_args += arg.split(" ", 1) rc = mktar(dirinstall_path, disk_img, opts.compression, compress_args) shutil.rmtree(dirinstall_path) if rc: raise InstallError("novirt_install mktar failed: rc=%s" % rc) elif opts.make_oci: # An OCI image places the filesystem under /rootfs/ and adds the json files at the top # And then creates a tar of the whole thing. compress_args = [] for arg in opts.compress_args: compress_args += arg.split(" ", 1) shutil.copy2(opts.oci_config, ROOT_PATH) shutil.copy2(opts.oci_runtime, ROOT_PATH) rc = mktar(ROOT_PATH, disk_img, opts.compression, compress_args) if rc: raise InstallError("novirt_install mktar failed: rc=%s" % rc) else: # For raw disk images, use fallocate to deallocate unused space execWithRedirect("fallocate", ["--dig-holes", disk_img], raise_err=True)
def test_execReadlines_error(self): with self.assertRaises(OSError): execReadlines("foo-prog", [])