Skip to content

Commit

Permalink
syscontainers: use temporarily CLI ostree for checkouts
Browse files Browse the repository at this point in the history
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 <[email protected]>

Closes: projectatomic#497
Approved by: jlebon
  • Loading branch information
giuseppe committed Jul 26, 2016
1 parent 79f8c78 commit 9166ff5
Showing 1 changed file with 34 additions and 12 deletions.
46 changes: 34 additions & 12 deletions Atomic/syscontainers.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 9166ff5

Please sign in to comment.