No description
Find a file
Jan De Landtsheer 4f771254d5 feat(xtest): runner binary (Plan B) + stock-distro-vm profile (Plan C)
Adds xtest/runner/ as a workspace member implementing the os-test-runner
binary spec from docs/plans/010-test-harness/B-runner-bin.md, and ships
the first profile at xtest/profiles/stock-distro-vm.toml per Plan C.

Runner (xtest/runner/):

- cli.rs: clap derive Args with all 8 flags (--socket, --profile, --report,
  --spawn, --timeout-default, --shutdown-after, --quiet, --json-stdout)
  and OS_TEST_* env-var fallbacks. validate() enforces the 4 mutual-
  exclusion / range rules from Plan B section 3.2.
- spawn.rs: DaemonGuard locates my-os-server-native via
  CARGO_BIN_EXE_my-os-server-native or PATH, spawns on a tempdir
  socket, polls UnixStream::connect 20x250ms with try_wait per iteration
  for child-exit detection, Drop sends SIGTERM via nix then SIGKILL
  after 3s.
- probe.rs: assemble RuntimeFacts. probe_hypervisor calls compute.vm.list
  with 2s timeout and classifies the error string for -32601 / -32000
  to drive the reachable bit (jsonrpsee::core::ClientError isn't
  re-exported through hero_rpc2; string-match is the contained
  workaround). probe_nested_kvm reads /sys/module/kvm_*/parameters/nested.
- report_write.rs: atomic tmp-write + rename, mode 0644, parent mkdir.
- summary.rs: ASCII header + per-namespace totals table + failed-methods
  list (only on failures > 0) + assertion-failures list + RESULT line.
- signals.rs + main.rs: tokio::select! between harness future, ctrl_c,
  SIGTERM. Exit codes 0 / 1 / 2 / 3 / 4 / 130 mapped per Plan B section 7.
  Partial-stub report on signal or harness error.

Profile (xtest/profiles/stock-distro-vm.toml):

- 87 methods classified: 82 must_be_registered + 5 must_be_unregistered
  (NET_DISABLED + VOL_DISABLED, interim until ADR 011) + 0 in
  skipped_methods. must_succeed restricted to the actually-succeeding-on-
  stock-Ubuntu set (mosnet-lib in-process methods, throwaway-VM-safe
  destructive_global, btrfs scratch ops, compute throwaway lifecycle).
- All 7 tiers in allow_tiers (the VM is wiped at end of run).
- [vol_armed] / [compute] use Plan A's actual struct field names
  (scratch_device, scratch_mount, memory_mib, vcpus) rather than Plan
  C's draft names (device, throwaway_vm_kind) so Policy::from_toml_file
  parses without rejection.

Tests: tests/profile_loads.rs (3 tests) verifies the profile parses
under Policy::from_toml_file, validate() passes, all 87 catalogue
methods are classified exactly once, and must_succeed is a subset of
must_be_registered. Full workspace cargo test passes; cargo check
clean (zero warnings).
2026-05-05 17:51:17 +02:00
crates feat(compute): add compute.vm.logs and compute.vm.exec to method catalogue 2026-04-16 12:19:03 +02:00
docs docs(adr): rewrite ADR 010 + plans for VM-only model 2026-05-05 15:07:10 +02:00
xtest feat(xtest): runner binary (Plan B) + stock-distro-vm profile (Plan C) 2026-05-05 17:51:17 +02:00
.gitignore chore: gitignore .codebase-memory/ (codebase-memory-mcp artifacts) 2026-04-17 17:34:36 +02:00
Cargo.lock feat(xtest): runner binary (Plan B) + stock-distro-vm profile (Plan C) 2026-05-05 17:51:17 +02:00
Cargo.toml feat(xtest): runner binary (Plan B) + stock-distro-vm profile (Plan C) 2026-05-05 17:51:17 +02:00
README.md docs: update for mosnet workspace split (ADR 031) and hero_rpc2 2026-04-21 17:21:09 +02:00

my_os_server

Unified OS-level System Abstraction Layer (SAL) daemon for the Geomind MyceliumOS platform.

Exposes networking (net.*) and storage (vol.*) management over a single hero_rpc JSON-RPC 2.0 interface. One socket, one protocol, one ACL — regardless of whether the underlying node is a full MOS deployment or a standard Linux box.

Why

Before my_os_server, managing a node meant:

  • Two socketsmosnetd for networking, mos_volmgrd for storage — each with its own line-delimited JSON-RPC protocol, no shared auth.
  • MOS-only — both daemons assume MOS boot conditions (ramdisk root, my_init, kernel params). No way to run on standard Linux for dev, CI, or non-MOS deployments.
  • No access control — any local process can call any method on either daemon.

my_os_server solves all three: single HTTP-over-UDS endpoint, dual-mode binaries (MOS proxy or native library calls), and hero_rpc ACL from day one.

Binaries

Two binaries, built from one workspace, exposing the same RPC interface:

Binary Environment How it works
my-os-server-native Standard Linux Calls mosnet-lib and mos_volmgr_common directly as libraries
my-os-server-mos MOS nodes Proxies to running mosnetd and mos_volmgrd daemons via hero_rpc Unix sockets

A consumer (hero_compute, hero_proc, CLI tools, future web UI) connects to the same socket and calls the same methods — it never knows which binary is behind it.

Architecture

┌─────────────────────────────────────────────────────────────┐
│                       Consumers                             │
│  hero_compute  │  hero_proc  │  CLI tools  │  web UI       │
└───────┬────────┴──────┬──────┴──────┬──────┴──────┬────────┘
        └───────────────┴─────────────┴─────────────┘
                            │
                  hero_rpc OsisClient
                  (HTTP-over-UDS JSON-RPC 2.0)
                            │
                ┌───────────▼───────────┐
                │     my_os_server      │
                │                       │
                │  domain: root/os      │
                │  net.* + vol.*        │
                └───────────┬───────────┘
                            │
          ┌─────────────────┼─────────────────┐
          │                                   │
 ┌────────▼─────────┐             ┌───────────▼──────────┐
 │  MOS binary       │             │  Native binary       │
 │  (proxy mode)     │             │  (direct calls)      │
 │                   │             │                      │
 │  net.* → mosnet.* │             │  mosnet-lib          │
 │  vol.* → storage.*│             │  mos_volmgr_common   │
 └────────┬──────────┘             └──────────────────────┘
          │
 ┌────────┼──────────┐
 │                    │
mosnetd           mos_volmgrd
(upstream)        (upstream)

Workspace Layout

my_os_server/
├── Cargo.toml                          # workspace root
├── docs/
│   ├── PRD.md                          # product requirements document
│   └── adr/
│       ├── 001-implementation-plan.md  # 7-step execution plan
│       └── 002-volmgr-adr-008-009-sync.md
└── crates/
    ├── my_os_server_common/            # shared types, method registry, ACL config
    │   └── src/
    │       ├── lib.rs                  # method constants, Right enum, method→right mapping
    │       └── acl_config.rs           # TOML ACL loader, group/ace builder
    ├── my_os_server_native/            # native implementation binary
    │   └── src/
    │       ├── main.rs                 # OServer setup, OsDomain handler
    │       ├── net_handler.rs          # ~30 net.* methods via mosnet-lib
    │       ├── vol_handler.rs          # ~26 vol.* methods via mos_volmgr_common
    │       └── state.rs               # JSON state persistence (mounts, taps, fw, NAT)
    └── my_os_server_mos/               # MOS proxy binary
        └── src/
            ├── main.rs                 # OServer setup, OsProxyDomain handler
            └── proxy.rs               # namespace remapping + upstream forwarding

RPC Interface

Domain: root/os Socket: ~/hero/var/sockets/hero_db_root_os.sock Protocol: HTTP/1.1 over Unix domain socket, JSON-RPC 2.0

Networking Methods (net.*)

Read-only

Method Description
net.status Daemon overview (pid, uptime, mode, IPs)
net.config Resolved kernel/boot configuration
net.lease DHCPv4 + DHCPv6 + SLAAC + prefix delegation
net.prefix Delegated IPv6 prefix state
net.vlan VLAN filtering configuration
net.health Structured health check
net.verify Drift detection (expected vs live state)
net.interfaces Interfaces with addresses, link state, bridge membership
net.routes Kernel routing table
net.neighbors ARP/NDP neighbor table
net.bridge Bridge state and ports
net.firewall nftables tables, chains, rules
net.dns Nameservers, search domains
net.sysctl Forwarding, proxy_arp, proxy_ndp per interface
net.conntrack nf_conntrack entries (optional zone filter)
net.conntrack.stats Conntrack statistics
net.nat.status NAT state (boot config + dynamic rules)
net.vm.list Managed VM tap interfaces
net.ovs OVS bridge/ports/interfaces (MOS only)
net.flows OpenFlow flow table (MOS only)
net.datapath Datapath info and flows (MOS only)
net.ovs.conntrack OVS datapath conntrack (MOS only)
net.ovs.conntrack.stats OVS conntrack statistics (MOS only)

Write (requires Write right)

Method Description
net.lease.restart Re-run DHCP DORA, reconfigure IP/routes
net.routes.add Add a route
net.routes.delete Delete a route
net.bridge.add Create a bridge
net.bridge.delete Delete a bridge
net.bridge.connect Connect two bridges (patch ports / veth)
net.bridge.add_port Add interface as bridge port
net.bridge.remove_port Remove port from bridge
net.vm.create_tap Create persistent tap, attach to bridge
net.vm.delete_tap Delete managed tap interface
net.firewall.add_rule Add input allow rule
net.firewall.remove_rule Remove input allow rule
net.nat.add_dnat Add DNAT port forward
net.nat.remove_dnat Remove DNAT port forward
net.nat.add_snat Add SNAT / masquerade
net.nat.remove_snat Remove SNAT / masquerade

Admin (requires Admin right)

Method Description
net.conntrack.flush Flush kernel conntrack entries
net.ovs.conntrack.flush Flush OVS datapath conntrack (MOS only)

Storage Methods (vol.*)

Read-only

Method Description
vol.list_disks All block devices
vol.list_partitions Partitions with filesystem info
vol.list_filesystems MOS-labeled filesystems
vol.list_mounts Mount points (enriched mountinfo)
vol.list_subvolumes Btrfs subvolumes on MOSDATA
vol.list_free_space Unpartitioned space on a disk
vol.inventory Full storage inventory snapshot
vol.feasible_topologies Feasible topology templates
vol.usage Filesystem usage statistics
vol.device_stats Btrfs device error counters
vol.scrub_status Btrfs scrub status
vol.fs_usage Detailed btrfs filesystem usage
vol.fs_df Btrfs filesystem df
vol.balance_status Btrfs balance status
vol.list_md_arrays Linux MD (software RAID) arrays
vol.md_detail Detailed MD array information

Write (requires Write right)

Method Description
vol.create_partition Create a GPT partition
vol.create_filesystem Format (btrfs, ext4, vfat, swap, bcachefs)
vol.mount Mount a filesystem
vol.unmount Unmount a path
vol.create_subvolume Create a btrfs subvolume
vol.delete_subvolume Delete a btrfs subvolume
vol.snapshot_subvolume Snapshot a subvolume
vol.set_quota Set qgroup quota
vol.scrub_start Start a btrfs scrub
vol.balance_start Start a btrfs balance
vol.defrag Defragment a path
vol.resize_max Resize filesystem to maximum

Admin (requires Admin right)

Method Description
vol.create_md_array Create MD RAID-1 array
vol.stop_md_array Stop an MD array
vol.create_btrfs_raid Create btrfs RAID filesystem

Built-in Methods (hero_rpc standard)

Method Description
rpc.discover Aggregated OpenRPC 1.3.2 spec
rpc.health {"status": "ok"}

Authentication and ACL

Uses hero_rpc's RequestContext and ACL system:

  • Identity: Public key (X-Public-Key header) or bearer token (Authorization: Bearer)
  • Rights: Admin > Write > Read (hierarchical)
  • Default: Anonymous local callers get Read; authenticated callers get per-group rights

ACL configuration via TOML:

[[group]]
name = "admins"
users = ["<pubkey_hex>"]

[[group]]
name = "operators"
users = ["<pubkey_hex>"]
member_groups = ["admins"]

[[ace]]
right = "admin"
groups = ["admins"]

[[ace]]
right = "write"
groups = ["operators"]

[policy]
anonymous_local = "read"
anonymous_remote = "none"

Building

# Build both binaries
cargo build --release

# Binaries at:
#   target/release/my-os-server-native
#   target/release/my-os-server-mos

Workspace dependencies (path deps, not published):

Dependency Path Purpose
hero_rpc2 ../hero_rpc2 Lean JSON-RPC 2.0 framework (server + client)
mosnet-lib ../mosnet/crates/mosnet-lib Networking operations (native binary)
mos_volmgr_common ../mos_volmgr/crates/mos_volmgr_common Storage operations (native binary)

System tools (native binary, non-fatal if missing):

btrfs, mount, umount, blkid, sgdisk, df, mkfs.btrfs, mkfs.ext4, mkfs.vfat, mkswap, mdadm, udevadm

Running

# Native mode (standard Linux, no upstream daemons)
my-os-server-native --state-dir /var/lib/my_os_server -v

# Native mode with ACL
my-os-server-native --acl /etc/my_os_server/acl.toml -v

# MOS mode (proxy to mosnetd + mos_volmgrd)
my-os-server-mos -v

# Query via hero_rpc
echo '{"jsonrpc":"2.0","id":1,"method":"net.interfaces","params":{}}' | \
  hero-rpc-call ~/hero/var/sockets/hero_db_root_os.sock

State Management (Native Binary)

The native binary tracks daemon-managed resources in JSON state files under --state-dir:

Registry Purpose
Mounts Tracks filesystems mounted by this daemon (restored on restart)
TAP interfaces VM taps created by net.vm.create_tap
Firewall rules Dynamically added input rules
DNAT entries Port forwarding rules
SNAT entries Masquerade / source NAT rules

On startup, mount state is verified against live /proc/self/mountinfo — stale entries are pruned automatically.

MOS Proxy — Namespace Remapping

The MOS binary remaps method namespaces when forwarding to upstream daemons:

Incoming Upstream Target daemon
net.* mosnet.* mosnetd (hero_db_root_mosnet.sock)
vol.* storage.* mos_volmgrd (hero_db_root_storage.sock)

If an upstream daemon is down, its methods return a structured error while the other domain continues working.

Upstream Prerequisites

This project required three prerequisite ADRs in upstream projects, all completed:

Step ADR Project What
1 ADR 031 mosnet Split into workspace (mosnet-lib + mosnet-rpc + mosnetd + mosnet-cli)
2 ADR 028 mosnet Migrate mosnetd RPC to hero_rpc2
3 ADR-007 mos_volmgr Migrate mos_volmgrd RPC to hero_rpc2

Additionally, ADR 002 tracks sync with mos_volmgr's ADR-008 (MD/btrfs RAID methods) and ADR-009 (mountinfo parser).

Implementation Status

Phase Status Description
Phase 1 Done Workspace scaffold + native read-only binary
Phase 2 Done Write operations + state management
Phase 3 Done MOS proxy binary with namespace remapping
Phase 4 Done ACL integration (TOML config, anonymous policy, per-method rights)
Phase 5 Planned TCP/TLS remote access
Phase 6 Planned CLI companion (my-os-ctl)

License

Part of the Geomind MyceliumOS project.