### Install Prerequisites and Run Example Source: https://github.com/tikoci/quickchr/blob/main/examples/vienk/README.md Installs project dependencies using bun and then executes the vienk integration test. Ensure you have bun installed before running. ```bash # Install prerequisites (once): bun install # Run the example: QUICKCHR_INTEGRATION=1 bun test examples/vienk/vienk.test.ts ``` -------------------------------- ### Start interactive setup wizard Source: https://github.com/tikoci/quickchr/blob/main/README.md Launch the interactive wizard to set up a new CHR machine. ```bash quickchr setup ``` -------------------------------- ### Start a Lab CHR Instance Source: https://github.com/tikoci/quickchr/blob/main/test/lab/README.md Command to start a CHR instance for lab testing in the background. Ensure quickchr is installed and configured. ```bash bun run dev -- start --name lab-pool --background ``` -------------------------------- ### QuickCHR Integration Test Example Source: https://github.com/tikoci/quickchr/blob/main/README.md Shows how to use QuickCHR within a test suite, starting an instance, performing checks, and cleaning up afterwards. ```typescript import { describe, test, afterAll, expect } from "bun:test"; import { QuickCHR } from "@tikoci/quickchr"; let chr: Awaited>; test("boot CHR and check version", async () => { chr = await QuickCHR.start({ channel: "stable" }); const resource = await chr.rest("/system/resource"); expect(resource["board-name"]).toBe("CHR"); }, 120_000); afterAll(async () => { if (chr) await chr.remove(); }); ``` -------------------------------- ### Install QEMU on Ubuntu/Debian Source: https://github.com/tikoci/quickchr/blob/main/README.md Install QEMU system components and utilities on Ubuntu or Debian-based systems. ```bash sudo apt install qemu-system-x86 qemu-system-arm qemu-efi-aarch64 qemu-utils ``` -------------------------------- ### QuickCHR Library Usage Example Source: https://github.com/tikoci/quickchr/blob/main/README.md Demonstrates starting a CHR instance, interacting with its REST API and CLI, and checking its state using the QuickCHR TypeScript library. ```typescript import { QuickCHR } from "@tikoci/quickchr"; // Start a CHR instance const chr = await QuickCHR.start({ name: "disk-lab", channel: "stable", arch: "arm64", mem: 512, bootSize: "1G", extraDisks: ["512M", "2G"], }); // Use REST API const info = await chr.rest("/system/resource"); console.log(info); // Run a RouterOS CLI command const result = await chr.exec("/system/resource/print"); console.log(result); // Stop (or remove) await chr.stop(); await chr.remove(); console.log(chr.state.bootDiskFormat); // "qcow2" console.log(chr.state.extraDisks); // ["512M", "2G"] ``` -------------------------------- ### Install QEMU and Bun on Windows Source: https://github.com/tikoci/quickchr/blob/main/README.md Install QEMU using winget and Bun using the official PowerShell script on Windows. ```powershell # Windows — install QEMU (qemu-img is included) winget install SoftwareFreedomConservancy.QEMU # Install Bun (PowerShell — matches bun.sh official install docs) powershell -c "irm bun.sh/install.ps1 | iex" # Alternative: winget install Oven-sh.Bun ``` -------------------------------- ### Install QEMU on Arch Linux Source: https://github.com/tikoci/quickchr/blob/main/README.md Install the full QEMU package on Arch Linux. ```bash sudo pacman -S qemu-full ``` -------------------------------- ### Install quickchr CLI from Source Source: https://github.com/tikoci/quickchr/blob/main/MANUAL.md Installs the quickchr CLI from its GitHub repository for development or testing purposes. Requires Git and Bun. ```bash git clone https://github.com/tikoci/quickchr cd quickchr bun install bun run dev -- doctor ``` -------------------------------- ### QuickCHR Static Methods Source: https://github.com/tikoci/quickchr/blob/main/MANUAL.md Use these static methods on the QuickCHR class for machine lifecycle management. `start()` creates and provisions a machine, `add()` materializes a machine without starting it, `list()` retrieves all machines, `get()` fetches a specific machine instance, `doctor()` diagnoses issues, and `resolveVersion()` gets the latest version for a channel. ```typescript QuickCHR.start(opts?: StartOptions): Promise QuickCHR.add(opts?: StartOptions): Promise QuickCHR.list(): MachineState[] QuickCHR.get(name: string): ChrInstance | null QuickCHR.doctor(): Promise QuickCHR.resolveVersion(channel: Channel): Promise ``` -------------------------------- ### Install QEMU on macOS Source: https://github.com/tikoci/quickchr/blob/main/README.md Use Homebrew to install QEMU on macOS. ```bash brew install qemu ``` -------------------------------- ### Install QEMU on Fedora/RHEL Source: https://github.com/tikoci/quickchr/blob/main/README.md Install QEMU KVM, system components, UEFI firmware, and utilities on Fedora or RHEL-based systems. ```bash sudo dnf install qemu-kvm qemu-system-aarch64 edk2-aarch64 qemu-img ``` -------------------------------- ### Clone and Install Dependencies with Bun Source: https://github.com/tikoci/quickchr/blob/main/CONTRIBUTING.md Clone the repository and install project dependencies using Bun. This is the initial step for setting up the development environment. ```bash git clone https://github.com/tikoci/quickchr cd quickchr bun install ``` -------------------------------- ### QuickCHR.add() - Register Machine Without Starting Source: https://context7.com/tikoci/quickchr/llms.txt Allocates ports, downloads the image, and materializes disks but does not spawn QEMU. Provisioning options are stored and applied on the first `start()` call. Use this to pre-configure a machine. ```typescript import { QuickCHR } from "@tikoci/quickchr"; const state = await QuickCHR.add({ name: "lab-router", channel: "stable", arch: "x86", bootSize: "2G", packages: ["dude"], }); console.log(state.name); // "lab-router" console.log(state.status); // "stopped" console.log(state.portBase); // e.g. 9100 // Later — start it (provisioning runs now) const chr = await QuickCHR.start({ name: "lab-router" }); await chr.stop(); ``` -------------------------------- ### Start Quickchr with Named Networks Source: https://github.com/tikoci/quickchr/blob/main/docs/networking.md Use these commands to start a quickchr instance with pre-configured networks from the registry. Multiple networks can be added using the --add-network flag. ```bash quickchr start my-chr --add-network shared quickchr start my-chr --add-network wifibridge quickchr start my-chr --add-network tap-nat ``` ```bash quickchr start my-chr --add-network user --add-network socket::hub-link --add-network wifibridge ``` -------------------------------- ### Start Quickchr VM with SLiRP Source: https://github.com/tikoci/quickchr/blob/main/test/lab/slirp-hostfwd/REPORT.md Starts a quickchr VM with SLiRP networking enabled. This is a baseline for testing hostfwd functionality. ```bash quickchr start slirp-exp1 --arch x86 --background --no-provision ``` -------------------------------- ### Import quickchr in consumer project Source: https://github.com/tikoci/quickchr/blob/main/examples/README.md Example of importing QuickCHR from an external consumer project after installing it via npm, local path, or bun link. Use the package name for imports. ```ts // your-consumer/test.ts import { QuickCHR, type ChrInstance } from "@tikoci/quickchr"; ``` -------------------------------- ### Install TAP-Windows Adapter Source: https://github.com/tikoci/quickchr/blob/main/docs/networking.md Instructions for installing the TAP-Windows adapter, which creates a virtual Ethernet adapter for kernel-level networking. This is typically done via the OpenVPN installer or a standalone download. ```powershell # Install via OpenVPN (includes driver) or standalone: # https://github.com/OpenVPN/tap-windows6/releases ``` -------------------------------- ### QuickCHR Static Methods Source: https://github.com/tikoci/quickchr/blob/main/MANUAL.md Provides an overview of the static methods available on the QuickCHR class for starting, adding, listing, getting, diagnosing, and resolving versions of QuickCHR machines. ```APIDOC ## QuickCHR Class Static Methods ### `QuickCHR.start(opts?: StartOptions): Promise` **Description**: Creates the machine if it doesn't exist, downloads the image, allocates a port block, spawns QEMU, waits for REST readiness, and runs all provisioning steps. It auto-cleans the machine if boot times out and acquires a `start-lock` to serialize concurrent starts. ### `QuickCHR.add(opts?: StartOptions): Promise` **Description**: Similar to `start()`, but without spawning QEMU. This is useful for materializing a machine and starting it later, or handing its configuration to another process. ### `QuickCHR.list(): MachineState[]` **Description**: Returns an array of `MachineState` for all machines found in the `machines/` directory. ### `QuickCHR.get(name: string): ChrInstance | null` **Description**: Retrieves a runtime handle for a specific machine by name. Returns `null` if the machine does not exist. It loads `machine.json`, refreshes PID liveness, and returns the handle. ### `QuickCHR.doctor(): Promise` **Description**: Runs diagnostic checks on the QuickCHR environment and returns a `DoctorResult`. ### `QuickCHR.resolveVersion(channel: Channel): Promise` **Description**: Resolves and returns the latest available version string for a given `Channel` (e.g., 'stable', 'beta'). ``` -------------------------------- ### Run example tests Source: https://github.com/tikoci/quickchr/blob/main/examples/README.md Execute the integrated tests for quickchr using Bun's test runner. These examples demonstrate integration with CHR VMs and can be run with specific environment variables. ```sh QUICKCHR_INTEGRATION=1 bun test examples/vienk/vienk.test.ts QUICKCHR_INTEGRATION=1 bun test examples/matrica/matrica.test.ts ``` ```sh bun run test:examples ``` -------------------------------- ### Create and start CHR machine Source: https://github.com/tikoci/quickchr/blob/main/README.md Create and immediately start a new CHR machine with a specific version and boot disk size in a single step. ```bash quickchr start --name throwaway --version 7.22.1 --boot-size 2G ``` -------------------------------- ### Install quickchr CLI Source: https://github.com/tikoci/quickchr/blob/main/README.md Install the quickchr command-line interface globally using Bun and run a doctor check. ```bash bun install -g @tikoci/quickchr quickchr doctor ``` -------------------------------- ### Start Quickchr VM with SLiRP and Shared Networking Source: https://github.com/tikoci/quickchr/blob/main/test/lab/slirp-hostfwd/REPORT.md Starts a quickchr VM with both SLiRP (user) and shared (vmnet) network interfaces. SLiRP is configured on ether1. ```bash quickchr start slirp-exp2 --arch x86 --background --no-provision \ --add-network user --add-network shared ``` -------------------------------- ### Start an existing CHR machine Source: https://github.com/tikoci/quickchr/blob/main/README.md Start a previously created CHR machine instance by its name. ```bash quickchr start my-chr ``` -------------------------------- ### QuickCHR.add() Source: https://context7.com/tikoci/quickchr/llms.txt Registers a machine without starting it. This method allocates ports, downloads the necessary image, and materializes the disks. Provisioning options are stored and will be applied when the machine is started for the first time using `QuickCHR.start()`. ```APIDOC ## QuickCHR.add() ### Description Allocates ports, downloads the image, and materializes disks, but does not spawn QEMU. Provisioning options are stored and applied on the first `start()` call. ### Method `QuickCHR.add(options: AddOptions)` ### Parameters #### Options (`AddOptions`) - **name** (string) - Required - A unique name for the machine. - **channel** (string) - Required - The RouterOS channel to download (e.g., "stable", "long-term"). - **arch** (string) - Optional - The architecture of the CHR image (e.g., "x86", "arm64"). Defaults to host-native. - **bootSize** (string) - Optional - Size of the boot disk (e.g., "2G"). - **packages** (string[]) - Optional - Array of packages to install (e.g., ["dude"]). ### Returns - `Promise` - A promise that resolves to the machine's state object. ### Request Example ```typescript import { QuickCHR } from "@tikoci/quickchr"; const state = await QuickCHR.add({ name: "lab-router", channel: "stable", arch: "x86", bootSize: "2G", packages: ["dude"], }); console.log(state.name); console.log(state.status); console.log(state.portBase); // Later, to start it: const chr = await QuickCHR.start({ name: "lab-router" }); await chr.stop(); ``` ### Response Example (MachineState object with properties like `name`, `status`, `portBase`, etc.) ``` -------------------------------- ### Add @tikoci/quickchr via local path Source: https://github.com/tikoci/quickchr/blob/main/examples/README.md Install the package directly from a local directory, useful for sibling projects. Edits to the source are picked up on the next Bun invocation without a rebuild step. ```sh bun add file:../quickchr ``` ```json { "dependencies": { "@tikoci/quickchr": "file:../quickchr" } } ``` -------------------------------- ### Setup Quickchr Network in CI Source: https://github.com/tikoci/quickchr/blob/main/docs/networking.md Configures a TAP interface and enables IP forwarding for Quickchr in a CI environment. Ensure this is run with sufficient privileges. ```bash sudo ip tuntap add dev tap-chr0 mode tap user runner sudo ip link set tap-chr0 up sudo sysctl -w net.ipv4.ip_forward=1 ``` -------------------------------- ### ChrInstance.installPackage Source: https://context7.com/tikoci/quickchr/llms.txt Downloads and installs extra RouterOS packages from `all_packages.zip`, then reboots the instance. ```APIDOC ## ChrInstance.installPackage() ### Description Downloads and installs extra packages from MikroTik's `all_packages.zip`, then reboots. Requires RouterOS ≥ 7.20.8. ### Methods - `availablePackages()`: Lists all available packages that can be installed. - `installPackage(packageNames: string[])`: Installs one or more specified packages. ### Request Example (Install) ```typescript const installed = await chr.installPackage(["dude", "container"]); console.log(installed); ``` ### Response Example (Installed Packages) ```json ["routeros", "dude", "container"] ``` ``` -------------------------------- ### Check prerequisites Source: https://github.com/tikoci/quickchr/blob/main/README.md Verify that all necessary prerequisites for quickchr are installed and configured correctly. ```bash quickchr doctor ``` -------------------------------- ### Configure qemu-bridge-helper for Automatic Bridging Source: https://github.com/tikoci/quickchr/blob/main/docs/networking.md Sets up the qemu-bridge-helper to automatically create and manage TAP devices for a specified bridge (br0). This avoids the need for sudo when starting QEMU. ```sh # Enable bridge (root, once) sudo mkdir -p /etc/qemu echo "allow br0" | sudo tee /etc/qemu/bridge.conf sudo chmod 640 /etc/qemu/bridge.conf # QEMU start — bridge helper handles TAP creation (setuid, transparent) qemu-system-x86_64 \ -netdev bridge,id=net0,br=br0 \ -device virtio-net-pci,netdev=net0 ``` -------------------------------- ### Run Integration Tests with QEMU Source: https://github.com/tikoci/quickchr/blob/main/CONTRIBUTING.md Execute integration tests which require QEMU to be installed. Ensure the QUICKCHR_INTEGRATION environment variable is set. ```bash QUICKCHR_INTEGRATION=1 bun test test/integration/ ``` -------------------------------- ### Start Quickchr VM with Reversed NIC Order Source: https://github.com/tikoci/quickchr/blob/main/test/lab/slirp-hostfwd/REPORT.md Starts a quickchr VM with shared networking on ether1 and SLiRP (user) networking on ether2. This tests the impact of NIC order on SLiRP functionality. ```bash quickchr start slirp-exp3 --arch x86 --background --no-provision \ --add-network shared --add-network user ``` -------------------------------- ### Install RouterOS Packages with QuickCHR Source: https://context7.com/tikoci/quickchr/llms.txt Downloads and installs extra packages from MikroTik's `all_packages.zip`, then reboots. Requires RouterOS ≥ 7.20.8. The function waits for the REST API to become available after the reboot. ```typescript import { QuickCHR } from "@tikoci/quickchr"; const chr = await QuickCHR.start({ channel: "long-term" }); // List available packages const available = await chr.availablePackages(); console.log(available); // ["calea", "container", "dude", "gps", "iot", "openflow", ...] // Install one or more packages (reboots and waits for REST to return) const installed = await chr.installPackage(["dude", "container"]); console.log(installed); // ["dude", "container"] // Verify const pkgs = await chr.rest("/system/package") as Array>; console.log(pkgs.map((p) => p.name)); // ["routeros", "dude", "container"] await chr.remove(); ``` -------------------------------- ### Configure static DHCP for socket_vmnet Source: https://github.com/tikoci/quickchr/blob/main/docs/networking.md Shows an example of an /etc/bootptab file to assign static IP addresses to VMs based on their MAC addresses when using socket_vmnet. ```text %% # hostname hwtype hwaddr ipaddr chr-router 1 52:54:00:ab:cd:01 192.168.105.10 chr-branch 1 52:54:00:ab:cd:02 192.168.105.11 ``` -------------------------------- ### Multi-NIC socket_vmnet Setup Source: https://github.com/tikoci/quickchr/blob/main/docs/networking.md This shell command demonstrates how to chain multiple `socket_vmnet_client` calls for dual-socket-vmnet configurations, passing different file descriptors (fd) for each network interface. ```sh # Multi-NIC with two different socket_vmnet networks socket_vmnet_client /var/run/socket_vmnet \ socket_vmnet_client /var/run/socket_vmnet.bridged.en0 \ qemu-system-aarch64 \ -netdev socket,id=net0,fd=3 \ -device virtio-net-pci,netdev=net0 \ -netdev socket,id=net1,fd=4 \ -device virtio-net-pci,netdev=net1 \ ... ``` -------------------------------- ### Add @tikoci/quickchr via npm Source: https://github.com/tikoci/quickchr/blob/main/examples/README.md Use this command to install the stable or pre-release version of the package from npm. The stable channel uses the 'latest' tag, while pre-releases use the 'next' tag. ```sh bun add @tikoci/quickchr # stable channel (latest) bun add @tikoci/quickchr@next # pre-release channel ``` -------------------------------- ### Boot Timeout Calculation Source: https://github.com/tikoci/quickchr/blob/main/MANUAL.md Calculates the base boot timeout, considering acceleration factors and package installation. Use --timeout-extra to add a buffer for slow hosts. ```text base = ceil(120s × accelTimeoutFactor(accel, isCrossArch)) withPackages ? base × 2 : base final = base + (timeoutExtra ms) ``` -------------------------------- ### QuickCHR.start() Source: https://context7.com/tikoci/quickchr/llms.txt Creates and boots a CHR instance. This method downloads the RouterOS image if not cached, allocates ports, starts QEMU, and waits for the VM to boot and complete all requested provisioning. It returns a `ChrInstance` object that is ready for REST API access. ```APIDOC ## QuickCHR.start() ### Description Downloads the RouterOS image (if not cached), allocates a port block, spawns QEMU, waits for boot, and runs all requested provisioning. Returns a `ChrInstance` that is immediately REST-ready. ### Method `QuickCHR.start(options?: StartOptions)` ### Parameters #### Options (`StartOptions`) - **channel** (string) - Required - The RouterOS channel to download (e.g., "stable", "long-term"). - **arch** (string) - Optional - The architecture of the CHR image (e.g., "x86", "arm64"). Defaults to host-native. - **cpu** (number) - Optional - Number of CPU cores to allocate. - **mem** (number) - Optional - Amount of memory in MB to allocate. - **bootSize** (string) - Optional - Size of the boot disk (e.g., "1G"). - **extraDisks** (string[]) - Optional - Array of additional disk sizes (e.g., ["512M", "2G"]). - **packages** (string[]) - Optional - Array of packages to install (e.g., ["container", "dude"]). - **user** (object) - Optional - User creation options: `{ name: string, password: string }`. - **disableAdmin** (boolean) - Optional - If true, disables the default admin user. - **license** (object) - Optional - License details: `{ level: string, account: string, password: string }`. - **deviceMode** (object) - Optional - Device mode configuration: `{ mode: string, enable: string[] }`. - **onProgress** (function) - Optional - Callback function to report provisioning progress. - **dryRun** (boolean) - Optional - If true, returns an instance handle without spawning QEMU. ### Returns - `Promise` - A promise that resolves to a `ChrInstance` object. ### Request Example ```typescript import { QuickCHR } from "@tikoci/quickchr"; // Minimal example const chr = await QuickCHR.start({ channel: "stable" }); console.log(chr.restUrl); console.log(chr.ports); await chr.remove(); // Full provisioning example const chr2 = await QuickCHR.start({ channel: "long-term", arch: "arm64", cpu: 2, mem: 1024, bootSize: "1G", extraDisks: ["512M", "2G"], packages: ["container", "dude"], user: { name: "ops", password: "s3cr3t" }, disableAdmin: true, license: { level: "p1", account: "me@example.com", password: "mikrotik-pw" }, deviceMode: { mode: "advanced", enable: ["container"] }, onProgress: (msg) => process.stdout.write(msg + "\n"), }); const res = await chr2.rest("/system/resource"); console.log(res); await chr2.remove(); // Dry run example const dry = await QuickCHR.start({ channel: "stable", dryRun: true }); console.log(dry.state.version); ``` ### Response Example (ChrInstance object with methods like `rest`, `remove`, `stop`, etc.) ``` -------------------------------- ### QuickCHR.start() - Create and Boot CHR Instance Source: https://context7.com/tikoci/quickchr/llms.txt Downloads the RouterOS image if not cached, allocates ports, spawns QEMU, and waits for boot. All provisioning completes before this method resolves, returning a ready `ChrInstance`. Use `dryRun: true` to get an instance handle without spawning QEMU. ```typescript import { QuickCHR, QuickCHRError } from "@tikoci/quickchr"; // Minimal: latest stable, host-native arch const chr = await QuickCHR.start({ channel: "stable" }); console.log(chr.restUrl); // "http://127.0.0.1:9100" console.log(chr.ports); // { http: 9100, https: 9101, ssh: 9102, ... } await chr.remove(); // Full provisioning: custom disk, packages, user, license, device-mode const chr2 = await QuickCHR.start({ channel: "long-term", arch: "arm64", cpu: 2, mem: 1024, bootSize: "1G", extraDisks: ["512M", "2G"], packages: ["container", "dude"], user: { name: "ops", password: "s3cr3t" }, disableAdmin: true, license: { level: "p1", account: "me@example.com", password: "mikrotik-pw" }, deviceMode: { mode: "advanced", enable: ["container"] }, onProgress: (msg) => process.stdout.write(msg + "\n"), }); const res = await chr2.rest("/system/resource"); console.log(res); // { "board-name": "CHR", "version": "7.22.1", "cpu-load": 0, ... } await chr2.remove(); // Dry run — returns instance handle without spawning QEMU const dry = await QuickCHR.start({ channel: "stable", dryRun: true }); console.log(dry.state.version); // resolved version string, e.g. "7.22.1" ``` -------------------------------- ### Add macOS Shared NAT Network Source: https://github.com/tikoci/quickchr/blob/main/docs/networking.md Command to add a shared NAT network on macOS using socket_vmnet. This command installs the necessary components and starts the launchd service. ```sh # macOS — shared NAT (socket_vmnet) sudo quickchr network add shared --type shared # → installs socket_vmnet (if brew-installed), starts launchd service # → registers: type=socket_vmnet-shared, socketPath=/opt/homebrew/var/run/socket_vmnet ``` -------------------------------- ### RouterOS VM Configuration for Host NAT Source: https://github.com/tikoci/quickchr/blob/main/docs/networking.md Example configuration for a RouterOS VM to set a static IP address, default gateway, and DNS servers to utilize the host's NAT setup. ```routeros /ip address add address=10.100.0.2/24 interface=ether1 /ip route add gateway=10.100.0.1 /ip dns set servers=8.8.8.8 ``` -------------------------------- ### Explore /system/device-mode REST API with curl Source: https://github.com/tikoci/quickchr/blob/main/test/lab/device-mode/REPORT.md Use curl to perform GET requests for device-mode attributes and POST requests for updates. Includes examples for filtering properties and testing error responses. ```bash curl -s -u admin: http://127.0.0.1:9100/rest/system/device-mode | jq . ``` ```bash curl -s -u admin: 'http://127.0.0.1:9100/rest/system/device-mode?.proplist=mode,container' | jq . ``` ```bash curl -s -u admin: -X POST http://127.0.0.1:9100/rest/system/device-mode/update \ -H "Content-Type: application/json" -d '{"mode":"invalid"}' ``` ```bash curl -s -u admin: -X POST http://127.0.0.1:9100/rest/system/device-mode/update \ -H "Content-Type: application/json" -d '{"nonexistent":"true"}' ``` ```bash curl -s -u admin: -X POST http://127.0.0.1:9100/rest/system/device-mode/update \ -H "Content-Type: application/json" -d '{"container":"true","activation-timeout":"10s"}' ``` ```bash curl -s -u admin: -X POST http://127.0.0.1:9100/rest/system/device-mode/print ``` ```bash curl -s -u admin: -X POST http://127.0.0.1:9100/rest/execute \ -H "Content-Type: application/json" \ -d '{"script":"/system/device-mode/print","as-string":""}' ``` -------------------------------- ### Install quickchr CLI Globally (Future) Source: https://github.com/tikoci/quickchr/blob/main/MANUAL.md Installs the quickchr CLI globally using npm once version 0.2.0 is published. This command requires npm to be installed. ```bash bun install -g @tikoci/quickchr ``` -------------------------------- ### Start RouterOS in Background Mode Source: https://github.com/tikoci/quickchr/blob/main/README.md Starts a RouterOS instance in the background. The command returns after the CHR finishes booting. This is the default behavior. ```bash quickchr start --channel stable ``` -------------------------------- ### Set up shell completions Source: https://github.com/tikoci/quickchr/blob/main/README.md Generate shell completion scripts for bash, zsh, or fish. ```bash quickchr completions ``` -------------------------------- ### Add CHR machine without starting Source: https://github.com/tikoci/quickchr/blob/main/README.md Create a new CHR machine instance with a specified name, channel, and architecture, but do not start it. ```bash quickchr add --name my-chr --channel stable --arch arm64 ``` -------------------------------- ### Install socket_vmnet and configure bridged mode Source: https://github.com/tikoci/quickchr/blob/main/docs/networking.md Installs socket_vmnet via Homebrew and sets up a systemd service for bridged networking on a specified interface. ```sh # Install (keg-only — intentionally not in PATH) brew install socket_vmnet # Start as launchd system service (auto-restarts on reboot) sudo brew services start socket_vmnet # For bridged on en0: BRIDGED=en0 sed -e "s@/opt@$(brew --prefix)/opt@g; s@/var@$(brew --prefix)/var@g; s@en0@${BRIDGED}@g" \ "$(brew --prefix)/opt/socket_vmnet/share/socket_vmnet/launchd/io.github.lima-vm.socket_vmnet.bridged.en0.plist" \ | sudo tee /Library/LaunchDaemons/io.github.lima-vm.socket_vmnet.bridged.${BRIDGED}.plist sudo launchctl bootstrap system /Library/LaunchDaemons/io.github.lima-vm.socket_vmnet.bridged.${BRIDGED}.plist ``` -------------------------------- ### Add QEMU for Cross-Architecture Execution Source: https://github.com/tikoci/quickchr/blob/main/skills/tikoci-oci-image-building/references/alpine-image-recipe.md Include QEMU binaries in the image to enable running binaries of a different architecture (e.g., x86 on an ARM host). This example extracts `qemu-i386` from a binfmt support image. ```sh # Extract qemu-i386 from the binfmt support image crane export --platform linux/arm64 tonistiigi/binfmt:latest - | \ tar xf - usr/bin/qemu-i386 mv usr/bin/qemu-i386 rootfs/app/i386 chmod +x rootfs/app/i386 ``` -------------------------------- ### Start CHR Bridged to Physical Interface Source: https://github.com/tikoci/quickchr/blob/main/README.md Starts a CHR instance with a user-mode NIC and another NIC bridged to a physical interface (e.g., en0). ```bash quickchr start --name gw --add-network user --add-network bridged:en0 ``` -------------------------------- ### MAC Address Generation Example Source: https://github.com/tikoci/quickchr/blob/main/docs/networking.md This text format shows the structure of a MAC address generated by quickchr for socket_vmnet and bridge modes, using the QEMU OUI and a hash of the machine and network names. ```text 52:54:00::: ``` -------------------------------- ### Check QEMU and system prerequisites with QuickCHR.doctor() Source: https://context7.com/tikoci/quickchr/llms.txt Verifies QEMU binaries, firmware, acceleration, disk space, cached images, and optional tools. Logs the status of each check. ```typescript import { QuickCHR } from "@tikoci/quickchr"; const result = await QuickCHR.doctor(); console.log(result.ok); // true if no errors for (const check of result.checks) { const icon = check.status === "ok" ? "✓" : check.status === "warn" ? "⚠" : "✗"; console.log(`${icon} ${check.label}: ${check.detail}`); } // ✓ Bun runtime: bun 1.2.0 // ✓ qemu-system-aarch64: QEMU emulator version 9.2.0 // ✓ UEFI firmware: /opt/homebrew/share/qemu/edk2-aarch64-code.fd // ✓ Acceleration: hvf (host: arm64) // ✓ qemu-img: /opt/homebrew/bin/qemu-img // ⚠ socket_vmnet: installed but daemon not running ``` -------------------------------- ### Start CHRs on Shared Network (macOS/Linux) Source: https://github.com/tikoci/quickchr/blob/main/README.md Starts two CHR instances on a shared L2 segment using socket_vmnet on macOS or bridge on Linux. ```bash quickchr start --name router1 --add-network user --add-network shared quickchr start --name router2 --add-network user --add-network shared ``` -------------------------------- ### Attach QEMU to socket_vmnet client (No Root) Source: https://github.com/tikoci/quickchr/blob/main/docs/networking.md Launches QEMU using the socket_vmnet client, passing a file descriptor for network communication. This allows QEMU to run as a non-root user. ```sh # Note: no sudo here! $(brew --prefix)/opt/socket_vmnet/bin/socket_vmnet_client \ $(brew --prefix)/var/run/socket_vmnet \ qemu-system-aarch64 \ -netdev socket,id=net0,fd=3 \ -device virtio-net-pci,netdev=net0 \ [... other QEMU args ...] ``` -------------------------------- ### Start RouterOS in Foreground Mode Source: https://github.com/tikoci/quickchr/blob/main/README.md Starts a RouterOS instance in foreground mode, attaching the serial console to your terminal. Use Ctrl-A X to exit QEMU. ```bash quickchr start --channel stable --fg ``` -------------------------------- ### Compare QEMU vmnet attachment methods Source: https://github.com/tikoci/quickchr/blob/main/docs/networking.md Highlights the difference between using QEMU's built-in vmnet (requires root for QEMU) and socket_vmnet (root for daemon, QEMU runs as user). ```sh # Built-in vmnet — root required for ENTIRE QEMU process sudo qemu-system-aarch64 -netdev vmnet-shared,id=net0 ... # socket_vmnet — root is in the daemon, QEMU runs as your user socket_vmnet_client /var/run/socket_vmnet qemu-system-aarch64 -netdev socket,id=net0,fd=3 ... ``` -------------------------------- ### Run Unit Tests with Bun Source: https://github.com/tikoci/quickchr/blob/main/CONTRIBUTING.md Execute fast unit tests using Bun. These tests do not require external dependencies like QEMU. ```bash bun test test/unit/ ``` -------------------------------- ### Setup TAP + Bridge for Real LAN Access Source: https://github.com/tikoci/quickchr/blob/main/docs/networking.md Configures a bridge interface (br0) and adds a physical interface (eth0) and a TAP device (tap-chr0) to it, enabling LAN access for the VM. Requires root privileges for setup. ```sh # Setup (root, once) sudo ip link add br0 type bridge sudo ip link set eth0 master br0 # bridge physical interface sudo ip link set br0 up sudo ip tuntap add dev tap-chr0 mode tap user $USER sudo ip link set tap-chr0 up sudo ip link set tap-chr0 master br0 # add TAP to bridge # QEMU start (no sudo) qemu-system-x86_64 \ -netdev tap,id=net0,ifname=tap-chr0,script=no,downscript=no \ -device virtio-net-pci,netdev=net0 ``` -------------------------------- ### Manage VM Snapshots with QEMU Monitor Source: https://github.com/tikoci/quickchr/blob/main/MANUAL.md Use the `chr.snapshot` API to save, load, list, and delete VM snapshots. The boot disk must be qcow2 for save/load operations, which require the machine to be running. ```typescript await chr.snapshot.save("before-upgrade"); ``` ```typescript await chr.snapshot.load("before-upgrade"); ``` ```typescript await chr.snapshot.list(); ``` ```typescript await chr.snapshot.delete("before-upgrade"); ``` -------------------------------- ### Start ARM64 CHR Instances Source: https://github.com/tikoci/quickchr/blob/main/examples/matrica/README.md This command starts four ARM64 CHR instances in parallel, each configured for a different RouterOS channel (long-term, stable, testing, development). It specifies the architecture, base port, and required packages (zerotier, container). ```sh quickchr start matrica-longterm --channel long-term --arch arm64 --port-base 9200 --packages zerotier,container quickchr start matrica-stable --channel stable --arch arm64 --port-base 9210 --packages zerotier,container quickchr start matrica-testing --channel testing --arch arm64 --port-base 9220 --packages zerotier,container quickchr start matrica-dev --channel development --arch arm64 --port-base 9230 --packages zerotier,container ``` -------------------------------- ### QEMU System VM Launch Command Source: https://github.com/tikoci/quickchr/blob/main/skills/tikoci-qemu-user-emulation/references/macos-vm-bridging.md Launches a QEMU system VM with specific kernel, initramfs, and virtfs configurations. Requires sudo for vmnet-bridging and Homebrew's qemu package. ```sh sudo qemu-system-x86_64 \ -m 256M \ -kernel downloads/vmlinuz-virt \ -initrd downloads/initramfs-netinstall.gz \ -append "console=ttyS0 quiet" \ -virtfs local,path=.,mount_tag=hostfs,security_model=none \ -netdev vmnet-bridged,id=n0,ifname=en5 \ -device virtio-net-pci,netdev=n0 \ -nographic \ -no-reboot ``` -------------------------------- ### ChrInstance.snapshot Source: https://context7.com/tikoci/quickchr/llms.txt Manages VM snapshots for QEMU qcow2 boot disks. Supports saving, loading, listing, and deleting snapshots. ```APIDOC ## ChrInstance.snapshot ### Description Saves, loads, lists, and deletes QEMU qcow2 internal snapshots. Requires a qcow2 boot disk. ### Methods - `save(name: string)`: Saves a snapshot with the given name. - `list()`: Lists all available snapshots. - `load(name: string)`: Loads a snapshot with the given name. - `delete(name: string)`: Deletes a snapshot with the given name. ### Request Example (Save) ```typescript const snap = await chr.snapshot.save("baseline"); console.log(snap.name); ``` ### Request Example (List) ```typescript const snaps = await chr.snapshot.list(); console.log(snaps.map((s) => s.name)); ``` ### Request Example (Load) ```typescript await chr.snapshot.load("baseline"); ``` ### Request Example (Delete) ```typescript await chr.snapshot.delete("baseline"); ``` ``` -------------------------------- ### Get detailed status of a CHR instance Source: https://github.com/tikoci/quickchr/blob/main/README.md Retrieve and display detailed status information for a specific CHR instance. ```bash quickchr status my-chr ```