def make_runtime(opts, mount_dir, work_dir, size=None): """ Make the squashfs image from a directory :param opts: options passed to livemedia-creator :type opts: argparse options :param str mount_dir: Directory tree to compress :param str work_dir: Output compressed image to work_dir+images/install.img :param int size: Size of disk image, in GiB """ kernel_arch = get_arch(mount_dir) # Fake dnf object fake_dbo = FakeDNF(conf=DataHolder(installroot=mount_dir)) # Fake arch with only basearch set arch = ArchData(kernel_arch) # TODO: Need to get release info from someplace... product = DataHolder(name=opts.project, version=opts.releasever, release="", variant="", bugurl="", isfinal=False) rb = RuntimeBuilder(product, arch, fake_dbo) compression, compressargs = squashfs_args(opts) if opts.squashfs_only: log.info("Creating a squashfs only runtime") rb.create_squashfs_runtime(joinpaths(work_dir, RUNTIME), size=size, compression=compression, compressargs=compressargs) else: log.info("Creating a squashfs+ext4 runtime") rb.create_ext4_runtime(joinpaths(work_dir, RUNTIME), size=size, compression=compression, compressargs=compressargs)
def run(self, dbo, product, version, release, variant="", bugurl="", isfinal=False, workdir=None, outputdir=None, buildarch=None, volid=None, domacboot=True, doupgrade=True, remove_temp=False, installpkgs=None, excludepkgs=None, size=2, add_templates=None, add_template_vars=None, add_arch_templates=None, add_arch_template_vars=None, verify=True, user_dracut_args=None, squashfs_only=False): assert self._configured installpkgs = installpkgs or [] excludepkgs = excludepkgs or [] if domacboot: try: runcmd(["rpm", "-q", "hfsplus-tools"]) except CalledProcessError: logger.critical( "you need to install hfsplus-tools to create mac images") sys.exit(1) # set up work directory self.workdir = workdir or tempfile.mkdtemp(prefix="pylorax.work.") if not os.path.isdir(self.workdir): os.makedirs(self.workdir) # set up log directory logdir = self.conf.get("lorax", "logdir") if not os.path.isdir(logdir): os.makedirs(logdir) self.init_stream_logging() self.init_file_logging(logdir) logger.debug("version is %s", vernum) log_selinux_state() logger.debug("using work directory %s", self.workdir) logger.debug("using log directory %s", logdir) # set up output directory self.outputdir = outputdir or tempfile.mkdtemp(prefix="pylorax.out.") if not os.path.isdir(self.outputdir): os.makedirs(self.outputdir) logger.debug("using output directory %s", self.outputdir) # do we have root privileges? logger.info("checking for root privileges") if not os.geteuid() == 0: logger.critical("no root privileges") sys.exit(1) # do we have a proper dnf base object? logger.info("checking dnf base object") if not isinstance(dbo, dnf.Base): logger.critical("no dnf base object") sys.exit(1) self.inroot = dbo.conf.installroot logger.debug("using install root: %s", self.inroot) if not buildarch: buildarch = get_buildarch(dbo) logger.info("setting up build architecture") self.arch = ArchData(buildarch) for attr in ('buildarch', 'basearch', 'libdir'): logger.debug("self.arch.%s = %s", attr, getattr(self.arch, attr)) logger.info("setting up build parameters") self.product = DataHolder(name=product, version=version, release=release, variant=variant, bugurl=bugurl, isfinal=isfinal) logger.debug("product data: %s", self.product) # NOTE: if you change isolabel, you need to change pungi to match, or # the pungi images won't boot. isolabel = volid or "%s-%s-%s" % ( self.product.name, self.product.version, self.arch.basearch) if len(isolabel) > 32: logger.fatal("the volume id cannot be longer than 32 characters") sys.exit(1) # NOTE: rb.root = dbo.conf.installroot (== self.inroot) rb = RuntimeBuilder(product=self.product, arch=self.arch, dbo=dbo, templatedir=self.templatedir, installpkgs=installpkgs, excludepkgs=excludepkgs, add_templates=add_templates, add_template_vars=add_template_vars) logger.info("installing runtime packages") rb.install() # write .buildstamp buildstamp = BuildStamp(self.product.name, self.product.version, self.product.bugurl, self.product.isfinal, self.arch.buildarch, self.product.variant) buildstamp.write(joinpaths(self.inroot, ".buildstamp")) if self.debug: rb.writepkglists(joinpaths(logdir, "pkglists")) rb.writepkgsizes(joinpaths(logdir, "original-pkgsizes.txt")) logger.info("doing post-install configuration") rb.postinstall() # write .discinfo discinfo = DiscInfo(self.product.release, self.arch.basearch) discinfo.write(joinpaths(self.outputdir, ".discinfo")) logger.info("backing up installroot") installroot = joinpaths(self.workdir, "installroot") linktree(self.inroot, installroot) logger.info("generating kernel module metadata") rb.generate_module_data() logger.info("cleaning unneeded files") rb.cleanup() if verify: logger.info("verifying the installroot") if not rb.verify(): sys.exit(1) else: logger.info("Skipping verify") if self.debug: rb.writepkgsizes(joinpaths(logdir, "final-pkgsizes.txt")) logger.info("creating the runtime image") runtime = "images/install.img" compression = self.conf.get("compression", "type") compressargs = self.conf.get("compression", "args").split() # pylint: disable=no-member if self.conf.getboolean("compression", "bcj"): if self.arch.bcj: compressargs += ["-Xbcj", self.arch.bcj] else: logger.info("no BCJ filter for arch %s", self.arch.basearch) if squashfs_only: # Create an ext4 rootfs.img and compress it with squashfs rb.create_squashfs_runtime(joinpaths(installroot, runtime), compression=compression, compressargs=compressargs, size=size) else: # Create an ext4 rootfs.img and compress it with squashfs rb.create_ext4_runtime(joinpaths(installroot, runtime), compression=compression, compressargs=compressargs, size=size) rb.finished() logger.info("preparing to build output tree and boot images") treebuilder = TreeBuilder(product=self.product, arch=self.arch, inroot=installroot, outroot=self.outputdir, runtime=runtime, isolabel=isolabel, domacboot=domacboot, doupgrade=doupgrade, templatedir=self.templatedir, add_templates=add_arch_templates, add_template_vars=add_arch_template_vars, workdir=self.workdir) logger.info("rebuilding initramfs images") if not user_dracut_args: dracut_args = DRACUT_DEFAULT else: dracut_args = [] for arg in user_dracut_args: dracut_args += arg.split(" ", 1) anaconda_args = dracut_args + [ "--add", "anaconda pollcdrom qemu qemu-net" ] # ppc64 cannot boot an initrd > 32MiB so remove some drivers if self.arch.basearch in ("ppc64", "ppc64le"): dracut_args.extend(["--omit-drivers", REMOVE_PPC64_DRIVERS]) # Only omit dracut modules from the initrd so that they're kept for # upgrade.img anaconda_args.extend(["--omit", REMOVE_PPC64_MODULES]) logger.info("dracut args = %s", dracut_args) logger.info("anaconda args = %s", anaconda_args) treebuilder.rebuild_initrds(add_args=anaconda_args) logger.info("populating output tree and building boot images") treebuilder.build() # write .treeinfo file and we're done treeinfo = TreeInfo(self.product.name, self.product.version, self.product.variant, self.arch.basearch) for section, data in treebuilder.treeinfo_data.items(): treeinfo.add_section(section, data) treeinfo.write(joinpaths(self.outputdir, ".treeinfo")) # cleanup if remove_temp: remove(self.workdir)