daemon: Rework API for rollback deployment lookup
Before this commit, in the case where we have 3 deployments, the rollback code would pick the merge/pending deployment. This is understandable since that logic predates us potentially creating 3 deployments. For livefs, I want rollback to actually go to the rollback, not the pending. Add an API to find the pending/rollback, and put it in syscore, since we have other similar functions to this there. (Perhaps in the future we'll figure out a way to dedup the deployment walking/filtering logic a bit). Port the two callers to it. Closes: #767 Approved by: jlebon
This commit is contained in:
parent
3f3090ee7e
commit
b7cf58efc1
@ -384,6 +384,48 @@ rpmostree_syscore_add_deployment (OstreeSysroot *sysroot,
|
||||
return g_steal_pointer (&new_deployments);
|
||||
}
|
||||
|
||||
/* Find the pending and rollback deployments (if any) for @osname. */
|
||||
void
|
||||
rpmostree_syscore_query_deployments (OstreeSysroot *sysroot,
|
||||
const char *osname,
|
||||
OstreeDeployment **out_pending,
|
||||
OstreeDeployment **out_rollback)
|
||||
{
|
||||
g_autoptr(GPtrArray) deployments = ostree_sysroot_get_deployments (sysroot);
|
||||
OstreeDeployment *booted_deployment = ostree_sysroot_get_booted_deployment (sysroot);
|
||||
g_autoptr(OstreeDeployment) ret_pending = NULL;
|
||||
g_autoptr(OstreeDeployment) ret_rollback = NULL;
|
||||
|
||||
gboolean found_booted = FALSE;
|
||||
for (guint i = 0; i < deployments->len; i++)
|
||||
{
|
||||
OstreeDeployment *deployment = deployments->pdata[i];
|
||||
|
||||
/* Is this deployment booted? If so, note we're past the booted */
|
||||
if (booted_deployment != NULL &&
|
||||
ostree_deployment_equal (deployment, booted_deployment))
|
||||
{
|
||||
found_booted = TRUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Ignore deployments not for this osname */
|
||||
if (strcmp (ostree_deployment_get_osname (deployment), osname) != 0)
|
||||
continue;
|
||||
|
||||
if (!found_booted && !ret_pending)
|
||||
ret_pending = g_object_ref (deployment);
|
||||
|
||||
if (found_booted && !ret_rollback)
|
||||
ret_rollback = g_object_ref (deployment);
|
||||
}
|
||||
if (out_pending)
|
||||
*out_pending = g_steal_pointer (&ret_pending);
|
||||
if (out_rollback)
|
||||
*out_rollback = g_steal_pointer (&ret_rollback);
|
||||
}
|
||||
|
||||
|
||||
/* Also a variant of ostree_sysroot_simple_write_deployment(), but here we are
|
||||
* just trying to remove a pending and/or rollback.
|
||||
*/
|
||||
|
@ -42,6 +42,11 @@ GPtrArray *rpmostree_syscore_add_deployment (OstreeSysroot *sysroot,
|
||||
OstreeDeployment *merge_deployment,
|
||||
gboolean pushing_rollback);
|
||||
|
||||
void rpmostree_syscore_query_deployments (OstreeSysroot *sysroot,
|
||||
const char *osname,
|
||||
OstreeDeployment **out_pending,
|
||||
OstreeDeployment **out_rollback);
|
||||
|
||||
GPtrArray *rpmostree_syscore_filter_deployments (OstreeSysroot *sysroot,
|
||||
const char *osname,
|
||||
gboolean remove_pending,
|
||||
|
@ -346,60 +346,3 @@ rpmostreed_commit_generate_cached_details_variant (OstreeDeployment *deployment,
|
||||
g_variant_dict_insert (&dict, "gpg-enabled", "b", gpg_enabled);
|
||||
return g_variant_dict_end (&dict);
|
||||
}
|
||||
|
||||
gint
|
||||
rpmostreed_rollback_deployment_index (const gchar *name,
|
||||
OstreeSysroot *ot_sysroot,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(GPtrArray) deployments = NULL;
|
||||
glnx_unref_object OstreeDeployment *merge_deployment = NULL;
|
||||
|
||||
gint index_to_prepend = -1;
|
||||
gint merge_index = -1;
|
||||
gint previous_index = -1;
|
||||
guint i;
|
||||
|
||||
merge_deployment = ostree_sysroot_get_merge_deployment (ot_sysroot, name);
|
||||
if (merge_deployment == NULL)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"No deployments found for os %s", name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
deployments = ostree_sysroot_get_deployments (ot_sysroot);
|
||||
if (deployments->len < 2)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Found %u deployments, at least 2 required for rollback",
|
||||
deployments->len);
|
||||
goto out;
|
||||
}
|
||||
|
||||
g_assert (merge_deployment != NULL);
|
||||
for (i = 0; i < deployments->len; i++)
|
||||
{
|
||||
if (deployments->pdata[i] == merge_deployment)
|
||||
merge_index = i;
|
||||
|
||||
if (g_strcmp0 (ostree_deployment_get_osname (deployments->pdata[i]), name) == 0 &&
|
||||
deployments->pdata[i] != merge_deployment &&
|
||||
previous_index < 0)
|
||||
{
|
||||
previous_index = i;
|
||||
}
|
||||
}
|
||||
|
||||
g_assert (merge_index < deployments->len);
|
||||
g_assert (deployments->pdata[merge_index] == merge_deployment);
|
||||
|
||||
/* If merge deployment is not booted assume we are using it. */
|
||||
if (merge_index == 0 && previous_index > 0)
|
||||
index_to_prepend = previous_index;
|
||||
else
|
||||
index_to_prepend = merge_index;
|
||||
|
||||
out:
|
||||
return index_to_prepend;
|
||||
}
|
||||
|
@ -40,7 +40,3 @@ GVariant * rpmostreed_commit_generate_cached_details_variant (OstreeDeploym
|
||||
OstreeRepo *repo,
|
||||
const gchar *refspec,
|
||||
GError **error);
|
||||
|
||||
gint rpmostreed_rollback_deployment_index (const gchar *name,
|
||||
OstreeSysroot *ot_sysroot,
|
||||
GError **error);
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "rpmostree-package-variants.h"
|
||||
#include "rpmostreed-errors.h"
|
||||
#include "rpmostree-origin.h"
|
||||
#include "rpmostree-sysroot-core.h"
|
||||
#include "rpmostreed-os.h"
|
||||
#include "rpmostreed-utils.h"
|
||||
#include "rpmostree-util.h"
|
||||
@ -1172,9 +1173,6 @@ rpmostreed_os_load_internals (RpmostreedOS *self, GError **error)
|
||||
GVariant *cached_update = NULL;
|
||||
gboolean has_cached_updates = FALSE;
|
||||
|
||||
gint rollback_index;
|
||||
guint i;
|
||||
|
||||
name = rpmostree_os_get_name (RPMOSTREE_OS (self));
|
||||
g_debug ("loading %s", name);
|
||||
|
||||
@ -1192,7 +1190,7 @@ rpmostreed_os_load_internals (RpmostreedOS *self, GError **error)
|
||||
}
|
||||
|
||||
deployments = ostree_sysroot_get_deployments (ot_sysroot);
|
||||
for (i=0; i<deployments->len; i++)
|
||||
for (guint i=0; i<deployments->len; i++)
|
||||
{
|
||||
if (g_strcmp0 (ostree_deployment_get_osname (deployments->pdata[i]), name) == 0)
|
||||
{
|
||||
@ -1206,17 +1204,21 @@ rpmostreed_os_load_internals (RpmostreedOS *self, GError **error)
|
||||
}
|
||||
}
|
||||
|
||||
if (deployments->len >= 2)
|
||||
if (booted)
|
||||
{
|
||||
rollback_index = rpmostreed_rollback_deployment_index (name, ot_sysroot, NULL);
|
||||
if (rollback_index >= 0)
|
||||
{
|
||||
rollback_variant = rpmostreed_deployment_generate_variant (ot_sysroot,
|
||||
deployments->pdata[rollback_index], booted_id,
|
||||
ot_repo, error);
|
||||
if (!rollback_variant)
|
||||
return FALSE;
|
||||
}
|
||||
g_autoptr(OstreeDeployment) pending = NULL;
|
||||
g_autoptr(OstreeDeployment) rollback = NULL;
|
||||
|
||||
rpmostree_syscore_query_deployments (ot_sysroot, ostree_deployment_get_osname (booted),
|
||||
NULL, &rollback);
|
||||
|
||||
if (rollback)
|
||||
{
|
||||
rollback_variant = rpmostreed_deployment_generate_variant (ot_sysroot, rollback, booted_id,
|
||||
ot_repo, error);
|
||||
if (!rollback_variant)
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
merge_deployment = ostree_sysroot_get_merge_deployment (ot_sysroot, name);
|
||||
|
@ -344,42 +344,38 @@ rollback_transaction_execute (RpmostreedTransaction *transaction,
|
||||
{
|
||||
RollbackTransaction *self;
|
||||
OstreeSysroot *sysroot;
|
||||
OstreeDeployment *deployment;
|
||||
g_autoptr(GPtrArray) old_deployments = NULL;
|
||||
g_autoptr(GPtrArray) new_deployments = NULL;
|
||||
|
||||
gint rollback_index;
|
||||
guint i;
|
||||
g_autoptr(OstreeDeployment) rollback_deployment = NULL;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
self = (RollbackTransaction *) transaction;
|
||||
|
||||
sysroot = rpmostreed_transaction_get_sysroot (transaction);
|
||||
|
||||
rollback_index = rpmostreed_rollback_deployment_index (self->osname, sysroot, error);
|
||||
if (rollback_index < 0)
|
||||
goto out;
|
||||
rpmostree_syscore_query_deployments (sysroot, self->osname, NULL, &rollback_deployment);
|
||||
if (!rollback_deployment)
|
||||
{
|
||||
(void) glnx_throw (error, "No rollback deployment found");
|
||||
goto out;
|
||||
}
|
||||
|
||||
old_deployments = ostree_sysroot_get_deployments (sysroot);
|
||||
new_deployments = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
|
||||
/* build out the reordered array */
|
||||
|
||||
deployment = old_deployments->pdata[rollback_index];
|
||||
g_ptr_array_add (new_deployments, g_object_ref (deployment));
|
||||
/* build out the reordered array; rollback is first now */
|
||||
g_ptr_array_add (new_deployments, g_object_ref (rollback_deployment));
|
||||
|
||||
rpmostreed_transaction_emit_message_printf (transaction,
|
||||
"Moving '%s.%d' to be first deployment",
|
||||
ostree_deployment_get_csum (deployment),
|
||||
ostree_deployment_get_deployserial (deployment));
|
||||
ostree_deployment_get_csum (rollback_deployment),
|
||||
ostree_deployment_get_deployserial (rollback_deployment));
|
||||
|
||||
for (i = 0; i < old_deployments->len; i++)
|
||||
for (guint i = 0; i < old_deployments->len; i++)
|
||||
{
|
||||
if (i == rollback_index)
|
||||
continue;
|
||||
|
||||
deployment = old_deployments->pdata[i];
|
||||
g_ptr_array_add (new_deployments, g_object_ref (deployment));
|
||||
OstreeDeployment *deployment = old_deployments->pdata[i];
|
||||
if (deployment != rollback_deployment)
|
||||
g_ptr_array_add (new_deployments, g_object_ref (deployment));
|
||||
}
|
||||
|
||||
/* if default changed write it */
|
||||
@ -396,7 +392,6 @@ rollback_transaction_execute (RpmostreedTransaction *transaction,
|
||||
rpmostreed_reboot (cancellable, error);
|
||||
|
||||
ret = TRUE;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user