From 94a2804b0af137c64b8bc0ca9f5874023ed570f8 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Wed, 30 Mar 2016 15:35:52 +0200 Subject: [PATCH] compose: support adding external files This will allow to copy arbitrary files into the rootfs, specifying something like: "add-files": [["service.template", "/exports/service.template"], ["config.json.template", "/exports/config.json.template"]] It is quite useful when building a container image. Signed-off-by: Giuseppe Scrivano Closes: #253 Approved by: cgwalters --- docs/manual/treefile.md | 8 +++ src/app/rpmostree-compose-builtin-tree.c | 3 + src/libpriv/rpmostree-postprocess.c | 77 ++++++++++++++++++++++++ src/libpriv/rpmostree-postprocess.h | 6 ++ 4 files changed, 94 insertions(+) diff --git a/docs/manual/treefile.md b/docs/manual/treefile.md index f25e3645df..2a95cac4c4 100644 --- a/docs/manual/treefile.md +++ b/docs/manual/treefile.md @@ -167,3 +167,11 @@ It supports the following parameters: rpm-ostree will not do any special handling of kernel, initrd or the /boot directory. This is useful if the target for the tree is some kind of container which does not have its own kernel. + + * `copy-files`: Array, optional: Copy external files to the rootfs. + + Each array element is an array, whose first member is the source + file name, and the second element is the destination name. The + source file must be in the same directory as the treefile. + + Example: `"add-files": [["bar", "/bar"], ["foo", "/foo"]]` diff --git a/src/app/rpmostree-compose-builtin-tree.c b/src/app/rpmostree-compose-builtin-tree.c index efbb20c775..80039fe637 100644 --- a/src/app/rpmostree-compose-builtin-tree.c +++ b/src/app/rpmostree-compose-builtin-tree.c @@ -796,6 +796,9 @@ rpmostree_compose_builtin_tree (int argc, if (!rpmostree_prepare_rootfs_for_commit (yumroot, treefile, cancellable, error)) goto out; + if (!rpmostree_copy_additional_files (yumroot, self->treefile_context_dirs->pdata[0], treefile, cancellable, error)) + goto out; + if (!rpmostree_check_passwd (repo, yumroot, treefile_dirpath, treefile, cancellable, error)) goto out; diff --git a/src/libpriv/rpmostree-postprocess.c b/src/libpriv/rpmostree-postprocess.c index 675a304d0b..f95601a339 100644 --- a/src/libpriv/rpmostree-postprocess.c +++ b/src/libpriv/rpmostree-postprocess.c @@ -1171,6 +1171,83 @@ rpmostree_rootfs_postprocess_common (int rootfs_fd, return ret; } +/** + * rpmostree_copy_additional_files: + * + * Copy external files, if specified in the configuration file, from + * the context directory to the rootfs. + */ +gboolean +rpmostree_copy_additional_files (GFile *rootfs, + GFile *context_directory, + JsonObject *treefile, + GCancellable *cancellable, + GError **error) +{ + gboolean ret = FALSE; + JsonArray *add = NULL; + guint i, len; + + gs_free char *dest_rootfs_path = g_strconcat (gs_file_get_path_cached (rootfs), ".post", NULL); + gs_unref_object GFile *targetroot = g_file_new_for_path (dest_rootfs_path); + + if (json_object_has_member (treefile, "add-files")) + { + add = json_object_get_array_member (treefile, "add-files"); + len = json_array_get_length (add); + } + else + { + ret = TRUE; + goto out; + } + + for (i = 0; i < len; i++) + { + const char *src, *dest; + + JsonArray *add_el = json_array_get_array_element (add, i); + gs_unref_object GFile *child = NULL; + + if (!add_el) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Element in add-files is not an array"); + goto out; + } + + src = _rpmostree_jsonutil_array_require_string_element (add_el, 0, error); + if (!src) + goto out; + + dest = _rpmostree_jsonutil_array_require_string_element (add_el, 1, error); + if (!dest) + goto out; + + { + gs_unref_object GFile *srcfile = g_file_resolve_relative_path (context_directory, src); + const char *rootfs_path = gs_file_get_path_cached (rootfs); + gs_free char *destpath = g_strconcat (rootfs_path, "/", dest, NULL); + gs_unref_object GFile *destfile = g_file_resolve_relative_path (targetroot, destpath); + gs_unref_object GFile *target_tmpfilesd_parent = g_file_get_parent (destfile); + + g_print ("Adding file '%s'\n", dest); + + if (!gs_file_ensure_directory (target_tmpfilesd_parent, TRUE, cancellable, error)) + goto out; + + if (!g_file_copy (srcfile, destfile, 0, cancellable, NULL, NULL, error)) + { + g_prefix_error (error, "Copying file '%s' into target: ", src); + goto out; + } + } + } + ret = TRUE; + out: + return ret; +} + gboolean rpmostree_treefile_postprocessing (GFile *yumroot, GFile *context_directory, diff --git a/src/libpriv/rpmostree-postprocess.h b/src/libpriv/rpmostree-postprocess.h index b86bd9cf72..d8fb64d399 100644 --- a/src/libpriv/rpmostree-postprocess.h +++ b/src/libpriv/rpmostree-postprocess.h @@ -51,3 +51,9 @@ rpmostree_commit (GFile *rootfs, gboolean enable_selinux, GCancellable *cancellable, GError **error); +gboolean +rpmostree_copy_additional_files (GFile *rootfs, + GFile *context_directory, + JsonObject *treefile, + GCancellable *cancellable, + GError **error);