mirror of
https://github.com/ostreedev/ostree.git
synced 2024-12-22 17:35:55 +03:00
Merge pull request #2296 from cgwalters/commit-os
Add an API+CLI to inject metadata for bootable OSTree commits
This commit is contained in:
commit
d522f261db
@ -28,6 +28,7 @@ libostree_public_headers = \
|
||||
src/libostree/ostree-dummy-enumtypes.h \
|
||||
src/libostree/ostree-mutable-tree.h \
|
||||
src/libostree/ostree-repo.h \
|
||||
src/libostree/ostree-repo-os.h \
|
||||
src/libostree/ostree-types.h \
|
||||
src/libostree/ostree-repo-file.h \
|
||||
src/libostree/ostree-diff.h \
|
||||
|
@ -92,6 +92,7 @@ libostree_1_la_SOURCES = \
|
||||
src/libostree/ostree-ref.c \
|
||||
src/libostree/ostree-remote.c \
|
||||
src/libostree/ostree-remote-private.h \
|
||||
src/libostree/ostree-repo-os.c \
|
||||
src/libostree/ostree-repo.c \
|
||||
src/libostree/ostree-repo-checkout.c \
|
||||
src/libostree/ostree-repo-commit.c \
|
||||
@ -186,10 +187,10 @@ endif # USE_GPGME
|
||||
|
||||
symbol_files = $(top_srcdir)/src/libostree/libostree-released.sym
|
||||
|
||||
## Uncomment this include when adding new development symbols.
|
||||
#if BUILDOPT_IS_DEVEL_BUILD
|
||||
#symbol_files += $(top_srcdir)/src/libostree/libostree-devel.sym
|
||||
#endif
|
||||
# Uncomment this include when adding new development symbols.
|
||||
if BUILDOPT_IS_DEVEL_BUILD
|
||||
symbol_files += $(top_srcdir)/src/libostree/libostree-devel.sym
|
||||
endif
|
||||
|
||||
# http://blog.jgc.org/2007/06/escaping-comma-and-space-in-gnu-make.html
|
||||
wl_versionscript_arg = -Wl,--version-script=
|
||||
|
@ -152,6 +152,7 @@ ostree_validate_structureof_dirtree
|
||||
ostree_validate_structureof_dirmeta
|
||||
ostree_commit_get_parent
|
||||
ostree_commit_get_timestamp
|
||||
ostree_commit_metadata_for_bootable
|
||||
ostree_commit_get_content_checksum
|
||||
ostree_commit_get_object_sizes
|
||||
OstreeCommitSizesEntry
|
||||
|
@ -321,6 +321,7 @@ _ostree_commit() {
|
||||
--canonical-permissions
|
||||
--editor -e
|
||||
--generate-sizes
|
||||
--bootable
|
||||
--link-checkout-speedup
|
||||
--no-xattrs
|
||||
--orphan
|
||||
|
@ -186,6 +186,13 @@ Boston, MA 02111-1307, USA.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--bootable</option></term>
|
||||
<listitem><para>
|
||||
Inject standard metadata for a bootable Linux filesystem tree.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--link-checkout-speedup</option></term>
|
||||
|
||||
|
@ -22,6 +22,11 @@
|
||||
- uncomment the include in Makefile-libostree.am
|
||||
*/
|
||||
|
||||
LIBOSTREE_2021.1 {
|
||||
global:
|
||||
ostree_commit_metadata_for_bootable;
|
||||
} LIBOSTREE_2020.8;
|
||||
|
||||
/* Stub section for the stable release *after* this development one; don't
|
||||
* edit this other than to update the year. This is just a copy/paste
|
||||
* source. Replace $LASTSTABLE with the last stable version, and $NEWVERSION
|
||||
|
83
src/libostree/ostree-repo-os.c
Normal file
83
src/libostree/ostree-repo-os.c
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <gio/gfiledescriptorbased.h>
|
||||
#include <gio/gunixinputstream.h>
|
||||
#include "libglnx.h"
|
||||
#include "ostree.h"
|
||||
#include "ostree-core-private.h"
|
||||
#include "ostree-repo-os.h"
|
||||
#include "otutil.h"
|
||||
|
||||
/**
|
||||
* ostree_commit_metadata_for_bootable:
|
||||
* @root: Root filesystem to be committed
|
||||
* @dict: Dictionary to update
|
||||
*
|
||||
* Update provided @dict with standard metadata for bootable OSTree commits.
|
||||
* Since: 2021.1
|
||||
*/
|
||||
_OSTREE_PUBLIC
|
||||
gboolean
|
||||
ostree_commit_metadata_for_bootable (GFile *root, GVariantDict *dict, GCancellable *cancellable, GError **error)
|
||||
{
|
||||
g_autoptr(GFile) modules = g_file_resolve_relative_path (root, "usr/lib/modules");
|
||||
g_autoptr(GFileEnumerator) dir_enum
|
||||
= g_file_enumerate_children (modules, OSTREE_GIO_FAST_QUERYINFO,
|
||||
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
||||
cancellable, error);
|
||||
if (!dir_enum)
|
||||
return glnx_prefix_error (error, "Opening usr/lib/modules");
|
||||
|
||||
g_autofree char *linux_release = NULL;
|
||||
while (TRUE)
|
||||
{
|
||||
GFileInfo *child_info;
|
||||
GFile *child_path;
|
||||
if (!g_file_enumerator_iterate (dir_enum, &child_info, &child_path,
|
||||
cancellable, error))
|
||||
return FALSE;
|
||||
if (child_info == NULL)
|
||||
break;
|
||||
if (g_file_info_get_file_type (child_info) != G_FILE_TYPE_DIRECTORY)
|
||||
continue;
|
||||
|
||||
g_autoptr(GFile) kernel_path = g_file_resolve_relative_path (child_path, "vmlinuz");
|
||||
if (!g_file_query_exists (kernel_path, NULL))
|
||||
continue;
|
||||
|
||||
if (linux_release != NULL)
|
||||
return glnx_throw (error, "Multiple kernels found in /usr/lib/modules");
|
||||
|
||||
linux_release = g_strdup (g_file_info_get_name (child_info));
|
||||
}
|
||||
|
||||
if (linux_release)
|
||||
{
|
||||
g_variant_dict_insert (dict, OSTREE_METADATA_KEY_BOOTABLE, "b", TRUE);
|
||||
g_variant_dict_insert (dict, OSTREE_METADATA_KEY_LINUX, "s", linux_release);
|
||||
return TRUE;
|
||||
}
|
||||
return glnx_throw (error, "No kernel found in /usr/lib/modules");
|
||||
}
|
47
src/libostree/ostree-repo-os.h
Normal file
47
src/libostree/ostree-repo-os.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <gio/gio.h>
|
||||
#include <ostree-types.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* OSTREE_METADATA_KEY_BOOTABLE:
|
||||
*
|
||||
* GVariant type `b`: Set if this commit is intended to be bootable
|
||||
* Since: 2021.1
|
||||
*/
|
||||
#define OSTREE_METADATA_KEY_BOOTABLE "ostree.bootable"
|
||||
/**
|
||||
* OSTREE_METADATA_KEY_LINUX:
|
||||
*
|
||||
* GVariant type `s`: Contains the Linux kernel release (i.e. `uname -r`)
|
||||
* Since: 2021.1
|
||||
*/
|
||||
#define OSTREE_METADATA_KEY_LINUX "ostree.linux"
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean
|
||||
ostree_commit_metadata_for_bootable (GFile *root, GVariantDict *dict, GCancellable *cancellable, GError **error);
|
||||
|
||||
G_END_DECLS
|
@ -24,6 +24,7 @@
|
||||
#include <ostree-async-progress.h>
|
||||
#include <ostree-core.h>
|
||||
#include <ostree-repo.h>
|
||||
#include <ostree-repo-os.h>
|
||||
#include <ostree-mutable-tree.h>
|
||||
#include <ostree-remote.h>
|
||||
#include <ostree-repo-file.h>
|
||||
|
@ -35,6 +35,7 @@
|
||||
|
||||
static char *opt_subject;
|
||||
static char *opt_body;
|
||||
static char *opt_bootable;
|
||||
static char *opt_body_file;
|
||||
static gboolean opt_editor;
|
||||
static char *opt_parent;
|
||||
@ -112,6 +113,7 @@ static GOptionEntry options[] = {
|
||||
{ "owner-uid", 0, 0, G_OPTION_ARG_INT, &opt_owner_uid, "Set file ownership user id", "UID" },
|
||||
{ "owner-gid", 0, 0, G_OPTION_ARG_INT, &opt_owner_gid, "Set file ownership group id", "GID" },
|
||||
{ "canonical-permissions", 0, 0, G_OPTION_ARG_NONE, &opt_canonical_permissions, "Canonicalize permissions in the same way bare-user does for hardlinked files", NULL },
|
||||
{ "bootable", 0, 0, G_OPTION_ARG_NONE, &opt_bootable, "Flag this commit as a bootable OSTree (e.g. contains a Linux kernel)", NULL },
|
||||
{ "mode-ro-executables", 0, 0, G_OPTION_ARG_NONE, &opt_ro_executables, "Ensure executable files are not writable", NULL },
|
||||
{ "no-xattrs", 0, 0, G_OPTION_ARG_NONE, &opt_no_xattrs, "Do not import extended attributes", NULL },
|
||||
{ "selinux-policy", 0, 0, G_OPTION_ARG_FILENAME, &opt_selinux_policy, "Set SELinux labels based on policy in root filesystem PATH (may be /)", "PATH" },
|
||||
@ -501,7 +503,7 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (opt_metadata_strings || opt_metadata_variants || opt_metadata_keep)
|
||||
if (opt_metadata_strings || opt_metadata_variants || opt_metadata_keep || opt_bootable)
|
||||
{
|
||||
g_autoptr(GVariantBuilder) builder =
|
||||
g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
|
||||
@ -841,6 +843,17 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio
|
||||
fill_bindings (repo, old_metadata, &metadata);
|
||||
}
|
||||
|
||||
if (opt_bootable)
|
||||
{
|
||||
g_autoptr(GVariant) old_metadata = g_steal_pointer (&metadata);
|
||||
g_auto(GVariantDict) bootmeta;
|
||||
g_variant_dict_init (&bootmeta, old_metadata);
|
||||
if (!ostree_commit_metadata_for_bootable (root, &bootmeta, cancellable, error))
|
||||
goto out;
|
||||
|
||||
metadata = g_variant_ref_sink (g_variant_dict_end (&bootmeta));
|
||||
}
|
||||
|
||||
if (!opt_timestamp)
|
||||
{
|
||||
if (!ostree_repo_write_commit (repo, parent, opt_subject, commit_body, metadata,
|
||||
|
@ -65,6 +65,12 @@ assert_not_file_has_content status.txt "pending"
|
||||
assert_not_file_has_content status.txt "rollback"
|
||||
validate_bootloader
|
||||
|
||||
# Test the bootable and linux keys
|
||||
${CMD_PREFIX} ostree --repo=sysroot/ostree/repo --print-metadata-key=ostree.linux show testos:testos/buildmaster/x86_64-runtime >out.txt
|
||||
assert_file_has_content_literal out.txt 3.6.0
|
||||
${CMD_PREFIX} ostree --repo=sysroot/ostree/repo --print-metadata-key=ostree.bootable show testos:testos/buildmaster/x86_64-runtime >out.txt
|
||||
assert_file_has_content_literal out.txt true
|
||||
|
||||
echo "ok deploy command"
|
||||
|
||||
${CMD_PREFIX} ostree admin --print-current-dir > curdir
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo "1..$((86 + ${extra_basic_tests:-0}))"
|
||||
echo "1..$((87 + ${extra_basic_tests:-0}))"
|
||||
|
||||
CHECKOUT_U_ARG=""
|
||||
CHECKOUT_H_ARGS="-H"
|
||||
@ -226,6 +226,13 @@ $OSTREE commit ${COMMIT_ARGS} -b test2-no-parent -s '' --parent=none $test_tmpdi
|
||||
assert_streq $($OSTREE log test2-no-parent |grep '^commit' | wc -l) "1"
|
||||
echo "ok commit no parent"
|
||||
|
||||
cd ${test_tmpdir}
|
||||
if $OSTREE commit ${COMMIT_ARGS} -b test-bootable --bootable $test_tmpdir/checkout-test2-4 2>err.txt; then
|
||||
fatal "committed non-bootable tree"
|
||||
fi
|
||||
assert_file_has_content err.txt "error: .*No such file or directory"
|
||||
echo "ok commit fails bootable if no kernel"
|
||||
|
||||
cd ${test_tmpdir}
|
||||
# Do the --bind-ref=<the other test branch>, so we store both branches sorted
|
||||
# in metadata and thus the checksums remain the same.
|
||||
|
@ -415,11 +415,14 @@ setup_os_repository () {
|
||||
echo "an hmac file" > ${hmac_path}
|
||||
bootcsum=$(cat ${kernel_path} ${initramfs_path} | sha256sum | cut -f 1 -d ' ')
|
||||
export bootcsum
|
||||
bootable_flag=""
|
||||
# Add the checksum for legacy dirs (/boot, /usr/lib/ostree-boot), but not
|
||||
# /usr/lib/modules.
|
||||
if [[ $bootdir != usr/lib/modules/* ]]; then
|
||||
mv ${kernel_path}{,-${bootcsum}}
|
||||
mv ${initramfs_path}{,-${bootcsum}}
|
||||
else
|
||||
bootable_flag="--bootable"
|
||||
fi
|
||||
|
||||
echo "an executable" > usr/bin/sh
|
||||
@ -439,12 +442,12 @@ EOF
|
||||
mkdir -p usr/etc/testdirectory
|
||||
echo "a default daemon file" > usr/etc/testdirectory/test
|
||||
|
||||
${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo commit --add-metadata-string version=1.0.9 -b testos/buildmaster/x86_64-runtime -s "Build"
|
||||
${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo commit ${bootable_flag} --add-metadata-string version=1.0.9 -b testos/buildmaster/x86_64-runtime -s "Build"
|
||||
|
||||
# Ensure these commits have distinct second timestamps
|
||||
sleep 2
|
||||
echo "a new executable" > usr/bin/sh
|
||||
${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo commit --add-metadata-string version=1.0.10 -b testos/buildmaster/x86_64-runtime -s "Build"
|
||||
${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo commit ${bootable_flag} --add-metadata-string version=1.0.10 -b testos/buildmaster/x86_64-runtime -s "Build"
|
||||
|
||||
cd ${test_tmpdir}
|
||||
rm -rf osdata-devel
|
||||
@ -453,7 +456,7 @@ EOF
|
||||
cd osdata-devel
|
||||
mkdir -p usr/include
|
||||
echo "a development header" > usr/include/foo.h
|
||||
${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo commit --add-metadata-string version=1.0.9 -b testos/buildmaster/x86_64-devel -s "Build"
|
||||
${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo commit ${bootable_flag} --add-metadata-string version=1.0.9 -b testos/buildmaster/x86_64-devel -s "Build"
|
||||
|
||||
${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo fsck -q
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user