From 58f2d96124d62a77e9a795a7506a47db19b0bd58 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Thu, 9 Jun 2022 17:18:00 +0200 Subject: [PATCH] ostree checkout: Support --composefs to create a composefs image --- src/ostree/ot-builtin-checkout.c | 73 ++++++++++++++++++++++++++++---- 1 file changed, 64 insertions(+), 9 deletions(-) diff --git a/src/ostree/ot-builtin-checkout.c b/src/ostree/ot-builtin-checkout.c index d69c8b0ba5..e5f53ecb27 100644 --- a/src/ostree/ot-builtin-checkout.c +++ b/src/ostree/ot-builtin-checkout.c @@ -33,6 +33,7 @@ static gboolean opt_user_mode; static gboolean opt_allow_noent; static gboolean opt_disable_cache; static char *opt_subpath; +static gboolean opt_composefs; static gboolean opt_union; static gboolean opt_union_add; static gboolean opt_union_identical; @@ -88,6 +89,7 @@ static GOptionEntry options[] = { { "skip-list", 0, 0, G_OPTION_ARG_FILENAME, &opt_skiplist_file, "File containing list of files to skip", "FILE" }, { "selinux-policy", 0, 0, G_OPTION_ARG_FILENAME, &opt_selinux_policy, "Set SELinux labels based on policy in root filesystem PATH (may be /); implies --force-copy", "PATH" }, { "selinux-prefix", 0, 0, G_OPTION_ARG_STRING, &opt_selinux_prefix, "When setting SELinux labels, prefix all paths by PREFIX", "PREFIX" }, + { "composefs", 0, 0, G_OPTION_ARG_NONE, &opt_composefs, "Check out into a composfs image", NULL }, { NULL } }; @@ -114,19 +116,60 @@ checkout_filter (OstreeRepo *self, } static gboolean -process_one_checkout (OstreeRepo *repo, - const char *resolved_commit, - const char *subpath, - const char *destination, - GCancellable *cancellable, - GError **error) +process_one_checkout (OstreeRepo *repo, + const char *resolved_commit, + const char *subpath, + const char *destination, + OstreeComposefsTarget *composefs_target, + GCancellable *cancellable, + GError **error) { + if (opt_composefs) + { + OstreeRepoCheckoutComposefsOptions checkout_options = { 0 }; + g_autoptr(OstreeComposefsTarget) default_target = NULL; + + if (composefs_target == NULL) + composefs_target = default_target = ostree_composefs_target_new (); + + if (opt_union && opt_union_add) + return glnx_throw (error, "Cannot specify both --union and --union-add"); + if (opt_union && opt_union_identical) + return glnx_throw (error, "Cannot specify both --union and --union-identical"); + if (opt_union_add && opt_union_identical) + return glnx_throw (error, "Cannot specify both --union-add and --union-identical"); + if (opt_union) + checkout_options.overwrite_mode = OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES; + else if (opt_union_add) + checkout_options.overwrite_mode = OSTREE_REPO_CHECKOUT_OVERWRITE_ADD_FILES; + else if (opt_union_identical) + checkout_options.overwrite_mode = OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_IDENTICAL; + + if (opt_whiteouts) + checkout_options.process_whiteouts = TRUE; + if (subpath) + checkout_options.subpath = subpath; + + /* Todo: Apply options */ + + if (!ostree_repo_checkout_composefs (repo, &checkout_options, composefs_target, + resolved_commit, cancellable, error)) + return FALSE; + + if (default_target) + { + if (!ostree_composefs_target_write_at (default_target, + AT_FDCWD, destination, + cancellable, error)) + return FALSE; + } + } /* This strange code structure is to preserve testing * coverage of both `ostree_repo_checkout_tree` and * `ostree_repo_checkout_at` until such time as we have a more * convenient infrastructure for testing C APIs with data. */ - if (opt_disable_cache || opt_whiteouts || opt_require_hardlinks || + else if (opt_disable_cache || opt_whiteouts || opt_require_hardlinks || opt_union_add || opt_force_copy || opt_force_copy_zerosized || opt_bareuseronly_dirs || opt_union_identical || opt_skiplist_file || opt_selinux_policy || opt_selinux_prefix) @@ -260,6 +303,10 @@ process_many_checkouts (OstreeRepo *repo, g_autofree char *revision = NULL; g_autofree char *subpath = NULL; g_autofree char *resolved_commit = NULL; + g_autoptr(OstreeComposefsTarget) composefs = NULL; + + if (opt_composefs) + composefs = ostree_composefs_target_new (); if (opt_from_stdin) { @@ -300,7 +347,7 @@ process_many_checkouts (OstreeRepo *repo, goto out; if (!process_one_checkout (repo, resolved_commit, subpath, target, - cancellable, error)) + composefs, cancellable, error)) { g_prefix_error (error, "Processing tree %s: ", resolved_commit); goto out; @@ -314,6 +361,14 @@ process_many_checkouts (OstreeRepo *repo, goto out; } + if (composefs) + { + if (!ostree_composefs_target_write_at (composefs, + AT_FDCWD, target, + cancellable, error)) + goto out; + } + ret = TRUE; out: return ret; @@ -358,7 +413,7 @@ ostree_builtin_checkout (int argc, char **argv, OstreeCommandInvocation *invocat return FALSE; if (!process_one_checkout (repo, resolved_commit, opt_subpath, - destination, + destination, NULL, cancellable, error)) return FALSE; }