Handle "pinned commits" specifically
There are a few scenarios today where one might deliver content to a machine via an external transport. For example, take the scenario of a single server updated via USB drive. While we can provide a refspec...what should the remote be? (This gets into ostree collections). There's nothing really that can happen when typing `rpm-ostree upgrade` unless the USB stick is plugged in. That type of scenario should be emphasized by pinning the commit - the machine is updated via an external script. Another case: we're experimenting embedding OSTree commits inside OCI containers. Here again since rpm-ostree can't understand how to pull content from containers, it's saner to drop the refspec bits, and pin to a commit. Further enhancements will follow to make the admin experience more obvious. Closes: #1396 Approved by: jlebon
This commit is contained in:
parent
26f04595b2
commit
27bd7b97bb
@ -480,6 +480,7 @@ print_one_deployment (RPMOSTreeSysroot *sysroot_proxy,
|
||||
g_autofree char *canonrefspec = rpmostree_refspec_to_string (refspectype, refspec_data);
|
||||
switch (refspectype)
|
||||
{
|
||||
case RPMOSTREE_REFSPEC_TYPE_CHECKSUM:
|
||||
case RPMOSTREE_REFSPEC_TYPE_OSTREE:
|
||||
{
|
||||
g_print ("%s", canonrefspec);
|
||||
|
@ -397,6 +397,7 @@ rpmostree_sysroot_upgrader_pull_base (RpmOstreeSysrootUpgrader *self,
|
||||
|
||||
switch (refspec_type)
|
||||
{
|
||||
case RPMOSTREE_REFSPEC_TYPE_CHECKSUM:
|
||||
case RPMOSTREE_REFSPEC_TYPE_OSTREE:
|
||||
{
|
||||
g_autofree char *origin_remote = NULL;
|
||||
|
@ -303,6 +303,9 @@ rpmostreed_deployment_generate_variant (OstreeSysroot *sysroot,
|
||||
|
||||
switch (refspec_type)
|
||||
{
|
||||
case RPMOSTREE_REFSPEC_TYPE_CHECKSUM:
|
||||
/* Nothing to do here */
|
||||
break;
|
||||
case RPMOSTREE_REFSPEC_TYPE_OSTREE:
|
||||
{
|
||||
if (!variant_add_remote_status (repo, refspec, base_checksum, &dict, error))
|
||||
@ -424,7 +427,9 @@ add_all_commit_details_to_vardict (OstreeDeployment *deployment,
|
||||
return FALSE;
|
||||
refspec = refspec_remainder;
|
||||
}
|
||||
refspec_is_ostree = (refspec_type == RPMOSTREE_REFSPEC_TYPE_OSTREE);
|
||||
refspec_is_ostree = refspec_type == RPMOSTREE_REFSPEC_TYPE_OSTREE;
|
||||
if (refspec_type == RPMOSTREE_REFSPEC_TYPE_CHECKSUM && !commit)
|
||||
checksum = refspec;
|
||||
|
||||
g_assert (refspec);
|
||||
|
||||
@ -962,10 +967,14 @@ rpmostreed_update_generate_variant (OstreeDeployment *booted_deployment,
|
||||
return FALSE;
|
||||
|
||||
/* we don't support rojig-based origins yet */
|
||||
if (refspectype != RPMOSTREE_REFSPEC_TYPE_OSTREE)
|
||||
switch (refspectype)
|
||||
{
|
||||
case RPMOSTREE_REFSPEC_TYPE_ROJIG:
|
||||
*out_update = NULL;
|
||||
return TRUE; /* NB: early return */
|
||||
case RPMOSTREE_REFSPEC_TYPE_OSTREE:
|
||||
case RPMOSTREE_REFSPEC_TYPE_CHECKSUM:
|
||||
break;
|
||||
}
|
||||
|
||||
/* just skip over "ostree://" so we can talk with libostree without thinking about it */
|
||||
|
@ -76,6 +76,7 @@ change_origin_refspec (OstreeSysroot *sysroot,
|
||||
return TRUE;
|
||||
}
|
||||
case RPMOSTREE_REFSPEC_TYPE_OSTREE:
|
||||
case RPMOSTREE_REFSPEC_TYPE_CHECKSUM:
|
||||
break;
|
||||
}
|
||||
|
||||
@ -137,6 +138,9 @@ apply_revision_override (RpmostreedTransaction *transaction,
|
||||
RpmOstreeRefspecType refspectype;
|
||||
rpmostree_origin_classify_refspec (origin, &refspectype, NULL);
|
||||
|
||||
if (refspectype == RPMOSTREE_REFSPEC_TYPE_CHECKSUM)
|
||||
return glnx_throw (error, "Cannot look up version while pinned to commit");
|
||||
|
||||
g_autofree char *checksum = NULL;
|
||||
g_autofree char *version = NULL;
|
||||
if (!rpmostreed_parse_revision (revision, &checksum, &version, error))
|
||||
@ -163,6 +167,8 @@ apply_revision_override (RpmostreedTransaction *transaction,
|
||||
/* This case we'll look up later */
|
||||
rpmostree_origin_set_rojig_version (origin, version);
|
||||
break;
|
||||
case RPMOSTREE_REFSPEC_TYPE_CHECKSUM:
|
||||
g_assert_not_reached (); /* Handled above */
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -182,6 +188,8 @@ apply_revision_override (RpmostreedTransaction *transaction,
|
||||
* on.
|
||||
*/
|
||||
break;
|
||||
case RPMOSTREE_REFSPEC_TYPE_CHECKSUM:
|
||||
g_assert_not_reached (); /* Handled above */
|
||||
}
|
||||
|
||||
rpmostree_origin_set_override_commit (origin, checksum, version);
|
||||
@ -1135,6 +1143,10 @@ deploy_transaction_execute (RpmostreedTransaction *transaction,
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
/* Past this point we've computed the origin */
|
||||
RpmOstreeRefspecType refspec_type;
|
||||
rpmostree_origin_classify_refspec (origin, &refspec_type, NULL);
|
||||
|
||||
if (download_metadata_only)
|
||||
{
|
||||
/* We have to short-circuit the usual path here; we already downloaded the ostree
|
||||
@ -1246,7 +1258,10 @@ deploy_transaction_execute (RpmostreedTransaction *transaction,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!self->revision)
|
||||
if (refspec_type == RPMOSTREE_REFSPEC_TYPE_CHECKSUM
|
||||
&& layering_type < RPMOSTREE_SYSROOT_UPGRADER_LAYERING_RPMMD_REPOS)
|
||||
rpmostree_output_message ("Pinned to commit; no upgrade available");
|
||||
else if (!self->revision)
|
||||
rpmostree_output_message ("No upgrade available.");
|
||||
else
|
||||
rpmostree_output_message ("No change.");
|
||||
|
@ -50,7 +50,9 @@
|
||||
static OstreeRepo * get_pkgcache_repo (RpmOstreeContext *self);
|
||||
|
||||
/* Given a string, look for ostree:// or rojig:// prefix and
|
||||
* return its type and the remainder of the string.
|
||||
* return its type and the remainder of the string. Note
|
||||
* that ostree:// can be either a refspec (TYPE_OSTREE) or
|
||||
* a bare commit (TYPE_COMMIT).
|
||||
*/
|
||||
gboolean
|
||||
rpmostree_refspec_classify (const char *refspec,
|
||||
@ -58,29 +60,28 @@ rpmostree_refspec_classify (const char *refspec,
|
||||
const char **out_remainder,
|
||||
GError **error)
|
||||
{
|
||||
if (g_str_has_prefix (refspec, RPMOSTREE_REFSPEC_OSTREE_PREFIX))
|
||||
{
|
||||
*out_type = RPMOSTREE_REFSPEC_TYPE_OSTREE;
|
||||
if (out_remainder)
|
||||
*out_remainder = refspec + strlen (RPMOSTREE_REFSPEC_OSTREE_PREFIX);
|
||||
return TRUE;
|
||||
}
|
||||
else if (g_str_has_prefix (refspec, RPMOSTREE_REFSPEC_ROJIG_PREFIX))
|
||||
if (g_str_has_prefix (refspec, RPMOSTREE_REFSPEC_ROJIG_PREFIX))
|
||||
{
|
||||
*out_type = RPMOSTREE_REFSPEC_TYPE_ROJIG;
|
||||
if (out_remainder)
|
||||
*out_remainder = refspec + strlen (RPMOSTREE_REFSPEC_ROJIG_PREFIX);
|
||||
return TRUE;
|
||||
}
|
||||
/* Add any other prefixes here */
|
||||
|
||||
/* Fallback case when we have no explicit prefix - treat this as ostree://
|
||||
* for compatibility. In the future we may do some error checking here,
|
||||
* i.e. trying to parse the refspec.
|
||||
*/
|
||||
*out_type = RPMOSTREE_REFSPEC_TYPE_OSTREE;
|
||||
/* For compatibility, fall back to ostree:// when we have no prefix. */
|
||||
const char *remainder;
|
||||
if (g_str_has_prefix (refspec, RPMOSTREE_REFSPEC_OSTREE_PREFIX))
|
||||
remainder = refspec + strlen (RPMOSTREE_REFSPEC_OSTREE_PREFIX);
|
||||
else
|
||||
remainder = refspec;
|
||||
|
||||
if (ostree_validate_checksum_string (remainder, NULL))
|
||||
*out_type = RPMOSTREE_REFSPEC_TYPE_CHECKSUM;
|
||||
else
|
||||
*out_type = RPMOSTREE_REFSPEC_TYPE_OSTREE;
|
||||
if (out_remainder)
|
||||
*out_remainder = refspec;
|
||||
|
||||
*out_remainder = remainder;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -92,6 +93,7 @@ rpmostree_refspec_to_string (RpmOstreeRefspecType reftype,
|
||||
switch (reftype)
|
||||
{
|
||||
case RPMOSTREE_REFSPEC_TYPE_OSTREE:
|
||||
case RPMOSTREE_REFSPEC_TYPE_CHECKSUM:
|
||||
prefix = RPMOSTREE_REFSPEC_OSTREE_PREFIX;
|
||||
break;
|
||||
case RPMOSTREE_REFSPEC_TYPE_ROJIG:
|
||||
|
@ -51,6 +51,7 @@ G_DECLARE_FINAL_TYPE (RpmOstreeTreespec, rpmostree_treespec, RPMOSTREE, TREESPEC
|
||||
typedef enum {
|
||||
RPMOSTREE_REFSPEC_TYPE_OSTREE,
|
||||
RPMOSTREE_REFSPEC_TYPE_ROJIG,
|
||||
RPMOSTREE_REFSPEC_TYPE_CHECKSUM,
|
||||
} RpmOstreeRefspecType;
|
||||
|
||||
#define RPMOSTREE_REFSPEC_OSTREE_PREFIX "ostree://"
|
||||
|
@ -125,7 +125,8 @@ rpmostree_origin_parse_keyfile (GKeyFile *origin,
|
||||
return glnx_null_throw (error, "Duplicate origin/refspec and origin/rojig in deployment origin");
|
||||
else if (refspec)
|
||||
{
|
||||
ret->refspec_type = RPMOSTREE_REFSPEC_TYPE_OSTREE;
|
||||
if (!rpmostree_refspec_classify (refspec, &ret->refspec_type, NULL, error))
|
||||
return FALSE;
|
||||
/* Note the lack of a prefix here so that code that just calls
|
||||
* rpmostree_origin_get_refspec() in the ostree:// case
|
||||
* sees it without the prefix for compatibility.
|
||||
@ -206,6 +207,7 @@ rpmostree_origin_get_full_refspec (RpmOstreeOrigin *origin,
|
||||
switch (origin->refspec_type)
|
||||
{
|
||||
case RPMOSTREE_REFSPEC_TYPE_OSTREE:
|
||||
case RPMOSTREE_REFSPEC_TYPE_CHECKSUM:
|
||||
return g_strdup (origin->cached_refspec);
|
||||
case RPMOSTREE_REFSPEC_TYPE_ROJIG:
|
||||
return g_strconcat (RPMOSTREE_REFSPEC_ROJIG_PREFIX, origin->cached_refspec, NULL);
|
||||
@ -485,6 +487,7 @@ rpmostree_origin_set_rebase (RpmOstreeOrigin *origin,
|
||||
origin->cached_refspec = g_strdup (refspecdata);
|
||||
switch (origin->refspec_type)
|
||||
{
|
||||
case RPMOSTREE_REFSPEC_TYPE_CHECKSUM:
|
||||
case RPMOSTREE_REFSPEC_TYPE_OSTREE:
|
||||
{
|
||||
g_key_file_remove_key (origin->kf, "origin", "rojig", NULL);
|
||||
@ -577,6 +580,7 @@ update_keyfile_pkgs_from_cache (RpmOstreeOrigin *origin,
|
||||
switch (origin->refspec_type)
|
||||
{
|
||||
case RPMOSTREE_REFSPEC_TYPE_OSTREE:
|
||||
case RPMOSTREE_REFSPEC_TYPE_CHECKSUM:
|
||||
{
|
||||
g_key_file_set_value (origin->kf, "origin", "baserefspec",
|
||||
origin->cached_refspec);
|
||||
|
40
tests/vmcheck/test-pinned-commit.sh
Executable file
40
tests/vmcheck/test-pinned-commit.sh
Executable file
@ -0,0 +1,40 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (C) 2018 Red Hat, Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
. ${commondir}/libtest.sh
|
||||
. ${commondir}/libvm.sh
|
||||
|
||||
set -x
|
||||
|
||||
checksum=$(vm_get_booted_csum)
|
||||
vm_rpmostree rebase :${checksum}
|
||||
vm_assert_status_jq ".deployments[0][\"origin\"] == \"${checksum}\""
|
||||
vm_rpmostree status > status.txt
|
||||
assert_file_has_content status.txt '^ ostree://'${checksum}
|
||||
echo "ok pin to commit"
|
||||
|
||||
vm_rpmostree upgrade >out.txt
|
||||
assert_file_has_content out.txt 'Pinned to commit; no upgrade available'
|
||||
if vm_rpmostree deploy 42 2>err.txt; then
|
||||
fatal "deployed version from commit?"
|
||||
fi
|
||||
assert_file_has_content err.txt 'Cannot look up version while pinned to commit'
|
||||
echo "ok cmds"
|
Loading…
Reference in New Issue
Block a user