update: Split update into check_for_update and update

This way we can avoid printing "updating foo" for every
app even if there is no update.
tingping/wmclass
Alexander Larsson 2017-05-09 12:52:28 +02:00
parent 864f2def12
commit 44cf5076fa
4 changed files with 183 additions and 115 deletions

View File

@ -703,31 +703,47 @@ flatpak_transaction_run (FlatpakTransaction *self,
else if (kind == FLATPAK_TRANSACTION_OP_KIND_UPDATE)
{
opname = _("update");
g_print (_("Updating: %s from %s\n"), pref, op->remote);
res = flatpak_dir_update (self->dir,
self->no_pull,
self->no_deploy,
self->no_static_deltas,
op->ref, op->remote, op->commit,
(const char **)op->subpaths,
NULL,
cancellable, &local_error);
if (res)
g_autofree char *target_commit = flatpak_dir_check_for_update (self->dir, op->ref, op->remote, op->commit,
(const char **)op->subpaths,
self->no_pull,
cancellable, &local_error);
if (target_commit != NULL)
{
g_autoptr(GVariant) deploy_data = NULL;
g_autofree char *commit = NULL;
deploy_data = flatpak_dir_get_deploy_data (self->dir, op->ref, NULL, NULL);
commit = g_strndup (flatpak_deploy_data_get_commit (deploy_data), 12);
g_print (_("Now at %s.\n"), commit);
g_print (_("Updating: %s from %s\n"), pref, op->remote);
res = flatpak_dir_update (self->dir,
self->no_pull,
self->no_deploy,
self->no_static_deltas,
op->commit != NULL, /* Allow downgrade if we specify commit */
op->ref, op->remote, target_commit,
(const char **)op->subpaths,
NULL,
cancellable, &local_error);
if (res)
{
g_autoptr(GVariant) deploy_data = NULL;
g_autofree char *commit = NULL;
deploy_data = flatpak_dir_get_deploy_data (self->dir, op->ref, NULL, NULL);
commit = g_strndup (flatpak_deploy_data_get_commit (deploy_data), 12);
g_print (_("Now at %s.\n"), commit);
}
/* Handle noop-updates */
if (!res && g_error_matches (local_error, FLATPAK_ERROR, FLATPAK_ERROR_ALREADY_INSTALLED))
{
g_print (_("No updates.\n"));
res = TRUE;
g_clear_error (&local_error);
}
}
/* Handle noop-updates */
if (!res && g_error_matches (local_error, FLATPAK_ERROR, FLATPAK_ERROR_ALREADY_INSTALLED))
else
{
g_print (_("No updates.\n"));
res = TRUE;
g_clear_error (&local_error);
res = FALSE;
if (g_error_matches (local_error, FLATPAK_ERROR, FLATPAK_ERROR_ALREADY_INSTALLED))
{
res = TRUE;
g_clear_error (&local_error);
}
}
}
else if (kind == FLATPAK_TRANSACTION_OP_KIND_BUNDLE)

View File

@ -5022,29 +5022,27 @@ out:
return ret;
}
gboolean
flatpak_dir_update (FlatpakDir *self,
gboolean no_pull,
gboolean no_deploy,
gboolean no_static_deltas,
const char *ref,
const char *remote_name,
const char *checksum_or_latest,
const char **opt_subpaths,
OstreeAsyncProgress *progress,
GCancellable *cancellable,
GError **error)
char *
flatpak_dir_check_for_update (FlatpakDir *self,
const char *ref,
const char *remote_name,
const char *checksum_or_latest,
const char **opt_subpaths,
gboolean no_pull,
GCancellable *cancellable,
GError **error)
{
g_autoptr(GVariant) deploy_data = NULL;
g_autofree const char **old_subpaths = NULL;
g_autofree const char *remote_and_branch = NULL;
const char **subpaths;
g_autoptr(GBytes) summary_bytes = NULL;
g_autofree char *url = NULL;
gboolean is_local;
g_autofree char *latest_rev = NULL;
const char *rev = NULL;
const char *target_rev = NULL;
const char *installed_commit;
const char *installed_alt_id;
g_autoptr(GVariant) summary = NULL;
deploy_data = flatpak_dir_get_deploy_data (self, ref,
cancellable, NULL);
@ -5061,69 +5059,118 @@ flatpak_dir_update (FlatpakDir *self,
installed_commit = flatpak_deploy_data_get_commit (deploy_data);
installed_alt_id = flatpak_deploy_data_get_alt_id (deploy_data);
if (!ostree_repo_remote_get_url (self->repo, remote_name, &url, error))
{
return NULL;
}
if (*url == 0)
{
/* Empty URL => disabled, but we preted to be already installed to avoid warnings */
g_set_error (error, FLATPAK_ERROR, FLATPAK_ERROR_ALREADY_INSTALLED,
_("%s branch %s already installed"), ref, installed_commit);
return NULL;
}
if (no_pull)
{
remote_and_branch = g_strdup_printf ("%s:%s", remote_name, ref);
if (!ostree_repo_resolve_rev (self->repo, remote_and_branch, FALSE, &latest_rev, NULL))
{
g_set_error (error, FLATPAK_ERROR, FLATPAK_ERROR_ALREADY_INSTALLED,
_("%s branch %s already installed"), ref, installed_commit);
return NULL; /* No update, because nothing to update to */
}
}
else
{
g_autoptr(GVariant) summary = NULL;
latest_rev = flatpak_dir_lookup_ref_from_summary (self, remote_name, ref, NULL, NULL, error);
if (latest_rev == NULL)
return NULL;
}
if (checksum_or_latest != NULL)
target_rev = checksum_or_latest;
else
target_rev = latest_rev;
/* Not deployed => update */
if (deploy_data == NULL)
return g_strdup (target_rev);
/* Different target commit than deployed => update */
if (g_strcmp0 (target_rev, installed_commit) != 0 &&
g_strcmp0 (target_rev, installed_alt_id) != 0)
return g_strdup (target_rev);
/* target rev is the same as latest, but maybe something else that is different? */
/* Same commit, but different subpaths => update */
if (!_g_strv_equal0 ((char **)subpaths, (char **)old_subpaths))
return g_strdup (target_rev);
g_set_error (error, FLATPAK_ERROR, FLATPAK_ERROR_ALREADY_INSTALLED,
_("%s branch %s already installed"), ref, installed_commit);
return NULL;
}
gboolean
flatpak_dir_update (FlatpakDir *self,
gboolean no_pull,
gboolean no_deploy,
gboolean no_static_deltas,
gboolean allow_downgrade,
const char *ref,
const char *remote_name,
const char *commit,
const char **opt_subpaths,
OstreeAsyncProgress *progress,
GCancellable *cancellable,
GError **error)
{
g_autoptr(GVariant) deploy_data = NULL;
const char **subpaths = NULL;
g_autofree char *url = NULL;
FlatpakPullFlags flatpak_flags;
gboolean is_oci;
/* This is calculated in check_for_update */
g_assert (commit != NULL);
flatpak_flags = FLATPAK_PULL_FLAGS_DOWNLOAD_EXTRA_DATA;
if (allow_downgrade)
flatpak_flags |= FLATPAK_PULL_FLAGS_ALLOW_DOWNGRADE;
if (no_static_deltas)
flatpak_flags |= FLATPAK_PULL_FLAGS_NO_STATIC_DELTAS;
deploy_data = flatpak_dir_get_deploy_data (self, ref,
cancellable, NULL);
if (opt_subpaths)
subpaths = opt_subpaths;
else if (deploy_data != NULL)
subpaths = flatpak_deploy_data_get_subpaths (deploy_data);
if (!ostree_repo_remote_get_url (self->repo, remote_name, &url, error))
return FALSE;
if (*url == 0)
return TRUE; /* Empty URL => disabled */
rev = checksum_or_latest;
is_local = g_str_has_prefix (url, "file:");
/* Quick check to terminate early if nothing changed in cached summary
(and subpaths didn't change) */
if (!no_pull && !is_local && deploy_data != NULL &&
_g_strv_equal0 ((char **)subpaths, (char **)old_subpaths))
{
if (checksum_or_latest != NULL)
{
if (strcmp (checksum_or_latest, installed_commit) == 0)
{
g_set_error (error, FLATPAK_ERROR, FLATPAK_ERROR_ALREADY_INSTALLED,
_("%s branch %s already installed"), ref, installed_commit);
return FALSE;
}
}
else if (flatpak_dir_remote_fetch_summary (self, remote_name,
&summary_bytes, NULL,
cancellable, NULL))
{
g_autoptr(GVariant) summary =
g_variant_ref_sink (g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT,
summary_bytes, FALSE));
if (flatpak_summary_lookup_ref (summary,
ref,
&latest_rev, NULL))
{
if (g_strcmp0 (latest_rev, installed_commit) == 0 ||
g_strcmp0 (latest_rev, installed_alt_id) == 0)
{
g_set_error (error, FLATPAK_ERROR, FLATPAK_ERROR_ALREADY_INSTALLED,
_("%s branch %s already installed"), ref, installed_commit);
return FALSE;
}
rev = latest_rev;
}
}
}
is_oci = flatpak_dir_get_remote_oci (self, remote_name);
if (flatpak_dir_use_system_helper (self, NULL))
{
const char *installation = flatpak_dir_get_id (self);
g_autoptr(OstreeRepo) child_repo = NULL;
g_auto(GLnxLockFile) child_repo_lock = GLNX_LOCK_FILE_INIT;
g_autofree char *latest_checksum = NULL;
FlatpakSystemHelper *system_helper;
g_autofree char *child_repo_path = NULL;
FlatpakHelperDeployFlags helper_flags = 0;
g_autofree char *url = NULL;
gboolean gpg_verify_summary;
gboolean gpg_verify;
gboolean is_oci;
if (checksum_or_latest != NULL)
return flatpak_fail (error, "Can't update to a specific commit without root permissions");
system_helper = flatpak_dir_get_system_helper (self);
g_assert (system_helper != NULL);
@ -5147,12 +5194,8 @@ flatpak_dir_update (FlatpakDir *self,
&gpg_verify, error))
return FALSE;
is_oci = flatpak_dir_get_remote_oci (self, remote_name);
if (no_pull)
{
if (!ostree_repo_resolve_rev (self->repo, ref, FALSE, &latest_checksum, error))
return FALSE;
}
else if (!gpg_verify_summary || !gpg_verify)
{
@ -5188,47 +5231,33 @@ 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 (no_static_deltas)
flatpak_flags |= FLATPAK_PULL_FLAGS_NO_STATIC_DELTAS;
if (!flatpak_dir_pull (self, remote_name, ref, rev, subpaths,
flatpak_flags |= FLATPAK_PULL_FLAGS_SIDELOAD_EXTRA_DATA;
if (!flatpak_dir_pull (self, remote_name, ref, commit, subpaths,
child_repo,
flatpak_flags, OSTREE_REPO_PULL_FLAGS_MIRROR,
progress, cancellable, error))
return FALSE;
if (!ostree_repo_resolve_rev (child_repo, ref, FALSE, &latest_checksum, error))
return FALSE;
child_repo_path = g_file_get_path (ostree_repo_get_path (child_repo));
}
if (no_deploy)
helper_flags |= FLATPAK_HELPER_DEPLOY_FLAGS_NO_DEPLOY;
if (g_strcmp0 (installed_commit, latest_checksum) != 0)
{
const char *installation = flatpak_dir_get_id (self);
g_debug ("Calling system helper: Deploy");
if (!flatpak_system_helper_call_deploy_sync (system_helper,
child_repo_path ? child_repo_path : "",
helper_flags, ref, remote_name,
subpaths,
installation ? installation : "",
cancellable,
error))
return FALSE;
}
g_debug ("Calling system helper: Deploy");
if (!flatpak_system_helper_call_deploy_sync (system_helper,
child_repo_path ? child_repo_path : "",
helper_flags, ref, remote_name,
subpaths,
installation ? installation : "",
cancellable,
error))
return FALSE;
if (child_repo_path)
(void) glnx_shutil_rm_rf_at (AT_FDCWD, child_repo_path, NULL, NULL);
@ -5238,15 +5267,20 @@ flatpak_dir_update (FlatpakDir *self,
if (!no_pull)
{
if (!flatpak_dir_pull (self, remote_name, ref, rev, subpaths,
NULL, FLATPAK_PULL_FLAGS_DOWNLOAD_EXTRA_DATA, OSTREE_REPO_PULL_FLAGS_NONE,
if (!flatpak_dir_pull (self, remote_name, ref, commit, subpaths,
NULL, flatpak_flags, OSTREE_REPO_PULL_FLAGS_NONE,
progress, cancellable, error))
return FALSE;
}
if (!no_deploy)
{
if (!flatpak_dir_deploy_update (self, ref, checksum_or_latest, subpaths,
if (!flatpak_dir_deploy_update (self, ref,
/* We don't know the local commit id in the OCI case, and
we only support one version anyway */
is_oci ? NULL : commit,
subpaths,
cancellable, error))
return FALSE;
}

View File

@ -393,10 +393,19 @@ gboolean flatpak_dir_install_bundle (FlatpakDir *self,
char **out_ref,
GCancellable *cancellable,
GError **error);
char * flatpak_dir_check_for_update (FlatpakDir *self,
const char *ref,
const char *remote_name,
const char *checksum_or_latest,
const char **opt_subpaths,
gboolean no_pull,
GCancellable *cancellable,
GError **error);
gboolean flatpak_dir_update (FlatpakDir *self,
gboolean no_pull,
gboolean no_deploy,
gboolean no_static_deltas,
gboolean allow_downgrade,
const char *ref,
const char *remote_name,
const char *checksum_or_latest,

View File

@ -1539,6 +1539,7 @@ flatpak_installation_update_full (FlatpakInstallation *self,
g_autoptr(OstreeAsyncProgress) ostree_progress = NULL;
g_autofree char *remote_name = NULL;
FlatpakInstalledRef *result = NULL;
g_autofree char *target_commit = NULL;
ref = flatpak_compose_ref (kind == FLATPAK_REF_KIND_APP, name, branch, arch, error);
if (ref == NULL)
@ -1557,6 +1558,13 @@ flatpak_installation_update_full (FlatpakInstallation *self,
if (remote_name == NULL)
return NULL;
target_commit = flatpak_dir_check_for_update (dir, ref, remote_name, NULL,
(const char **)subpaths,
(flags & FLATPAK_UPDATE_FLAGS_NO_PULL) != 0,
cancellable, error);
if (target_commit != NULL)
return NULL;
/* Pull, prune, etc are not threadsafe, so we work on a copy */
dir_clone = flatpak_dir_clone (dir);
if (!flatpak_dir_ensure_repo (dir_clone, cancellable, error))
@ -1577,7 +1585,8 @@ flatpak_installation_update_full (FlatpakInstallation *self,
(flags & FLATPAK_UPDATE_FLAGS_NO_PULL) != 0,
(flags & FLATPAK_UPDATE_FLAGS_NO_DEPLOY) != 0,
(flags & FLATPAK_UPDATE_FLAGS_NO_STATIC_DELTAS) != 0,
ref, remote_name, NULL, NULL,
FALSE,
ref, remote_name, target_commit, (const char **)subpaths,
ostree_progress, cancellable, error))
goto out;