New upstream version 2021.5

This commit is contained in:
Simon McVittie committed 2021-10-10 17:35:12 +01:00
commit 75e180c3f8
26 files changed
+591 -233

No files matched your search

+6
View File
@@ -668,6 +668,12 @@ global:
ostree_repo_signature_verify_commit_data;
} LIBOSTREE_2021.3;
LIBOSTREE_2021.5 {
global:
ostree_sepolicy_new_from_commit;
ostree_mutable_tree_new_from_commit;
} LIBOSTREE_2021.4;
/* NOTE: Only add more content here in release commits! See the
* comments at the top of this file.
*/
+36
View File
@@ -681,3 +681,39 @@ ostree_mutable_tree_new_from_checksum (OstreeRepo *repo,
out->metadata_checksum = g_strdup (metadata_checksum);
return out;
}
/**
* ostree_mutable_tree_new_from_commit:
* @repo: The repo which contains the objects refered by the checksums.
* @rev: ref or SHA-256 checksum
*
* Creates a new OstreeMutableTree with the contents taken from the given commit.
* The data will be loaded from the repo lazily as needed.
*
* Returns: (transfer full): A new tree
* Since: 2021.5
*/
OstreeMutableTree *
ostree_mutable_tree_new_from_commit (OstreeRepo *repo,
const char *rev,
GError **error)
{
g_autofree char *commit = NULL;
if (!ostree_repo_resolve_rev (repo, rev, FALSE, &commit, error))
return NULL;
g_autoptr(GVariant) commit_v = NULL;
if (!ostree_repo_load_commit (repo, commit, &commit_v, NULL, error))
return NULL;
g_autoptr(GVariant) contents_checksum_v = NULL;
g_autoptr(GVariant) metadata_checksum_v = NULL;
char contents_checksum[OSTREE_SHA256_STRING_LEN + 1];
char metadata_checksum[OSTREE_SHA256_STRING_LEN + 1];
g_variant_get_child (commit_v, 6, "@ay", &contents_checksum_v);
ostree_checksum_inplace_from_bytes (g_variant_get_data (contents_checksum_v),
contents_checksum);
g_variant_get_child (commit_v, 7, "@ay", &metadata_checksum_v);
ostree_checksum_inplace_from_bytes (g_variant_get_data (metadata_checksum_v),
metadata_checksum);
return ostree_mutable_tree_new_from_checksum (repo, contents_checksum, metadata_checksum);
}
+6
View File
@@ -52,6 +52,12 @@ GType ostree_mutable_tree_get_type (void) G_GNUC_CONST;
_OSTREE_PUBLIC
OstreeMutableTree *ostree_mutable_tree_new (void);
_OSTREE_PUBLIC
OstreeMutableTree *
ostree_mutable_tree_new_from_commit (OstreeRepo *repo,
const char *rev,
GError **error);
_OSTREE_PUBLIC
OstreeMutableTree * ostree_mutable_tree_new_from_checksum (OstreeRepo *repo,
const char *contents_checksum,
+9 -34
View File
@@ -1672,14 +1672,18 @@ ostree_repo_prepare_transaction (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
g_assert (self != NULL);
guint64 reserved_bytes = 0;
g_return_val_if_fail (self->in_transaction == FALSE, FALSE);
g_debug ("Preparing transaction in repository %p", self);
/* Set up to abort the transaction if we return early from this function. */
g_autoptr(_OstreeRepoAutoTransaction) txn = self;
/* Set up to abort the transaction if we return early from this function.
* This needs to be manually built here due to a circular dependency. */
g_autoptr(OstreeRepoAutoTransaction) txn = g_malloc(sizeof(OstreeRepoAutoTransaction));
txn->repo = self;
(void) txn; /* Add use to silence static analysis */
memset (&self->txn.stats, 0, sizeof (OstreeRepoTransactionStats));
@@ -1736,7 +1740,7 @@ ostree_repo_prepare_transaction (OstreeRepo *self,
return FALSE;
/* Success: do not abort the transaction when returning. */
txn = NULL; (void) txn;
txn->repo = NULL; (void) txn;
if (out_transaction_resume)
*out_transaction_resume = ret_transaction_resume;
@@ -4314,7 +4318,6 @@ ostree_repo_commit_modifier_unref (OstreeRepoCommitModifier *modifier)
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;
@@ -4386,38 +4389,10 @@ ostree_repo_commit_modifier_set_sepolicy_from_commit (OstreeRepoCommitModifier
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);
g_autoptr(OstreeSePolicy) policy = ostree_sepolicy_new_from_commit (repo, rev, cancellable, error);
if (!policy)
return glnx_prefix_error (error, "reading policy");
return FALSE;
ostree_repo_commit_modifier_set_sepolicy (modifier, policy);
/* Transfer ownership */
modifier->sepolicy_tmpdir = tmpdir;
tmpdir.initialized = FALSE;
return TRUE;
}
+35 -30
View File
@@ -229,36 +229,6 @@ struct OstreeRepo {
OstreeRepo *parent_repo;
};
/* Taken from flatpak; may be made into public API later */
typedef OstreeRepo _OstreeRepoAutoTransaction;
static inline void
_ostree_repo_auto_transaction_cleanup (void *p)
{
if (p == NULL)
return;
g_return_if_fail (OSTREE_IS_REPO (p));
OstreeRepo *repo = p;
g_autoptr(GError) error = NULL;
if (!ostree_repo_abort_transaction (repo, NULL, &error))
g_warning("Failed to auto-cleanup OSTree transaction: %s", error->message);
g_object_unref (repo);
}
static inline _OstreeRepoAutoTransaction *
_ostree_repo_auto_transaction_start (OstreeRepo *repo,
GCancellable *cancellable,
GError **error)
{
if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error))
return NULL;
return (_OstreeRepoAutoTransaction *) g_object_ref (repo);
}
G_DEFINE_AUTOPTR_CLEANUP_FUNC (_OstreeRepoAutoTransaction, _ostree_repo_auto_transaction_cleanup)
typedef struct {
dev_t dev;
ino_t ino;
@@ -544,4 +514,39 @@ _ostree_repo_verify_bindings (const char *collection_id,
GVariant *commit,
GError **error);
/**
* OstreeRepoAutoTransaction:
*
* A transaction guard for a specific #OstreeRepo. It can be explicitly
* completed through abort/commit. If the guard has not been completed
* beforehand, on cleanup it is automatically aborted.
*
* Taken from flatpak; may be made into public API later
*/
typedef struct
{
OstreeRepo *repo;
} OstreeRepoAutoTransaction;
OstreeRepoAutoTransaction *
_ostree_repo_auto_transaction_start (OstreeRepo *repo,
GCancellable *cancellable,
GError **error);
gboolean
_ostree_repo_auto_transaction_abort (OstreeRepoAutoTransaction *txn,
GCancellable *cancellable,
GError **error);
gboolean
_ostree_repo_auto_transaction_commit (OstreeRepoAutoTransaction *txn,
OstreeRepoTransactionStats *out_stats,
GCancellable *cancellable,
GError **error);
void
_ostree_repo_auto_transaction_cleanup (void *p);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeRepoAutoTransaction, _ostree_repo_auto_transaction_cleanup);
G_END_DECLS
+112
View File
@@ -711,6 +711,118 @@ ostree_repo_auto_lock_cleanup (OstreeRepoAutoLock *auto_lock)
}
}
/**
* _ostree_repo_auto_transaction_start:
* @repo: an #OsreeRepo object
* @cancellable: Cancellable
* @error: a #GError
*
* Start a transaction and return a guard for it.
*
* Returns: (transfer full): an #OsreeRepoAutoTransaction guard on success,
* %NULL otherwise.
*/
OstreeRepoAutoTransaction *
_ostree_repo_auto_transaction_start (OstreeRepo *repo,
GCancellable *cancellable,
GError **error)
{
g_assert (repo != NULL);
if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error))
return NULL;
OstreeRepoAutoTransaction *txn = g_malloc(sizeof(OstreeRepoAutoTransaction));
txn->repo = g_object_ref (repo);
return g_steal_pointer (&txn);
}
/**
* _ostree_repo_auto_transaction_abort:
* @txn: an #OsreeRepoAutoTransaction guard
* @cancellable: Cancellable
* @error: a #GError
*
* Abort a transaction, marking the related guard as completed.
*
* Returns: %TRUE on successful commit, %FALSE otherwise.
*/
gboolean
_ostree_repo_auto_transaction_abort (OstreeRepoAutoTransaction *txn,
GCancellable *cancellable,
GError **error)
{
g_assert (txn != NULL);
if (txn->repo == NULL) {
return glnx_throw (error, "transaction already completed");
}
if (!ostree_repo_abort_transaction (txn->repo, cancellable, error))
return FALSE;
g_clear_object (&txn->repo);
return TRUE;
}
/**
* _ostree_repo_auto_transaction_commit:
* @txn: an #OsreeRepoAutoTransaction guard
* @cancellable: Cancellable
* @error: a #GError
*
* Commit a transaction, marking the related guard as completed.
*
* Returns: %TRUE on successful aborting, %FALSE otherwise.
*/
gboolean
_ostree_repo_auto_transaction_commit (OstreeRepoAutoTransaction *txn,
OstreeRepoTransactionStats *out_stats,
GCancellable *cancellable,
GError **error)
{
g_assert (txn != NULL);
if (txn->repo == NULL) {
return glnx_throw (error, "transaction already completed");
}
if (!ostree_repo_commit_transaction (txn->repo, out_stats, cancellable, error))
return FALSE;
g_clear_object (&txn->repo);
return TRUE;
}
/**
* _ostree_repo_auto_transaction_cleanup:
* @p: pointer to an #OsreeRepoAutoTransaction guard
*
* Destroy a transaction guard. If the transaction has not yet been completed,
* it gets aborted.
*/
void
_ostree_repo_auto_transaction_cleanup (void *p)
{
if (p == NULL)
return;
OstreeRepoAutoTransaction *txn = p;
// Auto-abort only if transaction has not already been aborted/committed.
if (txn->repo != NULL)
{
g_autoptr(GError) error = NULL;
if (!_ostree_repo_auto_transaction_abort (txn, NULL, &error)) {
g_warning("Failed to auto-cleanup OSTree transaction: %s", error->message);
g_clear_object (&txn->repo);
}
}
}
static GFile *
get_remotes_d_dir (OstreeRepo *self,
GFile *sysroot);
+61 -1
View File
@@ -29,6 +29,7 @@
#include "otutil.h"
#include "ostree-sepolicy.h"
#include "ostree-repo.h"
#include "ostree-sepolicy-private.h"
#include "ostree-bootloader-uboot.h"
#include "ostree-bootloader-syslinux.h"
@@ -47,6 +48,7 @@ struct OstreeSePolicy {
int rootfs_dfd;
int rootfs_dfd_owned;
GFile *path;
GLnxTmpDir tmpdir;
#ifdef HAVE_SELINUX
GFile *selinux_policy_root;
@@ -77,6 +79,8 @@ ostree_sepolicy_finalize (GObject *object)
{
OstreeSePolicy *self = OSTREE_SEPOLICY (object);
(void) glnx_tmpdir_delete (&self->tmpdir, NULL, NULL);
g_clear_object (&self->path);
if (self->rootfs_dfd_owned != -1)
(void) close (self->rootfs_dfd_owned);
@@ -266,6 +270,58 @@ get_policy_checksum (char **out_csum,
#endif
/**
* ostree_sepolicy_new_from_commit:
* @repo: The repo
* @rev: ostree ref or checksum
* @cancellable: Cancellable
* @error: Error
*
* Extract the SELinux policy from a commit object via a partial checkout. This is useful
* for labeling derived content as separate commits.
*
* This function is the backend of `ostree_repo_commit_modifier_set_sepolicy_from_commit()`.
*
* Returns: (transfer full): A new policy
*/
OstreeSePolicy*
ostree_sepolicy_new_from_commit (OstreeRepo *repo,
const char *rev,
GCancellable *cancellable,
GError **error)
{
GLNX_AUTO_PREFIX_ERROR ("setting sepolicy from commit", error);
g_autoptr(GFile) root = NULL;
g_autofree char *commit = NULL;
if (!ostree_repo_read_commit (repo, rev, &root, &commit, cancellable, error))
return NULL;
const char policypath[] = "usr/etc/selinux";
g_autoptr(GFile) policyroot = g_file_get_child (root, policypath);
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;
if (g_file_query_exists (policyroot, NULL))
{
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_null (error, "policy checkout");
}
OstreeSePolicy *ret = ostree_sepolicy_new_at (tmpdir.fd, cancellable, error);
if (!ret)
return NULL;
/* Transfer ownership of tmpdir */
ret->tmpdir = tmpdir;
tmpdir.initialized = FALSE;
return ret;
}
/* Workaround for http://marc.info/?l=selinux&m=149323809332417&w=2 */
#ifdef HAVE_SELINUX
@@ -443,7 +499,11 @@ ostree_sepolicy_new_at (int rootfs_dfd,
/**
* ostree_sepolicy_get_path:
* @self:
* @self: A SePolicy object
*
* This API should be considered deprecated, because it's supported for
* policy objects to be created from file-descriptor relative paths, which
* may not be globally accessible.
*
* Returns: (transfer none): Path to rootfs
*/
+5
View File
@@ -44,6 +44,11 @@ OstreeSePolicy* ostree_sepolicy_new_at (int rootfs_dfd,
GCancellable *cancellable,
GError **error);
_OSTREE_PUBLIC
OstreeSePolicy* ostree_sepolicy_new_from_commit (OstreeRepo *repo,
const char *rev,
GCancellable *cancellable,
GError **error);
_OSTREE_PUBLIC
GFile * ostree_sepolicy_get_path (OstreeSePolicy *self);
+2 -2
View File
@@ -445,7 +445,7 @@ generate_deployment_refs (OstreeSysroot *self,
cancellable, error))
return FALSE;
g_autoptr(_OstreeRepoAutoTransaction) txn =
g_autoptr(OstreeRepoAutoTransaction) txn =
_ostree_repo_auto_transaction_start (repo, cancellable, error);
if (!txn)
return FALSE;
@@ -458,7 +458,7 @@ generate_deployment_refs (OstreeSysroot *self,
ostree_repo_transaction_set_refspec (repo, refname, ostree_deployment_get_csum (deployment));
}
if (!ostree_repo_commit_transaction (repo, NULL, cancellable, error))
if (!_ostree_repo_auto_transaction_commit (txn, NULL, cancellable, error))
return FALSE;
return TRUE;
+1 -3
View File
@@ -488,9 +488,7 @@ copy_modified_config_file (int orig_etc_fd,
}
else
{
return glnx_throw (error,
"Unsupported non-regular/non-symlink file in /etc '%s'",
path);
ot_journal_print (LOG_INFO, "Ignoring non-regular/non-symlink file found during /etc merge: %s", path);
}
return TRUE;
+3 -3
View File
@@ -43,7 +43,7 @@
*
* Since: 2017.4
*/
#define OSTREE_RELEASE_VERSION (4)
#define OSTREE_RELEASE_VERSION (5)
/**
* OSTREE_VERSION
@@ -52,7 +52,7 @@
*
* Since: 2017.4
*/
#define OSTREE_VERSION (2021.4)
#define OSTREE_VERSION (2021.5)
/**
* OSTREE_VERSION_S:
@@ -62,7 +62,7 @@
*
* Since: 2017.4
*/
#define OSTREE_VERSION_S "2021.4"
#define OSTREE_VERSION_S "2021.5"
#define OSTREE_ENCODE_VERSION(year,release) \
((year) << 16 | (release))
+15 -16
View File
@@ -602,6 +602,17 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio
filter_data.skip_list = skip_list;
modifier = ostree_repo_commit_modifier_new (flags, commit_filter,
&filter_data, NULL);
if (opt_selinux_policy)
{
glnx_autofd int rootfs_dfd = -1;
if (!glnx_opendirat (AT_FDCWD, opt_selinux_policy, TRUE, &rootfs_dfd, error))
goto out;
policy = ostree_sepolicy_new_at (rootfs_dfd, cancellable, error);
if (!policy)
goto out;
ostree_repo_commit_modifier_set_sepolicy (modifier, policy);
}
}
if (opt_editor)
@@ -627,20 +638,14 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio
if (opt_base)
{
g_autofree char *base_commit = NULL;
g_autoptr(GFile) base_root = NULL;
if (!ostree_repo_read_commit (repo, opt_base, &base_root, &base_commit, cancellable, error))
mtree = ostree_mutable_tree_new_from_commit (repo, opt_base, error);
if (!mtree)
goto out;
OstreeRepoFile *rootf = (OstreeRepoFile*) base_root;
mtree = ostree_mutable_tree_new_from_checksum (repo,
ostree_repo_file_tree_get_contents_checksum (rootf),
ostree_repo_file_tree_get_metadata_checksum (rootf));
if (opt_selinux_policy_from_base)
{
g_assert (modifier);
if (!ostree_repo_commit_modifier_set_sepolicy_from_commit (modifier, repo, base_commit, cancellable, error))
if (!ostree_repo_commit_modifier_set_sepolicy_from_commit (modifier, repo, opt_base, cancellable, error))
goto out;
/* Don't try to handle it twice */
opt_selinux_policy_from_base = FALSE;
@@ -691,14 +696,8 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio
{
if (first && opt_selinux_policy_from_base)
{
opt_selinux_policy = g_strdup (tree);
opt_selinux_policy_from_base = FALSE;
}
if (first && opt_selinux_policy)
{
g_assert (modifier);
glnx_autofd int rootfs_dfd = -1;
if (!glnx_opendirat (AT_FDCWD, opt_selinux_policy, TRUE, &rootfs_dfd, error))
if (!glnx_opendirat (AT_FDCWD, tree, TRUE, &rootfs_dfd, error))
goto out;
policy = ostree_sepolicy_new_at (rootfs_dfd, cancellable, error);
if (!policy)
+3
View File
@@ -459,5 +459,8 @@ ostree_builtin_fsck (int argc, char **argv, OstreeCommandInvocation *invocation,
if (n_fsck_partial > 0)
return glnx_throw (error, "%u partial commits from fsck-detected corruption", n_partial);
g_print ("object fsck of %d commits completed successfully - no errors found.\n",
(guint)g_hash_table_size (commits));
return TRUE;
}