gboolean rpmostree_commit (GFile *rootfs, OstreeRepo *repo, const char *refname, GVariant *metadata, const char *gpg_keyid, gboolean enable_selinux, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; gs_unref_object OstreeMutableTree *mtree = NULL; OstreeRepoCommitModifier *commit_modifier = NULL; gs_free char *parent_revision = NULL; gs_free char *new_revision = NULL; gs_unref_object GFile *root_tree = NULL; gs_unref_object OstreeSePolicy *sepolicy = NULL; gs_fd_close int rootfs_fd = -1; if (!gs_file_open_dir_fd (rootfs, &rootfs_fd, cancellable, error)) goto out; /* hardcode targeted policy for now */ if (enable_selinux) { if (!rpmostree_prepare_rootfs_get_sepolicy (rootfs_fd, ".", &sepolicy, cancellable, error)) goto out; } g_print ("Committing '%s' ...\n", gs_file_get_path_cached (rootfs)); if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error)) goto out; mtree = ostree_mutable_tree_new (); commit_modifier = ostree_repo_commit_modifier_new (0, NULL, NULL, NULL); ostree_repo_commit_modifier_set_xattr_callback (commit_modifier, read_xattrs_cb, NULL, GINT_TO_POINTER (rootfs_fd)); if (sepolicy) { const char *policy_name = ostree_sepolicy_get_name (sepolicy); g_print ("Labeling with SELinux policy '%s'\n", policy_name); ostree_repo_commit_modifier_set_sepolicy (commit_modifier, sepolicy); } if (!ostree_repo_write_directory_to_mtree (repo, rootfs, mtree, commit_modifier, cancellable, error)) goto out; if (!ostree_repo_write_mtree (repo, mtree, &root_tree, cancellable, error)) goto out; if (!ostree_repo_resolve_rev (repo, refname, TRUE, &parent_revision, error)) goto out; if (!ostree_repo_write_commit (repo, parent_revision, "", "", metadata, (OstreeRepoFile*)root_tree, &new_revision, cancellable, error)) goto out; if (gpg_keyid) { g_print ("Signing commit %s with key %s\n", new_revision, gpg_keyid); if (!ostree_repo_sign_commit (repo, new_revision, gpg_keyid, NULL, cancellable, error)) goto out; } ostree_repo_transaction_set_ref (repo, NULL, refname, new_revision); if (!ostree_repo_commit_transaction (repo, NULL, cancellable, error)) goto out; g_print ("%s => %s\n", refname, new_revision); if (!g_getenv ("RPM_OSTREE_PRESERVE_ROOTFS")) (void) gs_shutil_rm_rf (rootfs, NULL, NULL); else g_print ("Preserved %s\n", gs_file_get_path_cached (rootfs)); ret = TRUE; out: return ret; }
gboolean ot_admin_instutil_builtin_selinux_ensure_labeled (int argc, char **argv, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; const char *policy_name; g_autoptr(GFile) subpath = NULL; const char *prefix = NULL; glnx_unref_object OstreeSePolicy *sepolicy = NULL; g_autoptr(GPtrArray) deployments = NULL; OstreeDeployment *first_deployment; GOptionContext *context = NULL; glnx_unref_object OstreeSysroot *sysroot = NULL; g_autoptr(GFile) deployment_path = NULL; context = g_option_context_new ("[SUBPATH PREFIX] - relabel all or part of a deployment"); if (!ostree_admin_option_context_parse (context, options, &argc, &argv, OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER | OSTREE_ADMIN_BUILTIN_FLAG_UNLOCKED, &sysroot, cancellable, error)) goto out; if (!ostree_sysroot_load (sysroot, cancellable, error)) goto out; deployments = ostree_sysroot_get_deployments (sysroot); if (deployments->len == 0) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unable to find a deployment in sysroot"); goto out; } first_deployment = deployments->pdata[0]; deployment_path = ostree_sysroot_get_deployment_directory (sysroot, first_deployment); if (argc >= 2) { subpath = g_file_new_for_path (argv[1]); prefix = argv[2]; } else { subpath = g_object_ref (deployment_path); prefix = ""; } sepolicy = ostree_sepolicy_new (deployment_path, cancellable, error); if (!sepolicy) goto out; policy_name = ostree_sepolicy_get_name (sepolicy); if (policy_name) { g_print ("Relabeling using policy '%s'\n", policy_name); if (!selinux_relabel_dir (sepolicy, subpath, prefix, cancellable, error)) goto out; } else g_print ("No SELinux policy found in deployment '%s'\n", gs_file_get_path_cached (deployment_path)); ret = TRUE; out: if (context) g_option_context_free (context); return ret; }