# Create loop devices in build environment.
#use_loop_devices = true
+# Use private network.
+# Setting this to true will result in the build
+# chroot having its own network - i.e. no network connection
+# to the outside world.
+#private_network = false
+
[ccache]
# Turn on compression to get more files into the cache.
#compress = true
# 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.
"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.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")
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()
# 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()
help=_("Run a shell after a successful build."))
sub_build.add_argument("--no-install-test", action="store_true",
help=_("Do not perform the install test."))
+ sub_build.add_argument("--private-network", action="store_true",
+ help=_("Disable network in container."))
def parse_command_shell(self):
# Implement the "shell" command.
sub_shell.add_argument("-m", "--mode", nargs="?", default="development",
help=_("Mode to run in. Is either 'release' or 'development' (default)."))
+ sub_shell.add_argument("--private-network", action="store_true",
+ help=_("Disable network in container."))
def parse_command_dist(self):
# Implement the "dist" command.
else:
raise FileNotFoundError, pkg
- # Check whether to enable the install test.
- install_test = not self.args.no_install_test
+ # Build argument list.
+ kwargs = {
+ "after_shell" : self.args.after_shell,
+ # Check whether to enable the install test.
+ "install_test" : not self.args.no_install_test,
+ "result_dir" : [self.args.resultdir,],
+ "shell" : True,
+ }
if self.args.mode == "release":
- release_build = True
+ kwargs["release_build"] = True
else:
- release_build = False
+ kwargs["release_build"] = False
+
+ if self.args.private_network:
+ kwargs["private_network"] = True
p = self.create_pakfire()
- p.build(pkg,
- install_test=install_test,
- resultdirs=[self.args.resultdir,],
- shell=True,
- after_shell=self.args.after_shell,
- release_build=release_build,
- )
+ p.build(pkg, **kwargs)
def handle_shell(self):
pkg = None
release_build = False
p = self.create_pakfire()
- p.shell(pkg, release_build=release_build)
+
+ kwargs = {
+ "release_build" : release_build,
+ }
+
+ # Private network
+ if self.args.private_network:
+ kwargs["private_network"] = True
+
+ p.shell(pkg, **kwargs)
def handle_dist(self):
# Get the packages from the command line options
# #
#############################################################################*/
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
#include <Python.h>
#include <locale.h>
+#include <sched.h>
#include <sys/personality.h>
#include "capabilities.h"
{"set_capabilities", (PyCFunction)set_capabilities, METH_VARARGS, NULL},
{"personality", (PyCFunction)_personality, METH_VARARGS, NULL},
{"sync", (PyCFunction)_sync, METH_NOARGS, NULL},
+ {"unshare", (PyCFunction)_unshare, METH_VARARGS, NULL},
{ NULL, NULL, 0, NULL }
};
PyDict_SetItemString(d, "PERSONALITY_LINUX", Py_BuildValue("i", PER_LINUX));
PyDict_SetItemString(d, "PERSONALITY_LINUX32", Py_BuildValue("i", PER_LINUX32));
+ // Namespace stuff
+ PyDict_SetItemString(d, "SCHED_CLONE_NEWIPC", Py_BuildValue("i", CLONE_NEWIPC));
+ PyDict_SetItemString(d, "SCHED_CLONE_NEWPID", Py_BuildValue("i", CLONE_NEWPID));
+ PyDict_SetItemString(d, "SCHED_CLONE_NEWNET", Py_BuildValue("i", CLONE_NEWNET));
+ PyDict_SetItemString(d, "SCHED_CLONE_NEWNS", Py_BuildValue("i", CLONE_NEWNS));
+ PyDict_SetItemString(d, "SCHED_CLONE_NEWUTS", Py_BuildValue("i", CLONE_NEWUTS));
+
// Add constants for relations
PyDict_SetItemString(d, "REL_EQ", Py_BuildValue("i", REL_EQ));
PyDict_SetItemString(d, "REL_LT", Py_BuildValue("i", REL_LT));
# #
#############################################################################*/
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
#include <Python.h>
+#include <errno.h>
+#include <sched.h>
#include <sys/personality.h>
#include <unistd.h>
+#include "config.h"
#include "util.h"
PyObject *_personality(PyObject *self, PyObject *args) {
Py_RETURN_NONE;
}
+PyObject *_unshare(PyObject *self, PyObject *args) {
+ int flags = 0;
+
+ if (!PyArg_ParseTuple(args, "i", &flags)) {
+ return NULL;
+ }
+
+ int ret = unshare(flags);
+ if (ret < 0) {
+ return PyErr_SetFromErrno(PyExc_RuntimeError);
+ }
+
+ return Py_BuildValue("i", ret);
+}
+
PyObject *version_compare(PyObject *self, PyObject *args) {
Pool *pool;
const char *evr1, *evr2;
extern PyObject *_personality(PyObject *self, PyObject *args);
extern PyObject *_sync(PyObject *self, PyObject *args);
+extern PyObject *_unshare(PyObject *self, PyObject *args);
extern PyObject *version_compare(PyObject *self, PyObject *args);
#endif