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

deployment: enable adding custom metadata #3212

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions Makefile-ostree.am
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ ostree_SOURCES += \
src/ostree/ot-admin-builtin-set-default.c \
src/ostree/ot-admin-builtin-instutil.c \
src/ostree/ot-admin-builtin-kargs.c \
src/ostree/ot-admin-builtin-metadata.c \
src/ostree/ot-admin-builtin-cleanup.c \
src/ostree/ot-admin-builtin-os-init.c \
src/ostree/ot-admin-builtin-set-origin.c \
Expand Down
60 changes: 60 additions & 0 deletions src/libostree/ostree-deployment.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "config.h"

#include "ostree-deployment-private.h"
#include "ostree-sysroot-private.h"
#include "ostree.h"
#include "otutil.h"

Expand Down Expand Up @@ -476,3 +477,62 @@ ostree_deployment_is_finalization_locked (OstreeDeployment *self)
{
return self->finalization_locked;
}

/**
* ostree_deployment_set_ext_metadata:
* @self: Deployment
* @metadata_key: extended attribute(metadata) name/key to add.
* @metadata_value: extended attribute(metadata) value to add.
* @error: a #GError
*
*/
gboolean
ostree_deployment_set_ext_metadata (OstreeDeployment *self, const char *metadata_key,
const char *metadata_value, GError **error)
{
g_autofree char *backing_relpath = _ostree_sysroot_get_deployment_backing_relpath (self);
if (setxattr (backing_relpath, metadata_key, metadata_value, strlen (metadata_value), 0) < 0)
{
g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
"Failed to set deployment metadata %s on %s: %s", metadata_key, backing_relpath,
g_strerror (errno));
return FALSE;
}
return TRUE;
}

/**
* ostree_deployment_get_ext_metadata:
* @self: Deployment
* @metadata_key: (nullable): key of extended attribute
* @error: a #GError
* Returns: The value of a extended attribute(metadata) checksum given the key.
*/
const char *
ostree_deployment_get_ext_metadata (OstreeDeployment *self, const char *metadata_key,
GError **error)
{
g_autofree char *backing_relpath = _ostree_sysroot_get_deployment_backing_relpath (self);
g_autofree char *metadata_value = NULL;
g_autofree int len = getxattr (backing_relpath, metadata_key, NULL, 0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the general case ostree wants to support using fd-relative paths, so we need to open a fd for the dir (relative to self->sysroot_fd), then use fgetxattr().

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also

g_autofree int len

Definitely don't want to call free() on an integer. Also, getxattr returns a ssize_t, not an int (they're different sizes).

if (len < 0)
{
if (errno == ENODATA)
return NULL;
g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
"Failed to get deployment metadata %s on %s: %s", metadata_key, backing_relpath,
g_strerror (errno));
return NULL;
}
metadata_value = g_malloc (len + 1);
len = getxattr (backing_relpath, metadata_key, metadata_value, len);
if (len < 0)
{
g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
"Failed to get deployment metadata %s on %s: %s", metadata_key, backing_relpath,
g_strerror (errno));
return NULL;
}
metadata_value[len] = '\0';
return metadata_value;
}
8 changes: 8 additions & 0 deletions src/libostree/ostree-deployment.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,12 @@ const char *ostree_deployment_unlocked_state_to_string (OstreeDeploymentUnlocked
_OSTREE_PUBLIC
OstreeDeploymentUnlockedState ostree_deployment_get_unlocked (OstreeDeployment *self);

_OSTREE_PUBLIC
gboolean ostree_deployment_set_ext_metadata (OstreeDeployment *self, const char *metadata_key,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New API needs to be added to libostree-devel.sym; there's some ceremony to do that. See the comments around that and git log.

const char *metadata_value, GError **error);

_OSTREE_PUBLIC
const char *ostree_deployment_get_ext_metadata (OstreeDeployment *self, const char *metadata_key,
GError **error);

G_END_DECLS
77 changes: 77 additions & 0 deletions src/ostree/ot-admin-builtin-metadata.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright (C) 2015 Colin Walters <[email protected]>
*
* SPDX-License-Identifier: LGPL-2.0+
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <https://www.gnu.org/licenses/>.
*/

#include "config.h"

#include "ot-admin-builtins.h"
#include "ot-admin-functions.h"
#include "otutil.h"

static char **opt_set;
static char **opt_get;

static GOptionEntry options[]
= { { "set", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_set,
"Set deployment metadata, like DATE=030424; this overrides any metadata with the "
"same name",
"KEY=VALUE" },
{ "get", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_get,
"Get the value of a deployment metadata.", "KEY" },
{ NULL } };

gboolean
ot_admin_builtin_metadata (int argc, char **argv, OstreeCommandInvocation *invocation,
GCancellable *cancellable, GError **error)
{
gboolean ret = FALSE;
g_autoptr (GPtrArray) deployments = NULL;
OstreeDeployment *first_deployment = NULL;
g_autoptr (GOptionContext) context = NULL;
g_autoptr (OstreeSysroot) sysroot = NULL;

if (!ostree_admin_option_context_parse (context, options, &argc, &argv,
OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER, invocation, &sysroot,
cancellable, error))
goto out;

if (deployments->len == 0)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unable to find a deployment in sysroot");
goto out;
}

first_deployment = deployments->pdata[0];

if (opt_set)
{
char *key = strtok (*opt_set, "=");
char *value = strtok (NULL, "=");
// ^^ This needs error checking and probably is wrong... but builds!
ostree_deployment_set_ext_metadata (first_deployment, key, value, error);
}

if (opt_get)
{
ostree_deployment_get_ext_metadata (first_deployment, *opt_get, error);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to handle errors here

}

ret = TRUE;
out:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In brand new code we can avoid use of goto and just use return FALSE above

return ret;
}
1 change: 1 addition & 0 deletions src/ostree/ot-admin-builtins.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ BUILTINPROTO (kargs);
BUILTINPROTO (post_copy);
BUILTINPROTO (lock_finalization);
BUILTINPROTO (state_overlay);
BUILTINPROTO (metadata);

#undef BUILTINPROTO

Expand Down
2 changes: 2 additions & 0 deletions src/ostree/ot-builtin-admin.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ static OstreeCommand admin_subcommands[] = {
{ "upgrade", OSTREE_BUILTIN_FLAG_NO_REPO, ot_admin_builtin_upgrade,
"Construct new tree from current origin and deploy it, if it changed" },
{ "kargs", OSTREE_BUILTIN_FLAG_NO_REPO, ot_admin_builtin_kargs, "Change kernel arguments" },
{ "deployment-metadata", OSTREE_BUILTIN_FLAG_NO_REPO, ot_admin_builtin_metadata,
"Set extended metadata for current the deployment" },
{ NULL, 0, NULL, NULL }
};

Expand Down
Loading