app/uninstall: Add --all switch to drop all layering

This is one part of #1387 and is prep for a single higher level command
that makes it easier to remove all customizations (layering *and*
overrides).

Closes: #1408
Approved by: cgwalters
This commit is contained in:
Jonathan Lebon 2018-06-13 12:32:37 -04:00 committed by Atomic Bot
parent 65d08d928e
commit fb006b5b43
7 changed files with 97 additions and 4 deletions

View File

@ -37,6 +37,7 @@ static gchar **opt_uninstall;
static gboolean opt_cache_only;
static gboolean opt_download_only;
static gboolean opt_allow_inactive;
static gboolean opt_uninstall_all;
static GOptionEntry option_entries[] = {
{ "os", 0, 0, G_OPTION_ARG_STRING, &opt_osname, "Operate on provided OSNAME", "OSNAME" },
@ -48,6 +49,7 @@ static GOptionEntry option_entries[] = {
static GOptionEntry uninstall_option_entry[] = {
{ "install", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_install, "Install a package", "PKG" },
{ "all", 0, 0, G_OPTION_ARG_NONE, &opt_uninstall_all, "Remove all layered packages", NULL },
{ NULL }
};
@ -88,6 +90,7 @@ pkg_change (RpmOstreeCommandInvocation *invocation,
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;
@ -202,12 +205,19 @@ rpmostree_builtin_uninstall (int argc,
error))
return FALSE;
if (argc < 2)
if (argc < 2 && !opt_uninstall_all)
{
rpmostree_usage_error (context, "At least one PACKAGE must be specified", error);
return FALSE;
}
if (opt_install && opt_uninstall_all)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
"Cannot specify both --install and --all");
return FALSE;
}
/* shift to first pkgspec and ensure it's a proper strv (previous parsing
* might have moved args around) */
argv++; argc--;

View File

@ -184,6 +184,8 @@ os_authorize_method (GDBusInterfaceSkeleton *interface,
vardict_lookup_bool (&options_dict, "no-pull-base", FALSE);
gboolean no_overrides =
vardict_lookup_bool (&options_dict, "no-overrides", FALSE);
gboolean no_layering =
vardict_lookup_bool (&options_dict, "no-layering", FALSE);
if (refspec != NULL)
g_ptr_array_add (actions, "org.projectatomic.rpmostree1.rebase");
@ -192,7 +194,7 @@ os_authorize_method (GDBusInterfaceSkeleton *interface,
else if (!no_pull_base)
g_ptr_array_add (actions, "org.projectatomic.rpmostree1.upgrade");
if (install_pkgs != NULL || uninstall_pkgs != NULL)
if (install_pkgs != NULL || uninstall_pkgs != NULL || no_layering)
g_ptr_array_add (actions, "org.projectatomic.rpmostree1.install-uninstall-packages");
if (install_local_pkgs != NULL && g_variant_n_children (install_local_pkgs) > 0)

View File

@ -737,6 +737,8 @@ deploy_transaction_execute (RpmostreedTransaction *transaction,
((self->flags & RPMOSTREE_TRANSACTION_DEPLOY_FLAG_DRY_RUN) > 0);
const gboolean no_overrides =
((self->flags & RPMOSTREE_TRANSACTION_DEPLOY_FLAG_NO_OVERRIDES) > 0);
const gboolean no_layering =
((self->flags & RPMOSTREE_TRANSACTION_DEPLOY_FLAG_NO_LAYERING) > 0);
const gboolean cache_only =
((self->flags & RPMOSTREE_TRANSACTION_DEPLOY_FLAG_CACHE_ONLY) > 0);
const gboolean download_only =
@ -775,7 +777,12 @@ deploy_transaction_execute (RpmostreedTransaction *transaction,
upgrader_flags |= RPMOSTREE_SYSROOT_UPGRADER_FLAGS_PKGCACHE_ONLY;
}
/* this should have been checked already */
/* these should have been checked already */
if (no_layering)
{
g_assert (self->install_pkgs == NULL);
g_assert (self->install_local_pkgs == NULL);
}
if (no_overrides)
{
g_assert (self->override_replace_pkgs == NULL);
@ -882,7 +889,15 @@ deploy_transaction_execute (RpmostreedTransaction *transaction,
g_string_append (txn_title, " (download only)");
gboolean changed = FALSE;
if (self->uninstall_pkgs)
if (no_layering)
{
gboolean layering_changed = FALSE;
if (!rpmostree_origin_remove_all_packages (origin, &layering_changed, error))
return FALSE;
changed = changed || layering_changed;
}
else if (self->uninstall_pkgs)
{
if (!rpmostree_origin_remove_packages (origin, self->uninstall_pkgs, error))
return FALSE;
@ -1346,6 +1361,8 @@ deploy_flags_from_options (GVariant *options,
ret |= RPMOSTREE_TRANSACTION_DEPLOY_FLAG_DRY_RUN;
if (vardict_lookup_bool (&dict, "no-overrides", FALSE))
ret |= RPMOSTREE_TRANSACTION_DEPLOY_FLAG_NO_OVERRIDES;
if (vardict_lookup_bool (&dict, "no-layering", FALSE))
ret |= RPMOSTREE_TRANSACTION_DEPLOY_FLAG_NO_LAYERING;
if (vardict_lookup_bool (&dict, "cache-only", FALSE))
ret |= RPMOSTREE_TRANSACTION_DEPLOY_FLAG_CACHE_ONLY;
if (vardict_lookup_bool (&dict, "download-only", FALSE))
@ -1496,6 +1513,9 @@ rpmostreed_transaction_new_deploy (GDBusMethodInvocation *invocation,
override_replace_pkgs || override_replace_local_pkgs_idxs))
return glnx_null_throw (error, "Can't specify no-overrides if setting "
"override modifiers");
if (vardict_lookup_bool (&options_dict, "no-layering", FALSE) &&
((install_pkgs && *install_pkgs) || install_local_pkgs))
return glnx_null_throw (error, "Can't specify no-layering if also layering packages");
/* default to allowing downgrades for rebases & deploys */
if (vardict_lookup_bool (&options_dict, "allow-downgrade", refspec ||

View File

@ -61,6 +61,7 @@ typedef enum {
RPMOSTREE_TRANSACTION_DEPLOY_FLAG_DOWNLOAD_METADATA_ONLY = (1 << 9),
RPMOSTREE_TRANSACTION_DEPLOY_FLAG_STAGE = (1 << 10),
RPMOSTREE_TRANSACTION_DEPLOY_FLAG_ALLOW_INACTIVE = (1 << 11),
RPMOSTREE_TRANSACTION_DEPLOY_FLAG_NO_LAYERING = (1 << 12),
} RpmOstreeTransactionDeployFlags;

View File

@ -726,6 +726,37 @@ rpmostree_origin_remove_packages (RpmOstreeOrigin *origin,
return TRUE;
}
gboolean
rpmostree_origin_remove_all_packages (RpmOstreeOrigin *origin,
gboolean *out_changed,
GError **error)
{
gboolean changed = FALSE;
gboolean local_changed = FALSE;
if (g_hash_table_size (origin->cached_packages) > 0)
{
g_hash_table_remove_all (origin->cached_packages);
changed = TRUE;
}
if (g_hash_table_size (origin->cached_local_packages) > 0)
{
g_hash_table_remove_all (origin->cached_local_packages);
local_changed = TRUE;
}
if (changed)
update_keyfile_pkgs_from_cache (origin, "packages", "requested",
origin->cached_packages, FALSE);
if (local_changed)
update_keyfile_pkgs_from_cache (origin, "packages", "requested-local",
origin->cached_local_packages, TRUE);
if (out_changed)
*out_changed = changed || local_changed;
return TRUE;
}
gboolean
rpmostree_origin_add_overrides (RpmOstreeOrigin *origin,
char **packages,

View File

@ -147,6 +147,10 @@ gboolean
rpmostree_origin_remove_packages (RpmOstreeOrigin *origin,
char **packages,
GError **error);
gboolean
rpmostree_origin_remove_all_packages (RpmOstreeOrigin *origin,
gboolean *out_changed,
GError **error);
typedef enum {
/* RPMOSTREE_ORIGIN_OVERRIDE_REPLACE, */

View File

@ -94,3 +94,28 @@ assert_file_has_content out.txt "warning: .* Use --allow-inactive to squash this
vm_rpmostree cleanup -p
vm_rpmostree install glibc --allow-inactive &>out.txt
assert_not_file_has_content out.txt "warning:"
vm_rpmostree cleanup -p
echo "ok --allow-inactive"
# remove accumulated crud from previous tests
vm_rpmostree uninstall --all
vm_reboot
vm_rpmostree uninstall --all |& tee out.txt
assert_file_has_content out.txt "No change."
vm_build_rpm test-uninstall-all-pkg1
vm_build_rpm test-uninstall-all-pkg2
# do one from repo and one local for funsies
vm_rpmostree install test-uninstall-all-pkg1 \
/tmp/vmcheck/yumrepo/packages/x86_64/test-uninstall-all-pkg2-1.0-1.x86_64.rpm
vm_assert_status_jq \
'.deployments[0]["packages"]|length == 1' \
'.deployments[0]["requested-packages"]|length == 1' \
'.deployments[0]["requested-local-packages"]|length == 1'
vm_rpmostree uninstall --all |& tee out.txt
assert_not_file_has_content out.txt "No change."
vm_assert_status_jq \
'.deployments[0]["packages"]|length == 0' \
'.deployments[0]["requested-packages"]|length == 0' \
'.deployments[0]["requested-local-packages"]|length == 0'
vm_rpmostree cleanup -p
echo "ok uninstall --all"