Skip to content

Commit 900d7e3

Browse files
authored
feat: merge pulled container layers into a single rootfs dir (#28)
* feat: [ongoing] overlayfs merge * feat: fix some permissions issues around copying non-writable or non-readable files/dirs * feat: fixing permissions - ongoing * feat: the first permissionguard solution * refactor(overlayfs): improve permission handling during layer merging - Replace ad-hoc permission management with PermissionGuard struct - Add support for nested directory structures with mixed permissions - Improve permission restoration with ordered tracking - Add more comprehensive test cases for permission scenarios - Clean up error handling and logging * fix: put linux support temporarily on hold
1 parent 04444f9 commit 900d7e3

30 files changed

+2475
-606
lines changed

.github/workflows/tests_and_checks.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,4 +221,7 @@ jobs:
221221
run: |
222222
LIBRARY_PATH=${{ github.workspace }}/build/libkrunfw:${{ github.workspace }}/build/libkrun/target/release:${{ env.LIBRARY_PATH }} \
223223
LD_LIBRARY_PATH=${{ github.workspace }}/build/libkrunfw:${{ github.workspace }}/build/libkrun/target/release:${{ env.LD_LIBRARY_PATH }} \
224-
cargo test --all-features
224+
cargo test --all-features && \
225+
LIBRARY_PATH=${{ github.workspace }}/build/libkrunfw:${{ github.workspace }}/build/libkrun/target/release:${{ env.LIBRARY_PATH }} \
226+
LD_LIBRARY_PATH=${{ github.workspace }}/build/libkrunfw:${{ github.workspace }}/build/libkrun/target/release:${{ env.LD_LIBRARY_PATH }} \
227+
cargo test --all-features -- --ignored

.todo.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## monofs
2+
3+
- [ ] Implement tombstone for deletes.

Cargo.lock

Lines changed: 66 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

monocore/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ typed-path.workspace = true
5858
uuid.workspace = true
5959
xattr.workspace = true
6060
sysinfo = "0.32.0"
61+
nix = { version = "0.29", features = ["mount", "user", "fs"] }
62+
tar = "0.4"
63+
flate2 = "1.0"
64+
walkdir = "2.4"
65+
scopeguard = "1.2"
6166

6267
[dev-dependencies]
6368
test-log.workspace = true

monocore/Makefile

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ PREFIX ?= /usr/local
1212
MONOCORE_RELEASE_BIN := ../target/release/monocore
1313
MONOKRUN_RELEASE_BIN := ../target/release/monokrun
1414
EXAMPLES_DIR := ../target/release/examples
15-
FIXTURES_DIR := fixtures
16-
DISTRO_ROOTFS := rootfs-alpine
1715
BUILD_DIR := build
1816
BENCHES_DIR := ../target/release
1917

@@ -22,7 +20,7 @@ DARWIN_LIB_PATH := /usr/local/lib
2220
LINUX_LIB_PATH := /usr/local/lib64
2321

2422
# Phony targets
25-
.PHONY: all install clean example unpack_rootfs bench build_monokrun
23+
.PHONY: all install clean example bench build_monokrun
2624

2725
# Default target
2826
all: $(MONOCORE_RELEASE_BIN)
@@ -53,16 +51,8 @@ clean:
5351
cargo clean
5452
rm -rf $(BUILD_DIR)
5553

56-
# Unpack rootfs
57-
unpack_rootfs: $(BUILD_DIR)/$(DISTRO_ROOTFS)-$(ARCH)
58-
59-
$(BUILD_DIR)/$(DISTRO_ROOTFS)-$(ARCH): $(FIXTURES_DIR)/$(DISTRO_ROOTFS)-$(ARCH).tar.gz
60-
mkdir -p $(BUILD_DIR)/$(DISTRO_ROOTFS)-$(ARCH)
61-
tar -xzf $< -C $(BUILD_DIR)
62-
touch $@
63-
6454
# Run examples
65-
example: build_monokrun unpack_rootfs
55+
example: build_monokrun
6656
@if [ -z "$(word 2,$(MAKECMDGOALS))" ]; then \
6757
echo "Usage: make example <example_name> [-- <args>]"; \
6858
exit 1; \
@@ -74,9 +64,9 @@ _run_example:
7464
ifeq ($(OS),Darwin)
7565
cargo build --example $(EXAMPLE_NAME) --release
7666
codesign --entitlements monocore.entitlements --force -s - $(EXAMPLES_DIR)/$(EXAMPLE_NAME)
77-
DYLD_LIBRARY_PATH=$(DARWIN_LIB_PATH):$$RUST_DYLD_LIBRARY_PATH $(EXAMPLES_DIR)/$(EXAMPLE_NAME) $(ARGS) || exit $$?
67+
RUST_BACKTRACE=1 DYLD_LIBRARY_PATH=$(DARWIN_LIB_PATH):$$RUST_DYLD_LIBRARY_PATH $(EXAMPLES_DIR)/$(EXAMPLE_NAME) $(ARGS) || exit $$?
7868
else
79-
LD_LIBRARY_PATH=$(LINUX_LIB_PATH):$$LD_LIBRARY_PATH cargo run --example $(EXAMPLE_NAME) --release -- $(ARGS) || exit $$?
69+
RUST_BACKTRACE=1 LD_LIBRARY_PATH=$(LINUX_LIB_PATH):$$LD_LIBRARY_PATH cargo run --example $(EXAMPLE_NAME) --release -- $(ARGS) || exit $$?
8070
endif
8171

8272
# Run benchmarks

monocore/README.md

Lines changed: 10 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
- [Directory Structure](#directory-structure)
2626
- [Quick Start](#quick-start)
2727
- [Development](#development)
28-
- [Contributing](#contributing)
2928
- [License](#license)
3029

3130
## Features
@@ -71,15 +70,13 @@ graph TD
7170
oci_layer --> oci_layer_hash["[hash]"]
7271
7372
monocore_root --> microvm[microvm/]
74-
microvm --> microvm_tag["[repo-name]__[tag]/"]
75-
microvm --> microvm_instance["[repo-name]__[tag]__[uuid]/"]
76-
microvm_tag --> microvm_service[service.toml]
77-
microvm_tag --> microvm_cid["[repo-name]__[tag].cid"]
78-
microvm_tag --> microvm_rootfs[rootfs/]
79-
microvm_instance --> microvm_instance_rootfs[rootfs/]
73+
microvm --> microvm_service["[service-name]/"]
74+
microvm_service --> microvm_toml[service.toml]
75+
microvm_service --> microvm_cid["[service-name].cid"]
76+
microvm_service --> microvm_rootfs[rootfs/]
8077
8178
monocore_root --> run[run/]
82-
run --> run_service["[service-name]__[supervisor-pid].json"]
79+
run --> run_service["[service-name]__[pid].json"]
8380
8481
monocore_root --> log[log/]
8582
log --> log_stderr["[service-name].stderr.log"]
@@ -137,19 +134,9 @@ async fn main() -> anyhow::Result<()> {
137134

138135
### Prerequisites
139136
- Rust toolchain (1.75+)
140-
- libkrun development files
141-
142-
### Building
143-
```bash
144-
# Build the library
145-
cargo build
146-
147-
# Run tests
148-
cargo test
149-
150-
# Try an example
151-
cargo run --example microvm_shell
152-
```
137+
- libkrun (see [monocore/README.md](http://github.com/appcypher/monocore#setup))
138+
- Linux OS for full functionality (OverlayFS support)
139+
- macOS users should use Docker Desktop or a Linux VM for development
153140

154141
### Examples
155142
The `examples/` directory showcases key features:
@@ -158,14 +145,8 @@ The `examples/` directory showcases key features:
158145
- `orchestration_basic.rs`: Service orchestration
159146
- `orchestration_load.rs`: Load testing
160147

161-
## Contributing
162-
163-
Please read our [Contributing Guide](../../CONTRIBUTING.md) for details on:
164-
- Code style and conventions
165-
- Commit message format
166-
- Pull request process
167-
- Testing requirements
148+
Check the top of each file for usage instructions.
168149

169150
## License
170151

171-
This project is licensed under the [Apache License 2.0](../../LICENSE).
152+
This project is licensed under the [Apache License 2.0](./LICENSE).

monocore/bin/monokrun.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ use tracing::{error, info};
1313
// Function: main
1414
//--------------------------------------------------------------------------------------------------
1515

16-
/// Entry point for the runtime supervisor process.
16+
/// Entry point for the runtime supervisor and microvm subprocess.
1717
///
18-
/// Handles both supervisor and subprocess modes based on command line arguments.
18+
/// Handles both supervisor and microvm subprocess modes based on command line arguments.
1919
///
2020
/// # Arguments
2121
///

monocore/examples/microvm_curl.rs

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,11 @@
2929
//! make example microvm_curl -- --local-only localhost:8080
3030
//! ```
3131
32+
#[cfg(all(unix, not(target_os = "linux")))] // TODO: Linux support temporarily on hold
3233
use anyhow::{Context, Result};
3334
use clap::Parser;
34-
use monocore::vm::MicroVm;
35+
#[cfg(all(unix, not(target_os = "linux")))] // TODO: Linux support temporarily on hold
36+
use monocore::{utils, vm::MicroVm};
3537

3638
//--------------------------------------------------------------------------------------------------
3739
// Types
@@ -53,18 +55,27 @@ struct Args {
5355
// Functions: main
5456
//--------------------------------------------------------------------------------------------------
5557

56-
fn main() -> Result<()> {
57-
tracing_subscriber::fmt::init();
58+
#[cfg(all(unix, not(target_os = "linux")))] // TODO: Linux support temporarily on hold
59+
#[tokio::main]
60+
async fn main() -> Result<()> {
61+
tracing_subscriber::fmt()
62+
.with_max_level(tracing::Level::DEBUG)
63+
.init();
5864

5965
// Parse command line arguments
6066
let args = Args::parse();
6167

62-
// Use the architecture-specific build directory
63-
let rootfs_path = format!("build/rootfs-fedora-{}", get_current_arch());
68+
// Use specific directories for OCI and rootfs
69+
let oci_dir = format!("{}/build/oci", env!("CARGO_MANIFEST_DIR"));
70+
let merge_dir = format!("{}/build/rootfs/fedora", env!("CARGO_MANIFEST_DIR"));
71+
72+
// Pull and merge Fedora image
73+
utils::pull_docker_image(&oci_dir, "library/fedora", "latest").await?;
74+
utils::merge_image_layers(&oci_dir, &merge_dir, "library/fedora", "latest").await?;
6475

6576
// Build the MicroVm
6677
let vm = MicroVm::builder()
67-
.root_path(&rootfs_path)
78+
.root_path(format!("{}/merged", merge_dir))
6879
.num_vcpus(1)
6980
.exec_path("/bin/curl")
7081
.args([args.target.as_str()])
@@ -80,17 +91,7 @@ fn main() -> Result<()> {
8091
Ok(())
8192
}
8293

83-
//--------------------------------------------------------------------------------------------------
84-
// Functions: *
85-
//--------------------------------------------------------------------------------------------------
86-
87-
// Add this function to determine the current architecture
88-
fn get_current_arch() -> &'static str {
89-
if cfg!(target_arch = "x86_64") {
90-
"x86_64"
91-
} else if cfg!(target_arch = "aarch64") {
92-
"arm64"
93-
} else {
94-
panic!("Unsupported architecture")
95-
}
94+
#[cfg(target_os = "linux")] // TODO: Linux support temporarily on hold
95+
fn main() {
96+
panic!("This example is not yet supported on Linux");
9697
}

0 commit comments

Comments
 (0)