diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c index 1f1227fb..2e1f7f69 100644 --- a/common/flatpak-dir.c +++ b/common/flatpak-dir.c @@ -1769,6 +1769,7 @@ repo_pull_one_dir (OstreeRepo *self, const char **dirs_to_pull, const char *ref_to_fetch, const char *rev_to_fetch, + FlatpakPullFlags flatpak_flags, OstreeRepoPullFlags flags, OstreeAsyncProgress *progress, GCancellable *cancellable, @@ -1776,7 +1777,11 @@ repo_pull_one_dir (OstreeRepo *self, { GVariantBuilder builder; gboolean force_disable_deltas = FALSE; + g_autofree char *remote_and_branch = NULL; + g_autofree char *current_checksum = NULL; g_autoptr(GVariant) options = NULL; + g_autoptr(GVariant) old_commit = NULL; + g_autoptr(GVariant) new_commit = NULL; const char *refs_to_fetch[2]; const char *revs_to_fetch[2]; gboolean res; @@ -1811,9 +1816,33 @@ repo_pull_one_dir (OstreeRepo *self, g_variant_new_variant (g_variant_new_strv ((const char * const *) revs_to_fetch, -1))); options = g_variant_ref_sink (g_variant_builder_end (&builder)); + + remote_and_branch = g_strdup_printf ("%s:%s", remote_name, ref_to_fetch); + if (!ostree_repo_resolve_rev (self, remote_and_branch, TRUE, ¤t_checksum, error)) + return FALSE; + if (current_checksum != NULL && + !ostree_repo_load_commit (self, current_checksum, &old_commit, NULL, error)) + return FALSE; + res = ostree_repo_pull_with_options (self, remote_name, options, progress, cancellable, error); + if (old_commit && + (flatpak_flags & FLATPAK_PULL_FLAGS_ALLOW_DOWNGRADE) == 0) + { + guint64 old_timestamp; + guint64 new_timestamp; + + if (!ostree_repo_load_commit (self, rev_to_fetch, &new_commit, NULL, error)) + return FALSE; + + old_timestamp = ostree_commit_get_timestamp (old_commit); + new_timestamp = ostree_commit_get_timestamp (new_commit); + + if (new_timestamp < old_timestamp) + return flatpak_fail (error, "Update is older then current version"); + } + return res; } @@ -2376,7 +2405,7 @@ flatpak_dir_pull (FlatpakDir *self, if (!repo_pull_one_dir (repo, repository, subdirs_arg ? (const char **)subdirs_arg->pdata : NULL, - ref, rev, flags, + ref, rev, flatpak_flags, flags, progress, cancellable, error)) { @@ -5080,15 +5109,19 @@ flatpak_dir_update (FlatpakDir *self, /* We're pulling from a remote source, we do the network mirroring pull as a user and hand back the resulting data to the system-helper, that trusts us due to the GPG signatures in the repo */ + FlatpakPullFlags flatpak_flags; child_repo = flatpak_dir_create_system_child_repo (self, &child_repo_lock, error); if (child_repo == NULL) return FALSE; + flatpak_flags = FLATPAK_PULL_FLAGS_DOWNLOAD_EXTRA_DATA | FLATPAK_PULL_FLAGS_SIDELOAD_EXTRA_DATA; + if (checksum_or_latest != NULL) + flatpak_flags |= FLATPAK_PULL_FLAGS_ALLOW_DOWNGRADE; + if (!flatpak_dir_pull (self, remote_name, ref, rev, subpaths, child_repo, - FLATPAK_PULL_FLAGS_DOWNLOAD_EXTRA_DATA | FLATPAK_PULL_FLAGS_SIDELOAD_EXTRA_DATA, - OSTREE_REPO_PULL_FLAGS_MIRROR, + flatpak_flags, OSTREE_REPO_PULL_FLAGS_MIRROR, progress, cancellable, error)) return FALSE; diff --git a/common/flatpak-dir.h b/common/flatpak-dir.h index 52a3747b..8d9b6f19 100644 --- a/common/flatpak-dir.h +++ b/common/flatpak-dir.h @@ -98,6 +98,7 @@ typedef enum { FLATPAK_PULL_FLAGS_NONE = 0, FLATPAK_PULL_FLAGS_DOWNLOAD_EXTRA_DATA = 1 << 0, FLATPAK_PULL_FLAGS_SIDELOAD_EXTRA_DATA = 1 << 1, + FLATPAK_PULL_FLAGS_ALLOW_DOWNGRADE = 1 << 2, } FlatpakPullFlags; typedef enum { diff --git a/tests/test-run.sh b/tests/test-run.sh index 0a8d59b9..0f0d3aa9 100755 --- a/tests/test-run.sh +++ b/tests/test-run.sh @@ -24,7 +24,7 @@ set -euo pipefail skip_without_bwrap skip_without_user_xattrs -echo "1..9" +echo "1..10" setup_repo install_repo @@ -206,6 +206,19 @@ assert_file_has_content hello_out '^Hello world, from a sandboxUPDATED$' echo "ok update" +ostree --repo=repos/test reset app/org.test.Hello/$ARCH/master "$OLD_COMMIT" +update_repo + +if ${FLATPAK} ${U} update org.test.Hello; then + assert_not_reached "Should not be able to update to older commit" +fi + +NEW_NEW_COMMIT=`${FLATPAK} ${U} info --show-commit org.test.Hello` + +assert_streq "$NEW_COMMIT" "$NEW_NEW_COMMIT" + +echo "ok backwards update" + DIR=`mktemp -d` ${FLATPAK} build-init ${DIR} org.test.Split org.test.Platform org.test.Platform