]> git.ipfire.org Git - pakfire.git/blobdiff - src/pakfire/builder.py
libpakfire: execute: Automatically set personality from arch
[pakfire.git] / src / pakfire / builder.py
index 1f753bb6496476d5d38d8de207326026a4fbc552..ad77d57697e4f0485dc1b917297b7a949fad6809 100644 (file)
@@ -32,7 +32,7 @@ import uuid
 
 from . import _pakfire
 from . import base
-from . import cgroup
+from . import cgroups
 from . import config
 from . import downloaders
 from . import logger
@@ -64,7 +64,7 @@ BUILD_LOG_HEADER = """
 """
 
 class Builder(object):
-       def __init__(self, package=None, arch=None, build_id=None, logfile=None, **kwargs):
+       def __init__(self, arch=None, build_id=None, logfile=None, **kwargs):
                self.config = config.Config("general.conf", "builder.conf")
 
                distro_name = self.config.get("builder", "distro", None)
@@ -105,8 +105,8 @@ class Builder(object):
                if not _pakfire.arch_supported_by_host(self.arch):
                        raise BuildError(_("Cannot build for %s on this host") % self.arch)
 
-               # Initialize a cgroup (if supported)
-               self.cgroup = self.make_cgroup()
+               # Initialize cgroups
+               self.cgroup = self._make_cgroup()
 
                # Unshare namepsace.
                # If this fails because the kernel has no support for CLONE_NEWIPC or CLONE_NEWUTS,
@@ -148,26 +148,11 @@ class Builder(object):
                self.log.debug("Leaving %s" % self.path)
 
                # Kill all remaining processes in the build environment
-               if self.cgroup:
-                       # Move the builder process out of the cgroup.
-                       self.cgroup.migrate_task(self.cgroup.parent, os.getpid())
+               self.cgroup.killall()
 
-                       # Kill all still running processes in the cgroup.
-                       self.cgroup.kill_and_wait()
-
-                       # Remove cgroup and all parent cgroups if they are empty.
-                       self.cgroup.destroy()
-
-                       parent = self.cgroup.parent
-                       while parent:
-                               if not parent.is_empty(recursive=True):
-                                       break
-
-                               parent.destroy()
-                               parent = parent.parent
-
-               else:
-                       util.orphans_kill(self.path)
+               # Destroy the cgroup
+               self.cgroup.destroy()
+               self.cgroup = None
 
                # Umount the build environment
                self._umountall()
@@ -197,25 +182,21 @@ class Builder(object):
                        # If no logile was given, we use the root logger.
                        self.log = logging.getLogger("pakfire")
 
-       def make_cgroup(self):
+       def _make_cgroup(self):
                """
-                       Initialize cgroup (if the system supports it).
+                       Initialises a cgroup so that we can enforce resource limits
+                       and can identify processes belonging to this build environment.
                """
-               if not cgroup.supported():
-                       return
-
-               # Search for the cgroup this process is currently running in.
-               parent_cgroup = cgroup.find_by_pid(os.getpid())
-               if not parent_cgroup:
-                       return
+               # Find our current group
+               parent = cgroups.get_own_group()
 
-               # Create our own cgroup inside the parent cgroup.
-               c = parent_cgroup.create_child_cgroup("pakfire/builder/%s" % self.build_id)
+               # Create a sub-group
+               cgroup = parent.create_subgroup("pakfire-%s" % self.build_id)
 
-               # Attach the pakfire-builder process to the group.
-               c.attach()
+               # Make this process join the new group
+               cgroup.attach_self()
 
-               return c
+               return cgroup
 
        def lock(self):
                filename = os.path.join(self.path, ".lock")
@@ -450,8 +431,6 @@ class BuilderContext(object):
                        arch=self.builder.arch,
                )
 
-               self.setup()
-
        @property
        def environ(self):
                env = MINIMAL_ENVIRONMENT.copy()
@@ -486,24 +465,10 @@ class BuilderContext(object):
 
                return env
 
-       def setup(self, install=None):
-               self.log.info(_("Install packages needed for build..."))
-
-               packages = [
-                       "@Build",
-               ]
-
-               # If we have ccache enabled, we need to extract it
-               # to the build chroot
-               if self.builder.settings.get("enable_ccache"):
-                       packages.append("ccache")
-
-               # Install additional packages
-               if install:
-                       packages += install
-
-               # Logging
-               self.log.debug(_("Installing build requirements: %s") % ", ".join(packages))
+       def _install(self, packages):
+               self.log.debug(_("Installing packages in build environment:"))
+               for package in packages:
+                       self.log.debug("        %s" % package)
 
                # Initialise Pakfire
                with self.pakfire as p:
@@ -522,12 +487,25 @@ class BuilderContext(object):
                        transaction.run()
 
        def build(self, package, private_network=True, shell=True):
+               # Install build environment
+               packages = [
+                       "@Build",
+               ]
+
+               # If we have ccache enabled, we need to install it, too
+               if self.builder.settings.get("enable_ccache"):
+                       packages.append("ccache")
+
+               # Open the package archive
                archive = _pakfire.Archive(self.pakfire, package)
 
                requires = archive.get("dependencies.requires")
+               packages += requires.splitlines()
 
                # Setup the environment including any build dependencies
-               self.setup(install=requires.splitlines())
+               self._install(packages)
+
+               # XXX perform build
 
        def shell(self, install=[]):
                if not util.cli_is_interactive():
@@ -535,16 +513,10 @@ class BuilderContext(object):
                        return
 
                # Install our standard shell packages
-               install += SHELL_PACKAGES
-
-               self.setup(install=install)
+               self._install(SHELL_PACKAGES + install)
 
                command = "/usr/sbin/chroot %s %s %s" % (self.chrootPath(), SHELL_SCRIPT)
 
-               # Add personality if we require one
-               if self.pakfire.distro.personality:
-                       command = "%s %s" % (self.pakfire.distro.personality, command)
-
                for key, val in list(self.environ.items()):
                        command = "%s=\"%s\" " % (key, val) + command