def __create_iso(self, isodir): iso = self._outdir + "/" + self.name + ".iso" genisoimage = fs_related.find_binary_path("genisoimage") args = [ genisoimage, "-J", "-r", "-hide-rr-moved", "-hide-joliet-trans-tbl", "-V", self.fslabel, "-o", iso ] args.extend(self._get_mkisofs_options(isodir)) args.append(isodir) if runner.show(args) != 0: raise CreatorError("ISO creation failed!") """ It should be ok still even if you haven't isohybrid """ isohybrid = None try: isohybrid = fs_related.find_binary_path("isohybrid") except: pass if isohybrid: args = [isohybrid, "-partok", iso] if runner.show(args) != 0: raise CreatorError("Hybrid ISO creation failed!") self.__implant_md5sum(iso)
def __create_iso(self, isodir): iso = self._outdir + "/" + self.name + ".iso" genisoimage = fs_related.find_binary_path("genisoimage") args = [genisoimage, "-J", "-r", "-hide-rr-moved", "-hide-joliet-trans-tbl", "-V", self.fslabel, "-o", iso] args.extend(self._get_mkisofs_options(isodir)) args.append(isodir) if runner.show(args) != 0: raise CreatorError("ISO creation failed!") """ It should be ok still even if you haven't isohybrid """ isohybrid = None try: isohybrid = fs_related.find_binary_path("isohybrid") except: pass if isohybrid: args = [isohybrid, "-partok", iso ] if runner.show(args) != 0: raise CreatorError("Hybrid ISO creation failed!") self.__implant_md5sum(iso)
def _install_syslinux(self): i = 0 for name in self.__disks.keys(): loopdev = self.__disks[name].device i =i+1 msger.debug("Installing syslinux bootloader to %s" % loopdev) (bootdevnum, rootdevnum, rootdev, prefix) = self._get_syslinux_boot_config() #Set MBR mbrsize = os.stat("%s/usr/share/syslinux/mbr.bin" % self._instroot)[stat.ST_SIZE] rc = runner.show(['dd', "if=%s/usr/share/syslinux/mbr.bin" % self._instroot, "of=" + loopdev]) if rc != 0: raise MountError("Unable to set MBR to %s" % loopdev) #Set Bootable flag parted = fs_related.find_binary_path("parted") rc = runner.quiet([parted, "-s", loopdev, "set", "%d" % (bootdevnum + 1), "boot", "on"]) #XXX disabled return code check because parted always fails to #reload part table with loop devices. Annoying because we can't #distinguish this failure from real partition failures :-( if rc != 0 and 1 == 0: raise MountError("Unable to set bootable flag to %sp%d" % (loopdev, (bootdevnum + 1))) #Ensure all data is flushed to disk before doing syslinux install runner.quiet('sync') fullpathsyslinux = fs_related.find_binary_path("extlinux") rc = runner.show([fullpathsyslinux, "-i", "%s/boot/extlinux" % self._instroot]) if rc != 0: raise MountError("Unable to install syslinux bootloader to %sp%d" % (loopdev, (bootdevnum + 1)))
def setup_qemu_emulator(rootdir, arch): # mount binfmt_misc if it doesn't exist if not os.path.exists("/proc/sys/fs/binfmt_misc"): modprobecmd = find_binary_path("modprobe") runner.show([modprobecmd, "binfmt_misc"]) if not os.path.exists("/proc/sys/fs/binfmt_misc/register"): mountcmd = find_binary_path("mount") runner.show([mountcmd, "-t", "binfmt_misc", "none", "/proc/sys/fs/binfmt_misc"]) # qemu_emulator is a special case, we can't use find_binary_path # qemu emulator should be a statically-linked executable file if arch == "aarch64": node = "/proc/sys/fs/binfmt_misc/aarch64" if os.path.exists("/usr/bin/qemu-arm64") and is_statically_linked("/usr/bin/qemu-arm64"): arm_binary = "qemu-arm64" elif os.path.exists("/usr/bin/qemu-aarch64") and is_statically_linked("/usr/bin/qemu-aarch64"): arm_binary = "qemu-aarch64" elif os.path.exists("/usr/bin/qemu-arm64-static"): arm_binary = "qemu-arm64-static" elif os.path.exists("/usr/bin/qemu-aarch64-static"): arm_binary = "qemu-aarch64-static" else: raise CreatorError("Please install a statically-linked %s" % arm_binary) else: node = "/proc/sys/fs/binfmt_misc/arm" arm_binary = "qemu-arm" if not os.path.exists("/usr/bin/qemu-arm") or not is_statically_linked("/usr/bin/qemu-arm"): arm_binary = "qemu-arm-static" if not os.path.exists("/usr/bin/%s" % arm_binary): raise CreatorError("Please install a statically-linked %s" % arm_binary) qemu_emulator = "/usr/bin/%s" % arm_binary if not os.path.exists(rootdir + "/usr/bin"): makedirs(rootdir + "/usr/bin") shutil.copy(qemu_emulator, rootdir + qemu_emulator) # disable selinux, selinux will block qemu emulator to run if os.path.exists("/usr/sbin/setenforce"): msger.info('Try to disable selinux') runner.show(["/usr/sbin/setenforce", "0"]) # unregister it if it has been registered and is a dynamically-linked executable if os.path.exists(node): qemu_unregister_string = "-1\n" with open(node, "w") as fd: fd.write(qemu_unregister_string) # register qemu emulator for interpreting other arch executable file if not os.path.exists(node): if arch == "aarch64": qemu_arm_string = ":aarch64:M::\\x7fELF\\x02\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\xb7:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff:%s:\n" % qemu_emulator else: qemu_arm_string = ":arm:M::\\x7fELF\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x28\\x00:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfa\\xff\\xff\\xff:%s:\n" % qemu_emulator with open("/proc/sys/fs/binfmt_misc/register", "w") as fd: fd.write(qemu_arm_string) return qemu_emulator
def setup_qemu_emulator(rootdir, arch): # mount binfmt_misc if it doesn't exist if not os.path.exists("/proc/sys/fs/binfmt_misc"): modprobecmd = find_binary_path("modprobe") runner.show([modprobecmd, "binfmt_misc"]) if not os.path.exists("/proc/sys/fs/binfmt_misc/register"): mountcmd = find_binary_path("mount") runner.show([mountcmd, "-t", "binfmt_misc", "none", "/proc/sys/fs/binfmt_misc"]) # qemu_emulator is a special case, we can't use find_binary_path # qemu emulator should be a statically-linked executable file qemu_emulator = "/usr/bin/qemu-arm" if not os.path.exists(qemu_emulator) or not is_statically_linked(qemu_emulator): qemu_emulator = "/usr/bin/qemu-arm-static" if not os.path.exists(qemu_emulator): raise CreatorError("Please install a statically-linked qemu-arm") # qemu emulator version check armv7_list = [arch for arch in rpmmisc.archPolicies.keys() if arch.startswith('armv7')] if arch in armv7_list: # need qemu (>=0.13.0) qemuout = runner.outs([qemu_emulator, "-h"]) m = re.search("version\s*([.\d]+)", qemuout) if m: qemu_version = m.group(1) if qemu_version < "0.13": raise CreatorError("Requires %s version >=0.13 for %s" % (qemu_emulator, arch)) else: msger.warning("Can't get version info of %s, please make sure it's higher than 0.13.0" % qemu_emulator) if not os.path.exists(rootdir + "/usr/bin"): makedirs(rootdir + "/usr/bin") shutil.copy(qemu_emulator, rootdir + "/usr/bin/qemu-arm-static") qemu_emulator = "/usr/bin/qemu-arm-static" # disable selinux, selinux will block qemu emulator to run if os.path.exists("/usr/sbin/setenforce"): msger.info('Try to disable selinux') runner.show(["/usr/sbin/setenforce", "0"]) # unregister it if it has been registered and is a dynamically-linked executable node = "/proc/sys/fs/binfmt_misc/arm" if os.path.exists(node): qemu_unregister_string = "-1\n" fd = open("/proc/sys/fs/binfmt_misc/arm", "w") fd.write(qemu_unregister_string) fd.close() # register qemu emulator for interpreting other arch executable file if not os.path.exists(node): qemu_arm_string = ":arm:M::\\x7fELF\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x28\\x00:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfa\\xff\\xff\\xff:%s:\n" % qemu_emulator fd = open("/proc/sys/fs/binfmt_misc/register", "w") fd.write(qemu_arm_string) fd.close() return qemu_emulator
def extract_rpm(rpmfile, targetdir): rpm2cpio = find_binary_path("rpm2cpio") cpio = find_binary_path("cpio") olddir = os.getcwd() os.chdir(targetdir) msger.verbose("Extract rpm file with cpio: %s" % rpmfile) p1 = subprocess.Popen([rpm2cpio, rpmfile], stdout=subprocess.PIPE) p2 = subprocess.Popen([cpio, "-idv"], stdin=p1.stdout, stdout=subprocess.PIPE, stderr=subprocess.PIPE) (sout, serr) = p2.communicate() msger.verbose(sout or serr) os.chdir(olddir)
def _get_metadata_from_repo(baseurl, proxies, cachedir, reponame, filename, sumtype=None, checksum=None): url = baseurl.join(filename) filename_tmp = str("%s/%s/%s" % (cachedir, reponame, os.path.basename(filename))) if os.path.splitext(filename_tmp)[1] in (".gz", ".bz2"): filename = os.path.splitext(filename_tmp)[0] else: filename = filename_tmp if sumtype and checksum and os.path.exists(filename): try: sumcmd = find_binary_path("%ssum" % sumtype) except: file_checksum = None else: file_checksum = runner.outs([sumcmd, filename]).split()[0] if file_checksum and file_checksum == checksum: return filename return _get_uncompressed_data_from_url(url, filename_tmp, proxies)
def apply(self, kstimezone): self._check_sysconfig() tz = kstimezone.timezone or "America/New_York" utc = str(kstimezone.isUtc) f = open(self.path("/etc/sysconfig/clock"), "w+") f.write("ZONE=\"" + tz + "\"\n") f.write("UTC=" + utc + "\n") f.close() if not os.path.exists("/opt/etc"): fs.makedirs("/opt/etc") tz_source = "/usr/share/zoneinfo/%s" % (tz) tz_midst = "/opt/etc/localtime" tz_dest = "/etc/localtime" try: lncmd = fs.find_binary_inchroot('ln', self.instroot) if lncmd: self.call([lncmd, "-s", tz_source, tz_midst]) self.call([lncmd, "-s", tz_midst, tz_dest]) else: lncmd = fs.find_binary_path('ln') subprocess.call( [lncmd, "-s", self.path(tz_source), self.path(tz_midst)]) subprocess.call( [lncmd, "-s", self.path(tz_midst), self.path(tz_dest)]) except (IOError, OSError), (errno, msg): raise errors.KsError("Timezone setting error: %s" % msg)
def _install_syslinux(self): for name in self.__disks.keys(): loopdev = self.__disks[name].device # Set MBR mbrfile = "%s/usr/share/syslinux/" % self._instroot if self._ptable_format == 'gpt': mbrfile += "gptmbr.bin" else: mbrfile += "mbr.bin" msger.debug("Installing syslinux bootloader '%s' to %s" % \ (mbrfile, loopdev)) mbrsize = os.stat(mbrfile)[stat.ST_SIZE] rc = runner.show(['dd', 'if=%s' % mbrfile, 'of=' + loopdev]) if rc != 0: raise MountError("Unable to set MBR to %s" % loopdev) # Ensure all data is flushed to disk before doing syslinux install runner.quiet('sync') fullpathsyslinux = fs_related.find_binary_path("extlinux") rc = runner.show([fullpathsyslinux, "-i", "%s/boot/extlinux" % self._instroot]) if rc != 0: raise MountError("Unable to install syslinux bootloader to %s" \ % loopdev)
def uncompress_squashfs(squashfsimg, outdir): """Uncompress file system from squshfs image""" unsquashfs = find_binary_path("unsquashfs") args = [ unsquashfs, "-d", outdir, squashfsimg ] rc = runner.show(args) if (rc != 0): raise SquashfsError("Failed to uncompress %s." % squashfsimg)
def _install_syslinux(self): for name in self.__disks.keys(): loopdev = self.__disks[name].device # Set MBR mbrfile = "%s/usr/share/syslinux/" % self._instroot if self._ptable_format == 'gpt': mbrfile += "gptmbr.bin" else: mbrfile += "mbr.bin" msger.debug("Installing syslinux bootloader '%s' to %s" % \ (mbrfile, loopdev)) rc = runner.show(['dd', 'if=%s' % mbrfile, 'of=' + loopdev]) if rc != 0: raise MountError("Unable to set MBR to %s" % loopdev) # Ensure all data is flushed to disk before doing syslinux install runner.quiet('sync') fullpathsyslinux = fs_related.find_binary_path("extlinux") rc = runner.show([fullpathsyslinux, "-i", "%s/boot/extlinux" % self._instroot]) if rc != 0: raise MountError("Unable to install syslinux bootloader to %s" \ % loopdev)
def _stage_final_image(self): try: self.cmd_qemuimg = fs_related.find_binary_path('qemu-img') except errors.CreatorError: return LoopImageCreator._stage_final_image(self) self._resparse() imgfile = None for item in self._instloops: if item['mountpoint'] == '/': if item['fstype'] == "ext4": runner.show('/sbin/tune2fs -O ^huge_file,extents,uninit_bg %s' % imgfile) self.image_files.setdefault('partitions', {}).update( {item['mountpoint']: item['label']}) imgfile = os.path.join(self._imgdir, item['name']) if imgfile: qemuimage = imgfile + ".x86" runner.show("%s convert -O qcow2 %s %s" % (self.cmd_qemuimg, imgfile, qemuimage)) os.unlink(imgfile) os.rename(qemuimage, imgfile) for item in os.listdir(self._imgdir): shutil.move(os.path.join(self._imgdir, item), os.path.join(self._outdir, item))
def installLocal(self, pkg, po=None, updateonly=False): if not self.ts: self.__initialize_transaction() solvfile = "%s/.solv" % (self.creator.cachedir) rc, out = runner.runtool([fs_related.find_binary_path("rpms2solv"), pkg]) if rc == 0: f = open(solvfile, "w+") f.write(out) f.close() warnmsg = self.repo_manager.loadSolvFile(solvfile , os.path.basename(pkg)) if warnmsg: msger.warning(warnmsg) os.unlink(solvfile) else: msger.warning('Can not get %s solv data.' % pkg) hdr = rpmmisc.readRpmHeader(self.ts, pkg) arch = zypp.Arch(hdr['arch']) if self.creator.target_arch == None: # TODO, get the default_arch from conf or detected from global settings sysarch = zypp.Arch('i686') else: sysarch = zypp.Arch(self.creator.target_arch) if arch.compatible_with (sysarch): pkgname = hdr['name'] self.localpkgs[pkgname] = pkg self.selectPackage(pkgname) msger.info("Marking %s to be installed" % (pkg)) else: msger.warning ("Cannot add package %s to transaction. Not a compatible architecture: %s" % (pkg, hdr['arch']))
def installLocal(self, pkg, po=None, updateonly=False): if not self.ts: self.__initialize_transaction() solvfile = "%s/.solv" % (self.creator.cachedir) rc, out = runner.runtool( [fs_related.find_binary_path("rpms2solv"), pkg]) if rc == 0: f = open(solvfile, "w+") f.write(out) f.close() warnmsg = self.repo_manager.loadSolvFile(solvfile, os.path.basename(pkg)) if warnmsg: msger.warning(warnmsg) os.unlink(solvfile) else: msger.warning('Can not get %s solv data.' % pkg) hdr = rpmmisc.readRpmHeader(self.ts, pkg) arch = zypp.Arch(hdr['arch']) if self.creator.target_arch == None: # TODO, get the default_arch from conf or detected from global settings sysarch = zypp.Arch('i686') else: sysarch = zypp.Arch(self.creator.target_arch) if arch.compatible_with(sysarch): pkgname = hdr['name'] self.localpkgs[pkgname] = pkg self.selectPackage(pkgname) msger.info("Marking %s to be installed" % (pkg)) else: msger.warning( "Cannot add package %s to transaction. Not a compatible architecture: %s" % (pkg, hdr['arch']))
def package(self, destdir = "."): """Prepares the created image for final delivery. In its simplest form, this method merely copies the install root to the supplied destination directory; other subclasses may choose to package the image by e.g. creating a bootable ISO containing the image and bootloader configuration. destdir -- the directory into which the final image should be moved; this defaults to the current directory. """ self._stage_final_image() if not os.path.exists(destdir): fs.makedirs(destdir) if self._img_compression_method: if not self._img_name: raise CreatorError("Image name not set.") rc = None img_location = os.path.join(self._outdir,self._img_name) if self._img_compression_method == "bz2": bzip2 = fs.find_binary_path('bzip2') msger.info("Compressing %s with bzip2. Please wait..." \ % img_location) rc = runner.show([bzip2, "-f", img_location]) if rc: raise CreatorError("Failed to compress image %s with %s." \ % (img_location, self._img_compression_method)) for bootimg in glob.glob(os.path.dirname(img_location) + \ "/*-boot.bin"): msger.info("Compressing %s with bzip2. Please wait..." \ % bootimg) rc = runner.show([bzip2, "-f", bootimg]) if rc: raise CreatorError("Failed to compress image %s with " "%s." \ % (bootimg, self._img_compression_method)) if self._recording_pkgs: self._save_recording_pkgs(destdir) # For image formats with two or multiple image files, it will be # better to put them under a directory if self.image_format in ("raw", "vmdk", "vdi", "nand", "mrstnand"): destdir = os.path.join(destdir, "%s-%s" \ % (self.name, self.image_format)) msger.debug("creating destination dir: %s" % destdir) fs.makedirs(destdir) # Ensure all data is flushed to _outdir runner.quiet('sync') for f in os.listdir(self._outdir): shutil.move(os.path.join(self._outdir, f), os.path.join(destdir, f)) self.outimage.append(os.path.join(destdir, f)) self.do_genchecksum(os.path.join(destdir, f))
def _stage_final_image(self): try: self.cmd_qemuimg = fs_related.find_binary_path('qemu-img') except errors.CreatorError: return LoopImageCreator._stage_final_image(self) self._resparse() imgfile = None for item in self._instloops: if item['mountpoint'] == '/': if item['fstype'] == "ext4": runner.show( '/sbin/tune2fs -O ^huge_file,extents,uninit_bg %s' % imgfile) self.image_files.setdefault('partitions', {}).update( {item['mountpoint']: item['label']}) imgfile = os.path.join(self._imgdir, item['name']) if imgfile: qemuimage = imgfile + ".x86" runner.show("%s convert -O qcow2 %s %s" % (self.cmd_qemuimg, imgfile, qemuimage)) os.unlink(imgfile) os.rename(qemuimage, imgfile) for item in os.listdir(self._imgdir): shutil.move(os.path.join(self._imgdir, item), os.path.join(self._outdir, item))
def _install_syslinux(self): i = 0 for name in self.__disks.keys(): loopdev = self.__disks[name].device i =i+1 msger.debug("Installing syslinux bootloader to %s" % loopdev) (bootdevnum, rootdevnum, rootdev, prefix) = \ self._get_syslinux_boot_config() #Set MBR mbrsize = os.stat("%s/usr/share/syslinux/mbr.bin" \ % self._instroot)[stat.ST_SIZE] rc = runner.show(['dd', 'if=%s/usr/share/syslinux/mbr.bin' % self._instroot, 'of=' + loopdev]) if rc != 0: raise MountError("Unable to set MBR to %s" % loopdev) #Set Bootable flag parted = fs_related.find_binary_path("parted") rc = runner.quiet([parted, "-s", loopdev, "set", "%d" % (bootdevnum + 1), "boot", "on"]) #XXX disabled return code check because parted always fails to #reload part table with loop devices. Annoying because we can't #distinguish this failure from real partition failures :-( if rc != 0 and 1 == 0: raise MountError("Unable to set bootable flag to %sp%d" \ % (loopdev, (bootdevnum + 1))) #Ensure all data is flushed to disk before doing syslinux install runner.quiet('sync') fullpathsyslinux = fs_related.find_binary_path("extlinux") rc = runner.show([fullpathsyslinux, "-i", "%s/boot/extlinux" % self._instroot]) if rc != 0: raise MountError("Unable to install syslinux bootloader to %sp%d" \ % (loopdev, (bootdevnum + 1)))
def compressing(fpath, method): comp_map = {"gz": "gzip", "bz2": "bzip2"} if method not in comp_map: raise CreatorError("Unsupport compress format: %s, valid values: %s" % (method, ','.join(comp_map.keys()))) cmd = find_binary_path(comp_map[method]) rc = runner.show([cmd, "-f", fpath]) if rc: raise CreatorError("Failed to %s file: %s" % (comp_map[method], fpath))
def convert_image(srcimg, srcfmt, dstimg, dstfmt): #convert disk format if dstfmt != "raw": raise CreatorError("Invalid destination image format: %s" % dstfmt) msger.debug("converting %s image to %s" % (srcimg, dstimg)) if srcfmt == "vmdk": path = find_binary_path("qemu-img") argv = [path, "convert", "-f", "vmdk", srcimg, "-O", dstfmt, dstimg] elif srcfmt == "vdi": path = find_binary_path("VBoxManage") argv = [path, "internalcommands", "converttoraw", srcimg, dstimg] else: raise CreatorError("Invalid soure image format: %s" % srcfmt) rc = runner.show(argv) if rc == 0: msger.debug("convert successful") if rc != 0: raise CreatorError("Unable to convert disk to %s" % dstfmt)
def compressing(fpath, method): comp_map = { "gz": "gzip", "bz2": "bzip2" } if method not in comp_map: raise CreatorError("Unsupport compress format: %s, valid values: %s" % (method, ','.join(comp_map.keys()))) cmd = find_binary_path(comp_map[method]) rc = runner.show([cmd, "-f", fpath]) if rc: raise CreatorError("Failed to %s file: %s" % (comp_map[method], fpath))
def package(self, destdir = "."): """Prepares the created image for final delivery. In its simplest form, this method merely copies the install root to the supplied destination directory; other subclasses may choose to package the image by e.g. creating a bootable ISO containing the image and bootloader configuration. destdir -- the directory into which the final image should be moved; this defaults to the current directory. """ self._stage_final_image() if not os.path.exists(destdir): fs.makedirs(destdir) if self._img_compression_method: if not self._img_name: raise CreatorError("Image name not set.") rc = None img_location = os.path.join(self._outdir,self._img_name) if self._img_compression_method == "bz2": bzip2 = fs.find_binary_path('bzip2') msger.info("Compressing %s with bzip2. Please wait..." % img_location) rc = runner.show([bzip2, "-f", img_location]) if rc: raise CreatorError("Failed to compress image %s with %s." % (img_location, self._img_compression_method)) for bootimg in glob.glob(os.path.dirname(img_location) + "/*-boot.bin"): msger.info("Compressing %s with bzip2. Please wait..." % bootimg) rc = runner.show([bzip2, "-f", bootimg]) if rc: raise CreatorError("Failed to compress image %s with %s." % (bootimg, self._img_compression_method)) if self._recording_pkgs: self._save_recording_pkgs(destdir) """ For image formats with two or multiple image files, it will be better to put them under a directory """ if self.image_format in ("raw", "vmdk", "vdi", "nand", "mrstnand"): destdir = os.path.join(destdir, "%s-%s" % (self.name, self.image_format)) msger.debug("creating destination dir: %s" % destdir) fs.makedirs(destdir) # Ensure all data is flushed to _outdir runner.quiet('sync') for f in os.listdir(self._outdir): shutil.move(os.path.join(self._outdir, f), os.path.join(destdir, f)) self.outimage.append(os.path.join(destdir, f)) self.do_genchecksum(os.path.join(destdir, f))
def selinux_check(arch, fstypes): try: getenforce = find_binary_path('getenforce') except CreatorError: return selinux_status = runner.outs([getenforce]) if arch and arch.startswith("arm") and selinux_status == "Enforcing": raise CreatorError("Can't create arm image if selinux is enabled, " "please run 'setenforce 0' to disable selinux") use_btrfs = filter(lambda typ: typ == 'btrfs', fstypes) if use_btrfs and selinux_status == "Enforcing": raise CreatorError("Can't create btrfs image if selinux is enabled," " please run 'setenforce 0' to disable selinux")
def get_mic_binpath(): fp = None try: import pkg_resources # depends on 'setuptools' except ImportError: pass else: dist = pkg_resources.get_distribution('mic') # the real script is under EGG_INFO/scripts if dist.has_metadata('scripts/mic'): fp = os.path.join(dist.egg_info, "scripts/mic") if fp: return fp # not found script if 'flat' egg installed try: return find_binary_path('mic') except errors.CreatorError: raise errors.BootstrapError("Can't find mic binary in host OS")
def _get_metadata_from_repo(baseurl, proxies, cachedir, reponame, filename, sumtype=None, checksum=None): url = os.path.join(baseurl, filename) filename_tmp = str("%s/%s/%s" % (cachedir, reponame, os.path.basename(filename))) if os.path.splitext(filename_tmp)[1] in (".gz", ".bz2"): filename = os.path.splitext(filename_tmp)[0] else: filename = filename_tmp if sumtype and checksum and os.path.exists(filename): try: sumcmd = find_binary_path("%ssum" % sumtype) except: file_checksum = None else: file_checksum = runner.outs([sumcmd, filename]).split()[0] if file_checksum and file_checksum == checksum: return filename return _get_uncompressed_data_from_url(url,filename_tmp,proxies)
def compressing(fpath, method): comp_map = { "gz": ["pgzip", "pigz", "gzip"], "bz2": ["pbzip2", "bzip2"], } if method not in comp_map: raise CreatorError("Unsupport compress format: %s, valid values: %s" % (method, ','.join(comp_map.keys()))) cmd = None for cmdname in comp_map[method]: try: cmd = find_binary_path(cmdname) break except CreatorError as err: pass if not cmd: raise CreatorError("Command %s not available" % cmdname) rc = runner.show([cmd, "-f", fpath]) if rc: raise CreatorError("Failed to %s file: %s" % (comp_map[method], fpath))
def apply(self, kstimezone): self._check_sysconfig() tz = kstimezone.timezone or "America/New_York" utc = str(kstimezone.isUtc) f = open(self.path("/etc/sysconfig/clock"), "w+") f.write("ZONE=\"" + tz + "\"\n") f.write("UTC=" + utc + "\n") f.close() tz_source = "/usr/share/zoneinfo/%s" % (tz) tz_dest = "/etc/localtime" try: cpcmd = fs.find_binary_inchroot('cp', self.instroot) if cpcmd: self.call([cpcmd, "-f", tz_source, tz_dest]) else: cpcmd = fs.find_binary_path('cp') subprocess.call([cpcmd, "-f", self.path(tz_source), self.path(tz_dest)]) except (IOError, OSError), (errno, msg): raise errors.KsError("Timezone setting error: %s" % msg)
def apply(self, kstimezone): self._check_sysconfig() tz = kstimezone.timezone or "America/New_York" utc = str(kstimezone.isUtc) f = open(self.path("/etc/sysconfig/clock"), "w+") f.write("ZONE=\"" + tz + "\"\n") f.write("UTC=" + utc + "\n") f.close() tz_source = "/usr/share/zoneinfo/%s" % (tz) tz_dest = "/etc/localtime" try: cpcmd = fs.find_binary_inchroot('cp', self.instroot) if cpcmd: self.call([cpcmd, "-f", tz_source, tz_dest]) else: cpcmd = fs.find_binary_path('cp') subprocess.call([cpcmd, "-f", self.path(tz_source), self.path(tz_dest)]) except (IOError, OSError) as xxx_todo_changeme: (errno, msg) = xxx_todo_changeme.args raise errors.KsError("Timezone setting error: %s" % msg)
def package(self, destdir="."): ignores = [ "/dev/fd", "/dev/stdin", "/dev/stdout", "/dev/stderr", "/etc/mtab" ] if not os.path.exists(destdir): os.makedirs(destdir) if self._recording_pkgs: self._save_recording_pkgs(destdir) if not self.pack_to: self.image_files = {'image_files': [self.name]} fsdir = os.path.join(destdir, self.name) misc.check_space_pre_cp(self._instroot, destdir) msger.info("Copying %s to %s ..." % (self._instroot, fsdir)) runner.show(['cp', "-af", self._instroot, fsdir]) for exclude in ignores: if os.path.exists(fsdir + exclude): os.unlink(fsdir + exclude) self.outimage.append(fsdir) else: self.image_files = {'image_files': [self.pack_to]} (tar, comp) = os.path.splitext(self.pack_to) try: tarcreat = { '.tar': '-cf', '.gz': '-czf', '.bz2': '-cjf', '.tgz': '-czf', '.tbz': '-cjf' }[comp] except KeyError: raise CreatorError( "Unsupported comression for this image type:" " '%s', try '.tar', '.tar.gz', etc" % comp) dst = os.path.join(destdir, self.pack_to) msger.info("Pack rootfs to %s. Please wait..." % dst) tar = find_binary_path('tar') tar_cmdline = [ tar, "--numeric-owner", "--preserve-permissions", "--one-file-system", "--directory", self._instroot ] for ignore_entry in ignores: if ignore_entry.startswith('/'): ignore_entry = ignore_entry[1:] tar_cmdline.append("--exclude=%s" % (ignore_entry)) tar_cmdline.extend([tarcreat, dst, "."]) rc = runner.show(tar_cmdline) if rc: raise CreatorError("Failed compress image with tar.bz2. " "Cmdline: %s" % (" ".join(tar_cmdline))) self.outimage.append(dst)
def do_create(self, subcmd, opts, *args): """${cmd_name}: create loop image Usage: ${name} ${cmd_name} <ksfile> [OPTS] ${cmd_option_list} """ if len(args) != 1: raise errors.Usage("Extra arguments given") creatoropts = configmgr.create ksconf = args[0] if creatoropts['runtime'] == "bootstrap": configmgr._ksconf = ksconf rt_util.bootstrap_mic() elif not rt_util.inbootstrap(): try: fs_related.find_binary_path('mic-native') except errors.CreatorError: if not msger.ask("Subpackage \"mic-native\" has not been " "installed in your host system, still " "continue with \"native\" running mode?", False): raise errors.Abort("Abort because subpackage 'mic-native' " "has not been installed") recording_pkgs = [] if len(creatoropts['record_pkgs']) > 0: recording_pkgs = creatoropts['record_pkgs'] if creatoropts['release'] is not None: if 'name' not in recording_pkgs: recording_pkgs.append('name') if 'vcs' not in recording_pkgs: recording_pkgs.append('vcs') configmgr._ksconf = ksconf # try to find the pkgmgr pkgmgr = None backends = pluginmgr.get_plugins('backend') if 'auto' == creatoropts['pkgmgr']: for key in configmgr.prefer_backends: if key in backends: pkgmgr = backends[key] break else: for key in backends.keys(): if key == creatoropts['pkgmgr']: pkgmgr = backends[key] break if not pkgmgr: raise errors.CreatorError("Can't find backend: %s, " "available choices: %s" % (creatoropts['pkgmgr'], ','.join(backends.keys()))) creator = LoopImageCreator(creatoropts, pkgmgr, opts.compress_image, opts.shrink) if len(recording_pkgs) > 0: creator._recording_pkgs = recording_pkgs image_names = [creator.name + ".img"] image_names.extend(creator.get_image_names()) self.check_image_exists(creator.destdir, creator.pack_to, image_names, creatoropts['release']) try: creator.check_depend_tools() creator.mount(None, creatoropts["cachedir"]) creator.install() creator.configure(creatoropts["repomd"]) creator.copy_kernel() creator.unmount() creator.package(creatoropts["destdir"]) if creatoropts['release'] is not None: creator.release_output(ksconf, creatoropts['destdir'], creatoropts['release']) creator.print_outimage_info() except errors.CreatorError: raise finally: creator.cleanup() msger.info("Finished.") return 0
def do_create(self, subcmd, opts, *args): """${cmd_name}: create liveusb image Usage: ${name} ${cmd_name} <ksfile> [OPTS] ${cmd_option_list} """ if len(args) != 1: raise errors.Usage("Extra arguments given") creatoropts = configmgr.create ksconf = args[0] if creatoropts['runtime'] == "bootstrap": configmgr._ksconf = ksconf rt_util.bootstrap_mic() elif not rt_util.inbootstrap(): try: fs_related.find_binary_path('mic-native') except errors.CreatorError: if not msger.ask( "Subpackage \"mic-native\" has not been " "installed in your host system, still " "continue with \"native\" running mode?", False): raise errors.Abort("Abort because subpackage 'mic-native' " "has not been installed") if creatoropts['arch'] and creatoropts['arch'].startswith('arm'): msger.warning('liveusb cannot support arm images, Quit') return recording_pkgs = [] if len(creatoropts['record_pkgs']) > 0: recording_pkgs = creatoropts['record_pkgs'] if creatoropts['release'] is not None: if 'name' not in recording_pkgs: recording_pkgs.append('name') if 'vcs' not in recording_pkgs: recording_pkgs.append('vcs') configmgr._ksconf = ksconf # try to find the pkgmgr pkgmgr = None backends = pluginmgr.get_plugins('backend') if 'auto' == creatoropts['pkgmgr']: for key in configmgr.prefer_backends: if key in backends: pkgmgr = backends[key] break else: for key in backends.keys(): if key == creatoropts['pkgmgr']: pkgmgr = backends[key] break if not pkgmgr: raise errors.CreatorError( "Can't find backend: %s, " "available choices: %s" % (creatoropts['pkgmgr'], ','.join(backends.keys()))) creator = liveusb.LiveUSBImageCreator(creatoropts, pkgmgr) if len(recording_pkgs) > 0: creator._recording_pkgs = recording_pkgs self.check_image_exists(creator.destdir, creator.pack_to, [creator.name + ".usbimg"], creatoropts['release']) try: creator.check_depend_tools() creator.mount(None, creatoropts["cachedir"]) creator.install() creator.configure(creatoropts["repomd"]) creator.copy_kernel() creator.unmount() creator.package(creatoropts["destdir"]) creator.create_manifest() if creatoropts['release'] is not None: creator.release_output(ksconf, creatoropts['destdir'], creatoropts['release']) creator.print_outimage_info() except errors.CreatorError: raise finally: creator.cleanup() msger.info("Finished.") return 0
def check_depend_tools(self): for tool in self._dep_checks: fs.find_binary_path(tool)
def do_create(self, subcmd, opts, *args): """${cmd_name}: create fs image Usage: ${name} ${cmd_name} <ksfile> [OPTS] ${cmd_option_list} """ if len(args) != 1: raise errors.Usage("Extra arguments given") creatoropts = configmgr.create ksconf = args[0] if creatoropts['runtime'] == 'bootstrap': configmgr._ksconf = ksconf rt_util.bootstrap_mic() elif not rt_util.inbootstrap(): try: fs_related.find_binary_path('mic-native') except errors.CreatorError: if not msger.ask("Subpackage \"mic-native\" has not been " "installed in your host system, still " "continue with \"native\" running mode?", False): raise errors.Abort("Abort because subpackage 'mic-native' " "has not been installed") recording_pkgs = [] if len(creatoropts['record_pkgs']) > 0: recording_pkgs = creatoropts['record_pkgs'] if creatoropts['release'] is not None: if 'name' not in recording_pkgs: recording_pkgs.append('name') if 'vcs' not in recording_pkgs: recording_pkgs.append('vcs') configmgr._ksconf = ksconf # try to find the pkgmgr pkgmgr = None backends = pluginmgr.get_plugins('backend') if 'auto' == creatoropts['pkgmgr']: for key in configmgr.prefer_backends: if key in backends: pkgmgr = backends[key] break else: for key in backends.keys(): if key == creatoropts['pkgmgr']: pkgmgr = backends[key] break if not pkgmgr: raise errors.CreatorError("Can't find backend: %s, " "available choices: %s" % (creatoropts['pkgmgr'], ','.join(backends.keys()))) creator = fs.FsImageCreator(creatoropts, pkgmgr) creator._include_src = opts.include_src if len(recording_pkgs) > 0: creator._recording_pkgs = recording_pkgs self.check_image_exists(creator.destdir, creator.pack_to, [creator.name], creatoropts['release']) try: creator.check_depend_tools() creator.mount(None, creatoropts["cachedir"]) creator.install() #Download the source packages ###private options if opts.include_src: installed_pkgs = creator.get_installed_packages() msger.info('--------------------------------------------------') msger.info('Generating the image with source rpms included ...') if not misc.SrcpkgsDownload(installed_pkgs, creatoropts["repomd"], creator._instroot, creatoropts["cachedir"]): msger.warning("Source packages can't be downloaded") creator.configure(creatoropts["repomd"]) creator.copy_kernel() creator.unmount() creator.package(creatoropts["destdir"]) if creatoropts['release'] is not None: creator.release_output(ksconf, creatoropts['destdir'], creatoropts['release']) creator.print_outimage_info() except errors.CreatorError: raise finally: creator.cleanup() msger.info("Finished.") return 0
def do_chroot(cls, target, cmd=[]): img = target imgsize = misc.get_file_size(img) * 1024L * 1024L partedcmd = fs_related.find_binary_path("parted") disk = fs_related.SparseLoopbackDisk(img, imgsize) imgmnt = misc.mkdtemp() imgloop = PartitionedMount(imgmnt, skipformat = True) imgloop.add_disk('/dev/sdb', disk) img_fstype = "ext3" msger.info("Partition Table:") partnum = [] for line in runner.outs([partedcmd, "-s", img, "print"]).splitlines(): # no use strip to keep line output here if "Number" in line: msger.raw(line) if line.strip() and line.strip()[0].isdigit(): partnum.append(line.strip()[0]) msger.raw(line) rootpart = None if len(partnum) > 1: rootpart = msger.choice("please choose root partition", partnum) # Check the partitions from raw disk. # if choose root part, the mark it as mounted if rootpart: root_mounted = True else: root_mounted = False partition_mounts = 0 for line in runner.outs([partedcmd,"-s",img,"unit","B","print"]).splitlines(): line = line.strip() # Lines that start with number are the partitions, # because parted can be translated we can't refer to any text lines. if not line or not line[0].isdigit(): continue # Some vars have extra , as list seperator. line = line.replace(",","") # Example of parted output lines that are handled: # Number Start End Size Type File system Flags # 1 512B 3400000511B 3400000000B primary # 2 3400531968B 3656384511B 255852544B primary linux-swap(v1) # 3 3656384512B 3720347647B 63963136B primary fat16 boot, lba partition_info = re.split("\s+",line) size = partition_info[3].split("B")[0] if len(partition_info) < 6 or partition_info[5] in ["boot"]: # No filesystem can be found from partition line. Assuming # btrfs, because that is the only MeeGo fs that parted does # not recognize properly. # TODO: Can we make better assumption? fstype = "btrfs" elif partition_info[5] in ["ext2","ext3","ext4","btrfs"]: fstype = partition_info[5] elif partition_info[5] in ["fat16","fat32"]: fstype = "vfat" elif "swap" in partition_info[5]: fstype = "swap" else: raise errors.CreatorError("Could not recognize partition fs type '%s'." % partition_info[5]) if rootpart and rootpart == line[0]: mountpoint = '/' elif not root_mounted and fstype in ["ext2","ext3","ext4","btrfs"]: # TODO: Check that this is actually the valid root partition from /etc/fstab mountpoint = "/" root_mounted = True elif fstype == "swap": mountpoint = "swap" else: # TODO: Assing better mount points for the rest of the partitions. partition_mounts += 1 mountpoint = "/media/partition_%d" % partition_mounts if "boot" in partition_info: boot = True else: boot = False msger.verbose("Size: %s Bytes, fstype: %s, mountpoint: %s, boot: %s" % (size, fstype, mountpoint, boot)) # TODO: add_partition should take bytes as size parameter. imgloop.add_partition((int)(size)/1024/1024, "/dev/sdb", mountpoint, fstype = fstype, boot = boot) try: imgloop.mount() except errors.MountError: imgloop.cleanup() raise try: if len(cmd) != 0: cmdline = ' '.join(cmd) else: cmdline = "/bin/bash" envcmd = fs_related.find_binary_inchroot("env", imgmnt) if envcmd: cmdline = "%s HOME=/root %s" % (envcmd, cmdline) chroot.chroot(imgmnt, None, cmdline) except: raise errors.CreatorError("Failed to chroot to %s." %img) finally: chroot.cleanup_after_chroot("img", imgloop, None, imgmnt)
def _create_usbimg(self, isodir): overlaysizemb = 64 #default #skipcompress = self.skip_compression? fstype = "vfat" homesizemb=0 swapsizemb=0 homefile="home.img" plussize=128 kernelargs=None if fstype == 'vfat': if overlaysizemb > 2047: raise CreatorError("Can't have an overlay of 2048MB or " "greater on VFAT") if homesizemb > 2047: raise CreatorError("Can't have an home overlay of 2048MB or " "greater on VFAT") if swapsizemb > 2047: raise CreatorError("Can't have an swap overlay of 2048MB or " "greater on VFAT") livesize = misc.get_file_size(isodir + "/LiveOS") usbimgsize = (overlaysizemb + \ homesizemb + \ swapsizemb + \ livesize + \ plussize) * 1024 * 1024 disk = fs_related.SparseLoopbackDisk("%s/%s.usbimg" \ % (self._outdir, self.name), usbimgsize) usbmnt = self._mkdtemp("usb-mnt") usbloop = PartitionedMount({'/dev/sdb':disk}, usbmnt) usbloop.add_partition(usbimgsize/1024/1024, "/dev/sdb", "/", fstype, boot=True) usbloop.mount() try: fs_related.makedirs(usbmnt + "/LiveOS") if os.path.exists(isodir + "/LiveOS/squashfs.img"): shutil.copyfile(isodir + "/LiveOS/squashfs.img", usbmnt + "/LiveOS/squashfs.img") else: fs_related.mksquashfs(os.path.dirname(self._image), usbmnt + "/LiveOS/squashfs.img") if os.path.exists(isodir + "/LiveOS/osmin.img"): shutil.copyfile(isodir + "/LiveOS/osmin.img", usbmnt + "/LiveOS/osmin.img") uuid = usbloop.partitions[0]['mount'].uuid label = usbloop.partitions[0]['mount'].fslabel usblabel = "UUID=%s" % (uuid) overlaysuffix = "-%s-%s" % (label, uuid) args = ['cp', "-Rf", isodir + "/isolinux", usbmnt + "/syslinux"] rc = runner.show(args) if rc: raise CreatorError("Can't copy isolinux directory %s" \ % (isodir + "/isolinux/*")) if os.path.isfile("/usr/share/syslinux/isolinux.bin"): syslinux_path = "/usr/share/syslinux" elif os.path.isfile("/usr/lib/syslinux/isolinux.bin"): syslinux_path = "/usr/lib/syslinux" else: raise CreatorError("syslinux not installed : " "cannot find syslinux installation path") for f in ("isolinux.bin", "vesamenu.c32"): path = os.path.join(syslinux_path, f) if os.path.isfile(path): args = ['cp', path, usbmnt + "/syslinux/"] rc = runner.show(args) if rc: raise CreatorError("Can't copy syslinux file " + path) else: raise CreatorError("syslinux not installed: " "syslinux file %s not found" % path) fd = open(isodir + "/isolinux/isolinux.cfg", "r") text = fd.read() fd.close() pattern = re.compile('CDLABEL=[^ ]*') text = pattern.sub(usblabel, text) pattern = re.compile('rootfstype=[^ ]*') text = pattern.sub("rootfstype=" + fstype, text) if kernelargs: text = text.replace("liveimg", "liveimg " + kernelargs) if overlaysizemb > 0: msger.info("Initializing persistent overlay file") overfile = "overlay" + overlaysuffix if fstype == "vfat": args = ['dd', "if=/dev/zero", "of=" + usbmnt + "/LiveOS/" + overfile, "count=%d" % overlaysizemb, "bs=1M"] else: args = ['dd', "if=/dev/null", "of=" + usbmnt + "/LiveOS/" + overfile, "count=1", "bs=1M", "seek=%d" % overlaysizemb] rc = runner.show(args) if rc: raise CreatorError("Can't create overlay file") text = text.replace("liveimg", "liveimg overlay=" + usblabel) text = text.replace(" ro ", " rw ") if swapsizemb > 0: msger.info("Initializing swap file") swapfile = usbmnt + "/LiveOS/" + "swap.img" args = ['dd', "if=/dev/zero", "of=" + swapfile, "count=%d" % swapsizemb, "bs=1M"] rc = runner.show(args) if rc: raise CreatorError("Can't create swap file") args = ["mkswap", "-f", swapfile] rc = runner.show(args) if rc: raise CreatorError("Can't mkswap on swap file") if homesizemb > 0: msger.info("Initializing persistent /home") homefile = usbmnt + "/LiveOS/" + homefile if fstype == "vfat": args = ['dd', "if=/dev/zero", "of=" + homefile, "count=%d" % homesizemb, "bs=1M"] else: args = ['dd', "if=/dev/null", "of=" + homefile, "count=1", "bs=1M", "seek=%d" % homesizemb] rc = runner.show(args) if rc: raise CreatorError("Can't create home file") mkfscmd = fs_related.find_binary_path("/sbin/mkfs." + fstype) if fstype == "ext2" or fstype == "ext3": args = [mkfscmd, "-F", "-j", homefile] else: args = [mkfscmd, homefile] rc = runner.show(args) if rc: raise CreatorError("Can't mke2fs home file") if fstype == "ext2" or fstype == "ext3": tune2fs = fs_related.find_binary_path("tune2fs") args = [tune2fs, "-c0", "-i0", "-ouser_xattr,acl", homefile] rc = runner.show(args) if rc: raise CreatorError("Can't tune2fs home file") if fstype == "vfat" or fstype == "msdos": syslinuxcmd = fs_related.find_binary_path("syslinux") syslinuxcfg = usbmnt + "/syslinux/syslinux.cfg" args = [syslinuxcmd, "-d", "syslinux", usbloop.partitions[0]["device"]] elif fstype == "ext2" or fstype == "ext3": extlinuxcmd = fs_related.find_binary_path("extlinux") syslinuxcfg = usbmnt + "/syslinux/extlinux.conf" args = [extlinuxcmd, "-i", usbmnt + "/syslinux"] else: raise CreatorError("Invalid file system type: %s" % (fstype)) os.unlink(usbmnt + "/syslinux/isolinux.cfg") fd = open(syslinuxcfg, "w") fd.write(text) fd.close() rc = runner.show(args) if rc: raise CreatorError("Can't install boot loader.") finally: usbloop.unmount() usbloop.cleanup() # Need to do this after image is unmounted and device mapper is closed msger.info("set MBR") mbrfile = "/usr/lib/syslinux/mbr.bin" if not os.path.exists(mbrfile): mbrfile = "/usr/share/syslinux/mbr.bin" if not os.path.exists(mbrfile): raise CreatorError("mbr.bin file didn't exist.") mbrsize = os.path.getsize(mbrfile) outimg = "%s/%s.usbimg" % (self._outdir, self.name) args = ['dd', "if=" + mbrfile, "of=" + outimg, "seek=0", "conv=notrunc", "bs=1", "count=%d" % (mbrsize)] rc = runner.show(args) if rc: raise CreatorError("Can't set MBR.")
def _create_usbimg(self, isodir): overlaysizemb = 64 #default #skipcompress = self.skip_compression? fstype = "vfat" homesizemb=0 swapsizemb=0 homefile="home.img" plussize=128 kernelargs=None if fstype == 'vfat': if overlaysizemb > 2047: raise CreatorError("Can't have an overlay of 2048MB or " "greater on VFAT") if homesizemb > 2047: raise CreatorError("Can't have an home overlay of 2048MB or " "greater on VFAT") if swapsizemb > 2047: raise CreatorError("Can't have an swap overlay of 2048MB or " "greater on VFAT") livesize = misc.get_file_size(isodir + "/LiveOS") usbimgsize = (overlaysizemb + \ homesizemb + \ swapsizemb + \ livesize + \ plussize) * 1024L * 1024L disk = fs_related.SparseLoopbackDisk("%s/%s.usbimg" \ % (self._outdir, self.name), usbimgsize) usbmnt = self._mkdtemp("usb-mnt") usbloop = PartitionedMount(usbmnt) usbloop.add_disk('/dev/sdb', disk) usbloop.add_partition(usbimgsize/1024/1024, "/dev/sdb", "/", fstype, boot=True) usbloop.mount() try: fs_related.makedirs(usbmnt + "/LiveOS") if os.path.exists(isodir + "/LiveOS/squashfs.img"): shutil.copyfile(isodir + "/LiveOS/squashfs.img", usbmnt + "/LiveOS/squashfs.img") else: fs_related.mksquashfs(os.path.dirname(self._image), usbmnt + "/LiveOS/squashfs.img") if os.path.exists(isodir + "/LiveOS/osmin.img"): shutil.copyfile(isodir + "/LiveOS/osmin.img", usbmnt + "/LiveOS/osmin.img") if fstype == "vfat" or fstype == "msdos": uuid = usbloop.partitions[0]['mount'].uuid label = usbloop.partitions[0]['mount'].fslabel usblabel = "UUID=%s-%s" % (uuid[0:4], uuid[4:8]) overlaysuffix = "-%s-%s-%s" % (label, uuid[0:4], uuid[4:8]) else: diskmount = usbloop.partitions[0]['mount'] usblabel = "UUID=%s" % diskmount.uuid overlaysuffix = "-%s-%s" % (diskmount.fslabel, diskmount.uuid) args = ['cp', "-Rf", isodir + "/isolinux", usbmnt + "/syslinux"] rc = runner.show(args) if rc: raise CreatorError("Can't copy isolinux directory %s" \ % (isodir + "/isolinux/*")) if os.path.isfile("/usr/share/syslinux/isolinux.bin"): syslinux_path = "/usr/share/syslinux" elif os.path.isfile("/usr/lib/syslinux/isolinux.bin"): syslinux_path = "/usr/lib/syslinux" else: raise CreatorError("syslinux not installed : " "cannot find syslinux installation path") for f in ("isolinux.bin", "vesamenu.c32"): path = os.path.join(syslinux_path, f) if os.path.isfile(path): args = ['cp', path, usbmnt + "/syslinux/"] rc = runner.show(args) if rc: raise CreatorError("Can't copy syslinux file " + path) else: raise CreatorError("syslinux not installed: " "syslinux file %s not found" % path) fd = open(isodir + "/isolinux/isolinux.cfg", "r") text = fd.read() fd.close() pattern = re.compile('CDLABEL=[^ ]*') text = pattern.sub(usblabel, text) pattern = re.compile('rootfstype=[^ ]*') text = pattern.sub("rootfstype=" + fstype, text) if kernelargs: text = text.replace("rd.live.image", "rd.live.image " + kernelargs) if overlaysizemb > 0: msger.info("Initializing persistent overlay file") overfile = "overlay" + overlaysuffix if fstype == "vfat": args = ['dd', "if=/dev/zero", "of=" + usbmnt + "/LiveOS/" + overfile, "count=%d" % overlaysizemb, "bs=1M"] else: args = ['dd', "if=/dev/null", "of=" + usbmnt + "/LiveOS/" + overfile, "count=1", "bs=1M", "seek=%d" % overlaysizemb] rc = runner.show(args) if rc: raise CreatorError("Can't create overlay file") text = text.replace("rd.live.image", "rd.live.image rd.live.overlay=" + usblabel) text = text.replace(" ro ", " rw ") if swapsizemb > 0: msger.info("Initializing swap file") swapfile = usbmnt + "/LiveOS/" + "swap.img" args = ['dd', "if=/dev/zero", "of=" + swapfile, "count=%d" % swapsizemb, "bs=1M"] rc = runner.show(args) if rc: raise CreatorError("Can't create swap file") args = ["mkswap", "-f", swapfile] rc = runner.show(args) if rc: raise CreatorError("Can't mkswap on swap file") if homesizemb > 0: msger.info("Initializing persistent /home") homefile = usbmnt + "/LiveOS/" + homefile if fstype == "vfat": args = ['dd', "if=/dev/zero", "of=" + homefile, "count=%d" % homesizemb, "bs=1M"] else: args = ['dd', "if=/dev/null", "of=" + homefile, "count=1", "bs=1M", "seek=%d" % homesizemb] rc = runner.show(args) if rc: raise CreatorError("Can't create home file") mkfscmd = fs_related.find_binary_path("/sbin/mkfs." + fstype) if fstype == "ext2" or fstype == "ext3": args = [mkfscmd, "-F", "-j", homefile] else: args = [mkfscmd, homefile] rc = runner.show(args) if rc: raise CreatorError("Can't mke2fs home file") if fstype == "ext2" or fstype == "ext3": tune2fs = fs_related.find_binary_path("tune2fs") args = [tune2fs, "-c0", "-i0", "-ouser_xattr,acl", homefile] rc = runner.show(args) if rc: raise CreatorError("Can't tune2fs home file") if fstype == "vfat" or fstype == "msdos": syslinuxcmd = fs_related.find_binary_path("syslinux") syslinuxcfg = usbmnt + "/syslinux/syslinux.cfg" args = [syslinuxcmd, "-d", "syslinux", usbloop.partitions[0]["device"]] elif fstype == "ext2" or fstype == "ext3": extlinuxcmd = fs_related.find_binary_path("extlinux") syslinuxcfg = usbmnt + "/syslinux/extlinux.conf" args = [extlinuxcmd, "-i", usbmnt + "/syslinux"] else: raise CreatorError("Invalid file system type: %s" % (fstype)) os.unlink(usbmnt + "/syslinux/isolinux.cfg") fd = open(syslinuxcfg, "w") fd.write(text) fd.close() rc = runner.show(args) if rc: raise CreatorError("Can't install boot loader.") finally: usbloop.unmount() usbloop.cleanup() # Need to do this after image is unmounted and device mapper is closed msger.info("set MBR") mbrfile = "/usr/lib/syslinux/mbr.bin" if not os.path.exists(mbrfile): mbrfile = "/usr/share/syslinux/mbr.bin" if not os.path.exists(mbrfile): raise CreatorError("mbr.bin file didn't exist.") mbrsize = os.path.getsize(mbrfile) outimg = "%s/%s.usbimg" % (self._outdir, self.name) args = ['dd', "if=" + mbrfile, "of=" + outimg, "seek=0", "conv=notrunc", "bs=1", "count=%d" % (mbrsize)] rc = runner.show(args) if rc: raise CreatorError("Can't set MBR.")
def do_create(self, subcmd, opts, *args): """${cmd_name}: create fs image Usage: ${name} ${cmd_name} <ksfile> [OPTS] ${cmd_option_list} """ if len(args) != 1: raise errors.Usage("Extra arguments given") creatoropts = configmgr.create ksconf = args[0] if creatoropts['runtime'] == 'bootstrap': configmgr._ksconf = ksconf rt_util.bootstrap_mic() elif not rt_util.inbootstrap(): try: fs_related.find_binary_path('mic-native') except errors.CreatorError: if not msger.ask( "Subpackage \"mic-native\" has not been " "installed in your host system, still " "continue with \"native\" running mode?", False): raise errors.Abort("Abort because subpackage 'mic-native' " "has not been installed") recording_pkgs = [] if len(creatoropts['record_pkgs']) > 0: recording_pkgs = creatoropts['record_pkgs'] if creatoropts['release'] is not None: if 'name' not in recording_pkgs: recording_pkgs.append('name') if 'vcs' not in recording_pkgs: recording_pkgs.append('vcs') configmgr._ksconf = ksconf # try to find the pkgmgr pkgmgr = None backends = pluginmgr.get_plugins('backend') if 'auto' == creatoropts['pkgmgr']: for key in configmgr.prefer_backends: if key in backends: pkgmgr = backends[key] break else: for key in backends.keys(): if key == creatoropts['pkgmgr']: pkgmgr = backends[key] break if not pkgmgr: raise errors.CreatorError( "Can't find backend: %s, " "available choices: %s" % (creatoropts['pkgmgr'], ','.join(backends.keys()))) creator = fs.FsImageCreator(creatoropts, pkgmgr) creator._include_src = opts.include_src if len(recording_pkgs) > 0: creator._recording_pkgs = recording_pkgs self.check_image_exists(creator.destdir, creator.pack_to, [creator.name], creatoropts['release']) try: creator.check_depend_tools() creator.mount(None, creatoropts["cachedir"]) creator.install() #Download the source packages ###private options if opts.include_src: installed_pkgs = creator.get_installed_packages() msger.info( '--------------------------------------------------') msger.info( 'Generating the image with source rpms included ...') if not misc.SrcpkgsDownload( installed_pkgs, creatoropts["repomd"], creator._instroot, creatoropts["cachedir"]): msger.warning("Source packages can't be downloaded") creator.configure(creatoropts["repomd"]) creator.copy_kernel() creator.unmount() creator.package(creatoropts["destdir"]) creator.create_manifest() if creatoropts['release'] is not None: creator.release_output(ksconf, creatoropts['destdir'], creatoropts['release']) creator.print_outimage_info() except errors.CreatorError: raise finally: creator.cleanup() msger.info("Finished.") return 0
def package(self, destdir = "."): ignores = ["/dev/fd", "/dev/stdin", "/dev/stdout", "/dev/stderr", "/etc/mtab"] if not os.path.exists(destdir): os.makedirs(destdir) if self._recording_pkgs: self._save_recording_pkgs(destdir) if not self.pack_to: fsdir = os.path.join(destdir, self.name) misc.check_space_pre_cp(self._instroot, destdir) msger.info("Copying %s to %s ..." % (self._instroot, fsdir)) runner.show(['cp', "-af", self._instroot, fsdir]) for exclude in ignores: if os.path.exists(fsdir + exclude): os.unlink(fsdir + exclude) self.outimage.append(fsdir) else: (tar, comp) = os.path.splitext(self.pack_to) try: tarcreat = {'.tar': '-cf', '.gz': '-czf', '.bz2': '-cjf', '.tgz': '-czf', '.tbz': '-cjf'}[comp] except KeyError: raise CreatorError("Unsupported comression for this image type:" " '%s', try '.tar', '.tar.gz', etc" % comp) dst = os.path.join(destdir, self.pack_to) msger.info("Pack rootfs to %s. Please wait..." % dst) tar = find_binary_path('tar') tar_cmdline = [tar, "--numeric-owner", "--preserve-permissions", "--one-file-system", "--directory", self._instroot] for ignore_entry in ignores: if ignore_entry.startswith('/'): ignore_entry = ignore_entry[1:] tar_cmdline.append("--exclude=%s" % (ignore_entry)) tar_cmdline.extend([tarcreat, dst, "."]) rc = runner.show(tar_cmdline) if rc: raise CreatorError("Failed compress image with tar.bz2. " "Cmdline: %s" % (" ".join(tar_cmdline))) self.outimage.append(dst)
def do_chroot(cls, target): img = target imgsize = misc.get_file_size(img) * 1024L * 1024L partedcmd = fs_related.find_binary_path("parted") disk = fs_related.SparseLoopbackDisk(img, imgsize) imgmnt = misc.mkdtemp() imgloop = PartitionedMount({'/dev/sdb': disk}, imgmnt, skipformat=True) img_fstype = "ext3" # Check the partitions from raw disk. root_mounted = False partition_mounts = 0 for line in runner.outs([partedcmd, "-s", img, "unit", "B", "print"]).splitlines(): line = line.strip() # Lines that start with number are the partitions, # because parted can be translated we can't refer to any text lines. if not line or not line[0].isdigit(): continue # Some vars have extra , as list seperator. line = line.replace(",", "") # Example of parted output lines that are handled: # Number Start End Size Type File system Flags # 1 512B 3400000511B 3400000000B primary # 2 3400531968B 3656384511B 255852544B primary linux-swap(v1) # 3 3656384512B 3720347647B 63963136B primary fat16 boot, lba partition_info = re.split("\s+", line) size = partition_info[3].split("B")[0] if len(partition_info) < 6 or partition_info[5] in ["boot"]: # No filesystem can be found from partition line. Assuming # btrfs, because that is the only MeeGo fs that parted does # not recognize properly. # TODO: Can we make better assumption? fstype = "btrfs" elif partition_info[5] in ["ext2", "ext3", "ext4", "btrfs"]: fstype = partition_info[5] elif partition_info[5] in ["fat16", "fat32"]: fstype = "vfat" elif "swap" in partition_info[5]: fstype = "swap" else: raise errors.CreatorError( "Could not recognize partition fs type '%s'." % partition_info[5]) if not root_mounted and fstype in [ "ext2", "ext3", "ext4", "btrfs" ]: # TODO: Check that this is actually the valid root partition from /etc/fstab mountpoint = "/" root_mounted = True elif fstype == "swap": mountpoint = "swap" else: # TODO: Assing better mount points for the rest of the partitions. partition_mounts += 1 mountpoint = "/media/partition_%d" % partition_mounts if "boot" in partition_info: boot = True else: boot = False msger.verbose( "Size: %s Bytes, fstype: %s, mountpoint: %s, boot: %s" % (size, fstype, mountpoint, boot)) # TODO: add_partition should take bytes as size parameter. imgloop.add_partition((int)(size) / 1024 / 1024, "/dev/sdb", mountpoint, fstype=fstype, boot=boot) try: imgloop.mount() except errors.MountError: imgloop.cleanup() raise try: chroot.chroot(imgmnt, None, "/bin/env HOME=/root /bin/bash") except: raise errors.CreatorError("Failed to chroot to %s." % img) finally: chroot.cleanup_after_chroot("img", imgloop, None, imgmnt)
def setup_qemu_emulator(rootdir, arch): # mount binfmt_misc if it doesn't exist if not os.path.exists("/proc/sys/fs/binfmt_misc"): modprobecmd = find_binary_path("modprobe") runner.show([modprobecmd, "binfmt_misc"]) if not os.path.exists("/proc/sys/fs/binfmt_misc/register"): mountcmd = find_binary_path("mount") runner.show([ mountcmd, "-t", "binfmt_misc", "none", "/proc/sys/fs/binfmt_misc" ]) # qemu_emulator is a special case, we can't use find_binary_path # qemu emulator should be a statically-linked executable file if arch == "aarch64": node = "/proc/sys/fs/binfmt_misc/aarch64" if os.path.exists("/usr/bin/qemu-arm64") and is_statically_linked( "/usr/bin/qemu-arm64"): arm_binary = "qemu-arm64" elif os.path.exists("/usr/bin/qemu-aarch64") and is_statically_linked( "/usr/bin/qemu-aarch64"): arm_binary = "qemu-aarch64" elif os.path.exists("/usr/bin/qemu-arm64-static"): arm_binary = "qemu-arm64-static" elif os.path.exists("/usr/bin/qemu-aarch64-static"): arm_binary = "qemu-aarch64-static" else: raise CreatorError("Please install a statically-linked %s" % arm_binary) elif arch == "mipsel": node = "/proc/sys/fs/binfmt_misc/mipsel" arm_binary = "qemu-mipsel" if not os.path.exists( "/usr/bin/%s" % arm_binary) or not is_statically_linked("/usr/bin/%s"): arm_binary = "qemu-mipsel-static" if not os.path.exists("/usr/bin/%s" % arm_binary): raise CreatorError("Please install a statically-linked %s" % arm_binary) else: node = "/proc/sys/fs/binfmt_misc/arm" arm_binary = "qemu-arm" if not os.path.exists("/usr/bin/qemu-arm") or not is_statically_linked( "/usr/bin/qemu-arm"): arm_binary = "qemu-arm-static" if not os.path.exists("/usr/bin/%s" % arm_binary): raise CreatorError("Please install a statically-linked %s" % arm_binary) qemu_emulator = "/usr/bin/%s" % arm_binary if not os.path.exists(rootdir + "/usr/bin"): makedirs(rootdir + "/usr/bin") shutil.copy(qemu_emulator, rootdir + qemu_emulator) # disable selinux, selinux will block qemu emulator to run if os.path.exists("/usr/sbin/setenforce"): msger.info('Try to disable selinux') runner.show(["/usr/sbin/setenforce", "0"]) # unregister it if it has been registered and is a dynamically-linked executable if os.path.exists(node): qemu_unregister_string = "-1\n" with open(node, "w") as fd: fd.write(qemu_unregister_string) # register qemu emulator for interpreting other arch executable file if not os.path.exists(node): if arch == "aarch64": qemu_arm_string = ":aarch64:M::\\x7fELF\\x02\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\xb7:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff:%s:\n" % qemu_emulator elif arch == "mipsel": qemu_arm_string = ":mipsel:M::\\x7fELF\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x08\\x00:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xfe\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff\\xff:%s:\n" % qemu_emulator else: qemu_arm_string = ":arm:M::\\x7fELF\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x28\\x00:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfa\\xff\\xff\\xff:%s:\n" % qemu_emulator with open("/proc/sys/fs/binfmt_misc/register", "w") as fd: fd.write(qemu_arm_string) return qemu_emulator