libpriv/origin: Allow removing local RPMs by name only
This fixes a painful UX issue where one must use the full NEVRA when uninstalling a locally layered RPM. Now, one can specify either the NEVRA or the package name only. Though we still try to interpret the request first as a NEVRA or a capability. Closes: #1386 Closes: #1400 Approved by: cgwalters
This commit is contained in:
parent
073978aace
commit
d436d48a2f
@ -26,6 +26,7 @@
|
||||
#include "rpmostree-origin.h"
|
||||
#include "rpmostree-core.h"
|
||||
#include "rpmostree-util.h"
|
||||
#include "rpmostree-rpm-util.h"
|
||||
|
||||
struct RpmOstreeOrigin {
|
||||
guint refcount;
|
||||
@ -656,6 +657,25 @@ rpmostree_origin_add_packages (RpmOstreeOrigin *origin,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
build_name_to_nevra_map (GHashTable *nevras,
|
||||
GHashTable **out_name_to_nevra,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(GHashTable) name_to_nevra = /* nevra vals owned by @nevras */
|
||||
g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||
GLNX_HASH_TABLE_FOREACH (nevras, const char*, nevra)
|
||||
{
|
||||
g_autofree char *name = NULL;
|
||||
if (!rpmostree_decompose_nevra (nevra, &name, NULL, NULL, NULL, NULL, error))
|
||||
return FALSE;
|
||||
g_hash_table_insert (name_to_nevra, g_steal_pointer (&name), (gpointer)nevra);
|
||||
}
|
||||
|
||||
*out_name_to_nevra = g_steal_pointer (&name_to_nevra);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
rpmostree_origin_remove_packages (RpmOstreeOrigin *origin,
|
||||
char **packages,
|
||||
@ -664,14 +684,36 @@ rpmostree_origin_remove_packages (RpmOstreeOrigin *origin,
|
||||
gboolean changed = FALSE;
|
||||
gboolean local_changed = FALSE;
|
||||
|
||||
/* lazily calculated */
|
||||
g_autoptr(GHashTable) name_to_nevra = NULL;
|
||||
|
||||
for (char **it = packages; it && *it; it++)
|
||||
{
|
||||
if (g_hash_table_remove (origin->cached_local_packages, *it))
|
||||
/* really, either a NEVRA (local RPM) or freeform provides request (from repo) */
|
||||
const char *package = *it;
|
||||
if (g_hash_table_remove (origin->cached_local_packages, package))
|
||||
local_changed = TRUE;
|
||||
else if (g_hash_table_remove (origin->cached_packages, *it))
|
||||
else if (g_hash_table_remove (origin->cached_packages, package))
|
||||
changed = TRUE;
|
||||
else
|
||||
return glnx_throw (error, "Package/capability '%s' is not currently requested", *it);
|
||||
{
|
||||
if (!name_to_nevra)
|
||||
{
|
||||
if (!build_name_to_nevra_map (origin->cached_local_packages,
|
||||
&name_to_nevra, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (g_hash_table_contains (name_to_nevra, package))
|
||||
{
|
||||
g_assert (g_hash_table_remove (origin->cached_local_packages,
|
||||
g_hash_table_lookup (name_to_nevra, package)));
|
||||
local_changed = TRUE;
|
||||
}
|
||||
else
|
||||
return glnx_throw (error, "Package/capability '%s' is not currently requested",
|
||||
package);
|
||||
}
|
||||
}
|
||||
|
||||
if (changed)
|
||||
|
@ -40,6 +40,15 @@ vm_has_local_packages foo-1.2-3.x86_64
|
||||
vm_assert_layered_pkg foo-1.2-3.x86_64 present
|
||||
echo "ok pkg foo added locally"
|
||||
|
||||
# check we could uninstall the package using either its NEVRA or name
|
||||
vm_rpmostree uninstall foo-1.2-3.x86_64
|
||||
vm_assert_status_jq '.deployments[0]["requested-local-packages"]|length == 0'
|
||||
vm_rpmostree cleanup -p
|
||||
vm_rpmostree uninstall foo
|
||||
vm_assert_status_jq '.deployments[0]["requested-local-packages"]|length == 0'
|
||||
vm_rpmostree cleanup -p
|
||||
echo "ok uninstall by NEVRA or name"
|
||||
|
||||
# check that we can still request foo and it's dormant
|
||||
vm_rpmostree install foo
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user