New upstream version 2022.5

This commit is contained in:
Simon McVittie committed 2022-07-26 18:09:15 +01:00
commit 97f9ef0bb1
55 files changed
+4439 -3030

No files matched your search

+7 -1
View File
@@ -681,7 +681,13 @@ LIBOSTREE_2022.4 {
global:
ostree_fs_get_all_xattrs;
ostree_fs_get_all_xattrs_at;
} LIBOSTREE_2021.5;
} LIBOSTREE_2022.2;
LIBOSTREE_2022.5 {
global:
ostree_kernel_args_append_if_missing;
ostree_sysroot_deployment_set_kargs_in_place;
} LIBOSTREE_2022.4;
/* NOTE: Only add more content here in release commits! See the
* comments at the top of this file.
+1 -1
View File
@@ -28,7 +28,7 @@
#define SECURE_EXECUTION_SYSFS_FLAG "/sys/firmware/uv/prot_virt_guest"
#define SECURE_EXECUTION_PARTITION "/dev/disk/by-label/se"
#define SECURE_EXECUTION_MOUNTPOINT "/sysroot/se"
#define SECURE_EXECUTION_BOOT_IMAGE SECURE_EXECUTION_MOUNTPOINT "/sd-boot"
#define SECURE_EXECUTION_BOOT_IMAGE SECURE_EXECUTION_MOUNTPOINT "/sdboot"
#define SECURE_EXECUTION_HOSTKEY_PATH "/etc/se-hostkeys/"
#define SECURE_EXECUTION_HOSTKEY_PREFIX "ibm-z-hostkey"
#define SECURE_EXECUTION_LUKS_ROOT_KEY "/etc/luks/root"
+25
View File
@@ -804,3 +804,28 @@ ostree_kernel_args_get_last_value (OstreeKernelArgs *kargs, const char *key)
const OstreeKernelArgsEntry *e = entries->pdata[entries->len-1];
return _ostree_kernel_args_entry_get_value (e);
}
/**
* ostree_kernel_args_append_if_missing:
* @kargs: a OstreeKernelArgs instance
* @arg: key or key/value pair to be added
*
* Appends @arg which is in the form of key=value pair to the hash table kargs->table
* (appends to the value list if key is not in the hash table)
* and appends key to kargs->order if it is not in the hash table.
*
* Since: 2022.5
**/
void
ostree_kernel_args_append_if_missing (OstreeKernelArgs *kargs,
const char *arg)
{
g_autofree char *key = g_strdup (arg);
split_keyeq (key);
// Don't insert a duplicate key.
if (g_hash_table_contains (kargs->table, key))
return;
ostree_kernel_args_append (kargs, arg);
}
+4
View File
@@ -130,4 +130,8 @@ char **ostree_kernel_args_to_strv (OstreeKernelArgs *kargs);
_OSTREE_PUBLIC
char *ostree_kernel_args_to_string (OstreeKernelArgs *kargs);
_OSTREE_PUBLIC
void ostree_kernel_args_append_if_missing (OstreeKernelArgs *kargs,
const char *arg);
G_END_DECLS
+7
View File
@@ -224,6 +224,7 @@ struct OstreeRepo {
gint fs_support_reflink; /* The underlying filesystem has support for ioctl (FICLONE..) */
gchar **repo_finders;
OstreeCfgSysrootBootloaderOpt bootloader; /* Configure which bootloader to use. */
GHashTable *bls_append_values; /* Parsed key-values from bls-append-except-default key in config. */
OstreeRepo *parent_repo;
};
@@ -513,6 +514,12 @@ _ostree_repo_verify_bindings (const char *collection_id,
GVariant *commit,
GError **error);
GHashTable *
ostree_repo_list_objects_set (OstreeRepo *self,
OstreeRepoListObjectsFlags flags,
GCancellable *cancellable,
GError **error);
/**
* OstreeRepoAutoTransaction:
*
+27 -14
View File
@@ -189,7 +189,6 @@ _ostree_repo_prune_tmp (OstreeRepo *self,
return TRUE;
}
/**
* ostree_repo_prune_static_deltas:
* @self: Repo
@@ -280,15 +279,8 @@ repo_prune_internal (OstreeRepo *self,
g_autoptr(GHashTable) reachable_owned = g_hash_table_ref (options->reachable);
data.reachable = reachable_owned;
GLNX_HASH_TABLE_FOREACH_KV (objects, GVariant*, serialized_key, GVariant*, objdata)
GLNX_HASH_TABLE_FOREACH (objects, GVariant*, serialized_key)
{
gboolean is_loose;
g_variant_get_child (objdata, 0, "b", &is_loose);
if (!is_loose)
continue;
if (!maybe_prune_loose_object (&data, options->flags, serialized_key,
cancellable, error))
return FALSE;
@@ -444,8 +436,18 @@ ostree_repo_prune (OstreeRepo *self,
return FALSE;
}
if (!ostree_repo_list_objects (self, OSTREE_REPO_LIST_OBJECTS_ALL | OSTREE_REPO_LIST_OBJECTS_NO_PARENTS,
&objects, cancellable, error))
if (commit_only)
{
if (!ostree_repo_list_commit_objects_starting_with (self, "", &objects, cancellable, error))
return FALSE;
}
else
{
objects = ostree_repo_list_objects_set (self, OSTREE_REPO_LIST_OBJECTS_ALL | OSTREE_REPO_LIST_OBJECTS_NO_PARENTS,
cancellable, error);
}
if (!objects)
return FALSE;
if (!refs_only)
@@ -515,9 +517,20 @@ ostree_repo_prune_from_reachable (OstreeRepo *self,
return FALSE;
g_autoptr(GHashTable) objects = NULL;
if (!ostree_repo_list_objects (self, OSTREE_REPO_LIST_OBJECTS_ALL | OSTREE_REPO_LIST_OBJECTS_NO_PARENTS,
&objects, cancellable, error))
OstreeRepoPruneFlags flags = options->flags;
gboolean commit_only = (flags & OSTREE_REPO_PRUNE_FLAGS_COMMIT_ONLY) > 0;
if (commit_only)
{
if (!ostree_repo_list_commit_objects_starting_with (self, "", &objects, cancellable, error))
return FALSE;
}
else
{
objects =
ostree_repo_list_objects_set (self, OSTREE_REPO_LIST_OBJECTS_ALL | OSTREE_REPO_LIST_OBJECTS_NO_PARENTS,
cancellable, error);
}
if (!objects)
return FALSE;
return repo_prune_internal (self, objects, options, out_objects_total,
+113 -39
View File
@@ -1238,6 +1238,7 @@ ostree_repo_finalize (GObject *object)
g_mutex_clear (&self->txn_lock);
g_free (self->collection_id);
g_strfreev (self->repo_finders);
g_clear_pointer (&self->bls_append_values, g_hash_table_unref);
g_clear_pointer (&self->remotes, g_hash_table_destroy);
g_mutex_clear (&self->remotes_lock);
@@ -1412,6 +1413,9 @@ ostree_repo_init (OstreeRepo *self)
self->remotes = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify) NULL,
(GDestroyNotify) ostree_remote_unref);
self->bls_append_values = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify) g_free,
(GDestroyNotify) g_free);
g_mutex_init (&self->remotes_lock);
self->repo_dir_fd = -1;
@@ -3510,16 +3514,42 @@ reload_sysroot_config (OstreeRepo *self,
* https://github.com/ostreedev/ostree/issues/1719
* https://github.com/ostreedev/ostree/issues/1801
*/
gboolean valid_bootloader;
for (int i = 0; CFG_SYSROOT_BOOTLOADER_OPTS_STR[i]; i++)
{
if (g_str_equal (bootloader, CFG_SYSROOT_BOOTLOADER_OPTS_STR[i]))
{
self->bootloader = (OstreeCfgSysrootBootloaderOpt) i;
return TRUE;
valid_bootloader = TRUE;
}
}
if (!valid_bootloader)
{
return glnx_throw (error, "Invalid bootloader configuration: '%s'", bootloader);
}
/* Parse bls-append-except-default string list. */
g_auto(GStrv) read_values = NULL;
if (!ot_keyfile_get_string_list_with_default (self->config, "sysroot", "bls-append-except-default",
';', NULL, &read_values, error))
return glnx_throw(error, "Unable to parse bls-append-except-default");
/* get all key value pairs in bls-append-except-default */
g_hash_table_remove_all (self->bls_append_values);
for (char **iter = read_values; iter && *iter; iter++)
{
const char *key_value = *iter;
const char *sep = strchr (key_value, '=');
if (sep == NULL)
{
glnx_throw (error, "bls-append-except-default key must be of the form \"key1=value1;key2=value2...\"");
return FALSE;
}
char *key = g_strndup (key_value, sep - key_value);
char *value = g_strdup (sep + 1);
g_hash_table_replace (self->bls_append_values, key, value);
}
return glnx_throw (error, "Invalid bootloader configuration: '%s'", bootloader);
return TRUE;
}
/**
@@ -3895,6 +3925,7 @@ ostree_repo_get_parent (OstreeRepo *self)
static gboolean
list_loose_objects_at (OstreeRepo *self,
GVariant *dummy_value,
GHashTable *inout_objects,
int dfd,
const char *prefix,
@@ -3902,7 +3933,7 @@ list_loose_objects_at (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
GVariant *key, *value;
GVariant *key;
g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
gboolean exists;
@@ -3971,11 +4002,13 @@ list_loose_objects_at (OstreeRepo *self,
}
key = ostree_object_name_serialize (buf, objtype);
value = g_variant_new ("(b@as)",
TRUE, g_variant_new_strv (NULL, 0));
/* transfer ownership */
g_hash_table_replace (inout_objects, g_variant_ref_sink (key),
g_variant_ref_sink (value));
if (dummy_value)
g_hash_table_replace (inout_objects, g_variant_ref_sink (key),
g_variant_ref (dummy_value));
else
g_hash_table_add (inout_objects, g_variant_ref_sink (key));
}
return TRUE;
@@ -3983,6 +4016,7 @@ list_loose_objects_at (OstreeRepo *self,
static gboolean
list_loose_objects (OstreeRepo *self,
GVariant *dummy_value,
GHashTable *inout_objects,
const char *commit_starting_with,
GCancellable *cancellable,
@@ -3996,7 +4030,8 @@ list_loose_objects (OstreeRepo *self,
buf[0] = hexchars[c >> 4];
buf[1] = hexchars[c & 0xF];
buf[2] = '\0';
if (!list_loose_objects_at (self, inout_objects, self->objects_dir_fd, buf,
if (!list_loose_objects_at (self, dummy_value,
inout_objects, self->objects_dir_fd, buf,
commit_starting_with,
cancellable, error))
return FALSE;
@@ -4901,6 +4936,65 @@ ostree_repo_load_commit (OstreeRepo *self,
out_variant, NULL, NULL, out_state, NULL, error);
}
static GHashTable *
repo_list_objects_impl (OstreeRepo *self,
OstreeRepoListObjectsFlags flags,
GVariant *dummy_value,
GCancellable *cancellable,
GError **error)
{
g_assert (error == NULL || *error == NULL);
g_assert (self->inited);
g_autoptr(GHashTable) ret_objects =
g_hash_table_new_full (ostree_hash_object_name, g_variant_equal,
(GDestroyNotify) g_variant_unref,
dummy_value ? (GDestroyNotify) g_variant_unref : NULL);
if (flags & OSTREE_REPO_LIST_OBJECTS_ALL)
flags |= (OSTREE_REPO_LIST_OBJECTS_LOOSE | OSTREE_REPO_LIST_OBJECTS_PACKED);
if (flags & OSTREE_REPO_LIST_OBJECTS_LOOSE)
{
if (!list_loose_objects (self, dummy_value, ret_objects, NULL, cancellable, error))
return FALSE;
if ((flags & OSTREE_REPO_LIST_OBJECTS_NO_PARENTS) == 0 && self->parent_repo)
{
if (!list_loose_objects (self->parent_repo, dummy_value, ret_objects, NULL, cancellable, error))
return FALSE;
}
}
if (flags & OSTREE_REPO_LIST_OBJECTS_PACKED)
{
/* Nothing for now... */
}
return g_steal_pointer (&ret_objects);
}
/* A currently-internal version of ostree_repo_list_objects which returns
* a set, and not a map (with a useless value).
*/
GHashTable *
ostree_repo_list_objects_set (OstreeRepo *self,
OstreeRepoListObjectsFlags flags,
GCancellable *cancellable,
GError **error)
{
return repo_list_objects_impl (self, flags, NULL, cancellable, error);
}
/* For unfortunate historical reasons we emit this dummy value.
* It was intended to provide additional information about the object (e.g. "is in a pack file")
* but we ended up not shipping pack files.
*/
static GVariant *
get_dummy_list_objects_variant (void)
{
return g_variant_ref_sink (g_variant_new ("(b@as)", TRUE, g_variant_new_strv (NULL, 0)));
}
/**
* ostree_repo_list_objects:
* @self: Repo
@@ -4924,41 +5018,18 @@ ostree_repo_list_objects (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
g_return_val_if_fail (self->inited, FALSE);
g_autoptr(GHashTable) ret_objects =
g_hash_table_new_full (ostree_hash_object_name, g_variant_equal,
(GDestroyNotify) g_variant_unref,
(GDestroyNotify) g_variant_unref);
if (flags & OSTREE_REPO_LIST_OBJECTS_ALL)
flags |= (OSTREE_REPO_LIST_OBJECTS_LOOSE | OSTREE_REPO_LIST_OBJECTS_PACKED);
if (flags & OSTREE_REPO_LIST_OBJECTS_LOOSE)
{
if (!list_loose_objects (self, ret_objects, NULL, cancellable, error))
return FALSE;
if ((flags & OSTREE_REPO_LIST_OBJECTS_NO_PARENTS) == 0 && self->parent_repo)
{
if (!list_loose_objects (self->parent_repo, ret_objects, NULL, cancellable, error))
return FALSE;
}
}
if (flags & OSTREE_REPO_LIST_OBJECTS_PACKED)
{
/* Nothing for now... */
}
ot_transfer_out_value (out_objects, &ret_objects);
g_autoptr(GVariant) dummy_value = get_dummy_list_objects_variant ();
g_autoptr(GHashTable) ret = repo_list_objects_impl (self, flags, dummy_value, cancellable, error);
if (!ret)
return FALSE;
ot_transfer_out_value (out_objects, &ret);
return TRUE;
}
/**
* ostree_repo_list_commit_objects_starting_with:
* @self: Repo
* @start: List commits starting with this checksum
* @start: List commits starting with this checksum (empty string for all)
* @out_commits: (out) (transfer container) (element-type GVariant GVariant):
* Map of serialized commit name to variant data
* @cancellable: Cancellable
@@ -4967,6 +5038,8 @@ ostree_repo_list_objects (OstreeRepo *self,
* This function synchronously enumerates all commit objects starting
* with @start, returning data in @out_commits.
*
* To list all commit objects, provide the empty string `""` for @start.
*
* Returns: %TRUE on success, %FALSE on error, and @error will be set
*/
gboolean
@@ -4983,13 +5056,14 @@ ostree_repo_list_commit_objects_starting_with (OstreeRepo *self
g_hash_table_new_full (ostree_hash_object_name, g_variant_equal,
(GDestroyNotify) g_variant_unref,
(GDestroyNotify) g_variant_unref);
g_autoptr(GVariant) dummy_loose_object_variant = get_dummy_list_objects_variant ();
if (!list_loose_objects (self, ret_commits, start, cancellable, error))
if (!list_loose_objects (self, dummy_loose_object_variant, ret_commits, start, cancellable, error))
return FALSE;
if (self->parent_repo)
{
if (!list_loose_objects (self->parent_repo, ret_commits, start,
if (!list_loose_objects (self->parent_repo, dummy_loose_object_variant, ret_commits, start,
cancellable, error))
return FALSE;
}
+1 -1
View File
@@ -1261,7 +1261,7 @@ void ostree_repo_commit_traverse_iter_cleanup (void *p);
* OstreeRepoPruneFlags:
* @OSTREE_REPO_PRUNE_FLAGS_NONE: No special options for pruning
* @OSTREE_REPO_PRUNE_FLAGS_NO_PRUNE: Don't actually delete objects
* @OSTREE_REPO_PRUNE_FLAGS_REFS_ONLY: Do not traverse individual commit objects, only follow refs
* @OSTREE_REPO_PRUNE_FLAGS_REFS_ONLY: Do not traverse individual commit objects, only follow refs for reachability calculations
* @OSTREE_REPO_PRUNE_FLAGS_COMMIT_ONLY: Only traverse commit objects. (Since 2022.2)
*/
typedef enum {
+3
View File
@@ -209,6 +209,9 @@ gboolean ostree_sign_ed25519_data_verify (OstreeSign *self,
g_autoptr (GVariant) child = g_variant_get_child_value (signatures, i);
g_autoptr (GBytes) signature = g_variant_get_data_as_bytes(child);
if (g_bytes_get_size (signature) != crypto_sign_BYTES)
return glnx_throw (error, "Invalid signature length of %" G_GSIZE_FORMAT " bytes, expected %" G_GSIZE_FORMAT, (gsize) g_bytes_get_size (signature), (gsize) crypto_sign_BYTES);
g_autofree char * hex = g_malloc0 (crypto_sign_PUBLICKEYBYTES*2 + 1);
g_debug("Read signature %d: %s", (gint)i, g_variant_print(child, TRUE));
+54 -42
View File
@@ -1614,6 +1614,7 @@ full_system_sync (OstreeSysroot *self,
return FALSE;
start_msec = g_get_monotonic_time () / 1000;
g_assert_cmpint (self->boot_fd, !=, -1);
if (!fsfreeze_thaw_cycle (self, self->boot_fd, cancellable, error))
return FALSE;
end_msec = g_get_monotonic_time () / 1000;
@@ -1807,7 +1808,6 @@ parse_os_release (const char *contents,
*/
static gboolean
install_deployment_kernel (OstreeSysroot *sysroot,
OstreeRepo *repo,
int new_bootversion,
OstreeDeployment *deployment,
guint n_deployments,
@@ -1855,6 +1855,8 @@ install_deployment_kernel (OstreeSysroot *sysroot,
if (!glnx_shutil_mkdir_p_at (sysroot->boot_fd, bootconfdir, 0775, cancellable, error))
return FALSE;
OstreeRepo *repo = ostree_sysroot_repo (sysroot);
/* Install (hardlink/copy) the kernel into /boot/ostree/osname-${bootcsum} if
* it doesn't exist already.
*/
@@ -2082,25 +2084,6 @@ install_deployment_kernel (OstreeSysroot *sysroot,
g_autofree char *options_key = ostree_kernel_args_to_string (kargs);
ostree_bootconfig_parser_set (bootconfig, "options", options_key);
g_autoptr(GError) local_error = NULL;
GKeyFile *config = ostree_repo_get_config (repo);
gchar **read_values = g_key_file_get_string_list (config, "sysroot", "bls-append-except-default", NULL, &local_error);
/* We can ignore not found errors */
if (!read_values)
{
gboolean not_found = g_error_matches (local_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND) || \
g_error_matches (local_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND);
if (not_found)
{
g_clear_error (&local_error);
}
else
{
g_propagate_error (error, g_steal_pointer (&local_error));
return FALSE;
}
}
/* Only append to this BLS config if:
* - this is not the default deployment
*/
@@ -2110,20 +2093,8 @@ install_deployment_kernel (OstreeSysroot *sysroot,
if (allow_append)
{
/* get all key value pairs in bls-append */
for (char **iter = read_values; iter && *iter; iter++)
{
const char *key_value = *iter;
const char *sep = strchr (key_value, '=');
if (sep == NULL)
{
glnx_throw (error, "bls-append-except-default key must be of the form \"key1=value1;key2=value2...\"");
return FALSE;
}
g_autofree char *key = g_strndup (key_value, sep - key_value);
g_autofree char *value = g_strdup (sep + 1);
ostree_bootconfig_parser_set (bootconfig, key, value);
}
GLNX_HASH_TABLE_FOREACH_KV (repo->bls_append_values, const char *, key, const char *, value)
ostree_bootconfig_parser_set (bootconfig, key, value);
}
glnx_autofd int bootconf_dfd = -1;
@@ -2378,13 +2349,6 @@ write_deployments_bootswap (OstreeSysroot *self,
cancellable, error))
return FALSE;
/* Need the repo to try and extract the versions for deployments.
* But this is a "nice-to-have" for the bootloader UI, so failure
* here is not fatal to the whole operation. We just gracefully
* fall back to the deployment index. */
g_autoptr(OstreeRepo) repo = NULL;
(void) ostree_sysroot_get_repo (self, &repo, cancellable, NULL);
/* Only show the osname in bootloader titles if there are multiple
* osname's among the new deployments. Check for that here. */
gboolean show_osname = FALSE;
@@ -2402,7 +2366,7 @@ write_deployments_bootswap (OstreeSysroot *self,
for (guint i = 0; i < new_deployments->len; i++)
{
OstreeDeployment *deployment = new_deployments->pdata[i];
if (!install_deployment_kernel (self, repo, new_bootversion,
if (!install_deployment_kernel (self, new_bootversion,
deployment, new_deployments->len,
show_osname, cancellable, error))
return FALSE;
@@ -3563,6 +3527,7 @@ _ostree_sysroot_boot_complete (OstreeSysroot *self,
return FALSE;
glnx_autofd int failure_fd = -1;
g_assert_cmpint (self->boot_fd, !=, -1);
if (!ot_openat_ignore_enoent (self->boot_fd, _OSTREE_FINALIZE_STAGED_FAILURE_PATH, &failure_fd, error))
return FALSE;
// If we didn't find a failure log, then there's nothing to do right now.
@@ -3626,6 +3591,53 @@ ostree_sysroot_deployment_set_kargs (OstreeSysroot *self,
return TRUE;
}
/**
* ostree_sysroot_deployment_set_kargs_in_place:
* @self: Sysroot
* @deployment: A deployment
* @kargs_str: (allow none): Replace @deployment's kernel arguments
* @cancellable: Cancellable
* @error: Error
*
* Replace the kernel arguments of @deployment with the values in @kargs_str.
*/
gboolean
ostree_sysroot_deployment_set_kargs_in_place (OstreeSysroot *self,
OstreeDeployment *deployment,
char *kargs_str,
GCancellable *cancellable,
GError **error)
{
if (!ostree_sysroot_initialize (self, error))
return FALSE;
if (!_ostree_sysroot_ensure_boot_fd (self, error))
return FALSE;
if (!_ostree_sysroot_ensure_writable (self, error))
return FALSE;
g_assert (!ostree_deployment_is_staged (deployment));
OstreeBootconfigParser *new_bootconfig = ostree_deployment_get_bootconfig (deployment);
ostree_bootconfig_parser_set (new_bootconfig, "options", kargs_str);
g_autofree char *bootconf_name =
g_strdup_printf ("ostree-%d-%s.conf",
self->deployments->len - ostree_deployment_get_index (deployment),
ostree_deployment_get_osname (deployment));
g_autofree char *bootconfdir = g_strdup_printf ("loader.%d/entries", self->bootversion);
glnx_autofd int bootconf_dfd = -1;
if (!glnx_opendirat (self->boot_fd, bootconfdir, TRUE, &bootconf_dfd, error))
return FALSE;
if (!ostree_bootconfig_parser_write_at (new_bootconfig,
bootconf_dfd, bootconf_name,
cancellable, error))
return FALSE;
return TRUE;
}
/**
* ostree_sysroot_deployment_set_mutable:
* @self: Sysroot
+1 -3
View File
@@ -492,7 +492,6 @@ ostree_sysroot_upgrader_pull_one_dir (OstreeSysrootUpgrader *self,
GCancellable *cancellable,
GError **error)
{
g_autoptr(OstreeRepo) repo = NULL;
char *refs_to_fetch[] = { NULL, NULL };
const char *from_revision = NULL;
g_autofree char *origin_refspec = NULL;
@@ -506,8 +505,7 @@ ostree_sysroot_upgrader_pull_one_dir (OstreeSysrootUpgrader *self,
else
refs_to_fetch[0] = self->origin_ref;
if (!ostree_sysroot_get_repo (self->sysroot, &repo, cancellable, error))
return FALSE;
OstreeRepo *repo = ostree_sysroot_repo (self->sysroot);
if (self->origin_remote)
origin_refspec = g_strconcat (self->origin_remote, ":", self->origin_ref, NULL);
+3 -4
View File
@@ -328,14 +328,13 @@ gboolean
_ostree_sysroot_ensure_writable (OstreeSysroot *self,
GError **error)
{
if (!ostree_sysroot_initialize (self, error))
return FALSE;
/* Do nothing if no mount namespace is in use */
if (!self->mount_namespace_in_use)
return TRUE;
/* If a mount namespace is in use, ensure we're initialized */
if (!ostree_sysroot_initialize (self, error))
return FALSE;
/* If we aren't operating on a booted system, then we don't
* do anything with mounts.
*/
+7
View File
@@ -175,6 +175,13 @@ gboolean ostree_sysroot_deployment_set_kargs (OstreeSysroot *self,
GCancellable *cancellable,
GError **error);
_OSTREE_PUBLIC
gboolean ostree_sysroot_deployment_set_kargs_in_place (OstreeSysroot *self,
OstreeDeployment *deployment,
char *kargs_str,
GCancellable *cancellable,
GError **error);
_OSTREE_PUBLIC
gboolean ostree_sysroot_write_deployments (OstreeSysroot *self,
GPtrArray *new_deployments,
+3 -3
View File
@@ -41,7 +41,7 @@
*
* Since: 2017.4
*/
#define OSTREE_RELEASE_VERSION (4)
#define OSTREE_RELEASE_VERSION (5)
/**
* OSTREE_VERSION
@@ -50,7 +50,7 @@
*
* Since: 2017.4
*/
#define OSTREE_VERSION (2022.4)
#define OSTREE_VERSION (2022.5)
/**
* OSTREE_VERSION_S:
@@ -60,7 +60,7 @@
*
* Since: 2017.4
*/
#define OSTREE_VERSION_S "2022.4"
#define OSTREE_VERSION_S "2022.5"
#define OSTREE_ENCODE_VERSION(year,release) \
((year) << 16 | (release))
+134
View File
@@ -0,0 +1,134 @@
/*
* Copyright (C) 2015 Colin Walters <walters@verbum.org>
* Copyright (C) 2022 Huijing Hei <hhei@redhat.com>
*
* SPDX-License-Identifier: LGPL-2.0+
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "ot-main.h"
#include "ot-admin-builtins.h"
#include "ot-admin-functions.h"
#include "ot-admin-kargs-builtins.h"
#include "otutil.h"
#include <glib/gi18n.h>
static OstreeCommand admin_kargs_subcommands[] = {
{ "edit-in-place", OSTREE_BUILTIN_FLAG_NO_REPO | OSTREE_BUILTIN_FLAG_HIDDEN,
ot_admin_kargs_builtin_edit_in_place,
"Set new kernel command line arguments in place (applies to all deployments by default)" },
{ NULL, 0, NULL, NULL }
};
static GOptionContext *
ostree_admin_kargs_option_context_new_with_commands (void)
{
OstreeCommand *command = admin_kargs_subcommands;
GOptionContext *context = g_option_context_new ("COMMAND");
g_autoptr(GString) summary = g_string_new ("Builtin \"admin kargs\" Commands:");
while (command->name != NULL)
{
if ((command->flags & OSTREE_BUILTIN_FLAG_HIDDEN) == 0)
{
g_string_append_printf (summary, "\n %-24s", command->name);
if (command->description != NULL)
g_string_append_printf (summary, "%s", command->description);
}
command++;
}
g_option_context_set_summary (context, summary->str);
return context;
}
gboolean
ot_admin_builtin_kargs (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error)
{
const char *subcommand_name = NULL;
int in, out;
for (in = 1, out = 1; in < argc; in++, out++)
{
/* The non-option is the command, take it out of the arguments */
if (argv[in][0] != '-')
{
if (subcommand_name == NULL)
{
subcommand_name = argv[in];
out--;
continue;
}
}
else if (g_str_equal (argv[in], "--"))
{
break;
}
argv[out] = argv[in];
}
argc = out;
OstreeCommand *subcommand = admin_kargs_subcommands;
while (subcommand->name)
{
if (g_strcmp0 (subcommand_name, subcommand->name) == 0)
break;
subcommand++;
}
if (!subcommand->name)
{
g_autoptr(GOptionContext) context =
ostree_admin_kargs_option_context_new_with_commands ();
/* This will not return for some options (e.g. --version). */
if (ostree_admin_option_context_parse (context, NULL, &argc, &argv,
OSTREE_ADMIN_BUILTIN_FLAG_NO_SYSROOT,
invocation, NULL, cancellable, error))
{
if (subcommand_name == NULL)
{
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"No \"admin kargs\" subcommand specified");
}
else
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
"Unknown \"admin kargs\" subcommand '%s'", subcommand_name);
}
}
g_autofree char *help = g_option_context_get_help (context, FALSE, NULL);
g_printerr ("%s", help);
return FALSE;
}
g_autofree char *prgname = g_strdup_printf ("%s %s", g_get_prgname (), subcommand_name);
g_set_prgname (prgname);
OstreeCommandInvocation sub_invocation = { .command = subcommand };
if (!subcommand->fn (argc, argv, &sub_invocation, cancellable, error))
return FALSE;
return TRUE;
}
+8 -14
View File
@@ -35,35 +35,29 @@ static GOptionEntry options[] = {
gboolean
ot_admin_builtin_os_init (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error)
{
g_autoptr(GOptionContext) context = NULL;
g_autoptr(GOptionContext) context = g_option_context_new ("OSNAME");
g_autoptr(OstreeSysroot) sysroot = NULL;
gboolean ret = FALSE;
const char *osname = NULL;
context = g_option_context_new ("OSNAME");
if (!ostree_admin_option_context_parse (context, options, &argc, &argv,
OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER | OSTREE_ADMIN_BUILTIN_FLAG_UNLOCKED,
invocation, &sysroot, cancellable, error))
goto out;
return FALSE;
if (!ostree_sysroot_ensure_initialized (sysroot, cancellable, error))
goto out;
return FALSE;
if (argc < 2)
{
ot_util_usage_error (context, "OSNAME must be specified", error);
goto out;
return FALSE;
}
osname = argv[1];
const char *osname = argv[1];
if (!ostree_sysroot_init_osname (sysroot, osname, cancellable, error))
goto out;
return FALSE;
g_print ("ostree/deploy/%s initialized as OSTree root\n", osname);
ret = TRUE;
out:
return ret;
return TRUE;
}
+7 -12
View File
@@ -34,15 +34,9 @@ static GOptionEntry options[] = {
gboolean
ot_admin_builtin_undeploy (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error)
{
g_autoptr(GOptionContext) context = NULL;
g_autoptr(GOptionContext) context = g_option_context_new ("INDEX");
g_autoptr(OstreeSysroot) sysroot = NULL;
const char *deploy_index_str;
int deploy_index;
g_autoptr(GPtrArray) current_deployments = NULL;
g_autoptr(OstreeDeployment) target_deployment = NULL;
context = g_option_context_new ("INDEX");
if (!ostree_admin_option_context_parse (context, options, &argc, &argv,
OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER,
invocation, &sysroot, cancellable, error))
@@ -54,12 +48,13 @@ ot_admin_builtin_undeploy (int argc, char **argv, OstreeCommandInvocation *invoc
return FALSE;
}
current_deployments = ostree_sysroot_get_deployments (sysroot);
g_autoptr(GPtrArray) current_deployments = ostree_sysroot_get_deployments (sysroot);
deploy_index_str = argv[1];
deploy_index = atoi (deploy_index_str);
const char *deploy_index_str = argv[1];
int deploy_index = atoi (deploy_index_str);
target_deployment = ot_admin_get_indexed_deployment (sysroot, deploy_index, error);
g_autoptr(OstreeDeployment) target_deployment =
ot_admin_get_indexed_deployment (sysroot, deploy_index, error);
if (!target_deployment)
return FALSE;
+11 -18
View File
@@ -40,33 +40,28 @@ static GOptionEntry options[] = {
gboolean
ot_admin_builtin_unlock (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error)
{
gboolean ret = FALSE;
g_autoptr(GOptionContext) context = NULL;
g_autoptr(GOptionContext) context = g_option_context_new ("");
g_autoptr(OstreeSysroot) sysroot = NULL;
OstreeDeployment *booted_deployment = NULL;
OstreeDeploymentUnlockedState target_state;
context = g_option_context_new ("");
if (!ostree_admin_option_context_parse (context, options, &argc, &argv,
OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER,
invocation, &sysroot, cancellable, error))
goto out;
return FALSE;
if (argc > 1)
{
ot_util_usage_error (context, "This command takes no extra arguments", error);
goto out;
return FALSE;
}
booted_deployment = ostree_sysroot_require_booted_deployment (sysroot, error);
OstreeDeployment *booted_deployment = ostree_sysroot_require_booted_deployment (sysroot, error);
if (!booted_deployment)
goto out;
return FALSE;
OstreeDeploymentUnlockedState target_state;
if (opt_hotfix && opt_transient)
{
glnx_throw (error, "Cannot specify both --hotfix and --transient");
goto out;
return glnx_throw (error, "Cannot specify both --hotfix and --transient");
}
else if (opt_hotfix)
target_state = OSTREE_DEPLOYMENT_UNLOCKED_HOTFIX;
@@ -77,8 +72,8 @@ ot_admin_builtin_unlock (int argc, char **argv, OstreeCommandInvocation *invocat
if (!ostree_sysroot_deployment_unlock (sysroot, booted_deployment,
target_state, cancellable, error))
goto out;
return FALSE;
switch (target_state)
{
case OSTREE_DEPLOYMENT_UNLOCKED_NONE:
@@ -99,7 +94,5 @@ ot_admin_builtin_unlock (int argc, char **argv, OstreeCommandInvocation *invocat
break;
}
ret = TRUE;
out:
return ret;
return TRUE;
}
+1
View File
@@ -46,6 +46,7 @@ BUILTINPROTO(set_origin);
BUILTINPROTO(diff);
BUILTINPROTO(switch);
BUILTINPROTO(upgrade);
BUILTINPROTO(kargs);
#undef BUILTINPROTO
@@ -0,0 +1,79 @@
/*
* Copyright (C) 2014 Colin Walters <walters@verbum.org>
* Copyright (C) 2022 Huijing Hei <hhei@redhat.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2 of the licence or (at
* your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library. If not, see <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "ot-main.h"
#include "ot-admin-kargs-builtins.h"
#include "ostree.h"
#include "otutil.h"
static char **opt_kargs_edit_in_place_append;
static GOptionEntry options[] = {
{ "append-if-missing", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_kargs_edit_in_place_append, "Append kernel arguments if they do not exist", "NAME=VALUE" },
{ NULL }
};
gboolean
ot_admin_kargs_builtin_edit_in_place (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error)
{
g_autoptr(OstreeSysroot) sysroot = NULL;
g_autoptr(GOptionContext) context = g_option_context_new ("ARGS");
if (!ostree_admin_option_context_parse (context, options, &argc, &argv,
OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER,
invocation, &sysroot, cancellable, error))
return FALSE;
g_autoptr(GPtrArray) 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");
return FALSE;
}
// set kargs for each deployment
for (guint i = 0; i < deployments->len; i++)
{
OstreeDeployment *deployment = deployments->pdata[i];
OstreeBootconfigParser *bootconfig = ostree_deployment_get_bootconfig (deployment);
g_autoptr(OstreeKernelArgs) kargs = ostree_kernel_args_from_string (ostree_bootconfig_parser_get (bootconfig, "options"));
if (opt_kargs_edit_in_place_append)
{
for (char **strviter = opt_kargs_edit_in_place_append; strviter && *strviter; strviter++)
{
const char *arg = *strviter;
ostree_kernel_args_append_if_missing (kargs, arg);
}
}
g_autofree char *new_options = ostree_kernel_args_to_string (kargs);
if (!ostree_sysroot_deployment_set_kargs_in_place (sysroot, deployment, new_options,
cancellable, error))
return FALSE;
}
return TRUE;
}
+35
View File
@@ -0,0 +1,35 @@
/*
* Copyright (C) 2014 Colin Walters <walters@verbum.org>
* Copyright (C) 2022 Huijing Hei <hhei@redhat.com>
*
* SPDX-License-Identifier: LGPL-2.0+
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <ostree.h>
G_BEGIN_DECLS
#define BUILTINPROTO(name) gboolean ot_admin_kargs_builtin_ ## name (int argc, char **argv, \
OstreeCommandInvocation *invocation, \
GCancellable *cancellable, GError **error)
BUILTINPROTO(edit_in_place);
#undef BUILTINPROTO
G_END_DECLS
+3
View File
@@ -76,6 +76,9 @@ static OstreeCommand admin_subcommands[] = {
{ "upgrade", OSTREE_BUILTIN_FLAG_NO_REPO,
ot_admin_builtin_upgrade,
"Construct new tree from current origin and deploy it, if it changed" },
{ "kargs", OSTREE_BUILTIN_FLAG_NO_REPO,
ot_admin_builtin_kargs,
"Change kernel arguments" },
{ NULL, 0, NULL, NULL }
};
+10 -14
View File
@@ -61,18 +61,10 @@ split_key_string (const char *k,
gboolean
ostree_builtin_config (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error)
{
g_autoptr(GOptionContext) context = NULL;
g_autoptr(GOptionContext) context = g_option_context_new ("(get KEY|set KEY VALUE|unset KEY)");
g_autoptr(OstreeRepo) repo = NULL;
const char *op;
const char *section_key;
const char *value;
g_autofree char *section = NULL;
g_autofree char *key = NULL;
g_autoptr(GKeyFile) config = NULL;
int correct_argc;
context = g_option_context_new ("(get KEY|set KEY VALUE|unset KEY)");
if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, error))
return FALSE;
@@ -82,12 +74,11 @@ ostree_builtin_config (int argc, char **argv, OstreeCommandInvocation *invocatio
return FALSE;
}
op = argv[1];
const char *op = argv[1];
int correct_argc = 3;
if (!strcmp (op, "set"))
correct_argc = 4;
else
correct_argc = 3;
if (argc > correct_argc)
{
@@ -95,6 +86,11 @@ ostree_builtin_config (int argc, char **argv, OstreeCommandInvocation *invocatio
return FALSE;
}
g_autofree char *section = NULL;
g_autofree char *key = NULL;
g_autoptr(GKeyFile) config = NULL;
const char *section_key;
const char *value;
if (!strcmp (op, "set"))
{
if (opt_group)
+26 -36
View File
@@ -53,7 +53,6 @@ parse_file_or_commit (OstreeRepo *repo,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
g_autoptr(GFile) ret_file = NULL;
if (g_str_has_prefix (arg, "/")
@@ -65,13 +64,11 @@ parse_file_or_commit (OstreeRepo *repo,
else
{
if (!ostree_repo_read_commit (repo, arg, &ret_file, NULL, cancellable, error))
goto out;
return FALSE;
}
ret = TRUE;
ot_transfer_out_value (out_file, &ret_file);
out:
return ret;
return TRUE;
}
static GHashTable *
@@ -99,7 +96,6 @@ object_set_total_size (OstreeRepo *repo,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
GHashTableIter hashiter;
gpointer key, value;
@@ -116,34 +112,21 @@ object_set_total_size (OstreeRepo *repo,
ostree_object_name_deserialize (v, &csum, &objtype);
if (!ostree_repo_query_object_storage_size (repo, objtype, csum, &size,
cancellable, error))
goto out;
return FALSE;
*out_total += size;
}
ret = TRUE;
out:
return ret;
return TRUE;
}
gboolean
ostree_builtin_diff (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error)
{
gboolean ret = FALSE;
g_autoptr(GOptionContext) context = NULL;
g_autoptr(GOptionContext) context = g_option_context_new ("REV_OR_DIR REV_OR_DIR");
g_autoptr(OstreeRepo) repo = NULL;
const char *src;
const char *target;
g_autofree char *src_prev = NULL;
g_autoptr(GFile) srcf = NULL;
g_autoptr(GFile) targetf = NULL;
g_autoptr(GPtrArray) modified = NULL;
g_autoptr(GPtrArray) removed = NULL;
g_autoptr(GPtrArray) added = NULL;
context = g_option_context_new ("REV_OR_DIR REV_OR_DIR");
if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, error))
goto out;
return FALSE;
if (argc < 2)
{
@@ -152,9 +135,12 @@ ostree_builtin_diff (int argc, char **argv, OstreeCommandInvocation *invocation,
g_free (help);
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"REV must be specified");
goto out;
return FALSE;
}
g_autofree char *src_prev = NULL;
const char *src;
const char *target;
if (argc == 2)
{
src_prev = g_strconcat (argv[1], "^", NULL);
@@ -170,6 +156,12 @@ ostree_builtin_diff (int argc, char **argv, OstreeCommandInvocation *invocation,
if (!opt_stats && !opt_fs_diff)
opt_fs_diff = TRUE;
g_autoptr(GFile) srcf = NULL;
g_autoptr(GFile) targetf = NULL;
g_autoptr(GPtrArray) modified = NULL;
g_autoptr(GPtrArray) removed = NULL;
g_autoptr(GPtrArray) added = NULL;
if (opt_fs_diff)
{
OstreeDiffFlags diff_flags = OSTREE_DIFF_FLAGS_NONE;
@@ -178,9 +170,9 @@ ostree_builtin_diff (int argc, char **argv, OstreeCommandInvocation *invocation,
diff_flags |= OSTREE_DIFF_FLAGS_IGNORE_XATTRS;
if (!parse_file_or_commit (repo, src, &srcf, cancellable, error))
goto out;
return FALSE;
if (!parse_file_or_commit (repo, target, &targetf, cancellable, error))
goto out;
return FALSE;
modified = g_ptr_array_new_with_free_func ((GDestroyNotify)ostree_diff_item_unref);
removed = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
@@ -189,7 +181,7 @@ ostree_builtin_diff (int argc, char **argv, OstreeCommandInvocation *invocation,
OstreeDiffDirsOptions diff_opts = { opt_owner_uid, opt_owner_gid };
if (!ostree_diff_dirs_with_options (diff_flags, srcf, targetf, modified, removed,
added, &diff_opts, cancellable, error))
goto out;
return FALSE;
ostree_diff_print (srcf, targetf, modified, removed, added);
}
@@ -207,14 +199,14 @@ ostree_builtin_diff (int argc, char **argv, OstreeCommandInvocation *invocation,
guint64 total_common;
if (!ostree_repo_resolve_rev (repo, src, FALSE, &rev_a, error))
goto out;
return FALSE;
if (!ostree_repo_resolve_rev (repo, target, FALSE, &rev_b, error))
goto out;
return FALSE;
if (!ostree_repo_traverse_commit (repo, rev_a, 0, &reachable_a, cancellable, error))
goto out;
return FALSE;
if (!ostree_repo_traverse_commit (repo, rev_b, 0, &reachable_b, cancellable, error))
goto out;
return FALSE;
a_size = g_hash_table_size (reachable_a);
b_size = g_hash_table_size (reachable_b);
@@ -227,12 +219,10 @@ ostree_builtin_diff (int argc, char **argv, OstreeCommandInvocation *invocation,
if (!object_set_total_size (repo, reachable_intersection, &total_common,
cancellable, error))
goto out;
return FALSE;
size = g_format_size_full (total_common, 0);
g_print ("Common Object Size: %s\n", size);
}
ret = TRUE;
out:
return ret;
return TRUE;
}
+107 -113
View File
@@ -229,6 +229,90 @@ fsck_commit_for_ref (OstreeRepo *repo,
return TRUE;
}
static gboolean
fsck_one_commit (OstreeRepo *repo, const char *checksum, GVariant *commit, GPtrArray *tombstones,
GCancellable *cancellable, GError **error)
{
/* If requested, check that all the refs listed in the ref-bindings
* for this commit resolve back to this commit. */
if (opt_verify_back_refs)
{
g_autoptr(GVariant) metadata = g_variant_get_child_value (commit, 0);
const char *collection_id = NULL;
if (!g_variant_lookup (metadata,
OSTREE_COMMIT_META_KEY_COLLECTION_BINDING,
"&s",
&collection_id))
collection_id = NULL;
g_autofree const char **refs = NULL;
if (g_variant_lookup (metadata,
OSTREE_COMMIT_META_KEY_REF_BINDING,
"^a&s",
&refs))
{
for (const char **iter = refs; *iter != NULL; ++iter)
{
g_autofree char *checksum_for_ref = NULL;
if (collection_id != NULL)
{
const OstreeCollectionRef collection_ref = { (char *) collection_id, (char *) *iter };
if (!ostree_repo_resolve_collection_ref (repo, &collection_ref,
TRUE,
OSTREE_REPO_RESOLVE_REV_EXT_NONE,
&checksum_for_ref,
cancellable,
error))
return FALSE;
}
else
{
if (!ostree_repo_resolve_rev (repo, *iter, TRUE,
&checksum_for_ref, error))
return FALSE;
}
if (checksum_for_ref == NULL)
{
if (collection_id != NULL)
return glnx_throw (error,
"Collection–ref (%s, %s) in bindings for commit %s does not exist",
collection_id, *iter, checksum);
else
return glnx_throw (error,
"Ref ‘%s’ in bindings for commit %s does not exist",
*iter, checksum);
}
else if (g_strcmp0 (checksum_for_ref, checksum) != 0)
{
if (collection_id != NULL)
return glnx_throw (error,
"Collection–ref (%s, %s) in bindings for commit %s does not resolve to that commit",
collection_id, *iter, checksum);
else
return glnx_throw (error,
"Ref ‘%s’ in bindings for commit %s does not resolve to that commit",
*iter, checksum);
}
}
}
}
if (opt_add_tombstones)
{
g_autofree char *parent = ostree_commit_get_parent (commit);
if (parent)
{
g_autoptr(GVariant) parent_commit = NULL;
if (!ostree_repo_load_variant_if_exists (repo, OSTREE_OBJECT_TYPE_COMMIT, parent,
&parent_commit, error))
return FALSE;
if (!parent_commit)
g_ptr_array_add (tombstones, g_strdup (checksum));
}
}
return TRUE;
}
gboolean
ostree_builtin_fsck (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error)
{
@@ -282,17 +366,16 @@ ostree_builtin_fsck (int argc, char **argv, OstreeCommandInvocation *invocation,
}
if (!opt_quiet)
g_print ("Enumerating objects...\n");
g_print ("Enumerating commits...\n");
g_autoptr(GHashTable) objects = NULL;
if (!ostree_repo_list_objects (repo, OSTREE_REPO_LIST_OBJECTS_ALL,
&objects, cancellable, error))
// Find all commit objects, including partial ones
g_autoptr(GHashTable) all_commits = NULL;
if (!ostree_repo_list_commit_objects_starting_with (repo, "", &all_commits, cancellable, error))
return FALSE;
// And gather a set of non-partial commits for further analysis
g_autoptr(GHashTable) commits = g_hash_table_new_full (ostree_hash_object_name, g_variant_equal,
(GDestroyNotify)g_variant_unref, NULL);
g_autoptr(GPtrArray) tombstones = NULL;
if (opt_add_tombstones)
tombstones = g_ptr_array_new_with_free_func (g_free);
@@ -302,8 +385,8 @@ ostree_builtin_fsck (int argc, char **argv, OstreeCommandInvocation *invocation,
guint n_partial = 0;
guint n_fsck_partial = 0;
g_hash_table_iter_init (&hash_iter, objects);
while (g_hash_table_iter_next (&hash_iter, &key, &value))
g_hash_table_iter_init (&hash_iter, all_commits);
while (g_hash_table_iter_next (&hash_iter, &key, NULL))
{
GVariant *serialized_key = key;
const char *checksum;
@@ -313,114 +396,25 @@ ostree_builtin_fsck (int argc, char **argv, OstreeCommandInvocation *invocation,
ostree_object_name_deserialize (serialized_key, &checksum, &objtype);
if (objtype == OSTREE_OBJECT_TYPE_COMMIT)
g_assert (objtype == OSTREE_OBJECT_TYPE_COMMIT);
if (!ostree_repo_load_commit (repo, checksum, &commit, &commitstate, error))
return FALSE;
if (!fsck_one_commit (repo, checksum, commit, tombstones, cancellable, error))
return FALSE;
if (commitstate & OSTREE_REPO_COMMIT_STATE_PARTIAL)
{
if (!ostree_repo_load_commit (repo, checksum, &commit, &commitstate, error))
return FALSE;
/* If requested, check that all the refs listed in the ref-bindings
* for this commit resolve back to this commit. */
if (opt_verify_back_refs)
{
g_autoptr(GVariant) metadata = g_variant_get_child_value (commit, 0);
const char *collection_id = NULL;
if (!g_variant_lookup (metadata,
OSTREE_COMMIT_META_KEY_COLLECTION_BINDING,
"&s",
&collection_id))
collection_id = NULL;
g_autofree const char **refs = NULL;
if (g_variant_lookup (metadata,
OSTREE_COMMIT_META_KEY_REF_BINDING,
"^a&s",
&refs))
{
for (const char **iter = refs; *iter != NULL; ++iter)
{
g_autofree char *checksum_for_ref = NULL;
if (collection_id != NULL)
{
const OstreeCollectionRef collection_ref = { (char *) collection_id, (char *) *iter };
if (!ostree_repo_resolve_collection_ref (repo, &collection_ref,
TRUE,
OSTREE_REPO_RESOLVE_REV_EXT_NONE,
&checksum_for_ref,
cancellable,
error))
return FALSE;
}
else
{
if (!ostree_repo_resolve_rev (repo, *iter, TRUE,
&checksum_for_ref, error))
return FALSE;
}
if (checksum_for_ref == NULL)
{
if (collection_id != NULL)
return glnx_throw (error,
"Collection–ref (%s, %s) in bindings for commit %s does not exist",
collection_id, *iter, checksum);
else
return glnx_throw (error,
"Ref ‘%s’ in bindings for commit %s does not exist",
*iter, checksum);
}
else if (g_strcmp0 (checksum_for_ref, checksum) != 0)
{
if (collection_id != NULL)
return glnx_throw (error,
"Collection–ref (%s, %s) in bindings for commit %s does not resolve to that commit",
collection_id, *iter, checksum);
else
return glnx_throw (error,
"Ref ‘%s’ in bindings for commit %s does not resolve to that commit",
*iter, checksum);
}
}
}
}
if (opt_add_tombstones)
{
GError *local_error = NULL;
g_autofree char *parent = ostree_commit_get_parent (commit);
if (parent)
{
g_autoptr(GVariant) parent_commit = NULL;
if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, parent,
&parent_commit, &local_error))
{
if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
{
g_ptr_array_add (tombstones, g_strdup (checksum));
g_clear_error (&local_error);
}
else
{
g_propagate_error (error, local_error);
return FALSE;
}
}
}
}
if (commitstate & OSTREE_REPO_COMMIT_STATE_PARTIAL)
{
n_partial++;
if (commitstate & OSTREE_REPO_COMMIT_STATE_FSCK_PARTIAL)
n_fsck_partial++;
}
else
g_hash_table_add (commits, g_variant_ref (serialized_key));
n_partial++;
if (commitstate & OSTREE_REPO_COMMIT_STATE_FSCK_PARTIAL)
n_fsck_partial++;
}
}
else
g_hash_table_add (commits, g_variant_ref (serialized_key));
}
g_clear_pointer (&objects, g_hash_table_unref);
g_clear_pointer (&all_commits, g_hash_table_unref);
if (!opt_quiet)
g_print ("Verifying content integrity of %u commit objects...\n",
+20 -30
View File
@@ -201,62 +201,52 @@ out:
gboolean
ostree_builtin_gpg_sign (int argc, char **argv,OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error)
{
g_autoptr(GOptionContext) context = NULL;
g_autoptr(GOptionContext) context = g_option_context_new ("COMMIT KEY-ID...");
g_autoptr(OstreeRepo) repo = NULL;
g_autofree char *resolved_commit = NULL;
const char *commit;
char **key_ids;
int n_key_ids, ii;
gboolean ret = FALSE;
context = g_option_context_new ("COMMIT KEY-ID...");
if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, error))
goto out;
return FALSE;
if (argc < 2)
{
usage_error (context, "Need a COMMIT to sign", error);
goto out;
return FALSE;
}
if (argc < 3)
{
usage_error (context, "Need at least one GPG KEY-ID to sign with", error);
goto out;
return FALSE;
}
commit = argv[1];
key_ids = argv + 2;
n_key_ids = argc - 2;
const char *commit = argv[1];
char **key_ids = argv + 2;
int n_key_ids = argc - 2;
g_autofree char *resolved_commit = NULL;
if (!ostree_repo_resolve_rev (repo, commit, FALSE, &resolved_commit, error))
goto out;
return FALSE;
if (opt_delete)
{
guint n_deleted = 0;
if (delete_signatures (repo, resolved_commit,
(const char * const *) key_ids, n_key_ids,
&n_deleted, cancellable, error))
{
g_print ("Signatures deleted: %u\n", n_deleted);
ret = TRUE;
}
if (!delete_signatures (repo, resolved_commit,
(const char * const *) key_ids, n_key_ids,
&n_deleted, cancellable, error))
return FALSE;
goto out;
g_print ("Signatures deleted: %u\n", n_deleted);
return TRUE;
}
for (ii = 0; ii < n_key_ids; ii++)
for (int ii = 0; ii < n_key_ids; ii++)
{
if (!ostree_repo_sign_commit (repo, resolved_commit, key_ids[ii],
opt_gpg_homedir, cancellable, error))
goto out;
return FALSE;
}
ret = TRUE;
out:
return ret;
return TRUE;
}
+10 -17
View File
@@ -37,45 +37,38 @@ static GOptionEntry option_entries[] = {
gboolean
ot_remote_builtin_list (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error)
{
g_autoptr(GOptionContext) context = NULL;
g_autoptr(GOptionContext) context = g_option_context_new ("");
g_autoptr(OstreeRepo) repo = NULL;
g_auto(GStrv) remotes = NULL;
guint ii, n_remotes = 0;
gboolean ret = FALSE;
context = g_option_context_new ("");
if (!ostree_option_context_parse (context, option_entries, &argc, &argv,
invocation, &repo, cancellable, error))
goto out;
return FALSE;
remotes = ostree_repo_remote_list (repo, &n_remotes);
guint n_remotes = 0;
g_auto(GStrv) remotes = ostree_repo_remote_list (repo, &n_remotes);
if (opt_show_urls)
{
int max_length = 0;
for (ii = 0; ii < n_remotes; ii++)
for (guint ii = 0; ii < n_remotes; ii++)
max_length = MAX (max_length, strlen (remotes[ii]));
for (ii = 0; ii < n_remotes; ii++)
for (guint ii = 0; ii < n_remotes; ii++)
{
g_autofree char *remote_url = NULL;
if (!ostree_repo_remote_get_url (repo, remotes[ii], &remote_url, error))
goto out;
return FALSE;
g_print ("%-*s %s\n", max_length, remotes[ii], remote_url);
}
}
else
{
for (ii = 0; ii < n_remotes; ii++)
for (guint ii = 0; ii < n_remotes; ii++)
g_print ("%s\n", remotes[ii]);
}
ret = TRUE;
out:
return ret;
return TRUE;
}
+9 -15
View File
@@ -39,34 +39,30 @@ static GOptionEntry option_entries[] = {
gboolean
ot_remote_builtin_refs (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error)
{
g_autoptr(GOptionContext) context = NULL;
g_autoptr(GOptionContext) context = g_option_context_new ("NAME");
g_autoptr(OstreeRepo) repo = NULL;
const char *remote_name;
gboolean ret = FALSE;
g_autoptr(GHashTable) refs = NULL;
context = g_option_context_new ("NAME");
if (!ostree_option_context_parse (context, option_entries, &argc, &argv,
invocation, &repo, cancellable, error))
goto out;
return FALSE;
if (argc < 2)
{
ot_util_usage_error (context, "NAME must be specified", error);
goto out;
return FALSE;
}
if (opt_cache_dir)
{
if (!ostree_repo_set_cache_dir (repo, AT_FDCWD, opt_cache_dir, cancellable, error))
goto out;
return FALSE;
}
remote_name = argv[1];
const char *remote_name = argv[1];
g_autoptr(GHashTable) refs = NULL;
if (!ostree_repo_remote_list_refs (repo, remote_name, &refs, cancellable, error))
goto out;
return FALSE;
else
{
g_autoptr(GList) ordered_keys = NULL;
@@ -81,7 +77,5 @@ ot_remote_builtin_refs (int argc, char **argv, OstreeCommandInvocation *invocati
}
}
ret = TRUE;
out:
return ret;
return TRUE;
}