schroot-0.4/0000755000175000017500000000000012356027631012413 5ustar tagtag00000000000000schroot-0.4/schroot/0000755000175000017500000000000012356027631014074 5ustar tagtag00000000000000schroot-0.4/schroot/chroot.py0000644000175000017500000001226212356027361015747 0ustar tagtag00000000000000from schroot.utils import run_command from schroot.core import log from schroot.errors import SchrootError from contextlib import contextmanager from tempfile import NamedTemporaryFile import shutil import os import subprocess import pipes try: import configparser except ImportError: import ConfigParser as configparser # meh, Python 2 class SchrootCommandError(SchrootError): def __init__(self, value): self.value = value def __str__(self): return repr(self.value) SCHROOT_BASE = "/var/lib/schroot" class SchrootChroot(object): __slots__ = ('session', 'active', 'location') def __init__(self): self.session = None self.active = False self.location = None def _command_prefix(self, user, preserve_environment): command = ['schroot', '-r', '-c', self.session] if user: command += ['-u', user] if preserve_environment: command += ['-p'] command += ['--'] return command @contextmanager def _command(self, cmd, kwargs): user = kwargs.pop("user", None) preserve_environment = kwargs.pop("preserve_environment", False) env = kwargs.pop("env", None) command = self._command_prefix(user, preserve_environment) # short cut if env not set if env is None: command += cmd log.debug(" ".join((str(x) for x in command))) yield command return tmp_dir = os.path.join(self.location, "tmp") with NamedTemporaryFile(dir=tmp_dir) as tmp_file: for key, value in env.iteritems(): tmp_cmd = "export %s=%s" % ( pipes.quote(key), pipes.quote(value)) tmp_file.write(tmp_cmd) tmp_file.write("\n") tmp_file.write('"$@"\n') tmp_file.flush() chroot_tmp_file = os.path.basename(tmp_file.name) chroot_tmp_file = os.path.join("/tmp", chroot_tmp_file) command += ['sh', '-e', chroot_tmp_file] + cmd log.debug(" ".join((str(x) for x in command))) yield command def _safe_run(self, cmd): out, err, ret = run_command(cmd) if ret != 0: raise SchrootCommandError(err) return out, err, ret def copy(self, what, whence, user=None): with self.create_file(whence, user) as f: log.debug("copying %s to %s" % (what, f.name)) with open(what) as src: shutil.copyfileobj(src, f) def get_session_config(self): cfg = configparser.ConfigParser() fil = os.path.join(SCHROOT_BASE, 'session', self.session) if cfg.read(fil) == []: raise SchrootError("SANITY FAILURE") return cfg[self.session] def start(self, chroot_name): out, err, ret = self._safe_run(['schroot', '-b', '-c', chroot_name]) self.session = out.strip() self.active = True log.debug("new session: %s" % (self.session)) out, err, ret = self._safe_run([ 'schroot', '--location', '-c', "session:%s" % self.session ]) self.location = out.strip() def end(self): if self.session is not None: out, err, ret = self._safe_run(['schroot', '-e', '-c', self.session]) def __lt__(self, other): return self.run(other, return_codes=0) def __floordiv__(self, other): return UserProxy(other, self) @contextmanager def create_file(self, whence, user=None): tmp_dir = os.path.join(self.location, "tmp") with NamedTemporaryFile(dir=tmp_dir) as tmp_file: chroot_tmp_file = os.path.basename(tmp_file.name) chroot_tmp_file = os.path.join("/tmp", chroot_tmp_file) log.debug("creating %s" % (tmp_file.name)) yield tmp_file tmp_file.flush() self.check_call(['cp', chroot_tmp_file, whence], user=user) def run(self, cmd, **kwargs): with self._command(cmd, kwargs) as command: return run_command(command, **kwargs) def call(self, cmd, **kwargs): with self._command(cmd, kwargs) as command: return subprocess.call(command, **kwargs) def check_call(self, cmd, **kwargs): with self._command(cmd, kwargs) as command: return subprocess.check_call(command, **kwargs) def check_output(self, cmd, **kwargs): with self._command(cmd, kwargs) as command: return subprocess.check_output(command, **kwargs) def Popen(self, cmd, **kwargs): with self._command(cmd, kwargs) as command: return subprocess.Popen(command, **kwargs) class UserProxy(SchrootChroot): __slots__ = ('user') def __init__(self, user, other): super(UserProxy, self).__init__() self.user = user for entry in other.__slots__: setattr(self, entry, getattr(other, entry)) def run(self, cmd, return_codes=None): return super(UserProxy, self).run(cmd, user=self.user, return_codes=return_codes) @contextmanager def schroot(name): ch = SchrootChroot() try: ch.start(name) yield ch finally: ch.end() schroot-0.4/schroot/__init__.py0000644000175000017500000000013012356027372016201 0ustar tagtag00000000000000from schroot.chroot import schroot # noqa __appname__ = "schroot" __version__ = "0.4" schroot-0.4/schroot/core.py0000644000175000017500000000051012356027361015372 0ustar tagtag00000000000000import logging log = logging.getLogger('schroot') def set_debug(): log.setLevel(logging.DEBUG) _ch = logging.StreamHandler() _ch.setLevel(logging.DEBUG) _formatter = logging.Formatter( '[%(levelname)s] %(created)f: (%(funcName)s) %(message)s') _ch.setFormatter(_formatter) log.addHandler(_ch) schroot-0.4/schroot/utils.py0000644000175000017500000000173012356027361015607 0ustar tagtag00000000000000import subprocess import shlex def run_command(command, stdin=None, encoding='utf-8', return_codes=None, **kwargs): if not isinstance(command, list): command = shlex.split(command) try: pipe = subprocess.Popen(command, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs) except OSError: return (None, None, -1) kwargs = {} if stdin: kwargs['input'] = stdin.read() (output, stderr) = (x.decode(encoding) for x in pipe.communicate(**kwargs)) if return_codes is not None: if not isinstance(return_codes, tuple): return_codes = (return_codes, ) if pipe.returncode not in return_codes: raise SchrootCommandError("Bad return code %d" % pipe.returncode) return (output, stderr, pipe.returncode) schroot-0.4/schroot/errors.py0000644000175000017500000000005212356027361015757 0ustar tagtag00000000000000 class SchrootError(Exception): pass schroot-0.4/setup.py0000755000175000017500000000065712356027361014140 0ustar tagtag00000000000000from schroot import __appname__, __version__ from setuptools import setup long_description = "" setup( name=__appname__, version=__version__, scripts=[], packages=[ 'schroot', ], author="Paul Tagliamonte", author_email="tag@pault.ag", long_description=long_description, description='schroot chroot schroots!', license="Expat", url="http://pault.ag/", platforms=['any'], ) schroot-0.4/schroot.egg-info/0000755000175000017500000000000012356027631015566 5ustar tagtag00000000000000schroot-0.4/schroot.egg-info/PKG-INFO0000644000175000017500000000032512356027630016662 0ustar tagtag00000000000000Metadata-Version: 1.0 Name: schroot Version: 0.4 Summary: schroot chroot schroots! Home-page: http://pault.ag/ Author: Paul Tagliamonte Author-email: tag@pault.ag License: Expat Description: UNKNOWN Platform: any schroot-0.4/schroot.egg-info/SOURCES.txt0000644000175000017500000000037312356027630017454 0ustar tagtag00000000000000LICENSE MANIFEST.in README.md setup.py schroot/__init__.py schroot/chroot.py schroot/core.py schroot/errors.py schroot/utils.py schroot.egg-info/PKG-INFO schroot.egg-info/SOURCES.txt schroot.egg-info/dependency_links.txt schroot.egg-info/top_level.txtschroot-0.4/schroot.egg-info/top_level.txt0000644000175000017500000000001012356027630020306 0ustar tagtag00000000000000schroot schroot-0.4/schroot.egg-info/dependency_links.txt0000644000175000017500000000000112356027630021633 0ustar tagtag00000000000000 schroot-0.4/PKG-INFO0000644000175000017500000000032512356027631013510 0ustar tagtag00000000000000Metadata-Version: 1.0 Name: schroot Version: 0.4 Summary: schroot chroot schroots! Home-page: http://pault.ag/ Author: Paul Tagliamonte Author-email: tag@pault.ag License: Expat Description: UNKNOWN Platform: any schroot-0.4/LICENSE0000644000175000017500000000200012356027361013410 0ustar tagtag00000000000000Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. schroot-0.4/MANIFEST.in0000644000175000017500000000004212356027361014145 0ustar tagtag00000000000000include README.md include LICENSE schroot-0.4/setup.cfg0000644000175000017500000000007312356027631014234 0ustar tagtag00000000000000[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 schroot-0.4/README.md0000644000175000017500000000024412356027361013672 0ustar tagtag00000000000000Schroot ------- `python-schroot` is a `schroot(1)` wrapper for Python. This currently just wraps the binary, so be sure you have `schroot(1)` properly installed.