repo/commit: Add support for --selinux-policy-from-base

The [dev-overlay](https://github.com/coreos/coreos-assembler/blob/332c6ab3b91778d904224c3c960d9cc4739d60bd/src/cmd-dev-overlay)
script shipped in coreos-assembler mostly exists to deal
with the nontrivial logic around SELinux policy.  Let's make
the use case of "commit some binaries overlaying a base tree, using
the base's selinux policy" just require a magical
`--selinux-policy-from-base` argument to `ostree commit`.

A new C API was added to implement this in the case of `--tree=ref`;
when the base directory is already checked out, we can just reuse
the existing logic that `--selinux-policy` was using.

Requires: https://github.com/ostreedev/ostree/pull/2039
This commit is contained in:
Colin Walters committed 2020-03-24 16:34:26 +00:00
1 parent 41d3dfa7b8
commit b3bbbd1542
7 files changed
+121 -16

No files matched your search

+57 -1
View File
@@ -4227,9 +4227,11 @@ ostree_repo_commit_modifier_unref (OstreeRepoCommitModifier *modifier)
if (modifier->xattr_destroy)
modifier->xattr_destroy (modifier->xattr_user_data);
g_clear_object (&modifier->sepolicy);
g_clear_pointer (&modifier->devino_cache, (GDestroyNotify)g_hash_table_unref);
g_clear_object (&modifier->sepolicy);
(void) glnx_tmpdir_delete (&modifier->sepolicy_tmpdir, NULL, NULL);
g_free (modifier);
return;
}
@@ -4279,6 +4281,60 @@ ostree_repo_commit_modifier_set_sepolicy (OstreeRepoCommitModifier
modifier->sepolicy = sepolicy ? g_object_ref (sepolicy) : NULL;
}
/**
* ostree_repo_commit_modifier_set_sepolicy_from_commit:
* @modifier: Commit modifier
* @repo: OSTree repo containing @rev
* @rev: Find SELinux policy from this base commit
* @cancellable:
* @error:
*
* In many cases, one wants to create a "derived" commit from base commit.
* SELinux policy labels are part of that base commit. This API allows
* one to easily set up SELinux labeling from a base commit.
*/
gboolean
ostree_repo_commit_modifier_set_sepolicy_from_commit (OstreeRepoCommitModifier *modifier,
OstreeRepo *repo,
const char *rev,
GCancellable *cancellable,
GError **error)
{
GLNX_AUTO_PREFIX_ERROR ("setting sepolicy from commit", error);
g_autofree char *commit = NULL;
g_autoptr(GFile) root = NULL;
if (!ostree_repo_read_commit (repo, rev, &root, &commit, cancellable, error))
return FALSE;
const char policypath[] = "usr/etc/selinux";
g_autoptr(GFile) policyroot = g_file_get_child (root, policypath);
if (!g_file_query_exists (policyroot, NULL))
return TRUE; /* No policy, nothing to do */
GLnxTmpDir tmpdir = {0,};
if (!glnx_mkdtemp ("ostree-commit-sepolicy-XXXXXX", 0700, &tmpdir, error))
return FALSE;
if (!glnx_shutil_mkdir_p_at (tmpdir.fd, "usr/etc", 0755, cancellable, error))
return FALSE;
OstreeRepoCheckoutAtOptions coopts = {0,};
coopts.mode = OSTREE_REPO_CHECKOUT_MODE_USER;
coopts.subpath = glnx_strjoina ("/", policypath);
if (!ostree_repo_checkout_at (repo, &coopts, tmpdir.fd, policypath, commit, cancellable, error))
return glnx_prefix_error (error, "policy checkout");
g_autoptr(OstreeSePolicy) policy = ostree_sepolicy_new_at (tmpdir.fd, cancellable, error);
if (!policy)
return glnx_prefix_error (error, "reading policy");
ostree_repo_commit_modifier_set_sepolicy (modifier, policy);
/* Transfer ownership */
modifier->sepolicy_tmpdir = tmpdir;
tmpdir.initialized = FALSE;
return TRUE;
}
/**
* ostree_repo_commit_modifier_set_devino_cache:
* @modifier: Modifier