Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pending-base-commit to status #595

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 39 additions & 2 deletions src/app/rpmostree-builtin-status.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ status_generic (RPMOSTreeSysroot *sysroot_proxy,
{
g_autoptr(GVariant) child = g_variant_iter_next_value (&iter);
g_autoptr(GVariantDict) dict = NULL;
gboolean is_locally_assembled;
const gchar *const*origin_packages = NULL;
const gchar *origin_refspec;
const gchar *id;
Expand All @@ -123,7 +124,8 @@ status_generic (RPMOSTreeSysroot *sysroot_proxy,
guint64 t = 0;
int serial;
gboolean is_booted;
const guint max_key_len = strlen ("GPGSignature");
const gboolean was_first = first;
const guint max_key_len = strlen ("PendingBaseVersion");
g_autoptr(GVariant) signatures = NULL;
g_autofree char *timestamp_string = NULL;

Expand Down Expand Up @@ -198,13 +200,48 @@ status_generic (RPMOSTreeSysroot *sysroot_proxy,
{
print_kv ("Timestamp", max_key_len, timestamp_string);
}
if (origin_packages || regenerate_initramfs)
is_locally_assembled = origin_packages || regenerate_initramfs;
if (is_locally_assembled)
{
const char *base_checksum;
g_assert (g_variant_dict_lookup (dict, "base-checksum", "&s", &base_checksum));
print_kv ("BaseCommit", max_key_len, base_checksum);
}
print_kv ("Commit", max_key_len, checksum);

/* Show any difference between the baseref vs head, but only for the
booted commit, and only if there isn't a pending deployment. Otherwise
it's either unnecessary or too noisy.
*/
if (is_booted && was_first)
{
const gchar *pending_checksum = NULL;
const gchar *pending_version = NULL;

if (g_variant_dict_lookup (dict, "pending-base-checksum", "&s", &pending_checksum))
{
print_kv (is_locally_assembled ? "PendingBaseCommit" : "PendingCommit",
max_key_len, pending_checksum);
g_assert (g_variant_dict_lookup (dict, "pending-base-timestamp", "t", &t));
g_variant_dict_lookup (dict, "pending-base-version", "&s", &pending_version);

if (pending_version)
{
g_autoptr(GDateTime) timestamp = g_date_time_new_from_unix_utc (t);
g_autofree char *version_time = NULL;

if (timestamp != NULL)
timestamp_string = g_date_time_format (timestamp, "%Y-%m-%d %T");
else
timestamp_string = g_strdup_printf ("(invalid timestamp)");

version_time = g_strdup_printf ("%s (%s)", pending_version, timestamp_string);
print_kv (is_locally_assembled ? "PendingBaseVersion" : "PendingVersion",
max_key_len, version_time);
}
}
}

print_kv ("OSName", max_key_len, os_name);

if (!g_variant_dict_lookup (dict, "gpg-enabled", "b", &gpg_enabled))
Expand Down
53 changes: 40 additions & 13 deletions src/daemon/rpmostreed-deployment-utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ rpmostreed_deployment_generate_blank_variant (void)

static void
variant_add_commit_details (GVariantDict *dict,
GVariant *commit)
const char *prefix,
GVariant *commit)
{
g_autoptr(GVariant) metadata = NULL;
g_autofree gchar *version_commit = NULL;
Expand All @@ -152,9 +153,11 @@ variant_add_commit_details (GVariantDict *dict,
g_variant_lookup (metadata, "version", "s", &version_commit);

if (version_commit != NULL)
g_variant_dict_insert (dict, "version", "s", version_commit);
g_variant_dict_insert (dict, glnx_strjoina (prefix ?: "", "version"),
"s", version_commit);
if (timestamp > 0)
g_variant_dict_insert (dict, "timestamp", "t", timestamp);
g_variant_dict_insert (dict, glnx_strjoina (prefix ?: "", "timestamp"),
"t", timestamp);
}

GVariant *
Expand All @@ -166,11 +169,14 @@ rpmostreed_deployment_generate_variant (OstreeDeployment *deployment,
g_autoptr(GVariant) commit = NULL;
g_autoptr(RpmOstreeOrigin) origin = NULL;
g_autofree gchar *id = NULL;
const char *base_checksum;

GVariant *sigs = NULL; /* floating variant */

GVariantDict dict;

const char *refspec;
g_autofree char *pending_base_commitrev = NULL;
const gchar *osname = ostree_deployment_get_osname (deployment);
const gchar *csum = ostree_deployment_get_csum (deployment);
gint serial = ostree_deployment_get_deployserial (deployment);
Expand All @@ -189,6 +195,8 @@ rpmostreed_deployment_generate_variant (OstreeDeployment *deployment,
if (!origin)
return NULL;

refspec = rpmostree_origin_get_refspec (origin);

g_variant_dict_init (&dict, NULL);

g_variant_dict_insert (&dict, "id", "s", id);
Expand All @@ -198,18 +206,37 @@ rpmostreed_deployment_generate_variant (OstreeDeployment *deployment,
g_variant_dict_insert (&dict, "checksum", "s", csum);
if (rpmostree_origin_is_locally_assembled (origin))
{
const char *parent = ostree_commit_get_parent (commit);
g_assert (parent);
g_variant_dict_insert (&dict, "base-checksum", "s", parent);
sigs = rpmostreed_deployment_gpg_results (repo, rpmostree_origin_get_refspec (origin),
parent, &gpg_enabled);
base_checksum = ostree_commit_get_parent (commit);
g_assert (base_checksum);
g_variant_dict_insert (&dict, "base-checksum", "s", base_checksum);
}
else
sigs = rpmostreed_deployment_gpg_results (repo, rpmostree_origin_get_refspec (origin),
csum, &gpg_enabled);
{
base_checksum = csum;
}
sigs = rpmostreed_deployment_gpg_results (repo, refspec, base_checksum, &gpg_enabled);
variant_add_commit_details (&dict, NULL, commit);

if (!ostree_repo_resolve_rev (repo, refspec, TRUE,
&pending_base_commitrev, error))
return NULL;

if (pending_base_commitrev && strcmp (pending_base_commitrev, base_checksum) != 0)
{
g_autoptr(GVariant) pending_base_commit = NULL;

if (!ostree_repo_load_variant (repo,
OSTREE_OBJECT_TYPE_COMMIT,
pending_base_commitrev,
&pending_base_commit,
error))
return NULL;

g_variant_dict_insert (&dict, "pending-base-checksum", "s", pending_base_commitrev);
variant_add_commit_details (&dict, "pending-base-", pending_base_commit);
}

variant_add_commit_details (&dict, commit);
g_variant_dict_insert (&dict, "origin", "s", rpmostree_origin_get_refspec (origin));
g_variant_dict_insert (&dict, "origin", "s", refspec);
if (rpmostree_origin_get_packages (origin) != NULL)
g_variant_dict_insert (&dict, "packages", "^as", rpmostree_origin_get_packages (origin));
if (sigs != NULL)
Expand Down Expand Up @@ -285,7 +312,7 @@ rpmostreed_commit_generate_cached_details_variant (OstreeDeployment *deployment,
if (osname != NULL)
g_variant_dict_insert (&dict, "osname", "s", osname);
g_variant_dict_insert (&dict, "checksum", "s", head);
variant_add_commit_details (&dict, commit);
variant_add_commit_details (&dict, NULL, commit);
g_variant_dict_insert (&dict, "origin", "s", origin_refspec);
if (sigs != NULL)
g_variant_dict_insert_value (&dict, "signatures", sigs);
Expand Down
13 changes: 13 additions & 0 deletions tests/common/libtest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -382,3 +382,16 @@ ensure_dbus ()
exec "$topsrcdir/tests/utils/setup-session.sh" "$self"
fi
}

# Assert that @expression is true in @jsonfile
assert_status_jq() {
vm_rpmostree status --json > status.json

for expression in "$@"; do
if ! jq -e "${expression}" >/dev/null < status.json; then
jq . < status.json | sed -e 's/^/# /' >&2
echo 1>&2 "${expression} failed to match in status.json"
exit 1
fi
done
}
63 changes: 24 additions & 39 deletions tests/vmcheck/test-initramfs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,6 @@ set -x

# SUMMARY: Tests for the `initramfs` functionality

assert_jq() {
expression=$1
jsonfile=$2

if ! jq -e "${expression}" >/dev/null < $jsonfile; then
jq . < $jsonfile | sed -e 's/^/# /' >&2
echo 1>&2 "${expression} failed to match in $jsonfile"
exit 1
fi
}

vm_send_test_repo
base=$(vm_get_booted_csum)

Expand All @@ -55,20 +44,19 @@ assert_file_has_content err.txt "reboot.*used with.*enable"
echo "ok initramfs state"

vm_rpmostree initramfs --enable
vm_rpmostree status --json > status.json
assert_jq '.deployments[1].booted' status.json
assert_jq '.deployments[0]["regenerate-initramfs"]' status.json
assert_jq '.deployments[1]["regenerate-initramfs"]|not' status.json
assert_status_jq \
'.deployments[1].booted' \
'.deployments[0]["regenerate-initramfs"]' \
'.deployments[1]["regenerate-initramfs"]|not'

vm_reboot

assert_not_streq $base $(vm_get_booted_csum)
vm_rpmostree status --json > status.json
assert_jq '.deployments[0].booted' status.json
assert_jq '.deployments[0]["regenerate-initramfs"]' status.json
assert_jq '.deployments[0]["initramfs-args"]|length == 0' status.json
assert_jq '.deployments[1]["regenerate-initramfs"]|not' status.json
assert_jq '.deployments[1]["initramfs-args"]|not' status.json
assert_status_jq '.deployments[0].booted' \
'.deployments[0]["regenerate-initramfs"]' \
'.deployments[0]["initramfs-args"]|length == 0' \
'.deployments[1]["regenerate-initramfs"]|not' \
'.deployments[1]["initramfs-args"]|not'

if vm_rpmostree initramfs --enable 2>err.txt; then
assert_not_reached "Unexpectedly succeeded at enabling"
Expand All @@ -78,24 +66,21 @@ echo "ok initramfs enabled"

vm_rpmostree initramfs --disable
vm_reboot
vm_rpmostree status --json > status.json
assert_jq '.deployments[0].booted' status.json
assert_jq '.deployments[0]["regenerate-initramfs"]|not' status.json
assert_jq '.deployments[1]["regenerate-initramfs"]' status.json
assert_status_jq '.deployments[0].booted' \
'.deployments[0]["regenerate-initramfs"]|not' \
'.deployments[1]["regenerate-initramfs"]'

echo "ok initramfs disabled"

vm_reboot_cmd rpm-ostree initramfs --enable --reboot
vm_rpmostree status --json > status.json
assert_jq '.deployments[0].booted' status.json
assert_jq '.deployments[0]["regenerate-initramfs"]' status.json
assert_jq '.deployments[1]["regenerate-initramfs"]|not' status.json
assert_status_jq '.deployments[0].booted' \
'.deployments[0]["regenerate-initramfs"]' \
'.deployments[1]["regenerate-initramfs"]|not'

vm_reboot_cmd rpm-ostree initramfs --disable --reboot
vm_rpmostree status --json > status.json
assert_jq '.deployments[0].booted' status.json
assert_jq '.deployments[0]["regenerate-initramfs"]|not' status.json
assert_jq '.deployments[1]["regenerate-initramfs"]' status.json
assert_status_jq '.deployments[0].booted' \
'.deployments[0]["regenerate-initramfs"]|not' \
'.deployments[1]["regenerate-initramfs"]'

echo "ok initramfs enable disable reboot"

Expand All @@ -104,12 +89,12 @@ for file in first second; do
vm_cmd touch /etc/rpmostree-initramfs-testing-$file
vm_rpmostree initramfs --enable --arg="-I" --arg="/etc/rpmostree-initramfs-testing-$file"
vm_reboot
vm_rpmostree status --json > status.json
assert_jq '.deployments[0].booted' status.json
assert_jq '.deployments[0]["regenerate-initramfs"]' status.json
assert_jq '.deployments[0]["initramfs-args"]|index("-I") == 0' status.json
assert_jq '.deployments[0]["initramfs-args"]|index("/etc/rpmostree-initramfs-testing-'${file}'") == 1' status.json
assert_jq '.deployments[0]["initramfs-args"]|length == 2' status.json
assert_status_jq \
'.deployments[0].booted' \
'.deployments[0]["regenerate-initramfs"]' \
'.deployments[0]["initramfs-args"]|index("-I") == 0' \
'.deployments[0]["initramfs-args"]|index("/etc/rpmostree-initramfs-testing-'${file}'") == 1' \
'.deployments[0]["initramfs-args"]|length == 2'
initramfs=$(vm_cmd grep ^initrd /boot/loader/entries/ostree-fedora-atomic-0.conf | sed -e 's,initrd ,/boot/,')
test -n "${initramfs}"
vm_cmd lsinitrd $initramfs > lsinitrd.txt
Expand Down
4 changes: 4 additions & 0 deletions tests/vmcheck/test-layering-basic.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ vm_send_test_repo

# make sure the package is not already layered
vm_assert_layered_pkg foo absent
assert_status_jq '.deployments[0]["base-checksum"]|not' \
'.deployments[0]["pending-base-checksum"]|not'

# Be sure an unprivileged user exists
vm_cmd getent passwd bin
Expand All @@ -44,6 +46,8 @@ vm_rpmostree pkg-add foo-1.0
echo "ok pkg-add foo"

vm_reboot
assert_status_jq '.deployments[0]["base-checksum"]' \
'.deployments[0]["pending-base-checksum"]|not'

vm_assert_layered_pkg foo-1.0 present
echo "ok pkg foo added"
Expand Down
8 changes: 8 additions & 0 deletions tests/vmcheck/test-layering-relayer.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,18 @@ reboot_and_assert_base() {

# UPGRADE

assert_status_jq '.deployments[0]["base-checksum"]' \
'.deployments[0]["pending-base-checksum"]|not'
# let's synthesize an upgrade
commit=$(vm_cmd ostree commit -b vmcheck --tree=ref=vmcheck)
vm_rpmostree upgrade
assert_status_jq '.deployments[1]["base-checksum"]' \
'.deployments[1]["pending-base-checksum"]'
vm_rpmostree status --json > status.json
reboot_and_assert_base $commit
assert_status_jq '.deployments[0]["base-checksum"]' \
'.deployments[0]["pending-base-checksum"]|not' \
'.deployments[1]["pending-base-checksum"]'
echo "ok upgrade"

vm_assert_layered_pkg foo present
Expand Down