#include <libintl.h>
#include <locale.h>
+#include <sys/mount.h>
#include <solv/solver.h>
Py_RETURN_FALSE;
}
+static PyObject* _pakfire_mount(PyObject* self, PyObject* args, PyObject* kwds) {
+ char* kwlist[] = {
+ "path",
+ "target",
+ "type",
+ "flags",
+ "options",
+ NULL,
+ };
+
+ const char* path = NULL;
+ const char* target = NULL;
+ const char* type = NULL;
+ int flags = 0;
+ const char* options = NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "ss|zis", kwlist,
+ &path, &target, &type, &flags, &options))
+ return NULL;
+
+ int r = mount(path, target, type, flags, options);
+ if (r) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ return NULL;
+ }
+
+ Py_RETURN_NONE;
+}
+
+static PyObject* _pakfire_umount(PyObject* self, PyObject* args) {
+ const char* path = NULL;
+
+ if (!PyArg_ParseTuple(args, "s", &path))
+ return NULL;
+
+ int r = umount(path);
+ if (r) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ return NULL;
+ }
+
+ Py_RETURN_NONE;
+}
+
static PyMethodDef pakfireModuleMethods[] = {
{"performance_index", (PyCFunction)performance_index, METH_VARARGS, NULL},
{"version_compare", (PyCFunction)version_compare, METH_VARARGS, NULL},
{"sync", (PyCFunction)_sync, METH_NOARGS, NULL},
{"native_arch", (PyCFunction)_pakfire_native_arch, METH_NOARGS, NULL },
{"arch_supported_by_host", (PyCFunction)_pakfire_arch_supported_by_host, METH_VARARGS, NULL },
+ {"mount", (PyCFunction)_pakfire_mount, METH_VARARGS|METH_KEYWORDS, NULL },
+ {"umount", (PyCFunction)_pakfire_umount, METH_VARARGS, NULL },
{ NULL, NULL, 0, NULL }
};
PyDict_SetItemString(d, "SOLVER_FLAG_SPLITPROVIDES", Py_BuildValue("i", SOLVER_FLAG_SPLITPROVIDES));
PyDict_SetItemString(d, "SOLVER_FLAG_IGNORE_RECOMMENDED", Py_BuildValue("i", SOLVER_FLAG_IGNORE_RECOMMENDED));
+ // Mount Flags
+ if (PyModule_AddIntConstant(module, "MS_NOATIME", MS_NOATIME))
+ return NULL;
+
+ if (PyModule_AddIntConstant(module, "MS_NODEV", MS_NODEV))
+ return NULL;
+
+ if (PyModule_AddIntConstant(module, "MS_NOEXEC", MS_NOEXEC))
+ return NULL;
+
+ if (PyModule_AddIntConstant(module, "MS_RDONLY", MS_RDONLY))
+ return NULL;
+
+ if (PyModule_AddIntConstant(module, "MS_RELATIME", MS_RELATIME))
+ return NULL;
+
+ if (PyModule_AddIntConstant(module, "MS_STRICTATIME", MS_STRICTATIME))
+ return NULL;
+
+ if (PyModule_AddIntConstant(module, "MS_BIND", MS_BIND))
+ return NULL;
+
+ if (PyModule_AddIntConstant(module, "MS_REMOUNT", MS_REMOUNT))
+ return NULL;
+
return module;
}
from . import logger
from . import packages
from . import repository
-from . import shell
from . import util
import logging
# Settings array.
self.settings = {
"enable_ccache" : self.config.get_bool("builder", "use_ccache", True),
- "buildroot_tmpfs" : self.config.get_bool("builder", "use_tmpfs", False),
+ "buildroot_tmpfs" : self.config.get_bool("builder", "use_tmpfs", True),
}
# Add settings from keyword arguments
def __enter__(self):
self.log.debug("Entering %s" % self.path)
- # Mount the directories
- try:
- self._mountall()
- except OSError as e:
- if e.errno == 30: # Read-only FS
- raise BuildError("Buildroot is read-only: %s" % self.path)
-
- # Raise all other errors
- raise
+ # Mount the build environment
+ self._mount()
# Setup domain name resolution in chroot
self.setup_dns()
self.cgroup = None
# Umount the build environment
- self._umountall()
+ self._umount()
# Delete everything
self._destroy()
if os.path.exists(self.path):
util.rm(self.path)
- @property
- def mountpoints(self):
- mountpoints = []
+ def _mount(self):
+ """
+ Mounts the build environment
+ """
+ os.makedirs(self.path)
- # Make root as a tmpfs if enabled.
+ # Mount ramdisk if enabled
if self.settings.get("buildroot_tmpfs"):
- mountpoints += [
- ("pakfire_root", "/", "tmpfs", "defaults"),
- ]
+ _pakfire.mount("pakfire_root", self.path, "tmpfs")
- # If ccache support is requested, we bind mount the cache.
+ # Bind-mount the ccache if enabled
if self.settings.get("enable_ccache"):
- # Create ccache cache directory if it does not exist.
if not os.path.exists(CCACHE_CACHE_DIR):
os.makedirs(CCACHE_CACHE_DIR)
- mountpoints += [
- (CCACHE_CACHE_DIR, "/var/cache/ccache", "bind", "bind"),
- ]
-
- return mountpoints
-
- def _mountall(self):
- self.log.debug("Mounting environment")
-
- for src, dest, fs, options in self.mountpoints:
- mountpoint = self.chrootPath(dest)
- if options:
- options = "-o %s" % options
-
- # Eventually create mountpoint directory
- if not os.path.exists(mountpoint):
- os.makedirs(mountpoint)
-
- self.execute_root("mount -n -t %s %s %s %s" % (fs, options, src, mountpoint), shell=True)
+ os.makedirs("%s/var/cache/ccache" % self.path)
- def _umountall(self):
- self.log.debug("Umounting environment")
+ _pakfire.mount(CCACHE_CACHE_DIR, "%s/var/cache/ccache" % self.path,
+ flags=_pakfire.MS_BIND)
- mountpoints = []
- for src, dest, fs, options in reversed(self.mountpoints):
- dest = self.chrootPath(dest)
-
- if not dest in mountpoints:
- mountpoints.append(dest)
-
- while mountpoints:
- for mp in mountpoints:
- try:
- self.execute_root("umount -n %s" % mp, shell=True)
- except ShellEnvironmentError:
- pass
+ def _umount(self):
+ """
+ Umounts the build environment
+ """
+ mountpoints = (
+ "%s/var/cache/ccache" % self.path,
+ self.path,
+ )
- if not os.path.ismount(mp):
- mountpoints.remove(mp)
+ for mp in mountpoints:
+ _pakfire.umount(mp)
def copyin(self, file_out, file_in):
if file_in.startswith("/"):
for i in ("/etc/resolv.conf", "/etc/hosts"):
self.copyin(i, i)
- def execute_root(self, command, **kwargs):
- """
- Executes the given command outside the build chroot.
- """
- shellenv = shell.ShellExecuteEnvironment(command, logger=self.log, **kwargs)
- shellenv.execute()
-
- return shellenv
-
class BuilderContext(object):
def __init__(self, builder):