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.
This commit is contained in:
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) else if (kind == FLATPAK_TRANSACTION_OP_KIND_UPDATE)
{ {
opname = _("update"); opname = _("update");
g_print (_("Updating: %s from %s\n"), pref, op->remote); g_autofree char *target_commit = flatpak_dir_check_for_update (self->dir, op->ref, op->remote, op->commit,
res = flatpak_dir_update (self->dir, (const char **)op->subpaths,
self->no_pull, self->no_pull,
self->no_deploy, cancellable, &local_error);
self->no_static_deltas, if (target_commit != NULL)
op->ref, op->remote, op->commit,
(const char **)op->subpaths,
NULL,
cancellable, &local_error);
if (res)
{ {
g_autoptr(GVariant) deploy_data = NULL; g_print (_("Updating: %s from %s\n"), pref, op->remote);
g_autofree char *commit = NULL; res = flatpak_dir_update (self->dir,
deploy_data = flatpak_dir_get_deploy_data (self->dir, op->ref, NULL, NULL); self->no_pull,
commit = g_strndup (flatpak_deploy_data_get_commit (deploy_data), 12); self->no_deploy,
g_print (_("Now at %s.\n"), commit); 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);
}
} }
else
/* Handle noop-updates */
if (!res && g_error_matches (local_error, FLATPAK_ERROR, FLATPAK_ERROR_ALREADY_INSTALLED))
{ {
g_print (_("No updates.\n")); res = FALSE;
res = TRUE; if (g_error_matches (local_error, FLATPAK_ERROR, FLATPAK_ERROR_ALREADY_INSTALLED))
g_clear_error (&local_error); {
res = TRUE;
g_clear_error (&local_error);
}
} }
} }
else if (kind == FLATPAK_TRANSACTION_OP_KIND_BUNDLE) else if (kind == FLATPAK_TRANSACTION_OP_KIND_BUNDLE)

View File

@@ -5022,29 +5022,27 @@ out:
return ret; return ret;
} }
gboolean char *
flatpak_dir_update (FlatpakDir *self, flatpak_dir_check_for_update (FlatpakDir *self,
gboolean no_pull, const char *ref,
gboolean no_deploy, const char *remote_name,
gboolean no_static_deltas, const char *checksum_or_latest,
const char *ref, const char **opt_subpaths,
const char *remote_name, gboolean no_pull,
const char *checksum_or_latest, GCancellable *cancellable,
const char **opt_subpaths, GError **error)
OstreeAsyncProgress *progress,
GCancellable *cancellable,
GError **error)
{ {
g_autoptr(GVariant) deploy_data = NULL; g_autoptr(GVariant) deploy_data = NULL;
g_autofree const char **old_subpaths = NULL; g_autofree const char **old_subpaths = NULL;
g_autofree const char *remote_and_branch = NULL;
const char **subpaths; const char **subpaths;
g_autoptr(GBytes) summary_bytes = NULL; g_autoptr(GBytes) summary_bytes = NULL;
g_autofree char *url = NULL; g_autofree char *url = NULL;
gboolean is_local;
g_autofree char *latest_rev = NULL; g_autofree char *latest_rev = NULL;
const char *rev = NULL; const char *target_rev = NULL;
const char *installed_commit; const char *installed_commit;
const char *installed_alt_id; const char *installed_alt_id;
g_autoptr(GVariant) summary = NULL;
deploy_data = flatpak_dir_get_deploy_data (self, ref, deploy_data = flatpak_dir_get_deploy_data (self, ref,
cancellable, NULL); cancellable, NULL);
@@ -5061,69 +5059,118 @@ flatpak_dir_update (FlatpakDir *self,
installed_commit = flatpak_deploy_data_get_commit (deploy_data); installed_commit = flatpak_deploy_data_get_commit (deploy_data);
installed_alt_id = flatpak_deploy_data_get_alt_id (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)) if (!ostree_repo_remote_get_url (self->repo, remote_name, &url, error))
return FALSE; return FALSE;
if (*url == 0) if (*url == 0)
return TRUE; /* Empty URL => disabled */ return TRUE; /* Empty URL => disabled */
rev = checksum_or_latest; is_oci = flatpak_dir_get_remote_oci (self, remote_name);
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;
}
}
}
if (flatpak_dir_use_system_helper (self, NULL)) if (flatpak_dir_use_system_helper (self, NULL))
{ {
const char *installation = flatpak_dir_get_id (self);
g_autoptr(OstreeRepo) child_repo = NULL; g_autoptr(OstreeRepo) child_repo = NULL;
g_auto(GLnxLockFile) child_repo_lock = GLNX_LOCK_FILE_INIT; g_auto(GLnxLockFile) child_repo_lock = GLNX_LOCK_FILE_INIT;
g_autofree char *latest_checksum = NULL;
FlatpakSystemHelper *system_helper; FlatpakSystemHelper *system_helper;
g_autofree char *child_repo_path = NULL; g_autofree char *child_repo_path = NULL;
FlatpakHelperDeployFlags helper_flags = 0; FlatpakHelperDeployFlags helper_flags = 0;
g_autofree char *url = NULL; g_autofree char *url = NULL;
gboolean gpg_verify_summary; gboolean gpg_verify_summary;
gboolean gpg_verify; 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); system_helper = flatpak_dir_get_system_helper (self);
g_assert (system_helper != NULL); g_assert (system_helper != NULL);
@@ -5147,12 +5194,8 @@ flatpak_dir_update (FlatpakDir *self,
&gpg_verify, error)) &gpg_verify, error))
return FALSE; return FALSE;
is_oci = flatpak_dir_get_remote_oci (self, remote_name);
if (no_pull) if (no_pull)
{ {
if (!ostree_repo_resolve_rev (self->repo, ref, FALSE, &latest_checksum, error))
return FALSE;
} }
else if (!gpg_verify_summary || !gpg_verify) 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 /* 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 user and hand back the resulting data to the system-helper, that trusts us
due to the GPG signatures in the repo */ due to the GPG signatures in the repo */
FlatpakPullFlags flatpak_flags;
child_repo = flatpak_dir_create_system_child_repo (self, &child_repo_lock, error); child_repo = flatpak_dir_create_system_child_repo (self, &child_repo_lock, error);
if (child_repo == NULL) if (child_repo == NULL)
return FALSE; return FALSE;
flatpak_flags = FLATPAK_PULL_FLAGS_DOWNLOAD_EXTRA_DATA | FLATPAK_PULL_FLAGS_SIDELOAD_EXTRA_DATA; flatpak_flags |= FLATPAK_PULL_FLAGS_SIDELOAD_EXTRA_DATA;
if (checksum_or_latest != NULL) if (!flatpak_dir_pull (self, remote_name, ref, commit, subpaths,
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,
child_repo, child_repo,
flatpak_flags, OSTREE_REPO_PULL_FLAGS_MIRROR, flatpak_flags, OSTREE_REPO_PULL_FLAGS_MIRROR,
progress, cancellable, error)) progress, cancellable, error))
return FALSE; 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)); child_repo_path = g_file_get_path (ostree_repo_get_path (child_repo));
} }
if (no_deploy) if (no_deploy)
helper_flags |= FLATPAK_HELPER_DEPLOY_FLAGS_NO_DEPLOY; helper_flags |= FLATPAK_HELPER_DEPLOY_FLAGS_NO_DEPLOY;
if (g_strcmp0 (installed_commit, latest_checksum) != 0) g_debug ("Calling system helper: Deploy");
{ if (!flatpak_system_helper_call_deploy_sync (system_helper,
const char *installation = flatpak_dir_get_id (self); child_repo_path ? child_repo_path : "",
helper_flags, ref, remote_name,
g_debug ("Calling system helper: Deploy"); subpaths,
if (!flatpak_system_helper_call_deploy_sync (system_helper, installation ? installation : "",
child_repo_path ? child_repo_path : "", cancellable,
helper_flags, ref, remote_name, error))
subpaths, return FALSE;
installation ? installation : "",
cancellable,
error))
return FALSE;
}
if (child_repo_path) if (child_repo_path)
(void) glnx_shutil_rm_rf_at (AT_FDCWD, child_repo_path, NULL, NULL); (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 (!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)) progress, cancellable, error))
return FALSE; return FALSE;
} }
if (!no_deploy) 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)) cancellable, error))
return FALSE; return FALSE;
} }

View File

@@ -393,10 +393,19 @@ gboolean flatpak_dir_install_bundle (FlatpakDir *self,
char **out_ref, char **out_ref,
GCancellable *cancellable, GCancellable *cancellable,
GError **error); 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 flatpak_dir_update (FlatpakDir *self,
gboolean no_pull, gboolean no_pull,
gboolean no_deploy, gboolean no_deploy,
gboolean no_static_deltas, gboolean no_static_deltas,
gboolean allow_downgrade,
const char *ref, const char *ref,
const char *remote_name, const char *remote_name,
const char *checksum_or_latest, const char *checksum_or_latest,

View File

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