diff --git a/man/rpm-ostree.xml b/man/rpm-ostree.xml
index 06a424ffff..c756e0a142 100644
--- a/man/rpm-ostree.xml
+++ b/man/rpm-ostree.xml
@@ -182,6 +182,12 @@ Boston, MA 02111-1307, USA.
inspect the RPM diff, but do not actually create a new
deployment.
+
+
+ to perform the operation
+ without trying to download the target tree from the remote
+ nor the latest packages.
+
@@ -206,6 +212,11 @@ Boston, MA 02111-1307, USA.
exit after printing the transaction rather than downloading
the packages and creating a new deployment.
+
+
+ to perform the operation
+ without trying to download the latest packages.
+
@@ -265,6 +276,12 @@ Boston, MA 02111-1307, USA.
to pick a remote name.
+
+ to perform the rebase without
+ trying to download the target tree from the remote nor the
+ latest packages.
+
+
@@ -350,6 +367,12 @@ Boston, MA 02111-1307, USA.
available, without downloading it or performing a
package-level diff.
+
+
+ to perform the upgrade without
+ trying to download the latest tree from the remote nor the
+ latest packages.
+
diff --git a/src/app/rpmostree-builtin-deploy.c b/src/app/rpmostree-builtin-deploy.c
index 0b4fe13132..b54025aa94 100644
--- a/src/app/rpmostree-builtin-deploy.c
+++ b/src/app/rpmostree-builtin-deploy.c
@@ -40,7 +40,7 @@ static GOptionEntry option_entries[] = {
* A --preview option would work for both commands if we wanted to
* deprecate --check-diff. */
{ "preview", 0, 0, G_OPTION_ARG_NONE, &opt_preview, "Just preview package differences", NULL },
- { "cache-only", 'C', 0, G_OPTION_ARG_NONE, &opt_cache_only, "Do not update repo metadata cache", NULL },
+ { "cache-only", 'C', 0, G_OPTION_ARG_NONE, &opt_cache_only, "Do not download latest ostree and rpmmd data", NULL },
{ NULL }
};
diff --git a/src/app/rpmostree-builtin-rebase.c b/src/app/rpmostree-builtin-rebase.c
index 9c71bb7e41..8096d75c04 100644
--- a/src/app/rpmostree-builtin-rebase.c
+++ b/src/app/rpmostree-builtin-rebase.c
@@ -43,7 +43,7 @@ static GOptionEntry option_entries[] = {
{ "remote", 'm', 0, G_OPTION_ARG_STRING, &opt_remote, "Rebase to current branch name using REMOTE; may also be combined with --branch", "REMOTE" },
{ "reboot", 'r', 0, G_OPTION_ARG_NONE, &opt_reboot, "Initiate a reboot after rebase is finished", NULL },
{ "skip-purge", 0, 0, G_OPTION_ARG_NONE, &opt_skip_purge, "Keep previous refspec after rebase", NULL },
- { "cache-only", 'C', 0, G_OPTION_ARG_NONE, &opt_cache_only, "Do not update repo metadata cache", NULL },
+ { "cache-only", 'C', 0, G_OPTION_ARG_NONE, &opt_cache_only, "Do not download latest ostree and rpmmd data", NULL },
{ NULL }
};
diff --git a/src/app/rpmostree-builtin-upgrade.c b/src/app/rpmostree-builtin-upgrade.c
index 1352c41781..29113e2951 100644
--- a/src/app/rpmostree-builtin-upgrade.c
+++ b/src/app/rpmostree-builtin-upgrade.c
@@ -47,7 +47,7 @@ static GOptionEntry option_entries[] = {
{ "check-diff", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &opt_preview, "Check for upgrades and print package diff only", NULL },
{ "preview", 0, 0, G_OPTION_ARG_NONE, &opt_preview, "Just preview package differences", NULL },
{ "check", 0, 0, G_OPTION_ARG_NONE, &opt_check, "Just check if an upgrade is available", NULL },
- { "cache-only", 'C', 0, G_OPTION_ARG_NONE, &opt_cache_only, "Do not update repo metadata cache", NULL },
+ { "cache-only", 'C', 0, G_OPTION_ARG_NONE, &opt_cache_only, "Do not download latest ostree and rpmmd data", NULL },
{ "upgrade-unchanged-exit-77", 0, 0, G_OPTION_ARG_NONE, &opt_upgrade_unchanged_exit_77, "If no upgrade is available, exit 77", NULL },
{ NULL }
};
diff --git a/src/app/rpmostree-dbus-helpers.c b/src/app/rpmostree-dbus-helpers.c
index c2548e8780..495f1a484b 100644
--- a/src/app/rpmostree-dbus-helpers.c
+++ b/src/app/rpmostree-dbus-helpers.c
@@ -1075,7 +1075,7 @@ rpmostree_get_options_variant (gboolean reboot,
g_variant_dict_init (&dict, NULL);
g_variant_dict_insert (&dict, "reboot", "b", reboot);
g_variant_dict_insert (&dict, "allow-downgrade", "b", allow_downgrade);
- g_variant_dict_insert (&dict, "rpmmd-cache-only", "b", cache_only);
+ g_variant_dict_insert (&dict, "cache-only", "b", cache_only);
g_variant_dict_insert (&dict, "skip-purge", "b", skip_purge);
g_variant_dict_insert (&dict, "no-pull-base", "b", no_pull_base);
g_variant_dict_insert (&dict, "dry-run", "b", dry_run);
diff --git a/src/app/rpmostree-pkg-builtins.c b/src/app/rpmostree-pkg-builtins.c
index 53e115a456..1ea7f9423d 100644
--- a/src/app/rpmostree-pkg-builtins.c
+++ b/src/app/rpmostree-pkg-builtins.c
@@ -50,7 +50,7 @@ static GOptionEntry uninstall_option_entry[] = {
static GOptionEntry install_option_entry[] = {
{ "uninstall", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_uninstall, "Uninstall a package", "PKG" },
- { "cache-only", 'C', 0, G_OPTION_ARG_NONE, &opt_cache_only, "Do not update repo metadata cache", NULL },
+ { "cache-only", 'C', 0, G_OPTION_ARG_NONE, &opt_cache_only, "Do not download latest ostree and rpmmd data", NULL },
{ NULL }
};
diff --git a/src/daemon/org.projectatomic.rpmostree1.xml b/src/daemon/org.projectatomic.rpmostree1.xml
index c06ccb8bd2..4a71cd7b7e 100644
--- a/src/daemon/org.projectatomic.rpmostree1.xml
+++ b/src/daemon/org.projectatomic.rpmostree1.xml
@@ -255,13 +255,14 @@
Do not pull a base layer from the remote. Not valid if
either "set-refspec" or "set-revision" is specified.
"dry-run" (type 'b')
- Stop short of deploying the new tree. If
- layering packages, the pkg diff is printed.
+ Stop short of deploying the new tree. If layering packages,
+ the pkg diff is printed but packages are not downloaded or
+ imported.
"no-overrides" (type 'b')
Remove all active overrides. Not valid if any override
modifiers are specified.
- "rpmmd-cache-only" (type 'b')
- Do not update rpmmd repo metadata cache.
+ "cache-only" (type 'b')
+ Do not update rpmmd repo metadata cache or ostree refspec.
-->
diff --git a/src/daemon/rpmostree-sysroot-upgrader.c b/src/daemon/rpmostree-sysroot-upgrader.c
index cdaeed8981..95407be416 100644
--- a/src/daemon/rpmostree-sysroot-upgrader.c
+++ b/src/daemon/rpmostree-sysroot-upgrader.c
@@ -382,11 +382,13 @@ rpmostree_sysroot_upgrader_pull_base (RpmOstreeSysrootUpgrader *self,
const gboolean allow_older =
(self->flags & RPMOSTREE_SYSROOT_UPGRADER_FLAGS_ALLOW_OLDER) > 0;
+ const gboolean synthetic =
+ (self->flags & RPMOSTREE_SYSROOT_UPGRADER_FLAGS_SYNTHETIC_PULL) > 0;
const char *override_commit = rpmostree_origin_get_override_commit (self->origin);
g_assert (self->origin_merge_deployment);
- if (origin_remote)
+ if (origin_remote && !synthetic)
{
g_autoptr(GVariantBuilder) optbuilder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
if (dir_to_pull && *dir_to_pull)
@@ -428,8 +430,8 @@ rpmostree_sysroot_upgrader_pull_base (RpmOstreeSysrootUpgrader *self,
gboolean changed = !g_str_equal (new_base_rev, self->base_revision);
if (changed)
{
- /* check timestamps here too in case the commit was already pulled (or the
- * refspec is local) */
+ /* check timestamps here too in case the commit was already pulled, or the pull was
+ * synthetic, or the refspec is local */
if (!allow_older)
{
if (!ostree_sysroot_upgrader_check_timestamps (self->repo, self->base_revision,
@@ -785,6 +787,10 @@ prepare_context_for_assembly (RpmOstreeSysrootUpgrader *self,
return FALSE;
rpmostree_context_set_sepolicy (self->ctx, sepolicy);
+
+ if (self->flags & RPMOSTREE_SYSROOT_UPGRADER_FLAGS_PKGCACHE_ONLY)
+ rpmostree_context_set_pkgcache_only (self->ctx, TRUE);
+
return TRUE;
}
@@ -814,12 +820,6 @@ prep_local_assembly (RpmOstreeSysrootUpgrader *self,
cancellable, error))
return FALSE;
- if (self->flags & RPMOSTREE_SYSROOT_UPGRADER_FLAGS_RPMMD_CACHE_ONLY)
- {
- DnfContext *hifctx = rpmostree_context_get_hif (self->ctx);
- dnf_context_set_cache_age (hifctx, G_MAXUINT);
- }
-
g_autoptr(OstreeRepo) pkgcache_repo = NULL;
if (!rpmostree_get_pkgcache_repo (self->repo, &pkgcache_repo, cancellable, error))
return FALSE;
diff --git a/src/daemon/rpmostree-sysroot-upgrader.h b/src/daemon/rpmostree-sysroot-upgrader.h
index 47308068e1..ad2c149cbf 100644
--- a/src/daemon/rpmostree-sysroot-upgrader.h
+++ b/src/daemon/rpmostree-sysroot-upgrader.h
@@ -41,7 +41,8 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (RpmOstreeSysrootUpgrader, g_object_unref)
* @RPMOSTREE_SYSROOT_UPGRADER_FLAGS_IGNORE_UNCONFIGURED: Do not error if the origin has an unconfigured-state key
* @RPMOSTREE_SYSROOT_UPGRADER_FLAGS_ALLOW_OLDER: Do not error if the new deployment was composed earlier than the current deployment
* @RPMOSTREE_SYSROOT_UPGRADER_FLAGS_DRY_RUN: Don't deploy new base. If layering packages, only print the transaction
- * @RPMOSTREE_SYSROOT_UPGRADER_FLAGS_DRY_RUN: Don't update rpmmd cache.
+ * @RPMOSTREE_SYSROOT_UPGRADER_FLAGS_PKGCACHE_ONLY: Don't try to update cached packages.
+ * @RPMOSTREE_SYSROOT_UPGRADER_FLAGS_SYNTHETIC_PULL: Don't actually pull, just resolve ref and timestamp check
*
* Flags controlling operation of an #RpmOstreeSysrootUpgrader.
*/
@@ -50,7 +51,8 @@ typedef enum {
RPMOSTREE_SYSROOT_UPGRADER_FLAGS_IGNORE_UNCONFIGURED = (1 << 1),
RPMOSTREE_SYSROOT_UPGRADER_FLAGS_ALLOW_OLDER = (1 << 2),
RPMOSTREE_SYSROOT_UPGRADER_FLAGS_DRY_RUN = (1 << 3),
- RPMOSTREE_SYSROOT_UPGRADER_FLAGS_RPMMD_CACHE_ONLY = (1 << 4)
+ RPMOSTREE_SYSROOT_UPGRADER_FLAGS_PKGCACHE_ONLY = (1 << 4),
+ RPMOSTREE_SYSROOT_UPGRADER_FLAGS_SYNTHETIC_PULL = (1 << 5),
} RpmOstreeSysrootUpgraderFlags;
/* _NONE means we're doing pure ostree, no client-side computation.
diff --git a/src/daemon/rpmostreed-os.c b/src/daemon/rpmostreed-os.c
index 187e9193f7..95829f2543 100644
--- a/src/daemon/rpmostreed-os.c
+++ b/src/daemon/rpmostreed-os.c
@@ -546,8 +546,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, "rpmmd-cache-only", FALSE))
- ret |= RPMOSTREE_TRANSACTION_DEPLOY_FLAG_RPMMD_CACHE_ONLY;
+ if (vardict_lookup_bool (&dict, "cache-only", FALSE))
+ ret |= RPMOSTREE_TRANSACTION_DEPLOY_FLAG_CACHE_ONLY;
return ret;
}
diff --git a/src/daemon/rpmostreed-transaction-types.c b/src/daemon/rpmostreed-transaction-types.c
index 18f1d8b0c6..d07d4cd19f 100644
--- a/src/daemon/rpmostreed-transaction-types.c
+++ b/src/daemon/rpmostreed-transaction-types.c
@@ -558,11 +558,20 @@ deploy_transaction_execute (RpmostreedTransaction *transaction,
upgrader_flags |= RPMOSTREE_SYSROOT_UPGRADER_FLAGS_ALLOW_OLDER;
if (self->flags & RPMOSTREE_TRANSACTION_DEPLOY_FLAG_DRY_RUN)
upgrader_flags |= RPMOSTREE_SYSROOT_UPGRADER_FLAGS_DRY_RUN;
- if (self->flags & RPMOSTREE_TRANSACTION_DEPLOY_FLAG_RPMMD_CACHE_ONLY)
- upgrader_flags |= RPMOSTREE_SYSROOT_UPGRADER_FLAGS_RPMMD_CACHE_ONLY;
const gboolean no_overrides =
((self->flags & RPMOSTREE_TRANSACTION_DEPLOY_FLAG_NO_OVERRIDES) > 0);
+ if (self->flags & RPMOSTREE_TRANSACTION_DEPLOY_FLAG_CACHE_ONLY)
+ {
+ /* practically, we could unite those two into a single flag, though it's nice to be
+ * able to keep them separate as well */
+
+ /* don't pull, just resolve ref locally and timestamp check */
+ upgrader_flags |= RPMOSTREE_SYSROOT_UPGRADER_FLAGS_SYNTHETIC_PULL;
+ /* turn on rpmmd cache only in the upgrader */
+ upgrader_flags |= RPMOSTREE_SYSROOT_UPGRADER_FLAGS_PKGCACHE_ONLY;
+ }
+
/* this should have been checked already */
if (no_overrides)
{
@@ -803,7 +812,10 @@ deploy_transaction_execute (RpmostreedTransaction *transaction,
rpmostree_sysroot_upgrader_set_origin (upgrader, origin);
/* Mainly for the `install` and `override` commands */
- if (!(self->flags & RPMOSTREE_TRANSACTION_DEPLOY_FLAG_NO_PULL_BASE))
+ const gboolean no_pull_base =
+ ((self->flags & RPMOSTREE_TRANSACTION_DEPLOY_FLAG_NO_PULL_BASE) > 0);
+
+ if (!no_pull_base)
{
gboolean base_changed;
diff --git a/src/daemon/rpmostreed-transaction-types.h b/src/daemon/rpmostreed-transaction-types.h
index 66be27aa86..8608217176 100644
--- a/src/daemon/rpmostreed-transaction-types.h
+++ b/src/daemon/rpmostreed-transaction-types.h
@@ -54,7 +54,7 @@ typedef enum {
RPMOSTREE_TRANSACTION_DEPLOY_FLAG_NO_PULL_BASE = (1 << 4),
RPMOSTREE_TRANSACTION_DEPLOY_FLAG_DRY_RUN = (1 << 5),
RPMOSTREE_TRANSACTION_DEPLOY_FLAG_NO_OVERRIDES = (1 << 6),
- RPMOSTREE_TRANSACTION_DEPLOY_FLAG_RPMMD_CACHE_ONLY = (1 << 7),
+ RPMOSTREE_TRANSACTION_DEPLOY_FLAG_CACHE_ONLY = (1 << 7),
} RpmOstreeTransactionDeployFlags;
diff --git a/src/libpriv/rpmostree-core.c b/src/libpriv/rpmostree-core.c
index f0119716fd..42507ada78 100644
--- a/src/libpriv/rpmostree-core.c
+++ b/src/libpriv/rpmostree-core.c
@@ -243,6 +243,7 @@ struct _RpmOstreeContext {
RpmOstreeTreespec *spec;
gboolean empty;
+ gboolean pkgcache_only;
DnfContext *hifctx;
OstreeRepo *ostreerepo;
OstreeRepo *pkgcache_repo;
@@ -403,6 +404,15 @@ rpmostree_context_ensure_tmpdir (RpmOstreeContext *self,
return TRUE;
}
+void
+rpmostree_context_set_pkgcache_only (RpmOstreeContext *self,
+ gboolean pkgcache_only)
+{
+ /* if called, must always be before setup() */
+ g_assert (!self->spec);
+ self->pkgcache_only = pkgcache_only;
+}
+
/* Pick up repos dir and passwd from @cfg_deployment. */
void
rpmostree_context_configure_from_deployment (RpmOstreeContext *self,
@@ -600,13 +610,22 @@ rpmostree_context_setup (RpmOstreeContext *self,
if (!dnf_context_setup (self->hifctx, cancellable, error))
return FALSE;
- /* NB: missing "repos" --> let hif figure it out for itself */
- if (g_variant_dict_lookup (self->spec->dict, "repos", "^a&s", &enabled_repos))
- if (!context_repos_enable_only (self, (const char *const*)enabled_repos, error))
- return FALSE;
+ /* disable all repos in pkgcache-only mode, otherwise obey "repos" key */
+ if (self->pkgcache_only)
+ {
+ if (!context_repos_enable_only (self, NULL, error))
+ return FALSE;
+ }
+ else
+ {
+ /* NB: missing "repos" --> let hif figure it out for itself */
+ if (g_variant_dict_lookup (self->spec->dict, "repos", "^a&s", &enabled_repos))
+ if (!context_repos_enable_only (self, (const char *const*)enabled_repos, error))
+ return FALSE;
+ }
g_autoptr(GPtrArray) repos = get_enabled_rpmmd_repos (self->hifctx, DNF_REPO_ENABLED_PACKAGES);
- if (repos->len == 0)
+ if (repos->len == 0 && !self->pkgcache_only)
{
/* To be nice, let's only make this fatal if "packages" is empty (e.g. if
* we're only installing local RPMs. Missing deps will cause the regular
@@ -616,6 +635,7 @@ rpmostree_context_setup (RpmOstreeContext *self,
g_strv_length (pkgs) > 0)
return glnx_throw (error, "No enabled repositories");
}
+
/* Ensure that each repo that's enabled is marked as required; this should be
* the default, but we make sure. This is a bit of a messy topic, but for
* rpm-ostree we're being more strict about requiring repos.
@@ -807,8 +827,7 @@ rpmostree_find_cache_branch_by_nevra (OstreeRepo *pkgcache,
g_autoptr(GHashTable) refs = NULL;
if (!ostree_repo_list_refs_ext (pkgcache, "rpmostree/pkg", &refs,
- OSTREE_REPO_LIST_REFS_EXT_NONE, cancellable,
- error))
+ OSTREE_REPO_LIST_REFS_EXT_NONE, cancellable, error))
return FALSE;
GLNX_HASH_TABLE_FOREACH (refs, const char*, ref)
@@ -872,8 +891,7 @@ checkout_pkg_metadata_by_nevra (RpmOstreeContext *self,
&header, cancellable, error))
return FALSE;
- return checkout_pkg_metadata (self, nevra, header,
- cancellable, error);
+ return checkout_pkg_metadata (self, nevra, header, cancellable, error);
}
/* Fetches decomposed NEVRA information from pkgcache for a given nevra string. Requires the
@@ -921,7 +939,21 @@ rpmostree_context_download_metadata (RpmOstreeContext *self,
{
g_assert (!self->empty);
- g_autoptr(GPtrArray) rpmmd_repos = get_enabled_rpmmd_repos (self->hifctx, DNF_REPO_ENABLED_PACKAGES);
+ g_autoptr(GPtrArray) rpmmd_repos =
+ get_enabled_rpmmd_repos (self->hifctx, DNF_REPO_ENABLED_PACKAGES);
+
+ if (self->pkgcache_only)
+ {
+ g_assert_cmpint (rpmmd_repos->len, ==, 0);
+
+ /* this is essentially a no-op */
+ g_autoptr(DnfState) hifstate = dnf_state_new ();
+ if (!dnf_context_setup_sack (self->hifctx, hifstate, error))
+ return FALSE;
+
+ /* Note early return; no repos to fetch. */
+ return TRUE;
+ }
g_autoptr(GString) enabled_repos = g_string_new ("Enabled rpm-md repositories:");
for (guint i = 0; i < rpmmd_repos->len; i++)
@@ -1507,7 +1539,8 @@ install_pkg_from_cache (RpmOstreeContext *self,
/* This is the great lie: we make libdnf et al. think that they're dealing with a full
* RPM, all while crossing our fingers that they don't try to look past the header.
* Ideally, it would be best if libdnf could learn to treat the pkgcache repo as another
- * DnfRepo. */
+ * DnfRepo. We could do this all in-memory though it doesn't seem like libsolv has an
+ * appropriate API for this. */
g_autofree char *rpm = g_strdup_printf ("%s/metarpm/%s.rpm", self->tmpdir.path, nevra);
DnfPackage *pkg = dnf_sack_add_cmdline_package (dnf_context_get_sack (self->hifctx), rpm);
if (!pkg)
@@ -1517,6 +1550,49 @@ install_pkg_from_cache (RpmOstreeContext *self,
return TRUE;
}
+/* This is a hacky way to bridge the gap between libdnf and our pkgcache. We extract the
+ * metarpm for every RPM in our cache and present that as the cmdline repo to libdnf. But we
+ * do still want all the niceties of the libdnf stack, e.g. HyGoal, libsolv depsolv, etc...
+ */
+static gboolean
+add_remaining_pkgcache_pkgs (RpmOstreeContext *self,
+ GHashTable *already_added,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_assert (self->pkgcache_repo);
+ g_assert (self->pkgcache_only);
+
+ DnfSack *sack = dnf_context_get_sack (self->hifctx);
+ g_assert (sack);
+
+ g_autoptr(GHashTable) refs = NULL;
+ if (!ostree_repo_list_refs_ext (self->pkgcache_repo, "rpmostree/pkg", &refs,
+ OSTREE_REPO_LIST_REFS_EXT_NONE, cancellable, error))
+ return FALSE;
+
+ GLNX_HASH_TABLE_FOREACH (refs, const char*, ref)
+ {
+ g_autofree char *nevra = rpmostree_cache_branch_to_nevra (ref);
+ if (g_hash_table_contains (already_added, nevra))
+ continue;
+
+ g_autoptr(GVariant) header = NULL;
+ if (!get_header_variant (self->pkgcache_repo, ref, &header, cancellable, error))
+ return FALSE;
+
+ if (!checkout_pkg_metadata (self, nevra, header, cancellable, error))
+ return FALSE;
+
+ g_autofree char *rpm = g_strdup_printf ("%s/metarpm/%s.rpm", self->tmpdir.path, nevra);
+ DnfPackage *pkg = dnf_sack_add_cmdline_package (sack, rpm);
+ if (!pkg)
+ return glnx_throw (error, "Failed to add local pkg %s to sack", nevra);
+ }
+
+ return TRUE;
+}
+
/* Check for/download new rpm-md, then depsolve */
gboolean
rpmostree_context_prepare (RpmOstreeContext *self,
@@ -1562,6 +1638,9 @@ rpmostree_context_prepare (RpmOstreeContext *self,
g_ptr_array_add (removed_pkgnames, (gpointer)pkgname);
}
+ /* track cached pkgs already added to the sack so far */
+ g_autoptr(GHashTable) already_added = g_hash_table_new (g_str_hash, g_str_equal);
+
/* Handle packages to replace */
g_autoptr(GPtrArray) replaced_nevras = g_ptr_array_new ();
for (char **it = cached_replace_pkgs; it && *it; it++)
@@ -1575,6 +1654,7 @@ rpmostree_context_prepare (RpmOstreeContext *self,
return FALSE;
g_ptr_array_add (replaced_nevras, (gpointer)nevra);
+ g_hash_table_add (already_added, (gpointer)nevra);
}
/* For each new local package, tell libdnf to add it to the goal */
@@ -1587,6 +1667,18 @@ rpmostree_context_prepare (RpmOstreeContext *self,
if (!install_pkg_from_cache (self, nevra, sha256, cancellable, error))
return FALSE;
+
+ g_hash_table_add (already_added, (gpointer)nevra);
+ }
+
+ /* If we're in cache-only mode, add all the remaining pkgs now. We do this *after* the
+ * replace & local pkgs since they already handle a subset of the cached pkgs and have
+ * SHA256 checks. But we do it *before* dnf_context_install() since those subjects are not
+ * directly linked to a cached pkg, so we need to teach libdnf about them beforehand. */
+ if (self->pkgcache_only)
+ {
+ if (!add_remaining_pkgcache_pkgs (self, already_added, cancellable, error))
+ return FALSE;
}
/* Loop over each named package, and tell libdnf to add it to the goal */
diff --git a/src/libpriv/rpmostree-core.h b/src/libpriv/rpmostree-core.h
index cfe3790271..e9e382b3bf 100644
--- a/src/libpriv/rpmostree-core.h
+++ b/src/libpriv/rpmostree-core.h
@@ -44,6 +44,9 @@ RpmOstreeContext *rpmostree_context_new_tree (int basedir_dfd,
GCancellable *cancellable,
GError **error);
+void rpmostree_context_set_pkgcache_only (RpmOstreeContext *self,
+ gboolean pkgcache_only);
+
DnfContext * rpmostree_context_get_hif (RpmOstreeContext *self);
RpmOstreeTreespec *rpmostree_treespec_new_from_keyfile (GKeyFile *keyfile, GError **error);
diff --git a/tests/vmcheck/test-basic.sh b/tests/vmcheck/test-basic.sh
index 638bc38f0f..4ae27d1a0f 100755
--- a/tests/vmcheck/test-basic.sh
+++ b/tests/vmcheck/test-basic.sh
@@ -173,15 +173,12 @@ vm_build_rpm_repo_mode skip refresh-md-old-pkg
vm_rpmostree refresh-md
vm_build_rpm_repo_mode skip refresh-md-new-pkg
vm_rpmostree refresh-md # shouldn't do anything since it hasn't expired yet
-if ! vm_rpmostree install -C refresh-md-old-pkg --dry-run; then
- assert_not_reached "failed to dry-run install old pkg from cached rpmmd"
-fi
-if vm_rpmostree install -C refresh-md-new-pkg --dry-run; then
+if vm_rpmostree install refresh-md-new-pkg --dry-run; then
assert_not_reached "successfully dry-run installed new pkg from cached rpmmd?"
fi
vm_rpmostree refresh-md -f
-if ! vm_rpmostree install -C refresh-md-new-pkg --dry-run; then
+if ! vm_rpmostree install refresh-md-new-pkg --dry-run; then
assert_not_reached "failed to dry-run install new pkg from cached rpmmd?"
fi
vm_stop_httpd vmcheck
-echo "ok refresh-md and --cache-only"
+echo "ok refresh-md"