New upstream version 2022.5
This commit is contained in:
commit
97f9ef0bb1
55 files changed
+4439
-3030
No files matched your search
@@ -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.
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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:
|
||||
*
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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 }
|
||||
};
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
Reference in new issue
Block a user