Skip to content

About

No description, website, or topics provided.

Resources

Stars

4 stars

Watchers

0 watching

Forks

Repository files navigation

BareMetal-App

A quick way to get going with testing BareMetal-Firecracker, BareMetal-AppPort, and uploading your program to BareMetal Cloud.

BareMetal is an exokernel written in x86-64 Assembly that expects a payload program. Your C program is compiled into an .app and is combined with the BareMetal kernel to produce a single bootable .elf unikernel. It can then be run directly in Firecracker microVM with as little as 4MiB of RAM. This repo wires together the pieces needed to go from a C file on your laptop to a running instance, either locally in a VM for fast iteration or on BareMetal Cloud for real deployment.

Quickstart

Log into BareMetal Cloud, open API keys, and create a new API key.

Enter the following commands, pasting the new key when ./bmcloud login asks for it:

git clone https://github.com/ReturnInfinity/BareMetal-App
cd BareMetal-App
./setup.sh
./bmcloud login
cp BareMetal-AppPort/hello.c .
./1-build.sh hello.c
./2-run.sh
./3-upload.sh

When prompted to upload to cloud hit Y. Your program should be running in BareMetal Cloud now.

./1-build.sh writes the name of the .app it built to .prog_app in the repo root, which ./3-upload.sh reads back so it knows which file to upload — this is what lets the two scripts be run separately, one after the other.

Confirm it: ./bmcloud vm list

Requirements

The following commands must be installed before running ./setup.sh: git, curl, unzip, tar, gcc, nasm, make, patch, jq, mkfs.ext2 (from e2fsprogs). The script will check for these.

To run VMs locally you'll also need Firecracker installed and accessible, screen, and your user must be in the kvm group:

sudo usermod -aG kvm $YOURUSERNAME

Log out and back in for the group change to take effect.

Clone

git clone https://github.com/ReturnInfinity/BareMetal-App
cd BareMetal-App

Setup

./setup.sh

This runs a "pre-flight" check to verify the prerequisites above are installed (including mkfs.ext2, from e2fsprogs), then clones BareMetal-AppPort and BareMetal-Firecracker alongside this repo, copies the bundled libraries in files/ (lwIP, mbedTLS, musl) into the app-port build directory, builds everything, and downloads the bmcloud CLI into the repo root. It also creates a 512M disk.img, formatted as a plain EXT2 filesystem (mkfs.ext2 -b 4096 - the 4096-byte block size matters, see setup.sh's comment) for the VM to boot against; BareMetal-AppPort/port/ext4_shim.c mounts it through lwext4. A CA bundle (files/cacert.pem) is installed onto that image too, so https:// requests (tls_shim.c, curltest.c) verify the server's certificate rather than trusting it blindly; the same bundle is also compiled directly into every app binary as a fallback, so verification still works even with no disk attached at all.

Re-running ./setup.sh starts from a clean slate — it calls ./clean.sh first, which removes the cloned repos, baremetal.elf, disk.img, and bmcloud.

Write a program

Any standard C program is a valid starting point. For example:

echo -e '#include <stdio.h>\n\nint main(void) {\n    printf("Hello, World!\\n");\n    return 0;\n}' > hello.c

Build it

./1-build.sh hello.c

You can also use multiple C files:

./1-build.sh testjson.c cjson/cjson.c

This will:

  1. Build your program into a BareMetal .app via BareMetal-AppPort/build-app.sh.
  2. Link it into a bootable kernel image via BareMetal-Firecracker/build.sh, producing baremetal.elf in the repo root.

Run a SQL script with SQLite

./1-build.sh script.sql [database.db|-]

As with .py and .lua files, nothing is compiled: sqlite.app (SQLite's own command-line shell, built by setup.sh) runs the script as /sqlite/main.sql on disk.img, against the database /sqlite/main.db, and prints each statement followed by its results. The database persists between runs. Give a local database file as the second argument to replace it with a copy, or - to start over with an empty one. Arguments to ./2-run.sh become shell options, e.g. ./2-run.sh -box or ./2-run.sh -header -csv. See examples/sqlite/hello.

Serve a website with lighttpd

./1-build.sh lighttpd [lighttpd.conf] [docroot-dir]

There's nothing to compile here: lighttpd.app (the lighttpd web server, see BareMetal-AppPort/LIGHTTPD.md) is already built by setup.sh. This copies a config to /lighttpd/lighttpd.conf on disk.img and the contents of a site directory to /lighttpd/www, replacing any previous site, then builds baremetal.elf around lighttpd.app. With no arguments it uses the sample config and site in BareMetal-AppPort/port/lighttpd_port/; start from that lighttpd.conf when writing your own. lighttpd listens on port 80 and keeps running until the VM is stopped. Under QEMU without tap0, forward a host port to it (see below):

HOSTFWD=18080:80 ./2-run-qemu.sh
curl http://127.0.0.1:18080/

Run it

./2-run.sh

Boot baremetal.elf locally under Firecracker and print its console output.

Run it under QEMU

./2-run-qemu.sh

Boot the same baremetal.elf in a QEMU microvm instead, with disk.img and a network device attached and the serial console in your terminal. QEMU exits when the app finishes; press Ctrl-A then X to quit early. Needs qemu-system-x86_64 and access to /dev/kvm. The network uses tap0 if it exists, otherwise QEMU's user-mode networking (outbound only, no host setup needed). There is no memory hot-plug under QEMU, so the VM gets MEMSIZE MiB up front (default 256; e.g. MEMSIZE=1024 ./2-run-qemu.sh). Arguments are passed to the app as with ./2-run.sh. To reach a server in the guest over user-mode networking, set HOSTFWD to space-separated host:guest TCP port pairs; e.g. HOSTFWD=18080:80 makes guest port 80 reachable at 127.0.0.1:18080 (with tap0, connect to the guest's own address instead).

Upload it

Uploading requires an API key. Create one on the API keys page of the BareMetal Cloud portal, then save it once with:

./bmcloud login

Upload baremetal.elf to BareMetal Cloud as a kernel image and launch it as a VM:

./3-upload.sh

The image and the VM are both named after your program (e.g. hello). See Deploying to BareMetal Cloud for managing it afterwards.

Local networking (optional)

Local VM testing needs a tap0 device. Create one with:

./BareMetal-Firecracker/scripts/mkbr0.sh

This sets up a br0 bridge with tap0 attached in promiscuous mode. On a wired connection the host NIC is enslaved to the bridge for full L2 visibility to the VM; on Wi-Fi (which can't be bridged in station mode) it falls back to NAT so the guest still has outbound connectivity. If tap0 isn't present, ./2-run.sh warns and starts the VM without network access, and ./2-run-qemu.sh falls back to QEMU's user-mode networking.

Managing the local VM

./baremetal.sh controls the Firecracker VM directly:

Command Description
start Configure and start the VM (kernel, disk, network, boot)
status Check if the VM is currently running
send <text> Send a line of text to the VM serial console
output [--full] Print new console output since the last check (--full for the entire log)
stop Gracefully shut down the VM (Ctrl+Alt+Del)
attach Attach to the interactive screen session for the console
help Show usage and current configuration

./2-run.sh calls start, attach (when screen is installed), and output --full for you; use these directly when iterating without rebuilding, or attach to interact with the running program.

Deploying to BareMetal Cloud

BareMetal Cloud UI

./3-upload.sh handles a single upload-and-launch flow. For everything else, use ./bmcloud, the BareMetal Cloud command-line client (setup.sh downloads it from https://baremetal.returninfinity.com/cli/bmcloud; ./3-upload.sh fetches it if it's missing). It needs bash 4+, curl, and jq.

Authenticate with an API key from the portal's API keys page, either saved once or set per shell:

./bmcloud login               # prompts for the key and saves it to ~/.config/bmcloud/credentials
export BMC_API_KEY=bmc_...    # or provide it per shell/session

Then:

./bmcloud [--json] [--url URL] <command> [args...]

VMs and images can be referred to by id or by a unique name.

Command Description
login / logout Save / remove the API key
whoami Account, plan, balance, and limits
vm list List your VMs
vm show <vm> Status, hostname, memory, disk, forwards, and domains of a VM
vm create <name> --kernel <image> [--ram MiB] [--hotplug MiB] [--disk ext2|raw|none|image] [--disk-size MiB] [--disk-image <image>] [--args "app args"] [--no-start] [--no-https] Create (and by default start) a VM
vm start|stop|suspend|resume <vm> Lifecycle actions (applied asynchronously)
vm wait <vm> <status> [--timeout SECONDS] Wait until a VM reaches a status, e.g. running
vm delete <vm> [--yes] Delete a VM and its disk
vm args <vm> "<app args>" Change app arguments (VM must be stopped)
vm memory <vm> <ram-mib> [hotplug-mib] Change memory (VM must be stopped)
vm console <vm> [--bytes N] [--follow] Print the VM's console output
vm usage <vm> Hourly resource usage and cost
vm forwards <vm> List port forwards
vm forward-add <vm> <http|tcp|udp> <guest-port> [public-port] Forward a public port (or the HTTPS hostname) to the VM
vm forward-rm <vm> <forward-id> Remove a port forward
vm domains <vm> Custom domains and the DNS records they need
vm domain-add <vm> <hostname> Add a custom domain
vm domain-check <vm> <domain-id> Retry the DNS check and certificate now
vm domain-rm <vm> <domain-id> Remove a custom domain
image list List your images
image upload <file> [--name NAME] [--kind auto|kernel|disk] Upload a built .elf (kernel) or a disk image
image delete <image> [--yes] Delete an image
billing Balance, spend, and recent transactions
billing usage Hourly usage records
billing topup <amount> Fund the account (opens Stripe Checkout)

Pass --json before a command to print the raw JSON API response instead (for scripting). Run ./bmcloud help for the full usage text.

Cleaning up

./clean.sh

Removes the cloned BareMetal-AppPort and BareMetal-Firecracker repos, examples, baremetal.elf, disk.img, .prog_app, and bmcloud. Your saved bmcloud login credentials are kept. setup.sh runs this automatically before rebuilding.

About

No description, website, or topics provided.

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages