from . import _pakfire
from . import base
-from . import cgroup
+from . import cgroups
from . import config
from . import downloaders
from . import logger
"""
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)
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,
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()
# 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")
arch=self.builder.arch,
)
- self.setup()
-
@property
def environ(self):
env = MINIMAL_ENVIRONMENT.copy()
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:
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():
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