static gboolean generate_deployment_refs_and_prune (OstreeSysroot *self, OstreeRepo *repo, int bootversion, int subbootversion, GPtrArray *deployments, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; int cleanup_bootversion; int cleanup_subbootversion; guint i; gint n_objects_total, n_objects_pruned; guint64 freed_space; cleanup_bootversion = (bootversion == 0) ? 1 : 0; cleanup_subbootversion = (subbootversion == 0) ? 1 : 0; if (!cleanup_ref_prefix (repo, cleanup_bootversion, 0, cancellable, error)) goto out; if (!cleanup_ref_prefix (repo, cleanup_bootversion, 1, cancellable, error)) goto out; if (!cleanup_ref_prefix (repo, bootversion, cleanup_subbootversion, cancellable, error)) goto out; for (i = 0; i < deployments->len; i++) { OstreeDeployment *deployment = deployments->pdata[i]; gs_free char *refname = g_strdup_printf ("ostree/%d/%d/%u", bootversion, subbootversion, i); if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error)) goto out; ostree_repo_transaction_set_refspec (repo, refname, ostree_deployment_get_csum (deployment)); if (!ostree_repo_commit_transaction (repo, NULL, cancellable, error)) goto out; } if (!ostree_repo_prune (repo, OSTREE_REPO_PRUNE_FLAGS_REFS_ONLY, 0, &n_objects_total, &n_objects_pruned, &freed_space, cancellable, error)) goto out; if (freed_space > 0) { char *freed_space_str = g_format_size_full (freed_space, 0); g_print ("Freed objects: %s\n", freed_space_str); } ret = TRUE; out: ostree_repo_abort_transaction (repo, cancellable, NULL); return ret; }
gboolean ostree_builtin_prune (int argc, char **argv, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; GOptionContext *context; glnx_unref_object OstreeRepo *repo = NULL; g_autofree char *formatted_freed_size = NULL; OstreeRepoPruneFlags pruneflags = 0; gint n_objects_total; gint n_objects_pruned; guint64 objsize_total; context = g_option_context_new ("- Search for unreachable objects"); if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error)) goto out; if (!opt_no_prune && !ostree_ensure_repo_writable (repo, error)) goto out; if (opt_delete_commit) { if (opt_no_prune) { ot_util_usage_error (context, "Cannot specify both --delete-commit and --no-prune", error); goto out; } if (opt_static_deltas_only) { if(!ostree_repo_prune_static_deltas (repo, opt_delete_commit, cancellable, error)) goto out; } else if (!delete_commit (repo, opt_delete_commit, cancellable, error)) goto out; } if (opt_keep_younger_than) { if (opt_no_prune) { ot_util_usage_error (context, "Cannot specify both --keep-younger-than and --no-prune", error); goto out; } if (!prune_commits_keep_younger_than_date (repo, opt_keep_younger_than, cancellable, error)) goto out; } if (opt_refs_only) pruneflags |= OSTREE_REPO_PRUNE_FLAGS_REFS_ONLY; if (opt_no_prune) pruneflags |= OSTREE_REPO_PRUNE_FLAGS_NO_PRUNE; if (!ostree_repo_prune (repo, pruneflags, opt_depth, &n_objects_total, &n_objects_pruned, &objsize_total, cancellable, error)) goto out; formatted_freed_size = g_format_size_full (objsize_total, 0); g_print ("Total objects: %u\n", n_objects_total); if (n_objects_pruned == 0) g_print ("No unreachable objects\n"); else if (pruneflags & OSTREE_REPO_PRUNE_FLAGS_NO_PRUNE) g_print ("Would delete: %u objects, freeing %s\n", n_objects_pruned, formatted_freed_size); else g_print ("Deleted %u objects, %s freed\n", n_objects_pruned, formatted_freed_size); ret = TRUE; out: if (context) g_option_context_free (context); return ret; }
gboolean flatpak_builtin_build_update_repo (int argc, char **argv, GCancellable *cancellable, GError **error) { g_autoptr(GOptionContext) context = NULL; g_autoptr(GFile) repofile = NULL; g_autoptr(OstreeRepo) repo = NULL; const char *location; g_autoptr(GPtrArray) unwanted_deltas = NULL; context = g_option_context_new (_("LOCATION - Update repository metadata")); g_option_context_set_translation_domain (context, GETTEXT_PACKAGE); if (!flatpak_option_context_parse (context, options, &argc, &argv, FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, cancellable, error)) return FALSE; if (argc < 2) return usage_error (context, _("LOCATION must be specified"), error); if (opt_static_delta_jobs <= 0) opt_static_delta_jobs = g_get_num_processors (); location = argv[1]; repofile = g_file_new_for_commandline_arg (location); repo = ostree_repo_new (repofile); if (!ostree_repo_open (repo, cancellable, error)) return FALSE; if (opt_generate_delta_to) { if (!generate_one_delta (repo, opt_generate_delta_from, opt_generate_delta_to, opt_generate_delta_ref, cancellable, error)) return FALSE; return TRUE; } if (opt_title && !flatpak_repo_set_title (repo, opt_title[0] ? opt_title : NULL, error)) return FALSE; if (opt_comment && !flatpak_repo_set_comment (repo, opt_comment[0] ? opt_comment : NULL, error)) return FALSE; if (opt_description && !flatpak_repo_set_description (repo, opt_description[0] ? opt_description : NULL, error)) return FALSE; if (opt_homepage && !flatpak_repo_set_homepage (repo, opt_homepage[0] ? opt_homepage : NULL, error)) return FALSE; if (opt_icon && !flatpak_repo_set_icon (repo, opt_icon[0] ? opt_icon : NULL, error)) return FALSE; if (opt_redirect_url && !flatpak_repo_set_redirect_url (repo, opt_redirect_url[0] ? opt_redirect_url : NULL, error)) return FALSE; if (opt_default_branch && !flatpak_repo_set_default_branch (repo, opt_default_branch[0] ? opt_default_branch : NULL, error)) return FALSE; if (opt_collection_id != NULL) { /* Only allow a transition from no collection ID to a non-empty collection ID. * Changing the collection ID between two different non-empty values is too * dangerous: it will break all clients who have previously pulled from the repository. * Require the user to recreate the repository from scratch in that case. */ const char *old_collection_id = ostree_repo_get_collection_id (repo); const char *new_collection_id = opt_collection_id[0] ? opt_collection_id : NULL; if (old_collection_id != NULL && g_strcmp0 (old_collection_id, new_collection_id) != 0) return flatpak_fail (error, "The collection ID of an existing repository cannot be changed. " "Recreate the repository to change or clear its collection ID."); if (!flatpak_repo_set_collection_id (repo, new_collection_id, error)) return FALSE; } if (opt_deploy_collection_id && !flatpak_repo_set_deploy_collection_id (repo, TRUE, error)) return FALSE; if (opt_gpg_import) { g_autoptr(GBytes) gpg_data = flatpak_load_gpg_keys (opt_gpg_import, cancellable, error); if (gpg_data == NULL) return FALSE; if (!flatpak_repo_set_gpg_keys (repo, gpg_data, error)) return FALSE; } if (!opt_no_update_appstream) { g_print (_("Updating appstream branch\n")); if (!flatpak_repo_generate_appstream (repo, (const char **) opt_gpg_key_ids, opt_gpg_homedir, 0, cancellable, error)) return FALSE; } if (opt_generate_deltas && !generate_all_deltas (repo, &unwanted_deltas, cancellable, error)) return FALSE; if (unwanted_deltas != NULL) { int i; for (i = 0; i < unwanted_deltas->len; i++) { const char *delta = g_ptr_array_index (unwanted_deltas, i); g_print ("Deleting unwanted delta: %s\n", delta); g_autoptr(GError) my_error = NULL; if (!_ostree_repo_static_delta_delete (repo, delta, cancellable, &my_error)) g_printerr ("Unable to delete delta %s: %s\n", delta, my_error->message); } } if (!opt_no_update_summary) { g_print (_("Updating summary\n")); if (!flatpak_repo_update (repo, (const char **) opt_gpg_key_ids, opt_gpg_homedir, cancellable, error)) return FALSE; } if (opt_prune) { gint n_objects_total; gint n_objects_pruned; guint64 objsize_total; g_autofree char *formatted_freed_size = NULL; g_print ("Pruning old commits\n"); if (!ostree_repo_prune (repo, OSTREE_REPO_PRUNE_FLAGS_REFS_ONLY, opt_prune_depth, &n_objects_total, &n_objects_pruned, &objsize_total, cancellable, error)) return FALSE; formatted_freed_size = g_format_size_full (objsize_total, 0); g_print (_("Total objects: %u\n"), n_objects_total); if (n_objects_pruned == 0) g_print (_("No unreachable objects\n")); else g_print (_("Deleted %u objects, %s freed\n"), n_objects_pruned, formatted_freed_size); } return TRUE; }