/** * hif_state_get_child: **/ HifState * hif_state_get_child (HifState *state) { HifState *child = NULL; g_return_val_if_fail (HIF_IS_STATE (state), NULL); /* do we care */ if (!state->priv->report_progress) { child = state; goto out; } /* already set child */ if (state->priv->child != NULL) { g_signal_handler_disconnect (state->priv->child, state->priv->percentage_child_id); g_signal_handler_disconnect (state->priv->child, state->priv->allow_cancel_child_id); g_signal_handler_disconnect (state->priv->child, state->priv->action_child_id); g_signal_handler_disconnect (state->priv->child, state->priv->package_progress_child_id); g_signal_handler_disconnect (state->priv->child, state->priv->notify_speed_child_id); g_object_unref (state->priv->child); } /* connect up signals */ child = hif_state_new (); child->priv->parent = state; /* do not ref! */ state->priv->child = child; state->priv->percentage_child_id = g_signal_connect (child, "percentage-changed", G_CALLBACK (hif_state_child_percentage_changed_cb), state); state->priv->allow_cancel_child_id = g_signal_connect (child, "allow-cancel-changed", G_CALLBACK (hif_state_child_allow_cancel_changed_cb), state); state->priv->action_child_id = g_signal_connect (child, "action-changed", G_CALLBACK (hif_state_child_action_changed_cb), state); state->priv->package_progress_child_id = g_signal_connect (child, "package-progress-changed", G_CALLBACK (hif_state_child_package_progress_changed_cb), state); state->priv->notify_speed_child_id = g_signal_connect (child, "notify::speed", G_CALLBACK (hif_state_child_notify_speed_cb), state); /* reset child */ child->priv->current = 0; child->priv->last_percentage = 0; /* save so we can recover after child has done */ child->priv->action = state->priv->action; state->priv->child_action = state->priv->action; /* set cancellable, creating if required */ if (state->priv->cancellable == NULL) state->priv->cancellable = g_cancellable_new (); hif_state_set_cancellable (child, state->priv->cancellable); /* set the profile state */ hif_state_set_enable_profile (child, state->priv->enable_profile); out: return child; }
static gboolean install_packages_in_root (RpmOstreeTreeComposeContext *self, RpmOstreeContext *ctx, JsonObject *treedata, GFile *yumroot, char **packages, gboolean *out_unmodified, char **out_new_inputhash, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; guint progress_sigid; GFile *contextdir = self->treefile_context_dirs->pdata[0]; g_autoptr(RpmOstreeInstall) hifinstall = { 0, }; HifContext *hifctx; gs_free char *ret_new_inputhash = NULL; g_autoptr(GKeyFile) treespec = g_key_file_new (); JsonArray *enable_repos = NULL; JsonArray *add_files = NULL; /* TODO - uncomment this once we have SELinux working */ #if 0 g_autofree char *cache_repo_pathstr = glnx_fdrel_abspath (self->cachedir_dfd, "repo"); g_autoptr(GFile) cache_repo_path = g_file_new_for_path (cache_repo_pathstr); glnx_unref_object OstreeRepo *ostreerepo = ostree_repo_new (cache_repo_path); if (!g_file_test (cache_repo_pathstr, G_FILE_TEST_EXISTS)) { if (!ostree_repo_create (ostreerepo, OSTREE_REPO_MODE_BARE_USER, cancellable, error)) goto out; } #endif hifctx = rpmostree_context_get_hif (ctx); if (opt_proxy) hif_context_set_http_proxy (hifctx, opt_proxy); hif_context_set_repo_dir (hifctx, gs_file_get_path_cached (contextdir)); g_key_file_set_string (treespec, "tree", "ref", self->ref); g_key_file_set_string_list (treespec, "tree", "packages", (const char *const*)packages, g_strv_length (packages)); /* Some awful code to translate between JSON and GKeyFile */ if (json_object_has_member (treedata, "install-langs")) { JsonArray *a = json_object_get_array_member (treedata, "install-langs"); if (!set_keyfile_string_array_from_json (treespec, "tree", "install-langs", a, error)) goto out; } /* Bind the json \"repos\" member to the hif state, which looks at the * enabled= member of the repos file. By default we forcibly enable * only repos which are specified, ignoring the enabled= flag. */ if (!json_object_has_member (treedata, "repos")) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Treefile is missing required \"repos\" member"); goto out; } enable_repos = json_object_get_array_member (treedata, "repos"); if (!set_keyfile_string_array_from_json (treespec, "tree", "repos", enable_repos, error)) goto out; { gboolean docs = TRUE; if (!_rpmostree_jsonutil_object_get_optional_boolean_member (treedata, "documentation", &docs, error)) goto out; if (!docs) g_key_file_set_boolean (treespec, "tree", "documentation", FALSE); } { g_autoptr(GError) tmp_error = NULL; g_autoptr(RpmOstreeTreespec) treespec_value = rpmostree_treespec_new_from_keyfile (treespec, &tmp_error); g_assert_no_error (tmp_error); if (!rpmostree_context_setup (ctx, gs_file_get_path_cached (yumroot), "/", treespec_value, cancellable, error)) goto out; } /* --- Downloading metadata --- */ if (!rpmostree_context_download_metadata (ctx, cancellable, error)) goto out; if (!rpmostree_context_prepare_install (ctx, &hifinstall, cancellable, error)) goto out; if (json_object_has_member (treedata, "add-files")) add_files = json_object_get_array_member (treedata, "add-files"); /* FIXME - just do a depsolve here before we compute download requirements */ if (!compute_checksum_from_treefile_and_goal (self, hif_context_get_goal (hifctx), contextdir, add_files, &ret_new_inputhash, error)) goto out; /* Only look for previous checksum if caller has passed *out_unmodified */ if (self->previous_checksum && out_unmodified != NULL) { gs_unref_variant GVariant *commit_v = NULL; gs_unref_variant GVariant *commit_metadata = NULL; const char *previous_inputhash = NULL; if (!ostree_repo_load_variant (self->repo, OSTREE_OBJECT_TYPE_COMMIT, self->previous_checksum, &commit_v, error)) goto out; commit_metadata = g_variant_get_child_value (commit_v, 0); if (g_variant_lookup (commit_metadata, "rpmostree.inputhash", "&s", &previous_inputhash)) { if (strcmp (previous_inputhash, ret_new_inputhash) == 0) { *out_unmodified = TRUE; ret = TRUE; goto out; } } else g_print ("Previous commit found, but without rpmostree.inputhash metadata key\n"); } if (opt_dry_run) { ret = TRUE; goto out; } /* --- Downloading packages --- */ if (!rpmostree_context_download (ctx, hifinstall, cancellable, error)) goto out; { g_auto(GLnxConsoleRef) console = { 0, }; gs_unref_object HifState *hifstate = hif_state_new (); progress_sigid = g_signal_connect (hifstate, "percentage-changed", G_CALLBACK (on_hifstate_percentage_changed), "Installing packages:"); glnx_console_lock (&console); if (!hif_transaction_commit (hif_context_get_transaction (hifctx), hif_context_get_goal (hifctx), hifstate, error)) goto out; g_signal_handler_disconnect (hifstate, progress_sigid); } ret = TRUE; if (out_unmodified) *out_unmodified = FALSE; gs_transfer_out_value (out_new_inputhash, &ret_new_inputhash); out: return ret; }