def addUser(self, userconfig): args = ["/usr/sbin/useradd"] if userconfig.groups: args += ["--groups", string.join(userconfig.groups, ",")] if userconfig.name: args.append(userconfig.name) try: dev_null = os.open("/dev/null", os.O_WRONLY) subprocess.call(args, stdout=dev_null, stderr=dev_null, preexec_fn=self.chroot) os.close(dev_null) except: msger.warning('Cannot add user using "useradd"') if userconfig.password not in (None, ""): if userconfig.isCrypted: self.set_encrypted_passwd(userconfig.name, userconfig.password) else: self.set_unencrypted_passwd(userconfig.name, userconfig.password) else: self.set_empty_passwd(userconfig.name) else: raise errors.KsError("Invalid kickstart command: %s" \ % userconfig.__str__())
def load_mountpoints(fpath): """Load mount points mapping from file :fpath, file path to load """ if not fpath: return from xml.dom import minidom mount_maps = [] with open(fpath, 'r') as rf: dom = minidom.parse(rf) imgroot = dom.documentElement for part in imgroot.getElementsByTagName("partition"): p = dict(part.attributes.items()) try: mp = (p['mountpoint'], p['label'], p['name'], int(p['size']), p['fstype']) except KeyError: msger.warning("Wrong format line in file: %s" % fpath) except ValueError: msger.warning("Invalid size '%s' in file: %s" % (p['size'], fpath)) else: mount_maps.append(mp) return mount_maps
def _parse_siteconf(self, siteconf): if os.getenv("MIC_PLUGIN_DIR"): self.common["plugin_dir"] = os.environ["MIC_PLUGIN_DIR"] if siteconf and not os.path.exists(siteconf): msger.warning("cannot find config file: %s" % siteconf) siteconf = None if not siteconf: self.common["distro_name"] = "Tizen" # append common section items to other sections for section in self.DEFAULTS.keys(): if section != "common": getattr(self, section).update(self.common) return parser = ConfigParser.SafeConfigParser() parser.read(siteconf) for section in parser.sections(): if section in self.DEFAULTS: getattr(self, section).update(dict(parser.items(section))) # append common section items to other sections for section in self.DEFAULTS.keys(): if section != "common": getattr(self, section).update(self.common) # check and normalize the scheme of proxy url if self.create['proxy']: m = re.match('^(\w+)://.*', self.create['proxy']) if m: scheme = m.group(1) if scheme not in ('http', 'https', 'ftp', 'socks'): raise errors.ConfigError("%s: proxy scheme is incorrect" % siteconf) else: msger.warning("%s: proxy url w/o scheme, use http as default" % siteconf) self.create['proxy'] = "http://" + self.create['proxy'] proxy.set_proxies(self.create['proxy'], self.create['no_proxy']) # bootstrap option handling self.set_runtime(self.create['runtime']) if isinstance(self.bootstrap['packages'], basestring): packages = self.bootstrap['packages'].replace('\n', ' ') if packages.find(',') != -1: packages = packages.split(',') else: packages = packages.split() self.bootstrap['packages'] = packages if type(self.create['use_mic_in_bootstrap']) != 'bool': use_mic_in_bootstrap = str(self.create['use_mic_in_bootstrap']) if use_mic_in_bootstrap.lower() in ('on', 'yes', 'true', '1'): self.create['use_mic_in_bootstrap'] = True else: self.create['use_mic_in_bootstrap'] = False
def cleanup_mounts(chrootdir): umountcmd = misc.find_binary_path("umount") for point in BIND_MOUNTS: args = [ umountcmd, "-l", chrootdir + point ] runner.quiet(args) point = '/parentroot' args = [ umountcmd, "-l", chrootdir + point ] runner.quiet(args) abs_chrootdir = os.path.abspath(chrootdir) with open('/proc/mounts') as f: for line in f: if abs_chrootdir in line: point = line.split()[1] if abs_chrootdir == point: continue args = [ umountcmd, "-l", point ] ret = runner.quiet(args) if ret != 0: msger.warning("failed to unmount %s" % point) return ret return 0
def configure(self, repodata=None): """Configure the system image according to the kickstart. This method applies the (e.g. keyboard or network) configuration specified in the kickstart and executes the kickstart %post scripts. If necessary, it also prepares the image to be bootable by e.g. creating an initrd and bootloader configuration. """ ksh = self.ks.handler msger.info("Applying configurations ...") try: kickstart.LanguageConfig(self._instroot).apply(ksh.lang) kickstart.KeyboardConfig(self._instroot).apply(ksh.keyboard) kickstart.TimezoneConfig(self._instroot).apply(ksh.timezone) # kickstart.AuthConfig(self._instroot).apply(ksh.authconfig) kickstart.FirewallConfig(self._instroot).apply(ksh.firewall) kickstart.RootPasswordConfig(self._instroot).apply(ksh.rootpw) kickstart.UserConfig(self._instroot).apply(ksh.user) kickstart.ServicesConfig(self._instroot).apply(ksh.services) kickstart.XConfig(self._instroot).apply(ksh.xconfig) kickstart.NetworkConfig(self._instroot).apply(ksh.network) kickstart.RPMMacroConfig(self._instroot).apply(self.ks) kickstart.DesktopConfig(self._instroot).apply(ksh.desktop) self.__save_repo_keys(repodata) kickstart.MoblinRepoConfig(self._instroot).apply(ksh.repo, repodata) except: msger.warning("Failed to apply configuration to image") raise self._create_bootconfig() self.__run_post_scripts()
def savefs_before_chroot(chrootdir, saveto = None): """ backup chrootdir to another directory before chrooting in """ if configmgr.chroot['saveto']: savefs = True saveto = configmgr.chroot['saveto'] wrnmsg = "Can't save chroot fs for dir %s exists" % saveto if saveto == chrootdir: savefs = False wrnmsg = "Dir %s is being used to chroot" % saveto elif os.path.exists(saveto): if msger.ask("Dir %s already exists, cleanup and continue?" % saveto): shutil.rmtree(saveto, ignore_errors = True) savefs = True else: savefs = False if savefs: msger.info("Saving image to directory %s" % saveto) fs_related.makedirs(os.path.dirname(os.path.abspath(saveto))) runner.quiet("cp -af %s %s" % (chrootdir, saveto)) devs = ['dev/fd', 'dev/stdin', 'dev/stdout', 'dev/stderr', 'etc/mtab'] ignlst = [os.path.join(saveto, x) for x in devs] map(os.unlink, filter(os.path.exists, ignlst)) else: msger.warning(wrnmsg)
def preinstallPkgs(self): if not self.ts_pre: self.__initialize_transaction() self.ts_pre.order() cb = rpmmisc.RPMInstallCallback(self.ts_pre) cb.headmsg = "Preinstall" installlogfile = "%s/__catched_stderr.buf" % (self.instroot) # start to catch stderr output from librpm msger.enable_logstderr(installlogfile) errors = self.ts_pre.run(cb.callback, '') # stop catch msger.disable_logstderr() self.ts_pre.closeDB() self.ts_pre = None if errors is not None: if len(errors) == 0: msger.warning('scriptlet or other non-fatal errors occurred ' 'during transaction.') else: for e in errors: msger.warning(e[0]) raise RepoError('Could not run transaction.')
def exec_cmd(cmd_and_args, as_shell = False, catch = 3): """ Execute command, catching stderr, stdout Need to execute as_shell if the command uses wildcards """ msger.debug("exec_cmd: %s" % cmd_and_args) args = cmd_and_args.split() msger.debug(args) if (as_shell): rc, out = runner.runtool(cmd_and_args, catch) else: rc, out = runner.runtool(args, catch) out = out.strip() msger.debug("exec_cmd: output for %s (rc = %d): %s" % \ (cmd_and_args, rc, out)) if rc != 0: # We don't throw exception when return code is not 0, because # parted always fails to reload part table with loop devices. This # prevents us from distinguishing real errors based on return # code. msger.warning("WARNING: %s returned '%s' instead of 0" % (cmd_and_args, rc)) return (rc, out)
def cleanup_mountdir(chrootdir, bindmounts): if bindmounts == "" or bindmounts == None: return chrootmounts = [] for mount in bindmounts.split(";"): if not mount: continue srcdst = mount.split(":") if len(srcdst) == 1: srcdst.append("none") if srcdst[0] == "/": continue if srcdst[1] == "" or srcdst[1] == "none": srcdst[1] = srcdst[0] srcdst[1] = os.path.abspath(os.path.expanduser(srcdst[1])) tmpdir = chrootdir + "/" + srcdst[1] if os.path.isdir(tmpdir): if len(os.listdir(tmpdir)) == 0: shutil.rmtree(tmpdir, ignore_errors = True) else: msger.warning("Warning: dir %s isn't empty." % tmpdir)
def deselectPackage(self, pkg): """Deselect package. Can be specified as name.arch or name*""" sp = pkg.rsplit(".", 2) txmbrs = [] if len(sp) == 2: txmbrs = self.tsInfo.matchNaevr(name=sp[0], arch=sp[1]) if len(txmbrs) == 0: exact, match, unmatch = yum.packages.parsePackages( self.pkgSack.returnPackages(), [pkg], casematch=1) for p in exact + match: txmbrs.append(p) if len(txmbrs) > 0: for x in txmbrs: self.tsInfo.remove(x.pkgtup) # we also need to remove from the conditionals # dict so that things don't get pulled back in as a result # of them. yes, this is ugly. conditionals should die. for req, pkgs in self.tsInfo.conditionals.iteritems(): if x in pkgs: pkgs.remove(x) self.tsInfo.conditionals[req] = pkgs else: msger.warning("No such package %s to remove" % (pkg, ))
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 if self._isohybrid: try: isohybrid = fs_related.find_binary_path("isohybrid") msger.info("isohybrid found") except: msger.warning("isohybrid NOT found") if isohybrid: args = [isohybrid, "-partok", iso ] if runner.show(args) != 0: raise CreatorError("Hybrid ISO creation failed!") else: msger.info("Hybrid ISO created successfully") self.__implant_md5sum(iso)
def addUser(self, userconfig): args = [ "/usr/sbin/useradd" ] if userconfig.groups: args += [ "--groups", string.join(userconfig.groups, ",") ] if userconfig.name: args += [ "-m"] args += [ "-d", "/home/%s" % userconfig.name ] args.append(userconfig.name) try: dev_null = os.open("/dev/null", os.O_WRONLY) msger.debug('adding user with %s' % args) subprocess.call(args, stdout = dev_null, stderr = dev_null, preexec_fn = self.chroot) os.close(dev_null) except: msger.warning('Cannot add user using "useradd"') if userconfig.password not in (None, ""): if userconfig.isCrypted: self.set_encrypted_passwd(userconfig.name, userconfig.password) else: self.set_unencrypted_passwd(userconfig.name, userconfig.password) else: self.set_empty_passwd(userconfig.name) else: raise errors.KsError("Invalid kickstart command: %s" \ % userconfig.__str__())
def _set_noproxy_list(): global _my_noproxy, _my_noproxy_list _my_noproxy_list = [] if not _my_noproxy: return #solve in /etc/enviroment contains command like `echo 165.xxx.xxx.{1..255} | sed 's/ /,/g'`` _my_noproxy_bak = _my_noproxy start = _my_noproxy.find("`") while(start < len(_my_noproxy) and start != -1): start = _my_noproxy.find("`",start) end = _my_noproxy.find("`",start+1) cmd = _my_noproxy[start+1:end] pstr = _my_noproxy[start:end+1] start = end + 1 _my_noproxy=_my_noproxy.replace(pstr,len(pstr)*" ") try: c_result = os.popen(cmd).readlines() if len(c_result) == 0: continue except Exception,e: msger.warning(str(e)) continue to_list = c_result[0].strip("\n").split(",") _my_noproxy_list.extend(to_list)
def check_bind_mounts(chrootdir, bindmounts): chrootmounts = [] for mount in bindmounts.split(";"): if not mount: continue srcdst = mount.split(":") if len(srcdst) == 1: srcdst.append("none") if not os.path.isdir(srcdst[0]): return False if srcdst[1] == "" or srcdst[1] == "none": srcdst[1] = None if srcdst[0] in BIND_MOUNTS or srcdst[0] == '/': continue if chrootdir: if not srcdst[1]: srcdst[1] = os.path.abspath(os.path.expanduser(srcdst[0])) else: srcdst[1] = os.path.abspath(os.path.expanduser(srcdst[1])) tmpdir = chrootdir + "/" + srcdst[1] if os.path.isdir(tmpdir): msger.warning("Warning: dir %s has existed." % tmpdir) return True
def deselectPackage(self, pkg): """Deselect package. Can be specified as name.arch or name* """ sp = pkg.rsplit(".", 2) txmbrs = [] if len(sp) == 2: txmbrs = self.tsInfo.matchNaevr(name=sp[0], arch=sp[1]) if len(txmbrs) == 0: exact, match, unmatch = yum.packages.parsePackages( self.pkgSack.returnPackages(), [pkg], casematch=1) for p in exact + match: txmbrs.append(p) if len(txmbrs) > 0: for x in txmbrs: self.tsInfo.remove(x.pkgtup) # we also need to remove from the conditionals # dict so that things don't get pulled back in as a result # of them. yes, this is ugly. conditionals should die. for req, pkgs in self.tsInfo.conditionals.iteritems(): if x in pkgs: pkgs.remove(x) self.tsInfo.conditionals[req] = pkgs else: msger.warning("No such package %s to remove" %(pkg,))
def cleanup_mountdir(chrootdir, bindmounts): if bindmounts == "" or bindmounts == None: return chrootmounts = [] for mount in bindmounts.split(";"): if not mount: continue srcdst = mount.split(":") if len(srcdst) == 1: srcdst.append("none") if srcdst[0] == "/": continue if srcdst[1] == "" or srcdst[1] == "none": srcdst[1] = srcdst[0] srcdst[1] = os.path.abspath(os.path.expanduser(srcdst[1])) tmpdir = chrootdir + "/" + srcdst[1] if os.path.isdir(tmpdir): if len(os.listdir(tmpdir)) == 0: shutil.rmtree(tmpdir, ignore_errors=True) else: msger.warning("Warning: dir %s isn't empty." % tmpdir)
def SrcpkgsDownload(pkgs, repometadata, instroot, cachedir): def get_source_repometadata(repometadata): src_repometadata = [] for repo in repometadata: if repo["name"].endswith("-source"): src_repometadata.append(repo) if src_repometadata: return src_repometadata return None def get_src_name(srpm): m = re.match("(.*)-(\d+.*)-(\d+\.\d+).src.rpm", srpm) if m: return m.group(1) return None src_repometadata = get_source_repometadata(repometadata) if not src_repometadata: msger.warning("No source repo found") return None src_pkgs = [] lpkgs_dict = {} lpkgs_path = [] for repo in src_repometadata: cachepath = "%s/%s/packages/*.src.rpm" % (cachedir, repo["name"]) lpkgs_path += glob.glob(cachepath) for lpkg in lpkgs_path: lpkg_name = get_src_name(os.path.basename(lpkg)) lpkgs_dict[lpkg_name] = lpkg localpkgs = lpkgs_dict.keys() cached_count = 0 destdir = instroot + '/usr/src/SRPMS' if not os.path.exists(destdir): os.makedirs(destdir) srcpkgset = set() for _pkg in pkgs: srcpkg_name = get_source_name(_pkg, repometadata) if not srcpkg_name: continue srcpkgset.add(srcpkg_name) for pkg in list(srcpkgset): if pkg in localpkgs: cached_count += 1 shutil.copy(lpkgs_dict[pkg], destdir) src_pkgs.append(os.path.basename(lpkgs_dict[pkg])) else: src_pkg = get_package(pkg, src_repometadata, 'src') if src_pkg: shutil.copy(src_pkg, destdir) src_pkgs.append(src_pkg) msger.info("%d source packages gotten from cache" % cached_count) return src_pkgs
def SrcpkgsDownload(pkgs, repometadata, instroot, cachedir): def get_source_repometadata(repometadata): src_repometadata=[] for repo in repometadata: if repo["name"].endswith("-source"): src_repometadata.append(repo) if src_repometadata: return src_repometadata return None def get_src_name(srpm): m = SRPM_RE.match(srpm) if m: return m.group(1) return None src_repometadata = get_source_repometadata(repometadata) if not src_repometadata: msger.warning("No source repo found") return None src_pkgs = [] lpkgs_dict = {} lpkgs_path = [] for repo in src_repometadata: cachepath = "%s/%s/packages/*.src.rpm" %(cachedir, repo["name"]) lpkgs_path += glob.glob(cachepath) for lpkg in lpkgs_path: lpkg_name = get_src_name(os.path.basename(lpkg)) lpkgs_dict[lpkg_name] = lpkg localpkgs = lpkgs_dict.keys() cached_count = 0 destdir = instroot+'/usr/src/SRPMS' if not os.path.exists(destdir): os.makedirs(destdir) srcpkgset = set() for _pkg in pkgs: srcpkg_name = get_source_name(_pkg, repometadata) if not srcpkg_name: continue srcpkgset.add(srcpkg_name) for pkg in list(srcpkgset): if pkg in localpkgs: cached_count += 1 shutil.copy(lpkgs_dict[pkg], destdir) src_pkgs.append(os.path.basename(lpkgs_dict[pkg])) else: src_pkg = get_package(pkg, src_repometadata, 'src') if src_pkg: shutil.copy(src_pkg, destdir) src_pkgs.append(src_pkg) msger.info("%d source packages gotten from cache" % cached_count) return src_pkgs
def get_bind_mounts(chrootdir, bindmounts, mountparent = True): chrootmounts = [] if bindmounts in ("", None): bindmounts = "" for mount in bindmounts.split(";"): if not mount: continue srcdst = mount.split(":") srcdst[0] = os.path.abspath(os.path.expanduser(srcdst[0])) if len(srcdst) == 1: srcdst.append("none") # if some bindmount is not existed, but it's created inside # chroot, this is not expected if not os.path.exists(srcdst[0]): os.makedirs(srcdst[0]) if not os.path.isdir(srcdst[0]): continue if srcdst[0] in BIND_MOUNTS or srcdst[0] == '/': msger.verbose("%s will be mounted by default." % srcdst[0]) continue if srcdst[1] == "" or srcdst[1] == "none": srcdst[1] = None else: srcdst[1] = os.path.abspath(os.path.expanduser(srcdst[1])) if os.path.isdir(chrootdir + "/" + srcdst[1]): msger.warning("%s has existed in %s , skip it."\ % (srcdst[1], chrootdir)) continue chrootmounts.append(fs_related.BindChrootMount(srcdst[0], chrootdir, srcdst[1])) """Default bind mounts""" for pt in BIND_MOUNTS: chrootmounts.append(fs_related.BindChrootMount(pt, chrootdir, None)) if mountparent: chrootmounts.append(fs_related.BindChrootMount("/", chrootdir, "/parentroot", "ro")) for kernel in os.listdir("/lib/modules"): chrootmounts.append(fs_related.BindChrootMount( "/lib/modules/"+kernel, chrootdir, None, "ro")) return chrootmounts
def buildTransaction(self): if not self.Z.resolver().resolvePool(): msger.warning("Problem count: %d" % len(self.Z.resolver().problems())) for problem in self.Z.resolver().problems(): msger.warning("Problem: %s, %s" % (problem.description().decode("utf-8"), problem.details().decode("utf-8")))
def get_repos(ks, repo_urls=None): repos = {} for repo in ks.handler.repo.repoList: inc = [] if hasattr(repo, "includepkgs"): inc.extend(repo.includepkgs) exc = [] if hasattr(repo, "excludepkgs"): exc.extend(repo.excludepkgs) baseurl = repo.baseurl mirrorlist = repo.mirrorlist if repo_urls and repo.name in repo_urls: baseurl = repo_urls[repo.name] mirrorlist = None if repos.has_key(repo.name): msger.warning("Overriding already specified repo %s" % (repo.name, )) proxy = None if hasattr(repo, "proxy"): proxy = repo.proxy proxy_username = None if hasattr(repo, "proxy_username"): proxy_username = repo.proxy_username proxy_password = None if hasattr(repo, "proxy_password"): proxy_password = repo.proxy_password if hasattr(repo, "debuginfo"): debuginfo = repo.debuginfo if hasattr(repo, "source"): source = repo.source if hasattr(repo, "gpgkey"): gpgkey = repo.gpgkey if hasattr(repo, "disable"): disable = repo.disable ssl_verify = True if hasattr(repo, "ssl_verify"): ssl_verify = repo.ssl_verify == "yes" nocache = False if hasattr(repo, "nocache"): nocache = repo.nocache cost = None if hasattr(repo, "cost"): cost = repo.cost priority = None if hasattr(repo, "priority"): priority = repo.priority repos[repo.name] = (repo.name, baseurl, mirrorlist, inc, exc, proxy, proxy_username, proxy_password, debuginfo, source, gpgkey, disable, ssl_verify, nocache, cost, priority) return repos.values()
def addRepository(self, name, url=None, mirrorlist=None, proxy=None, proxy_username=None, proxy_password=None, inc=None, exc=None, ssl_verify=True, cost=None, priority=None): # TODO: Handle priority attribute for repos def _varSubstitute(option): # takes a variable and substitutes like yum configs do option = option.replace("$basearch", rpmUtils.arch.getBaseArch()) option = option.replace("$arch", rpmUtils.arch.getCanonArch()) return option repo = MyYumRepository(name) # Set proxy repo.proxy = proxy repo.proxy_username = proxy_username repo.proxy_password = proxy_password if url: repo.baseurl.append(_varSubstitute(url)) # check LICENSE files if not rpmmisc.checkRepositoryEULA(name, repo): msger.warning('skip repo:%s for failed EULA confirmation' % name) return None if mirrorlist: repo.mirrorlist = _varSubstitute(mirrorlist) conf = yum.config.RepoConf() for k, v in conf.iteritems(): if v or not hasattr(repo, k): repo.setAttribute(k, v) repo.sslverify = ssl_verify repo.basecachedir = self.conf.cachedir repo.base_persistdir = self.conf.persistdir repo.failovermethod = "priority" repo.metadata_expire = 0 # Enable gpg check for verifying corrupt packages repo.gpgcheck = 1 repo.enable() repo.setup(0) self.repos.add(repo) if cost: repo.cost = cost msger.verbose('repo: %s was added' % name) return repo
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 + 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"]) node = "/proc/sys/fs/binfmt_misc/arm" if is_statically_linked(qemu_emulator) and os.path.exists(node): return qemu_emulator # unregister it if it has been registered and is a dynamically-linked executable if not is_statically_linked(qemu_emulator) and 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 checkPkg(self, pkg): ret = 1 if not os.path.exists(pkg): return ret ret = rpmmisc.checkRpmIntegrity('rpm', pkg) if ret != 0: msger.warning("package %s is damaged: %s" % (os.path.basename(pkg), pkg)) return ret
def get_repos(ks, repo_urls=None): repos = {} for repo in ks.handler.repo.repoList: inc = [] if hasattr(repo, "includepkgs"): inc.extend(repo.includepkgs) exc = [] if hasattr(repo, "excludepkgs"): exc.extend(repo.excludepkgs) baseurl = repo.baseurl mirrorlist = repo.mirrorlist if repo_urls and repo.name in repo_urls: baseurl = repo_urls[repo.name] mirrorlist = None if repos.has_key(repo.name): msger.warning("Overriding already specified repo %s" %(repo.name,)) proxy = None if hasattr(repo, "proxy"): proxy = repo.proxy proxy_username = None if hasattr(repo, "proxy_username"): proxy_username = repo.proxy_username proxy_password = None if hasattr(repo, "proxy_password"): proxy_password = repo.proxy_password if hasattr(repo, "debuginfo"): debuginfo = repo.debuginfo if hasattr(repo, "source"): source = repo.source if hasattr(repo, "gpgkey"): gpgkey = repo.gpgkey if hasattr(repo, "disable"): disable = repo.disable ssl_verify = True if hasattr(repo, "ssl_verify"): ssl_verify = repo.ssl_verify == "yes" nocache = False if hasattr(repo, "nocache"): nocache = repo.nocache cost = None if hasattr(repo, "cost"): cost = repo.cost priority = None if hasattr(repo, "priority"): priority = repo.priority repos[repo.name] = (repo.name, baseurl, mirrorlist, inc, exc, proxy, proxy_username, proxy_password, debuginfo, source, gpgkey, disable, ssl_verify, nocache, cost, priority) return repos.values()
def bootstrap_mic(argv=None): def mychroot(): os.chroot(rootdir) os.chdir(cwd) # by default, sys.argv is used to run mic in bootstrap if not argv: argv = sys.argv if argv[0] not in ('/usr/bin/mic', 'mic'): argv[0] = '/usr/bin/mic' cropts = configmgr.create bsopts = configmgr.bootstrap distro = bsopts['distro_name'].lower() rootdir = bsopts['rootdir'] pkglist = bsopts['packages'] cwd = os.getcwd() # create bootstrap and run mic in bootstrap bsenv = bootstrap.Bootstrap(rootdir, distro, cropts['arch']) bsenv.logfile = cropts['logfile'] # rootdir is regenerated as a temp dir rootdir = bsenv.rootdir if 'optional' in bsopts: optlist = bsopts['optional'] else: optlist = [] try: msger.info("Creating %s bootstrap ..." % distro) bsenv.create(cropts['repomd'], pkglist, optlist) # bootstrap is relocated under "bootstrap" if os.path.exists(os.path.join(rootdir, "bootstrap")): rootdir = os.path.join(rootdir, "bootstrap") bsenv.dirsetup(rootdir) sync_mic(rootdir) #FIXME: sync the ks file to bootstrap if "/" == os.path.dirname(os.path.abspath(configmgr._ksconf)): safecopy(configmgr._ksconf, rootdir) msger.info("Start mic in bootstrap: %s\n" % rootdir) bindmounts = get_bindmounts(cropts) ret = bsenv.run(argv, cwd, rootdir, bindmounts) except errors.BootstrapError, err: msger.warning('\n%s' % err) if msger.ask("Switch to native mode and continue?"): return else: raise errors.BootstrapError("Failed to create bootstrap: %s" % err)
def bootstrap_mic(argv=None): def mychroot(): os.chroot(rootdir) os.chdir(cwd) # by default, sys.argv is used to run mic in bootstrap if not argv: argv = sys.argv if argv[0] not in ('/usr/bin/mic', 'mic'): argv[0] = '/usr/bin/mic' cropts = configmgr.create bsopts = configmgr.bootstrap distro = bsopts['distro_name'].lower() rootdir = bsopts['rootdir'] pkglist = bsopts['packages'] cwd = os.getcwd() # create bootstrap and run mic in bootstrap bsenv = bootstrap.Bootstrap(rootdir, distro, cropts['arch']) bsenv.logfile = cropts['logfile'] # rootdir is regenerated as a temp dir rootdir = bsenv.rootdir if 'optional' in bsopts: optlist = bsopts['optional'] else: optlist = [] try: msger.info("Creating %s bootstrap ..." % distro) bsenv.create(cropts['repomd'], pkglist, optlist) # bootstrap is relocated under "bootstrap" if os.path.exists(os.path.join(rootdir, "bootstrap")): rootdir = os.path.join(rootdir, "bootstrap") bsenv.dirsetup(rootdir) sync_mic(rootdir) #FIXME: sync the ks file to bootstrap if "/" == os.path.dirname(os.path.abspath(configmgr._ksconf)): safecopy(configmgr._ksconf, rootdir) msger.info("Start mic in bootstrap: %s\n" % rootdir) bindmounts = get_bindmounts(cropts) ret = bsenv.run(argv, cwd, rootdir, bindmounts) except errors.BootstrapError, err: msger.warning('\n%s' % err) if msger.ask("Switch to native mode and continue?"): return raise
def read_kickstart(path): """Parse a kickstart file and return a KickstartParser instance. This is a simple utility function which takes a path to a kickstart file, parses it and returns a pykickstart KickstartParser instance which can be then passed to an ImageCreator constructor. If an error occurs, a CreatorError exception is thrown. """ #version = ksversion.makeVersion() #ks = ksparser.KickstartParser(version) using_version = ksversion.DEVEL commandMap[using_version]["desktop"] = desktop.Moblin_Desktop commandMap[using_version]["repo"] = moblinrepo.Moblin_Repo commandMap[using_version]["bootloader"] = micboot.Moblin_Bootloader commandMap[using_version]["part"] = partition.MeeGo_Partition commandMap[using_version]["partition"] = partition.MeeGo_Partition commandMap[using_version]["btrfs"] = btrfs.BTRFS dataMap[using_version]["RepoData"] = moblinrepo.Moblin_RepoData dataMap[using_version]["PartData"] = partition.MeeGo_PartData dataMap[using_version]["BTRFSData"] = btrfs.BTRFSData superclass = ksversion.returnClassForVersion(version=using_version) class KSHandlers(superclass): def __init__(self, mapping={}): superclass.__init__(self, mapping=commandMap[using_version]) self.prepackages = PrePackages() self.attachment = Attachment() def __str__(self): retval = superclass.__str__(self) if self.prepackages: retval += self.prepackages.__str__() if self.attachment: retval += self.attachment.__str__() return retval ks = ksparser.KickstartParser(KSHandlers(), errorsAreFatal=False) ks.registerSection(PackScriptSection(ks.handler, dataObj=PackScript)) ks.registerSection(PrepackageSection(ks.handler)) ks.registerSection(AttachmentSection(ks.handler)) try: ks.readKickstart(path) except (kserrors.KickstartParseError, kserrors.KickstartError) as err: if msger.ask("Errors occured on kickstart file, skip and continue?"): msger.warning("%s" % err) pass else: raise errors.KsError("%s" % err) return ks
def get_mic_binpath(): # FIXME: please use mic.find_binary_path() path = os.environ['PATH'] paths = string.split(path, os.pathsep) for pth in paths: fn = os.path.join(pth, 'mic') if os.path.isfile(fn): return fn msger.warning("Can't find mic command")
def mount(self): if self.mounted or self.ismounted(): return try: makedirs(self.dest) except OSError, err: if err.errno == errno.ENOSPC: msger.warning("No space left on device '%s'" % err.filename) return
def __implant_md5sum(self, iso): """Implant an isomd5sum.""" if os.path.exists("/usr/bin/implantisomd5"): implantisomd5 = "/usr/bin/implantisomd5" else: msger.warning("isomd5sum not installed; not setting up mediacheck") implantisomd5 = "" return runner.show([implantisomd5, iso])
def _add_plugindir(self, path): path = os.path.abspath(os.path.expanduser(path)) if not os.path.isdir(path): msger.warning("Plugin dir is not a directory or does not exist: %s"\ % path) return if path not in self.plugin_dirs: self.plugin_dirs[path] = False
def get_bind_mounts(chrootdir, bindmounts, mountparent=True): chrootmounts = [] if bindmounts in ("", None): bindmounts = "" for mount in bindmounts.split(";"): if not mount: continue srcdst = mount.split(":") srcdst[0] = os.path.abspath(os.path.expanduser(srcdst[0])) if len(srcdst) == 1: srcdst.append("none") # if some bindmount is not existed, but it's created inside # chroot, this is not expected if not os.path.exists(srcdst[0]): os.makedirs(srcdst[0]) if not os.path.isdir(srcdst[0]): continue if srcdst[0] in BIND_MOUNTS or srcdst[0] == '/': msger.verbose("%s will be mounted by default." % srcdst[0]) continue if srcdst[1] == "" or srcdst[1] == "none": srcdst[1] = None else: srcdst[1] = os.path.abspath(os.path.expanduser(srcdst[1])) if os.path.isdir(chrootdir + "/" + srcdst[1]): msger.warning("%s has existed in %s , skip it."\ % (srcdst[1], chrootdir)) continue chrootmounts.append( fs_related.BindChrootMount(srcdst[0], chrootdir, srcdst[1])) """Default bind mounts""" for pt in BIND_MOUNTS: if not os.path.exists(pt): continue chrootmounts.append(fs_related.BindChrootMount( pt, chrootdir, None)) if mountparent: chrootmounts.append( fs_related.BindChrootMount("/", chrootdir, "/parentroot", "ro")) for kernel in os.listdir("/lib/modules"): chrootmounts.append( fs_related.BindChrootMount("/lib/modules/" + kernel, chrootdir, None, "ro")) return chrootmounts
def get_bindmounts(chrootdir, bindmounts=None): """ calculate all bind mount entries for global usage """ # bindmounts should be a string like '/dev:/dev' # FIXME: refine the bindmounts from string to dict global chroot_bindmounts def totuple(string): """ convert string contained ':' to a tuple """ if ':' in string: src, dst = string.split(':', 1) else: src = string dst = None return (src or None, dst or None) if chroot_bindmounts: return chroot_bindmounts chroot_bindmounts = [] bindmounts = bindmounts or "" mountlist = [] for mount in bindmounts.split(";"): if not mount: continue (src, dst) = totuple(mount) if src in BIND_MOUNTS or src == '/': continue if not os.path.exists(src): os.makedirs(src) if dst and os.path.isdir("%s/%s" % (chrootdir, dst)): msger.warning("%s existed in %s , skip it." % (dst, chrootdir)) continue mountlist.append(totuple(mount)) for mntpoint in BIND_MOUNTS: if os.path.isdir(mntpoint): mountlist.append(tuple((mntpoint, None))) for pair in mountlist: if pair[0] == "/lib/modules": opt = "ro" else: opt = None bmount = fs_related.BindChrootMount(pair[0], chrootdir, pair[1], opt) chroot_bindmounts.append(bmount) return chroot_bindmounts
def wrapper(*kargs, **kwargs): try: func(*kargs, **kwargs) except (OSError, IOError, errors.KsError), err: cfgcls = kargs[0].__class__.__name__ if msger.ask("Failed to apply %s, skip and continue?" % cfgcls): msger.warning("%s" % err) pass else: # just throw out the exception raise
def release_output(self, config, destdir, release): """ Create release directory and files """ def _rpath(fn): """ release path """ return os.path.join(destdir, fn) outimages = self.outimage # new ks new_kspath = _rpath(self.name + ".ks") with open(config) as fr: with open(new_kspath, "w") as wf: # When building a release we want to make sure the .ks # file generates the same build even when --release= is not used. wf.write(fr.read().replace("@BUILD_ID@", release)) outimages.append(new_kspath) # rename iso and usbimg for f in os.listdir(destdir): if f.endswith(".iso"): newf = f[:-4] + ".img" elif f.endswith(".usbimg"): newf = f[:-7] + ".img" else: continue os.rename(_rpath(f), _rpath(newf)) outimages.append(_rpath(newf)) # generate MANIFEST with open(_rpath("MANIFEST"), "w") as wf: if os.path.exists("/usr/bin/md5sum"): for f in os.listdir(destdir): if f == "MANIFEST": continue if os.path.isdir(os.path.join(destdir, f)): continue rc, md5sum = runner.runtool(["/usr/bin/md5sum", "-b", _rpath(f)]) if rc != 0: msger.warning("Failed to generate md5sum for file %s" % _rpath(f)) else: md5sum = md5sum.lstrip().split()[0] wf.write(md5sum + " " + f + "\n") else: msger.warning("no md5sum tool found, no checksum string in MANIFEST") wf.writelines(os.listdir(destdir)) outimages.append("%s/MANIFEST" % destdir) # Filter out the nonexist file for fp in outimages[:]: if not os.path.exists("%s" % fp): outimages.remove(fp)
def buildTransaction(self): if not self.Z.resolver().resolvePool(): probs = self.Z.resolver().problems() for problem in probs: msger.warning("repo problem: %s, %s" \ % (problem.description().decode("utf-8"), problem.details().decode("utf-8"))) raise RepoError("found %d resolver problem, abort!" \ % len(probs))
def get_bindmounts(chrootdir, bindmounts = None): """ calculate all bind mount entries for global usage """ # bindmounts should be a string like '/dev:/dev' # FIXME: refine the bindmounts from string to dict global chroot_bindmounts def totuple(string): """ convert string contained ':' to a tuple """ if ':' in string: src, dst = string.split(':', 1) else: src = string dst = None return (src or None, dst or None) if chroot_bindmounts: return chroot_bindmounts chroot_bindmounts = [] bindmounts = bindmounts or "" mountlist = [] for mount in bindmounts.split(";"): if not mount: continue (src, dst) = totuple(mount) if src in BIND_MOUNTS or src == '/': continue if not os.path.exists(src): os.makedirs(src) if dst and os.path.isdir("%s/%s" % (chrootdir, dst)): msger.warning("%s existed in %s , skip it." % (dst, chrootdir)) continue mountlist.append(totuple(mount)) for mntpoint in BIND_MOUNTS: if os.path.isdir(mntpoint): mountlist.append(tuple((mntpoint, None))) for pair in mountlist: if pair[0] == "/lib/modules": opt = "ro" else: opt = None bmount = fs_related.BindChrootMount(pair[0], chrootdir, pair[1], opt) chroot_bindmounts.append(bmount) return chroot_bindmounts
def wrapper(*kargs, **kwargs): try: func(*kargs, **kwargs) except (OSError, IOError, errors.KsError) as err: cfgcls = kargs[0].__class__.__name__ if msger.ask("Failed to apply %s, skip and continue?" % cfgcls): msger.warning("%s" % err) pass else: # just throw out the exception raise
def __init__(self, *args, **kwargs): cmdln.Cmdln.__init__(self, *args, **kwargs) # get cmds from pluginmgr # mix-in do_subcmd interface for subcmd, klass in pluginmgr.get_plugins('imager').iteritems(): if not hasattr(klass, 'do_create'): msger.warning("Unsurpport subcmd: %s" % subcmd) continue func = getattr(klass, 'do_create') setattr(self.__class__, "do_" + subcmd, func)
def checkRpmChecksum(package, checksum): # The checksum from rpm includes a preceding type .. eg: sha256-834561aa3... (sumtype, csum) = str(checksum).split("-") h = hashlib.new(sumtype) with open(package, "rb") as f: for chunk in iter(lambda: f.read(512 * h.block_size), b''): h.update(chunk) if h.hexdigest() == csum: return True msger.warning("package %s %s checksum %s from repo.xml is not same as the cached rpm digest %s-%s " \ % (package, sumtype, checksum, sumtype, h.hexdigest())) return False
def __init__(self, *args, **kwargs): cmdln.Cmdln.__init__(self, *args, **kwargs) # get cmds from pluginmgr # mix-in do_subcmd interface for subcmd, klass in pluginmgr.get_plugins('imager').iteritems(): if not hasattr(klass, 'do_create'): msger.warning("Unsurpport subcmd: %s" % subcmd) continue func = getattr(klass, 'do_create') setattr(self.__class__, "do_"+subcmd, func)
def release_output(self, config, destdir, release): """ Create release directory and files """ def _rpath(fn): """ release path """ return os.path.join(destdir, fn) outimages = self.outimage # new ks new_kspath = _rpath(self.name+'.ks') with open(config) as fr: with open(new_kspath, "w") as wf: # When building a release we want to make sure the .ks # file generates the same build even when --release= is not used. wf.write(fr.read().replace("@BUILD_ID@", release)) outimages.append(new_kspath) # rename iso and usbimg for f in os.listdir(destdir): if f.endswith(".iso"): newf = f[:-4] + '.img' elif f.endswith(".usbimg"): newf = f[:-7] + '.img' else: continue os.rename(_rpath(f), _rpath(newf)) outimages.append(_rpath(newf)) # generate MANIFEST with open(_rpath("MANIFEST"), "w") as wf: if os.path.exists("/usr/bin/md5sum"): for f in os.listdir(destdir): if f == "MANIFEST": continue if os.path.isdir(os.path.join(destdir,f)): continue rc, md5sum = runner.runtool(["/usr/bin/md5sum", "-b", _rpath(f)]) if rc != 0: msger.warning("Failed to generate md5sum for file %s" % _rpath(f)) else: md5sum = md5sum.lstrip().split()[0] wf.write(md5sum+" "+ f +"\n") else: msger.warning('no md5sum tool found, no checksum string in MANIFEST') wf.writelines(os.listdir(destdir)) outimages.append("%s/MANIFEST" % destdir) # Filter out the nonexist file for fp in outimages[:]: if not os.path.exists("%s" % fp): outimages.remove(fp)
def __select_groups(self, pkg_manager): skipped_groups = [] for group in self._required_groups: e = pkg_manager.selectGroup(group.name, group.include) if e: if kickstart.ignore_missing(self.ks): skipped_groups.append(group) else: raise CreatorError("Failed to find group '%s' : %s" % (group.name, e)) for group in skipped_groups: msger.warning("Skipping missing group '%s'" % (group.name,))
def check_armv7_qemu_version(arch, qemu_emulator): 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) return None
def _parse_siteconf(self, siteconf): if os.getenv("MIC_PLUGIN_DIR"): self.common["plugin_dir"] = os.environ["MIC_PLUGIN_DIR"] if siteconf and not os.path.exists(siteconf): msger.warning("cannot find config file: %s" % siteconf) siteconf = None if not siteconf: self.common["distro_name"] = "Tizen" # append common section items to other sections for section in self.DEFAULTS.keys(): if section != "common": getattr(self, section).update(self.common) return parser = ConfigParser.SafeConfigParser() parser.read(siteconf) for section in parser.sections(): if section in self.DEFAULTS: getattr(self, section).update(dict(parser.items(section))) # append common section items to other sections for section in self.DEFAULTS.keys(): if section != "common": getattr(self, section).update(self.common) # check and normalize the scheme of proxy url if self.create['proxy']: m = re.match('^(\w+)://.*', self.create['proxy']) if m: scheme = m.group(1) if scheme not in ('http', 'https', 'ftp', 'socks'): raise errors.ConfigError("%s: proxy scheme is incorrect" % siteconf) else: msger.warning("%s: proxy url w/o scheme, use http as default" % siteconf) self.create['proxy'] = "http://" + self.create['proxy'] proxy.set_proxies(self.create['proxy'], self.create['no_proxy']) # bootstrap option handling self.set_runtime(self.create['runtime']) if isinstance(self.bootstrap['packages'], basestring): packages = self.bootstrap['packages'].replace('\n', ' ') if packages.find(',') != -1: packages = packages.split(',') else: packages = packages.split() self.bootstrap['packages'] = packages
def do_create(self, subcmd, opts, *args): """${cmd_name}: create fs image Usage: ${name} ${cmd_name} <ksfile> [OPTS] ${cmd_option_list} """ creatoropts = common.creatoropts(args) creator = fs.FsImageCreator(creatoropts, creatoropts['pkgmgr_pcls']) creator._recording_pkgs = creatoropts['record_pkgs'] creator._include_src = opts.include_src 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["outdir"]) if creatoropts['release'] is not None: creator.release_output(ksconf, creatoropts['outdir'], creatoropts['release']) else: creator.outimage.append(creatoropts['dst_ks']) creator.print_outimage_info() except errors.CreatorError: raise finally: creator.cleanup() msger.info("Finished.") return 0
def __select_groups(self, pkg_manager): skipped_groups = [] for group in self._required_groups: e = pkg_manager.selectGroup(group.name, group.include) if e: if kickstart.ignore_missing(self.ks): skipped_groups.append(group) else: raise CreatorError("Failed to find group '%s' : %s" % (group.name, e)) for group in skipped_groups: msger.warning("Skipping missing group '%s'" % (group.name, ))
def addRepository(self, name, url = None, mirrorlist = None, proxy = None, proxy_username = None, proxy_password = None, inc = None, exc = None, ssl_verify=True, nocache=False, cost = None, priority=None): # TODO: Handle priority attribute for repos def _varSubstitute(option): # takes a variable and substitutes like yum configs do option = option.replace("$basearch", rpmUtils.arch.getBaseArch()) option = option.replace("$arch", rpmUtils.arch.getCanonArch()) return option repo = MyYumRepository(name) # Set proxy repo.proxy = proxy repo.proxy_username = proxy_username repo.proxy_password = proxy_password if url: repo.baseurl.append(_varSubstitute(url)) # check LICENSE files if not rpmmisc.checkRepositoryEULA(name, repo): msger.warning('skip repo:%s for failed EULA confirmation' % name) return None if mirrorlist: repo.mirrorlist = _varSubstitute(mirrorlist) conf = yum.config.RepoConf() for k, v in conf.iteritems(): if v or not hasattr(repo, k): repo.setAttribute(k, v) repo.sslverify = ssl_verify repo.cache = not nocache repo.basecachedir = self.cachedir repo.base_persistdir = self.conf.persistdir repo.failovermethod = "priority" repo.metadata_expire = 0 # Enable gpg check for verifying corrupt packages repo.gpgcheck = 1 repo.enable() repo.setup(0) self.repos.add(repo) if cost: repo.cost = cost msger.verbose('repo: %s was added' % name) return repo