New upstream version 2022.6
This commit is contained in:
commit
46bfe6e238
79 files changed
+2679
-2141
No files matched your search
@@ -0,0 +1,35 @@
|
||||
# Copyright (C) 2018 Red Hat, Inc.
|
||||
# Copyright (C) 2022 Endless OS Foundation LLC
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
# See https://github.com/ostreedev/ostree/pull/2543 for background.
|
||||
[Unit]
|
||||
Description=Hold /boot Open for OSTree Finalize Staged Deployment
|
||||
Documentation=man:ostree(1)
|
||||
ConditionPathExists=/run/ostree-booted
|
||||
DefaultDependencies=no
|
||||
|
||||
RequiresMountsFor=/sysroot /boot
|
||||
After=local-fs.target
|
||||
Before=basic.target final.target
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
|
||||
# This is explicitly run in the root namespace to ensure an automounted
|
||||
# /boot doesn't time out since autofs doesn't handle mount namespaces.
|
||||
#
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=2056090
|
||||
ExecStart=+/usr/bin/ostree admin finalize-staged --hold
|
||||
@@ -29,6 +29,11 @@ Before=basic.target final.target
|
||||
After=systemd-journal-flush.service
|
||||
Conflicts=final.target
|
||||
|
||||
# Start the hold unit and ensure it stays active throughout this
|
||||
# service.
|
||||
Wants=ostree-finalize-staged-hold.service
|
||||
After=ostree-finalize-staged-hold.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
|
||||
@@ -73,7 +73,7 @@ ostree_bootconfig_parser_parse_at (OstreeBootconfigParser *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (!self->parsed, FALSE);
|
||||
g_assert (!self->parsed);
|
||||
|
||||
g_autofree char *contents = glnx_file_get_contents_utf8_at (dfd, path, NULL, cancellable, error);
|
||||
if (!contents)
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "ostree-sysroot-private.h"
|
||||
#include "ostree-bootloader-zipl.h"
|
||||
#include "ostree-deployment-private.h"
|
||||
#include "ostree-libarchive-private.h"
|
||||
#include "otutil.h"
|
||||
#include <sys/mount.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -34,7 +35,10 @@
|
||||
#define SECURE_EXECUTION_LUKS_ROOT_KEY "/etc/luks/root"
|
||||
#define SECURE_EXECUTION_LUKS_BOOT_KEY "/etc/luks/boot"
|
||||
#define SECURE_EXECUTION_LUKS_CONFIG "/etc/crypttab"
|
||||
#define SECURE_EXECUTION_RAMDISK_TOOL PKGLIBEXECDIR "/s390x-se-luks-gencpio"
|
||||
|
||||
#if !(defined HAVE_LIBARCHIVE) && defined(__s390x__)
|
||||
#error libarchive is required for s390x
|
||||
#endif
|
||||
|
||||
/* This is specific to zipl today, but in the future we could also
|
||||
* use it for the grub2-mkconfig case.
|
||||
@@ -195,31 +199,86 @@ static gboolean
|
||||
_ostree_secure_execution_luks_key_exists (void)
|
||||
{
|
||||
return (access(SECURE_EXECUTION_LUKS_CONFIG, F_OK) == 0 &&
|
||||
(access(SECURE_EXECUTION_LUKS_ROOT_KEY, F_OK) == 0 || access(SECURE_EXECUTION_LUKS_BOOT_KEY, F_OK) == 0));
|
||||
access(SECURE_EXECUTION_LUKS_ROOT_KEY, F_OK) == 0 &&
|
||||
access(SECURE_EXECUTION_LUKS_BOOT_KEY, F_OK) == 0);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_ostree_secure_execution_enable_luks(const gchar *oldramfs,
|
||||
const gchar *newramfs,
|
||||
GError **error)
|
||||
_ostree_secure_execution_append_luks_keys (int initrd_fd,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
const char *const argv[] = {SECURE_EXECUTION_RAMDISK_TOOL, oldramfs, newramfs, NULL};
|
||||
g_autofree gchar *out = NULL;
|
||||
g_autofree gchar *err = NULL;
|
||||
int status = 0;
|
||||
if (!g_spawn_sync (NULL, (char**)argv, NULL, G_SPAWN_SEARCH_PATH,
|
||||
NULL, NULL, &out, &err, &status, error))
|
||||
return glnx_prefix_error(error, "s390x SE: spawning %s", SECURE_EXECUTION_RAMDISK_TOOL);
|
||||
#ifdef HAVE_LIBARCHIVE
|
||||
// appending cpio gzip archive with LUKS keys
|
||||
g_autoptr(OtAutoArchiveWrite) a = archive_write_new ();
|
||||
g_assert (a != NULL);
|
||||
|
||||
if (!g_spawn_check_exit_status (status, error))
|
||||
if (archive_write_set_format_cpio_newc (a) != 0 ||
|
||||
archive_write_add_filter_gzip (a) != 0 ||
|
||||
archive_write_open_fd(a, initrd_fd) != 0)
|
||||
return glnx_prefix_error (error, "s390x SE: initing cpio: %s", archive_error_string (a));
|
||||
|
||||
const char *files[] = {"/etc", "/etc/luks", SECURE_EXECUTION_LUKS_CONFIG, SECURE_EXECUTION_LUKS_BOOT_KEY, SECURE_EXECUTION_LUKS_ROOT_KEY};
|
||||
for (uint i = 0; i != G_N_ELEMENTS (files); ++i)
|
||||
{
|
||||
g_printerr("s390x SE: `%s` stdout: %s\n", SECURE_EXECUTION_RAMDISK_TOOL, out);
|
||||
g_printerr("s390x SE: `%s` stderr: %s\n", SECURE_EXECUTION_RAMDISK_TOOL, err);
|
||||
return glnx_prefix_error(error, "s390x SE: `%s` failed", SECURE_EXECUTION_RAMDISK_TOOL);
|
||||
}
|
||||
const char *path = files[i];
|
||||
struct stat st;
|
||||
if (stat(path, &st) != 0)
|
||||
glnx_throw_errno_prefix (error, "s390x SE: stat(%s) failed", path);
|
||||
|
||||
ot_journal_print(LOG_INFO, "s390x SE: luks key added to initrd");
|
||||
g_autoptr(OtArchiveEntry) ae = archive_entry_new ();
|
||||
g_assert (ae != NULL);
|
||||
|
||||
archive_entry_copy_stat (ae, &st);
|
||||
archive_entry_set_pathname (ae, path);
|
||||
if (archive_write_header (a, ae) != 0)
|
||||
glnx_prefix_error (error, "s390x SE: writing cpio header: %s", archive_error_string (a));
|
||||
|
||||
if (S_ISREG (st.st_mode))
|
||||
{
|
||||
ot_journal_print(LOG_INFO, "s390x SE: appending %s to initrd", path);
|
||||
glnx_autofd int fd = -1;
|
||||
if (!glnx_openat_rdonly (AT_FDCWD, path, TRUE, &fd, error))
|
||||
return glnx_prefix_error (error, "s390x SE: opening %s", path);
|
||||
g_autoptr(GBytes) data = glnx_fd_readall_bytes (fd, cancellable, error);
|
||||
if (!data)
|
||||
return glnx_prefix_error (error, "s390x SE: reading %s", path);
|
||||
|
||||
gsize size = 0;
|
||||
const char *ptr = (const char *) g_bytes_get_data (data, &size);
|
||||
ssize_t written = archive_write_data (a, ptr, size);
|
||||
if (written == -1)
|
||||
return glnx_prefix_error (error, "s390x SE: writing cpio entry: %s", archive_error_string (a));
|
||||
if (written != size)
|
||||
return glnx_prefix_error (error, "s390x SE: writing cpio entry %zd != %zu", written, size);
|
||||
}
|
||||
}
|
||||
ot_journal_print(LOG_INFO, "s390x SE: luks keys added to initrd");
|
||||
return TRUE;
|
||||
#else
|
||||
return glnx_throw (error, "'libarchive' is required for s390x");
|
||||
#endif
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_ostree_secure_execution_generate_initrd (const gchar *initrd,
|
||||
GLnxTmpfile *out_initrd,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
if (!_ostree_secure_execution_luks_key_exists ())
|
||||
return glnx_throw (error, "s390x SE: missing luks keys and config");
|
||||
|
||||
if (!glnx_open_anonymous_tmpfile (O_RDWR | O_CLOEXEC, out_initrd, error))
|
||||
return glnx_prefix_error (error, "s390x SE: opening new ramdisk");
|
||||
{
|
||||
glnx_autofd int fd = -1;
|
||||
glnx_openat_rdonly (AT_FDCWD, initrd, TRUE, &fd, error);
|
||||
if (glnx_regfile_copy_bytes (fd, out_initrd->fd, (off_t) -1) < 0)
|
||||
return glnx_throw_errno_prefix (error, "s390x SE: copying ramdisk");
|
||||
}
|
||||
|
||||
return _ostree_secure_execution_append_luks_keys (out_initrd->fd, cancellable, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -227,6 +286,7 @@ _ostree_secure_execution_generate_sdboot (gchar *vmlinuz,
|
||||
gchar *initramfs,
|
||||
gchar *options,
|
||||
GPtrArray *keys,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_assert (vmlinuz && initramfs && options && keys && keys->len);
|
||||
@@ -234,34 +294,28 @@ _ostree_secure_execution_generate_sdboot (gchar *vmlinuz,
|
||||
ot_journal_print(LOG_INFO, "s390x SE: initrd: %s", initramfs);
|
||||
ot_journal_print(LOG_INFO, "s390x SE: kargs: %s", options);
|
||||
|
||||
pid_t self = getpid();
|
||||
pid_t self = getpid ();
|
||||
|
||||
// Store kernel options to temp file, so `genprotimg` can later embed it
|
||||
g_auto(GLnxTmpfile) cmdline = { 0, };
|
||||
if (!glnx_open_anonymous_tmpfile (O_RDWR | O_CLOEXEC, &cmdline, error))
|
||||
return glnx_prefix_error(error, "s390x SE: opening cmdline file");
|
||||
return glnx_prefix_error (error, "s390x SE: opening cmdline file");
|
||||
if (glnx_loop_write (cmdline.fd, options, strlen (options)) < 0)
|
||||
return glnx_throw_errno_prefix (error, "s390x SE: writting cmdline file");
|
||||
return glnx_throw_errno_prefix (error, "s390x SE: writing cmdline file");
|
||||
g_autofree gchar *cmdline_filename = g_strdup_printf ("/proc/%d/fd/%d", self, cmdline.fd);
|
||||
|
||||
// Copy initramfs to temp file and embed LUKS key and config into it
|
||||
// Copy initramfs to temp file and embed LUKS keys & config into it
|
||||
g_auto(GLnxTmpfile) ramdisk = { 0, };
|
||||
g_autofree gchar *ramdisk_filename = NULL;
|
||||
if (_ostree_secure_execution_luks_key_exists ())
|
||||
{
|
||||
if (!glnx_open_anonymous_tmpfile (O_RDWR | O_CLOEXEC, &ramdisk, error))
|
||||
return glnx_prefix_error(error, "s390x SE: creating new ramdisk");
|
||||
ramdisk_filename = g_strdup_printf ("/proc/%d/fd/%d", self, ramdisk.fd);
|
||||
if (!_ostree_secure_execution_enable_luks (initramfs, ramdisk_filename, error))
|
||||
return FALSE;
|
||||
}
|
||||
if (!_ostree_secure_execution_generate_initrd (initramfs, &ramdisk, cancellable, error))
|
||||
return FALSE;
|
||||
g_autofree gchar *ramdisk_filename = g_strdup_printf ("/proc/%d/fd/%d", self, ramdisk.fd);
|
||||
|
||||
g_autoptr(GPtrArray) argv = g_ptr_array_new ();
|
||||
g_ptr_array_add (argv, "genprotimg");
|
||||
g_ptr_array_add (argv, "-i");
|
||||
g_ptr_array_add (argv, vmlinuz);
|
||||
g_ptr_array_add (argv, "-r");
|
||||
g_ptr_array_add (argv, (ramdisk_filename == NULL) ? initramfs: ramdisk_filename);
|
||||
g_ptr_array_add (argv, ramdisk_filename);
|
||||
g_ptr_array_add (argv, "-p");
|
||||
g_ptr_array_add (argv, cmdline_filename);
|
||||
for (guint i = 0; i < keys->len; ++i)
|
||||
@@ -300,7 +354,7 @@ _ostree_secure_execution_call_zipl (GError **error)
|
||||
if (!g_spawn_check_exit_status (status, error))
|
||||
return glnx_prefix_error(error, "s390x SE: `zipl` failed");
|
||||
|
||||
ot_journal_print(LOG_INFO, "s390x SE: `sd-boot` zipled");
|
||||
ot_journal_print(LOG_INFO, "s390x SE: `sdboot` zipled");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -318,7 +372,7 @@ _ostree_secure_execution_enable (OstreeBootloaderZipl *self,
|
||||
gboolean rc =
|
||||
_ostree_secure_execution_mount (error) &&
|
||||
_ostree_secure_execution_get_bls_config (self, bootversion, &vmlinuz, &initramfs, &options, cancellable, error) &&
|
||||
_ostree_secure_execution_generate_sdboot (vmlinuz, initramfs, options, keys, error) &&
|
||||
_ostree_secure_execution_generate_sdboot (vmlinuz, initramfs, options, keys, cancellable, error) &&
|
||||
_ostree_secure_execution_call_zipl (error) &&
|
||||
_ostree_secure_execution_umount (error);
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ _ostree_bootloader_query (OstreeBootloader *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (OSTREE_IS_BOOTLOADER (self), FALSE);
|
||||
g_assert (OSTREE_IS_BOOTLOADER (self));
|
||||
|
||||
return OSTREE_BOOTLOADER_GET_IFACE (self)->query (self, out_is_active, cancellable, error);
|
||||
}
|
||||
@@ -44,7 +44,7 @@ _ostree_bootloader_query (OstreeBootloader *self,
|
||||
const char *
|
||||
_ostree_bootloader_get_name (OstreeBootloader *self)
|
||||
{
|
||||
g_return_val_if_fail (OSTREE_IS_BOOTLOADER (self), NULL);
|
||||
g_assert (OSTREE_IS_BOOTLOADER (self));
|
||||
|
||||
return OSTREE_BOOTLOADER_GET_IFACE (self)->get_name (self);
|
||||
}
|
||||
@@ -56,7 +56,7 @@ _ostree_bootloader_write_config (OstreeBootloader *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (OSTREE_IS_BOOTLOADER (self), FALSE);
|
||||
g_assert (OSTREE_IS_BOOTLOADER (self));
|
||||
|
||||
return OSTREE_BOOTLOADER_GET_IFACE (self)->write_config (self, bootversion,
|
||||
new_deployments,
|
||||
@@ -69,7 +69,7 @@ _ostree_bootloader_post_bls_sync (OstreeBootloader *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (OSTREE_IS_BOOTLOADER (self), FALSE);
|
||||
g_assert (OSTREE_IS_BOOTLOADER (self));
|
||||
|
||||
if (OSTREE_BOOTLOADER_GET_IFACE (self)->post_bls_sync)
|
||||
return OSTREE_BOOTLOADER_GET_IFACE (self)->post_bls_sync (self, bootversion, cancellable, error);
|
||||
@@ -80,7 +80,7 @@ _ostree_bootloader_post_bls_sync (OstreeBootloader *self,
|
||||
gboolean
|
||||
_ostree_bootloader_is_atomic (OstreeBootloader *self)
|
||||
{
|
||||
g_return_val_if_fail (OSTREE_IS_BOOTLOADER (self), FALSE);
|
||||
g_assert (OSTREE_IS_BOOTLOADER (self));
|
||||
|
||||
if (OSTREE_BOOTLOADER_GET_IFACE (self)->is_atomic)
|
||||
return OSTREE_BOOTLOADER_GET_IFACE (self)->is_atomic (self);
|
||||
|
||||
@@ -882,8 +882,10 @@ initiate_next_curl_request (FetcherRequest *req,
|
||||
if (!(self->config_flags & OSTREE_FETCHER_FLAGS_DISABLE_HTTP2))
|
||||
{
|
||||
#if CURL_AT_LEAST_VERSION(7, 51, 0)
|
||||
rc = curl_easy_setopt (req->easy, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
|
||||
g_assert_cmpint (rc, ==, CURLM_OK);
|
||||
if ((curl_version_info (CURLVERSION_NOW))->features & CURL_VERSION_HTTP2) {
|
||||
rc = curl_easy_setopt (req->easy, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
|
||||
g_assert_cmpint (rc, ==, CURLM_OK);
|
||||
}
|
||||
#endif
|
||||
/* https://github.com/curl/curl/blob/curl-7_53_0/docs/examples/http2-download.c */
|
||||
#if (CURLPIPE_MULTIPLEX > 0)
|
||||
|
||||
@@ -38,6 +38,8 @@ G_BEGIN_DECLS
|
||||
#ifdef HAVE_LIBARCHIVE
|
||||
typedef struct archive OtAutoArchiveWrite;
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(OtAutoArchiveWrite, archive_write_free)
|
||||
typedef struct archive_entry OtArchiveEntry;
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(OtArchiveEntry, archive_entry_free)
|
||||
typedef struct archive OtAutoArchiveRead;
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(OtAutoArchiveRead, archive_read_free)
|
||||
|
||||
|
||||
@@ -24,10 +24,12 @@
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
// This should be the only file including linux/fs.h; see
|
||||
// https://sourceware.org/glibc/wiki/Release/2.36#Usage_of_.3Clinux.2Fmount.h.3E_and_.3Csys.2Fmount.h.3E
|
||||
// https://github.com/ostreedev/ostree/issues/2685
|
||||
#include <linux/fs.h>
|
||||
#include <ext2fs/ext2_fs.h>
|
||||
|
||||
#include "otutil.h"
|
||||
|
||||
/**
|
||||
* _ostree_linuxfs_fd_alter_immutable_flag:
|
||||
* @fd: A file descriptor
|
||||
@@ -88,3 +90,21 @@ _ostree_linuxfs_fd_alter_immutable_flag (int fd,
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Wrapper for FIFREEZE ioctl.
|
||||
* This is split into a separate wrapped API for
|
||||
* reasons around conflicts between glibc and linux/fs.h
|
||||
* includes; see above.
|
||||
*/
|
||||
int
|
||||
_ostree_linuxfs_filesystem_freeze (int fd)
|
||||
{
|
||||
return TEMP_FAILURE_RETRY (ioctl (fd, FIFREEZE, 0));
|
||||
}
|
||||
|
||||
/* Wrapper for FITHAW ioctl. See above. */
|
||||
int
|
||||
_ostree_linuxfs_filesystem_thaw (int fd)
|
||||
{
|
||||
return TEMP_FAILURE_RETRY (ioctl (fd, FITHAW, 0));
|
||||
}
|
||||
@@ -29,4 +29,7 @@ _ostree_linuxfs_fd_alter_immutable_flag (int fd,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
int _ostree_linuxfs_filesystem_freeze (int fd);
|
||||
int _ostree_linuxfs_filesystem_thaw (int fd);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -303,8 +303,6 @@ ostree_mutable_tree_replace_file (OstreeMutableTree *self,
|
||||
const char *checksum,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (name != NULL, FALSE);
|
||||
|
||||
if (!ot_util_filename_validate (name, error))
|
||||
return FALSE;
|
||||
|
||||
@@ -338,8 +336,6 @@ ostree_mutable_tree_remove (OstreeMutableTree *self,
|
||||
gboolean allow_noent,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (name != NULL, FALSE);
|
||||
|
||||
if (!ot_util_filename_validate (name, error))
|
||||
return FALSE;
|
||||
|
||||
@@ -374,8 +370,6 @@ ostree_mutable_tree_ensure_dir (OstreeMutableTree *self,
|
||||
OstreeMutableTree **out_subdir,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (name != NULL, FALSE);
|
||||
|
||||
if (!ot_util_filename_validate (name, error))
|
||||
return FALSE;
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
#define WHITEOUT_PREFIX ".wh."
|
||||
#define OPAQUE_WHITEOUT_NAME ".wh..wh..opq"
|
||||
|
||||
#define OVERLAYFS_WHITEOUT_PREFIX ".ostree-wh."
|
||||
|
||||
/* Per-checkout call state/caching */
|
||||
typedef struct {
|
||||
GString *path_buf; /* buffer for real path if filtering enabled */
|
||||
@@ -582,6 +584,117 @@ checkout_file_hardlink (OstreeRepo *self,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_checkout_overlayfs_whiteout_at_no_overwrite (OstreeRepoCheckoutAtOptions *options,
|
||||
int destination_dfd,
|
||||
const char *destination_name,
|
||||
GFileInfo *file_info,
|
||||
GVariant *xattrs,
|
||||
gboolean *found_exant_file,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
if (found_exant_file != NULL)
|
||||
*found_exant_file = FALSE;
|
||||
guint32 file_mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode");
|
||||
if (mknodat(destination_dfd, destination_name, (file_mode & ~S_IFMT) | S_IFCHR, (dev_t)0) < 0)
|
||||
{
|
||||
if (errno == EEXIST && found_exant_file != NULL)
|
||||
{
|
||||
*found_exant_file = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
return glnx_throw_errno_prefix (error, "Creating whiteout char device");
|
||||
}
|
||||
if (options->mode != OSTREE_REPO_CHECKOUT_MODE_USER)
|
||||
{
|
||||
if (xattrs != NULL &&
|
||||
!glnx_dfd_name_set_all_xattrs(destination_dfd, destination_name, xattrs,
|
||||
cancellable, error))
|
||||
return glnx_throw_errno_prefix (error, "Setting xattrs for whiteout char device");
|
||||
|
||||
if (TEMP_FAILURE_RETRY(fchownat(destination_dfd, destination_name,
|
||||
g_file_info_get_attribute_uint32 (file_info, "unix::uid"),
|
||||
g_file_info_get_attribute_uint32 (file_info, "unix::gid"),
|
||||
AT_SYMLINK_NOFOLLOW) < 0))
|
||||
return glnx_throw_errno_prefix (error, "fchownat");
|
||||
if (TEMP_FAILURE_RETRY (fchmodat (destination_dfd, destination_name, file_mode & ~S_IFMT, 0)) < 0)
|
||||
return glnx_throw_errno_prefix (error, "fchmodat %s to 0%o", destination_name, file_mode & ~S_IFMT);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_checkout_overlayfs_whiteout_at (OstreeRepo *repo,
|
||||
OstreeRepoCheckoutAtOptions *options,
|
||||
int destination_dfd,
|
||||
const char *destination_name,
|
||||
GFileInfo *file_info,
|
||||
GVariant *xattrs,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean found_exant_file = FALSE;
|
||||
if (!_checkout_overlayfs_whiteout_at_no_overwrite(options, destination_dfd, destination_name,
|
||||
file_info, xattrs,&found_exant_file,
|
||||
cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
if (!found_exant_file)
|
||||
return TRUE;
|
||||
|
||||
guint32 uid = g_file_info_get_attribute_uint32 (file_info, "unix::uid");
|
||||
guint32 gid = g_file_info_get_attribute_uint32 (file_info, "unix::gid");
|
||||
guint32 file_mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode");
|
||||
|
||||
struct stat dest_stbuf;
|
||||
|
||||
switch(options->overwrite_mode)
|
||||
{
|
||||
case OSTREE_REPO_CHECKOUT_OVERWRITE_NONE:
|
||||
return FALSE;
|
||||
case OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES:
|
||||
if (!ot_ensure_unlinked_at (destination_dfd, destination_name, error))
|
||||
return FALSE;
|
||||
return _checkout_overlayfs_whiteout_at_no_overwrite(options, destination_dfd, destination_name,
|
||||
file_info, xattrs, NULL, cancellable, error);
|
||||
case OSTREE_REPO_CHECKOUT_OVERWRITE_ADD_FILES:
|
||||
return TRUE;
|
||||
|
||||
case OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_IDENTICAL:
|
||||
if (!glnx_fstatat(destination_dfd, destination_name, &dest_stbuf, AT_SYMLINK_NOFOLLOW,
|
||||
error))
|
||||
return FALSE;
|
||||
if (!(repo->disable_xattrs || repo->mode == OSTREE_REPO_MODE_BARE_USER_ONLY))
|
||||
{
|
||||
g_autoptr(GVariant) fs_xattrs;
|
||||
if (!glnx_dfd_name_get_all_xattrs (destination_dfd, destination_name,
|
||||
&fs_xattrs, cancellable, error))
|
||||
return FALSE;
|
||||
if (!g_variant_equal(fs_xattrs, xattrs))
|
||||
return glnx_throw(error, "existing destination file %s xattrs don't match",
|
||||
destination_name);
|
||||
}
|
||||
if (options->mode != OSTREE_REPO_CHECKOUT_MODE_USER)
|
||||
{
|
||||
if (gid != dest_stbuf.st_gid)
|
||||
return glnx_throw(error, "existing destination file %s does not match gid %d",
|
||||
destination_name, gid);
|
||||
|
||||
if (uid != dest_stbuf.st_uid)
|
||||
return glnx_throw(error, "existing destination file %s does not match uid %d",
|
||||
destination_name, gid);
|
||||
|
||||
if ((file_mode & ALLPERMS) != (dest_stbuf.st_mode & ALLPERMS))
|
||||
return glnx_throw(error, "existing destination file %s does not match mode %o",
|
||||
destination_name, file_mode);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
checkout_one_file_at (OstreeRepo *repo,
|
||||
OstreeRepoCheckoutAtOptions *options,
|
||||
@@ -603,7 +716,8 @@ checkout_one_file_at (OstreeRepo *repo,
|
||||
|
||||
/* FIXME - avoid the GFileInfo here */
|
||||
g_autoptr(GFileInfo) source_info = NULL;
|
||||
if (!ostree_repo_load_file (repo, checksum, NULL, &source_info, NULL,
|
||||
g_autoptr(GVariant) source_xattrs = NULL;
|
||||
if (!ostree_repo_load_file (repo, checksum, NULL, &source_info, &source_xattrs,
|
||||
cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
@@ -623,6 +737,7 @@ checkout_one_file_at (OstreeRepo *repo,
|
||||
const gboolean is_unreadable = (!is_symlink && (source_mode & S_IRUSR) == 0);
|
||||
const gboolean is_whiteout = (!is_symlink && options->process_whiteouts &&
|
||||
g_str_has_prefix (destination_name, WHITEOUT_PREFIX));
|
||||
const gboolean is_overlayfs_whiteout = (!is_symlink && g_str_has_prefix (destination_name, OVERLAYFS_WHITEOUT_PREFIX));
|
||||
const gboolean is_reg_zerosized = (!is_symlink && g_file_info_get_size (source_info) == 0);
|
||||
const gboolean override_user_unreadable = (options->mode == OSTREE_REPO_CHECKOUT_MODE_USER && is_unreadable);
|
||||
|
||||
@@ -643,6 +758,18 @@ checkout_one_file_at (OstreeRepo *repo,
|
||||
|
||||
need_copy = FALSE;
|
||||
}
|
||||
else if (is_overlayfs_whiteout && options->process_passthrough_whiteouts)
|
||||
{
|
||||
const char *name = destination_name + (sizeof (OVERLAYFS_WHITEOUT_PREFIX) - 1);
|
||||
|
||||
if (!name[0])
|
||||
return glnx_throw (error, "Invalid empty overlayfs whiteout '%s'", name);
|
||||
|
||||
g_assert (name[0] != '/'); /* Sanity */
|
||||
|
||||
return _checkout_overlayfs_whiteout_at(repo, options, destination_dfd, name,
|
||||
source_info, source_xattrs, cancellable, error);
|
||||
}
|
||||
else if (is_reg_zerosized || override_user_unreadable)
|
||||
{
|
||||
/* In https://github.com/ostreedev/ostree/commit/673cacd633f9d6b653cdea530657d3e780a41bbd we
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
#include <sys/xattr.h>
|
||||
#include <glib/gprintf.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/fs.h>
|
||||
#include <ext2fs/ext2_fs.h>
|
||||
|
||||
#include "otutil.h"
|
||||
@@ -882,11 +881,8 @@ _try_clone_from_payload_link (OstreeRepo *self,
|
||||
else
|
||||
{
|
||||
/* This undoes all of the previous writes; we want to generate reflinked data. */
|
||||
if (ftruncate (tmpf->fd, 0) < 0)
|
||||
return glnx_throw_errno_prefix (error, "ftruncate");
|
||||
|
||||
if (glnx_regfile_copy_bytes (fdf, tmpf->fd, -1) < 0)
|
||||
return glnx_throw_errno_prefix (error, "regfile copy");
|
||||
if (ioctl (tmpf->fd, FICLONE, fdf) < 0)
|
||||
return glnx_throw_errno_prefix (error, "FICLONE");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1749,7 +1745,7 @@ ostree_repo_prepare_transaction (OstreeRepo *self,
|
||||
return FALSE;
|
||||
|
||||
/* Success: do not abort the transaction when returning. */
|
||||
txn->repo = NULL; (void) txn;
|
||||
g_clear_object (&txn->repo); (void) txn;
|
||||
|
||||
if (out_transaction_resume)
|
||||
*out_transaction_resume = ret_transaction_resume;
|
||||
|
||||
@@ -3680,7 +3680,7 @@ all_requested_refs_have_commit (GHashTable *requested_refs /* (element-type Ostr
|
||||
* * `override-commit-ids` (`as`): Array of specific commit IDs to fetch for refs
|
||||
* * `timestamp-check` (`b`): Verify commit timestamps are newer than current (when pulling via ref); Since: 2017.11
|
||||
* * `timestamp-check-from-rev` (`s`): Verify that all fetched commit timestamps are newer than timestamp of given rev; Since: 2020.4
|
||||
* * `metadata-size-restriction` (`t`): Restrict metadata objects to a maximum number of bytes; 0 to disable. Since: 2018.9
|
||||
* * `max-metadata-size` (`t`): Restrict metadata objects to a maximum number of bytes; 0 to disable. Since: 2018.9
|
||||
* * `dry-run` (`b`): Only print information on what will be downloaded (requires static deltas)
|
||||
* * `override-url` (`s`): Fetch objects from this URL if remote specifies no metalink in options
|
||||
* * `inherit-transaction` (`b`): Don't initiate, finish or abort a transaction, useful to do multiple pulls in one transaction.
|
||||
|
||||
@@ -1369,7 +1369,6 @@ ostree_repo_static_delta_generate (OstreeRepo *self,
|
||||
g_autoptr(GPtrArray) builder_parts = g_ptr_array_new_with_free_func ((GDestroyNotify)ostree_static_delta_part_builder_unref);
|
||||
g_autoptr(GPtrArray) builder_fallback_objects = g_ptr_array_new_with_free_func ((GDestroyNotify)g_variant_unref);
|
||||
g_auto(GLnxTmpfile) descriptor_tmpf = { 0, };
|
||||
g_autoptr(OtVariantBuilder) descriptor_builder = NULL;
|
||||
const char *opt_sign_name;
|
||||
const char **opt_key_ids;
|
||||
|
||||
@@ -1456,7 +1455,10 @@ ostree_repo_static_delta_generate (OstreeRepo *self,
|
||||
&descriptor_tmpf, error))
|
||||
return FALSE;
|
||||
|
||||
descriptor_builder = ot_variant_builder_new (G_VARIANT_TYPE (OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT), descriptor_tmpf.fd);
|
||||
g_autoptr(OtVariantBuilder) descriptor_builder =
|
||||
ot_variant_builder_new (G_VARIANT_TYPE (OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT),
|
||||
descriptor_tmpf.fd);
|
||||
g_assert (descriptor_builder != NULL);
|
||||
|
||||
/* Open the metadata dict */
|
||||
if (!ot_variant_builder_open (descriptor_builder, G_VARIANT_TYPE ("a{sv}"), error))
|
||||
@@ -1603,7 +1605,6 @@ ostree_repo_static_delta_generate (OstreeRepo *self,
|
||||
const gchar *signature_key = NULL;
|
||||
g_autoptr(GVariantBuilder) signature_builder = NULL;
|
||||
g_auto(GLnxTmpfile) descriptor_sign_tmpf = { 0, };
|
||||
g_autoptr(OtVariantBuilder) descriptor_sign_builder = NULL;
|
||||
|
||||
lseek (descriptor_tmpf.fd, 0, SEEK_SET);
|
||||
tmpdata = glnx_fd_readall_bytes (descriptor_tmpf.fd, cancellable, error);
|
||||
@@ -1640,8 +1641,10 @@ ostree_repo_static_delta_generate (OstreeRepo *self,
|
||||
&descriptor_sign_tmpf, error))
|
||||
return FALSE;
|
||||
|
||||
descriptor_sign_builder = ot_variant_builder_new (G_VARIANT_TYPE (OSTREE_STATIC_DELTA_SIGNED_FORMAT),
|
||||
descriptor_sign_tmpf.fd);
|
||||
g_autoptr(OtVariantBuilder) descriptor_sign_builder =
|
||||
ot_variant_builder_new (G_VARIANT_TYPE (OSTREE_STATIC_DELTA_SIGNED_FORMAT),
|
||||
descriptor_sign_tmpf.fd);
|
||||
g_assert (descriptor_sign_builder != NULL);
|
||||
|
||||
if (!ot_variant_builder_add (descriptor_sign_builder, error, "t",
|
||||
GUINT64_TO_BE (OSTREE_STATIC_DELTA_SIGNED_MAGIC)))
|
||||
|
||||
@@ -3514,7 +3514,7 @@ reload_sysroot_config (OstreeRepo *self,
|
||||
* https://github.com/ostreedev/ostree/issues/1719
|
||||
* https://github.com/ostreedev/ostree/issues/1801
|
||||
*/
|
||||
gboolean valid_bootloader;
|
||||
gboolean valid_bootloader = FALSE;
|
||||
for (int i = 0; CFG_SYSROOT_BOOTLOADER_OPTS_STR[i]; i++)
|
||||
{
|
||||
if (g_str_equal (bootloader, CFG_SYSROOT_BOOTLOADER_OPTS_STR[i]))
|
||||
|
||||
@@ -989,8 +989,9 @@ typedef struct {
|
||||
gboolean force_copy; /* Since: 2017.6 */
|
||||
gboolean bareuseronly_dirs; /* Since: 2017.7 */
|
||||
gboolean force_copy_zerosized; /* Since: 2018.9 */
|
||||
gboolean unused_bools[4];
|
||||
/* 4 byte hole on 64 bit */
|
||||
gboolean process_passthrough_whiteouts;
|
||||
gboolean unused_bools[3];
|
||||
/* 3 byte hole on 64 bit */
|
||||
|
||||
const char *subpath;
|
||||
|
||||
|
||||
+41
-19
@@ -96,8 +96,11 @@ ostree_sign_default_init (OstreeSignInterface *iface)
|
||||
const gchar *
|
||||
ostree_sign_metadata_key (OstreeSign *self)
|
||||
{
|
||||
g_assert (OSTREE_IS_SIGN (self));
|
||||
|
||||
if (OSTREE_SIGN_GET_IFACE (self)->metadata_key == NULL)
|
||||
return NULL;
|
||||
|
||||
g_return_val_if_fail (OSTREE_SIGN_GET_IFACE (self)->metadata_key != NULL, NULL);
|
||||
return OSTREE_SIGN_GET_IFACE (self)->metadata_key (self);
|
||||
}
|
||||
|
||||
@@ -116,8 +119,11 @@ ostree_sign_metadata_key (OstreeSign *self)
|
||||
const gchar *
|
||||
ostree_sign_metadata_format (OstreeSign *self)
|
||||
{
|
||||
g_assert (OSTREE_IS_SIGN (self));
|
||||
|
||||
if (OSTREE_SIGN_GET_IFACE (self)->metadata_format == NULL)
|
||||
return NULL;
|
||||
|
||||
g_return_val_if_fail (OSTREE_SIGN_GET_IFACE (self)->metadata_format != NULL, NULL);
|
||||
return OSTREE_SIGN_GET_IFACE (self)->metadata_format (self);
|
||||
}
|
||||
|
||||
@@ -136,7 +142,8 @@ gboolean
|
||||
ostree_sign_clear_keys (OstreeSign *self,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE);
|
||||
g_assert (OSTREE_IS_SIGN (self));
|
||||
|
||||
if (OSTREE_SIGN_GET_IFACE (self)->clear_keys == NULL)
|
||||
return glnx_throw (error, "not implemented");
|
||||
|
||||
@@ -163,7 +170,8 @@ ostree_sign_set_sk (OstreeSign *self,
|
||||
GVariant *secret_key,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE);
|
||||
g_assert (OSTREE_IS_SIGN (self));
|
||||
|
||||
if (OSTREE_SIGN_GET_IFACE (self)->set_sk == NULL)
|
||||
return glnx_throw (error, "not implemented");
|
||||
|
||||
@@ -191,7 +199,8 @@ ostree_sign_set_pk (OstreeSign *self,
|
||||
GVariant *public_key,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE);
|
||||
g_assert (OSTREE_IS_SIGN (self));
|
||||
|
||||
if (OSTREE_SIGN_GET_IFACE (self)->set_pk == NULL)
|
||||
return glnx_throw (error, "not implemented");
|
||||
|
||||
@@ -219,7 +228,8 @@ ostree_sign_add_pk (OstreeSign *self,
|
||||
GVariant *public_key,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE);
|
||||
g_assert (OSTREE_IS_SIGN (self));
|
||||
|
||||
if (OSTREE_SIGN_GET_IFACE (self)->add_pk == NULL)
|
||||
return glnx_throw (error, "not implemented");
|
||||
|
||||
@@ -258,7 +268,8 @@ ostree_sign_load_pk (OstreeSign *self,
|
||||
GVariant *options,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE);
|
||||
g_assert (OSTREE_IS_SIGN (self));
|
||||
|
||||
if (OSTREE_SIGN_GET_IFACE (self)->load_pk == NULL)
|
||||
return glnx_throw (error, "not implemented");
|
||||
|
||||
@@ -290,8 +301,8 @@ ostree_sign_data (OstreeSign *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_assert (OSTREE_IS_SIGN (self));
|
||||
|
||||
g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE);
|
||||
if (OSTREE_SIGN_GET_IFACE (self)->data == NULL)
|
||||
return glnx_throw (error, "not implemented");
|
||||
|
||||
@@ -324,7 +335,8 @@ ostree_sign_data_verify (OstreeSign *self,
|
||||
char **out_success_message,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE);
|
||||
g_assert (OSTREE_IS_SIGN (self));
|
||||
|
||||
if (OSTREE_SIGN_GET_IFACE (self)->data_verify == NULL)
|
||||
return glnx_throw (error, "not implemented");
|
||||
|
||||
@@ -337,9 +349,13 @@ ostree_sign_data_verify (OstreeSign *self,
|
||||
static GVariant *
|
||||
_sign_detached_metadata_append (OstreeSign *self,
|
||||
GVariant *existing_metadata,
|
||||
GBytes *signature_bytes)
|
||||
GBytes *signature_bytes,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (signature_bytes != NULL, FALSE);
|
||||
g_assert (OSTREE_IS_SIGN (self));
|
||||
|
||||
if (signature_bytes == NULL)
|
||||
return glnx_null_throw (error, "Invalid NULL signature bytes");
|
||||
|
||||
GVariantDict metadata_dict;
|
||||
g_autoptr(GVariant) signature_data = NULL;
|
||||
@@ -395,7 +411,7 @@ ostree_sign_commit_verify (OstreeSign *self,
|
||||
GError **error)
|
||||
|
||||
{
|
||||
g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE);
|
||||
g_assert (OSTREE_IS_SIGN (self));
|
||||
|
||||
g_autoptr(GVariant) commit_variant = NULL;
|
||||
/* Load the commit */
|
||||
@@ -447,10 +463,12 @@ ostree_sign_commit_verify (OstreeSign *self,
|
||||
const gchar *
|
||||
ostree_sign_get_name (OstreeSign *self)
|
||||
{
|
||||
g_return_val_if_fail (OSTREE_IS_SIGN (self), NULL);
|
||||
g_return_val_if_fail (OSTREE_SIGN_GET_IFACE (self)->get_name != NULL, NULL);
|
||||
g_assert (OSTREE_IS_SIGN (self));
|
||||
|
||||
return OSTREE_SIGN_GET_IFACE (self)->get_name (self);
|
||||
if (OSTREE_SIGN_GET_IFACE (self)->get_name == NULL)
|
||||
return NULL;
|
||||
|
||||
return OSTREE_SIGN_GET_IFACE (self)->get_name (self);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -503,7 +521,9 @@ ostree_sign_commit (OstreeSign *self,
|
||||
return glnx_prefix_error (error, "Not able to sign the cobject");
|
||||
|
||||
new_metadata =
|
||||
_sign_detached_metadata_append (self, old_metadata, signature);
|
||||
_sign_detached_metadata_append (self, old_metadata, signature, error);
|
||||
if (new_metadata == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (!ostree_repo_write_commit_detached_metadata (repo,
|
||||
commit_checksum,
|
||||
@@ -603,8 +623,8 @@ ostree_sign_summary (OstreeSign *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE);
|
||||
g_return_val_if_fail (OSTREE_IS_REPO (repo), FALSE);
|
||||
g_assert (OSTREE_IS_SIGN (self));
|
||||
g_assert (OSTREE_IS_REPO (repo));
|
||||
|
||||
g_autoptr(GVariant) normalized = NULL;
|
||||
g_autoptr(GBytes) summary_data = NULL;
|
||||
@@ -653,7 +673,9 @@ ostree_sign_summary (OstreeSign *self,
|
||||
|
||||
g_autoptr(GVariant) old_metadata = g_steal_pointer (&metadata);
|
||||
metadata =
|
||||
_sign_detached_metadata_append (self, old_metadata, signature);
|
||||
_sign_detached_metadata_append (self, old_metadata, signature, error);
|
||||
if (metadata == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
g_variant_iter_free (iter);
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/poll.h>
|
||||
#include <linux/fs.h>
|
||||
#include <err.h>
|
||||
|
||||
#ifdef HAVE_LIBMOUNT
|
||||
@@ -642,7 +641,7 @@ checkout_deployment_tree (OstreeSysroot *sysroot,
|
||||
return FALSE;
|
||||
|
||||
/* Generate hardlink farm, then opendir it */
|
||||
OstreeRepoCheckoutAtOptions checkout_opts = { 0, };
|
||||
OstreeRepoCheckoutAtOptions checkout_opts = { .process_passthrough_whiteouts = TRUE };
|
||||
if (!ostree_repo_checkout_at (repo, &checkout_opts, osdeploy_dfd,
|
||||
checkout_target_name, csum,
|
||||
cancellable, error))
|
||||
@@ -1476,7 +1475,7 @@ fsfreeze_thaw_cycle (OstreeSysroot *self,
|
||||
* EOPNOTSUPP: If the filesystem doesn't support it
|
||||
*/
|
||||
int saved_errno = errno;
|
||||
(void) TEMP_FAILURE_RETRY (ioctl (rootfs_dfd, FITHAW, 0));
|
||||
_ostree_linuxfs_filesystem_thaw (rootfs_dfd);
|
||||
errno = saved_errno;
|
||||
/* But if we got an error from poll, let's log it */
|
||||
if (r < 0)
|
||||
@@ -1517,7 +1516,7 @@ fsfreeze_thaw_cycle (OstreeSysroot *self,
|
||||
return glnx_throw (error, "aborting due to test-fifreeze");
|
||||
}
|
||||
/* Do a freeze/thaw cycle; TODO add a FIFREEZETHAW ioctl */
|
||||
if (ioctl (rootfs_dfd, FIFREEZE, 0) != 0)
|
||||
if (_ostree_linuxfs_filesystem_freeze (rootfs_dfd) != 0)
|
||||
{
|
||||
/* Not supported, we're running in the unit tests (as non-root), or
|
||||
* the filesystem is already frozen (EBUSY).
|
||||
@@ -1539,7 +1538,7 @@ fsfreeze_thaw_cycle (OstreeSysroot *self,
|
||||
return glnx_throw_errno_prefix (error, "ioctl(FIFREEZE)");
|
||||
}
|
||||
/* And finally thaw, then signal our completion to the watchdog */
|
||||
if (TEMP_FAILURE_RETRY (ioctl (rootfs_dfd, FITHAW, 0)) != 0)
|
||||
if (_ostree_linuxfs_filesystem_thaw (rootfs_dfd) != 0)
|
||||
{
|
||||
/* Warn but don't error if the filesystem was already thawed */
|
||||
if (errno == EINVAL)
|
||||
@@ -2006,7 +2005,7 @@ install_deployment_kernel (OstreeSysroot *sysroot,
|
||||
&variant, NULL))
|
||||
{
|
||||
metadata = g_variant_get_child_value (variant, 0);
|
||||
g_variant_lookup (metadata, OSTREE_COMMIT_META_KEY_VERSION, "s", &deployment_version);
|
||||
(void) g_variant_lookup (metadata, OSTREE_COMMIT_META_KEY_VERSION, "s", &deployment_version);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2233,7 +2232,7 @@ get_deployment_ostree_version (OstreeRepo *repo,
|
||||
if (ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, csum, &variant, NULL))
|
||||
{
|
||||
g_autoptr(GVariant) metadata = g_variant_get_child_value (variant, 0);
|
||||
g_variant_lookup (metadata, OSTREE_COMMIT_META_KEY_VERSION, "s", &version);
|
||||
(void) g_variant_lookup (metadata, OSTREE_COMMIT_META_KEY_VERSION, "s", &version);
|
||||
}
|
||||
|
||||
return g_steal_pointer (&version);
|
||||
@@ -3595,7 +3594,7 @@ ostree_sysroot_deployment_set_kargs (OstreeSysroot *self,
|
||||
* ostree_sysroot_deployment_set_kargs_in_place:
|
||||
* @self: Sysroot
|
||||
* @deployment: A deployment
|
||||
* @kargs_str: (allow none): Replace @deployment's kernel arguments
|
||||
* @kargs_str: (allow-none): Replace @deployment's kernel arguments
|
||||
* @cancellable: Cancellable
|
||||
* @error: Error
|
||||
*
|
||||
@@ -3615,25 +3614,55 @@ ostree_sysroot_deployment_set_kargs_in_place (OstreeSysroot *self,
|
||||
if (!_ostree_sysroot_ensure_writable (self, error))
|
||||
return FALSE;
|
||||
|
||||
g_assert (!ostree_deployment_is_staged (deployment));
|
||||
// handle staged deployment
|
||||
if (ostree_deployment_is_staged (deployment))
|
||||
{
|
||||
/* Read the staged state from disk */
|
||||
glnx_autofd int fd = -1;
|
||||
if (!glnx_openat_rdonly (AT_FDCWD, _OSTREE_SYSROOT_RUNSTATE_STAGED, TRUE, &fd, error))
|
||||
return FALSE;
|
||||
|
||||
OstreeBootconfigParser *new_bootconfig = ostree_deployment_get_bootconfig (deployment);
|
||||
ostree_bootconfig_parser_set (new_bootconfig, "options", kargs_str);
|
||||
|
||||
g_autofree char *bootconf_name =
|
||||
g_strdup_printf ("ostree-%d-%s.conf",
|
||||
self->deployments->len - ostree_deployment_get_index (deployment),
|
||||
ostree_deployment_get_osname (deployment));
|
||||
|
||||
g_autofree char *bootconfdir = g_strdup_printf ("loader.%d/entries", self->bootversion);
|
||||
glnx_autofd int bootconf_dfd = -1;
|
||||
if (!glnx_opendirat (self->boot_fd, bootconfdir, TRUE, &bootconf_dfd, error))
|
||||
return FALSE;
|
||||
|
||||
if (!ostree_bootconfig_parser_write_at (new_bootconfig,
|
||||
bootconf_dfd, bootconf_name,
|
||||
g_autoptr(GBytes) contents = ot_fd_readall_or_mmap (fd, 0, error);
|
||||
if (!contents)
|
||||
return FALSE;
|
||||
g_autoptr(GVariant) staged_deployment_data =
|
||||
g_variant_new_from_bytes ((GVariantType*)"a{sv}", contents, TRUE);
|
||||
g_autoptr(GVariantDict) staged_deployment_dict =
|
||||
g_variant_dict_new (staged_deployment_data);
|
||||
|
||||
g_autoptr(OstreeKernelArgs) kargs = ostree_kernel_args_from_string (kargs_str);
|
||||
g_auto(GStrv) kargs_strv = ostree_kernel_args_to_strv (kargs);
|
||||
|
||||
g_variant_dict_insert (staged_deployment_dict, "kargs", "^a&s", kargs_strv);
|
||||
g_autoptr(GVariant) new_staged_deployment_data = g_variant_dict_end (staged_deployment_dict);
|
||||
|
||||
if (!glnx_file_replace_contents_at (fd, _OSTREE_SYSROOT_RUNSTATE_STAGED,
|
||||
g_variant_get_data (new_staged_deployment_data),
|
||||
g_variant_get_size (new_staged_deployment_data),
|
||||
GLNX_FILE_REPLACE_NODATASYNC,
|
||||
cancellable, error))
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
OstreeBootconfigParser *new_bootconfig = ostree_deployment_get_bootconfig (deployment);
|
||||
ostree_bootconfig_parser_set (new_bootconfig, "options", kargs_str);
|
||||
|
||||
g_autofree char *bootconf_name =
|
||||
g_strdup_printf ("ostree-%d-%s.conf",
|
||||
self->deployments->len - ostree_deployment_get_index (deployment),
|
||||
ostree_deployment_get_osname (deployment));
|
||||
|
||||
g_autofree char *bootconfdir = g_strdup_printf ("loader.%d/entries", self->bootversion);
|
||||
glnx_autofd int bootconf_dfd = -1;
|
||||
if (!glnx_opendirat (self->boot_fd, bootconfdir, TRUE, &bootconf_dfd, error))
|
||||
return FALSE;
|
||||
|
||||
if (!ostree_bootconfig_parser_write_at (new_bootconfig,
|
||||
bootconf_dfd, bootconf_name,
|
||||
cancellable, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
*
|
||||
* Since: 2017.4
|
||||
*/
|
||||
#define OSTREE_RELEASE_VERSION (5)
|
||||
#define OSTREE_RELEASE_VERSION (6)
|
||||
|
||||
/**
|
||||
* OSTREE_VERSION
|
||||
@@ -50,7 +50,7 @@
|
||||
*
|
||||
* Since: 2017.4
|
||||
*/
|
||||
#define OSTREE_VERSION (2022.5)
|
||||
#define OSTREE_VERSION (2022.6)
|
||||
|
||||
/**
|
||||
* OSTREE_VERSION_S:
|
||||
@@ -60,7 +60,7 @@
|
||||
*
|
||||
* Since: 2017.4
|
||||
*/
|
||||
#define OSTREE_VERSION_S "2022.5"
|
||||
#define OSTREE_VERSION_S "2022.6"
|
||||
|
||||
#define OSTREE_ENCODE_VERSION(year,release) \
|
||||
((year) << 16 | (release))
|
||||
@@ -99,5 +99,5 @@
|
||||
* Since: 2019.3
|
||||
*/
|
||||
#ifndef __GI_SCANNER__
|
||||
#define OSTREE_BUILT_FEATURES "libsoup gpgme ex-fsverity libarchive selinux libmount systemd release p2p"
|
||||
#define OSTREE_BUILT_FEATURES "libsoup gpgme ex-fsverity libarchive selinux avahi libmount systemd release p2p"
|
||||
#endif
|
||||
@@ -1,22 +0,0 @@
|
||||
#!/bin/bash
|
||||
# This script creates new initramdisk with LUKS config within
|
||||
set -euo pipefail
|
||||
|
||||
old_initrd=$1
|
||||
new_initrd=$2
|
||||
currdir=$PWD
|
||||
|
||||
# Copying existing initramdisk
|
||||
cp ${old_initrd} ${new_initrd}
|
||||
|
||||
# Appending LUKS root keys and crypttab config to the end of initrd
|
||||
workdir=$(mktemp -d -p /tmp se-initramfs-XXXXXX)
|
||||
cd ${workdir}
|
||||
mkdir -p etc/luks
|
||||
cp -f /etc/luks/* etc/luks/
|
||||
cp -f /etc/crypttab etc/
|
||||
find . -mindepth 1 | cpio --quiet -H newc -o | gzip -9 -n >> ${new_initrd}
|
||||
|
||||
# Cleanup
|
||||
cd ${currdir}
|
||||
rm -rf ${workdir}
|
||||
@@ -758,11 +758,9 @@ struct _OtVariantBuilder {
|
||||
static OtVariantBuilderInfo *
|
||||
ot_variant_builder_info_new (OtVariantBuilder *builder, const GVariantType *type)
|
||||
{
|
||||
OtVariantBuilderInfo *info;
|
||||
g_assert (g_variant_type_is_container (type));
|
||||
|
||||
g_return_val_if_fail (g_variant_type_is_container (type), NULL);
|
||||
|
||||
info = (OtVariantBuilderInfo *) g_slice_new0 (OtVariantBuilderInfo);
|
||||
OtVariantBuilderInfo *info = (OtVariantBuilderInfo *) g_slice_new0 (OtVariantBuilderInfo);
|
||||
|
||||
info->builder = builder;
|
||||
info->type = g_variant_type_copy (type);
|
||||
@@ -843,11 +841,9 @@ OtVariantBuilder *
|
||||
ot_variant_builder_new (const GVariantType *type,
|
||||
int fd)
|
||||
{
|
||||
OtVariantBuilder *builder;
|
||||
g_assert (g_variant_type_is_container (type));
|
||||
|
||||
g_return_val_if_fail (g_variant_type_is_container (type), NULL);
|
||||
|
||||
builder = (OtVariantBuilder *) g_slice_new0 (OtVariantBuilder);
|
||||
OtVariantBuilder *builder = (OtVariantBuilder *) g_slice_new0 (OtVariantBuilder);
|
||||
|
||||
builder->head = ot_variant_builder_info_new (builder, type);
|
||||
builder->ref_count = 1;
|
||||
@@ -1083,7 +1079,6 @@ ot_variant_builder_open (OtVariantBuilder *builder,
|
||||
GError **error)
|
||||
{
|
||||
OtVariantBuilderInfo *info = builder->head;
|
||||
OtVariantBuilderInfo *new_info;
|
||||
|
||||
g_assert (info->n_children < info->max_items);
|
||||
g_assert (!info->expected_type ||
|
||||
@@ -1096,7 +1091,9 @@ ot_variant_builder_open (OtVariantBuilder *builder,
|
||||
if (!ot_variant_builder_pre_add (info, type, error))
|
||||
return FALSE;
|
||||
|
||||
new_info = ot_variant_builder_info_new (builder, type);
|
||||
OtVariantBuilderInfo *new_info = ot_variant_builder_info_new (builder, type);
|
||||
g_assert (new_info != NULL);
|
||||
|
||||
new_info->parent = info;
|
||||
|
||||
/* push the prev_item_type down into the subcontainer */
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Red Hat, Inc.
|
||||
* Copyright (C) 2022 Endless OS Foundation LLC
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.0+
|
||||
*
|
||||
@@ -19,8 +20,9 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib-unix.h>
|
||||
#include <sched.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "ot-main.h"
|
||||
@@ -32,7 +34,10 @@
|
||||
#include "ostree-cmd-private.h"
|
||||
#include "ostree.h"
|
||||
|
||||
static gboolean opt_hold;
|
||||
|
||||
static GOptionEntry options[] = {
|
||||
{ "hold", 0, 0, G_OPTION_ARG_NONE, &opt_hold, "Hold /boot open during finalization", NULL },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
@@ -50,13 +55,52 @@ ot_admin_builtin_finalize_staged (int argc, char **argv, OstreeCommandInvocation
|
||||
|
||||
g_autoptr(GOptionContext) context = g_option_context_new ("");
|
||||
g_autoptr(OstreeSysroot) sysroot = NULL;
|
||||
|
||||
/* First parse the args without loading the sysroot to see what options are
|
||||
* set. */
|
||||
if (!ostree_admin_option_context_parse (context, options, &argc, &argv,
|
||||
OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER,
|
||||
OSTREE_ADMIN_BUILTIN_FLAG_NO_LOAD,
|
||||
invocation, &sysroot, cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
if (!ostree_cmd__private__()->ostree_finalize_staged (sysroot, cancellable, error))
|
||||
return FALSE;
|
||||
if (opt_hold)
|
||||
{
|
||||
/* Load the sysroot unlocked so that a separate namespace isn't
|
||||
* created. */
|
||||
if (!ostree_admin_sysroot_load (sysroot,
|
||||
OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER | OSTREE_ADMIN_BUILTIN_FLAG_UNLOCKED,
|
||||
cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
/* In case it's an automount, open /boot so that the automount doesn't
|
||||
* expire until before this process exits. If it did expire and got
|
||||
* unmounted, the service would be stopped and the deployment would be
|
||||
* finalized earlier than expected.
|
||||
*/
|
||||
int sysroot_fd = ostree_sysroot_get_fd (sysroot);
|
||||
glnx_autofd int boot_fd = -1;
|
||||
g_debug ("Opening /boot directory");
|
||||
if (!glnx_opendirat (sysroot_fd, "boot", TRUE, &boot_fd, error))
|
||||
return FALSE;
|
||||
|
||||
/* We want to keep /boot open until the deployment is finalized during
|
||||
* system shutdown, so block until we get SIGTERM which systemd will send
|
||||
* when the unit is stopped.
|
||||
*/
|
||||
pause ();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Load the sysroot with the normal flags and actually finalize the
|
||||
* deployment. */
|
||||
if (!ostree_admin_sysroot_load (sysroot,
|
||||
OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER,
|
||||
cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
if (!ostree_cmd__private__()->ostree_finalize_staged (sysroot, cancellable, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -37,6 +37,7 @@ static gboolean opt_union;
|
||||
static gboolean opt_union_add;
|
||||
static gboolean opt_union_identical;
|
||||
static gboolean opt_whiteouts;
|
||||
static gboolean opt_process_passthrough_whiteouts;
|
||||
static gboolean opt_from_stdin;
|
||||
static char *opt_from_file;
|
||||
static gboolean opt_disable_fsync;
|
||||
@@ -77,6 +78,7 @@ static GOptionEntry options[] = {
|
||||
{ "union-add", 0, 0, G_OPTION_ARG_NONE, &opt_union_add, "Keep existing files/directories, only add new", NULL },
|
||||
{ "union-identical", 0, 0, G_OPTION_ARG_NONE, &opt_union_identical, "When layering checkouts, error out if a file would be replaced with a different version, but add new files and directories", NULL },
|
||||
{ "whiteouts", 0, 0, G_OPTION_ARG_NONE, &opt_whiteouts, "Process 'whiteout' (Docker style) entries", NULL },
|
||||
{ "process-passthrough-whiteouts", 0, 0, G_OPTION_ARG_NONE, &opt_process_passthrough_whiteouts, "Enable overlayfs whiteout extraction into char 0:0 devices", NULL },
|
||||
{ "allow-noent", 0, 0, G_OPTION_ARG_NONE, &opt_allow_noent, "Do nothing if specified path does not exist", NULL },
|
||||
{ "from-stdin", 0, 0, G_OPTION_ARG_NONE, &opt_from_stdin, "Process many checkouts from standard input", NULL },
|
||||
{ "from-file", 0, 0, G_OPTION_ARG_STRING, &opt_from_file, "Process many checkouts from input file", "FILE" },
|
||||
@@ -129,7 +131,8 @@ process_one_checkout (OstreeRepo *repo,
|
||||
if (opt_disable_cache || opt_whiteouts || opt_require_hardlinks ||
|
||||
opt_union_add || opt_force_copy || opt_force_copy_zerosized ||
|
||||
opt_bareuseronly_dirs || opt_union_identical ||
|
||||
opt_skiplist_file || opt_selinux_policy || opt_selinux_prefix)
|
||||
opt_skiplist_file || opt_selinux_policy || opt_selinux_prefix ||
|
||||
opt_process_passthrough_whiteouts)
|
||||
{
|
||||
OstreeRepoCheckoutAtOptions checkout_options = { 0, };
|
||||
|
||||
@@ -162,6 +165,8 @@ process_one_checkout (OstreeRepo *repo,
|
||||
}
|
||||
if (opt_whiteouts)
|
||||
checkout_options.process_whiteouts = TRUE;
|
||||
if (opt_process_passthrough_whiteouts)
|
||||
checkout_options.process_passthrough_whiteouts = TRUE;
|
||||
if (subpath)
|
||||
checkout_options.subpath = subpath;
|
||||
|
||||
|
||||
@@ -25,47 +25,73 @@
|
||||
#include "ot-builtins.h"
|
||||
#include "ostree.h"
|
||||
#include "otutil.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
/* ATTENTION:
|
||||
* Please remember to update the bash-completion script (bash/ostree) and
|
||||
* man page (man/ostree-rev-parse.xml) when changing the option list.
|
||||
*/
|
||||
|
||||
static gboolean opt_single;
|
||||
|
||||
static GOptionEntry options[] = {
|
||||
{ "single", 'S', 0, G_OPTION_ARG_NONE, &opt_single, "If the repository has exactly one commit, then print it; any other case will result in an error", NULL },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
gboolean
|
||||
ostree_builtin_rev_parse (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error)
|
||||
{
|
||||
g_autoptr(GOptionContext) context = NULL;
|
||||
g_autoptr(GOptionContext) context = g_option_context_new ("REV");
|
||||
g_autoptr(OstreeRepo) repo = NULL;
|
||||
gboolean ret = FALSE;
|
||||
const char *rev = "master";
|
||||
int i;
|
||||
g_autofree char *resolved_rev = NULL;
|
||||
|
||||
context = g_option_context_new ("REV");
|
||||
|
||||
if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, error))
|
||||
goto out;
|
||||
return FALSE;
|
||||
|
||||
if (opt_single)
|
||||
{
|
||||
if (argc >= 2)
|
||||
{
|
||||
ot_util_usage_error (context, "Cannot specify arguments with --single", error);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_autoptr(GHashTable) objects = NULL;
|
||||
if (!ostree_repo_list_commit_objects_starting_with (repo, "", &objects, cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
GVariant *found = NULL;
|
||||
GLNX_HASH_TABLE_FOREACH (objects, GVariant*, key)
|
||||
{
|
||||
if (found)
|
||||
return glnx_throw (error, "Multiple commit objects found");
|
||||
found = key;
|
||||
}
|
||||
if (!found)
|
||||
return glnx_throw (error, "No commit objects found");
|
||||
const char *checksum;
|
||||
OstreeObjectType objtype;
|
||||
ostree_object_name_deserialize (found, &checksum, &objtype);
|
||||
g_assert (objtype == OSTREE_OBJECT_TYPE_COMMIT);
|
||||
|
||||
g_print ("%s\n", checksum);
|
||||
|
||||
return TRUE; /* Note early return */
|
||||
}
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
ot_util_usage_error (context, "REV must be specified", error);
|
||||
goto out;
|
||||
return FALSE;
|
||||
}
|
||||
for (i = 1; i < argc; i++)
|
||||
|
||||
for (gint i = 1; i < argc; i++)
|
||||
{
|
||||
rev = argv[i];
|
||||
g_free (resolved_rev);
|
||||
resolved_rev = NULL;
|
||||
const char *rev = argv[i];
|
||||
g_autofree char *resolved_rev = NULL;
|
||||
if (!ostree_repo_resolve_rev (repo, rev, FALSE, &resolved_rev, error))
|
||||
goto out;
|
||||
return FALSE;
|
||||
g_print ("%s\n", resolved_rev);
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
return TRUE;
|
||||
}
|
||||
+49
-35
@@ -28,7 +28,6 @@
|
||||
#include <string.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include <sys/mount.h>
|
||||
#include <linux/fs.h>
|
||||
|
||||
#include "ot-main.h"
|
||||
#include "ostree.h"
|
||||
@@ -580,41 +579,11 @@ on_sysroot_journal_msg (OstreeSysroot *sysroot,
|
||||
}
|
||||
|
||||
gboolean
|
||||
ostree_admin_option_context_parse (GOptionContext *context,
|
||||
const GOptionEntry *main_entries,
|
||||
int *argc,
|
||||
char ***argv,
|
||||
OstreeAdminBuiltinFlags flags,
|
||||
OstreeCommandInvocation *invocation,
|
||||
OstreeSysroot **out_sysroot,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
ostree_admin_sysroot_load (OstreeSysroot *sysroot,
|
||||
OstreeAdminBuiltinFlags flags,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
/* Entries are listed in --help output in the order added. We add the
|
||||
* main entries ourselves so that we can add the --sysroot entry first. */
|
||||
|
||||
g_option_context_add_main_entries (context, global_admin_entries, NULL);
|
||||
|
||||
if (!ostree_option_context_parse (context, main_entries, argc, argv,
|
||||
invocation, NULL, cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
if (!opt_print_current_dir && (flags & OSTREE_ADMIN_BUILTIN_FLAG_NO_SYSROOT))
|
||||
{
|
||||
g_assert_null (out_sysroot);
|
||||
/* Early return if no sysroot is requested */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
g_autoptr(GFile) sysroot_path = NULL;
|
||||
if (opt_sysroot != NULL)
|
||||
sysroot_path = g_file_new_for_path (opt_sysroot);
|
||||
|
||||
g_autoptr(OstreeSysroot) sysroot = ostree_sysroot_new (sysroot_path);
|
||||
if (!ostree_sysroot_initialize (sysroot, error))
|
||||
return FALSE;
|
||||
g_signal_connect (sysroot, "journal-msg", G_CALLBACK (on_sysroot_journal_msg), NULL);
|
||||
|
||||
if ((flags & OSTREE_ADMIN_BUILTIN_FLAG_UNLOCKED) == 0)
|
||||
{
|
||||
/* If we're requested to lock the sysroot, first check if we're operating
|
||||
@@ -658,6 +627,51 @@ ostree_admin_option_context_parse (GOptionContext *context,
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ostree_admin_option_context_parse (GOptionContext *context,
|
||||
const GOptionEntry *main_entries,
|
||||
int *argc,
|
||||
char ***argv,
|
||||
OstreeAdminBuiltinFlags flags,
|
||||
OstreeCommandInvocation *invocation,
|
||||
OstreeSysroot **out_sysroot,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
/* Entries are listed in --help output in the order added. We add the
|
||||
* main entries ourselves so that we can add the --sysroot entry first. */
|
||||
|
||||
g_option_context_add_main_entries (context, global_admin_entries, NULL);
|
||||
|
||||
if (!ostree_option_context_parse (context, main_entries, argc, argv,
|
||||
invocation, NULL, cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
if (!opt_print_current_dir && (flags & OSTREE_ADMIN_BUILTIN_FLAG_NO_SYSROOT))
|
||||
{
|
||||
g_assert_null (out_sysroot);
|
||||
/* Early return if no sysroot is requested */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
g_autoptr(GFile) sysroot_path = NULL;
|
||||
if (opt_sysroot != NULL)
|
||||
sysroot_path = g_file_new_for_path (opt_sysroot);
|
||||
|
||||
g_autoptr(OstreeSysroot) sysroot = ostree_sysroot_new (sysroot_path);
|
||||
if (!ostree_sysroot_initialize (sysroot, error))
|
||||
return FALSE;
|
||||
g_signal_connect (sysroot, "journal-msg", G_CALLBACK (on_sysroot_journal_msg), NULL);
|
||||
|
||||
if (opt_print_current_dir || (flags & OSTREE_ADMIN_BUILTIN_FLAG_NO_LOAD) == 0)
|
||||
{
|
||||
if (!ostree_admin_sysroot_load (sysroot, flags, cancellable, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (opt_print_current_dir)
|
||||
{
|
||||
g_autoptr(GPtrArray) deployments = NULL;
|
||||
|
||||
@@ -36,6 +36,7 @@ typedef enum {
|
||||
OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER = (1 << 0),
|
||||
OSTREE_ADMIN_BUILTIN_FLAG_UNLOCKED = (1 << 1),
|
||||
OSTREE_ADMIN_BUILTIN_FLAG_NO_SYSROOT = (1 << 2),
|
||||
OSTREE_ADMIN_BUILTIN_FLAG_NO_LOAD = (1 << 3),
|
||||
} OstreeAdminBuiltinFlags;
|
||||
|
||||
|
||||
@@ -91,6 +92,11 @@ gboolean ostree_admin_option_context_parse (GOptionContext *context,
|
||||
OstreeSysroot **out_sysroot,
|
||||
GCancellable *cancellable, GError **error);
|
||||
|
||||
gboolean ostree_admin_sysroot_load (OstreeSysroot *sysroot,
|
||||
OstreeAdminBuiltinFlags flags,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
gboolean ostree_ensure_repo_writable (OstreeRepo *repo, GError **error);
|
||||
|
||||
void ostree_print_gpg_verify_result (OstreeGpgVerifyResult *result);
|
||||
|
||||
Reference in new issue
Block a user