def __format_filesystem(self): if self.skipformat: msger.debug("Skip filesystem format.") return msger.verbose("Formating %s filesystem on %s" % (self.fstype, self.disk.device)) rc = runner.show([ self.mkfscmd, "-F", "-L", self.fslabel, "-m", "1", "-b", str(self.blocksize), "-O", "^64bit", # syslinux does not support 64bit filesystems self.disk.device ]) # str(self.disk.size / self.blocksize)]) if rc != 0: raise MountError("Error creating %s filesystem on disk %s" % (self.fstype, self.disk.device)) out = runner.outs([self.dumpe2fs, '-h', self.disk.device]) self.uuid = self.__parse_field(out, "Filesystem UUID") msger.debug("Tuning filesystem on %s" % self.disk.device) runner.show([ self.tune2fs, "-c0", "-i0", "-Odir_index", "-ouser_xattr,acl", self.disk.device ])
def __format_filesystem(self): if self.skipformat: msger.debug("Skip filesystem format.") return msger.verbose("Formating %s filesystem on %s" % (self.fstype, self.disk.device)) cmdlist = [ self.mkfscmd, "-F", "-L", self.fslabel, "-m", "1", "-b", str(self.blocksize), "-U", self.uuid ] if self.extopts: cmdlist.extend(self.extopts.split()) cmdlist.extend([self.disk.device]) rc, errout = runner.runtool(cmdlist, catch=2) if rc != 0: raise MountError("Error creating %s filesystem on disk %s:\n%s" % (self.fstype, self.disk.device, errout)) if not self.extopts: msger.debug("Tuning filesystem on %s" % self.disk.device) runner.show([ self.tune2fs, "-c0", "-i0", "-Odir_index", "-ouser_xattr,acl", self.disk.device ])
def __format_filesystem(self): if self.skipformat: msger.debug("Skip filesystem format.") return msger.verbose("Formating %s filesystem on %s" % (self.fstype, self.disk.device)) cmdlist = [self.mkfscmd, "-F", "-L", self.fslabel, "-m", "1", "-b", str(self.blocksize)] if self.extopts: cmdlist.extend(self.extopts.split()) cmdlist.extend([self.disk.device]) rc, errout = runner.runtool(cmdlist, catch=2) if rc != 0: raise MountError("Error creating %s filesystem on disk %s:\n%s" % (self.fstype, self.disk.device, errout)) if not self.extopts: msger.debug("Tuning filesystem on %s" % self.disk.device) runner.show([self.tune2fs, "-c0", "-i0", "-Odir_index", "-ouser_xattr,acl", self.disk.device]) rc, errout = runner.runtool([self.dumpe2fs, '-h', self.disk.device], catch=2) if rc != 0: raise MountError("Error dumpe2fs %s filesystem on disk %s:\n%s" % (self.fstype, self.disk.device, errout)) # FIXME: specify uuid in mkfs parameter try: self.uuid = self.__parse_field(out, "Filesystem UUID") except: self.uuid = None
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
def testVerbose(self): excepted = "Verbose: hello\n" msger.verbose("hello") self.assertEqual("", sys.stdout.getvalue()) msger.set_loglevel("verbose") msger.verbose("hello") self.assertEqual(excepted, sys.stdout.getvalue())
def __format_filesystem(self): if self.skipformat: msger.debug("Skip filesystem format.") return msger.verbose("Formating %s filesystem on %s" % (self.fstype, self.disk.device)) cmdlist = [self.mkfscmd, "-F", "-L", self.fslabel, "-m", "1", "-b", str(self.blocksize)] if self.extopts: cmdlist.extend(self.extopts.split()) cmdlist.extend([self.disk.device]) rc, errout = runner.runtool(cmdlist, catch=2) if rc != 0: raise MountError("Error creating %s filesystem on disk %s:\n%s" % (self.fstype, self.disk.device, errout)) if not self.extopts: msger.debug("Tuning filesystem on %s" % self.disk.device) runner.show([self.tune2fs, "-c0", "-i0", "-Odir_index", "-ouser_xattr,acl", self.disk.device]) rc, out = runner.runtool([self.dumpe2fs, '-h', self.disk.device], catch=2) if rc != 0: raise MountError("Error dumpe2fs %s filesystem on disk %s:\n%s" % (self.fstype, self.disk.device, out)) # FIXME: specify uuid in mkfs parameter try: self.uuid = self.__parse_field(out, "Filesystem UUID") except: self.uuid = None
def _mount_instroot(self, base_on=None): if base_on and os.path.isfile(base_on): self._imgdir = os.path.dirname(base_on) imgname = os.path.basename(base_on) self._base_on(base_on) self._set_image_size(misc.get_file_size(self._image)) # here, self._instloops must be [] self._instloops.append({ "mountpoint": "/", "label": self.name, "name": imgname, "size": self.__image_size or 4096L, "fstype": self.__fstype or "ext3", "extopts": None, "loop": None, "uuid": None, "kspart": None }) self._check_imgdir() for loop in self._instloops: fstype = loop['fstype'] mp = os.path.join(self._instroot, loop['mountpoint'].lstrip('/')) size = loop['size'] * 1024L * 1024L imgname = loop['name'] if fstype in ("ext2", "ext3", "ext4"): MyDiskMount = fs.ExtDiskMount elif fstype == "btrfs": MyDiskMount = fs.BtrfsDiskMount elif fstype in ("vfat", "msdos"): MyDiskMount = fs.VfatDiskMount else: raise MountError('Cannot support fstype: %s' % fstype) loop['loop'] = MyDiskMount(fs.SparseLoopbackDisk( os.path.join(self._imgdir, imgname), size), mp, fstype, self._blocksize, loop['label'], fsuuid=loop['uuid']) if fstype in ("ext2", "ext3", "ext4"): loop['loop'].extopts = loop['extopts'] try: msger.verbose('Mounting image "%s" on "%s"' % (imgname, mp)) fs.makedirs(mp) loop['loop'].mount() # Make an autogenerated uuid avaialble in _get_post_scripts_env() if loop['kspart'] and loop['kspart'].uuid is None and \ loop['loop'].uuid: loop['kspart'].uuid = loop['loop'].uuid except MountError, e: raise
def _do_chroot_tar(cls, target, cmd=[]): mountfp_xml = os.path.splitext(target)[0] + '.xml' if not os.path.exists(mountfp_xml): raise errors.CreatorError("No mount point file found for this tar " "image, please check %s" % mountfp_xml) import tarfile tar = tarfile.open(target, 'r') tmpdir = misc.mkdtemp() tar.extractall(path=tmpdir) tar.close() mntdir = misc.mkdtemp() loops = [] for (mp, label, name, size, fstype) in load_mountpoints(mountfp_xml): if fstype in ("ext2", "ext3", "ext4"): myDiskMount = fs_related.ExtDiskMount elif fstype == "btrfs": myDiskMount = fs_related.BtrfsDiskMount elif fstype in ("vfat", "msdos"): myDiskMount = fs_related.VfatDiskMount else: raise errors.CreatorError("Cannot support fstype: %s" % fstype) name = os.path.join(tmpdir, name) size = size * 1024L * 1024L loop = myDiskMount(fs_related.SparseLoopbackDisk(name, size), os.path.join(mntdir, mp.lstrip('/')), fstype, size, label) try: msger.verbose("Mount %s to %s" % (mp, mntdir + mp)) fs_related.makedirs(os.path.join(mntdir, mp.lstrip('/'))) loop.mount() except: loop.cleanup() for lp in reversed(loops): chroot.cleanup_after_chroot("img", lp, None, mntdir) shutil.rmtree(tmpdir, ignore_errors=True) raise loops.append(loop) try: if len(cmd) != 0: cmdline = "/usr/bin/env HOME=/root " + ' '.join(cmd) else: cmdline = "/usr/bin/env HOME=/root /bin/bash" chroot.chroot(mntdir, None, cmdline) except: raise errors.CreatorError("Failed to chroot to %s." % target) finally: for loop in reversed(loops): chroot.cleanup_after_chroot("img", loop, None, mntdir) shutil.rmtree(tmpdir, ignore_errors=True)
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 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 __format_filesystem(self): if self.skipformat: msger.debug("Skip filesystem format.") return msger.verbose("Formating %s filesystem on %s" % (self.fstype, self.disk.device)) rc = runner.show([self.mkfscmd, "-L", self.fslabel, self.disk.device]) if rc != 0: raise MountError("Error creating %s filesystem on disk %s" % (self.fstype,self.disk.device)) self.uuid = self.__parse_field(runner.outs([self.blkidcmd, self.disk.device]), "UUID")
def __format_filesystem(self): if self.skipformat: msger.debug("Skip filesystem format.") return msger.verbose("Formating %s filesystem on %s" % (self.fstype, self.disk.device)) rc = runner.show([self.mkfscmd, "-n", self.fslabel, "-i", self.uuid, self.disk.device]) if rc != 0: raise MountError("Error creating %s filesystem on disk %s" % (self.fstype,self.disk.device)) msger.verbose("Tuning filesystem on %s" % self.disk.device)
def copy_attachment(self): if not hasattr(self, '_attachment') or not self._attachment: return self._check_imgdir() msger.info("Copying attachment files...") for item in self._attachment: dpath = os.path.join(self.__imgdir, os.path.basename(item)) msger.verbose("Copy attachment %s to %s" % (item, dpath)) shutil.copy(item, dpath)
def _mount_instroot(self, base_on=None): if base_on and os.path.isfile(base_on): self.__imgdir = os.path.dirname(base_on) imgname = os.path.basename(base_on) self._base_on(base_on) self._set_image_size(misc.get_file_size(self._image)) # here, self._instloops must be [] self._instloops.append({ "mountpoint": "/", "label": self.name, "name": imgname, "size": self.__image_size or 4096, "fstype": self.__fstype or "ext3", "loop": None }) self._check_imgdir() for loop in self._instloops: fstype = loop['fstype'] mp = os.path.join(self._instroot, loop['mountpoint'].lstrip('/')) size = loop['size'] * 1024 * 1024 imgname = loop['name'] fsopts = loop['fsopts'] dargs = [ fs.SparseLoopbackDisk(os.path.join(self._imgdir, imgname), size), mp, fstype, self._blocksize, loop['label'] ] dkwargs = {"fsopts": fsopts} if fstype in ("ext2", "ext3", "ext4"): MyDiskMount = fs.ExtDiskMount elif fstype == "btrfs": MyDiskMount = fs.BtrfsDiskMount dkwargs["subvolumes"] = loop["subvolumes"] dkwargs["snapshots"] = loop["snapshots"] elif fstype in ("vfat", "msdos"): MyDiskMount = fs.VfatDiskMount else: msger.error('Cannot support fstype: %s' % fstype) loop['loop'] = MyDiskMount(*dargs, **dkwargs) loop['uuid'] = loop['loop'].uuid try: msger.verbose('Mounting image "%s" on "%s"' % (imgname, mp)) fs.makedirs(mp) loop['loop'].mount() except MountError as e: raise
def _mount_instroot(self, base_on=None): if base_on and os.path.isfile(base_on): self.__imgdir = os.path.dirname(base_on) imgname = os.path.basename(base_on) self._base_on(base_on) self._set_image_size(misc.get_file_size(self._image)) # here, self._instloops must be [] self._instloops.append({ "mountpoint": "/", "label": self.name, "name": imgname, "size": self.__image_size or 4096L, "fstype": self.__fstype or "ext3", "extopts": None, "loop": None }) self._check_imgdir() for loop in self._instloops: fstype = loop['fstype'] mp = os.path.join(self._instroot, loop['mountpoint'].lstrip('/')) size = loop['size'] * 1024L * 1024L imgname = loop['name'] if fstype in ("ext2", "ext3", "ext4"): MyDiskMount = fs.ExtDiskMount elif fstype == "btrfs": MyDiskMount = fs.BtrfsDiskMount elif fstype in ("vfat", "msdos"): MyDiskMount = fs.VfatDiskMount else: msger.error('Cannot support fstype: %s' % fstype) loop['loop'] = MyDiskMount(fs.SparseLoopbackDisk( os.path.join(self.__imgdir, imgname), size), mp, fstype, self._blocksize, loop['label']) if fstype in ("ext2", "ext3", "ext4"): loop['loop'].extopts = loop['extopts'] try: msger.verbose('Mounting image "%s" on "%s"' % (imgname, mp)) fs.makedirs(mp) loop['loop'].mount() except MountError, e: raise
def move_post_umount_scripts(self): scripts_dir = self._instroot + "/var/tmp/post_umount_scripts" if not os.path.exists(scripts_dir): return self._umountdir = self._mkdtemp("umount") msger.info("Moving post umount scripts...") for item in os.listdir(scripts_dir): spath = os.path.join(scripts_dir, item) dpath = os.path.join(self._umountdir, item) msger.verbose("Move post umount scripts %s to %s" % (spath, dpath)) shutil.move(spath, dpath) shutil.rmtree(scripts_dir)
def __format_filesystem(self): if self.skipformat: msger.debug("Skip filesystem format.") return msger.verbose("Formating %s filesystem on %s" % (self.fstype, self.disk.device)) # For now hardcode the 'no extref' option msger.verbose("Hardcode in /usr/lib/python2.7/site-packages/mic/utils/fs_related.py for the 'no extref' option (-O ^extref). See JB#39420") rc = runner.show([self.mkfscmd, "-O", "^extref", "-L", self.fslabel, self.disk.device]) if rc != 0: raise MountError("Error creating %s filesystem on disk %s" % (self.fstype,self.disk.device)) self.uuid = self.__parse_field(runner.outs([self.blkidcmd, "-c /dev/null", self.disk.device]), "UUID")
def copy_attachment(self): if not hasattr(self, '_attachment') or not self._attachment: return self._check_imgdir() msger.info("Copying attachment files...") for item in self._attachment: if not os.path.exists(item): continue dpath = os.path.join(self._imgdir, os.path.basename(item)) msger.verbose("Copy attachment %s to %s" % (item, dpath)) shutil.copy(item, dpath)
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
def mkvdfs(in_img, out_img, fsoptions): """ This function is incomplete. """ fullpathmkvdfs = find_binary_path("mkfs.vdfs") # args = fullpathmkvdfs + " -i -r "+ in_img + " -z 1024M -s " + out_img args = fullpathmkvdfs + " " + fsoptions + " -r " + in_img + " " + out_img msger.verbose("vdfs args: %s" % args) runner.show("%s --help" % fullpathmkvdfs) # if not sys.stdout.isatty(): # args.append("-no-progress") # runner.show("%s --help" % fullpathmkvdfs) ret = runner.show(args) if ret != 0: runner.show("vdfs error") raise VdfsError("' %s' exited with error (%d)" % (args, ret))
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 __format_filesystem(self): if self.skipformat: msger.debug("Skip filesystem format.") return msger.verbose("Formating %s filesystem on %s" % (self.fstype, self.disk.device)) rc = runner.show( [self.mkfscmd, "-F", "-L", self.fslabel, "-m", "1", "-b", str(self.blocksize), self.disk.device] ) # str(self.disk.size / self.blocksize)]) if rc != 0: raise MountError("Error creating %s filesystem on disk %s" % (self.fstype, self.disk.device)) out = runner.outs([self.dumpe2fs, "-h", self.disk.device]) self.uuid = self.__parse_field(out, "Filesystem UUID") msger.debug("Tuning filesystem on %s" % self.disk.device) runner.show([self.tune2fs, "-c0", "-i0", "-Odir_index", "-ouser_xattr,acl", self.disk.device])
def __format_filesystem(self): if self.skipformat: msger.debug("Skip filesystem format.") return msger.verbose("Formating %s filesystem on %s" % (self.fstype, self.disk.device)) cmdlist = [self.mkfscmd, "-F", "-L", self.fslabel, "-m", "1", "-b", str(self.blocksize), "-U", self.uuid] if self.extopts: cmdlist.extend(self.extopts.split()) cmdlist.extend([self.disk.device]) rc, errout = runner.runtool(cmdlist, catch=2) if rc != 0: raise MountError("Error creating %s filesystem on disk %s:\n%s" % (self.fstype, self.disk.device, errout)) if not self.extopts: msger.debug("Tuning filesystem on %s" % self.disk.device) runner.show([self.tune2fs, "-c0", "-i0", "-Odir_index", "-ouser_xattr,acl", self.disk.device])
def show(cmdln_or_args): # show all the message using msger.verbose rc, out = runtool(cmdln_or_args, catch=3) if isinstance(cmdln_or_args, list): cmd = ' '.join(cmdln_or_args) else: cmd = cmdln_or_args msg = 'running command: "%s"' % cmd if out: out = out.strip() if out: msg += ', with output::' msg += '\n +----------------' for line in out.splitlines(): msg += '\n | %s' % line msg += '\n +----------------' msger.verbose(msg) return rc
def _load_all(self): for (pdir, loaded) in self.plugin_dirs.iteritems(): if loaded: continue sys.path.insert(0, pdir) for mod in [x[:-3] for x in os.listdir(pdir) if x.endswith(".py")]: if mod and mod != '__init__': if mod in sys.modules: #self.plugin_dirs[pdir] = True msger.warning("Module %s already exists, skip" % mod) else: try: pymod = __import__(mod) self.plugin_dirs[pdir] = True msger.debug("Plugin module %s:%s imported"\ % (mod, pymod.__file__)) except ImportError, err: msg = 'Failed to load plugin %s/%s: %s' \ % (os.path.basename(pdir), mod, err) msger.verbose(msg) del(sys.path[0])
def bind_mount(chrootmounts): """ perform bind mounting """ for mnt in chrootmounts: msger.verbose("bind_mount: %s -> %s" % (mnt.src, mnt.dest)) mnt.mount()
def installPkgs(self, package_objects): if not self.ts: self.__initialize_transaction() # clean rpm lock self._cleanupRpmdbLocks(self.instroot) self._cleanupZyppJunk(self.instroot) # Set filters probfilter = 0 for flag in self.probFilterFlags: probfilter |= flag self.ts.setProbFilter(probfilter) self.ts_pre.setProbFilter(probfilter) localpkgs = self.localpkgs.keys() for po in package_objects: pkgname = po.name() if pkgname in localpkgs: rpmpath = self.localpkgs[pkgname] else: rpmpath = self.getLocalPkgPath(po) if not os.path.exists(rpmpath): # Maybe it is a local repo rpmuri = self.get_url(po) if rpmuri.startswith("file:/"): rpmpath = rpmuri[5:] if not os.path.exists(rpmpath): raise RpmError("Error: %s doesn't exist" % rpmpath) h = rpmmisc.readRpmHeader(self.ts, rpmpath) if pkgname in self.pre_pkgs: msger.verbose("pre-install package added: %s" % pkgname) self.ts_pre.addInstall(h, rpmpath, 'u') self.ts.addInstall(h, rpmpath, 'u') unresolved_dependencies = self.ts.check() if not unresolved_dependencies: if self.pre_pkgs: self.preinstallPkgs() self.ts.order() cb = rpmmisc.RPMInstallCallback(self.ts) installlogfile = "%s/__catched_stderr.buf" % (self.instroot) # start to catch stderr output from librpm msger.enable_logstderr(installlogfile) errors = self.ts.run(cb.callback, '') # stop catch msger.disable_logstderr() self.ts.closeDB() self.ts = 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.') else: for pkg, need, needflags, sense, key in unresolved_dependencies: package = '-'.join(pkg) if needflags == rpm.RPMSENSE_LESS: deppkg = ' < '.join(need) elif needflags == rpm.RPMSENSE_EQUAL: deppkg = ' = '.join(need) elif needflags == rpm.RPMSENSE_GREATER: deppkg = ' > '.join(need) else: deppkg = '-'.join(need) if sense == rpm.RPMDEP_SENSE_REQUIRES: msger.warning("[%s] Requires [%s], which is not provided" \ % (package, deppkg)) elif sense == rpm.RPMDEP_SENSE_CONFLICTS: msger.warning("[%s] Conflicts with [%s]" %(package,deppkg)) raise RepoError("Unresolved dependencies, transaction failed.")
for url in repo.baseurl: tmphandlers = handlers[:] (scheme, host, path, parm, query, frag) = urlparse.urlparse(url.rstrip('/') + '/') if scheme not in ("http", "https", "ftp", "ftps", "file"): raise CreatorError("Error: invalid url %s" % url) if '@' in host: try: user_pass, host = host.split('@', 1) if ':' in user_pass: user, password = user_pass.split(':', 1) except ValueError, e: raise CreatorError('Bad URL: %s' % url) msger.verbose("adding HTTP auth: %s, %s" %(user, password)) auth_handler.add_password(None, host, user, password) tmphandlers.append(auth_handler) url = scheme + "://" + host + path + parm + query + frag if tmphandlers: u2opener = u2.build_opener(*tmphandlers) # try to download repo_eula_url = urlparse.urljoin(url, "LICENSE.txt") repo_eula_path = _check_and_download_url( u2opener, repo_eula_url, os.path.join(repo_lic_dir, repo.id + '_LICENSE.txt')) if repo_eula_path: # found
for url in repo.baseurl: tmphandlers = handlers[:] (scheme, host, path, parm, query, frag) = urlparse.urlparse(url.rstrip('/') + '/') if scheme not in ("http", "https", "ftp", "ftps", "file"): raise CreatorError("Error: invalid url %s" % url) if '@' in host: try: user_pass, host = host.split('@', 1) if ':' in user_pass: user, password = user_pass.split(':', 1) except ValueError, e: raise CreatorError('Bad URL: %s' % url) msger.verbose("adding HTTP auth: %s, XXXXXXXX" %(user)) auth_handler.add_password(None, host, user, password) tmphandlers.append(auth_handler) url = scheme + "://" + host + path + parm + query + frag if tmphandlers: u2opener = u2.build_opener(*tmphandlers) # try to download repo_eula_url = urlparse.urljoin(url, "LICENSE.txt") repo_eula_path = _check_and_download_url( u2opener, repo_eula_url, os.path.join(repo_lic_dir, repo.id + '_LICENSE.txt')) if repo_eula_path: # found
def callback(self, what, bytes, total, h, user): if what == rpm.RPMCALLBACK_TRANS_START: if bytes == 6: self.total_actions = total elif what == rpm.RPMCALLBACK_TRANS_PROGRESS: pass elif what == rpm.RPMCALLBACK_TRANS_STOP: pass elif what == rpm.RPMCALLBACK_INST_OPEN_FILE: self.lastmsg = None hdr = None if h is not None: try: hdr, rpmloc = h except: rpmloc = h hdr = readRpmHeader(self.ts, h) m = re.match("(.*)-(\d+.*)-(\d+\.\d+)\.(.+)\.rpm", os.path.basename(rpmloc)) if m: pkgname = m.group(1) else: pkgname = os.path.basename(rpmloc) msger.info("Next install: %s " % pkgname) handle = self._makeHandle(hdr) fd = os.open(rpmloc, os.O_RDONLY) self.callbackfilehandles[handle] = fd if hdr['name'] not in self.installed_pkg_names: self.installed_pkg_names.append(hdr['name']) self.total_installed += 1 return fd else: self._localprint("No header - huh?") elif what == rpm.RPMCALLBACK_INST_CLOSE_FILE: hdr = None if h is not None: try: hdr, rpmloc = h except: rpmloc = h hdr = readRpmHeader(self.ts, h) handle = self._makeHandle(hdr) os.close(self.callbackfilehandles[handle]) fd = 0 # log stuff #pkgtup = self._dopkgtup(hdr) self.logString.append(self._logPkgString(hdr)) elif what == rpm.RPMCALLBACK_INST_START: self.total_installing += 1 elif what == rpm.RPMCALLBACK_UNINST_STOP: pass elif what == rpm.RPMCALLBACK_INST_PROGRESS: if h is not None: percent = (self.total_installed * 100L) / self.total_actions if total > 0: try: hdr, rpmloc = h except: rpmloc = h m = re.match("(.*)-(\d+.*)-(\d+\.\d+)\.(.+)\.rpm", os.path.basename(rpmloc)) if m: pkgname = m.group(1) else: pkgname = os.path.basename(rpmloc) if self.output: fmt = self._makefmt(percent) msg = fmt % (self.headmsg, pkgname) if msg != self.lastmsg: self.lastmsg = msg msger.info(msg) if self.total_installed == self.total_actions: msger.raw('') msger.verbose('\n'.join(self.logString)) elif what == rpm.RPMCALLBACK_UNINST_START: pass elif what == rpm.RPMCALLBACK_UNINST_PROGRESS: pass elif what == rpm.RPMCALLBACK_UNINST_STOP: self.total_removed += 1 elif what == rpm.RPMCALLBACK_REPACKAGE_START: pass elif what == rpm.RPMCALLBACK_REPACKAGE_STOP: pass elif what == rpm.RPMCALLBACK_REPACKAGE_PROGRESS: pass elif what == rpm.RPMCALLBACK_SCRIPT_ERROR: if h is not None: try: hdr, rpmloc = h except: rpmloc = h m = re.match("(.*)-(\d+.*)-(\d+\.\d+)\.(.+)\.rpm", os.path.basename(rpmloc)) if m: pkgname = m.group(1) else: pkgname = os.path.basename(rpmloc) msger.warning('(%s) Post script failed' % pkgname)
def bind_unmount(chrootmounts): """ perform bind unmounting """ for mnt in reversed(chrootmounts): msger.verbose("bind_unmount: %s -> %s" % (mnt.src, mnt.dest)) mnt.unmount()
def bind_unmount(chrootmounts): for b in reversed(chrootmounts): msger.verbose("bind_unmount: %s -> %s" % (b.src, b.dest)) b.unmount()
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 cost attribute for repos if not self.repo_manager: self.__initialize_repo_manager() if not proxy and url: proxy = get_proxy_for(url) repo = RepositoryStub() repo.name = name repo.id = name repo.proxy = proxy repo.proxy_username = proxy_username repo.proxy_password = proxy_password repo.ssl_verify = ssl_verify repo.baseurl.append(url) if inc: for pkg in inc: self.incpkgs[pkg] = name if exc: for pkg in exc: self.excpkgs[pkg] = name # 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 = mirrorlist # Enable gpg check for verifying corrupt packages repo.gpgcheck = 0 if priority: repo.priority = priority try: repo_info = zypp.RepoInfo() repo_info.setAlias(repo.name) repo_info.setName(repo.name) repo_info.setEnabled(repo.enabled) repo_info.setGpgCheck(repo.gpgcheck) repo_info.setAutorefresh(repo.autorefresh) repo_info.setKeepPackages(repo.keeppackages) baseurl = zypp.Url(repo.baseurl[0]) if not ssl_verify: baseurl.setQueryParam("ssl_verify", "no") if proxy: scheme, host, path, parm, query, frag = urllib.parse.urlparse(proxy) proxyinfo = host.split(":") host = proxyinfo[0] port = "80" if len(proxyinfo) > 1: port = proxyinfo[1] if proxy.startswith("socks") and len(proxy.rsplit(':', 1)) == 2: host = proxy.rsplit(':', 1)[0] port = proxy.rsplit(':', 1)[1] baseurl.setQueryParam ("proxy", host) baseurl.setQueryParam ("proxyport", port) repo.baseurl[0] = baseurl.asCompleteString() self.repos.append(repo) repo_info.addBaseUrl(baseurl) if repo.priority: repo_info.setPriority(repo.priority) self.repo_manager.addRepository(repo_info) self.__build_repo_cache(name) except RuntimeError as e: raise CreatorError(str(e)) msger.verbose('repo: %s was added' % name) return repo
def bind_mount(chrootmounts): for b in chrootmounts: msger.verbose("bind_mount: %s -> %s" % (b.src, b.dest)) b.mount()
def installPkgs(self, package_objects): if not self.ts: self.__initialize_transaction() # Set filters probfilter = 0 for flag in self.probFilterFlags: probfilter |= flag self.ts.setProbFilter(probfilter) self.ts_pre.setProbFilter(probfilter) localpkgs = list(self.localpkgs.keys()) for po in package_objects: pkgname = po.name() if pkgname in localpkgs: rpmpath = self.localpkgs[pkgname] else: rpmpath = self.getLocalPkgPath(po) if not os.path.exists(rpmpath): # Maybe it is a local repo baseurl = str(po.repoInfo().baseUrls()[0]) baseurl = baseurl.strip() location = po.location() location = str(location.filename()) if baseurl.startswith("file:/"): rpmpath = baseurl[5:] + "/%s" % (location) if not os.path.exists(rpmpath): raise RpmError("Error: %s doesn't exist" % rpmpath) h = rpmmisc.readRpmHeader(self.ts, rpmpath) if pkgname in self.pre_pkgs: msger.verbose("pre-install package added: %s" % pkgname) self.ts_pre.addInstall(h, rpmpath, 'u') self.ts.addInstall(h, rpmpath, 'u') unresolved_dependencies = self.ts.check() if not unresolved_dependencies: if self.pre_pkgs: self.preinstallPkgs() self.ts.order() cb = rpmmisc.RPMInstallCallback(self.ts) installlogfile = "%s/__catched_stderr.buf" % (self.instroot) # start to catch stderr output from librpm msger.enable_logstderr(installlogfile) errors = self.ts.run(cb.callback, '') # stop catch msger.disable_logstderr() self.ts.closeDB() self.ts = 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.') else: for pkg, need, needflags, sense, key in unresolved_dependencies: package = '-'.join(pkg) if needflags == rpm.RPMSENSE_LESS: deppkg = ' < '.join(need) elif needflags == rpm.RPMSENSE_EQUAL: deppkg = ' = '.join(need) elif needflags == rpm.RPMSENSE_GREATER: deppkg = ' > '.join(need) else: deppkg = '-'.join(need) if sense == rpm.RPMDEP_SENSE_REQUIRES: msger.warning("[%s] Requires [%s], which is not provided" \ % (package, deppkg)) elif sense == rpm.RPMDEP_SENSE_CONFLICTS: msger.warning("[%s] Conflicts with [%s]" %(package,deppkg)) raise RepoError("Unresolved dependencies, transaction failed.")
def callback(self, what, bytes, total, h, user): if what == rpm.RPMCALLBACK_TRANS_START: if bytes == 6: self.total_actions = total elif what == rpm.RPMCALLBACK_TRANS_PROGRESS: pass elif what == rpm.RPMCALLBACK_TRANS_STOP: pass elif what == rpm.RPMCALLBACK_INST_OPEN_FILE: self.lastmsg = None hdr = None if h is not None: try: hdr, rpmloc = h except: rpmloc = h hdr = readRpmHeader(self.ts, h) handle = self._makeHandle(hdr) fd = os.open(rpmloc, os.O_RDONLY) self.callbackfilehandles[handle]=fd self.total_installed += 1 self.installed_pkg_names.append(hdr['name']) return fd else: self._localprint("No header - huh?") elif what == rpm.RPMCALLBACK_INST_CLOSE_FILE: hdr = None if h is not None: try: hdr, rpmloc = h except: rpmloc = h hdr = readRpmHeader(self.ts, h) handle = self._makeHandle(hdr) os.close(self.callbackfilehandles[handle]) fd = 0 # log stuff #pkgtup = self._dopkgtup(hdr) self.logString.append(self._logPkgString(hdr)) elif what == rpm.RPMCALLBACK_INST_PROGRESS: if h is not None: percent = (self.total_installed*100L)/self.total_actions if total > 0: try: hdr, rpmloc = h except: rpmloc = h m = re.match("(.*)-(\d+.*)-(\d+\.\d+)\.(.+)\.rpm", os.path.basename(rpmloc)) if m: pkgname = m.group(1) else: pkgname = os.path.basename(rpmloc) if self.output and (sys.stdout.isatty() or self.total_installed == self.total_actions): fmt = self._makefmt(percent) msg = fmt % (self.headmsg, pkgname) if msg != self.lastmsg: self.lastmsg = msg msger.info(msg) if self.total_installed == self.total_actions: msger.raw('') msger.verbose('\n'.join(self.logString)) elif what == rpm.RPMCALLBACK_UNINST_START: pass elif what == rpm.RPMCALLBACK_UNINST_PROGRESS: pass elif what == rpm.RPMCALLBACK_UNINST_STOP: self.total_removed += 1 elif what == rpm.RPMCALLBACK_REPACKAGE_START: pass elif what == rpm.RPMCALLBACK_REPACKAGE_STOP: pass elif what == rpm.RPMCALLBACK_REPACKAGE_PROGRESS: pass
def bind_unmount(chrootmounts): chrootmounts.reverse() for b in chrootmounts: msger.verbose("bind_unmount: %s -> %s" % (b.src, b.dest)) b.unmount()
class Zypp(BackendPlugin): name = 'zypp' def __init__(self, target_arch, instroot, cachedir, strict_mode = False): self.cachedir = cachedir self.instroot = instroot self.target_arch = target_arch self.strict_mode = strict_mode self.__pkgs_license = {} self.__pkgs_content = {} self.__pkgs_vcsinfo = {} self.repos = [] self.to_deselect = [] self.localpkgs = {} self.repo_manager = None self.repo_manager_options = None self.Z = None self.ts = None self.ts_pre = None self.incpkgs = {} self.excpkgs = {} self.pre_pkgs = [] self.check_pkgs = [] self.probFilterFlags = [ rpm.RPMPROB_FILTER_OLDPACKAGE, rpm.RPMPROB_FILTER_REPLACEPKG ] self.has_prov_query = True self.install_debuginfo = False # this can't be changed, it is used by zypp self.tmp_file_path = '/var/tmp' def doFileLogSetup(self, uid, logfile): # don't do the file log for the livecd as it can lead to open fds # being left and an inability to clean up after ourself pass def closeRpmDB(self): pass def close(self): if self.ts: self.ts.closeDB() self.ts = None if self.ts_pre: self.ts_pre.closeDB() self.ts = None self.closeRpmDB() def __del__(self): self.close() def _cleanupRpmdbLocks(self, installroot): # cleans up temporary files left by bdb so that differing # versions of rpm don't cause problems import glob for f in glob.glob(installroot + "/var/lib/rpm/__db*"): os.unlink(f) def _cleanupZyppJunk(self, installroot): try: shutil.rmtree(os.path.join(installroot, '.zypp')) except: pass def setup(self): self._cleanupRpmdbLocks(self.instroot) # '/var/tmp' is used by zypp to build cache, so make sure # if it exists if not os.path.exists(self.tmp_file_path ): os.makedirs(self.tmp_file_path) def whatObsolete(self, pkg): query = zypp.PoolQuery() query.addKind(zypp.ResKind.package) query.addDependency(zypp.SolvAttr.obsoletes, pkg.name(), pkg.edition()) query.setMatchExact() for pi in query.queryResults(self.Z.pool()): return pi return None def _zyppQueryPackage(self, pkg): query = zypp.PoolQuery() query.addKind(zypp.ResKind.package) query.addAttribute(zypp.SolvAttr.name, pkg) query.setMatchExact() for pi in query.queryResults(self.Z.pool()): return pi return None def _splitPkgString(self, pkg): sp = pkg.rsplit(".", 1) name = sp[0] arch = None if len(sp) == 2: arch = sp[1] sysarch = zypp.Arch(self.target_arch) if not zypp.Arch(arch).compatible_with (sysarch): arch = None name = ".".join(sp) return name, arch def selectPackage(self, pkg): """Select a given package or package pattern, can be specified with name.arch or name* or *name """ if not self.Z: self.__initialize_zypp() def markPoolItem(obs, pi): if obs == None: pi.status().setToBeInstalled (zypp.ResStatus.USER) else: obs.status().setToBeInstalled (zypp.ResStatus.USER) def cmpEVR(p1, p2): # compare criterion: arch compatibility first, then repo # priority, and version last a1 = p1.arch() a2 = p2.arch() if str(a1) != str(a2): if a1.compatible_with(a2): return -1 else: return 1 # Priority of a repository is an integer value between 0 (the # highest priority) and 99 (the lowest priority) pr1 = int(p1.repoInfo().priority()) pr2 = int(p2.repoInfo().priority()) if pr1 > pr2: return -1 elif pr1 < pr2: return 1 ed1 = p1.edition() ed2 = p2.edition() (e1, v1, r1) = map(str, [ed1.epoch(), ed1.version(), ed1.release()]) (e2, v2, r2) = map(str, [ed2.epoch(), ed2.version(), ed2.release()]) return rpm.labelCompare((e1, v1, r1), (e2, v2, r2)) found = False startx = pkg.startswith("*") endx = pkg.endswith("*") ispattern = startx or endx name, arch = self._splitPkgString(pkg) q = zypp.PoolQuery() q.addKind(zypp.ResKind.package) if ispattern: if startx and not endx: pattern = '%s$' % (pkg[1:]) if endx and not startx: pattern = '^%s' % (pkg[0:-1]) if endx and startx: pattern = '%s' % (pkg[1:-1]) q.setMatchRegex() q.addAttribute(zypp.SolvAttr.name, pattern) elif arch: q.setMatchExact() q.addAttribute(zypp.SolvAttr.name, name) else: q.setMatchExact() q.addAttribute(zypp.SolvAttr.name, pkg) for pitem in sorted( q.queryResults(self.Z.pool()), cmp=lambda x,y: cmpEVR(zypp.asKindPackage(x), zypp.asKindPackage(y)), reverse=True): item = zypp.asKindPackage(pitem) if item.name() in self.excpkgs.keys() and \ self.excpkgs[item.name()] == item.repoInfo().name(): continue if item.name() in self.incpkgs.keys() and \ self.incpkgs[item.name()] != item.repoInfo().name(): continue found = True obspkg = self.whatObsolete(item) if arch: if arch == str(item.arch()): pitem.status().setToBeInstalled (zypp.ResStatus.USER) else: markPoolItem(obspkg, pitem) if not ispattern: break # Can't match using package name, then search from packge # provides infomation if found == False and not ispattern: q.addAttribute(zypp.SolvAttr.provides, pkg) q.addAttribute(zypp.SolvAttr.name,'') for pitem in sorted( q.queryResults(self.Z.pool()), cmp=lambda x,y: cmpEVR(zypp.asKindPackage(x), zypp.asKindPackage(y)), reverse=True): item = zypp.asKindPackage(pitem) if item.name() in self.excpkgs.keys() and \ self.excpkgs[item.name()] == item.repoInfo().name(): continue if item.name() in self.incpkgs.keys() and \ self.incpkgs[item.name()] != item.repoInfo().name(): continue found = True obspkg = self.whatObsolete(item) markPoolItem(obspkg, pitem) break if found: return None else: raise CreatorError("Unable to find package: %s" % (pkg,)) def inDeselectPackages(self, pitem): """check if specified pacakges are in the list of inDeselectPackages """ item = zypp.asKindPackage(pitem) name = item.name() for pkg in self.to_deselect: startx = pkg.startswith("*") endx = pkg.endswith("*") ispattern = startx or endx pkgname, pkgarch = self._splitPkgString(pkg) if not ispattern: if pkgarch: if name == pkgname and str(item.arch()) == pkgarch: return True else: if name == pkgname: return True else: if startx and name.endswith(pkg[1:]): return True if endx and name.startswith(pkg[:-1]): return True return False def deselectPackage(self, pkg): """collect packages should not be installed""" self.to_deselect.append(pkg) def selectGroup(self, grp, include = ksparser.GROUP_DEFAULT): def compareGroup(pitem): item = zypp.asKindPattern(pitem) return item.repoInfo().priority() if not self.Z: self.__initialize_zypp() found = False q = zypp.PoolQuery() q.addKind(zypp.ResKind.pattern) for pitem in sorted(q.queryResults(self.Z.pool()), key=compareGroup): item = zypp.asKindPattern(pitem) summary = "%s" % item.summary() name = "%s" % item.name() if name == grp or summary == grp: found = True pitem.status().setToBeInstalled (zypp.ResStatus.USER) break if found: if include == ksparser.GROUP_REQUIRED: map( lambda p: self.deselectPackage(p), grp.default_packages.keys()) return None else: raise CreatorError("Unable to find pattern: %s" % (grp,)) 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 cost attribute for repos if not self.repo_manager: self.__initialize_repo_manager() if not proxy and url: proxy = get_proxy_for(url) repo = RepositoryStub() repo.name = name repo.id = name repo.proxy = proxy repo.proxy_username = proxy_username repo.proxy_password = proxy_password repo.ssl_verify = ssl_verify repo.nocache = nocache repo.baseurl.append(url) if inc: for pkg in inc: self.incpkgs[pkg] = name if exc: for pkg in exc: self.excpkgs[pkg] = name if mirrorlist: repo.mirrorlist = mirrorlist # Enable gpg check for verifying corrupt packages repo.gpgcheck = 1 if priority is not None: # priority 0 has issue in RepoInfo.setPriority repo.priority = priority + 1 try: repo_info = zypp.RepoInfo() repo_info.setAlias(repo.name) repo_info.setName(repo.name) repo_info.setEnabled(repo.enabled) repo_info.setAutorefresh(repo.autorefresh) repo_info.setKeepPackages(repo.keeppackages) baseurl = zypp.Url(repo.baseurl[0].full) if not ssl_verify: baseurl.setQueryParam("ssl_verify", "no") if proxy: host = urlparse.urlparse(proxy)[1] # scheme, host, path, parm, query, frag = urlparse.urlparse(proxy) proxyinfo = host.rsplit(":", 1) host = proxyinfo[0] port = "80" if len(proxyinfo) > 1: port = proxyinfo[1] if proxy.startswith("socks") and len(proxy.rsplit(':', 1)) == 2: host = proxy.rsplit(':', 1)[0] port = proxy.rsplit(':', 1)[1] # parse user/pass from proxy host proxyinfo = host.rsplit("@", 1) if len(proxyinfo) == 2: host = proxyinfo[1] # Known Issue: If password contains ":", which should be # quoted, for example, use '123%3Aabc' instead of 123:abc userpassinfo = proxyinfo[0].rsplit(":", 1) if len(userpassinfo) == 2: proxy_username = userpassinfo[0] proxy_password = userpassinfo[1] elif len(userpassinfo) == 1: proxy_username = userpassinfo[0] baseurl.setQueryParam ("proxy", host) baseurl.setQueryParam ("proxyport", port) if proxy_username: baseurl.setQueryParam ("proxyuser", proxy_username) if proxy_password: baseurl.setQueryParam ("proxypass", proxy_password) else: baseurl.setQueryParam ("proxy", "_none_") self.repos.append(repo) repo_info.addBaseUrl(baseurl) if repo.priority is not None: repo_info.setPriority(repo.priority) # this hack is used to change zypp credential file location # the default one is $HOME/.zypp, which cause conflicts when # installing some basic packages, and the location doesn't # have any interface actually, so use a tricky way anyway homedir = None if 'HOME' in os.environ: homedir = os.environ['HOME'] os.environ['HOME'] = '/' else: os.environ['HOME'] = '/' self.repo_manager.addRepository(repo_info) # save back the $HOME env if homedir: os.environ['HOME'] = homedir else: del os.environ['HOME'] self.__build_repo_cache(name) except RuntimeError, e: raise CreatorError(str(e)) msger.verbose('repo: %s was added' % name) return repo
class Zypp(BackendPlugin): name = 'zypp' def __init__(self, creator=None): if not isinstance(creator, BaseImageCreator): raise CreatorError("Invalid argument: creator") self.__pkgs_license = {} self.__pkgs_content = {} self.creator = creator self.repos = [] self.to_deselect = [] self.localpkgs = {} self.repo_manager = None self.repo_manager_options = None self.Z = None self.ts = None self.probFilterFlags = [] self.incpkgs = {} self.excpkgs = {} self.has_prov_query = True def doFileLogSetup(self, uid, logfile): # don't do the file log for the livecd as it can lead to open fds # being left and an inability to clean up after ourself pass def closeRpmDB(self): pass def close(self): self.closeRpmDB() if not os.path.exists("/etc/fedora-release") and not os.path.exists( "/etc/meego-release"): for i in range(3, os.sysconf("SC_OPEN_MAX")): try: os.close(i) except: pass if self.ts: self.ts.closeDB() self.ts = None def __del__(self): self.close() def _cleanupRpmdbLocks(self, installroot): # cleans up temporary files left by bdb so that differing # versions of rpm don't cause problems import glob for f in glob.glob(installroot + "/var/lib/rpm/__db*"): os.unlink(f) def setup(self, confpath, installroot): self._cleanupRpmdbLocks(installroot) self.installroot = installroot def whatObsolete(self, pkg): query = zypp.PoolQuery() query.addKind(zypp.ResKind.package) query.addAttribute(zypp.SolvAttr.obsoletes, pkg) query.setMatchExact() for pi in query.queryResults(self.Z.pool()): return pi return None def _splitPkgString(self, pkg): sp = pkg.rsplit(".", 1) name = sp[0] arch = None if len(sp) == 2: arch = sp[1] 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 not zypp.Arch(arch).compatible_with(sysarch): arch = None name = ".".join(sp) return name, arch def selectPackage(self, pkg): """ Select a given package or package pattern, can be specified with name.arch or name* or *name """ if not self.Z: self.__initialize_zypp() def markPoolItem(obs, pi): if obs == None: pi.status().setToBeInstalled(zypp.ResStatus.USER) else: obs.status().setToBeInstalled(zypp.ResStatus.USER) found = False startx = pkg.startswith("*") endx = pkg.endswith("*") ispattern = startx or endx name, arch = self._splitPkgString(pkg) q = zypp.PoolQuery() q.addKind(zypp.ResKind.package) if ispattern: if startx and not endx: pattern = '%s$' % (pkg[1:]) if endx and not startx: pattern = '^%s' % (pkg[0:-1]) if endx and startx: pattern = '%s' % (pkg[1:-1]) q.setMatchRegex() q.addAttribute(zypp.SolvAttr.name, pattern) elif arch: q.setMatchExact() q.addAttribute(zypp.SolvAttr.name, name) else: q.setMatchExact() q.addAttribute(zypp.SolvAttr.name, pkg) for item in sorted(q.queryResults(self.Z.pool()), key=lambda item: str(item.edition()), reverse=True): if item.name() in self.excpkgs.keys() and self.excpkgs[ item.name()] == item.repoInfo().name(): continue if item.name() in self.incpkgs.keys( ) and self.incpkgs[item.name()] != item.repoInfo().name(): continue found = True obspkg = self.whatObsolete(item.name()) if arch: if arch == str(item.arch()): item.status().setToBeInstalled(zypp.ResStatus.USER) else: markPoolItem(obspkg, item) if not ispattern: break # Can't match using package name, then search from packge provides infomation if found == False and not ispattern: q.addAttribute(zypp.SolvAttr.provides, pkg) q.addAttribute(zypp.SolvAttr.name, '') for item in sorted(q.queryResults(self.Z.pool()), key=lambda item: str(item.edition()), reverse=True): if item.name() in self.excpkgs.keys() and self.excpkgs[ item.name()] == item.repoInfo().name(): continue if item.name() in self.incpkgs.keys( ) and self.incpkgs[item.name()] != item.repoInfo().name(): continue found = True obspkg = self.whatObsolete(item.name()) markPoolItem(obspkg, item) break if found: return None else: raise CreatorError("Unable to find package: %s" % (pkg, )) def inDeselectPackages(self, item): """check if specified pacakges are in the list of inDeselectPackages""" name = item.name() for pkg in self.to_deselect: startx = pkg.startswith("*") endx = pkg.endswith("*") ispattern = startx or endx pkgname, pkgarch = self._splitPkgString(pkg) if not ispattern: if pkgarch: if name == pkgname and str(item.arch()) == pkgarch: return True else: if name == pkgname: return True else: if startx and name.endswith(pkg[1:]): return True if endx and name.startswith(pkg[:-1]): return True return False def deselectPackage(self, pkg): """collect packages should not be installed""" self.to_deselect.append(pkg) def selectGroup(self, grp, include=ksparser.GROUP_DEFAULT): if not self.Z: self.__initialize_zypp() found = False q = zypp.PoolQuery() q.addKind(zypp.ResKind.pattern) for item in q.queryResults(self.Z.pool()): summary = "%s" % item.summary() name = "%s" % item.name() if name == grp or summary == grp: found = True item.status().setToBeInstalled(zypp.ResStatus.USER) break if found: if include == ksparser.GROUP_REQUIRED: map(lambda p: self.deselectPackage(p), grp.default_packages.keys()) return None else: raise CreatorError("Unable to find pattern: %s" % (grp, )) 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 cost attribute for repos if not self.repo_manager: self.__initialize_repo_manager() repo = RepositoryStub() repo.name = name repo.id = name repo.proxy = proxy repo.proxy_username = proxy_username repo.proxy_password = proxy_password repo.ssl_verify = ssl_verify repo.baseurl.append(url) if inc: for pkg in inc: self.incpkgs[pkg] = name if exc: for pkg in exc: self.excpkgs[pkg] = name # 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 = mirrorlist # Enable gpg check for verifying corrupt packages repo.gpgcheck = 1 if priority: repo.priority = priority self.repos.append(repo) try: repo_info = zypp.RepoInfo() repo_info.setAlias(repo.name) repo_info.setName(repo.name) repo_info.setEnabled(repo.enabled) repo_info.setAutorefresh(repo.autorefresh) repo_info.setKeepPackages(repo.keeppackages) baseurl = zypp.Url(repo.baseurl[0]) if not ssl_verify: baseurl.setQueryParam("ssl_verify", "no") if proxy: (scheme, host, path, parm, query, frag) = urlparse.urlparse(proxy) proxyinfo = host.split(":") baseurl.setQueryParam("proxy", proxyinfo[0]) port = "80" if len(proxyinfo) > 1: port = proxyinfo[1] baseurl.setQueryParam("proxyport", port) repo_info.addBaseUrl(baseurl) if repo.priority: repo_info.setPriority(repo.priority) self.repo_manager.addRepository(repo_info) self.__build_repo_cache(name) except RuntimeError, e: raise CreatorError(str(e)) msger.verbose('repo: %s was added' % name) return repo
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 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)
tmphandlers = handlers[:] (scheme, host, path, parm, query, frag) = urlparse.urlparse(url.rstrip('/') + '/') if scheme not in ("http", "https", "ftp", "ftps", "file"): raise CreatorError("Error: invalid url %s" % url) if '@' in host: try: user_pass, host = host.split('@', 1) if ':' in user_pass: user, password = user_pass.split(':', 1) except ValueError, e: raise CreatorError('Bad URL: %s' % url) msger.verbose("adding HTTP auth: %s, %s" % (user, password)) auth_handler.add_password(None, host, user, password) tmphandlers.append(auth_handler) url = scheme + "://" + host + path + parm + query + frag if tmphandlers: u2opener = u2.build_opener(*tmphandlers) # try to download repo_eula_url = urlparse.urljoin(url, "LICENSE.txt") repo_eula_path = _check_and_download_url( u2opener, repo_eula_url, os.path.join(repo_lic_dir, repo.id + '_LICENSE.txt')) if repo_eula_path: # found baseurl = url