]> git.ipfire.org Git - pakfire.git/blobdiff - python/pakfire/builder.py
Create an extra namespace for build environments and private network.
[pakfire.git] / python / pakfire / builder.py
index 16cef3840c223961536ae58cf5bc6ad10e531fbe..5cb00aab7c524ab92a08fa0f5be8935e5cb69cf1 100644 (file)
@@ -69,7 +69,7 @@ class BuildEnviron(object):
        # The version of the kernel this machine is running.
        kernel_version = os.uname()[2]
 
-       def __init__(self, pakfire, filename=None, distro_name=None, build_id=None, logfile=None, release_build=True):
+       def __init__(self, pakfire, filename=None, distro_name=None, build_id=None, logfile=None, release_build=True, **kwargs):
                self.pakfire = pakfire
 
                # Check if the given pakfire instance is of the correct type.
@@ -117,13 +117,23 @@ class BuildEnviron(object):
                        "enable_icecream"     : self.config.get_bool("builder", "use_icecream", False),
                        "sign_packages"       : False,
                        "buildroot_tmpfs"     : self.config.get_bool("builder", "use_tmpfs", False),
+                       "private_network"     : self.config.get_bool("builder", "private_network", False),
                }
 
+               # Get ccache settings.
+               if self.settings.get("enable_ccache", False):
+                       self.settings.update({
+                               "ccache_compress" : self.config.get_bool("ccache", "compress", True),
+                       })
+
                # Try to get the configured host key. If it is available,
                # we will automatically sign all packages with it.
                if self.keyring.get_host_key(secret=True):
                        self.settings["sign_packages"] = True
 
+               # Add settings from keyword arguments.
+               self.settings.update(kwargs)
+
                # Where do we put the result?
                self.resultdir = os.path.join(self.pakfire.path, "result")
 
@@ -158,6 +168,14 @@ class BuildEnviron(object):
        def start(self):
                assert not self.pakfire.initialized, "Pakfire has already been initialized"
 
+               # Unshare namepsace.
+               # If this fails because the kernel has no support for CLONE_NEWIPC or CLONE_NEWUTS,
+               # we try to fall back to just set CLONE_NEWNS.
+               try:
+                       _pakfire.unshare(_pakfire.SCHED_CLONE_NEWNS|_pakfire.SCHED_CLONE_NEWIPC|_pakfire.SCHED_CLONE_NEWUTS)
+               except RuntimeError, e:
+                       _pakfire.unshare(_pakfire.SCHED_CLONE_NEWNS)
+
                # Mount the directories.
                self._mountall()
 
@@ -167,6 +185,10 @@ class BuildEnviron(object):
                # Initialize pakfire instance.
                self.pakfire.initialize()
 
+               # Optionally enable private networking.
+               if self.settings.get("private_network", None):
+                       _pakfire.unshare(_pakfire.SCHED_CLONE_NEWNET)
+
                # Populate /dev.
                self.populate_dev()
 
@@ -572,6 +594,7 @@ class BuildEnviron(object):
                        ("pakfire_tmpfs", "/dev",      "tmpfs", "mode=755,nosuid"),
                        ("/dev/pts",      "/dev/pts",  "bind",  "bind"),
                        ("pakfire_tmpfs", "/run",      "tmpfs", "mode=755,nosuid,nodev"),
+                       ("pakfire_tmpfs", "/tmp",      "tmpfs", "mode=755,nosuid,nodev"),
                ]
 
                # If selinux is enabled.
@@ -614,6 +637,15 @@ class BuildEnviron(object):
                # Inherit environment from distro
                env.update(self.pakfire.distro.environ)
 
+               # ccache environment settings
+               if self.settings.get("enable_ccache", False):
+                       compress = self.settings.get("ccache_compress", False)
+                       if compress:
+                               env["CCACHE_COMPRESS"] = "1"
+
+                       # Let ccache create its temporary files in /tmp.
+                       env["CCACHE_TEMPDIR"] = "/tmp"
+
                # Icecream environment settings
                if self.settings.get("enable_icecream", False):
                        # Set the toolchain path
@@ -752,7 +784,6 @@ class BuildEnviron(object):
 
                build_command = " ".join(build_command)
 
-               error = False
                try:
                        self.execute(build_command, logger=self.log)
 
@@ -761,12 +792,15 @@ class BuildEnviron(object):
                                self.install_test()
 
                except ShellEnvironmentError:
-                       error = True
                        self.log.error(_("Build failed"))
 
+               except KeyboardInterrupt:
+                       self.log.error(_("Build interrupted"))
+
+                       raise
+
                # Catch all other errors.
                except:
-                       error = True
                        self.log.error(_("Build failed."), exc_info=True)
 
                else: