OstreeDeployment * rpmostreed_deployment_get_for_id (OstreeSysroot *sysroot, const gchar *deploy_id) { g_autoptr(GPtrArray) deployments = NULL; guint i; OstreeDeployment *deployment = NULL; deployments = ostree_sysroot_get_deployments (sysroot); if (deployments == NULL) goto out; for (i=0; i<deployments->len; i++) { g_autofree gchar *id = rpmostreed_deployment_generate_id (deployments->pdata[i]); if (g_strcmp0 (deploy_id, id) == 0) { deployment = g_object_ref (deployments->pdata[i]); } } out: return deployment; }
static gboolean sysroot_populate_deployments_unlocked (RpmostreedSysroot *self, gboolean *out_changed, GError **error) { gboolean ret = FALSE; OstreeDeployment *booted = NULL; /* owned by sysroot */ g_autofree gchar *booted_id = NULL; g_autoptr(GPtrArray) deployments = NULL; g_autoptr(GHashTable) seen_osnames = NULL; GHashTableIter iter; gpointer hashkey; gpointer value; GVariantBuilder builder; guint i; gboolean sysroot_changed; gboolean repo_changed; struct stat repo_new_stat; if (!ostree_sysroot_load_if_changed (self->ot_sysroot, &sysroot_changed, self->cancellable, error)) goto out; if (fstat (ostree_repo_get_dfd (self->repo), &repo_new_stat) < 0) { glnx_set_error_from_errno (error); goto out; } repo_changed = !(self->repo_last_stat.st_mtim.tv_sec == repo_new_stat.st_mtim.tv_sec && self->repo_last_stat.st_mtim.tv_nsec == repo_new_stat.st_mtim.tv_nsec); if (repo_changed) self->repo_last_stat = repo_new_stat; if (!(sysroot_changed || repo_changed)) { ret = TRUE; if (out_changed) *out_changed = FALSE; goto out; } g_debug ("loading deployments"); g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}")); seen_osnames = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL); /* Updated booted property */ booted = ostree_sysroot_get_booted_deployment (self->ot_sysroot); if (booted) { const gchar *os = ostree_deployment_get_osname (booted); g_autofree gchar *path = rpmostreed_generate_object_path (BASE_DBUS_PATH, os, NULL); rpmostree_sysroot_set_booted (RPMOSTREE_SYSROOT (self), path); booted_id = rpmostreed_deployment_generate_id (booted); } else { rpmostree_sysroot_set_booted (RPMOSTREE_SYSROOT (self), "/"); } /* Add deployment interfaces */ deployments = ostree_sysroot_get_deployments (self->ot_sysroot); for (i = 0; deployments != NULL && i < deployments->len; i++) { GVariant *variant; OstreeDeployment *deployment = deployments->pdata[i]; const char *deployment_os; variant = rpmostreed_deployment_generate_variant (deployment, booted_id, self->repo, error); if (!variant) goto out; g_variant_builder_add_value (&builder, variant); deployment_os = ostree_deployment_get_osname (deployment); /* Have we not seen this osname instance before? If so, add it * now. */ if (!g_hash_table_contains (self->os_interfaces, deployment_os)) { RPMOSTreeOS *obj = rpmostreed_os_new (self->ot_sysroot, self->repo, deployment_os, self->transaction_monitor); g_hash_table_insert (self->os_interfaces, g_strdup (deployment_os), obj); } /* Owned by deployment, hash lifetime is smaller */ g_hash_table_add (seen_osnames, (char*)deployment_os); } /* Remove dead os paths */ g_hash_table_iter_init (&iter, self->os_interfaces); while (g_hash_table_iter_next (&iter, &hashkey, &value)) { if (!g_hash_table_contains (seen_osnames, hashkey)) { g_object_run_dispose (G_OBJECT (value)); g_hash_table_iter_remove (&iter); } } rpmostree_sysroot_set_deployments (RPMOSTREE_SYSROOT (self), g_variant_builder_end (&builder)); g_debug ("finished deployments"); ret = TRUE; if (out_changed) *out_changed = TRUE; out: 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); }
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); }