static void do_countBools (SoupMessage *msg, SoupXMLRPCParams *params) { GVariant *args; GVariant *child; GVariantIter iter; gboolean val; int trues = 0, falses = 0; GVariantDict dict; if (!(args = parse_params (msg, params, "(ab)"))) return; child = g_variant_get_child_value (args, 0); g_variant_iter_init (&iter, child); while (g_variant_iter_loop (&iter, "b", &val)) { if (val) trues++; else falses++; } g_variant_dict_init (&dict, NULL); g_variant_dict_insert (&dict, "true", "i", trues); g_variant_dict_insert (&dict, "false", "i", falses); soup_xmlrpc_message_set_response (msg, g_variant_dict_end (&dict), NULL); g_variant_unref (args); g_variant_unref (child); }
GVariant * rpmostreed_commit_generate_cached_details_variant (OstreeDeployment *deployment, OstreeRepo *repo, const gchar *refspec, GError **error) { g_autoptr(GVariant) commit = NULL; g_autofree gchar *origin_refspec = NULL; g_autofree gchar *head = NULL; gboolean gpg_enabled; const gchar *osname; GVariant *sigs = NULL; /* floating variant */ GVariantDict dict; osname = ostree_deployment_get_osname (deployment); if (refspec) origin_refspec = g_strdup (refspec); else { g_autoptr(RpmOstreeOrigin) origin = NULL; origin = rpmostree_origin_parse_deployment (deployment, error); if (!origin) return NULL; origin_refspec = g_strdup (rpmostree_origin_get_refspec (origin)); } g_assert (origin_refspec); /* allow_noent=TRUE since the ref may have been deleted for a * rebase. */ if (!ostree_repo_resolve_rev (repo, origin_refspec, TRUE, &head, error)) return NULL; if (head == NULL) head = g_strdup (ostree_deployment_get_csum (deployment)); if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, head, &commit, error)) return NULL; sigs = rpmostreed_deployment_gpg_results (repo, origin_refspec, head, &gpg_enabled); g_variant_dict_init (&dict, NULL); if (osname != NULL) g_variant_dict_insert (&dict, "osname", "s", osname); g_variant_dict_insert (&dict, "checksum", "s", head); variant_add_commit_details (&dict, commit); g_variant_dict_insert (&dict, "origin", "s", origin_refspec); if (sigs != NULL) g_variant_dict_insert_value (&dict, "signatures", sigs); g_variant_dict_insert (&dict, "gpg-enabled", "b", gpg_enabled); return g_variant_dict_end (&dict); }
GVariant * rpmostreed_deployment_generate_blank_variant (void) { GVariantDict dict; g_variant_dict_init (&dict, NULL); return g_variant_dict_end (&dict); }
static void test_g_variant_dict (void) { g_autoptr(GVariant) data = g_variant_new_from_data (G_VARIANT_TYPE ("a{sv}"), "", 0, FALSE, NULL, NULL); g_auto(GVariantDict) stackval; g_autoptr(GVariantDict) val = g_variant_dict_new (data); g_variant_dict_init (&stackval, data); g_assert (val != NULL); }
static GVariant * get_args_variant (void) { GVariantDict dict; g_variant_dict_init (&dict, NULL); g_variant_dict_insert (&dict, "reboot", "b", opt_reboot); return g_variant_dict_end (&dict); }
void abrt_p2_task_add_detail(AbrtP2Task *task, const char *key, GVariant *value) { GVariantDict dict; g_variant_dict_init(&dict, task->pv->p2t_details); g_variant_dict_insert(&dict, key, "v", value); if (task->pv->p2t_details) g_variant_unref(task->pv->p2t_details); task->pv->p2t_details = g_variant_dict_end(&dict); }
static GVariant * artist_album_cursor_to_variant_dict (TrackerSparqlCursor *const cursor) { GVariantDict dict; g_variant_dict_init (&dict, NULL); insert_string_value (cursor, &dict, "urn", 0); insert_integer_value (cursor, &dict, "id", 1); insert_string_value (cursor, &dict, "title", 2); return g_variant_dict_end (&dict); }
static GVariant * get_args_variant (const char *revision) { GVariantDict dict; g_variant_dict_init (&dict, NULL); g_variant_dict_insert (&dict, "skip-purge", "b", opt_skip_purge); g_variant_dict_insert (&dict, "reboot", "b", opt_reboot); if (revision != NULL) g_variant_dict_insert (&dict, "revision", "s", revision); return g_variant_dict_end (&dict); }
static GVariant * get_args_variant (void) { GVariantDict dict; g_variant_dict_init (&dict, NULL); g_variant_dict_insert (&dict, "reboot", "b", opt_reboot); g_variant_dict_insert (&dict, "dry-run", "b", opt_dry_run); #if 0 if (opt_no_scripts) g_variant_dict_insert (&dict, "noscripts", "b", TRUE); if (opt_ignore_script) g_variant_dict_insert (&dict, "ignore-scripts", "^as", opt_ignore_script); #endif return g_variant_dict_end (&dict); }
static RpmOstreeTransactionLiveFsFlags livefs_flags_from_options (GVariant *options) { RpmOstreeTransactionLiveFsFlags ret = 0; GVariantDict options_dict; gboolean opt = FALSE; g_variant_dict_init (&options_dict, options); if (g_variant_dict_lookup (&options_dict, "dry-run", "b", &opt) && opt) ret |= RPMOSTREE_TRANSACTION_LIVEFS_FLAG_DRY_RUN; if (g_variant_dict_lookup (&options_dict, "replace", "b", &opt) && opt) ret |= RPMOSTREE_TRANSACTION_LIVEFS_FLAG_REPLACE; g_variant_dict_clear (&options_dict); return ret; }
static GVariant * track_cursor_to_variant_dict (TrackerSparqlCursor *const cursor) { GVariantDict dict; g_variant_dict_init (&dict, NULL); insert_string_value (cursor, &dict, "urn", 0); insert_integer_value (cursor, &dict, "id", 1); insert_string_value (cursor, &dict, "url", 2); insert_string_value (cursor, &dict, "title", 3); insert_integer_value (cursor, &dict, "track-number", 4); insert_integer_value (cursor, &dict, "disc-number", 5); return g_variant_dict_end (&dict); }
GVariant* rpmostree_get_options_variant (gboolean reboot, gboolean allow_downgrade, gboolean skip_purge, gboolean no_pull_base, gboolean dry_run, gboolean no_overrides) { GVariantDict dict; g_variant_dict_init (&dict, NULL); g_variant_dict_insert (&dict, "reboot", "b", reboot); g_variant_dict_insert (&dict, "allow-downgrade", "b", allow_downgrade); g_variant_dict_insert (&dict, "skip-purge", "b", skip_purge); g_variant_dict_insert (&dict, "no-pull-base", "b", no_pull_base); g_variant_dict_insert (&dict, "dry-run", "b", dry_run); g_variant_dict_insert (&dict, "no-overrides", "b", no_overrides); return g_variant_ref_sink (g_variant_dict_end (&dict)); }
static gboolean get_modifiers_variant (const char *set_refspec, const char *set_revision, const char *const* install_pkgs, const char *const* uninstall_pkgs, const char *const* override_replace_pkgs, const char *const* override_remove_pkgs, const char *const* override_reset_pkgs, GVariant **out_modifiers, GUnixFDList **out_fd_list, GError **error) { GVariantDict dict; g_variant_dict_init (&dict, NULL); g_autoptr(GUnixFDList) fd_list = g_unix_fd_list_new (); if (install_pkgs) { if (!vardict_sort_and_insert_pkgs (&dict, "install", fd_list, install_pkgs, error)) return FALSE; } if (override_replace_pkgs) { if (!vardict_sort_and_insert_pkgs (&dict, "override-replace", fd_list, override_replace_pkgs, error)) return FALSE; } if (set_refspec) g_variant_dict_insert (&dict, "set-refspec", "s", set_refspec); if (set_revision) g_variant_dict_insert (&dict, "set-revision", "s", set_revision); vardict_insert_strv (&dict, "uninstall-packages", uninstall_pkgs); vardict_insert_strv (&dict, "override-remove-packages", override_remove_pkgs); vardict_insert_strv (&dict, "override-reset-packages", override_reset_pkgs); *out_fd_list = g_steal_pointer (&fd_list); *out_modifiers = g_variant_ref_sink (g_variant_dict_end (&dict)); return TRUE; }
static void properties_changed (GDBusProxy *proxy, GVariant *changed_properties, GStrv invalidated_properties, gpointer user_data) { GVariant *v; GVariantDict dict; g_variant_dict_init (&dict, changed_properties); if (g_variant_dict_contains (&dict, "HasAccelerometer")) { v = g_dbus_proxy_get_cached_property (iio_proxy, "HasAccelerometer"); g_message ("Accelerometer %s", g_variant_get_boolean (v) ? "appeared" : "disappeared"); g_variant_unref (v); } if (g_variant_dict_contains (&dict, "AccelerometerOrientation")) { v = g_dbus_proxy_get_cached_property (iio_proxy, "AccelerometerOrientation"); g_message ("Accelerometer orientation changed: %s", g_variant_get_string (v, NULL)); g_variant_unref (v); } if (g_variant_dict_contains (&dict, "HasAmbientLight")) { v = g_dbus_proxy_get_cached_property (iio_proxy, "HasAmbientLight"); g_message ("Light sensor %s", g_variant_get_boolean (v) ? "appeared" : "disappeared"); g_variant_unref (v); } if (g_variant_dict_contains (&dict, "LightLevel")) { GVariant *unit; v = g_dbus_proxy_get_cached_property (iio_proxy, "LightLevel"); unit = g_dbus_proxy_get_cached_property (iio_proxy, "LightLevelUnit"); g_message ("Light changed: %lf (%s)", g_variant_get_double (v), g_variant_get_string (unit, NULL)); g_variant_unref (v); g_variant_unref (unit); } }
static gboolean pkg_change (RpmOstreeCommandInvocation *invocation, RPMOSTreeSysroot *sysroot_proxy, const char *const* packages_to_add, const char *const* packages_to_remove, GCancellable *cancellable, GError **error) { const char *const strv_empty[] = { NULL }; if (!packages_to_add) packages_to_add = strv_empty; if (!packages_to_remove) packages_to_remove = strv_empty; glnx_unref_object RPMOSTreeOS *os_proxy = NULL; if (!rpmostree_load_os_proxy (sysroot_proxy, opt_osname, cancellable, &os_proxy, error)) return FALSE; g_autoptr(GVariant) previous_deployment = rpmostree_os_dup_default_deployment (os_proxy); GVariantDict dict; g_variant_dict_init (&dict, NULL); g_variant_dict_insert (&dict, "reboot", "b", opt_reboot); g_variant_dict_insert (&dict, "cache-only", "b", opt_cache_only); g_variant_dict_insert (&dict, "download-only", "b", opt_download_only); g_variant_dict_insert (&dict, "no-pull-base", "b", TRUE); g_variant_dict_insert (&dict, "dry-run", "b", opt_dry_run); g_variant_dict_insert (&dict, "allow-inactive", "b", opt_allow_inactive); g_variant_dict_insert (&dict, "no-layering", "b", opt_uninstall_all); g_autoptr(GVariant) options = g_variant_ref_sink (g_variant_dict_end (&dict)); gboolean met_local_pkg = FALSE; for (const char *const* it = packages_to_add; it && *it; it++) met_local_pkg = met_local_pkg || g_str_has_suffix (*it, ".rpm"); /* Use newer D-Bus API only if we have to. */ g_autofree char *transaction_address = NULL; if (met_local_pkg) { if (!rpmostree_update_deployment (os_proxy, NULL, /* refspec */ NULL, /* revision */ packages_to_add, packages_to_remove, NULL, /* override replace */ NULL, /* override remove */ NULL, /* override reset */ options, &transaction_address, cancellable, error)) return FALSE; } else { if (!rpmostree_os_call_pkg_change_sync (os_proxy, options, packages_to_add, packages_to_remove, NULL, &transaction_address, NULL, cancellable, error)) return FALSE; } return rpmostree_transaction_client_run (invocation, sysroot_proxy, os_proxy, options, FALSE, transaction_address, previous_deployment, cancellable, error); }
gboolean rpmostree_builtin_upgrade (int argc, char **argv, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; GOptionContext *context = g_option_context_new ("- Perform a system upgrade"); glnx_unref_object RPMOSTreeOS *os_proxy = NULL; glnx_unref_object RPMOSTreeSysroot *sysroot_proxy = NULL; g_autoptr(GVariant) default_deployment = NULL; g_autofree char *transaction_address = NULL; if (!rpmostree_option_context_parse (context, option_entries, &argc, &argv, RPM_OSTREE_BUILTIN_FLAG_NONE, cancellable, &sysroot_proxy, error)) goto out; if (opt_check_diff && opt_reboot) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "cannot specify both --reboot and --check-diff"); goto out; } if (!rpmostree_load_os_proxy (sysroot_proxy, opt_osname, cancellable, &os_proxy, error)) goto out; if (opt_check_diff) { if (!rpmostree_os_call_download_update_rpm_diff_sync (os_proxy, &transaction_address, cancellable, error)) goto out; } else { g_signal_connect (os_proxy, "notify::default-deployment", G_CALLBACK (default_changed_callback), &default_deployment); if (!rpmostree_os_call_upgrade_sync (os_proxy, get_args_variant (), &transaction_address, cancellable, error)) goto out; } if (!rpmostree_transaction_get_response_sync (sysroot_proxy, transaction_address, cancellable, error)) goto out; if (opt_check_diff) { /* yes, doing this without using dbus */ gs_unref_object OstreeSysroot *sysroot = NULL; gs_unref_object OstreeRepo *repo = NULL; gs_unref_object GFile *rpmdbdir = NULL; gs_unref_object GFile *sysroot_file = NULL; g_autofree char *origin_description = NULL; g_autoptr(GVariant) cached_update = NULL; const char *sysroot_path; GVariantDict upgrade_dict; _cleanup_rpmrev_ struct RpmRevisionData *rpmrev1 = NULL; _cleanup_rpmrev_ struct RpmRevisionData *rpmrev2 = NULL; gs_free char *ref = NULL; /* location of this rev */ gs_free char *remote = NULL; if (!rpmostree_os_get_has_cached_update_rpm_diff (os_proxy)) goto out; sysroot_path = rpmostree_sysroot_get_path (sysroot_proxy); sysroot_file = g_file_new_for_path (sysroot_path); sysroot = ostree_sysroot_new (sysroot_file); if (!ostree_sysroot_load (sysroot, cancellable, error)) goto out; if (!ostree_sysroot_get_repo (sysroot, &repo, cancellable, error)) goto out; cached_update = rpmostree_os_dup_cached_update(os_proxy); g_variant_dict_init (&upgrade_dict, cached_update); if (!g_variant_dict_lookup (&upgrade_dict, "origin", "s", &origin_description)) goto out; if (!ostree_parse_refspec (origin_description, &remote, &ref, error)) goto out; if (rpmReadConfigFiles (NULL, NULL)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "rpm failed to init: %s", rpmlogMessage ()); goto out; } if (!(rpmrev1 = rpmrev_new (repo, ostree_deployment_get_csum (ostree_sysroot_get_booted_deployment (sysroot)), NULL, cancellable, error))) goto out; if (!(rpmrev2 = rpmrev_new (repo, ref, NULL, cancellable, error))) goto out; rpmhdrs_diff_prnt_diff (rpmhdrs_diff (rpmrev_get_headers (rpmrev1), rpmrev_get_headers (rpmrev2))); } else { /* nothing changed */ if (default_deployment == NULL) { goto out; } if (!opt_reboot) { const char *sysroot_path; sysroot_path = rpmostree_sysroot_get_path (sysroot_proxy); if (!rpmostree_print_treepkg_diff_from_sysroot_path (sysroot_path, cancellable, error)) goto out; g_print ("Run \"systemctl reboot\" to start a reboot\n"); } } ret = TRUE; out: /* Does nothing if using the message bus. */ rpmostree_cleanup_peer (); return ret; }
GVariant * rpmostreed_deployment_generate_variant (OstreeDeployment *deployment, OstreeRepo *repo) { g_autoptr(GVariant) commit = NULL; g_autofree gchar *origin_refspec = NULL; g_autofree gchar *version_commit = NULL; g_autofree gchar *id = NULL; GVariant *sigs = NULL; /* floating variant */ GError *error = NULL; GVariantDict dict; guint64 timestamp = 0; const gchar *osname = ostree_deployment_get_osname (deployment); const gchar *csum = ostree_deployment_get_csum (deployment); gint serial = ostree_deployment_get_deployserial (deployment); id = rpmostreed_deployment_generate_id (deployment); if (ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, csum, &commit, &error)) { g_autoptr(GVariant) metadata = NULL; timestamp = ostree_commit_get_timestamp (commit); metadata = g_variant_get_child_value (commit, 0); if (metadata != NULL) g_variant_lookup (metadata, "version", "s", &version_commit); } else { g_warning ("Error loading commit %s", error->message); } g_clear_error (&error); origin_refspec = rpmostreed_deployment_get_refspec (deployment); if (origin_refspec) sigs = rpmostreed_deployment_gpg_results (repo, origin_refspec, csum); g_variant_dict_init (&dict, NULL); g_variant_dict_insert (&dict, "id", "s", id); if (osname != NULL) g_variant_dict_insert (&dict, "osname", "s", osname); g_variant_dict_insert (&dict, "serial", "i", serial); g_variant_dict_insert (&dict, "checksum", "s", csum); if (version_commit != NULL) g_variant_dict_insert (&dict, "version", "s", version_commit); if (timestamp > 0) g_variant_dict_insert (&dict, "timestamp", "t", timestamp); if (origin_refspec != NULL) g_variant_dict_insert (&dict, "origin", "s", origin_refspec); if (sigs != NULL) g_variant_dict_insert_value (&dict, "signatures", sigs); return g_variant_dict_end (&dict); }
static void abrt_p2_task_finish_gtask(GObject *source_object, GAsyncResult *result, gpointer user_data) { AbrtP2Task *task = ABRT_P2_TASK(source_object); if (!g_task_is_valid(result, task)) { error_msg("BUG:%s:%s: invalid GTask", __FILE__, __func__); return; } GError *error = NULL; const gint32 code = g_task_propagate_int(G_TASK(result), &error); if (code == ABRT_P2_TASK_CODE_STOP) { log_debug("Task stopped"); abrt_p2_task_change_status(task, ABRT_P2_TASK_STATUS_STOPPED); } else if (code >= ABRT_P2_TASK_CODE_DONE) { log_debug("Task done"); task->pv->p2t_code = code - ABRT_P2_TASK_CODE_DONE; abrt_p2_task_change_status(task, ABRT_P2_TASK_STATUS_DONE); } else if (abrt_p2_task_is_cancelled(task)) { if (error != NULL) { log_debug("Task canceled with error: %s", error->message); g_error_free(error); error = NULL; } else log_debug("Task canceled"); ABRT_P2_TASK_VIRTUAL_CANCEL(task, &error); abrt_p2_task_change_status(task, ABRT_P2_TASK_STATUS_CANCELED); } else { GVariantDict response; g_variant_dict_init(&response, NULL); if (error != NULL) { log_debug("Task failed with error: %s", error->message); g_variant_dict_insert(&response, "Error.Message", "s", error->message); g_error_free(error); } else if (code == ABRT_P2_TASK_CODE_ERROR) { log_debug("Task failed without error message"); g_variant_dict_insert(&response, "Error.Message", "s", "Task failed"); } else { error_msg("BUG:%s:%s: unknown Task return code: %d", __FILE__, __func__, code); g_variant_dict_insert(&response, "Error.Message", "s", "Internal error: Invalid Task return code"); } abrt_p2_task_set_response(task, g_variant_dict_end(&response)); abrt_p2_task_change_status(task, ABRT_P2_TASK_STATUS_FAILED); } g_object_unref(task->pv->p2t_cancellable); task->pv->p2t_cancellable = NULL; }
GVariant * rpmostreed_deployment_generate_variant (OstreeDeployment *deployment, const char *booted_id, OstreeRepo *repo, GError **error) { g_autoptr(GVariant) commit = NULL; g_autoptr(RpmOstreeOrigin) origin = NULL; g_autofree gchar *id = NULL; GVariant *sigs = NULL; /* floating variant */ GVariantDict dict; const gchar *osname = ostree_deployment_get_osname (deployment); const gchar *csum = ostree_deployment_get_csum (deployment); gint serial = ostree_deployment_get_deployserial (deployment); gboolean gpg_enabled = FALSE; if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, csum, &commit, error)) return NULL; id = rpmostreed_deployment_generate_id (deployment); origin = rpmostree_origin_parse_deployment (deployment, error); if (!origin) return NULL; g_variant_dict_init (&dict, NULL); g_variant_dict_insert (&dict, "id", "s", id); if (osname != NULL) g_variant_dict_insert (&dict, "osname", "s", osname); g_variant_dict_insert (&dict, "serial", "i", serial); g_variant_dict_insert (&dict, "checksum", "s", csum); if (rpmostree_origin_is_locally_assembled (origin)) { const char *parent = ostree_commit_get_parent (commit); g_assert (parent); g_variant_dict_insert (&dict, "base-checksum", "s", parent); sigs = rpmostreed_deployment_gpg_results (repo, rpmostree_origin_get_refspec (origin), parent, &gpg_enabled); } else sigs = rpmostreed_deployment_gpg_results (repo, rpmostree_origin_get_refspec (origin), csum, &gpg_enabled); variant_add_commit_details (&dict, commit); g_variant_dict_insert (&dict, "origin", "s", rpmostree_origin_get_refspec (origin)); if (rpmostree_origin_get_packages (origin) != NULL) g_variant_dict_insert (&dict, "packages", "^as", rpmostree_origin_get_packages (origin)); if (sigs != NULL) g_variant_dict_insert_value (&dict, "signatures", sigs); g_variant_dict_insert (&dict, "gpg-enabled", "b", gpg_enabled); g_variant_dict_insert (&dict, "unlocked", "s", ostree_deployment_unlocked_state_to_string (ostree_deployment_get_unlocked (deployment))); if (booted_id != NULL) g_variant_dict_insert (&dict, "booted", "b", g_strcmp0 (booted_id, id) == 0); return g_variant_dict_end (&dict); }
int rpmostree_builtin_status (int argc, char **argv, GCancellable *cancellable, GError **error) { int exit_status = EXIT_FAILURE; GOptionContext *context = g_option_context_new ("- Get the version of the booted system"); glnx_unref_object RPMOSTreeOS *os_proxy = NULL; glnx_unref_object RPMOSTreeSysroot *sysroot_proxy = NULL; g_autoptr(GVariant) booted_deployment = NULL; g_autoptr(GVariant) deployments = NULL; g_autoptr(GVariant) booted_signatures = NULL; g_autoptr(GPtrArray) deployment_dicts = NULL; GVariantIter iter; GVariant *child; g_autofree gchar *booted_id = NULL; const guint CSUM_DISP_LEN = 10; /* number of checksum characters to display */ guint i, n; guint max_timestamp_len = 19; /* length of timestamp "YYYY-MM-DD HH:MM:SS" */ guint max_id_len = CSUM_DISP_LEN; /* length of checksum ID */ guint max_osname_len = 0; /* maximum length of osname - determined in code */ guint max_refspec_len = 0; /* maximum length of refspec - determined in code */ guint max_version_len = 0; /* maximum length of version - determined in code */ guint buffer = 5; /* minimum space between end of one entry and new column */ if (!rpmostree_option_context_parse (context, option_entries, &argc, &argv, RPM_OSTREE_BUILTIN_FLAG_NONE, cancellable, &sysroot_proxy, error)) goto out; if (!rpmostree_load_os_proxy (sysroot_proxy, NULL, cancellable, &os_proxy, error)) goto out; booted_deployment = rpmostree_os_dup_booted_deployment (os_proxy); if (booted_deployment) { GVariantDict dict; g_variant_dict_init (&dict, booted_deployment); g_variant_dict_lookup (&dict, "id", "s", &booted_id); booted_signatures = g_variant_dict_lookup_value (&dict, "signatures", G_VARIANT_TYPE ("av")); g_variant_dict_clear (&dict); } deployment_dicts = g_ptr_array_new_with_free_func ((GDestroyNotify) g_variant_dict_unref); deployments = rpmostree_sysroot_dup_deployments (sysroot_proxy); g_variant_iter_init (&iter, deployments); while ((child = g_variant_iter_next_value (&iter)) != NULL) { GVariantDict *dict = g_variant_dict_new (child); /* Takes ownership of the dictionary */ g_ptr_array_add (deployment_dicts, dict); /* find lengths for use in column output */ if (!opt_pretty) { gchar *origin_refspec = NULL; /* borrowed */ gchar *os_name = NULL; /* borrowed */ gchar *version_string = NULL; /* borrowed */ /* osname should always be present. */ if (g_variant_dict_lookup (dict, "osname", "&s", &os_name)) max_osname_len = MAX (max_osname_len, strlen (os_name)); else { const char *id = NULL; g_variant_dict_lookup (dict, "id", "&s", &id); g_critical ("Deployment '%s' missing osname", id != NULL ? id : "?"); } if (g_variant_dict_lookup (dict, "version", "&s", &version_string)) max_version_len = MAX (max_version_len, strlen (version_string)); if (g_variant_dict_lookup (dict, "origin", "&s", &origin_refspec)) max_refspec_len = MAX (max_refspec_len, strlen (origin_refspec)); } g_variant_unref (child); } if (!opt_pretty) { /* print column headers */ g_print (" %-*s", max_timestamp_len+buffer,"TIMESTAMP (UTC)"); if (max_version_len) g_print ("%-*s", max_version_len+buffer,"VERSION"); g_print ("%-*s%-*s%-*s\n", max_id_len+buffer, "ID", max_osname_len+buffer, "OSNAME", max_refspec_len+buffer, "REFSPEC"); } /* header for "pretty" row output */ else printchar ("=", 60); n = deployment_dicts->len; /* print entries for each deployment */ for (i = 0; i < n; i++) { GVariantDict *dict; g_autoptr(GDateTime) timestamp = NULL; g_autofree char *timestamp_string = NULL; g_autofree gchar *truncated_csum = NULL; g_autoptr(GVariant) signatures = NULL; gchar *id = NULL; /* borrowed */ gchar *origin_refspec = NULL; /* borrowed */ gchar *os_name = NULL; /* borrowed */ gchar *version_string = NULL; /* borrowed */ gchar *checksum = NULL; /* borrowed */ guint64 t = 0; gint serial; gboolean is_booted = FALSE; dict = g_ptr_array_index (deployment_dicts, i); g_variant_dict_lookup (dict, "id", "&s", &id); g_variant_dict_lookup (dict, "osname", "&s", &os_name); g_variant_dict_lookup (dict, "serial", "i", &serial); g_variant_dict_lookup (dict, "checksum", "s", &checksum); g_variant_dict_lookup (dict, "version", "s", &version_string); g_variant_dict_lookup (dict, "timestamp", "t", &t); g_variant_dict_lookup (dict, "origin", "s", &origin_refspec); signatures = g_variant_dict_lookup_value (dict, "signatures", G_VARIANT_TYPE ("av")); is_booted = g_strcmp0 (booted_id, id) == 0; timestamp = g_date_time_new_from_unix_utc (t); if (timestamp != NULL) timestamp_string = g_date_time_format (timestamp, "%Y-%m-%d %T"); else timestamp_string = g_strdup_printf ("(invalid)"); /* truncate checksum */ truncated_csum = g_strndup (checksum, CSUM_DISP_LEN); /* print deployment info column */ if (!opt_pretty) { g_print ("%c %-*s", is_booted ? '*' : ' ', max_timestamp_len+buffer, timestamp_string); if (max_version_len) g_print ("%-*s", max_version_len+buffer, version_string ? version_string : ""); g_print ("%-*s%-*s%-*s\n", max_id_len+buffer, truncated_csum, max_osname_len+buffer, os_name, max_refspec_len+buffer, origin_refspec); } /* print "pretty" row info */ else { guint tab = 11; char *title = NULL; if (i==0) title = "DEFAULT ON BOOT"; else if (is_booted || n <= 2) title = "NON-DEFAULT ROLLBACK TARGET"; else title = "NON-DEFAULT DEPLOYMENT"; g_print (" %c %s\n", is_booted ? '*' : ' ', title); printchar ("-", 40); if (version_string) g_print (" %-*s%-*s\n", tab, "version", tab, version_string); g_print (" %-*s%-*s\n %-*s%-*s.%d\n %-*s%-*s\n %-*s%-*s\n", tab, "timestamp", tab, timestamp_string, tab, "id", tab, checksum, serial, tab, "osname", tab, os_name, tab, "refspec", tab, origin_refspec); if (signatures != NULL) rpmostree_print_signatures (signatures, " GPG: "); printchar ("=", 60); } } /* Print any signatures for the booted deployment, but only in NON-pretty * mode. We save this for the end to preserve the tabular formatting for * deployments. */ if (!opt_pretty && booted_signatures != NULL) { guint n_sigs = g_variant_n_children (booted_signatures); if (n_sigs > 0) { /* XXX If we ever add internationalization, use ngettext() here. */ g_print ("\nGPG: Found %u signature%s on the booted deployment (*):\n", n_sigs, n_sigs == 1 ? "" : "s"); rpmostree_print_signatures (booted_signatures, " "); } } exit_status = EXIT_SUCCESS; out: /* Does nothing if using the message bus. */ rpmostree_cleanup_peer (); return exit_status; }
static gboolean rewrite_delta (OstreeRepo *src_repo, const char *src_commit, OstreeRepo *dst_repo, const char *dst_commit, GVariant *dst_commitv, const char *from, GError **error) { g_autoptr(GFile) src_delta_file = NULL; g_autoptr(GFile) dst_delta_file = NULL; g_autofree char *src_detached_key = _ostree_get_relative_static_delta_path (from, src_commit, "commitmeta"); g_autofree char *dst_detached_key = _ostree_get_relative_static_delta_path (from, dst_commit, "commitmeta"); g_autofree char *src_delta_dir = _ostree_get_relative_static_delta_path (from, src_commit, NULL); g_autofree char *dst_delta_dir = _ostree_get_relative_static_delta_path (from, dst_commit, NULL); g_autofree char *src_superblock_path = _ostree_get_relative_static_delta_path (from, src_commit, "superblock"); g_autofree char *dst_superblock_path = _ostree_get_relative_static_delta_path (from, dst_commit, "superblock"); GMappedFile *mfile = NULL; g_auto(GVariantBuilder) superblock_builder = FLATPAK_VARIANT_BUILDER_INITIALIZER; g_autoptr(GVariant) src_superblock = NULL; g_autoptr(GVariant) dst_superblock = NULL; g_autoptr(GBytes) bytes = NULL; g_autoptr(GVariant) dst_detached = NULL; g_autoptr(GVariant) src_metadata = NULL; g_autoptr(GVariant) src_recurse = NULL; g_autoptr(GVariant) src_parts = NULL; g_auto(GVariantDict) dst_metadata_dict = FLATPAK_VARIANT_DICT_INITIALIZER; int i; src_delta_file = g_file_resolve_relative_path (ostree_repo_get_path (src_repo), src_superblock_path); mfile = g_mapped_file_new (flatpak_file_get_path_cached (src_delta_file), FALSE, NULL); if (mfile == NULL) return TRUE; /* No superblock, not an error */ bytes = g_mapped_file_get_bytes (mfile); g_mapped_file_unref (mfile); src_superblock = g_variant_ref_sink (g_variant_new_from_bytes (G_VARIANT_TYPE (OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT), bytes, FALSE)); src_metadata = g_variant_get_child_value (src_superblock, 0); src_recurse = g_variant_get_child_value (src_superblock, 5); src_parts = g_variant_get_child_value (src_superblock, 6); if (g_variant_n_children (src_recurse) != 0) return flatpak_fail (error, "Recursive deltas not supported, ignoring"); g_variant_builder_init (&superblock_builder, G_VARIANT_TYPE (OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT)); g_variant_dict_init (&dst_metadata_dict, src_metadata); g_variant_dict_remove (&dst_metadata_dict, src_detached_key); if (ostree_repo_read_commit_detached_metadata (dst_repo, dst_commit, &dst_detached, NULL, NULL) && dst_detached != NULL) g_variant_dict_insert_value (&dst_metadata_dict, dst_detached_key, dst_detached); g_variant_builder_add_value (&superblock_builder, g_variant_dict_end (&dst_metadata_dict)); g_variant_builder_add_value (&superblock_builder, g_variant_get_child_value (src_superblock, 1)); /* timestamp */ g_variant_builder_add_value (&superblock_builder, from ? ostree_checksum_to_bytes_v (from) : new_bytearray ((guchar *) "", 0)); g_variant_builder_add_value (&superblock_builder, ostree_checksum_to_bytes_v (dst_commit)); g_variant_builder_add_value (&superblock_builder, dst_commitv); g_variant_builder_add_value (&superblock_builder, src_recurse); g_variant_builder_add_value (&superblock_builder, src_parts); g_variant_builder_add_value (&superblock_builder, g_variant_get_child_value (src_superblock, 7)); /* fallback */ dst_superblock = g_variant_ref_sink (g_variant_builder_end (&superblock_builder)); if (!glnx_shutil_mkdir_p_at (ostree_repo_get_dfd (dst_repo), dst_delta_dir, 0755, NULL, error)) return FALSE; for (i = 0; i < g_variant_n_children (src_parts); i++) { g_autofree char *src_part_path = g_strdup_printf ("%s/%d", src_delta_dir, i); g_autofree char *dst_part_path = g_strdup_printf ("%s/%d", dst_delta_dir, i); if (!glnx_file_copy_at (ostree_repo_get_dfd (src_repo), src_part_path, NULL, ostree_repo_get_dfd (dst_repo), dst_part_path, GLNX_FILE_COPY_OVERWRITE | GLNX_FILE_COPY_NOXATTRS, NULL, error)) return FALSE; } dst_delta_file = g_file_resolve_relative_path (ostree_repo_get_path (dst_repo), dst_superblock_path); if (!flatpak_variant_save (dst_delta_file, dst_superblock, NULL, error)) return FALSE; return TRUE; }
/** * rpmostreed_repo_pull_ancestry: * @repo: Repo * @refspec: Repository branch * @visitor: (allow-none): Visitor function to call on each commit * @visitor_data: (allow-none): User data for @visitor * @progress: (allow-none): Progress * @cancellable: Cancellable * @error: Error * * Downloads an ancestry of commit objects starting from @refspec. * * If a @visitor function pointer is given, commit objects are downloaded * in batches and the @visitor function is called for each commit object. * The @visitor function can stop the recursion, such as when looking for * a particular commit. * * Returns: %TRUE on success, %FALSE on failure */ gboolean rpmostreed_repo_pull_ancestry (OstreeRepo *repo, const char *refspec, RpmostreedCommitVisitor visitor, gpointer visitor_data, OstreeAsyncProgress *progress, GCancellable *cancellable, GError **error) { OstreeRepoPullFlags flags; GVariantDict options; GVariant *refs_value; const char *refs_array[] = { NULL, NULL }; g_autofree char *remote = NULL; g_autofree char *ref = NULL; g_autofree char *checksum = NULL; int depth, ii; gboolean ret = FALSE; g_return_val_if_fail (OSTREE_IS_REPO (repo), FALSE); g_return_val_if_fail (refspec != NULL, FALSE); if (!ostree_parse_refspec (refspec, &remote, &ref, error)) goto out; /* If no visitor function was provided then we won't be short-circuiting * the recursion, so pull everything in one shot. Otherwise pull commits * in increasingly large batches. */ depth = (visitor != NULL) ? 10 : -1; flags = OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY; /* It's important to use the ref name instead of a checksum on the first * pass because we want to search from the latest available commit on the * remote server, which is not necessarily what the ref name is currently * pointing at in our local repo. */ refs_array[0] = ref; while (TRUE) { /* Floating reference, transferred to dictionary. */ refs_value = g_variant_new_strv ((const char * const *) refs_array, -1); g_variant_dict_init (&options, NULL); g_variant_dict_insert (&options, "depth", "i", depth); g_variant_dict_insert (&options, "flags", "i", flags); g_variant_dict_insert_value (&options, "refs", refs_value); if (!ostree_repo_pull_with_options (repo, remote, g_variant_dict_end (&options), progress, cancellable, error)) goto out; /* First pass only. Now we can resolve the ref to a checksum. */ if (checksum == NULL) { if (!ostree_repo_resolve_rev (repo, ref, FALSE, &checksum, error)) goto out; } /* If depth is negative (no visitor), this loop is skipped. */ for (ii = 0; ii < depth && checksum != NULL; ii++) { g_autoptr(GVariant) commit = NULL; gboolean stop = FALSE; if (!ostree_repo_load_commit (repo, checksum, &commit, NULL, error)) goto out; if (!visitor (repo, checksum, commit, visitor_data, &stop, error)) goto out; g_clear_pointer (&checksum, g_free); if (!stop) checksum = ostree_commit_get_parent (commit); } /* Break if no visitor, or visitor told us to stop. */ if (depth < 0 || checksum == NULL) break; /* Pull the next batch of commits, twice as many. */ refs_array[0] = checksum; depth = depth * 2; } ret = TRUE; out: return ret; }