{"id":13876047,"url":"https://github.com/s-hamann/firecracker-tools","last_synced_at":"2025-05-07T08:13:58.794Z","repository":{"id":50590333,"uuid":"345740054","full_name":"s-hamann/firecracker-tools","owner":"s-hamann","description":"Scripts to handle Firecracker MicroVM deployments","archived":false,"fork":false,"pushed_at":"2025-03-18T18:38:49.000Z","size":387,"stargazers_count":6,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-07T08:13:49.702Z","etag":null,"topics":["firecracker","firecracker-microvms","microvm","microvms"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/s-hamann.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-03-08T17:32:30.000Z","updated_at":"2025-03-18T18:38:52.000Z","dependencies_parsed_at":"2024-01-13T19:43:35.733Z","dependency_job_id":"d6d12b35-caa0-42d0-8078-01860989e2cc","html_url":"https://github.com/s-hamann/firecracker-tools","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/s-hamann%2Ffirecracker-tools","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/s-hamann%2Ffirecracker-tools/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/s-hamann%2Ffirecracker-tools/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/s-hamann%2Ffirecracker-tools/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/s-hamann","download_url":"https://codeload.github.com/s-hamann/firecracker-tools/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252839296,"owners_count":21812089,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["firecracker","firecracker-microvms","microvm","microvms"],"created_at":"2024-08-06T06:00:58.574Z","updated_at":"2025-05-07T08:13:58.772Z","avatar_url":"https://github.com/s-hamann.png","language":"Shell","funding_links":[],"categories":["Shell","others"],"sub_categories":[],"readme":"About\n=====\n\nThis is a set of tools for use with the [Firecracker MicroVM hypervisor](http://firecracker-microvm.io/).\nThese scripts can be used to:\n1. Build a kernel image suitable for use with Firecracker.\n2. Build a root filesystem image suitable for use with Firecracker.\n3. Start a VM using Firecracker.\n\nThese scripts are suitable for non-interactive use, e.g. in a cronjob that rebuilds images or launches MicroVMs.\n\nDependencies\n============\n\nThese scripts generally do not have particularly exotic dependencies and should simply run on most modern Linux systems. The dependencies are listed here for completeness and for the benefit of those, who run non-mainstream systems or containers.\n\nbuild-kernel.sh\n---------------\n* bash\n* GNU Coreutils or BusyBox\n* GNU wget\n* curl\n* gnupg \u003e= 2.1.12\n* GNU grep\n* tar (GNU, BSD or BusyBox)\n* xz\n* gzip (optional)\n* bzip2 (optional)\n* file\n* binutils (or BusyBox)\n* patch (or BusyBox) (optional)\n* tput (ncurses, optional)\n* [Requirements to compile the Kernel](https://www.kernel.org/doc/html/latest/process/changes.html)\n\nbuild-rootfs.sh\n---------------\n* bash\n* GNU Coreutils or BusyBox\n* GNU wget\n* curl\n* gnupg \u003e= 2.1.12\n* util-linux\n* newuidmap, newgidmap (shadow)\n* awk (or BusyBox)\n* GNU grep\n* GNU tar or BSD tar (or BusyBox, but with limited functionality)\n* e2fsprogs\n* btrfs-progs (optional)\n* tput (ncurses, optional)\n\nfirestarter.py\n--------------\n* Python \u003e= 3.8\n* [packaging](https://github.com/pypa/packaging) (optional)\n* Firecracker (and Jailer)\n* iproute2 (optional)\n\nUsage\n=====\n\nAll scripts provide usage information when called with the parameter `--help` or `-h`.\nThis section provides additional information.\n\nbuild-kernel.sh\n---------------\n\nThis scripts builds a kernel image that can be used by Firecracker.\nRefer to `build-kernel.sh --help` for a list of parameters.\nAll parameters are optional.\nWhen called without any parameters, `build-kernel.sh` does the following:\n1. Determine the latest stable kernel version.\n2. Download the source code for this version.\n3. Verify the PGP signature on the archive.\n4. Extract the source code to a temporary directory.\n5. Copy the configuration file template that is most specific for the given version to the kernel build directory.\n6. Completes the kernel configuration. If this requires user input and the script does not run from a terminal, this step fails.\n7. Build the kernel image.\n8. Copy the kernel image to the current working directory with a filename indicating the version.\n9. Clean up the temporary directory.\n\nOptional parameters can influence this sequence to some degree and eliminate some of the automatic decisions.\nIt is also possible to apply custom patches to the kernel source before compiling.\n\nRunning this script as `root` is neither required nor recommended.\n\nbuild-rootfs.sh\n---------------\n\nThis script builds one or more root filesystem images that can be used with Firecracker.\nRefer to `build-rootfs.sh --help` for a list of parameters.\nAll parameters are optional.\nWhen called without parameters, `build-rootfs.sh` builds all rootfs images described by `.rootfs` files in the current directory and places the resulting images in the current directory.\nTo build only specific images, specify the respective `.rootfs` files on the command line.\nNote that images may expand on other images.\nThis only works if the base image(s) are built in the same call to `build-rootfs.sh` and are ordered before the depending image(s).\nHaving the resulting image file available is *not* sufficient.\n\nRunning this script as `root` is neither required nor recommended.\n`build-rootfs.sh` automatically establishes namespace confinement.\nIt uses an environment similar to a container when running commands \"in\" the rootfs image, such as installing software using the rootfs image's package manager.\nThis means, however, that subuids and subgids need to be set up for the user running `build-rootfs.sh`.\nTo allocate a range of 65536 subuids and subgids run the following command (or similar):\n```sh\nusermod --add-subuid 1065536-1131071 --add-subgids 1065536-1131071 \u003cuser\u003e\n```\nIt is important to ensure that the ranges allocated to different users do not overlap!\n\n### .rootfs File Format\n\nFiles with the extension `.rootfs` (by convention) define, how to programmatically build a rootfs image.\nThese files use a simple description language that is documented in the following.\n\nEmpty lines and lines starting with `#` are ignored.\nAll other lines need to start with a command, followed by a number of parameters specific to the command.\nParameters are separated by whitespace.\nTo include a whitespace in a parameter value, it needs to be escaped by `\\`, e.g. `\\ `. To include a literal `\\ ` in a parameter, use `\\\\ `.\nThe following commands are implemented:\n\n#### UMASK\n\nSets the umask value used when creating the filesystem image.\nExpects one parameter and the is the umask value.\nFor example, to restrict all access to the image for 'other users':\n```\nUMASK 027\n```\nThe default value is inherited from the environment from which `build-rootfs.sh` is called.\n\n#### FROM\n\nEvery `.rootfs` file needs to contain this command. It describes the base used for the image.\nMultiple forms are supported:\n* `FROM scratch`  \n  Start with a completely empty root filesystem.\n* `FROM some.img`  \n  Populate the rootfs image with the contents of `some.img`.\n  Note that this only works if `some.rootfs` was already built by `build-rootfs.sh` in the same script invocation.\n  The resulting `.img` file alone is not sufficient.\n* `FROM some.tar`  \n  Populate the rootfs image with the  contents of a (possibly compressed) tar archive `some.tar`.\n  Accepted file extensions are `.tar`, `.tar.*`, `.tgz`, `.tbz`, `.tbz2`, `.tlz`, `.txz`, `.tZ` and `.tzst`.\n* `FROM url [signature_url [key [...]]]`  \n  Download a (possibly compressed) tar archive from `url` and extract it into the image.\n  The URL of a detached PGP signature for the archive can be specified as `signature_url`.\n  If one or more `key`s are given, the signature is verified against these keys.\n  If no `key`s are given, the signature is verified against the default gnupg keyring of the user running `build-rootfs.sh`.\n* `FROM name[:version]`  \n  This is a convenient short-hand for certain known bases.\n  At this time, the following values are accepted for `name`:\n    * `alpine`: the [Alpine Linux](https://alpinelinux.org/) minimal root filesystem\n    * `gentoo-*`: a [Gentoo Linux](https://www.gentoo.org/) stage3 archive.\n      Gentoo provides various stage3 archives.\n      To use a specific archive, include its \"keywords\" in `name`, e.g. `gentoo-hardened-nomultilib-selinux-openrc`.\n      The name `gentoo` is short for `gentoo-nomultilib-openrc`.\n  If `version` is set, that specific version is used.\n  If it is not set, `latest` is assumed, which makes `build-rootfs.sh` detect the latest (stable) version of the given base.\n\nNote: It is possible to use multiple `FROM` directives.\nBases are merged in the order of appearance, i.e. files from later `FROM` commands overwrite files from previous ones.\n\n#### FILESYSTEM\n\nSet the type of filesystem used to format the rootfs image.\nExpects one parameter and that is the name of the filesystem.\nFor example, to use `ext2`:\n```\nFILESYSTEM ext2\n```\n\nValid values are:\n* `ext2` (default)\n* `ext3`\n* `ext4`\n* `btrfs`\n\nIf `FILESYSTEM` is use multiple times, only the last instance is taken into account.\nThere are no restrictions on where this command may appear, in particular it does not need to (but may) be before the first `FROM` directive.\n\n#### MAX_SIZE\n\nSets the maximum size of the resulting rootfs image.\nExpects one parameter and that is the size in MiB.\nFor example, to limit the filesystem to 128 MiB (which is the default) value:\n```\nMAX_SIZE 128\n```\nIt is recommended setting this directive before the first `FROM` command, but this is not strictly necessary.\nIf `MAX_SIZE` is used later, the limit is adjusted accordingly.\nHowever, until then, the default value is in effect, which would cause issues if the base set up by `FROM` needs more space.\n\n`build-rootfs.sh` builds the rootfs image in memory.\nLimiting the size of the filesystem therefore serves as a limit on the amount of memory used in the process.\n\n#### MIN_SIZE\n\nSets the minimum size of the resulting rootfs image.\nExpects one parameter and that is the size in MiB.\nFor example, to request at least 0 MiB (which is the default) value:\n```\nMIN_SIZE 0\n```\n\nThe filesystem will take up at least as much space as needed by it's contents.\n`MIN_SIZE` can be used to ensure that there is some free space to work with during runtime.\nFor read-only use, a value of `0` is recommended.\n\n#### RUN\n\nRun a command in the rootfs image.\nEverything after the `RUN` directive is passed to `/bin/sh` in the rootfs.\nTherefore, a working `/bin/sh` needs to be present before the first `RUN` command.\n\nFor example to update the package database in an Alpine image:\n```\nRUN apk update\n```\n\n`RUN` can not be used before `FROM`.\nBut a second `FROM` may appear after `RUN`.\n\n#### COPY\n\nCopy one or more files from the host to the rootfs image.\nTakes at least two arguments.\n\nAll but the last argument are files or directories on the host (relative paths are relative to the location of the `.rootfs` file).\nThese arguments can be patterns as described in the section 'Pathname Expansion' in the bash documentation.\nTo match `*`, `?` or `[` literally, these characters need to be enclosed in `[]`, e.g. `[*]`.\n\nThe last argument denotes a path in the root filesystem and is the target of the copy operation (relative paths are relative to `/` in the rootfs).\nThe file ownership is set to `root` in the rootfs.\nExample:\n```\nCOPY files/custom_issue /etc/issue\n```\n\n`COPY` can not be used before `FROM`.\nBut a second `FROM` may appear after `COPY`.\n\nfirestarter.py\n--------------\n\nThis script runs a MicroVM using Firecracker.\nIt handles populating the chroot environment with the necessary files, running `jailer` (which in turn starts `firecracker`) and cleaning up the chroot after Firecracker terminates.\n\nThe only mandatory argument to `firestarter.py` is the path to a config file that describes the VM.\nSee [Config File Format](#Config File Format) below for further information.\n`firestarter.py` also accept some optional parameters.\nRefer to `firestarter.py --help` for a list.\n\n`firestarter.py` needs to be started as `root`, since this is a requirement of `jailer`.\n\nThe first time `firestarter.py` receives a terminating signal (`SIGINT`, `SIGTERM`, `SIGQUIT`, `SIGHUP`), it sends `Ctrl+Alt+Del` to the VM, so the guest can shut down gracefully.\nThis does, however, require the cooperation of the guest.\nIf `firestarter.py` does not terminate in an acceptable time span, it is recommended to send the same signal again.\nGraceful guest shutdown is attempted only once.\nThe second signal is passed to the Firecracker process, followed by `SIGKILL` after a short delay.\n\n### Config File Format\n\n`firestarter.py` expects a JSON formatted config file that contains all information about the VM.\nThe file format is mostly identical to the file format accepted by Firecracker with the following extensions:\n\n* The `boot-source` section is not mandatory. If it is not present, a sensible default (i.e. the latest kernel image as created by `build-kernel.sh`) is assumed.\n* Paths to the kernel, initrd and filesystems simply refer to files on the host. `firestarter.py` handles rewriting these paths for use in the chroot. Relative paths are considered to be relative to the location of the config file (or a path specified as a parameter to `firestarter.py`).\n* Paths to the kernel, initrd and filesystems support globbing. If multiple files match a globbing expression the most recently modified or (if the `packaging` module is available) the one containing the highest version number is chosen.\n* The `boot-source` and `drives` sections support the key `glob_order` to override the default choice of algorithm. Valid values are `most_recent` and `latest_version` (if available).\n* The `network-interfaces` section has limited support for IP address configuration:\n    * `host_dev_name` is not mandatory. If it is omitted but `host_bridge_name` is set, a tap device is created and connected to the bridge device `host_bridge_name`.\n      The bridge needs to be fully set up on the host; it is not configured by `firestarter.py`.\n    * The parameter `ip_address` can be added to a network interfaces.\n      It may specify an IP address in CIDR notation or one of the special keywords `dhcp`, `bootp`, `rarp` or `any`.\n      `dhcp`, `bootp` and `rarp` use the respective protocol to obtain a network configuration, `any` uses any of these protocols.\n      This only works if the kernel was compiled with support for IP autoconfiguration (`CONFIG_IP_PNP`, possibly `CONFIG_IP_PNP_DHCP`, `CONFIG_IP_PNP_BOOTP`, `CONFIG_IP_PNP_RARP`) and only works for *one* network interface.\n    * If `ip_address` is set, the optional parameter `gateway` can be set to the address of the gateway (or router) for the interface.\n    * If `ip_address` is set, the optional parameter `dns` can be set to a list of up to two nameserver addresses.\n      Note that the kernel provides the nameserver information in `/proc/net/pnp`.\n      It is up to the rootfs to set up `/etc/resolv.conf` accordingly, for example by making it a symlink to `/proc/net/pnp`.\n\nHere is an example that showcases some of the extended options:\n```json\n{\n  \"boot-source\": {\n    \"kernel_image_path\": \"vmlinux-*\",\n    \"boot_args\": \"console=ttyS0 reboot=k panic=1 pci=off quiet i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd\"\n  },\n  \"drives\": [\n    {\n      \"drive_id\": \"rootfs\",\n      \"path_on_host\": \"rootfs_*.img\",\n      \"glob_order\": \"most_recent\",\n      \"is_root_device\": true,\n      \"is_read_only\": true\n    }\n  ],\n  \"machine-config\": {\n    \"vcpu_count\": 1,\n    \"mem_size_mib\": 128\n  },\n  \"network-interfaces\": [\n    {\n      \"iface_id\": \"eth0\",\n      \"host_bridge_name\": \"fcbr0\",\n      \"ip_address\": \"192.168.0.2/24\",\n      \"gateway\": \"192.168.0.1\",\n      \"dns\": [\"192.168.0.1\"]\n    }\n  ]\n}\n```\n\nLicense\n=======\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fs-hamann%2Ffirecracker-tools","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fs-hamann%2Ffirecracker-tools","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fs-hamann%2Ffirecracker-tools/lists"}