Skip to content

Commit

Permalink
context: use rpmtsAddReinstallElement() when doing a reinstall
Browse files Browse the repository at this point in the history
`rpmtsAddInstallElement()` doesn't work for all reinstall cases, such as
when a package `Provides` and `Conflicts` with the same capability.

Fixes: rpm-software-management/microdnf#137
  • Loading branch information
kontura authored and jan-kolarik committed Apr 12, 2024
1 parent 0120e70 commit 85432df
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 37 deletions.
6 changes: 6 additions & 0 deletions libdnf/dnf-rpmts-private.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,10 @@ gboolean dnf_rpmts_add_install_filename2(rpmts ts,
DnfPackage *pkg,
GError **error);

gboolean dnf_rpmts_add_reinstall_filename(rpmts ts,
const gchar *filename,
gboolean allow_untrusted,
GError **error);


#endif /* __DNF_RPMTS_PRIVATE_HPP */
108 changes: 73 additions & 35 deletions libdnf/dnf-rpmts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,94 +88,132 @@ test_fail_safe(Header * hdr, DnfPackage * pkg, GError **error)
return ret;
}

gboolean
dnf_rpmts_add_install_filename2(rpmts ts,
const gchar *filename,
gboolean allow_untrusted,
gboolean is_update,
DnfPackage * pkg,
GError **error) try
{
gboolean ret = TRUE;
gint res;
Header hdr;
FD_t fd;

/* open this */
fd = Fopen(filename, "r.ufdio");
res = rpmReadPackageFile(ts, fd, filename, &hdr);

static gboolean
result_is_accepted(gint result, gboolean allow_untrusted, const gchar *filename, GError **error) {
/* be less strict when we're allowing untrusted transactions */
if (allow_untrusted) {
switch(res) {
switch(result) {
case RPMRC_NOKEY:
case RPMRC_NOTFOUND:
case RPMRC_NOTTRUSTED:
case RPMRC_OK:
break;
return TRUE;
case RPMRC_FAIL:
ret = FALSE;
g_set_error(error,
DNF_ERROR,
DNF_ERROR_INTERNAL_ERROR,
_("signature does not verify for %s"),
filename);
goto out;
return FALSE;
default:
ret = FALSE;
g_set_error(error,
DNF_ERROR,
DNF_ERROR_INTERNAL_ERROR,
_("failed to open(generic error): %s"),
filename);
goto out;
return FALSE;
}
} else {
switch(res) {
switch(result) {
case RPMRC_OK:
break;
return TRUE;
case RPMRC_NOTTRUSTED:
ret = FALSE;
g_set_error(error,
DNF_ERROR,
DNF_ERROR_INTERNAL_ERROR,
_("failed to verify key for %s"),
filename);
goto out;
return FALSE;
case RPMRC_NOKEY:
ret = FALSE;
g_set_error(error,
DNF_ERROR,
DNF_ERROR_INTERNAL_ERROR,
_("public key unavailable for %s"),
filename);
goto out;
return FALSE;
case RPMRC_NOTFOUND:
ret = FALSE;
g_set_error(error,
DNF_ERROR,
DNF_ERROR_INTERNAL_ERROR,
_("signature not found for %s"),
filename);
goto out;
return FALSE;
case RPMRC_FAIL:
ret = FALSE;
g_set_error(error,
DNF_ERROR,
DNF_ERROR_INTERNAL_ERROR,
_("signature does not verify for %s"),
filename);
goto out;
return FALSE;
default:
ret = FALSE;
g_set_error(error,
DNF_ERROR,
DNF_ERROR_INTERNAL_ERROR,
_("failed to open(generic error): %s"),
filename);
goto out;
return FALSE;
}
}
}

gboolean
dnf_rpmts_add_reinstall_filename(rpmts ts,
const gchar *filename,
gboolean allow_untrusted,
GError **error) try
{
gboolean ret = TRUE;
gint res;
Header hdr;
FD_t fd;

/* open this */
fd = Fopen(filename, "r.ufdio");
res = rpmReadPackageFile(ts, fd, filename, &hdr);

if (!result_is_accepted(res, allow_untrusted, filename, error)) {
ret = FALSE;
goto out;
}

/* add to the transaction */
res = rpmtsAddReinstallElement(ts, hdr, (fnpyKey) filename);
if (res != 0) {
ret = FALSE;
g_set_error(error,
DNF_ERROR,
DNF_ERROR_INTERNAL_ERROR,
_("failed to add reinstall element: %1$s [%2$i]"),
filename, res);
goto out;
}
out:
Fclose(fd);
headerFree(hdr);
return ret;
} CATCH_TO_GERROR(FALSE)

gboolean
dnf_rpmts_add_install_filename2(rpmts ts,
const gchar *filename,
gboolean allow_untrusted,
gboolean is_update,
DnfPackage * pkg,
GError **error) try
{
gboolean ret = TRUE;
gint res;
Header hdr;
FD_t fd;

/* open this */
fd = Fopen(filename, "r.ufdio");
res = rpmReadPackageFile(ts, fd, filename, &hdr);

if (!result_is_accepted(res, allow_untrusted, filename, error)) {
ret = FALSE;
goto out;
}
if (pkg) {
if (!test_fail_safe(&hdr, pkg, error)) {
ret = FALSE;
Expand Down
8 changes: 6 additions & 2 deletions libdnf/dnf-transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1222,8 +1222,12 @@ dnf_transaction_commit(DnfTransaction *transaction, HyGoal goal, DnfState *state
filename = dnf_package_get_filename(pkg);
allow_untrusted = (priv->flags & DNF_TRANSACTION_FLAG_ONLY_TRUSTED) == 0;
is_update = action == DNF_STATE_ACTION_UPDATE || action == DNF_STATE_ACTION_DOWNGRADE;
ret = dnf_rpmts_add_install_filename2(
priv->ts, filename, allow_untrusted, is_update, pkg, error);
if (action == DNF_STATE_ACTION_REINSTALL) {
ret = dnf_rpmts_add_reinstall_filename(priv->ts, filename, allow_untrusted, error);
} else {
ret = dnf_rpmts_add_install_filename2(
priv->ts, filename, allow_untrusted, is_update, pkg, error);
}
if (!ret)
goto out;

Expand Down

0 comments on commit 85432df

Please sign in to comment.