From 3c486d4e3b36362c189145336ad23bbdb91a87b5 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Fri, 22 Jul 2016 10:17:35 +0200 Subject: [PATCH] iQIcBAABAgAGBQJXl4HLAAoJECY9bfLhY+Hqep0P/ih/gXvMYZnbUOkgSRi17Dka rooLwowNuHbfjNn+r+eo2C6cl91jUDcyOFlSuk1YNiH2INRams25Ap4a5u7vPkmN 6FiXjXjKHbFYLW7WryevJ5Ac22lfW7bRUM5cb3d3VcwVjvwxJj2BR27e/AxNJZSY V4h7DRl9948W+aFmbtkhBuAOIMttJ8jfwvMevSmNXnvWeW8WygfpPOrDVPg99By0 uNjL/OFR8Gl7zhTsVm5XMh7gxDPSSkYrObitG+6VL6Jtem9/dkiVtHshEQrF3S8W XgZXowJ1+6HXl9H3bX2zGB+n44dtNm10jxxqZhxOQIkNlVrkbP5CieveRNwra8Fl dJ76lLCA14OSLF8ZqrEalyQeqow7EexcW0ikdgHBqerL6rQ/5CRRMd/DpPfXKvkX MVT+7tPl9DVD21PDa7kRHGWkrhT0yjNF+NKAlE2fS8nmnHKV6FE0rnvq1Jfyxkva f4gXfv9WLS1cHHm7ba3ZaqSxv8zCn3QL4CtvzYKHrVXLhoQ2+TYmpVkiaiqffDKq gYcOnR1J12wcqxCIHmk55Kr+/pwJWvW6W4fQo3WauY1EYiD8Vd+Bfeq9Yge/0s5v 6KX4Wzf35+lNQ8hJ3TRszmxKMPGa3GdDvIrcCKF165o1CU42lNpg7T6Ema99vEg+ z7D+ZZ38jXIPtR1zLnef =JzHT -----END PGP SIGNATURE----- syscontainers: use temporarily CLI ostree for checkouts This is required to process Docker whiteouts files in OSTree, which are not enabled by this patch. There is an issue in the way the RepoCheckoutOptions object is mapped by glib, as the C struct is using bit fields that are not supported by the introspection, so use the CLI version of OSTree for now. Signed-off-by: Giuseppe Scrivano Closes: #497 Approved by: jlebon --- Atomic/syscontainers.py | 46 ++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/Atomic/syscontainers.py b/Atomic/syscontainers.py index ec198dda..aa8cc304 100644 --- a/Atomic/syscontainers.py +++ b/Atomic/syscontainers.py @@ -58,6 +58,28 @@ def __init__(self): def get_atomic_config_item(self, config_item): return util.get_atomic_config_item(config_item, atomic_config=self.atomic_config) + def _checkout_layer(self, repo, rootfs_fd, rootfs, rev): + OSTREE_SAFE_GLIB_REPO_CHECKOUT_OPTIONS = False + # There is an issue in the way the RepoCheckoutOptions is mapped by glib, as the C + # struct is using bit fields that are not supported by the introspection. + # Accessing .disable_fsync and .process_whiteouts thus results in a segfault in + # libostree. Re-enable this once it gets fixed. + if OSTREE_SAFE_GLIB_REPO_CHECKOUT_OPTIONS: + options = OSTree.RepoCheckoutOptions() + options.overwrite_mode = OSTree.RepoCheckoutOverwriteMode.UNION_FILES + options.process_whiteouts = True + repo.checkout_tree_at(options, rootfs_fd, rootfs, rev) + else: + util.check_call(["ostree", "--repo=%s" % self._get_ostree_repo_location(), + "checkout", + "--union", + "--whiteouts", + rev, + rootfs], + stdin=DEVNULL, + stdout=DEVNULL, + stderr=DEVNULL) + def set_args(self, args): self.args = args @@ -148,19 +170,17 @@ def _checkout_system_container(self, repo, name, img, deployment, upgrade, value rev = repo.resolve_rev(imagebranch, False)[1] manifest = SystemContainers._get_commit_metadata(repo, rev, "docker.manifest") - options = OSTree.RepoCheckoutOptions() - options.overwrite_mode = OSTree.RepoCheckoutOverwriteMode.UNION_FILES rootfs_fd = None try: rootfs_fd = os.open(rootfs, os.O_DIRECTORY) if manifest is None: - repo.checkout_tree_at(options, rootfs_fd, rootfs, rev) + self._checkout_layer(repo, rootfs_fd, rootfs, rev) else: layers = SystemContainers._get_layers_from_manifest(json.loads(manifest)) for layer in layers: rev_layer = repo.resolve_rev("%s%s" % (OSTREE_OCIIMAGE_PREFIX, layer.replace("sha256:", "")), False)[1] - repo.checkout_tree_at(options, rootfs_fd, rootfs, rev_layer) + self._checkout_layer(repo, rootfs_fd, rootfs, rev_layer) finally: if rootfs_fd: os.close(rootfs_fd) @@ -247,18 +267,20 @@ def _get_system_checkout_path(self): self.get_atomic_config_item(["checkout_path"]) or \ "/var/lib/containers/atomic" - def _get_ostree_repo(self): - if not OSTREE_PRESENT: - return None - + def _get_ostree_repo_location(self): if self.user: home_dir = os.getenv("HOME") - repo_location = os.path.expanduser("%s/ostree/repo" % home_dir) + return os.path.expanduser("%s/ostree/repo" % home_dir) else: - repo_location = os.environ.get("ATOMIC_OSTREE_REPO") or \ - self.get_atomic_config_item(["ostree_repository"]) or \ - "/ostree/repo" + return os.environ.get("ATOMIC_OSTREE_REPO") or \ + self.get_atomic_config_item(["ostree_repository"]) or \ + "/ostree/repo" + + def _get_ostree_repo(self): + if not OSTREE_PRESENT: + return None + repo_location = self._get_ostree_repo_location() repo = OSTree.Repo.new(Gio.File.new_for_path(repo_location)) # If the repository doesn't exist at the specified location, create it