-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hello all,
I was poking around in the mock source last week and did some minor refactoring, a couple of name-changes and tried out the rpmlint request. Attached below is a CVS diff of my mock.py with the head of CVS. Please review and comment. A quick summary of the changes: 1. Changed version to 0.7. 2. Added code to avoid exec'ing mount for proc, sys, and dev/pts if we've already done it 3. Oh yeah, added /sys to chroot mount 4. Refactoring: renamed _mount to _mountall, created _mount routine that is called by _mountall 5. Renamed _umount_by_file to _umountall 6. Added code to run rpmlint 7. Added elevate/drop around raw chroot command I'd especially like some thought on #7, since any time you elevate and drop you can introduce a security hole and I freely admit that I'm not always thinking security first. If I don't get any push-back (or if I do and then get things resolved), I'll commit these later this week. Clark -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.4 (GNU/Linux) Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org iD8DBQFEu6y9Hyuj/+TTEp0RAgumAJ9STO3Qc/7Ca4xYNdIAifcKs4oPvACgqpDD zOm5eNJ1Gwsgc4KqhS8WW0s= =0mBy -----END PGP SIGNATURE-----
Index: mock.py =================================================================== RCS file: /cvs/fedora/mock/mock.py,v retrieving revision 1.55 diff -u -r1.55 mock.py --- mock.py 17 Jul 2006 15:04:00 -0000 1.55 +++ mock.py 17 Jul 2006 15:15:16 -0000 @@ -31,7 +31,7 @@ from optparse import OptionParser -__VERSION__ = '0.6' +__VERSION__ = '0.7' def error(msg): print >> sys.stderr, msg @@ -162,12 +162,18 @@ cfgout.write('statedir = %s\n' % self.statedir) cfgout.flush() cfgout.close() - + + # note that we haven't mounted anything (yet) + self._mounted = 0 + self.run_rpmlint = config['run_rpmlint'] + def elevate(self): + "elevate privileges by changing to privileged uid" self.debug("elevate: setting uid to %d" % self.highuid) os.setreuid(self.highuid, self.lowuid) def drop(self): + "drop privileges by changing to unprivileged uid" self.debug("drop: setting uid to %d" % self.lowuid) os.setreuid(self.lowuid, self.highuid) @@ -293,7 +299,7 @@ # mock-helper yum --installroot=rootdir cmd basecmd = '%s --installroot %s' % (self.config['yum'], self.rootdir) - self._mount() # check it again + self._mountall() # check it again command = '%s %s' % (basecmd, cmd) self.debug("yum: command %s" % command) @@ -308,7 +314,7 @@ """take an srpm, install it, rebuild it to srpm, return chroot-local path to the resulting srpm""" - self._mount() # check it again + self._mountall() # check it again bd_out = '%s%s' % (self.rootdir, self.builddir) # init build_dir self._build_dir_setup() @@ -366,6 +372,10 @@ arg_string = arg_string + " " + "'%s'" % item + # if running rpmlint add it to the transaction set + if self.run_rpmlint: + arg_string = arg_string + " 'rpmlint'" + # everything exists, okay, install them all. # pass build reqs (as strings) to installer if arg_string != "": @@ -412,13 +422,24 @@ for item in packages: shutil.copy2(item, self.resultdir) + if self.run_rpmlint: + self.rpmlint(packages) - + def rpmlint(self, packages): + """Run the rpmlint utility on the list of input packages and append the output + to an rpmlint log file""" + cmd = "rpmlint -iv %s" % " ".join(packages) + (retval, output) = self.do_elevated(cmd) + lintlog = open(os.path.join(self.resultdir, "rpmlint.log"), "w+") + lintlog.write(output) + lintlog.close() + return (retval, output) + def close(self): """unmount things and clean up a bit""" self.root_log("Cleaning up...") self.state("ending") - self._umount_by_file() + self._umountall() self._build_log.close() self.state("done") self.root_log("Done.") @@ -438,45 +459,43 @@ except OSError, e: raise Error, "Could not create dir %s. Error: %s" % (path, e) - def _mount(self): - """mount proc and devpts into chroot""" + def _mount(self, type, device, path): + "mount a device, given a filesystem type and a path" + mntpath = os.path.join(self.rootdir, path) + self._ensure_dir(mntpath) + self.debug("mounting %s as %s" % (device, mntpath)) + command = '%s -n -t %s %s %s' % (self.config['mount'], type, device, mntpath) mf = os.path.join(self.statedir, 'mounted-locations') - track = open(mf, 'w+') - - # make the procdir if we don't have it - # mount up proc - procdir = os.path.join(self.rootdir, 'proc') - self._ensure_dir(procdir) - - self.debug("mounting proc in %s" % procdir) - command = '%s -n -t proc proc %s/proc' % (self.config['mount'], - self.rootdir) - track.write('proc\n') (retval, output) = self.do_elevated(command) - track.flush() - if retval != 0: if output.find('already mounted') == -1: # probably won't work in other LOCALES - error("could not mount proc error was: %s" % output) - - # devpts - # - devptsdir = os.path.join(self.rootdir, 'dev/pts') - self._ensure_dir(devptsdir) - self.debug("mounting devpts in %s" % devptsdir) - command = '%s -n -t devpts devpts %s' % (self.config['mount'], devptsdir) - track.write('dev/pts\n') - (retval, output) = self.do_elevated(command) - track.flush() + estr = "could not mount %s. Error was: %s" % (path, output) + error(estr) + raise RootError, estr + track = open(mf, 'w+') + track.write('%s\n' % path) track.close() - - if retval != 0: - if output.find('already mounted') == -1: # probably won't work in other LOCALES - raise RootError, "could not mount /dev/pts error was: %s" % output + def _mountall(self): + """mount proc, sys and devpts into chroot""" + + # if we've already mounted these guys, then just return + if self._mounted: + return + + # mount /proc + self._mount('proc', 'proc', 'proc') + + # mount /dev/pts + self._mount('devpts', 'dev/pts', 'dev/pts') + + # mount /sys (if we're on a 2.6 kernel) + if os.uname()[2].find('2.6') == 0: + self._mount('sysfs', 'sys', 'sys') + + self._mounted = 1 def _umount(self, path): - item = '%s/%s' % (self.rootdir, path) command = '%s -n %s' % (self.config['umount'], item) (retval, output) = self.do_elevated(command) @@ -486,8 +505,9 @@ raise RootError, "could not umount %s error was: %s" % (path, output) - def _umount_by_file(self): - + def _umountall(self): + "undo the results of _mountall (umount proc,sys, and dev/pts)" + mf = os.path.join(self.statedir, 'mounted-locations') if not os.path.exists(mf): return @@ -497,13 +517,10 @@ track.close() for item in lines: - item = item.replace('\n','') - if len(item.strip()) < 1: + item = item.strip() + if len(item) < 1: continue - - self.elevate() self._umount(item) - self.drop() # poof, no more file if os.path.exists(mf): @@ -651,7 +668,7 @@ os.path.join(self.rootdir, 'etc/yum.repos.d')]: self._ensure_dir(item) - self._mount() + self._mountall() # we need stuff devices = [('null', 'c', '1', '3', '666'), @@ -783,7 +800,7 @@ """prep the chroot for building packages""" self._make_our_user() self._build_dir_setup() - self._mount() # check it again + self._mountall() # check it again def command_parse(): """return options and args from parsing the command line""" @@ -818,7 +835,9 @@ default=False, help="Turn on build-root caching") parser.add_option("--rebuildcache", action ="store_true", dest="rebuild_cache", default=False, help="Force rebuild of build-root cache") - + parser.add_option("--rpmlint", action = "store_true", dest="run_rpmlint", + default=False, help="Run rpmlint on rpms after a build") + return parser.parse_args() def setup_default_config_opts(config_opts): @@ -871,6 +890,8 @@ config_opts['quiet'] = options.quiet config_opts['use_cache'] = options.use_cache config_opts['rebuild_cache'] = options.rebuild_cache + config_opts['run_rpmlint'] = options.run_rpmlint + if config_opts['rebuild_cache']: config_opts['use_cache'] = True @@ -903,14 +924,16 @@ def do_run_cmd(config_opts, cmd, env='', raw_chroot=0): my = Root(config_opts) my.debug("executing: %s" % cmd) - my._mount() + my._mountall() if raw_chroot: cmd = '%s %s %s %s' % (env, config_opts['chroot'], my.rootdir, cmd) + my.elevate() os.system(cmd) + my.drop() else: my.do_chroot(cmd, True) my.close() - my.debug('finished chroot command') + my.debug('finished: %s' % cmd) def ensure_filetype_srpm(srpms): for srpm in srpms:
-- Fedora-buildsys-list mailing list Fedora-buildsys-list@redhat.com https://www.redhat.com/mailman/listinfo/fedora-buildsys-list