From bb2c6f45a5914458b9aa96b7f5a27e9d81134c55 Mon Sep 17 00:00:00 2001 From: PatternCatalyst Date: Sat, 18 Jul 2026 22:46:24 -0400 Subject: [PATCH] =?UTF-8?q?docs(r03):=20Part=200=20=E2=80=94=20outline=20c?= =?UTF-8?q?ourse=20map,=20prerequisites,=20KVM=20lab,=20observability=20st?= =?UTF-8?q?ack=20chapters=20with=20verified=20evidence?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _docs/00-outline.md | 14 +- _docs/01-prerequisites.md | 381 ++- _docs/02-lab-setup.md | 263 ++ _docs/03-observability-stack.md | 300 ++ _parts/09-containers-and-virtualization.md | 2 +- _parts/13-appendices-tooling.md | 2 +- assets/diagrams/00-course-map.excalidraw | 2646 +++++++++++++++++ assets/diagrams/00-course-map.svg | 81 + .../01-toolchain-landscape.excalidraw | 1743 +++++++++++ assets/diagrams/01-toolchain-landscape.svg | 56 + assets/diagrams/02-lab-topology.excalidraw | 1317 ++++++++ assets/diagrams/02-lab-topology.svg | 44 + .../diagrams/03-telemetry-pipeline.excalidraw | 1561 ++++++++++ assets/diagrams/03-telemetry-pipeline.svg | 50 + assets/diagrams/README.md | 5 +- examples/01-hello-syscalls/README.md | 60 + examples/01-hello-syscalls/cpp/.clang-format | 8 + examples/01-hello-syscalls/cpp/.clang-tidy | 11 + examples/01-hello-syscalls/cpp/CMakeLists.txt | 8 + .../01-hello-syscalls/cpp/CMakePresets.json | 62 + examples/01-hello-syscalls/cpp/demo.sh | 40 + examples/01-hello-syscalls/cpp/src/main.cpp | 32 + examples/01-hello-syscalls/demo.sh | 23 + examples/01-hello-syscalls/go/demo.sh | 23 + examples/01-hello-syscalls/go/go.mod | 7 + examples/01-hello-syscalls/go/go.sum | 2 + examples/01-hello-syscalls/go/main.go | 30 + examples/01-hello-syscalls/rust/Cargo.lock | 66 + examples/01-hello-syscalls/rust/Cargo.toml | 11 + examples/01-hello-syscalls/rust/demo.sh | 26 + .../rust/rust-toolchain.toml | 3 + examples/01-hello-syscalls/rust/src/main.rs | 12 + examples/01-hello-syscalls/verify.lua | 17 + examples/_infra/compose-lgtm.yaml | 3 +- examples/manifest.yaml | 4 + scripts/check-host.sh | 10 +- scripts/lab/provision-vm.sh | 4 +- scripts/new-example.sh | 4 + 38 files changed, 8869 insertions(+), 62 deletions(-) create mode 100644 _docs/02-lab-setup.md create mode 100644 _docs/03-observability-stack.md create mode 100644 assets/diagrams/00-course-map.excalidraw create mode 100644 assets/diagrams/00-course-map.svg create mode 100644 assets/diagrams/01-toolchain-landscape.excalidraw create mode 100644 assets/diagrams/01-toolchain-landscape.svg create mode 100644 assets/diagrams/02-lab-topology.excalidraw create mode 100644 assets/diagrams/02-lab-topology.svg create mode 100644 assets/diagrams/03-telemetry-pipeline.excalidraw create mode 100644 assets/diagrams/03-telemetry-pipeline.svg create mode 100644 examples/01-hello-syscalls/README.md create mode 100644 examples/01-hello-syscalls/cpp/.clang-format create mode 100644 examples/01-hello-syscalls/cpp/.clang-tidy create mode 100644 examples/01-hello-syscalls/cpp/CMakeLists.txt create mode 100644 examples/01-hello-syscalls/cpp/CMakePresets.json create mode 100755 examples/01-hello-syscalls/cpp/demo.sh create mode 100644 examples/01-hello-syscalls/cpp/src/main.cpp create mode 100755 examples/01-hello-syscalls/demo.sh create mode 100755 examples/01-hello-syscalls/go/demo.sh create mode 100644 examples/01-hello-syscalls/go/go.mod create mode 100644 examples/01-hello-syscalls/go/go.sum create mode 100644 examples/01-hello-syscalls/go/main.go create mode 100644 examples/01-hello-syscalls/rust/Cargo.lock create mode 100644 examples/01-hello-syscalls/rust/Cargo.toml create mode 100755 examples/01-hello-syscalls/rust/demo.sh create mode 100644 examples/01-hello-syscalls/rust/rust-toolchain.toml create mode 100644 examples/01-hello-syscalls/rust/src/main.rs create mode 100644 examples/01-hello-syscalls/verify.lua diff --git a/_docs/00-outline.md b/_docs/00-outline.md index 1476427..83a72a7 100644 --- a/_docs/00-outline.md +++ b/_docs/00-outline.md @@ -11,6 +11,11 @@ understand what their code asks of the kernel. Every hands-on chapter ships a runnable example implemented idiomatically in all three languages, presented in switchable code tabs, and every example doubles as a standalone demo. +{% include excalidraw.html + file="00-course-map" + alt="Course map: four journey stages - Foundations, Core systems, Operating context, and Mastery - shown as bands containing the fourteen parts with their chapter ranges, and the six artifacts fwatch, shmkv, chatterd, pmon, bugfarm, and sysagent along the bottom, each with an arrow to the part where it grows." + caption="Figure 0.1 — the course at a glance." %} + Two threads run through the whole book and never stop: - **Errors, three ways** — how `errno` becomes `std::expected`, a wrapped Go @@ -49,7 +54,7 @@ artifacts that grow chapter by chapter: | **Debugging** | gdb and remote debugging, valgrind vs sanitizers vs miri, eBPF observation tools, per-language toolbelts | 28–31 | | **Containers and Virtualization** | namespaces and cgroups, seccomp and Landlock, our programs in containers, KVM and the isolation spectrum | 32–35 | | **Observability** | /proc and /sys by hand, the USE method, OpenTelemetry into Grafana/Loki/Tempo/Mimir | 36–38 | -| **Performance and Low Latency** | honest benchmarking, pinned-core fast paths, the capstone fleet | 39–41 | +| **Performance and Low Latency** | benchmarking without self-deception, pinned-core fast paths, the capstone fleet | 39–41 | | **Deep Dives** | embedding Lua, Rust macros for systems code, the Go runtime | 42–44 | | **Appendices: Tooling** | Cockpit, SystemTap, and PCP; the C++, Go, and Rust toolboxes | 45–48 | @@ -64,4 +69,9 @@ experimental ever runs un-snapshotted on your workstation. > **Note** — every example section carries a verification status. A demo is > marked *verified* only when it has produced its claimed observable effect on -> the stated environment — never merely because it compiled. +> the stated environment — never merely because it compiled. That claim is +> enforced by machinery, not habit: the runner, `scripts/test-all-examples.py`, +> builds each example in all three languages and then executes the example's own +> Lua `verify.lua` harness, which must observe the behavior to report a PASS. If +> the VM lab or the LGTM stack an example depends on is down, the runner reports +> a SKIP — never a false PASS. diff --git a/_docs/01-prerequisites.md b/_docs/01-prerequisites.md index bcfb6b5..9b81bd8 100644 --- a/_docs/01-prerequisites.md +++ b/_docs/01-prerequisites.md @@ -2,50 +2,213 @@ title: "Prerequisites and toolchains" order: 1 part: "Setting Up" -description: "Fedora 44 packages, the C++/Go/Rust toolchains, CLion and terminal workflows — and a first tri-language example to prove the setup." +description: "Prepare a Fedora 44 host for systems programming in C++23, Go, and Rust — pinned toolchains, one check script that verifies everything, and a first tri-language example that asks the kernel who you are." duration: 60 minutes --- -> **Note** — this chapter is a **preview stub**: it exists so you can see the -> site's look and feel, including the multi-language code tabs below. The full -> chapter (package lists, toolchain pins, CLion setup, and the -> `examples/01-hello-syscalls` walkthrough) lands in iteration r03. +Every chapter in this book ends with something you can run, and almost every +one of them shows the same program three times — in C++23, Go, and Rust. That +only works if all three toolchains on your machine agree with the ones the +book was written against, which is why this chapter is less "install these +packages" and more "here is *why* each pin exists, and here is one script that +tells you whether your host matches." By the end you will have run the book's +first program, `examples/01-hello-syscalls`, in all three languages, and +cross-checked with `strace` that each of them really made the syscalls the +source code claims. -Every chapter in this book shows the same program in all three languages. -Click a tab once and the whole site follows you — your choice is remembered -across pages. Here is the flavor of it, with the book's first program: ask the -kernel who you are. +The code is in `examples/01-hello-syscalls/`. `./demo.sh` there builds and +runs all three implementations; its `README.md` covers the run-script contract +every later example reuses. + +{% include excalidraw.html + file="01-toolchain-landscape" + alt="Three toolchain stacks — GCC/CMake/gdb for C++, go1.26.5/go build/dlv for Go, rustc/cargo/clippy for Rust — each converging through its own demo.sh onto one shared demo.sh runner contract." + caption="Figure 1.1 — three toolchains, one demo.sh contract shared by every example in the book" %} + +## One host, three toolchains + +The book targets **Fedora 44** deliberately. Systems programming is the one +domain where "any recent Linux" is not good enough: chapters later in the book +read kernel tracepoints, load eBPF programs, and poke at cgroup files whose +layout shifts between kernel versions. Fedora ships close to upstream — the +reference host here runs kernel `7.1.3-200.fc44` — so what you observe matches +what current kernel documentation describes. It also ships **GCC 16.1.1** as +the system compiler, which matters immediately: the C++ examples use C++23's +`std::println` and `std::expected`, and those need GCC 14 or newer. On Fedora +44 you get that for free; on an LTS distribution you would be building a +compiler first. + +Go and Rust are pinned differently, and the difference is worth understanding +because it decides *where* the pin lives: + +- **Go** pins inside the module. `examples/01-hello-syscalls/go/go.mod` + declares `toolchain go1.26.5`, so any reasonably modern `go` binary — + including Fedora's packaged one — will download and use exactly go1.26.5 on + first build. The pin travels with the code; your system Go only bootstraps + it. +- **Rust** pins via `rust-toolchain.toml` (`channel = "1.97.1"`), but that + file is honored by **rustup**, not by Fedora's packaged `rustc`. Install + Rust through rustup or the pin silently does nothing — which is exactly the + kind of drift that later makes an example "work on my machine" only. + +C++ has no equivalent in-tree pin mechanism, so it pins by *floor* instead: +the check script requires GCC ≥ 14 and CMake ≥ 3.25 (the first version with +the `CMakePresets.json` v6 schema the examples use). Clang is installed as a +first-class alternate — every C++ example carries `release-clang` / +`debug-clang` presets, because two compilers disagreeing about your code is +the cheapest static analysis you will ever get. + +## What `scripts/check-host.sh` verifies — and why + +Rather than a page of `dnf install` lines to transcribe, the repo ships +`scripts/check-host.sh`: run it, read the table, fix the `[fail]` rows. Two +design choices in the script are worth noticing before the package list. + +First, it deliberately does **not** use `set -e`: + +```bash +# Deliberately no -e: failing checks are recorded in the table, not +# fatal on the spot. +set -uo pipefail +``` + +A host-check script that dies on the first missing tool tells you one problem +per run; this one accumulates every result into a table and exits non-zero +only at the end, so one pass gives you the full shopping list. Second, it +distinguishes **hard requirements** (`fail` — gates the exit code) from +**soft** ones (`warn` — informational). That split encodes what the book +actually needs versus what is merely convenient. + +The hard requirements, and the reason each is hard: + +- **`gcc`/`g++` ≥ 14, `cmake` ≥ 3.25, `clang`, `ninja`** — the C++ floor + described above. Ninja is required because every preset in + `CMakePresets.json` sets `"generator": "Ninja"`. +- **`go`** — any version, because of the toolchain-directive trick; the + script only *warns* if it is not already 1.26.x, noting the directive + "auto-downloads go1.26.5 on first build." +- **`rustup` + `rustc` + `cargo`** — a hard fail if rustup is absent, with + the hint "do not use Fedora's system rust". If rustup is present but on a + different version, it is only a warning: `rust-toolchain.toml` installs + 1.97.1 on first build anyway. +- **`lua` ≥ 5.4 (or LuaJIT) and `python3`** — Lua drives the per-example + `verify.lua` checks that CI runs; the harness accepts LuaJIT locally (the + check script records a warning recommending lua 5.4 for parity with CI). + Python drives the site's tooling (including the diagram generator that + produced Figure 1.1). +- **`podman` ≥ 5.0** — the observability chapters run the LGTM stack + (Grafana, Loki, Tempo, Mimir) as containers; the reference host has 5.8.4. +- **`virsh`, `virt-install`, `qemu-img`, `cloud-localds`, and `/dev/kvm`** — + the KVM lab that the next chapter provisions. `/dev/kvm` missing means + virtualization is disabled in firmware, which no package can fix, so the + script checks the device node itself. +- **`git` and `gh`** — the repo workflow. + +The soft rows: **Conan 2.x** (only some C++ demos pull dependencies through +it), **ruby + bundler** (local Jekyll preview of this site only), and the Go +lint/debug trio **golangci-lint, staticcheck, dlv** (CI runs them; locally +they are nice-to-have). Membership in the `libvirt` group is also warn-only — +everything works with `sudo`, it is just tedious without the group. + +## The demo contract + +Every example in the book is driven the same way, and +`examples/01-hello-syscalls` is where the contract is established. The +top-level `demo.sh` is nothing but a dispatcher: + +```bash +case "${1:-all}" in + cpp|go|rust) + lang="$1"; shift + exec "./$lang/demo.sh" "$@" + ;; + all) + for lang in "${langs[@]}"; do "./$lang/demo.sh"; done + ;; + build) + for lang in "${langs[@]}"; do "./$lang/demo.sh" build; done + ;; +esac +``` + +Each language directory owns a `demo.sh` with an identical interface: +`./demo.sh` builds then runs, `./demo.sh build` builds only, `./demo.sh run +[args]` runs the built binary. The C++ variant shows the shape: + +```bash +build() { + cmake --preset release + cmake --build --preset release +} + +run() { + if [[ ! -x "$BIN" ]]; then + build + fi + if [[ -n "${TARGET:-}" ]]; then + "$REPO_ROOT/scripts/lab/deploy-to-vm.sh" "$TARGET" "$BIN" -- "$@" + else + "./$BIN" "$@" + fi +} +``` + +The `TARGET` branch is the part that pays off later: set `TARGET` to a lab VM +name and `run` deploys the host-built binary to the guest via +`scripts/lab/deploy-to-vm.sh` instead of running it locally. Privileged +examples in later chapters need exactly this — build on the host, execute on +a disposable kernel — and because the contract is uniform, `TARGET=… ./demo.sh +go run` means the same thing in every chapter. Alongside the demo sits +`verify.lua`, which CI runs once per language: it executes `./demo.sh $LSP_LANG +run` and asserts the output matches the Lua pattern `pid %d+ on Linux`. That +is the book's definition of *verified*: the observable effect, not a clean +compile. + +## How the code works + +The program itself is three files, one per language, each printing exactly one +line — `pid on ()` — using two of the +oldest syscalls in the catalog: `getpid(2)` and `uname(2)`. {% include codetabs.html langs="C++|Go|Rust" %} ```cpp -// C++23 — no raw printf, no C-style error handling +// hello-syscall: print "pid on ()" via getpid(2) + uname(2). + +#include +#include #include #include #include + #include #include -std::expected identify() { - utsname u{}; - if (uname(&u) == -1) - return std::unexpected(std::error_code(errno, std::system_category())); - return u; +namespace { + +[[nodiscard]] std::expected system_info() { + utsname info{}; + if (::uname(&info) != 0) { + return std::unexpected(std::error_code{errno, std::system_category()}); + } + return info; } +} // namespace + int main() { - if (auto u = identify()) { - std::println("pid {} on {} {}", getpid(), u->sysname, u->release); - return 0; - } else { - std::println(stderr, "uname: {}", u.error().message()); + const auto info = system_info(); + if (!info) { + std::println(stderr, "uname failed: {}", info.error().message()); return 1; } + std::println("pid {} on {} {} ({})", ::getpid(), info->sysname, info->release, info->machine); + return 0; } ``` ```go -// Go — errors are values; syscalls go through golang.org/x/sys/unix +// hello-syscall: print "pid on ()". package main import ( @@ -55,57 +218,169 @@ import ( "golang.org/x/sys/unix" ) -func identify() (unix.Utsname, error) { - var u unix.Utsname - if err := unix.Uname(&u); err != nil { - return u, fmt.Errorf("uname: %w", err) +func helloLine() (string, error) { + var uts unix.Utsname + if err := unix.Uname(&uts); err != nil { + return "", fmt.Errorf("uname: %w", err) } - return u, nil + return fmt.Sprintf("pid %d on %s %s (%s)", + unix.Getpid(), + unix.ByteSliceToString(uts.Sysname[:]), + unix.ByteSliceToString(uts.Release[:]), + unix.ByteSliceToString(uts.Machine[:])), nil } func main() { - u, err := identify() + line, err := helloLine() if err != nil { - fmt.Fprintln(os.Stderr, err) + fmt.Fprintln(os.Stderr, "error:", err) os.Exit(1) } - fmt.Printf("pid %d on %s %s\n", os.Getpid(), - unix.ByteSliceToString(u.Sysname[:]), - unix.ByteSliceToString(u.Release[:])) + fmt.Println(line) } ``` ```rust -// Rust — Result all the way down; rustix gives safe, ergonomic syscalls use rustix::system::uname; -use std::process; fn main() { - let u = uname(); // infallible on Linux: the kernel fills a struct we own + let info = uname(); println!( - "pid {} on {} {}", - process::id(), - u.sysname().to_string_lossy(), - u.release().to_string_lossy() + "pid {} on {} {} ({})", + std::process::id(), + info.sysname().to_string_lossy(), + info.release().to_string_lossy(), + info.machine().to_string_lossy(), ); } ``` -The same program, three worldviews: C++ hands you `errno` and lets you decide -how to dress it (`std::expected` here — exceptions are reserved for subsystem -boundaries); Go wraps the error and returns it up the call chain; Rust's -binding layer has already decided which calls can fail at all. Chapter 5 turns -this observation into the error-handling policy the rest of the book applies. +All three call `uname(2)`, which fills a caller-supplied `utsname` struct with +fixed-size, NUL-terminated byte arrays — the kernel writes into *your* memory; +there is no allocation and no pointer handed back. Each language then has to +answer the same two questions: *how do I get at those bytes?* and *what do I +do if the call fails?* — and the three answers are a preview of the error- +handling policy the whole book runs on. + +**C++** wraps the raw call in `system_info()`, which returns +`std::expected`. The kernel reports failure as `-1` +plus `errno`; the wrapper immediately converts that into +`std::error_code{errno, std::system_category()}` so the error is a value, not +ambient global state that the next libc call could overwrite. `[[nodiscard]]` +makes ignoring the result a warning, and `main` branches on the `expected` +rather than on `errno`. The `::uname` scope qualifier is not decoration — the +struct and the function are *both* named `uname`, and `::` disambiguates the +global C function from the type. The struct's `char[]` fields print directly +because `std::println` treats them as C strings. + +**Go** goes through `golang.org/x/sys/unix` (v0.47.0) — the maintained home +for raw syscall bindings since the standard `syscall` package was frozen. +`unix.Uname` returns an ordinary `error`, which `helloLine` wraps with `%w` so +callers can still `errors.Is`/`errors.As` through the added context. The +`Utsname` fields arrive as `[65]byte` arrays, and `unix.ByteSliceToString` +does the careful conversion: scan to the first NUL, slice, convert — without it +you would print 65 bytes of name plus garbage. + +**Rust** uses `rustix` (1.1.4), a safe binding layer that makes syscalls +directly rather than through libc. Note what is *missing*: no `Result`, no +`unwrap`. `rustix::system::uname()` is typed as infallible because on Linux +`uname` cannot fail when handed a valid struct the caller owns — the binding +encodes the manpage's failure contract in the signature. The returned fields +are `CStr`-like views, and `to_string_lossy()` handles the (theoretical) +non-UTF-8 case instead of panicking. Three languages, three defaults: C++ +makes you construct the error discipline yourself, Go hands you an error value +and conventions, and Rust moves part of the manpage into the type system. +Chapter 5 turns this comparison into policy. + +## Build, run, observe + +Check the host first, then run the whole example: + +```bash +[host]$ ./scripts/check-host.sh +[host]$ cd examples/01-hello-syscalls && ./demo.sh +``` + +The check script prints its `[ ok ]`/`[warn]`/`[fail]` table and ends with a +summary line; on the reference host every required check passes. The demo then +builds and runs each language in turn — CMake configures the `release` preset +into `cpp/build/release/`, `go build` resolves go1.26.5 and `x/sys` on first +run, `cargo` installs the pinned 1.97.1 toolchain if needed — and each binary +prints one line of the same shape: + +``` +pid 2520094 on Linux 7.1.3-200.fc44.x86_64 (x86_64) +``` + +Three lines, three different PIDs, identical formatting: that is the whole +point. If any language prints something else — or the pattern +`pid %d+ on Linux` fails to match — your toolchain differs from the pin, and +`check-host.sh` will usually tell you where. -## What this chapter will cover +## Cross-check: watch the syscalls happen -- The Fedora 44 package set for all three toolchains, the debuggers - (gdb, valgrind, delve), the eBPF observation tools (bcc-tools, bpftrace, - bpftool), and the analysis suites (Cockpit, SystemTap, PCP via Podman). -- Pinned toolchains: GCC (with clang as a first-class alternate), CMake presets - and Conan 2 for C++; Go 1.26.5; Rust 1.97.1 via rustup. -- CLion with the Rust and Go plugins — and the terminal equivalent for every - build, run, and debug step in the book. -- `scripts/check-host.sh`, which verifies the whole setup in one shot. +The source *claims* it calls `uname(2)` and `getpid(2)`. `strace` — which +intercepts every syscall a process makes — lets you verify that independently +of any language runtime (`sudo dnf install -y strace` if you lack it). On the +C++ binary, trimmed to the `uname` call: + +```bash +[host]$ strace -f -e trace=uname ./cpp/build/release/app +uname({sysname="Linux", nodename="Lemuria", ...}) = 0 +pid 2520274 on Linux 7.1.3-200.fc44.x86_64 (x86_64) ++++ exited with 0 +++ +``` + +One process, one `uname`, exit 0. Now the Go binary, same filter: + +```bash +[host]$ strace -f -e trace=uname ./go/bin/app +strace: Process 2520268 attached +strace: Process 2520269 attached +strace: Process 2520270 attached +strace: Process 2520271 attached +[pid 2520267] uname({sysname="Linux", nodename="Lemuria", ...}) = 0 +pid 2520267 on Linux 7.1.3-200.fc44.x86_64 (x86_64) ++++ exited with 0 +++ +``` + +Same single `uname`, but four extra threads attached before `main` even ran — +the Go scheduler's worker threads, created with `clone(2)`. Run `strace -c` +on the C++ binary and `strace -cf` on the Go one (the `-f` follows those +threads) and the difference gets numeric: on this host the C++ binary made 64 +syscalls total, while the Go binary made 217 across all threads, including +114 `rt_sigaction` calls (the runtime installing its signal handlers) and 4 +`clone`s. Neither number is a problem — but it is the first concrete sighting +of a theme that recurs all book long: a language runtime is itself a systems +program, and `strace` does not let it hide. + +## CLion (optional) + +If you use CLion, opening `examples/01-hello-syscalls/cpp` should auto-import +the `CMakePresets.json` presets (release, debug, asan, and the clang pair) as +build configurations, and the Rust and Go plugins cover the other two +directories. Everything in the book, though, is driven from the terminal — no +step ever requires the IDE. + +

unverified — the CLion preset auto-import and plugin flow has not yet been exercised for this repo; confirm the five presets appear and that the Rust plugin picks up rust-toolchain.toml.

+ +## What you learned + +- Fedora 44 gives current-kernel observability and a C++23-capable system GCC; + Go pins itself via the `go.mod` toolchain directive, Rust via + `rust-toolchain.toml` — but only under rustup. +- `scripts/check-host.sh` separates hard requirements from soft ones and + reports all failures in one pass instead of dying on the first. +- Every example follows one `demo.sh` contract — `build`, `run`, and + `TARGET=` for deploy-to-guest — and is *verified* only by its observable + output, which `verify.lua` pattern-matches. +- `strace` confirms what a binary actually asks the kernel for, and already + reveals runtime differences: 64 syscalls for the C++ hello, 217 for Go's. + +Next, the **KVM lab**: provisioning the `systems-target` and `systems-peer` +guests so that everything privileged in later chapters runs on a disposable, +snapshotted kernel instead of yours. + +--- -

unverified — preview stub; the runnable example and verification land in r03.

+

verified — runner table PASS for cpp, go, and rust on the Fedora 44 host (kernel 7.1.3-200.fc44, GCC 16.1.1, go1.26.5, rustc 1.97.1): each binary printed pid <PID> on Linux 7.1.3-200.fc44.x86_64 (x86_64), and the strace excerpts above are real trimmed output from those binaries. The CLion section remains unverified as noted.

diff --git a/_docs/02-lab-setup.md b/_docs/02-lab-setup.md new file mode 100644 index 0000000..8e98adb --- /dev/null +++ b/_docs/02-lab-setup.md @@ -0,0 +1,263 @@ +--- +title: "The KVM lab" +order: 2 +part: "Setting Up" +description: "Provision two disposable Fedora KVM guests with cloud-init — an observation-first toolset, snapshot/revert discipline, and a deploy script whose output proves your code ran on the guest kernel, not yours." +duration: 45 minutes +--- + +Chapter 1 proved that three toolchains build and run the same program on your +workstation. This chapter builds the other half of the book's infrastructure: +two disposable Fedora VMs — `systems-target` and `systems-peer` — that absorb +everything you should never do to the machine you work on. A systems-programming +book keeps asking you to run code as root, watch the kernel from the inside, +fill filesystems, kill process trees, and misconfigure networks on purpose. +The lab is where all of that happens, and one snapshot command makes any +mistake reversible in seconds. + +The scripts are in `scripts/lab/`. They are parameterized by `LAB_PREFIX` +(default `systems`), so the same set provisions, starts, snapshots, and +destroys the guests by name. + +{% include excalidraw.html + file="02-lab-topology" + alt="Lab topology: a host band with libvirtd/KVM, the ~/.cache/systems-lab image cache holding the pristine Fedora Cloud Base image plus one qcow2 overlay per guest, and the scripts/lab directory; below it, the libvirt NAT network 192.168.124.0/24 containing systems-target (4 GB, .7) and systems-peer (2 GB, .95), both on kernel 6.19.10. An amber deploy arrow runs from the scripts to systems-target; a dashed line links the two guests for later two-host chapters; a note marks the lab-ready snapshot taken on both." + caption="Figure 2.1 — the systems-* lab: cached base image + per-VM overlays on the host, two guests on libvirt NAT, one amber deploy path" %} + +## Why a disposable lab + +Three kinds of chapters force the issue. **Privileged demos** — capabilities, +namespaces, cgroup writes, mount tricks — need root, and root that fat-fingers +a path on your workstation is a bad afternoon. **Kernel observation** — bpftrace +one-liners, perf profiles, the BCC tools — attaches instrumentation to a live +kernel, and you want that kernel to be one you can reboot without losing your +editor. **Destructive demos** — OOM kills, disk-full behavior, deliberately +broken network configs — only teach if you actually break something, which +means you need something safe to break. + +A VM answers all three at once, and adds the property no container gives you: +**its own kernel**. Namespaces share the host kernel, so a container can't show +you kernel-version drift, can't be probed as an isolated kernel, and can't be +snapshot-reverted with its kernel state. The lab guests run their own +`6.19.10-300.fc44` kernel while the host runs `7.1.3-200.fc44` — a visible +difference this chapter turns into its cross-check. + +That said, the VM is not the default. The book's decision rule, applied at the +top of every example: + +> **Run locally unless the demo needs root, needs to observe the kernel, or +> needs two hosts.** Everything else — ordinary syscalls, file I/O, unprivileged +> process work — runs faster and debugs easier on your workstation. + +## Host prerequisites + +Provisioning needs four things on the host, and +`scripts/lab/provision-vm.sh` checks for `virt-install` and `cloud-localds` +before doing anything: + +```bash +[host]$ sudo dnf install virt-install qemu-img cloud-utils libvirt +[host]$ sudo usermod -aG libvirt "$USER" # then log out/in, or: sg libvirt -c '...' +[host]$ ls -l /dev/kvm # hardware virtualization is available +``` + +`virt-install` defines and boots the domain, `qemu-img` builds overlay disks, +`cloud-localds` (from `cloud-utils`) packs the cloud-init seed, and membership +in the `libvirt` group lets you talk to the system libvirt instance — every +script exports `LIBVIRT_DEFAULT_URI=qemu:///system` so the guests live in the +system instance, not a per-user session that vanishes with your login. + +## How provisioning works + +`scripts/lab/provision-vm.sh` is a straight pipeline: cached base image → +per-VM overlay → cloud-init seed → `virt-install`. Each stage exists for a +reason worth spelling out. + +**The cached base image.** The script downloads +`Fedora-Cloud-Base-Generic-44-1.7.x86_64.qcow2` once into +`~/.cache/systems-lab/` and never modifies it. The version is pinned in the +script ("Pin the exact image you tested; bump deliberately") — an unpinned +"latest" would silently change the guest kernel under the whole book. + +**The overlay disk.** Instead of copying the 400 MB base per guest, the script +layers a qcow2 overlay on top of it: + +```bash +qemu-img create -f qcow2 -F qcow2 -b "$CACHE_DIR/$BASE_IMG" "$OVERLAY" "${DISK_GB}G" +``` + +The overlay records only the blocks the guest changes; the base stays pristine +and shared. This is what makes the guests *disposable* — destroying and +re-provisioning a guest deletes one thin overlay and rebuilds it in seconds, +with no re-download. + +**The cloud-init seed.** Fedora Cloud Base has no users, no packages, no SSH +access — cloud-init is how it becomes yours on first boot. The script fills +two placeholders (`__HOSTNAME__`, `__SSH_PUBKEY__`) in +`scripts/lab/cloud-init/user-data.tmpl` with `sed`, then `cloud-localds` packs +the result into a tiny seed image that is attached as a CD-ROM. On first boot +the guest reads it, creates the `fedora` user with your SSH key and +passwordless sudo, grows the root filesystem into the overlay, and installs +the toolset. + +**Booting.** `virt-install --import` boots the overlay directly (no installer), +with `--cpu host-passthrough` so the guest sees your real CPU features, +virtio disk and network for near-native I/O, and `--graphics none +--noautoconsole` because everything from here on is SSH. The script also +refuses to clobber: an existing domain of the same name is an error, and the +fix is an explicit `./destroy-vm.sh ` — rebuilds are deliberate, never +accidental. + +## What goes in the guest — and what deliberately doesn't + +The package list in `scripts/lab/cloud-init/user-data.tmpl` *is* the book's +tooling philosophy, so read it as an argument, not a manifest. The first block +is **observation tooling**: `bcc-tools`, `bpftrace`, `bpftool`, `libbpf-tools` +(precompiled CO-RE tools — `opensnoop`, `execsnoop`, `biolatency`), `perf`, +`strace`, `ltrace`, `gdb` plus `gdb-gdbserver`, `valgrind`, `sysstat`. That +block is the point of the lab: this book uses eBPF **as tooling, not as a +build target**, which is why there is *no* clang/llvm/libbpf-devel eBPF build +chain in the guest — the template says so in a comment right above the list. +You will trace with bpftrace constantly; you will not compile BPF programs. + +The second block is **per-language toolchains** (`gcc-c++`, `clang`, `cmake`, +`ninja-build`, `golang`, `rust`/`cargo`) so demos that must compile in-VM — +privileged code, namespace experiments, glibc-parity fallbacks — can. The rest +is `podman`/`crun` for the container chapters, networking tools (`tcpdump`, +`socat`, `nmap-ncat`) for the two-host chapters, and `cockpit`, whose socket +cloud-init enables so the web console is reachable at +`https://:9090` — a useful visual second opinion on guest load. + +The `runcmd` section ends with the **readiness stamp**: it writes +`bpftrace --version` and `uname -r` into `/var/log/lab-ready`. That file is +the lab's contract — if it exists and names a bpftrace, cloud-init finished +and the observation tooling works. Every later chapter can check one file +instead of guessing whether provisioning completed. + +Packages a single demo needs (fio, rt-tests, numactl) stay *out* of the base +on purpose: install them on demand, then re-snapshot to bake them in. A lean +base keeps provisioning fast and the snapshot meaningful. + +## Snapshots: the discipline that makes "destructive" safe + +`scripts/lab/snapshot-vm.sh ` captures a snapshot named `lab-ready` — +RAM *and* disk, because the guest is running, so a revert restores it +*running*, tools warm, in seconds. The discipline has two halves: + +- **Snapshot immediately after provisioning** (and after any deliberate + addition you want to keep). This is your known-good tooled baseline. +- **Revert after every destructive demo**: `scripts/lab/revert-vm.sh + systems-target` puts the guest back to `lab-ready`, no forensics, no + "did that experiment leave state behind?" doubt. + +Re-running `snapshot-vm.sh` replaces the same-named snapshot, so refreshing +the baseline is idempotent. `destroy-vm.sh` is the nuclear option — it +undefines the domain and deletes its overlay and seed, leaving only the cached +base image, from which a fresh guest is minutes away. + +## The daily lifecycle + +Day to day you touch two scripts. `scripts/lab/lab-up.sh` starts whichever of +`systems-target`/`systems-peer` are defined but stopped, waits for DHCP +leases, and prints IPs; `eval "$(./lab-up.sh --export)"` drops `TARGET_IP` and +`PEER_IP` straight into your shell for scripted tests. `scripts/lab/lab-down.sh` +sends ACPI shutdowns, waits up to 60 seconds, and — deliberately — deletes +nothing; disks and snapshots survive, and `FORCE=1` hard-stops a guest that +ignores ACPI. `vm-ip.sh` answers "what address did libvirt lease this guest?" +by reading the DHCP lease (guest-agent fallback). One host-specific note: on +this machine the libvirt `default` network is `192.168.124.0/24` with gateway +`192.168.124.1` — not the stock `192.168.122.0/24` you'll see in most libvirt +docs — so never hardcode an address; always ask `vm-ip.sh`. + +## Deploying host builds + +`scripts/lab/deploy-to-vm.sh [-- args]` is how host-built code +reaches the guest: it resolves the IP, `scp`s the binary to +`/home/fedora/`, marks it executable, and `exec`s it over `ssh -t` so Ctrl-C +reaches the remote process. Two toggles matter. `SUDO=1` runs the binary under +sudo for the demos that genuinely need root — the default is unprivileged, +matching the decision rule. And if `OTEL_ENDPOINT` is set, the script forwards +it as `OTEL_EXPORTER_OTLP_ENDPOINT` through `env` explicitly, because `sudo` +strips the environment — without that, a privileged guest binary would fall +back to its own localhost and its telemetry would never reach the host's +observability stack. This works because host builds and the guest are both +Fedora 44 (glibc parity); the in-VM toolchains are the fallback when that +assumption breaks. + +## Build, run, observe + +Provision both guests — target at the 4 GB default, peer smaller: + +```bash +[host]$ cd scripts/lab +[host]$ ./provision-vm.sh systems-target +[host]$ RAM_MB=2048 ./provision-vm.sh systems-peer +``` + +Give cloud-init a minute or two (package installation dominates), then read +the readiness stamp: + +```bash +[host]$ ssh fedora@"$(./vm-ip.sh systems-target)" cat /var/log/lab-ready +bpftrace v0.24.2 +6.19.10-300.fc44.x86_64 +``` + +That one file confirms the whole chain: the guest booted, cloud-init ran to +completion, the observation tooling works, and you can see which kernel the +lab runs. On this run the guests came up at `192.168.124.7` (target) and +`192.168.124.95` (peer). Now freeze the baseline on both: + +```bash +[host]$ ./snapshot-vm.sh systems-target +[host]$ ./snapshot-vm.sh systems-peer +``` + +`virsh snapshot-list` on each should show one `lab-ready` snapshot. That's the +lab: built once, reverted forever. + +## Cross-check: prove the code runs *there* + +Chapter 1's example prints the kernel it runs on — which makes it a perfect +independent check that `deploy-to-vm.sh` really executes on the guest rather +than, say, quietly running the local binary. Run it both ways: + +```bash +[host]$ cd examples/01-hello-syscalls +[host]$ ./demo.sh cpp +pid on Linux 7.1.3-200.fc44.x86_64 (x86_64) +[host]$ TARGET=systems-target ./demo.sh cpp +→ copying app to fedora@192.168.124.7:/home/fedora/app +→ running on systems-target (Ctrl-C to stop): +pid on Linux 6.19.10-300.fc44.x86_64 (x86_64) +``` + +Same binary, two different kernel strings: `7.1.3-200.fc44` is your host, +`6.19.10-300.fc44` is the guest. The example's per-language `demo.sh` wires +this up — with `TARGET` set, its `run` step calls +`scripts/lab/deploy-to-vm.sh "$TARGET" ` instead of executing locally, +so every example in the book gets remote execution for free. The Go build +behaves identically (`TARGET=systems-target ./demo.sh go`); both were run on +this lab and printed the guest kernel string. The kernel version in the output +is the observable proof — a claim like "it deployed" is worthless next to the +guest's own `uname` in your terminal. + +## What you learned + +- The lab exists for exactly three reasons — root, kernel observation, and + two-host demos — and the decision rule says everything else runs locally. +- Provisioning is a cheap pipeline: pinned cached base image → qcow2 overlay + per guest → cloud-init seed → `virt-install`; guests are disposable because + only the overlay is theirs. +- The guest toolset is observation-first (bcc/bpftrace/perf/gdbserver), with + in-VM toolchains as a fallback and deliberately no eBPF build chain. +- Snapshot `lab-ready` after provisioning, revert after destructive demos — + and trust `/var/log/lab-ready` plus a guest kernel string in your output, + not assumptions. + +Next, the third and final piece of setup: the Podman **LGTM observability +stack**, so every later demo has somewhere to send its telemetry. + +--- + +

verified — both guests were provisioned from Fedora-Cloud-Base-Generic-44-1.7 on this host (target 4 GB at 192.168.124.7, peer 2 GB at 192.168.124.95); /var/log/lab-ready read back bpftrace v0.24.2 and kernel 6.19.10-300.fc44 on both; lab-ready snapshots exist on both; and deploy-to-vm.sh ran the host-built C++ and Go binaries on systems-target, printing the guest kernel string 6.19.10-300.fc44.x86_64 versus 7.1.3-200.fc44.x86_64 locally.

diff --git a/_docs/03-observability-stack.md b/_docs/03-observability-stack.md new file mode 100644 index 0000000..7b4a159 --- /dev/null +++ b/_docs/03-observability-stack.md @@ -0,0 +1,300 @@ +--- +title: "The local observability stack" +order: 3 +part: "Setting Up" +description: "Stand up the Grafana LGTM all-in-one container with podman compose: OTLP ingest on :4318, Grafana on :3000, a curl-able trace smoke test through Tempo, and the gateway rule that lets lab VMs reach the stack." +duration: "30 minutes" +--- + +Chapter 1 gave you three toolchains; Chapter 2 gave you two disposable VMs. +This chapter adds the last piece of the workbench: somewhere for telemetry to +*go*. Many chapters in this book emit metrics, traces, or logs — a syscall +counter here, a request span there — and printing them to a terminal only gets +you so far. What you want is a real backend you can query, graph, and +cross-check against, without turning your workstation into a monitoring +deployment. The answer is one container: the Grafana **LGTM** all-in-one +image, run rootless under Podman, listening on exactly two ports you will +memorize — **4318** for sending and **3000** for looking. + +The infrastructure is in `examples/_infra/` — one compose file and a README. +There is no per-chapter example here; every telemetry-emitting example from +Chapter 38 onward depends on what you stand up now. + +{% include excalidraw.html + file="03-telemetry-pipeline" + alt="Telemetry pipeline: a host demo and a VM demo send OTLP HTTP to port 4318 on the lsp-lgtm container, where the OpenTelemetry Collector fans out to Loki for logs, Tempo for traces, and Mimir for metrics; Grafana on port 3000 queries all three and serves the developer's browser. The VM demo reaches the host at the libvirt gateway address 192.168.124.1." + caption="Figure 3.1 — one container, whole pipeline: OTLP in on :4318, Grafana out on :3000" %} + +## What LGTM is, and why one container + +LGTM is Grafana Labs' acronym for its open-source backend quartet: **L**oki +(logs), **G**rafana (the UI), **T**empo (traces), **M**imir (metrics, +Prometheus-compatible). In production these are four separately scaled, +separately configured services. For local development that topology is pure +overhead — what you need is the *interfaces*, not the scale. So Grafana ships +`grafana/otel-lgtm`, a single image containing all four **plus an embedded +OpenTelemetry Collector** wired to receive OTLP and fan each signal out to the +right store, with Grafana's datasources pre-provisioned to read them back. +One `podman compose up` and the entire pipeline in Figure 3.1 exists. + +The collector is the part worth pausing on. Your programs will never speak +"Loki" or "Mimir" directly — they speak **OTLP** (the OpenTelemetry protocol) +to the collector, and the collector routes logs, traces, and metrics to their +stores. That indirection is the whole point of OpenTelemetry: instrument once, +point `OTEL_EXPORTER_OTLP_ENDPOINT` somewhere, and the backend becomes +swappable. The endpoint you point at is the same whether the sender is a C++ +binary on the host or a Go binary inside `systems-target`. + +OTLP comes in two transports, and the image exposes both: gRPC on **4317** +and HTTP/protobuf-or-JSON on **4318**. This book standardizes on **HTTP +:4318**, for reasons that matter in a lab: you can drive it with `curl` (which +makes today's smoke test possible), it needs no gRPC client libraries or +HTTP/2 plumbing in minimal demos, and it traverses the NAT hop from the lab +VMs with nothing to debug. gRPC's streaming efficiency is a production +concern; debuggability wins on a workbench. + +## The compose file, line by line + +Read `examples/_infra/compose-lgtm.yaml` — it is short enough to understand +completely: + +```yaml +services: + lgtm: + image: docker.io/grafana/otel-lgtm:0.8.1 + container_name: lsp-lgtm + ports: + - "3000:3000" # Grafana UI + - "4317:4317" # OTLP gRPC + - "4318:4318" # OTLP HTTP + mem_limit: 2g + environment: + # Anonymous admin access keeps local demos friction-free. Never ship this. + - GF_AUTH_ANONYMOUS_ENABLED=true + - GF_AUTH_ANONYMOUS_ORG_ROLE=Admin + - GF_AUTH_DISABLE_LOGIN_FORM=true + healthcheck: + # curl, not wget — the otel-lgtm image ships curl only + test: ["CMD", "curl", "-sf", "http://localhost:3000/api/health"] + interval: 5s + timeout: 3s + retries: 20 + start_period: 30s # the all-in-one image takes a while on first boot + +networks: + default: + name: lsp-observability +``` + +Each choice has a why. The image is **pinned to `0.8.1`** — an unpinned +`latest` would let the stack silently change under a book whose chapters +promise reproducible output. `container_name: lsp-lgtm` gives scripts (and +you) a stable handle instead of a generated name. Only three ports are +published; Loki, Tempo, and Mimir listen on internal ports *inside* the +container, deliberately unpublished — everything goes in through the collector +and comes out through Grafana, which is exactly the discipline production +imposes. `mem_limit: 2g` exists because this one container runs five services; +the cap keeps a runaway ingest from competing with your builds for RAM. The +three `GF_AUTH_*` variables make Grafana skip its login entirely and treat +every visitor as an admin — indefensible anywhere reachable, perfect for a +loopback-only lab, and the comment in the file says so. The `healthcheck` +polls Grafana's `/api/health` from inside the container with a generous +`start_period`, because first boot unpacks and starts all five services and +takes ~30 seconds; the health state is what scripts wait on instead of +sleeping. Finally the network gets the fixed name `lsp-observability` so any +future container (the PCP suite in Chapter 45, for instance) can join it by +name rather than by guessing a generated one. + +## The prerequisite: the Podman user socket + +One thing must exist before `podman compose` works, and it is the step +everyone forgets: + +```bash +[host]$ systemctl --user enable --now podman.socket +``` + +Why: `podman compose` is not a compose implementation. It is a thin +dispatcher that delegates to an external provider — on Fedora, the +`docker-compose` plugin — which speaks the Docker Engine API to a daemon +socket. Podman famously has no daemon, but it emulates one: the systemd user +unit `podman.socket` listens on +`$XDG_RUNTIME_DIR/podman/podman.sock` and socket-activates a Podman service +that answers Docker API calls, rootless, as you. Without the unit enabled +there is no socket, the provider finds no endpoint, and compose fails with a +connection error that says nothing about systemd. Enable it once +(`--now` also starts it immediately); it persists across reboots. + +## How examples depend on the stack + +Telemetry-emitting examples declare the dependency in `examples/manifest.yaml`: + +```yaml +requires: [lgtm] +``` + +The verification harness (`scripts/test-all-examples.py`) probes +`http://localhost:4318` before running such an example — and counts *any* +HTTP response as alive, including a 4xx, because a bare GET to an OTLP ingest +path legitimately returns an error status while proving something is +listening. If nothing answers, the example is marked **SKIP (lgtm down)** +rather than FAIL; per-example `verify.lua` checks use `expect_port_open` the +same way. The principle: an absent optional backend should never turn a +working example red. + +## Reaching the stack from inside a VM + +A guest cannot use `localhost:4318` — its loopback is its own. But on a +libvirt NAT network, the **network gateway is the host**, so the host's +published ports are reachable at the gateway IP. On this lab that is +`192.168.124.1` (libvirt's stock default network is `192.168.122.0/24`, so +most references say `.122.1` — always check yours): + +```bash +[vm]$ ip route show default +default via 192.168.124.1 dev eth0 proto dhcp metric 100 +``` + +You pass the endpoint through `deploy-to-vm.sh` via `OTEL_ENDPOINT`: + +```bash +[host]$ OTEL_ENDPOINT=http://192.168.124.1:4318 TARGET=systems-target ./demo.sh run +``` + +The script forwards it explicitly because of a subtlety worth knowing: `sudo` +strips the environment, so `scripts/lab/deploy-to-vm.sh` re-injects it with +`env` on the remote side — + +```bash +RENV="" +[[ -n "${OTEL_ENDPOINT:-}" ]] && RENV="OTEL_EXPORTER_OTLP_ENDPOINT='$OTEL_ENDPOINT'" +... +exec ssh -t $SSH_OPTS "fedora@$IP" "sudo env $RENV '$REMOTE' $*" +``` + +— otherwise the guest binary would fall back to *its* localhost and telemetry +would vanish silently. One host-side requirement: ports 4317/4318 must be open +toward the libvirt bridge (on Fedora, the `libvirt` firewalld zone). + +## Build, run, observe + +Bring the stack up and wait for health: + +```bash +[host]$ systemctl --user enable --now podman.socket +[host]$ podman compose -f examples/_infra/compose-lgtm.yaml up -d +``` + +{% raw %} +```bash +[host]$ podman inspect --format '{{.State.Health.Status}}' lsp-lgtm +healthy +[host]$ curl -s http://localhost:3000/api/health +{"database": "ok", ...} +``` +{% endraw %} + +Open `http://localhost:3000` — no login form, straight to Grafana as an +anonymous admin. Take the two-minute tour: **Explore** in the left navigation +is where you will live; its datasource picker already lists **Loki**, +**Tempo**, and **Mimir** (as a Prometheus datasource), provisioned by the +image. All three are empty. Let's fix that with the same smoke test the r02 +gate used: hand-post one trace with `curl`, then query it back. + +```bash +[host]$ TRACE_ID=$(openssl rand -hex 16); SPAN_ID=$(openssl rand -hex 8); NOW=$(date +%s%N) +[host]$ curl -s -o /dev/null -w '%{http_code}\n' -X POST http://localhost:4318/v1/traces \ + -H 'Content-Type: application/json' \ + -d '{"resourceSpans":[{"resource":{"attributes":[{"key":"service.name", + "value":{"stringValue":"lsp-smoke"}}]},"scopeSpans":[{"spans":[{ + "traceId":"'$TRACE_ID'","spanId":"'$SPAN_ID'","name":"r02-gate-smoke","kind":1, + "startTimeUnixNano":"'$NOW'","endTimeUnixNano":"'$((NOW+50000000))'"}]}]}]}' +200 +``` + +That `200` is the collector accepting a minimal but complete OTLP/JSON trace: +one resource (carrying `service.name`, the identity every backend groups by), +one scope, one 50 ms span. Now query it back **through Grafana's datasource +proxy** — Tempo's own HTTP port is intentionally unpublished, so the proxy +route both reaches Tempo *and* proves the Grafana→Tempo wiring in a single +request: + +```bash +[host]$ curl -s http://localhost:3000/api/datasources/proxy/uid/tempo/api/traces/$TRACE_ID | python3 -m json.tool +``` + +```json +{ + "batches": [ + { + "resource": { + "attributes": [ + { "key": "service.name", + "value": { "stringValue": "lsp-smoke" } } + ] + }, + "scopeSpans": [ + { "spans": [ { "name": "r02-gate-smoke", ... } ] } + ... +} +``` + +(Response trimmed.) The span went curl → collector → Tempo → Grafana proxy → +back to your terminal — every arrow in Figure 3.1's trace path, exercised +once. In the UI, Explore → Tempo → TraceQL query +`{ resource.service.name = "lsp-smoke" }` finds the same span with a waterfall +view of one bar. + +Stop the stack the same way you started it (state is not preserved — fine for +a lab): + +```bash +[host]$ podman compose -f examples/_infra/compose-lgtm.yaml down +``` + +## Cross-check + +Confirm what compose claims with Podman itself, and Grafana with its own +health endpoint: + +{% raw %} +```bash +[host]$ podman ps --filter name=lsp-lgtm --format '{{.Names}} {{.Image}} {{.Status}}' +lsp-lgtm docker.io/grafana/otel-lgtm:0.8.1 Up ... (healthy) +[host]$ curl -s http://localhost:3000/api/health +{"database": "ok", ...} +``` +{% endraw %} + +`podman ps` is independent of the compose provider — it asks the container +runtime directly, so agreement here means the docker-compose plugin, the user +socket, and the runtime all see the same world. The `(healthy)` suffix is the +compose file's `curl` healthcheck reporting from *inside* the container (the +image ships curl, not wget — a detail that cost this chapter one debugging +round), while your `curl` hits the *published* port from outside: same +endpoint, two network paths, both answering. + +## What you learned + +- The LGTM all-in-one image packs Loki, Grafana, Tempo, Mimir, and an OTel + Collector into one pinned container — production interfaces, workbench + footprint; senders only ever speak OTLP, and this book standardizes on the + curl-able HTTP transport at `:4318`. +- `podman compose` delegates to the docker-compose plugin over the Docker + API socket that `systemctl --user enable --now podman.socket` provides — + the one-time prerequisite behind every `up -d`. +- Examples declare `requires: [lgtm]`; the harness probes `:4318` and skips, + never fails, when the stack is down. +- Guests reach host ports at the libvirt gateway (`192.168.124.1` here, stock + `.122.1`), and `deploy-to-vm.sh` forwards `OTEL_ENDPOINT` through `sudo + env` because sudo strips the environment. + +The stack sits idle until Chapter 38 instruments real programs in all three +languages against it, and Chapter 45 adds the PCP, Cockpit, and SystemTap +suites alongside. With the toolchains, the lab, and the telemetry pipeline in +place, the workbench is complete — next, Foundations begins where everything +in this book bottoms out: the syscall boundary and the ABI beneath it. + +--- + +

verified — on the Fedora 44 host: podman.socket enabled, podman compose -f examples/_infra/compose-lgtm.yaml up -d brought lsp-lgtm (otel-lgtm:0.8.1) to healthy, /api/health returned ok, the OTLP HTTP POST to :4318/v1/traces returned 200, and the Tempo query by trace ID through Grafana's datasource proxy returned the span r02-gate-smoke (service lsp-smoke). Not yet exercised: exporting telemetry from inside a lab VM via the 192.168.124.1 gateway — the endpoint-forwarding path is verified only as far as deploy-to-vm.sh running host-built binaries on the guest; a VM-side OTLP export lands with Chapter 38.

diff --git a/_parts/09-containers-and-virtualization.md b/_parts/09-containers-and-virtualization.md index d050205..4071ebc 100644 --- a/_parts/09-containers-and-virtualization.md +++ b/_parts/09-containers-and-virtualization.md @@ -2,5 +2,5 @@ title: "Containers and Virtualization" order: 9 part_name: "Containers and Virtualization" -blurb: "Namespaces, cgroup v2, seccomp, and Landlock as APIs our programs call — then our daemons living inside Podman containers and the honest trade-offs of containers versus KVM virtual machines." +blurb: "Namespaces, cgroup v2, seccomp, and Landlock as APIs our programs call — then our daemons living inside Podman containers and the real trade-offs of containers versus KVM virtual machines." --- diff --git a/_parts/13-appendices-tooling.md b/_parts/13-appendices-tooling.md index d54dd8f..23680de 100644 --- a/_parts/13-appendices-tooling.md +++ b/_parts/13-appendices-tooling.md @@ -2,5 +2,5 @@ title: "Appendices: Tooling" order: 13 part_name: "Appendices: Tooling" -blurb: "Reference-depth guides to the analysis suites — Cockpit, SystemTap, and Performance Co-Pilot — and the full C++, Go, and Rust toolboxes that keep this book's examples honest." +blurb: "Reference-depth guides to the analysis suites — Cockpit, SystemTap, and Performance Co-Pilot — and the full C++, Go, and Rust toolboxes that keep this book's examples sharp." --- diff --git a/assets/diagrams/00-course-map.excalidraw b/assets/diagrams/00-course-map.excalidraw new file mode 100644 index 0000000..d1de3e5 --- /dev/null +++ b/assets/diagrams/00-course-map.excalidraw @@ -0,0 +1,2646 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "id": "r1667126386", + "type": "rectangle", + "x": 14, + "y": 34, + "width": 150, + "height": 258, + "angle": 0, + "strokeColor": "#dddddd", + "backgroundColor": "#fafafa", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1022716566, + "versionNonce": 974569201, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t1879050811", + "type": "text", + "x": 26, + "y": 40, + "width": 99.00000000000001, + "height": 15.0, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1143186835, + "versionNonce": 187437396, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "1 \u00b7 Foundations", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "1 \u00b7 Foundations", + "lineHeight": 1.25, + "baseline": 12 + }, + { + "id": "r1621637983", + "type": "rectangle", + "x": 184, + "y": 34, + "width": 300, + "height": 258, + "angle": 0, + "strokeColor": "#dddddd", + "backgroundColor": "#fafafa", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 908873683, + "versionNonce": 136532044, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t128672029", + "type": "text", + "x": 196, + "y": 40, + "width": 105.60000000000001, + "height": 15.0, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1084097075, + "versionNonce": 1442457700, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "2 \u00b7 Core systems", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "2 \u00b7 Core systems", + "lineHeight": 1.25, + "baseline": 12 + }, + { + "id": "r654507653", + "type": "rectangle", + "x": 504, + "y": 34, + "width": 188, + "height": 258, + "angle": 0, + "strokeColor": "#dddddd", + "backgroundColor": "#fafafa", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1375622335, + "versionNonce": 1906776756, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t1675001463", + "type": "text", + "x": 516, + "y": 40, + "width": 138.60000000000002, + "height": 15.0, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1233620082, + "versionNonce": 1014688300, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "3 \u00b7 Operating context", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "3 \u00b7 Operating context", + "lineHeight": 1.25, + "baseline": 12 + }, + { + "id": "r197293631", + "type": "rectangle", + "x": 712, + "y": 34, + "width": 174, + "height": 258, + "angle": 0, + "strokeColor": "#dddddd", + "backgroundColor": "#fafafa", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 803354743, + "versionNonce": 1876517279, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t1932396834", + "type": "text", + "x": 724, + "y": 40, + "width": 72.60000000000001, + "height": 15.0, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1686115408, + "versionNonce": 746304264, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "4 \u00b7 Mastery", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "4 \u00b7 Mastery", + "lineHeight": 1.25, + "baseline": 12 + }, + { + "id": "r827142304", + "type": "rectangle", + "x": 26, + "y": 64, + "width": 126, + "height": 46, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1963479397, + "versionNonce": 1883569480, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t731264136", + "type": "text", + "x": 36, + "y": 72, + "width": 77.0, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1442621318, + "versionNonce": 537726597, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "Setting Up", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Setting Up", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t1497175219", + "type": "text", + "x": 36, + "y": 92, + "width": 48.400000000000006, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 55162616, + "versionNonce": 1106586834, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "ch 00\u201303", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "ch 00\u201303", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r979054046", + "type": "rectangle", + "x": 26, + "y": 124, + "width": 126, + "height": 46, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1644941061, + "versionNonce": 207859912, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t1802310598", + "type": "text", + "x": 36, + "y": 132, + "width": 84.7, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 551993234, + "versionNonce": 1751090673, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "Foundations", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Foundations", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t1290020969", + "type": "text", + "x": 36, + "y": 152, + "width": 48.400000000000006, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 793871018, + "versionNonce": 237310885, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "ch 04\u201306", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "ch 04\u201306", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r444332859", + "type": "rectangle", + "x": 194, + "y": 64, + "width": 138, + "height": 46, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1037174894, + "versionNonce": 1738985829, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t492950644", + "type": "text", + "x": 204, + "y": 72, + "width": 100.10000000000001, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 473906511, + "versionNonce": 107791375, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "Files and I/O", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Files and I/O", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t783851738", + "type": "text", + "x": 204, + "y": 92, + "width": 48.400000000000006, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1809168129, + "versionNonce": 306729212, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "ch 07\u201310", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "ch 07\u201310", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r215753091", + "type": "rectangle", + "x": 340, + "y": 64, + "width": 136, + "height": 46, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 199725280, + "versionNonce": 1120532191, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t81897152", + "type": "text", + "x": 350, + "y": 72, + "width": 146.3, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1298434234, + "versionNonce": 1599074814, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "Processes, Signals,", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Processes, Signals,", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t289249942", + "type": "text", + "x": 350, + "y": 92, + "width": 121.00000000000001, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 962883778, + "versionNonce": 1945450809, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "Privilege \u00b7 ch 11\u201314", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Privilege \u00b7 ch 11\u201314", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r1210036572", + "type": "rectangle", + "x": 194, + "y": 120, + "width": 138, + "height": 46, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1505445558, + "versionNonce": 1805362027, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t427480644", + "type": "text", + "x": 204, + "y": 128, + "width": 46.2, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1749052802, + "versionNonce": 164374104, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "Memory", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Memory", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t1396215965", + "type": "text", + "x": 204, + "y": 148, + "width": 48.400000000000006, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 268612940, + "versionNonce": 887668424, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "ch 15\u201317", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "ch 15\u201317", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r1958698092", + "type": "rectangle", + "x": 340, + "y": 120, + "width": 136, + "height": 46, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 110545770, + "versionNonce": 1800467667, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t1051472506", + "type": "text", + "x": 350, + "y": 128, + "width": 40, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 170674095, + "versionNonce": 1910860226, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "IPC", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "IPC", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t94327323", + "type": "text", + "x": 350, + "y": 148, + "width": 48.400000000000006, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1887804654, + "versionNonce": 620791404, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "ch 18\u201320", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "ch 18\u201320", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r514428949", + "type": "rectangle", + "x": 194, + "y": 176, + "width": 138, + "height": 46, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1697036857, + "versionNonce": 1107124837, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t661333768", + "type": "text", + "x": 204, + "y": 184, + "width": 77.0, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1899338530, + "versionNonce": 1921978151, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "Networking", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Networking", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t873925251", + "type": "text", + "x": 204, + "y": 204, + "width": 48.400000000000006, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1423691726, + "versionNonce": 1778606679, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "ch 21\u201324", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "ch 21\u201324", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r1454347725", + "type": "rectangle", + "x": 340, + "y": 176, + "width": 136, + "height": 46, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1877103484, + "versionNonce": 290728868, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t233796500", + "type": "text", + "x": 350, + "y": 184, + "width": 154.0, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1630571811, + "versionNonce": 965046441, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "Concurrency in Depth", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Concurrency in Depth", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t1980637864", + "type": "text", + "x": 350, + "y": 204, + "width": 48.400000000000006, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 309089695, + "versionNonce": 1400493277, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "ch 25\u201327", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "ch 25\u201327", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r549952537", + "type": "rectangle", + "x": 516, + "y": 64, + "width": 164, + "height": 46, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1294665815, + "versionNonce": 127300886, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t1617117601", + "type": "text", + "x": 526, + "y": 72, + "width": 69.30000000000001, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1540705232, + "versionNonce": 890094911, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "Debugging", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Debugging", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t739851811", + "type": "text", + "x": 526, + "y": 92, + "width": 48.400000000000006, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1201887234, + "versionNonce": 404839346, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "ch 28\u201331", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "ch 28\u201331", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r270547130", + "type": "rectangle", + "x": 516, + "y": 120, + "width": 164, + "height": 46, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1508266416, + "versionNonce": 160794046, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t1866193202", + "type": "text", + "x": 526, + "y": 128, + "width": 154.0, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1487167726, + "versionNonce": 1273801356, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "Containers and Virt.", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Containers and Virt.", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t1266926428", + "type": "text", + "x": 526, + "y": 148, + "width": 48.400000000000006, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 586006065, + "versionNonce": 1787051092, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "ch 32\u201335", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "ch 32\u201335", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r443343677", + "type": "rectangle", + "x": 516, + "y": 176, + "width": 164, + "height": 46, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1490615334, + "versionNonce": 1555215782, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t873953596", + "type": "text", + "x": 526, + "y": 184, + "width": 100.10000000000001, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1149247950, + "versionNonce": 391233616, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "Observability", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Observability", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t245594965", + "type": "text", + "x": 526, + "y": 204, + "width": 48.400000000000006, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1099582439, + "versionNonce": 44078253, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "ch 36\u201338", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "ch 36\u201338", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r889444785", + "type": "rectangle", + "x": 722, + "y": 64, + "width": 154, + "height": 46, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 813932113, + "versionNonce": 851088479, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t80500900", + "type": "text", + "x": 732, + "y": 72, + "width": 115.50000000000001, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1843496152, + "versionNonce": 1631919298, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "Performance and", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Performance and", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t1562055365", + "type": "text", + "x": 732, + "y": 92, + "width": 133.10000000000002, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1737734670, + "versionNonce": 344759224, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "Low Latency \u00b7 ch 39\u201341", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Low Latency \u00b7 ch 39\u201341", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r1946454891", + "type": "rectangle", + "x": 722, + "y": 120, + "width": 154, + "height": 46, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 52542655, + "versionNonce": 290365301, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t823492563", + "type": "text", + "x": 732, + "y": 128, + "width": 77.0, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1094780613, + "versionNonce": 813039616, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "Deep Dives", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Deep Dives", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t1737142632", + "type": "text", + "x": 732, + "y": 148, + "width": 48.400000000000006, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1832896353, + "versionNonce": 557957629, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "ch 42\u201344", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "ch 42\u201344", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r832303110", + "type": "rectangle", + "x": 722, + "y": 176, + "width": 154, + "height": 46, + "angle": 0, + "strokeColor": "#999999", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1941561339, + "versionNonce": 1967790803, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t1076886712", + "type": "text", + "x": 732, + "y": 184, + "width": 146.3, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1166771372, + "versionNonce": 136429807, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "Appendices: Tooling", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Appendices: Tooling", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t1973313368", + "type": "text", + "x": 732, + "y": 204, + "width": 48.400000000000006, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 236983956, + "versionNonce": 1098468304, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "ch 45\u201348", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "ch 45\u201348", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r48494918", + "type": "rectangle", + "x": 30, + "y": 336, + "width": 126, + "height": 54, + "angle": 0, + "strokeColor": "#e8870c", + "backgroundColor": "#fff8ef", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1052649579, + "versionNonce": 336628771, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t727575333", + "type": "text", + "x": 40, + "y": 344, + "width": 46.2, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1985756718, + "versionNonce": 411952467, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "fwatch", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "fwatch", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t997761278", + "type": "text", + "x": 40, + "y": 364, + "width": 72.60000000000001, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1153435747, + "versionNonce": 1252290567, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "file watcher", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "file watcher", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r130216966", + "type": "rectangle", + "x": 172, + "y": 336, + "width": 126, + "height": 54, + "angle": 0, + "strokeColor": "#e8870c", + "backgroundColor": "#fff8ef", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1180519022, + "versionNonce": 1370358458, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t1580133766", + "type": "text", + "x": 182, + "y": 344, + "width": 40, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1230872927, + "versionNonce": 1984260107, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "shmkv", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "shmkv", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t1145380334", + "type": "text", + "x": 182, + "y": 364, + "width": 96.80000000000001, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1804812487, + "versionNonce": 625111593, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "shared-memory KV", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "shared-memory KV", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r313979366", + "type": "rectangle", + "x": 314, + "y": 336, + "width": 126, + "height": 54, + "angle": 0, + "strokeColor": "#e8870c", + "backgroundColor": "#fff8ef", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 983593132, + "versionNonce": 430451847, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t626726905", + "type": "text", + "x": 324, + "y": 344, + "width": 61.60000000000001, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 26886887, + "versionNonce": 1281027718, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "chatterd", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "chatterd", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t1339514014", + "type": "text", + "x": 324, + "y": 364, + "width": 90.75000000000001, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1894369741, + "versionNonce": 1414849047, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "p2p chat daemon", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "p2p chat daemon", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r1313806678", + "type": "rectangle", + "x": 456, + "y": 336, + "width": 126, + "height": 54, + "angle": 0, + "strokeColor": "#e8870c", + "backgroundColor": "#fff8ef", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 690640661, + "versionNonce": 1313833265, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t1018164572", + "type": "text", + "x": 466, + "y": 344, + "width": 40, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1426309149, + "versionNonce": 1792999593, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "pmon", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "pmon", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t1167235881", + "type": "text", + "x": 466, + "y": 364, + "width": 108.9, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1175923877, + "versionNonce": 1107075600, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "process supervisor", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "process supervisor", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r1752062370", + "type": "rectangle", + "x": 598, + "y": 336, + "width": 126, + "height": 54, + "angle": 0, + "strokeColor": "#e8870c", + "backgroundColor": "#fff8ef", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 835132553, + "versionNonce": 315743361, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t989697505", + "type": "text", + "x": 608, + "y": 344, + "width": 53.900000000000006, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 692979485, + "versionNonce": 1434942369, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "bugfarm", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "bugfarm", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t482905169", + "type": "text", + "x": 608, + "y": 364, + "width": 102.85000000000001, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 527385767, + "versionNonce": 989406070, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "seeded-bug corpus", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "seeded-bug corpus", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r1039070477", + "type": "rectangle", + "x": 740, + "y": 336, + "width": 126, + "height": 54, + "angle": 0, + "strokeColor": "#e8870c", + "backgroundColor": "#fff8ef", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 713312543, + "versionNonce": 830282824, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t1988685825", + "type": "text", + "x": 750, + "y": 344, + "width": 61.60000000000001, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1157194036, + "versionNonce": 408561964, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "sysagent", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "sysagent", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t1997612480", + "type": "text", + "x": 750, + "y": 364, + "width": 78.65, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1187449345, + "versionNonce": 234536614, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "metrics agent", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "metrics agent", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "a1746718935", + "type": "arrow", + "x": 164, + "y": 160, + "width": 20, + "height": 0, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 1713580563, + "versionNonce": 1871125726, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 20, + 0 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "a834307798", + "type": "arrow", + "x": 484, + "y": 160, + "width": 20, + "height": 0, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 702827139, + "versionNonce": 1066326901, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 20, + 0 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "a335553524", + "type": "arrow", + "x": 692, + "y": 160, + "width": 20, + "height": 0, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 628367767, + "versionNonce": 1277919143, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 20, + 0 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "a833940914", + "type": "arrow", + "x": 93, + "y": 336, + "width": 147, + "height": 44, + "angle": 0, + "strokeColor": "#b8650a", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 918751622, + "versionNonce": 1986407089, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 147, + -44 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "a1069479981", + "type": "arrow", + "x": 235, + "y": 336, + "width": 35, + "height": 44, + "angle": 0, + "strokeColor": "#b8650a", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 374966438, + "versionNonce": 782605447, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 35, + -44 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "a1562415357", + "type": "arrow", + "x": 377, + "y": 336, + "width": 57, + "height": 44, + "angle": 0, + "strokeColor": "#b8650a", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 474136929, + "versionNonce": 1426870938, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -57, + -44 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "a1613101313", + "type": "arrow", + "x": 519, + "y": 336, + "width": 131, + "height": 44, + "angle": 0, + "strokeColor": "#b8650a", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 1324396339, + "versionNonce": 1574161226, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -131, + -44 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "a240924584", + "type": "arrow", + "x": 661, + "y": 336, + "width": 61, + "height": 44, + "angle": 0, + "strokeColor": "#b8650a", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 1282735705, + "versionNonce": 212473414, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -61, + -44 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "a21110309", + "type": "arrow", + "x": 803, + "y": 336, + "width": 153, + "height": 44, + "angle": 0, + "strokeColor": "#b8650a", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 609763377, + "versionNonce": 959286981, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -153, + -44 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "t1175679038", + "type": "text", + "x": 450, + "y": 404, + "width": 607.2, + "height": 15.0, + "angle": 0, + "strokeColor": "#b8650a", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 15199072, + "versionNonce": 769587224, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "The six artifacts grow across their part arcs and converge in the Chapter 41 capstone fleet.", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "The six artifacts grow across their part arcs and converge in the Chapter 41 capstone fleet.", + "lineHeight": 1.25, + "baseline": 12 + } + ], + "appState": { + "viewBackgroundColor": "#ffffff", + "gridSize": null + }, + "files": {} +} \ No newline at end of file diff --git a/assets/diagrams/00-course-map.svg b/assets/diagrams/00-course-map.svg new file mode 100644 index 0000000..dc07247 --- /dev/null +++ b/assets/diagrams/00-course-map.svg @@ -0,0 +1,81 @@ + + + +1 · Foundations + +2 · Core systems + +3 · Operating context + +4 · Mastery + +Setting Up +ch 00–03 + +Foundations +ch 04–06 + +Files and I/O +ch 07–10 + +Processes, Signals, +Privilege · ch 11–14 + +Memory +ch 15–17 + +IPC +ch 18–20 + +Networking +ch 21–24 + +Concurrency in Depth +ch 25–27 + +Debugging +ch 28–31 + +Containers and Virt. +ch 32–35 + +Observability +ch 36–38 + +Performance and +Low Latency · ch 39–41 + +Deep Dives +ch 42–44 + +Appendices: Tooling +ch 45–48 + +fwatch +file watcher + +shmkv +shared-memory KV + +chatterd +p2p chat daemon + +pmon +process supervisor + +bugfarm +seeded-bug corpus + +sysagent +metrics agent + + + + + + + + + +The six artifacts grow across their part arcs and converge in the Chapter 41 capstone fleet. + \ No newline at end of file diff --git a/assets/diagrams/01-toolchain-landscape.excalidraw b/assets/diagrams/01-toolchain-landscape.excalidraw new file mode 100644 index 0000000..e5dcfe0 --- /dev/null +++ b/assets/diagrams/01-toolchain-landscape.excalidraw @@ -0,0 +1,1743 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "id": "r833418630", + "type": "rectangle", + "x": 28, + "y": 44, + "width": 260, + "height": 256, + "angle": 0, + "strokeColor": "#dddddd", + "backgroundColor": "#fafafa", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1118727560, + "versionNonce": 172298388, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t1670372411", + "type": "text", + "x": 40, + "y": 50, + "width": 40, + "height": 15.0, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 672421967, + "versionNonce": 1542772152, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "C++", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "C++", + "lineHeight": 1.25, + "baseline": 12 + }, + { + "id": "r1855999344", + "type": "rectangle", + "x": 312, + "y": 44, + "width": 260, + "height": 256, + "angle": 0, + "strokeColor": "#dddddd", + "backgroundColor": "#fafafa", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 284623370, + "versionNonce": 449044269, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t915113430", + "type": "text", + "x": 324, + "y": 50, + "width": 40, + "height": 15.0, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 325688288, + "versionNonce": 993924279, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "Go", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Go", + "lineHeight": 1.25, + "baseline": 12 + }, + { + "id": "r654250716", + "type": "rectangle", + "x": 596, + "y": 44, + "width": 260, + "height": 256, + "angle": 0, + "strokeColor": "#dddddd", + "backgroundColor": "#fafafa", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1954565008, + "versionNonce": 893983652, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t1904073928", + "type": "text", + "x": 608, + "y": 50, + "width": 40, + "height": 15.0, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1344726972, + "versionNonce": 1864990222, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "Rust", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Rust", + "lineHeight": 1.25, + "baseline": 12 + }, + { + "id": "r1107755383", + "type": "rectangle", + "x": 52, + "y": 74, + "width": 212, + "height": 46, + "angle": 0, + "strokeColor": "#2f6db5", + "backgroundColor": "#eef4fb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 534434510, + "versionNonce": 838156491, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t277829660", + "type": "text", + "x": 62, + "y": 82, + "width": 107.80000000000001, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1463330, + "versionNonce": 153517289, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "GCC 16 / clang", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "GCC 16 / clang", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t730407282", + "type": "text", + "x": 62, + "y": 102, + "width": 84.7, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 217706280, + "versionNonce": 1938261763, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "g++ -std=c++23", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "g++ -std=c++23", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r1543152593", + "type": "rectangle", + "x": 52, + "y": 138, + "width": 212, + "height": 46, + "angle": 0, + "strokeColor": "#2f6db5", + "backgroundColor": "#eef4fb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1394107630, + "versionNonce": 1207806340, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t1063656400", + "type": "text", + "x": 62, + "y": 146, + "width": 130.9, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1935084757, + "versionNonce": 210042449, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "CMake 4.3 + Ninja", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "CMake 4.3 + Ninja", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t88710017", + "type": "text", + "x": 62, + "y": 166, + "width": 175.45000000000002, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 447025738, + "versionNonce": 1985479069, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "presets: release, asan, clang", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "presets: release, asan, clang", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r1635472307", + "type": "rectangle", + "x": 52, + "y": 202, + "width": 212, + "height": 46, + "angle": 0, + "strokeColor": "#2f6db5", + "backgroundColor": "#eef4fb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 507786433, + "versionNonce": 487483322, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t1473907817", + "type": "text", + "x": 62, + "y": 210, + "width": 107.80000000000001, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 617391521, + "versionNonce": 1235733040, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "gdb / valgrind", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "gdb / valgrind", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t217970700", + "type": "text", + "x": 62, + "y": 230, + "width": 102.85000000000001, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 135198880, + "versionNonce": 1171456925, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "sanitizer presets", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "sanitizer presets", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r66275494", + "type": "rectangle", + "x": 336, + "y": 74, + "width": 212, + "height": 46, + "angle": 0, + "strokeColor": "#2f6db5", + "backgroundColor": "#eef4fb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1489320006, + "versionNonce": 803471083, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t776835075", + "type": "text", + "x": 346, + "y": 82, + "width": 61.60000000000001, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 411022361, + "versionNonce": 1885213893, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "go1.26.5", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "go1.26.5", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t1336564473", + "type": "text", + "x": 346, + "y": 102, + "width": 175.45000000000002, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1339678024, + "versionNonce": 719211983, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "toolchain directive in go.mod", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "toolchain directive in go.mod", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r645007988", + "type": "rectangle", + "x": 336, + "y": 138, + "width": 212, + "height": 46, + "angle": 0, + "strokeColor": "#2f6db5", + "backgroundColor": "#eef4fb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 485267155, + "versionNonce": 1115472880, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t107006428", + "type": "text", + "x": 346, + "y": 146, + "width": 61.60000000000001, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 114404402, + "versionNonce": 1837346326, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "go build", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "go build", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t244289423", + "type": "text", + "x": 346, + "y": 166, + "width": 145.20000000000002, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 30155598, + "versionNonce": 1675715712, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "golang.org/x/sys v0.47.0", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "golang.org/x/sys v0.47.0", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r110413897", + "type": "rectangle", + "x": 336, + "y": 202, + "width": 212, + "height": 46, + "angle": 0, + "strokeColor": "#2f6db5", + "backgroundColor": "#eef4fb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1777120703, + "versionNonce": 679441305, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t1846383405", + "type": "text", + "x": 346, + "y": 210, + "width": 130.9, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 929679394, + "versionNonce": 1852905292, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "dlv / staticcheck", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "dlv / staticcheck", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t1762373902", + "type": "text", + "x": 346, + "y": 230, + "width": 78.65, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1720900752, + "versionNonce": 644320403, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "golangci-lint", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "golangci-lint", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r1663564537", + "type": "rectangle", + "x": 620, + "y": 74, + "width": 212, + "height": 46, + "angle": 0, + "strokeColor": "#2f6db5", + "backgroundColor": "#eef4fb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 382298576, + "versionNonce": 1074660229, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t1124821647", + "type": "text", + "x": 630, + "y": 82, + "width": 92.4, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 889011496, + "versionNonce": 483607811, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "rustc 1.97.1", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "rustc 1.97.1", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t1342043847", + "type": "text", + "x": 630, + "y": 102, + "width": 169.4, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 553598071, + "versionNonce": 163482564, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "rustup + rust-toolchain.toml", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "rustup + rust-toolchain.toml", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r727239042", + "type": "rectangle", + "x": 620, + "y": 138, + "width": 212, + "height": 46, + "angle": 0, + "strokeColor": "#2f6db5", + "backgroundColor": "#eef4fb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1737501773, + "versionNonce": 1128817103, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t1809851073", + "type": "text", + "x": 630, + "y": 146, + "width": 40, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1459926080, + "versionNonce": 374105137, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "cargo", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "cargo", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t98119180", + "type": "text", + "x": 630, + "y": 166, + "width": 72.60000000000001, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 999020822, + "versionNonce": 1755909019, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "rustix 1.1.4", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "rustix 1.1.4", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r45293154", + "type": "rectangle", + "x": 620, + "y": 202, + "width": 212, + "height": 46, + "angle": 0, + "strokeColor": "#2f6db5", + "backgroundColor": "#eef4fb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1534966987, + "versionNonce": 1321624169, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t1329989678", + "type": "text", + "x": 630, + "y": 210, + "width": 123.20000000000002, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1635601303, + "versionNonce": 1836321217, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "clippy / rustfmt", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "clippy / rustfmt", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t1170547580", + "type": "text", + "x": 630, + "y": 230, + "width": 108.9, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 175439400, + "versionNonce": 414243743, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "rust-src component", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "rust-src component", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r1952505747", + "type": "rectangle", + "x": 330, + "y": 356, + "width": 224, + "height": 62, + "angle": 0, + "strokeColor": "#e8870c", + "backgroundColor": "#fff8ef", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1116222397, + "versionNonce": 1601598507, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t556405934", + "type": "text", + "x": 340, + "y": 364, + "width": 123.20000000000002, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 264328970, + "versionNonce": 1865588794, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "demo.sh contract", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "demo.sh contract", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t1397837423", + "type": "text", + "x": 340, + "y": 384, + "width": 181.50000000000003, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 928176432, + "versionNonce": 1761383906, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "build | run [args] | TARGET=vm", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "build | run [args] | TARGET=vm", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "t455727259", + "type": "text", + "x": 340, + "y": 399, + "width": 211.75000000000003, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 851353530, + "versionNonce": 1929413055, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "same interface, all three languages", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "same interface, all three languages", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "a881983370", + "type": "arrow", + "x": 158, + "y": 120, + "width": 0, + "height": 18, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 1590571733, + "versionNonce": 492203209, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 18 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "a1150526498", + "type": "arrow", + "x": 158, + "y": 184, + "width": 0, + "height": 18, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 1835048145, + "versionNonce": 1103466192, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 18 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "a844705190", + "type": "arrow", + "x": 442, + "y": 120, + "width": 0, + "height": 18, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 1195265347, + "versionNonce": 1242286992, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 18 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "a295910953", + "type": "arrow", + "x": 442, + "y": 184, + "width": 0, + "height": 18, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 262736320, + "versionNonce": 1903695646, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 18 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "a1746060590", + "type": "arrow", + "x": 726, + "y": 120, + "width": 0, + "height": 18, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 1783430626, + "versionNonce": 1181786396, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 18 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "a82378284", + "type": "arrow", + "x": 726, + "y": 184, + "width": 0, + "height": 18, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 1445436565, + "versionNonce": 1070261430, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 18 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "a1350033437", + "type": "arrow", + "x": 158, + "y": 300, + "width": 194, + "height": 58, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 770381728, + "versionNonce": 75279832, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 194, + 58 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "t24671073", + "type": "text", + "x": 255.0, + "y": 315.0, + "width": 66.55000000000001, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1056397698, + "versionNonce": 1178864047, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "cpp/demo.sh", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "cpp/demo.sh", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "a1536915270", + "type": "arrow", + "x": 442, + "y": 300, + "width": 0, + "height": 54, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 52148063, + "versionNonce": 1376365420, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 54 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "t953285335", + "type": "text", + "x": 442.0, + "y": 313.0, + "width": 60.50000000000001, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1782134559, + "versionNonce": 27087175, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "go/demo.sh", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "go/demo.sh", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "a933724300", + "type": "arrow", + "x": 726, + "y": 300, + "width": 194, + "height": 58, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 51684902, + "versionNonce": 545541440, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -194, + 58 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "t1048186867", + "type": "text", + "x": 629.0, + "y": 315.0, + "width": 72.60000000000001, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1137196824, + "versionNonce": 194107364, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "rust/demo.sh", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "rust/demo.sh", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "t1542164708", + "type": "text", + "x": 442, + "y": 14, + "width": 284.90000000000003, + "height": 17.5, + "angle": 0, + "strokeColor": "#b8650a", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1378416246, + "versionNonce": 1793486133, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "Three toolchains, one runner contract", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Three toolchains, one runner contract", + "lineHeight": 1.25, + "baseline": 14 + } + ], + "appState": { + "viewBackgroundColor": "#ffffff", + "gridSize": null + }, + "files": {} +} \ No newline at end of file diff --git a/assets/diagrams/01-toolchain-landscape.svg b/assets/diagrams/01-toolchain-landscape.svg new file mode 100644 index 0000000..6f6843a --- /dev/null +++ b/assets/diagrams/01-toolchain-landscape.svg @@ -0,0 +1,56 @@ + + + +C++ + +Go + +Rust + +GCC 16 / clang +g++ -std=c++23 + +CMake 4.3 + Ninja +presets: release, asan, clang + +gdb / valgrind +sanitizer presets + +go1.26.5 +toolchain directive in go.mod + +go build +golang.org/x/sys v0.47.0 + +dlv / staticcheck +golangci-lint + +rustc 1.97.1 +rustup + rust-toolchain.toml + +cargo +rustix 1.1.4 + +clippy / rustfmt +rust-src component + +demo.sh contract +build | run [args] | TARGET=vm +same interface, all three languages + + + + + + + +cpp/demo.sh +cpp/demo.sh + +go/demo.sh +go/demo.sh + +rust/demo.sh +rust/demo.sh +Three toolchains, one runner contract + \ No newline at end of file diff --git a/assets/diagrams/02-lab-topology.excalidraw b/assets/diagrams/02-lab-topology.excalidraw new file mode 100644 index 0000000..a33f1ee --- /dev/null +++ b/assets/diagrams/02-lab-topology.excalidraw @@ -0,0 +1,1317 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "id": "r1406275144", + "type": "rectangle", + "x": 20, + "y": 36, + "width": 840, + "height": 158, + "angle": 0, + "strokeColor": "#dddddd", + "backgroundColor": "#fafafa", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1286383899, + "versionNonce": 1391667404, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t37608055", + "type": "text", + "x": 32, + "y": 42, + "width": 396.00000000000006, + "height": 15.0, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1747495038, + "versionNonce": 765384985, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "host \u2014 Fedora 44, kernel 7.1.3 (workstation stays untouched)", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "host \u2014 Fedora 44, kernel 7.1.3 (workstation stays untouched)", + "lineHeight": 1.25, + "baseline": 12 + }, + { + "id": "r1016053037", + "type": "rectangle", + "x": 20, + "y": 236, + "width": 840, + "height": 172, + "angle": 0, + "strokeColor": "#dddddd", + "backgroundColor": "#fafafa", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 324334303, + "versionNonce": 962449309, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t1024004781", + "type": "text", + "x": 32, + "y": 242, + "width": 402.6, + "height": 15.0, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 827607742, + "versionNonce": 138550664, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "libvirt NAT network 'default' \u2014 192.168.124.0/24 (gateway .1)", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "libvirt NAT network 'default' \u2014 192.168.124.0/24 (gateway .1)", + "lineHeight": 1.25, + "baseline": 12 + }, + { + "id": "r188313025", + "type": "rectangle", + "x": 40, + "y": 76, + "width": 170, + "height": 78, + "angle": 0, + "strokeColor": "#2f6db5", + "backgroundColor": "#eef4fb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 550248026, + "versionNonce": 1478467730, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t895957610", + "type": "text", + "x": 50, + "y": 84, + "width": 107.80000000000001, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1804292842, + "versionNonce": 827967000, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "libvirtd / KVM", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "libvirtd / KVM", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t606991430", + "type": "text", + "x": 50, + "y": 104, + "width": 84.7, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1384161087, + "versionNonce": 539702070, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "qemu:///system", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "qemu:///system", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "t1165046291", + "type": "text", + "x": 50, + "y": 119, + "width": 48.400000000000006, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 655876536, + "versionNonce": 1316742746, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "/dev/kvm", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "/dev/kvm", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "t474292913", + "type": "text", + "x": 50, + "y": 134, + "width": 72.60000000000001, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1587349225, + "versionNonce": 1938581658, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "virt-install", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "virt-install", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r708236325", + "type": "rectangle", + "x": 240, + "y": 76, + "width": 250, + "height": 92, + "angle": 0, + "strokeColor": "#2f6db5", + "backgroundColor": "#eef4fb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1009373892, + "versionNonce": 1281287366, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t121164782", + "type": "text", + "x": 250, + "y": 84, + "width": 161.70000000000002, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1139989814, + "versionNonce": 1979514433, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "~/.cache/systems-lab/", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "~/.cache/systems-lab/", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t1107683681", + "type": "text", + "x": 250, + "y": 104, + "width": 223.85000000000002, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 244568690, + "versionNonce": 1933144511, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "Fedora-Cloud-Base-44 (base, pristine)", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Fedora-Cloud-Base-44 (base, pristine)", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "t123806410", + "type": "text", + "x": 250, + "y": 119, + "width": 181.50000000000003, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 203331581, + "versionNonce": 46822407, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "systems-target.qcow2 (overlay)", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "systems-target.qcow2 (overlay)", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "t1594530982", + "type": "text", + "x": 250, + "y": 134, + "width": 169.4, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1981428247, + "versionNonce": 874562795, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "systems-peer.qcow2 (overlay)", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "systems-peer.qcow2 (overlay)", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r149866498", + "type": "rectangle", + "x": 520, + "y": 76, + "width": 230, + "height": 92, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1065372091, + "versionNonce": 121775353, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t991236292", + "type": "text", + "x": 530, + "y": 84, + "width": 92.4, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1801821180, + "versionNonce": 521984856, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "scripts/lab/", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "scripts/lab/", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t1306460124", + "type": "text", + "x": 530, + "y": 104, + "width": 175.45000000000002, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1195629303, + "versionNonce": 587126608, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "provision-vm.sh \u00b7 lab-up/down", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "provision-vm.sh \u00b7 lab-up/down", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "t1675667832", + "type": "text", + "x": 530, + "y": 119, + "width": 175.45000000000002, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 228585974, + "versionNonce": 478565482, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "snapshot-vm.sh \u00b7 revert-vm.sh", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "snapshot-vm.sh \u00b7 revert-vm.sh", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "t768555814", + "type": "text", + "x": 530, + "y": 134, + "width": 157.3, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 10585708, + "versionNonce": 1715523794, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "deploy-to-vm.sh \u00b7 vm-ip.sh", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "deploy-to-vm.sh \u00b7 vm-ip.sh", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r1463324468", + "type": "rectangle", + "x": 120, + "y": 282, + "width": 250, + "height": 96, + "angle": 0, + "strokeColor": "#e8870c", + "backgroundColor": "#fff8ef", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 266437677, + "versionNonce": 151633303, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t1414575284", + "type": "text", + "x": 130, + "y": 290, + "width": 107.80000000000001, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 570133344, + "versionNonce": 1810757568, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "systems-target", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "systems-target", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t1969270386", + "type": "text", + "x": 130, + "y": 310, + "width": 121.00000000000001, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 749735240, + "versionNonce": 1995214227, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "4 GB \u00b7 192.168.124.7", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "4 GB \u00b7 192.168.124.7", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "t1309411583", + "type": "text", + "x": 130, + "y": 325, + "width": 139.15, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 468749571, + "versionNonce": 546300156, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "kernel 6.19.10-300.fc44", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "kernel 6.19.10-300.fc44", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "t475718686", + "type": "text", + "x": 130, + "y": 340, + "width": 187.55, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 603160918, + "versionNonce": 1890858912, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "bpftrace \u00b7 perf \u00b7 cockpit :9090", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "bpftrace \u00b7 perf \u00b7 cockpit :9090", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r1405528348", + "type": "rectangle", + "x": 540, + "y": 282, + "width": 240, + "height": 96, + "angle": 0, + "strokeColor": "#888888", + "backgroundColor": "#f4f4f4", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 424420554, + "versionNonce": 1785176074, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t571931272", + "type": "text", + "x": 550, + "y": 290, + "width": 92.4, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1210820383, + "versionNonce": 1410869989, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "systems-peer", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "systems-peer", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t257768065", + "type": "text", + "x": 550, + "y": 310, + "width": 127.05000000000001, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 427648417, + "versionNonce": 970658024, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "2 GB \u00b7 192.168.124.95", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "2 GB \u00b7 192.168.124.95", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "t1158220638", + "type": "text", + "x": 550, + "y": 325, + "width": 139.15, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 102937666, + "versionNonce": 572631202, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "kernel 6.19.10-300.fc44", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "kernel 6.19.10-300.fc44", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "t1179154860", + "type": "text", + "x": 550, + "y": 340, + "width": 175.45000000000002, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 462555431, + "versionNonce": 214141018, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "second host for network demos", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "second host for network demos", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "a1505128328", + "type": "arrow", + "x": 320, + "y": 168, + "width": 75, + "height": 114, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 473393111, + "versionNonce": 1491534672, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -75, + 114 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "t477136396", + "type": "text", + "x": 282.5, + "y": 211.0, + "width": 181.50000000000003, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 515935267, + "versionNonce": 27708328, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "qcow2 overlay backs each guest", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "qcow2 overlay backs each guest", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "a997228135", + "type": "arrow", + "x": 620, + "y": 168, + "width": 290, + "height": 114, + "angle": 0, + "strokeColor": "#b8650a", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 1115376542, + "versionNonce": 186469253, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -290, + 114 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "t591947760", + "type": "text", + "x": 475.0, + "y": 211.0, + "width": 163.35000000000002, + "height": 13.75, + "angle": 0, + "strokeColor": "#b8650a", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 733899596, + "versionNonce": 1747906267, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "deploy-to-vm.sh (scp \u2192 run)", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "deploy-to-vm.sh (scp \u2192 run)", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "a504553229", + "type": "arrow", + "x": 370, + "y": 330, + "width": 170, + "height": 0, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 811574355, + "versionNonce": 900117774, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 170, + 0 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "t868994942", + "type": "text", + "x": 455.0, + "y": 316.0, + "width": 151.25, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1217121225, + "versionNonce": 205073676, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "two-host chapters (later)", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "two-host chapters (later)", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "t1571404033", + "type": "text", + "x": 786, + "y": 248, + "width": 157.3, + "height": 16.25, + "angle": 0, + "strokeColor": "#b8650a", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1816259905, + "versionNonce": 816585615, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "\u27f2 snapshot \"lab-ready\"", + "fontSize": 13, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "\u27f2 snapshot \"lab-ready\"", + "lineHeight": 1.25, + "baseline": 13 + }, + { + "id": "t638956466", + "type": "text", + "x": 786, + "y": 266, + "width": 181.50000000000003, + "height": 13.75, + "angle": 0, + "strokeColor": "#1d1d1d", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1323834534, + "versionNonce": 167429913, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "taken on both after provision;", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "taken on both after provision;", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "t864978747", + "type": "text", + "x": 786, + "y": 281, + "width": 181.50000000000003, + "height": 13.75, + "angle": 0, + "strokeColor": "#1d1d1d", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1456640518, + "versionNonce": 122612297, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "revert after destructive demos", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "revert after destructive demos", + "lineHeight": 1.25, + "baseline": 11 + } + ], + "appState": { + "viewBackgroundColor": "#ffffff", + "gridSize": null + }, + "files": {} +} \ No newline at end of file diff --git a/assets/diagrams/02-lab-topology.svg b/assets/diagrams/02-lab-topology.svg new file mode 100644 index 0000000..2ef7d00 --- /dev/null +++ b/assets/diagrams/02-lab-topology.svg @@ -0,0 +1,44 @@ + + + +host — Fedora 44, kernel 7.1.3 (workstation stays untouched) + +libvirt NAT network 'default' — 192.168.124.0/24 (gateway .1) + +libvirtd / KVM +qemu:///system +/dev/kvm +virt-install + +~/.cache/systems-lab/ +Fedora-Cloud-Base-44 (base, pristine) +systems-target.qcow2 (overlay) +systems-peer.qcow2 (overlay) + +scripts/lab/ +provision-vm.sh · lab-up/down +snapshot-vm.sh · revert-vm.sh +deploy-to-vm.sh · vm-ip.sh + +systems-target +4 GB · 192.168.124.7 +kernel 6.19.10-300.fc44 +bpftrace · perf · cockpit :9090 + +systems-peer +2 GB · 192.168.124.95 +kernel 6.19.10-300.fc44 +second host for network demos + +qcow2 overlay backs each guest +qcow2 overlay backs each guest + +deploy-to-vm.sh (scp → run) +deploy-to-vm.sh (scp → run) + +two-host chapters (later) +two-host chapters (later) +⟲ snapshot "lab-ready" +taken on both after provision; +revert after destructive demos + \ No newline at end of file diff --git a/assets/diagrams/03-telemetry-pipeline.excalidraw b/assets/diagrams/03-telemetry-pipeline.excalidraw new file mode 100644 index 0000000..0ab8136 --- /dev/null +++ b/assets/diagrams/03-telemetry-pipeline.excalidraw @@ -0,0 +1,1561 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "id": "r360657190", + "type": "rectangle", + "x": 250, + "y": 48, + "width": 430, + "height": 320, + "angle": 0, + "strokeColor": "#dddddd", + "backgroundColor": "#fafafa", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1637545074, + "versionNonce": 163770782, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t880970590", + "type": "text", + "x": 262, + "y": 54, + "width": 290.40000000000003, + "height": 15.0, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1842893310, + "versionNonce": 1086073061, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "lsp-lgtm container (grafana/otel-lgtm:0.8.1)", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "lsp-lgtm container (grafana/otel-lgtm:0.8.1)", + "lineHeight": 1.25, + "baseline": 12 + }, + { + "id": "r1712330105", + "type": "rectangle", + "x": 30, + "y": 96, + "width": 155, + "height": 60, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 222152973, + "versionNonce": 135005593, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t1338299503", + "type": "text", + "x": 40, + "y": 104, + "width": 69.30000000000001, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1611199507, + "versionNonce": 1427291531, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "host demo", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "host demo", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t1511466805", + "type": "text", + "x": 40, + "y": 124, + "width": 66.55000000000001, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1129451552, + "versionNonce": 162952124, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "examples/NN", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "examples/NN", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "t855579072", + "type": "text", + "x": 40, + "y": 139, + "width": 84.7, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 335909622, + "versionNonce": 1599969004, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "localhost:4318", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "localhost:4318", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r560429977", + "type": "rectangle", + "x": 30, + "y": 226, + "width": 155, + "height": 60, + "angle": 0, + "strokeColor": "#888888", + "backgroundColor": "#f4f4f4", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 972517271, + "versionNonce": 84460505, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t156470264", + "type": "text", + "x": 40, + "y": 234, + "width": 53.900000000000006, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1350415382, + "versionNonce": 830727003, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "VM demo", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "VM demo", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t1444399514", + "type": "text", + "x": 40, + "y": 254, + "width": 84.7, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 723090097, + "versionNonce": 1973166529, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "systems-target", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "systems-target", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "t564779398", + "type": "text", + "x": 40, + "y": 269, + "width": 66.55000000000001, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 423414474, + "versionNonce": 1593992043, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "via gateway", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "via gateway", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r777650421", + "type": "rectangle", + "x": 275, + "y": 156, + "width": 125, + "height": 72, + "angle": 0, + "strokeColor": "#e8870c", + "backgroundColor": "#fff8ef", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1918926171, + "versionNonce": 475955264, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t1559005498", + "type": "text", + "x": 285, + "y": 164, + "width": 107.80000000000001, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1932529844, + "versionNonce": 949259394, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "OTel Collector", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "OTel Collector", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t289028578", + "type": "text", + "x": 285, + "y": 184, + "width": 90.75000000000001, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 156706709, + "versionNonce": 1548809627, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "OTLP HTTP :4318", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "OTLP HTTP :4318", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "t410222883", + "type": "text", + "x": 285, + "y": 199, + "width": 90.75000000000001, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1397499314, + "versionNonce": 1446163961, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "OTLP gRPC :4317", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "OTLP gRPC :4317", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r1206484770", + "type": "rectangle", + "x": 445, + "y": 78, + "width": 95, + "height": 50, + "angle": 0, + "strokeColor": "#999999", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1108652158, + "versionNonce": 374336289, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t1106483183", + "type": "text", + "x": 455, + "y": 86, + "width": 40, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1031199473, + "versionNonce": 30699507, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "Loki", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Loki", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t340384964", + "type": "text", + "x": 455, + "y": 106, + "width": 40, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1430392643, + "versionNonce": 884710897, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "logs", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "logs", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r1510873232", + "type": "rectangle", + "x": 445, + "y": 168, + "width": 95, + "height": 50, + "angle": 0, + "strokeColor": "#999999", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1015016503, + "versionNonce": 1705096193, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t520409307", + "type": "text", + "x": 455, + "y": 176, + "width": 40, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1401074830, + "versionNonce": 856065685, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "Tempo", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Tempo", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t1237138681", + "type": "text", + "x": 455, + "y": 196, + "width": 40, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1895005395, + "versionNonce": 1070062094, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "traces", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "traces", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r332234410", + "type": "rectangle", + "x": 445, + "y": 258, + "width": 95, + "height": 50, + "angle": 0, + "strokeColor": "#999999", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 47249836, + "versionNonce": 788185940, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t1324094284", + "type": "text", + "x": 455, + "y": 266, + "width": 40, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1069767941, + "versionNonce": 1214006416, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "Mimir", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Mimir", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t1887989820", + "type": "text", + "x": 455, + "y": 286, + "width": 42.35, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 436971471, + "versionNonce": 404451605, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "metrics", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "metrics", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r1040300676", + "type": "rectangle", + "x": 570, + "y": 160, + "width": 92, + "height": 64, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "#ffffff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1446304739, + "versionNonce": 993199772, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t860486241", + "type": "text", + "x": 580, + "y": 168, + "width": 53.900000000000006, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 803636408, + "versionNonce": 1774109103, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "Grafana", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Grafana", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t129052830", + "type": "text", + "x": 580, + "y": 188, + "width": 40, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 723308767, + "versionNonce": 1120951950, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": ":3000", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": ":3000", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "r1448069186", + "type": "rectangle", + "x": 730, + "y": 168, + "width": 130, + "height": 56, + "angle": 0, + "strokeColor": "#2f6db5", + "backgroundColor": "#eef4fb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 302002914, + "versionNonce": 1163105945, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "t180832579", + "type": "text", + "x": 740, + "y": 176, + "width": 69.30000000000001, + "height": 17.5, + "angle": 0, + "strokeColor": "#111111", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 317247434, + "versionNonce": 1913892261, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "developer", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "developer", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "id": "t1801971735", + "type": "text", + "x": 740, + "y": 196, + "width": 42.35, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 976042124, + "versionNonce": 1207997427, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "browser", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "browser", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "a822268750", + "type": "arrow", + "x": 185, + "y": 118, + "width": 90, + "height": 54, + "angle": 0, + "strokeColor": "#b8650a", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 1364135645, + "versionNonce": 991514186, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 90, + 54 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "t224322521", + "type": "text", + "x": 230.0, + "y": 131.0, + "width": 54.45, + "height": 13.75, + "angle": 0, + "strokeColor": "#b8650a", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 600161313, + "versionNonce": 1048801807, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "OTLP HTTP", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "OTLP HTTP", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "a1565908948", + "type": "arrow", + "x": 185, + "y": 262, + "width": 90, + "height": 50, + "angle": 0, + "strokeColor": "#b8650a", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 514615696, + "versionNonce": 22571865, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 90, + -50 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "t1941339956", + "type": "text", + "x": 230.0, + "y": 223.0, + "width": 108.9, + "height": 13.75, + "angle": 0, + "strokeColor": "#b8650a", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 306131301, + "versionNonce": 1093538627, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "192.168.124.1:4318", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "192.168.124.1:4318", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "a226582616", + "type": "arrow", + "x": 400, + "y": 172, + "width": 45, + "height": 66, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 56227534, + "versionNonce": 493559451, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 45, + -66 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "a79081188", + "type": "arrow", + "x": 400, + "y": 192, + "width": 45, + "height": 1, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 1204938181, + "versionNonce": 1810389820, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 45, + 1 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "a1140309755", + "type": "arrow", + "x": 400, + "y": 212, + "width": 45, + "height": 68, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 1275256339, + "versionNonce": 1083224485, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 45, + 68 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "a1322714865", + "type": "arrow", + "x": 540, + "y": 103, + "width": 30, + "height": 69, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 60618261, + "versionNonce": 1794984491, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 30, + 69 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "a583417199", + "type": "arrow", + "x": 540, + "y": 193, + "width": 30, + "height": 1, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 1780584263, + "versionNonce": 926703480, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 30, + -1 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "a307942651", + "type": "arrow", + "x": 540, + "y": 283, + "width": 30, + "height": 71, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 1742769289, + "versionNonce": 1906892454, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 30, + -71 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "a1421269201", + "type": "arrow", + "x": 662, + "y": 192, + "width": 68, + "height": 2, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 1644463500, + "versionNonce": 619923383, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 68, + 2 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "t897863638", + "type": "text", + "x": 696.0, + "y": 179.0, + "width": 127.05000000000001, + "height": 13.75, + "angle": 0, + "strokeColor": "#555555", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 204412366, + "versionNonce": 714515164, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "http://localhost:3000", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "http://localhost:3000", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "t1443920573", + "type": "text", + "x": 107, + "y": 68, + "width": 50.050000000000004, + "height": 16.25, + "angle": 0, + "strokeColor": "#1d1d1d", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1431370682, + "versionNonce": 1733527834, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "senders", + "fontSize": 13, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "senders", + "lineHeight": 1.25, + "baseline": 13 + }, + { + "id": "t183171213", + "type": "text", + "x": 107, + "y": 198, + "width": 157.3, + "height": 13.75, + "angle": 0, + "strokeColor": "#1d1d1d", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1596872540, + "versionNonce": 1678587277, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "libvirt NAT gateway = host", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "libvirt NAT gateway = host", + "lineHeight": 1.25, + "baseline": 11 + }, + { + "id": "t952554162", + "type": "text", + "x": 795, + "y": 140, + "width": 157.3, + "height": 13.75, + "angle": 0, + "strokeColor": "#b8650a", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 875582392, + "versionNonce": 594334578, + "isDeleted": false, + "boundElements": [], + "updated": 1, + "link": null, + "locked": false, + "text": "one container, whole stack", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "one container, whole stack", + "lineHeight": 1.25, + "baseline": 11 + } + ], + "appState": { + "viewBackgroundColor": "#ffffff", + "gridSize": null + }, + "files": {} +} \ No newline at end of file diff --git a/assets/diagrams/03-telemetry-pipeline.svg b/assets/diagrams/03-telemetry-pipeline.svg new file mode 100644 index 0000000..c621243 --- /dev/null +++ b/assets/diagrams/03-telemetry-pipeline.svg @@ -0,0 +1,50 @@ + + + +lsp-lgtm container (grafana/otel-lgtm:0.8.1) + +host demo +examples/NN +localhost:4318 + +VM demo +systems-target +via gateway + +OTel Collector +OTLP HTTP :4318 +OTLP gRPC :4317 + +Loki +logs + +Tempo +traces + +Mimir +metrics + +Grafana +:3000 + +developer +browser + +OTLP HTTP +OTLP HTTP + +192.168.124.1:4318 +192.168.124.1:4318 + + + + + + + +http://localhost:3000 +http://localhost:3000 +senders +libvirt NAT gateway = host +one container, whole stack + \ No newline at end of file diff --git a/assets/diagrams/README.md b/assets/diagrams/README.md index 51a9da7..7e37603 100644 --- a/assets/diagrams/README.md +++ b/assets/diagrams/README.md @@ -7,4 +7,7 @@ here as you add them: | Diagram | Chapter | What it shows | |---|---|---| -| `example-flow` | 1 | (replace with your diagrams) | +| `00-course-map` | 0 | The four journey stages, fourteen parts, and six recurring artifacts | +| `01-toolchain-landscape` | 1 | Three language toolchain stacks converging on the shared demo.sh contract | +| `02-lab-topology` | 2 | Host, libvirt NAT network, and the systems-target/systems-peer guests | +| `03-telemetry-pipeline` | 3 | Demos exporting OTLP into the lsp-lgtm container and out to Grafana | diff --git a/examples/01-hello-syscalls/README.md b/examples/01-hello-syscalls/README.md new file mode 100644 index 0000000..4e9786f --- /dev/null +++ b/examples/01-hello-syscalls/README.md @@ -0,0 +1,60 @@ +# 01-hello-syscalls + +Chapter 1's example — and the seed for every runnable example in the book. It +implements the same tiny program three times — C++23, Go, and Rust — each +printing exactly one line: + +``` +pid on () +``` + +via `getpid(2)` + `uname(2)` equivalents, with each language's idiomatic error +handling (`std::expected` over `errno` / wrapped errors via `%w` / `rustix`, +whose `uname` is typed infallible on Linux). + +The chapter (`_docs/01-prerequisites.md`) walks all three sources, the host +prerequisites (`scripts/check-host.sh`), and an `strace` cross-check of the +built binaries. + +## Layout + +``` +01-hello-syscalls/ +├── demo.sh # dispatcher: ./demo.sh [cpp|go|rust|all|build] [args...] +├── verify.lua # automated check driven by CI +├── cpp/ # CMake preset build (GCC or clang), demo.sh +├── go/ # go build (toolchain go1.26.5), demo.sh +└── rust/ # cargo build (rustup pin 1.97.1), demo.sh +``` + +## The demo contract + +Every language directory has a `demo.sh` with the same interface, identical +across the whole book: + +- `./demo.sh` — build then run +- `./demo.sh build` — build only +- `./demo.sh run [args]` — run the built binary +- With env `TARGET` set, `run` deploys the binary to that lab VM via + `scripts/lab/deploy-to-vm.sh "$TARGET" -- [args]` instead of + running locally. + +The top-level `demo.sh` here is only a dispatcher: `./demo.sh cpp run` execs +`cpp/demo.sh run`; bare `./demo.sh` (or `all`) builds and runs all three. + +## Verification + +`verify.lua` is run from this directory with `LSP_LANG` set to one language at +a time. It uses `scripts/lib/checks.lua` to run `./demo.sh $LSP_LANG run` and +asserts the output matches `pid %d+ on Linux`. Exit 0 = pass, 1 = fail, +77 = skip. + +Verified on the Fedora 44 reference host (kernel 7.1.3-200.fc44): all three +languages PASS and print `pid on Linux 7.1.3-200.fc44.x86_64 (x86_64)`. + +## Mapping to a chapter + +Each later chapter's example is a copy of this shape (`scripts/new-example.sh +NN-slug`) with the program body replaced by that chapter's code. Keep the +demo contract and `verify.lua` intact so CI and the manifest +(`examples/manifest.yaml`) keep working. diff --git a/examples/01-hello-syscalls/cpp/.clang-format b/examples/01-hello-syscalls/cpp/.clang-format new file mode 100644 index 0000000..2c8640f --- /dev/null +++ b/examples/01-hello-syscalls/cpp/.clang-format @@ -0,0 +1,8 @@ +--- +BasedOnStyle: LLVM +Language: Cpp +Standard: c++20 +IndentWidth: 4 +ColumnLimit: 100 +PointerAlignment: Left +AllowShortFunctionsOnASingleLine: Inline diff --git a/examples/01-hello-syscalls/cpp/.clang-tidy b/examples/01-hello-syscalls/cpp/.clang-tidy new file mode 100644 index 0000000..2f275ba --- /dev/null +++ b/examples/01-hello-syscalls/cpp/.clang-tidy @@ -0,0 +1,11 @@ +--- +Checks: > + bugprone-*, + modernize-*, + performance-*, + readability-*, + -modernize-use-trailing-return-type, + -readability-identifier-length +WarningsAsErrors: '' +HeaderFilterRegex: '.*' +FormatStyle: file diff --git a/examples/01-hello-syscalls/cpp/CMakeLists.txt b/examples/01-hello-syscalls/cpp/CMakeLists.txt new file mode 100644 index 0000000..6bdb445 --- /dev/null +++ b/examples/01-hello-syscalls/cpp/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.25) +project(template_hello CXX) + +set(CMAKE_CXX_STANDARD 23) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +add_executable(app src/main.cpp) diff --git a/examples/01-hello-syscalls/cpp/CMakePresets.json b/examples/01-hello-syscalls/cpp/CMakePresets.json new file mode 100644 index 0000000..e31bd2f --- /dev/null +++ b/examples/01-hello-syscalls/cpp/CMakePresets.json @@ -0,0 +1,62 @@ +{ + "version": 6, + "cmakeMinimumRequired": { "major": 3, "minor": 25, "patch": 0 }, + "configurePresets": [ + { + "name": "_base", + "hidden": true, + "generator": "Ninja", + "binaryDir": "${sourceDir}/build/${presetName}", + "cacheVariables": { + "CMAKE_EXPORT_COMPILE_COMMANDS": "ON" + } + }, + { + "name": "release", + "inherits": "_base", + "displayName": "Release (-O2 with debug info)", + "cacheVariables": { "CMAKE_BUILD_TYPE": "RelWithDebInfo" } + }, + { + "name": "debug", + "inherits": "_base", + "displayName": "Debug", + "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" } + }, + { + "name": "asan", + "inherits": "_base", + "displayName": "ASan + UBSan instrumented build", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_CXX_FLAGS": "-O1 -g -fno-omit-frame-pointer -fsanitize=address,undefined", + "CMAKE_EXE_LINKER_FLAGS": "-fsanitize=address,undefined" + } + }, + { + "name": "release-clang", + "inherits": "release", + "displayName": "Release (clang)", + "cacheVariables": { + "CMAKE_C_COMPILER": "clang", + "CMAKE_CXX_COMPILER": "clang++" + } + }, + { + "name": "debug-clang", + "inherits": "debug", + "displayName": "Debug (clang)", + "cacheVariables": { + "CMAKE_C_COMPILER": "clang", + "CMAKE_CXX_COMPILER": "clang++" + } + } + ], + "buildPresets": [ + { "name": "release", "configurePreset": "release" }, + { "name": "debug", "configurePreset": "debug" }, + { "name": "asan", "configurePreset": "asan" }, + { "name": "release-clang", "configurePreset": "release-clang" }, + { "name": "debug-clang", "configurePreset": "debug-clang" } + ] +} diff --git a/examples/01-hello-syscalls/cpp/demo.sh b/examples/01-hello-syscalls/cpp/demo.sh new file mode 100755 index 0000000..6af6509 --- /dev/null +++ b/examples/01-hello-syscalls/cpp/demo.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +set -euo pipefail + +cd "$(dirname "${BASH_SOURCE[0]}")" +REPO_ROOT="$(cd ../../.. && pwd)" +BIN=build/release/app + +build() { + cmake --preset release + cmake --build --preset release +} + +run() { + if [[ ! -x "$BIN" ]]; then + build + fi + if [[ -n "${TARGET:-}" ]]; then + "$REPO_ROOT/scripts/lab/deploy-to-vm.sh" "$TARGET" "$BIN" -- "$@" + else + "./$BIN" "$@" + fi +} + +case "${1:-}" in + build) + build + ;; + run) + shift + run "$@" + ;; + "") + build + run + ;; + *) + echo "usage: $0 [build|run [args]]" >&2 + exit 2 + ;; +esac diff --git a/examples/01-hello-syscalls/cpp/src/main.cpp b/examples/01-hello-syscalls/cpp/src/main.cpp new file mode 100644 index 0000000..74a956e --- /dev/null +++ b/examples/01-hello-syscalls/cpp/src/main.cpp @@ -0,0 +1,32 @@ +// hello-syscall: print "pid on ()" via getpid(2) + uname(2). + +#include +#include +#include +#include +#include + +#include +#include + +namespace { + +[[nodiscard]] std::expected system_info() { + utsname info{}; + if (::uname(&info) != 0) { + return std::unexpected(std::error_code{errno, std::system_category()}); + } + return info; +} + +} // namespace + +int main() { + const auto info = system_info(); + if (!info) { + std::println(stderr, "uname failed: {}", info.error().message()); + return 1; + } + std::println("pid {} on {} {} ({})", ::getpid(), info->sysname, info->release, info->machine); + return 0; +} diff --git a/examples/01-hello-syscalls/demo.sh b/examples/01-hello-syscalls/demo.sh new file mode 100755 index 0000000..afbbe4c --- /dev/null +++ b/examples/01-hello-syscalls/demo.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +set -euo pipefail +cd "$(dirname "$0")" + +langs=(cpp go rust) + +case "${1:-all}" in + cpp|go|rust) + lang="$1" + shift + exec "./$lang/demo.sh" "$@" + ;; + all) + for lang in "${langs[@]}"; do "./$lang/demo.sh"; done + ;; + build) + for lang in "${langs[@]}"; do "./$lang/demo.sh" build; done + ;; + *) + echo "usage: $0 [cpp|go|rust|all|build] [args...]" >&2 + exit 2 + ;; +esac diff --git a/examples/01-hello-syscalls/go/demo.sh b/examples/01-hello-syscalls/go/demo.sh new file mode 100755 index 0000000..28606df --- /dev/null +++ b/examples/01-hello-syscalls/go/demo.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +set -euo pipefail +cd "$(dirname "$0")" +REPO_ROOT="$(cd ../../.. && pwd)" +BIN=bin/app + +build() { + go build -o "$BIN" . +} + +run() { + if [[ -n "${TARGET:-}" ]]; then + exec "$REPO_ROOT/scripts/lab/deploy-to-vm.sh" "$TARGET" "$BIN" -- "$@" + fi + exec "./$BIN" "$@" +} + +case "${1:-}" in + build) build ;; + run) shift; run "$@" ;; + "") build; run ;; + *) echo "usage: $0 [build|run [args...]]" >&2; exit 2 ;; +esac diff --git a/examples/01-hello-syscalls/go/go.mod b/examples/01-hello-syscalls/go/go.mod new file mode 100644 index 0000000..b149e6a --- /dev/null +++ b/examples/01-hello-syscalls/go/go.mod @@ -0,0 +1,7 @@ +module github.com/patterncatalyst/linux-systems-programming/examples/01-hello-syscalls/go + +go 1.26 + +toolchain go1.26.5 + +require golang.org/x/sys v0.47.0 diff --git a/examples/01-hello-syscalls/go/go.sum b/examples/01-hello-syscalls/go/go.sum new file mode 100644 index 0000000..37ee2d4 --- /dev/null +++ b/examples/01-hello-syscalls/go/go.sum @@ -0,0 +1,2 @@ +golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= +golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= diff --git a/examples/01-hello-syscalls/go/main.go b/examples/01-hello-syscalls/go/main.go new file mode 100644 index 0000000..98d75b2 --- /dev/null +++ b/examples/01-hello-syscalls/go/main.go @@ -0,0 +1,30 @@ +// hello-syscall: print "pid on ()". +package main + +import ( + "fmt" + "os" + + "golang.org/x/sys/unix" +) + +func helloLine() (string, error) { + var uts unix.Utsname + if err := unix.Uname(&uts); err != nil { + return "", fmt.Errorf("uname: %w", err) + } + return fmt.Sprintf("pid %d on %s %s (%s)", + unix.Getpid(), + unix.ByteSliceToString(uts.Sysname[:]), + unix.ByteSliceToString(uts.Release[:]), + unix.ByteSliceToString(uts.Machine[:])), nil +} + +func main() { + line, err := helloLine() + if err != nil { + fmt.Fprintln(os.Stderr, "error:", err) + os.Exit(1) + } + fmt.Println(line) +} diff --git a/examples/01-hello-syscalls/rust/Cargo.lock b/examples/01-hello-syscalls/rust/Cargo.lock new file mode 100644 index 0000000..9fc0988 --- /dev/null +++ b/examples/01-hello-syscalls/rust/Cargo.lock @@ -0,0 +1,66 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "bitflags" +version = "2.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "libc" +version = "0.2.186" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + +[[package]] +name = "rustix" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "template-hello" +version = "0.1.0" +dependencies = [ + "rustix", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] diff --git a/examples/01-hello-syscalls/rust/Cargo.toml b/examples/01-hello-syscalls/rust/Cargo.toml new file mode 100644 index 0000000..62c962f --- /dev/null +++ b/examples/01-hello-syscalls/rust/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "template-hello" +version = "0.1.0" +edition = "2024" + +[[bin]] +name = "app" +path = "src/main.rs" + +[dependencies] +rustix = { version = "1", features = ["system"] } diff --git a/examples/01-hello-syscalls/rust/demo.sh b/examples/01-hello-syscalls/rust/demo.sh new file mode 100755 index 0000000..220feea --- /dev/null +++ b/examples/01-hello-syscalls/rust/demo.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +set -euo pipefail +cd "$(dirname "${BASH_SOURCE[0]}")" + +BIN=target/release/app + +build() { + cargo build --release +} + +run() { + if [[ -n "${TARGET:-}" ]]; then + local repo_root + repo_root=$(cd ../../.. && pwd) + "$repo_root/scripts/lab/deploy-to-vm.sh" "$TARGET" "$BIN" -- "$@" + else + "./$BIN" "$@" + fi +} + +case "${1:-}" in + build) build ;; + run) shift; run "$@" ;; + "") build; run ;; + *) echo "usage: $0 [build|run [args...]]" >&2; exit 2 ;; +esac diff --git a/examples/01-hello-syscalls/rust/rust-toolchain.toml b/examples/01-hello-syscalls/rust/rust-toolchain.toml new file mode 100644 index 0000000..4099f1a --- /dev/null +++ b/examples/01-hello-syscalls/rust/rust-toolchain.toml @@ -0,0 +1,3 @@ +[toolchain] +channel = "1.97.1" +components = ["rustfmt", "clippy", "rust-src"] diff --git a/examples/01-hello-syscalls/rust/src/main.rs b/examples/01-hello-syscalls/rust/src/main.rs new file mode 100644 index 0000000..9536d12 --- /dev/null +++ b/examples/01-hello-syscalls/rust/src/main.rs @@ -0,0 +1,12 @@ +use rustix::system::uname; + +fn main() { + let info = uname(); + println!( + "pid {} on {} {} ({})", + std::process::id(), + info.sysname().to_string_lossy(), + info.release().to_string_lossy(), + info.machine().to_string_lossy(), + ); +} diff --git a/examples/01-hello-syscalls/verify.lua b/examples/01-hello-syscalls/verify.lua new file mode 100644 index 0000000..230569e --- /dev/null +++ b/examples/01-hello-syscalls/verify.lua @@ -0,0 +1,17 @@ +-- Verify the hello-syscall template: run the demo for LSP_LANG and check its output. +-- Invoked from the example directory with LSP_LANG (cpp|go|rust) and EXAMPLE_DIR set. + +local script_dir = arg[0]:match("(.*/)") or "./" +local repo_root = os.getenv("REPO_ROOT") or (script_dir .. "../..") +package.path = package.path .. ";" .. repo_root .. "/scripts/lib/?.lua" +local checks = require("checks") + +local lang = os.getenv("LSP_LANG") +if lang ~= "cpp" and lang ~= "go" and lang ~= "rust" then + checks.skip("LSP_LANG must be cpp|go|rust (got " .. tostring(lang) .. ")") +end + +local r = checks.run("./demo.sh " .. lang .. " run") +checks.expect_exit(r, 0, lang .. ": demo exits 0") +checks.expect_match(r.out, "pid %d+ on Linux", lang .. ": prints pid/uname line") +checks.finish() diff --git a/examples/_infra/compose-lgtm.yaml b/examples/_infra/compose-lgtm.yaml index 503787a..47ddcf7 100644 --- a/examples/_infra/compose-lgtm.yaml +++ b/examples/_infra/compose-lgtm.yaml @@ -28,7 +28,8 @@ services: - GF_AUTH_ANONYMOUS_ORG_ROLE=Admin - GF_AUTH_DISABLE_LOGIN_FORM=true healthcheck: - test: ["CMD", "wget", "-qO-", "http://localhost:3000/api/health"] + # curl, not wget — the otel-lgtm image ships curl only + test: ["CMD", "curl", "-sf", "http://localhost:3000/api/health"] interval: 5s timeout: 3s retries: 20 diff --git a/examples/manifest.yaml b/examples/manifest.yaml index 6337fb2..109bb1c 100644 --- a/examples/manifest.yaml +++ b/examples/manifest.yaml @@ -13,3 +13,7 @@ examples: langs: [cpp, go, rust] mode: local timeout: 180 + - id: 01-hello-syscalls + langs: [cpp, go, rust] + mode: local + timeout: 180 diff --git a/scripts/check-host.sh b/scripts/check-host.sh index 43c09ca..b57e7a6 100755 --- a/scripts/check-host.sh +++ b/scripts/check-host.sh @@ -158,7 +158,15 @@ else fi # ── Lua / Python ───────────────────────────────────────────────────────── -check_version "lua >= 5.4" lua -v 5 4 lua +# The verify harness runs under lua 5.4 (CI) but falls back to luajit locally, +# so either interpreter satisfies the hard requirement. +if command -v lua >/dev/null 2>&1; then + check_version "lua >= 5.4" lua -v 5 4 lua +elif command -v luajit >/dev/null 2>&1; then + record warn "lua >= 5.4" "luajit $(luajit -v 2>&1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1) only — verify harness falls back to it; install lua for 5.4 parity with CI" "sudo dnf install -y lua" +else + record fail "lua >= 5.4" "neither lua nor luajit installed" "sudo dnf install -y lua" +fi if command -v python3 >/dev/null 2>&1; then record ok "python3" "$(python3 --version 2>&1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)" diff --git a/scripts/lab/provision-vm.sh b/scripts/lab/provision-vm.sh index 016e085..c34a5e6 100755 --- a/scripts/lab/provision-vm.sh +++ b/scripts/lab/provision-vm.sh @@ -3,7 +3,7 @@ # provision-vm.sh — provision a Fedora KVM guest via cloud-init for a # systems-programming / kernel test lab. # -# export LAB_PREFIX=myproject # names everything (default: lab) +# export LAB_PREFIX=myproject # names everything (default: systems) # ./provision-vm.sh "$LAB_PREFIX-target" # the deploy target # ./provision-vm.sh "$LAB_PREFIX-peer" # optional 2nd host for networking tests # @@ -99,7 +99,7 @@ ok "domain $VM_NAME created" echo echo "Wait ~60s for cloud-init, then find its IP:" echo " ./vm-ip.sh $VM_NAME" -echo "confirm it's ready (expect 'BTF: present'):" +echo "confirm it's ready (expect a bpftrace version + kernel release):" echo " ssh fedora@\$(./vm-ip.sh $VM_NAME) 'cat /var/log/lab-ready'" echo "then snapshot the tooled baseline:" echo " ./snapshot-vm.sh $VM_NAME" diff --git a/scripts/new-example.sh b/scripts/new-example.sh index 3dcd77e..d3863bb 100755 --- a/scripts/new-example.sh +++ b/scripts/new-example.sh @@ -19,6 +19,10 @@ dst="$repo_root/examples/$name" cp -r "$src" "$dst" +# Strip build outputs the template may have on disk (gitignored, but a copied +# CMake cache poisons the new example's out-of-source build). +rm -rf "$dst/cpp/build" "$dst/go/bin" "$dst/rust/target" + if [[ -f "$dst/go/go.mod" ]]; then sed -i "s|_template|$name|g" "$dst/go/go.mod" else