Compare commits

...

7 Commits

Author SHA1 Message Date
Colin Walters
9a59138d18
Merge 9593fd370e into 8aaea0c65d 2024-12-20 14:43:37 -05:00
Colin Walters
8aaea0c65d
Merge pull request #3361 from cgwalters/release
Release 2024.10
2024-12-19 17:10:40 -05:00
Colin Walters
45ddf3b798
Merge pull request #3351 from cgwalters/fix-transient-root-doc
man: Note semantics combining `root.transient` with `composefs.enabled`
2024-12-19 16:23:48 -05:00
Colin Walters
aca6f17ff8 Post-release version bump
Signed-off-by: Colin Walters <walters@verbum.org>
2024-12-19 15:11:42 -05:00
Colin Walters
66f5a77ae6 Release 2024.10
Signed-off-by: Colin Walters <walters@verbum.org>
2024-12-19 15:10:12 -05:00
Colin Walters
786b38c2cf man: Note semantics combining root.transient with composefs.enabled
It's all quite confusing having to reason about both the pre-composefs
ostree and the composefs version. But hopefully soon we more firmly
leave behind that first legacy.

Signed-off-by: Colin Walters <walters@verbum.org>
2024-12-17 16:04:38 -05:00
Colin Walters
9593fd370e Demonstrate Rust code from sysroot
This is a demo/prototype for starting to add new Rust
code only for `OstreeSysroot`.

https://github.com/ostreedev/ostree/issues/2427#issuecomment-1728210940
2023-09-20 15:17:21 -04:00
8 changed files with 110 additions and 15 deletions

View File

@ -31,7 +31,7 @@ name = "integration"
path = "rust-bindings/tests/tests.rs"
[workspace]
members = [".", "rust-bindings/sys"]
members = [".", "src/sysroot-rs", "rust-bindings/sys"]
[dependencies]
base64 = "0.20.0"

23
Makefile-sysroot-rs.am Normal file
View File

@ -0,0 +1,23 @@
# Makefile for Rust lib
#
# 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/>.
target/release/libostreesysrs.so: src/sysroot-rs/src/lib.rs
cargo build --release --workspace
libostreesysrs_DATA = target/release/libostreesysrs.so
libostreesysrsdir = $(pkglibexecdir)

View File

@ -128,6 +128,7 @@ include Makefile-switchroot.am
if BUILDOPT_FUSE
include src/rofiles-fuse/Makefile-inc.am
endif
include Makefile-sysroot-rs.am
include Makefile-tests.am
include Makefile-boot.am
include Makefile-man.am

View File

@ -1,7 +1,7 @@
AC_PREREQ([2.63])
dnl To perform a release, follow the instructions in `docs/CONTRIBUTING.md`.
m4_define([year_version], [2024])
m4_define([release_version], [10])
m4_define([release_version], [11])
m4_define([package_version], [year_version.release_version])
AC_INIT([libostree], [package_version], [walters@verbum.org])
is_release_build=no

View File

@ -120,20 +120,25 @@ License along with this library. If not, see <https://www.gnu.org/licenses/>.
<varlistentry>
<term><varname>root.transient</varname></term>
<listitem><para>A boolean value; the default is <literal>false</literal>.
If this is set to <literal>true</literal>, then the <literal>/</literal> filesystem will be a writable <literal>overlayfs</literal>,
with the upper directory being a hidden directory (in the underlying system root filesystem) that will persist across reboots by default.
However, changes will <emphasis>be discarded</emphasis> on OS updates!
Setting this flag to <literal>true</literal> requires composefs (See <literal>composefs.enabled</literal>).
When enabled, the root mount point <literal>/</literal> will be an overlayfs whose contents will be stored
in a tmpfs, and hence discarded on OS upgrade or reboot.
</para>
<para>
Enabling this option can be very useful for cases such as packages (dpkg/rpm/etc) that write content into <literal>/opt</literal>,
particularly where they expect the target to be writable at runtime. To make that work, ensure that your <literal>/opt</literal>
directory is *not* a symlink to <literal>/var/opt</literal>, but is just an empty directory.
</para>
<para>
Note the <literal>/usr</literal> mount point remains read-only by default. This option is independent of <literal>etc.transient</literal> and <literal>sysroot.readonly</literal>;
This option is independent of <literal>etc.transient</literal> and <literal>sysroot.readonly</literal>;
it is supported for example to have <literal>root.transient=true</literal> but <literal>etc.transient=false</literal> in which case changes to <literal>/etc</literal> continue
to persist across updates, with the default OSTree 3-way merge applied.
</para></listitem>
Also related to persistence it is important to emphasize that <literal>/sysroot</literal> (the physical root filesystem) is still persistent
by default; in-place OS upgrades can be applied.
</para>
<para>
Enabling this option can make it significantly easier to adopt an image-based model in some circumstances.
For example, if you have a configuration management system that is inspecting machine-specific state and
e.g. dynamically installing packages or applying configuration, it can more easily be adapted to
run on each boot, while still shifting a portion (or ideally most) image configuration to build time
as part of the base image/commit.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>composefs.enabled</varname></term>

View File

@ -21,6 +21,7 @@
#include "config.h"
#include "otutil.h"
#include <dlfcn.h>
#include <err.h>
#include <sys/file.h>
#include <sys/mount.h>
@ -76,6 +77,29 @@ enum
G_DEFINE_TYPE (OstreeSysroot, ostree_sysroot, G_TYPE_OBJECT)
static void *
load_sysroot_rs (void)
{
static gssize initialized = 0;
static void *sysrootrs = NULL;
if (g_once_init_enter (&initialized))
{
const char *uninstalled = g_getenv ("OSTREE_UNINSTALLED");
g_autofree char *path = NULL;
if (uninstalled)
path = g_strdup_printf ("%s/target/release/libostreesysrs.so", uninstalled);
else
path = g_strdup_printf ("%s/libostreesysrs.so", PKGLIBEXECDIR);
sysrootrs = dlopen (path, RTLD_NOW);
if (sysrootrs == NULL)
{
errx (EXIT_FAILURE, "failed to initialize libostreesysrs.so: %s", dlerror ());
}
g_once_init_leave (&initialized, 1);
}
return sysrootrs;
}
static void
ostree_sysroot_finalize (GObject *object)
{
@ -448,11 +472,16 @@ ostree_sysroot_is_booted (OstreeSysroot *self)
gboolean
_ostree_sysroot_bump_mtime (OstreeSysroot *self, GError **error)
{
void *lib = load_sysroot_rs ();
int (*f) (int fd) = dlsym (lib, "_ostreesys_bump_mtime");
g_assert (f);
/* Allow other systems to monitor for changes */
if (utimensat (self->sysroot_fd, "ostree/deploy", NULL, 0) < 0)
int r = f (self->sysroot_fd);
if (r < 0)
{
glnx_set_prefix_error_from_errno (error, "%s", "futimens");
return FALSE;
errno = r;
return glnx_throw_errno_prefix (error, "futimens");
}
return TRUE;
}

20
src/sysroot-rs/Cargo.toml Normal file
View File

@ -0,0 +1,20 @@
[package]
description = "Internal Rust sysroot code"
edition = "2021"
keywords = ["ostree", "libostree"]
license = "MIT"
name = "ostreesysrs"
readme = "rust-bindings/README.md"
repository = "https://github.com/ostreedev/ostree"
rust-version = "1.70.0"
version = "0.0.0"
publish = false
[lib]
name = "ostreesysrs"
crate-type = ["cdylib"]
[dependencies]
ostree = { package = "ostree", path = "../..", version = "0.19", features = ["v2022_6"] }
libc = "0.2"
rustix = { version = "0.38", features = ["fs"] }

17
src/sysroot-rs/src/lib.rs Normal file
View File

@ -0,0 +1,17 @@
#[no_mangle]
pub extern "C" fn _ostreesys_bump_mtime(fd: libc::c_int) -> libc::c_int {
let fd = unsafe { std::os::fd::BorrowedFd::borrow_raw(fd) };
let now = rustix::fs::Timespec {
tv_sec: 0,
tv_nsec: rustix::fs::UTIME_NOW,
};
let ts = rustix::fs::Timestamps {
last_access: now.clone(),
last_modification: now.clone(),
};
if let Err(e) = rustix::fs::utimensat(fd, "ostree/deploy", &ts, rustix::fs::AtFlags::empty()) {
e.raw_os_error().into()
} else {
0
}
}