Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
d7dfded
[rust] Add rust root
tobe2098 Dec 8, 2025
a434e2e
[rust] Add procedural macros crate
tobe2098 Dec 18, 2025
68714b7
[rust] Add skeleton petname crate
tobe2098 Dec 18, 2025
e4b721e
[petname] Implement petname in rust
tobe2098 Dec 18, 2025
fa41640
[petname] Remove old source files
tobe2098 Jan 7, 2026
56b61ac
[petname] Add new petname implementation
tobe2098 Jan 7, 2026
617816c
[rust] Add clean target for rust builds
tobe2098 Jan 7, 2026
2f53b43
[petname] Minimize sources of truth for params
tobe2098 Jan 7, 2026
6bca1f2
[tests] Add petname module tests
tobe2098 Jan 8, 2026
ac0adaf
[tests] Add petname rust integration tests
tobe2098 Jan 8, 2026
5a2db1c
[ci] Add Rust CI and coverage build
tobe2098 Jan 8, 2026
9fdbfe6
[tests] Set test executable to multipass_cpp_tests
tobe2098 Jan 12, 2026
fe10f8b
[petname] Improve petname implementation
tobe2098 Jan 13, 2026
5cf3660
[tests] Move to new testing paradigm in Rust
tobe2098 Jan 13, 2026
b1af39b
[fflags] Add feature flag support
tobe2098 Jan 13, 2026
64a252b
[docs] Update installation documentation
tobe2098 Jan 14, 2026
fc71f51
[rust] Change build folder to build/rxx
tobe2098 Jan 19, 2026
7fac699
[cmake] Solve cmake dependency
tobe2098 Jan 27, 2026
a4eae3f
[petname] Fix c_char ABI incompatibility
tobe2098 Jan 27, 2026
8957684
[petname] Simplify petname implementation
tobe2098 Mar 20, 2026
27496d2
[petname] Revert naming convention change
tobe2098 Mar 23, 2026
2a00827
[petname] Add explanatory comments
tobe2098 Mar 31, 2026
18426d9
[fix] Address review comments
tobe2098 Apr 16, 2026
bcd99e2
[ci][cmake] Add verbose flag and uppercase vars
tobe2098 Apr 17, 2026
c40e15c
[ci] Enable macOS coredump upload in Rust
tobe2098 Apr 20, 2026
c9c4f73
[snap] Update snapcraft for Rust install
tobe2098 Apr 21, 2026
ec273aa
[cargo] Change optimization profiles
tobe2098 Apr 22, 2026
1fcffbb
[snap] Move jq to CI override
tobe2098 Apr 22, 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
36 changes: 26 additions & 10 deletions .github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -222,20 +222,26 @@ jobs:
if: ${{ matrix.build-type == 'Debug' }}
timeout-minutes: 2
run: |

trap 'echo "MULTIPASS_TESTS_EXIT_CODE=$?" >> $GITHUB_ENV' EXIT
instance_name=`/snap/bin/lxc --project snapcraft --format=csv --columns=n list | grep multipass`
instance_name=$(/snap/bin/lxc --project snapcraft --format=csv --columns=n list | grep multipass)
trap '
EXIT_STATUS=$?
echo "MULTIPASS_TESTS_EXIT_CODE=$EXIT_STATUS" >> $GITHUB_ENV
# Check if any files were generated in /cores/
if /snap/bin/lxc --project snapcraft exec "$instance_name" -- bash -c "[ \"\$(ls -A /coredump 2>/dev/null)\" ]"; then
echo "CORE_DUMPS_FOUND=true" >> $GITHUB_ENV
fi
' EXIT
/snap/bin/lxc --project snapcraft start $instance_name
# Let's print the core pattern so we can check if it's successfully propagated to the container.
/snap/bin/lxc --project snapcraft exec $instance_name -- bash -c 'cat /proc/sys/kernel/core_pattern'
# Create the directory for the coredumps
/snap/bin/lxc --project snapcraft exec $instance_name -- bash -c 'mkdir -p /coredump'
# Create the directory for the coredumps and ensure the directory is empty
/snap/bin/lxc --project snapcraft exec $instance_name -- bash -c 'mkdir -p /coredump && rm -f /coredump/*'
# Enable coredumps by setting the core dump size to "unlimited", and run the tests.
/snap/bin/lxc --project snapcraft exec $instance_name -- bash -c "\
cd /root/parts/multipass/build && \
ulimit -c unlimited && \
env CTEST_OUTPUT_ON_FAILURE=1 \
LD_LIBRARY_PATH=/root/stage/usr/lib/x86_64-linux-gnu/:/root/stage/lib/:/root/parts/multipass/build/lib/ \
/root/parts/multipass/build/bin/multipass_tests"
ctest -V"

- name: Measure coverage
id: measure-coverage
Expand Down Expand Up @@ -279,7 +285,7 @@ jobs:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

- name: Pull coredump and executable from LXC container
if: ${{ failure() && env.MULTIPASS_TESTS_EXIT_CODE != '0'}}
if: ${{ failure() && env.MULTIPASS_TESTS_EXIT_CODE != '0' && env.CORE_DUMPS_FOUND }}
# do not cause job to fail if there are no coredumps available.
continue-on-error: true
run: |
Expand All @@ -294,16 +300,26 @@ jobs:
instance_name=`/snap/bin/lxc --project snapcraft --format=csv --columns=n list | grep multipass`
# Pull the crashed executable from the container
/snap/bin/lxc --project snapcraft file pull \
-p -r "$instance_name/root/parts/multipass/build/bin/multipass_tests" /tmp/coredump/multipass_tests
-p -r "$instance_name/root/parts/multipass/build/bin/multipass_cpp_tests" /tmp/coredump/multipass_cpp_tests
echo "Pulled the executable."
# Pull the coredump folder
/snap/bin/lxc --project snapcraft file pull -p -r "$instance_name/coredump" /tmp/coredump
echo "Pulled the coredumps folder."

mapfile -t BINS < <(/snap/bin/lxc --project snapcraft exec "$instance_name" -- bash -c "
cd /root/parts/multipass/src/rxx
cargo test --workspace --no-run --message-format=json --target-dir /root/parts/multipass/build/rxx | \
jq -r 'select(.reason == \"compiler-artifact\" and .executable != null) | .executable'
")
for bin in "${BINS[@]}"; do
/snap/bin/lxc --project snapcraft file pull -p -r "$instance_name/$bin" "/tmp/coredump/$(basename "$bin")"
done
echo "Pulled the rust executables"
set +o xtrace

- name: Upload test coredump
uses: actions/upload-artifact@v7
if: ${{ failure() && env.MULTIPASS_TESTS_EXIT_CODE != '0' }}
if: ${{ failure() && env.MULTIPASS_TESTS_EXIT_CODE != '0' && env.CORE_DUMPS_FOUND }}
with:
name: buildandtest-test-crash-${{ runner.os }}-${{ matrix.build-type }}
path: /tmp/coredump/**
Expand Down
52 changes: 46 additions & 6 deletions .github/workflows/macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ jobs:
env:
BUILD_DIR: ${{ github.workspace }}/build
SCCACHE_DIR: ${{ github.workspace }}/.sccache
RUST_DIR: ${{ github.workspace }}/rxx
RUSTC_WRAPPER: "sccache"

steps:
Expand Down Expand Up @@ -110,6 +111,9 @@ jobs:
mkdir -p ~/.pip
echo -e "[install]\nbreak-system-packages = true" > ~/.pip/pip.conf

- name: Set up Rust
uses: dtolnay/rust-toolchain@stable

- name: Install dependencies from brew
run: |
# Avoid reinstalling cmake
Expand Down Expand Up @@ -229,16 +233,42 @@ jobs:
- name: Build
run: cmake --build ${{ env.BUILD_DIR }}

- name: Collect rust binary paths
working-directory: ${{ env.RUST_DIR }}
run: |
{
echo 'RUST_EXEC_PATHS<<__EOF__'
cargo test --workspace --no-run --message-format=json --target-dir ${{ env.BUILD_DIR }}/rxx \
| jq -r 'select(.reason == "compiler-artifact" and .executable != null) | .executable' \
| while IFS= read -r exe; do
[ -n "$exe" ] && echo "$exe"
done
echo '__EOF__'
} >> "$GITHUB_ENV"

- name: Enable core dump generation
working-directory: ${{ env.BUILD_DIR }}
shell: bash
run : |
# Allow core dumps
sudo sysctl -w kern.coredump=1
# Force core dump location/pattern to match the upload step expectations
sudo sysctl -w kern.corefile=/cores/core.%P
# This entitlement is needed for a proc to produce a coredump
/usr/libexec/PlistBuddy -c "Add :com.apple.security.get-task-allow bool true" segv.entitlements
# Code-sign the test executable to grant core dump entitlement
codesign -s - -f --entitlements segv.entitlements bin/multipass_tests
codesign -s - -f --entitlements segv.entitlements bin/multipass_cpp_tests

RUST_EXECUTABLES=()
while IFS= read -r line; do
[[ -n "$line" ]] || continue
RUST_EXECUTABLES+=("$line")
done <<< "$RUST_EXEC_PATHS"
for RUST_EXEC in "${RUST_EXECUTABLES[@]}";
do
codesign -s - -f --entitlements segv.entitlements "$RUST_EXEC"
done

# Ensure destination exists and is writable
sudo mkdir -p /cores || true
sudo chmod 1777 /cores
Expand All @@ -250,21 +280,31 @@ jobs:
- name: Test
working-directory: ${{ env.BUILD_DIR }}
run: |
# Catch and save the test executable's exit code
trap 'echo "MULTIPASS_TESTS_EXIT_CODE=$?" >> $GITHUB_ENV' EXIT
# Define the trap to catch the exit code AND check for core dumps
trap '
EXIT_STATUS=$?
echo "MULTIPASS_TESTS_EXIT_CODE=$EXIT_STATUS" >> $GITHUB_ENV
# Check if any files were generated in /cores/
if [ "$(ls -A /cores/ 2>/dev/null)" ]; then
echo "CORE_DUMPS_FOUND=true" >> $GITHUB_ENV
fi
' EXIT
# Clean existing core dumps for coredump detection
sudo rm -f /cores/*
# Set soft limit for the core file size (512MiB)
ulimit -c 1048576
bin/multipass_tests
ctest -V

- name: Upload test coredump
uses: actions/upload-artifact@v7
if: ${{ failure() && env.MULTIPASS_TESTS_EXIT_CODE != '0' }}
if: ${{ failure() && env.MULTIPASS_TESTS_EXIT_CODE != '0' && env.CORE_DUMPS_FOUND }}
with:
name: buildandtest-test-crash-${{ matrix.runs-on }}-${{ matrix.build-type }}
retention-days: 7
path: |
/cores/**
${{ env.BUILD_DIR }}/bin/multipass_tests
${{ env.BUILD_DIR }}/bin/multipass_cpp_tests
${{ env.RUST_EXEC_PATHS }}

- name: Package
id: cmake-package
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ jobs:
id: build-params
uses: ./.github/actions/build-params

- name: Set up Rust
uses: dtolnay/rust-toolchain@stable

- name: Install specific QEMU from Choco
uses: crazy-max/ghaction-chocolatey@v4
with:
Expand Down Expand Up @@ -176,7 +179,7 @@ jobs:
- name: Test
working-directory: ${{ env.BUILD_DIR }}
run: |
bin/multipass_tests
ctest -V

- name: Package
id: cmake-package
Expand Down
7 changes: 7 additions & 0 deletions BUILD.linux.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ sudo apt install devscripts equivs
mk-build-deps -s sudo -i
```

### Install the Rust compiler

Go [here](https://rust-lang.org/tools/install/) for the most recent method. The current method is:
```
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable
```

## Building

First, go into the repository root and get all the submodules:
Expand Down
7 changes: 7 additions & 0 deletions BUILD.macOS.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ means to obtain cmake is with Homebrew <https://brew.sh/>.

brew install cmake

### Rust compiler

To build multipass you will need the rust compiler. It can be installed using brew:
```
brew install rustup
```

Building
---------------------------------------

Expand Down
4 changes: 2 additions & 2 deletions BUILD.windows.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ After chocolatey is installed you can now install the rest of the dependencies f
Powershell(Admin). To get the best results, in the following order:

```[pwsh]
choco install cmake ninja qemu-img git wget unzip -yfd
choco install cmake ninja qemu-img git wget unzip rustup.install -yfd
```

```[pwsh]
Expand Down Expand Up @@ -140,7 +140,7 @@ Finally, to build the project, run:
cmake --build . --parallel
```

This builds `multipass`, `multipassd`, and `multipass_tests`.
This builds `multipass`, `multipassd`, and `multipass_cpp_tests`.
To create an installer, run `cmake --build . --target package`.

## Running `multipass`
Expand Down
21 changes: 13 additions & 8 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -174,25 +174,25 @@ if(MULTIPASS_ENABLE_FLUTTER_GUI)
set(DART_PROTOC_PLUGIN ${CMAKE_SOURCE_DIR}/3rd-party/protobuf.dart/protoc_plugin/bin/protoc_plugin.exe)
endif(MULTIPASS_ENABLE_FLUTTER_GUI)

string(TOLOWER "${CMAKE_BUILD_TYPE}" cmake_build_type_lower)
string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER)

if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
add_definitions(-DMULTIPASS_COMPILER_CLANG)

if(cmake_build_type_lower MATCHES "asan")
if(CMAKE_BUILD_TYPE_LOWER MATCHES "asan")
add_compile_options(-fno-omit-frame-pointer -fsanitize=address)
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=address")
elseif(cmake_build_type_lower MATCHES "ubsan")
elseif(CMAKE_BUILD_TYPE_LOWER MATCHES "ubsan")
add_compile_options(-fno-omit-frame-pointer -fsanitize=undefined)
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=undefined")
elseif(cmake_build_type_lower MATCHES "tsan")
elseif(CMAKE_BUILD_TYPE_LOWER MATCHES "tsan")
add_compile_options(-fno-omit-frame-pointer -fsanitize=thread)
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=thread")
endif()
endif()

# these we want to apply even to 3rd-party
if(cmake_build_type_lower MATCHES "coverage")
if(CMAKE_BUILD_TYPE_LOWER MATCHES "coverage")
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
add_compile_options(--coverage)
if(COMMAND add_link_options)
Expand Down Expand Up @@ -315,7 +315,7 @@ else()
endif()
endif()

if(cmake_build_type_lower MATCHES "coverage")
if(CMAKE_BUILD_TYPE_LOWER MATCHES "coverage")
find_program(GCOV gcov)
find_program(LCOV lcov)
find_program(GENHTML genhtml)
Expand All @@ -337,7 +337,7 @@ if(cmake_build_type_lower MATCHES "coverage")
endif()

add_custom_target(covreport
DEPENDS multipass_tests
DEPENDS multipass_cpp_tests rust_coverage_tarpaulin
WORKING_DIRECTORY ${CMAKE_BUILD_DIR}
COMMAND ${LCOV} --directory . --zerocounters
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target test
Expand All @@ -351,7 +351,9 @@ if(cmake_build_type_lower MATCHES "coverage")
${CMAKE_BINARY_DIR}'/*'
--output-file coverage.cleaned
COMMAND ${CMAKE_COMMAND} -E remove coverage.info
COMMAND ${GENHTML} -o coverage coverage.cleaned
COMMAND ${CMAKE_COMMAND} -E remove coverage.info
COMMAND ${LCOV} -a coverage.cleaned -a lcov.info -o total_coverage.info
COMMAND ${GENHTML} -o coverage total_coverage.info
)
endif()
endif()
Expand All @@ -371,6 +373,9 @@ if(MULTIPASS_ENABLE_TESTS)
add_subdirectory(tests/unit)
endif()

#Added later to be compatible with enable_testing() above
add_subdirectory(rxx)

include(packaging/cpack.cmake OPTIONAL)

# Disable .clang-tidy in build folder
Expand Down
34 changes: 33 additions & 1 deletion include/multipass/name_generator.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,37 @@ class NameGenerator : private DisabledCopyMove
NameGenerator() = default;
};

NameGenerator::UPtr make_default_name_generator();
namespace petname
{
enum NumWords
{
One,
Two,
Three,
};
template <char S>
concept IsValidSeparator = (S == '-' || S == '_');

namespace detail
{
NameGenerator::UPtr make_petname_provider_impl(NumWords num_words, char separator);
} // namespace detail

// Templated functions to avoid exposing the PetnameProvider type in the interface header with
// the default arguments. The templates ensure the argument checks are done at compile-time.
template <NumWords NW = NumWords::Two, char S = '-'>
requires IsValidSeparator<S>
NameGenerator::UPtr make_petname_provider()
{
return detail::make_petname_provider_impl(NW, S);
};

template <char S>
requires IsValidSeparator<S>
NameGenerator::UPtr make_petname_provider()
{
return detail::make_petname_provider_impl(NumWords::Two, S);
}
} // namespace petname

} // namespace multipass
2 changes: 1 addition & 1 deletion packaging/cpack.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ if (MSVC)
# and creats an install(PROGRAMS ...) rule using the destination and component IDs setup below.
set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION bin)
set(CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT multipassd)
if(cmake_build_type_lower STREQUAL "debug")
if(CMAKE_BUILD_TYPE_LOWER STREQUAL "debug")
set(CMAKE_INSTALL_DEBUG_LIBRARIES TRUE)
set(CMAKE_INSTALL_UCRT_LIBRARIES TRUE)
endif()
Expand Down
5 changes: 5 additions & 0 deletions packaging/gui-less/snap/snapcraft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,11 @@ parts:
override-pull: |
set -e

if ! snap list rustup >/dev/null 2>&1; then
snap install rustup --classic
rustup default stable
fi

# https://github.com/microsoft/vcpkg/issues/37279
# vcpkg-systemd: required for meson.build
python3 -m pip install --break-system-packages jinja2
Expand Down
Loading
Loading