Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
6e267c1
add rootless version of squashfs-mount
simonpintarelli Jun 10, 2026
fe8947f
add --priviledged flag for the container
simonpintarelli Jun 11, 2026
ae84494
move rootless code to src/uenv
simonpintarelli Jun 11, 2026
67e6746
fuse mount in the spank plugin
simonpintarelli Jun 11, 2026
1aae9eb
fix meson.build
simonpintarelli Jun 11, 2026
18983ed
update
simonpintarelli Jun 11, 2026
a984c11
fix cli
simonpintarelli Jun 11, 2026
19629f9
error msg and format
simonpintarelli Jun 11, 2026
46ffb7f
format
simonpintarelli Jun 11, 2026
7178b1a
format
simonpintarelli Jun 11, 2026
0dd727b
add missing version flag
simonpintarelli Jun 17, 2026
1fac641
install shared squashfuse
simonpintarelli Jun 17, 2026
733e279
error handling
simonpintarelli Jun 22, 2026
d4c0653
WIP: add --join
simonpintarelli Jun 25, 2026
d18cddf
update
simonpintarelli Jun 25, 2026
098fedc
cleanup comment
simonpintarelli Jun 25, 2026
4d6ae4d
forward join to squashfs-mount via uenv cli
simonpintarelli Jun 26, 2026
e48910c
option -> flag
simonpintarelli Jun 26, 2026
214a7b1
forward uenv -vvv to squashfs-mount call
simonpintarelli Jun 26, 2026
a80770c
update install script
simonpintarelli Jun 26, 2026
3be8b76
add missing pkg
simonpintarelli Jun 26, 2026
e022571
CI: add sudo
simonpintarelli Jun 26, 2026
6c9aca1
update meson
simonpintarelli Jun 26, 2026
8ce0b18
add jq to container
simonpintarelli Jun 26, 2026
56aa7cf
use fork + ns join in spank plugin
simonpintarelli Jun 29, 2026
c98aac2
exclude forked squashfs-mount process from join_begin/end
simonpintarelli Jun 30, 2026
8e39781
rename variable
simonpintarelli Jun 30, 2026
29bd93c
comments / rename variable
simonpintarelli Jun 30, 2026
d4851ef
remove #ifdef
simonpintarelli Jun 30, 2026
4ad79fe
cleanup includes
simonpintarelli Jun 30, 2026
d106dd0
remove ifdef
simonpintarelli Jun 30, 2026
5e8168a
remove unused header
simonpintarelli Jun 30, 2026
3454617
std::optional for winner_pid
simonpintarelli Jun 30, 2026
557d959
typo
simonpintarelli Jul 1, 2026
73277b6
add direct sqfs_ll version in plugin, cleanup
simonpintarelli Jul 1, 2026
9c03ad1
tmpfs_str -> tmpfs_arg, bind_mounts_str -> bind_mounts_arg
simonpintarelli Jul 2, 2026
a7fc8da
update docstrings
simonpintarelli Jul 2, 2026
1d3dce1
cleanup
simonpintarelli Jul 2, 2026
d78fd57
prtcl PR_SET_DUMPABLE
simonpintarelli Jul 2, 2026
b15d33a
sanity check for write/close/openat
simonpintarelli Jul 2, 2026
701d1c4
refactoring
simonpintarelli Jul 5, 2026
7d9a7bf
fix ns_join for setuid
simonpintarelli Jul 8, 2026
6afed54
cleanup
simonpintarelli Jul 9, 2026
dec2487
cleanup make_mutable_root
simonpintarelli Jul 9, 2026
f1b2363
format
simonpintarelli Jul 9, 2026
c068ee2
fuse plugin: missing args
simonpintarelli Jul 9, 2026
4ccb29e
skip remount of proc/sys/tmp
simonpintarelli Jul 10, 2026
2a25b17
don't skip `squashfs-mount -r`
simonpintarelli Jul 10, 2026
4aff578
disable mutable_root sandbox for setuid
simonpintarelli Jul 10, 2026
ed3f159
add comments
simonpintarelli Jul 10, 2026
af63c8a
remove some ifdefs
simonpintarelli Jul 10, 2026
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
9 changes: 9 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
root = true

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

How does this interact with clang format? Because we have clang format, most editors should automatically apply the formatting rules on save.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It's redundant. It was just to avoid the nuisance of 2 space indent (my default) when entering a new line.


[*.build]
indent_style = space
indent_size = 4

[*{,cpp,h}]
indent_style = space
indent_size = 4
37 changes: 31 additions & 6 deletions .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,56 @@ jobs:
- buildtype: release
sanitizer: address
runs-on: ubuntu-24.04
container:
image: ubuntu:noble
options: --privileged
steps:
- uses: actions/checkout@v6
- name: Update apt repositories for ccache
run: sudo apt update
run: apt update
- name: Install dependencies
run: sudo apt-get install util-linux libmount-dev libslurm-dev
run: apt-get install --no-install-recommends --yes util-linux libmount-dev libslurm-dev
# run: sudo apt-get install util-linux libmount-dev slurm-wlm libslurm-dev slurmd slurmctld slurm-client
- name: Set up ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
key: ccache-linux-${{ matrix.buildtype }}-${{ matrix.sanitizer }}
- name: Install compiler and build tools
run: sudo apt install --no-install-recommends --yes g++-12 ninja-build
run: |
apt install --no-install-recommends --yes \
g++-12 \
ninja-build \
libsquashfuse-dev \
libfuse3-dev \
wget \
ca-certificates \
python3 \
pkg-config \
sqlite3 \
git \
squashfs-tools \
curl \
ninja-build \
locales \
xxd \
jq \
sudo

locale-gen en_US.UTF-8
update-locale LANG=en_US.UTF-8
- name: install meson
run: |
wget https://github.com/mesonbuild/meson/releases/download/1.4.0/meson-1.4.0.tar.gz && \
tar -xzf meson-1.4.0.tar.gz && \
mv meson-1.4.0 meson && \
wget https://github.com/mesonbuild/meson/releases/download/1.11.1/meson-1.11.1.tar.gz && \
tar -xzf meson-1.11.1.tar.gz && \
mv meson-1.11.1 meson && \
mv meson/meson.py meson/meson
- name: Configure
run: |
CC="ccache gcc-12" CXX="ccache g++-12" ./meson/meson setup \
--buildtype ${{ matrix.buildtype }} \
-Db_sanitize=${{ matrix.sanitizer }} \
-Dtests=enabled \
-Dfuse=true \
-Dsquashfs_mount=true \
--warnlevel 3 \
--werror \
Expand Down
55 changes: 52 additions & 3 deletions install-alps-local.sh
Original file line number Diff line number Diff line change
@@ -1,11 +1,60 @@
#!/bin/bash

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I was thinking about removing this completely, because it is not up to date.

There is a meson wrap db for zstd: https://mensinda.github.io/meson/Wrapdb-projects.html


set -e
set -eu

squashfuse_version=0.6.2
zstd_version=1.5.7

# build static dependencies
(
cd extern/
if [ ! -d "zstd-${zstd_version}/install/lib/pkgconfig" ]; then
(
curl -L https://github.com/facebook/zstd/releases/download/v${zstd_version}/zstd-${zstd_version}.tar.gz | tar xzf -
cd zstd-${zstd_version}/build/meson
CXX=g++-12 CC=gcc-12 uvx --with=meson,ninja \
meson setup \
--buildtype=release \
-Dbin_programs=true \
-Dbin_contrib=true \
--prefix=$PWD/../../install \
--wipe builddir
uvx --with=meson,ninja ninja -C builddir install
cd ../../install
# squashfuse expects a lib dir
ln -sf lib64 lib
)
fi
export ZSTD=$(realpath zstd-${zstd_version}/install)

if [ ! -d "squashfuse-${squashfuse_version}/install/lib/pkgconfig" ]; then
(
curl -L https://github.com/vasi/squashfuse/releases/download/${squashfuse_version}/squashfuse-${squashfuse_version}.tar.gz | tar xzf -

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should we be trying to use squashfuse available on Alps systems? The container team install a version from RPM.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

squashfuse on alps is 0.5.1. The latest release is 0.6.2.

It is linked to fuse2:

[daint][simonpi@daint-ln001 ~]$ ldd /usr/lib64/libsquashfuse_ll.so.0
	linux-vdso.so.1 (0x000040001c560000)
	libz.so.1 => /usr/lib64/libz.so.1 (0x000040001c5b0000)
	liblzma.so.5 => /usr/lib64/liblzma.so.5 (0x000040001c5f0000)
	liblzo2.so.2 => /usr/lib64/liblzo2.so.2 (0x000040001c650000)
	liblz4.so.1 => /usr/lib64/liblz4.so.1 (0x000040001c690000)
	libzstd.so.1 => /usr/lib64/libzstd.so.1 (0x000040001c6e0000)
	libfuse.so.2 => /lib64/libfuse.so.2 (0x000040001c7b0000)
	libc.so.6 => /lib64/libc.so.6 (0x000040001c810000)
	/lib/ld-linux-aarch64.so.1 (0x000040001c4f0000)
	libdl.so.2 => /lib64/libdl.so.2 (0x000040001c9d0000)
	libpthread.so.0 => /lib64/libpthread.so.0 (0x000040001ca00000)
``

Afaik the multithreaded version requires fuse3.

cd squashfuse-${squashfuse_version}

# patch includedir in pkg-config
sed -i 's/^includedir=.*/includedir=@includedir@/' squashfuse.pc.in
sed -i 's/^includedir=.*/includedir=@includedir@/' squashfuse_ll.pc.in

./configure --disable-high-level \
--enable-static=no \
--enable-shared=yes \
--without-lzo \
--without-lz4 \
--with-zstd=$ZSTD \
--prefix=$PWD/install
make install
)
fi
)

PKG_CONFIG_PATH=$(realpath extern/zstd-${zstd_version}/install/lib/pkgconfig):$(realpath extern/squashfuse-${squashfuse_version}/install/lib/pkgconfig):${PKG_CONFIG_PATH:-}
export PKG_CONFIG_PATH

arch=$(uname -m)
echo "== architecture: $arch"

root=$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd)
root=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
build=$root/build-alps-$arch
pyenv=$root/pyenv-alps-$arch
install=$HOME/.local/$arch
Expand All @@ -17,7 +66,7 @@ echo "== configure in $build"

export CC=gcc-12
export CXX=g++-12
uvx --with meson,ninja meson setup --prefix=$install $build $root
uvx --with meson,ninja meson setup -Dsquashfs_mount=true -Dfuse=true --prefix=$install $build $root
uvx --with meson,ninja meson compile -C$build
uvx --with meson,ninja meson install -C$build --skip-subprojects

Expand Down
69 changes: 54 additions & 15 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ oras_version = get_option('oras_version')
uenv_slurm_plugin = get_option('slurm_plugin')
uenv_cli = get_option('cli')
uenv_squashfs_mount = get_option('squashfs_mount')

conf_data = configuration_data()

add_global_arguments('-Wno-missing-field-initializers', language : 'cpp')
Expand Down Expand Up @@ -47,6 +46,7 @@ barkeep_dep = declare_dependency(

libmount_dep = dependency('mount')


# the lib dependency is all of the common funtionality shared between the CLI
# and the slurm plugin.
lib_src = [
Expand All @@ -58,7 +58,9 @@ lib_src = [
'src/uenv/mount.cpp',
'src/uenv/oras.cpp',
'src/uenv/parse.cpp',
'src/uenv/posix_io.cpp',
'src/uenv/print.cpp',
'src/uenv/ns_join.cpp',
'src/uenv/repository.cpp',
'src/uenv/settings.cpp',
'src/uenv/telemetry.cpp',
Expand All @@ -76,18 +78,43 @@ lib_src = [
'src/util/subprocess.cpp',
'src/util/toml.cpp',
]
use_fuse = get_option('fuse')

if use_fuse
fuse_version = get_option('fuse_version')
if fuse_version == '2'
fuse_dep = dependency('fuse', required: true)
elif fuse_version == '3'
fuse_dep = dependency('fuse3', required: true)
else
error('fuse_version must be 2 or 3')
endif
squashfuse_dep = dependency('squashfuse_ll', static: false)
endif



if use_fuse
lib_src += ['src/uenv/rootless.cpp']
# dependencies += [squashfuse_dep, fuse_dep]
endif

lib_inc = include_directories('src')

uenv_deps = [curl_dep, sqlite3_dep, fmt_dep, spdlog_dep, json_dep, barkeep_dep, toml_dep]
if use_fuse
uenv_deps += [squashfuse_dep, fuse_dep]
endif
lib_uenv = static_library(
'uenv',
lib_src,
include_directories: lib_inc,
dependencies: [curl_dep, sqlite3_dep, fmt_dep, spdlog_dep, json_dep, barkeep_dep, toml_dep],
'uenv',
lib_src,
include_directories: lib_inc,
dependencies: uenv_deps,
)

uenv_dep = declare_dependency(
link_with: lib_uenv,
dependencies: [curl_dep, sqlite3_dep, fmt_dep, spdlog_dep, json_dep, barkeep_dep, libmount_dep, toml_dep],
link_with: lib_uenv,
dependencies: [curl_dep, sqlite3_dep, fmt_dep, spdlog_dep, json_dep, barkeep_dep, libmount_dep, toml_dep],
include_directories: lib_inc
)

Expand Down Expand Up @@ -163,14 +190,26 @@ if uenv_slurm_plugin
endif

if uenv_squashfs_mount
squashfs_mount = executable('squashfs-mount',
sources: ['src/squashfs-mount/squashfs-mount.cpp'],
dependencies: [uenv_dep, fmt_dep, cli11_dep],
c_args: [
'-DVERSION="@0@"'.format(version),
],
install_mode: ['rwsr-xr-x', 'root', 'root'],
install: true)
if get_option('fuse')
squashfs_mount_build = executable('squashfs-mount',
sources: ['src/squashfs-mount/squashfs-mount.cpp'],
dependencies: [uenv_dep, fmt_dep, cli11_dep, squashfuse_dep, fuse_dep],
cpp_args: [
'-DVERSION="@0@"'.format(version),
'-DUENV_FUSE_MOUNT=1',
],
install: true
)
else
squashfs_mountd = executable('squashfs-mount',
sources: ['src/squashfs-mount/squashfs-mount.cpp'],
dependencies: [uenv_dep, fmt_dep, cli11_dep],
cpp_args: [
'-DVERSION="@0@"'.format(version),
],
install_mode: ['rwsr-xr-x', 'root', 'root'],
install: true)
endif
endif

if get_option('tests').enabled()
Expand Down
3 changes: 2 additions & 1 deletion meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ option('tests', type: 'feature', value: 'disabled')
option('slurm_plugin', type: 'boolean', value: true)
option('cli', type: 'boolean', value: true)
option('squashfs_mount', type: 'boolean', value: false)

option('fuse', type: 'boolean', value: false)
option('fuse_version', type: 'string', value: '3')
option('oras_version', type: 'string', value: '1.2.0')
#option('slurm_version', type: 'string', value: '24.05.0')
option('slurm_version', type: 'string', value: '0.00.0')
8 changes: 6 additions & 2 deletions src/cli/run.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ void run_args::add_cli(CLI::App& cli, global_settings& settings) {
auto* run_cli = cli.add_subcommand("run", "run a uenv session");
run_cli->add_option("-v,--view", view_description,
"comma separated list of views to load");
run_cli->add_flag("-j,--join", join,
"comma separated list of views to load");
run_cli
->add_option("uenv", uenv_description,
"comma separated list of uenv to mount")
Expand All @@ -34,6 +36,7 @@ void run_args::add_cli(CLI::App& cli, global_settings& settings) {
->add_option("commands", commands,
"the command to run, including with arguments")
->required();

run_cli->add_flag(
"-V,--no-default-view", disable_default_view,
"disable loading default views when no view is specified");
Expand Down Expand Up @@ -86,8 +89,9 @@ You need to finish the current session by typing 'exit' or hitting '<ctrl-d>'.)"
m.second.mount_path));
}

const auto commands = uenv::squashfs_mount_args(
settings.calling_environment, mounts, args.commands);
const auto commands =
uenv::squashfs_mount_args(settings.calling_environment, mounts,
args.join, settings.verbose, args.commands);

auto c_env = runtime_environment.c_env();
auto error = util::exec(commands, c_env);
Expand Down
1 change: 1 addition & 0 deletions src/cli/run.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ void run_help();
struct run_args {
std::string uenv_description;
std::optional<std::string> view_description;
bool join = false;
std::vector<std::string> commands;
bool disable_default_view = false;
void add_cli(CLI::App&, global_settings& settings);
Expand Down
3 changes: 2 additions & 1 deletion src/cli/start.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,8 @@ will not work, because it starts a new interactive shell.)",
}

const auto commands = uenv::squashfs_mount_args(
settings.calling_environment, mounts, {shell->string()});
settings.calling_environment, mounts, false /* join */,
settings.verbose, {shell->string()});

auto c_env = runtime_environment.c_env();
auto error = util::exec(commands, c_env);
Expand Down
12 changes: 10 additions & 2 deletions src/cli/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,17 @@ bool sqfs_mount_v9(const envvars::state& calling_environment) {

std::vector<std::string>
squashfs_mount_args(const envvars::state& calling_environment,
const std::vector<std::string>& mounts,
const std::vector<std::string>& args) {
const std::vector<std::string>& mounts, bool join,
int verbosity, const std::vector<std::string>& args) {
std::vector<std::string> commands = {"squashfs-mount"};
if (join) {
commands.push_back("--join");
}

if (verbosity > 0) {
commands.push_back("-" + std::string(verbosity, 'v'));
}

if (!sqfs_mount_v9(calling_environment)) {
for (auto& m : mounts) {
commands.push_back(m);
Expand Down
4 changes: 2 additions & 2 deletions src/cli/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ validate_squashfs_image(const std::string& path);

std::vector<std::string>
squashfs_mount_args(const envvars::state& calling_environment,
const std::vector<std::string>& mounts,
const std::vector<std::string>& args);
const std::vector<std::string>& mounts, bool join,
int verbosity, const std::vector<std::string>& args);

} // namespace uenv

Expand Down
9 changes: 8 additions & 1 deletion src/slurm/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,15 @@ module_src = [
'plugin.cpp',
]

cpp_args_list = ['-Wall', '-Wpedantic', '-Wextra']
if use_fuse
module_src += ['plugin_fuse.cpp']
cpp_args_list += ['-DUENV_FUSE']
endif


shared_module('slurm-uenv-mount',
sources: module_src,
dependencies: [uenv_dep, slurm_dep],
cpp_args: ['-Wall', '-Wpedantic', '-Wextra'],
cpp_args: cpp_args_list,
install: true)
Loading
Loading