### Local API Server and Storewolf Setup (Rust) Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/README.md Sets up a local data store using storewolf and starts the Bottlerocket API server. This is crucial for local development and testing of Bottlerocket OS components, allowing for manual inspection and manipulation of settings. ```rust cd sources/api/storewolf cargo run -- --data-store-base-path /tmp/data-store --version 0.0.1 cd sources/api/apiserver cargo run -- --datastore-path /tmp/data-store/current --socket-path /tmp/bottlerocket-api.sock --log-level debug ``` -------------------------------- ### Start apiserver with custom paths and log level Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/apiserver/README.md This command demonstrates how to start the apiserver with a specified datastore path, socket path, and log level. It's useful for testing or custom deployments. ```bash cargo run -- --datastore-path /tmp/bottlerocket/data --socket-path /tmp/bottlerocket/api.sock --log-level debug ``` -------------------------------- ### Local Settings Committer Setup (Rust) Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/README.md Starts the settings-committer service locally, which commits pending settings to the API data store. This is a necessary step after setting up the API server and storewolf for local development, ensuring settings are processed. ```rust cd sources/api/settings-committer cargo run -- --socket-path /tmp/bottlerocket-api.sock ``` -------------------------------- ### Start Bottlerocket Apiserver Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/README.md This command starts the Bottlerocket API server with root privileges, enabling it to communicate with the containerd socket. It specifies the data store path and the API socket path. Ensure you are in the 'sources' directory when executing this command. The `--exec-socket-path` option can be used if your containerd socket is not at the default location. ```shell sudo target/debug/apiserver --datastore-path /tmp/data-store/current --socket-path /tmp/bottlerocket-api.sock ``` -------------------------------- ### Signpost Upgrade Procedure Example Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/updater/signpost/README.md This example details the steps for upgrading the Bottlerocket OS using the signpost utility. It involves clearing inactive partition data, copying new images, and then promoting the inactive partitions for a single boot attempt. ```plain 1. Run `signpost clear-inactive` to clear the priority and successful bits before making any changes to the inactive partitions. 2. Copy the downloaded images to the inactive partitions on disk, then validate data was written correctly. 3. Run `signpost upgrade-to-inactive` to prioritize the inactive partitions and allow it one boot attempt before automatically rolling back. ``` -------------------------------- ### Rendering Templates with schnauzer CLI Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/schnauzer/README.md This command-line example shows how to use the schnauzer-v2 (or schnauzer) binary to render a template. It demonstrates specifying required settings extensions and helpers directly via CLI arguments, rather than using TOML frontmatter. ```bash schnauzer-v2 render \ --requires 'settings@v1(helpers=[myhelper])' \ --template 'foo-{{ myhelper settings.bar }}' ``` -------------------------------- ### Bootstrap Container Dockerfile Example Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/bootstrap-containers/README.md A Dockerfile for building a bootstrap container image. It sets up an Alpine base image, copies a bootstrap script, makes it executable, and defines the entrypoint to run the script. ```dockerfile FROM alpine ADD bootstrap-script / RUN chmod +x /bootstrap-script ENTRYPOINT ["sh", "bootstrap-script"] ``` -------------------------------- ### Signpost Rollback Procedure Example Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/updater/signpost/README.md This example outlines the procedure for rolling back to a previous version of Bottlerocket OS using signpost. It focuses on reprioritizing inactive partitions without altering the success status of the currently active ones. ```plain 1. Run `signpost rollback-to-inactive` to prioritize the inactive partitions without modifying whether the active partitions were successful. ``` -------------------------------- ### Example Update Status JSON Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/updater/README.md An example JSON structure representing the output of the `/updates/status` endpoint. It details the current update state, lists available updates, specifies the chosen update and active/staging partitions, and includes information about the most recent command executed. ```json { "update_state": "Available", "available_updates": [ "0.4.0", "0.3.4", ... ], "chosen_update": { "arch": "x86_64", "version": "0.4.0", "variant": "aws-k8s-1.15" }, "active_partition": { "image": { "arch": "x86_64", "version": "0.3.2", "variant": "aws-k8s-1.15" }, "next_to_boot": true }, "staging_partition": null, "most_recent_command": { "cmd_type": "refresh", "cmd_status": "Success", ... } } ``` -------------------------------- ### Metricdog TOML Configuration Example Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/metricdog/README.md This TOML configuration defines how Metricdog operates, including the metrics endpoint URL, whether to send metrics, which services to check, and regional and update-related settings. ```toml # the url to which metricdog will send metrics information metrics_url = "https://example.com/metrics" # whether or not metricdog will send metrics. opt-out by setting this to false send_metrics = true # a list of systemd service names that will be checked service_checks = ["apiserver", "containerd", "kubelet"] # the region region = "us-west-2" # the update wave seed seed = 1234 # what version bottlerocket should stay on version_lock = "latest" # whether bottlerocket should ignore update roll-out timing ignore_waves = false ``` -------------------------------- ### Migrating Templates: TOML Frontmatter Example Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/schnauzer/README.md This TOML snippet illustrates how to migrate a template from schnauzer v1 to v2 by explicitly declaring settings extensions and their owned helpers in the frontmatter. This ensures proper resolution of settings and helpers in the new version. ```toml [required-extensions] foo = "v1" fooify = { version = "v1", helpers = ["barify", "bazify"] } +++ ``` -------------------------------- ### Data Store Symlink Structure Example Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/migration/README.md Illustrates the symbolic link structure used by Bottlerocket OS to access the data store, allowing applications to interact with a consistent path regardless of the underlying version. ```shell /var/lib/bottlerocket/datastore/current -> v1 -> v1.5 -> v1.5.2 -> v1.5.2_0123456789abcdef ``` -------------------------------- ### Install cargo-make Build Tool Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/BUILDING.md Installs the `cargo-make` tool, which is used to organize build tasks for the Rust-based Bottlerocket build system. Requires Rust and Cargo to be installed. ```shell cargo install cargo-make ``` -------------------------------- ### RPM Spec File Structure for Bottlerocket Package Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/packages/README.md This is a template RPM spec file for a Bottlerocket package, named `%{_cross_os}libwoof`. It defines package metadata, dependencies, build requirements, installation files, and changelog. Macros starting with `%` are used, with Bottlerocket-specific macros including the `cross` token. The `%{_cross_variant}` macro specifies the Bottlerocket variant being built. ```spec Name: %{_cross_os}libwoof Version: 1.0.0 Release: 1%{?dist} Summary: Library for woof License: Apache-2.0 OR MIT URL: http://sourceforge.net/projects/libwoof/ Source0: http://downloads.sourceforge.net/libwoof/libwoof-1.0.0.tar.xz BuildRequires: %{_cross_os}glibc-devel BuildRequires: %{_cross_os}libseccomp-devel %description %{summary}. %package devel Summary: Files for development using the library for woof Requires: %{name} %description devel %{summary}. %prep %autosetup -n libwoof-%{version} -p1 %build %cross_configure %make_build %install %make_install %files %license LICENSE %{_cross_libdir}/*.so.* %files devel %{_cross_libdir}/*.so %dir %{_cross_includedir}/libwoof %{_cross_includedir}/libwoof/*.h %{_cross_pkgconfigdir}/*.pc %changelog ``` -------------------------------- ### Install Build Dependencies on Ubuntu Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/BUILDING.md Installs essential packages required for building the Bottlerocket core kit on Ubuntu systems. These include compilers, libraries, and build tools. ```shell apt install build-essential openssl libssl-dev pkg-config liblz4-tool cmake clang libclang-dev ``` -------------------------------- ### Raw Mode: Fetch Current Settings (Shell) Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/apiclient/README.md Fetches the current system settings in JSON format using the apiclient raw command. It defaults to a GET request to the /settings endpoint. ```shell apiclient raw -u /settings ``` -------------------------------- ### Check and Apply Bottlerocket Updates using apiclient Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/apiclient/README.md Manages system updates on Bottlerocket OS. The `check` subcommand shows available updates, and `apply` downloads and installs them to an alternate partition, preparing for a reboot. Updates are controlled by `settings.updates`. ```shell apiclient update check apiclient update apply apiclient update apply --check --reboot ``` -------------------------------- ### Install Build Dependencies on Fedora Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/BUILDING.md Installs necessary packages for building the Bottlerocket core kit on Fedora systems. This includes development tools and libraries. ```shell dnf install make automake gcc openssl openssl-devel pkg-config lz4 perl-FindBin perl-lib cmake clang clang-tools-extra ``` -------------------------------- ### Run Container Task with ctr Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/README.md This snippet demonstrates how to pull a Docker image and run a new container task using the 'ctr' command-line tool. It assumes you have containerd installed and configured. The 'ctr i pull' command fetches the specified image, and 'ctr run' starts a new container with an interactive bash shell, removing it once the shell exits. ```shell sudo ctr i pull public.ecr.aws/amazonlinux/amazonlinux:latest sudo ctr run --rm -t public.ecr.aws/amazonlinux/amazonlinux:latest al bash ``` -------------------------------- ### Handling Bundled Go Module Sources in Spec Files Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/packages/README.md This section shows how to include and unpack bundled Go module tarball sources within an RPM spec file. `Source` lines are added for each bundled tarball, and `%setup` commands with specific options (`-T`, `-D`, `-n`, `-b`, `-q`) are used in the `%prep` section to manage their unpacking. ```spec Source1: bundled-v0.5.0.tar.gz Source2: bundled-cmd.tar.gz ``` ```spec %setup -T -D -n libwoof-1.0.0 -b 1 -q %setup -T -D -n libwoof-1.0.0 -b 2 -q ``` -------------------------------- ### Get Bottlerocket Settings using apiclient Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/apiclient/README.md Retrieves system settings from the Bottlerocket API. Supports fetching all settings, specific prefixes, or individual settings by name. It interacts with the Bottlerocket socket by default and can be directed to a different socket path using the `--socket-path` flag for local testing. ```shell apiclient get settings apiclient get settings.host-containers.admin apiclient get settings.motd settings.kernel.lockdown ``` -------------------------------- ### Settings API Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/apiserver/README.md The Settings APIs allow you to GET current settings and PATCH changes. Settings are stored as a pending transaction until committed. ```APIDOC ## GET /settings ### Description Retrieves the current system settings. ### Method GET ### Endpoint /settings ### Query Parameters - **tx** (string) - Optional - The transaction ID to retrieve settings from. ### Response #### Success Response (200) - **settings** (object) - A map of setting keys to their values. #### Response Example ```json { "settings": { "example.setting": "value" } } ``` ## PATCH /settings ### Description Applies changes to system settings within a specified transaction. ### Method PATCH ### Endpoint /settings ### Query Parameters - **tx** (string) - Optional - The transaction ID to apply changes to. ### Request Body - **settings** (object) - Required - A map of setting keys to their new values. ### Request Example ```json { "settings": { "example.setting": "new_value" } } ``` ### Response #### Success Response (200) - **message** (string) - Confirmation of the patch operation. #### Response Example ```json { "message": "Settings patched successfully." } ``` ``` -------------------------------- ### Bootstrap Script Shell Example Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/bootstrap-containers/README.md A shell script executed by the bootstrap container. It reads user-data, creates a directory on the host's persistent storage, writes the user-data to a file within that directory, and then delays the boot process. ```shell #!/usr/bin/env sh # We'll read some data to be written out from given user-data. USER_DATA_DIR=/.bottlerocket/bootstrap-containers/current # This is the in-container view of where the host's `/var` can be accessed. HOST_VAR_DIR=/.bottlerocket/rootfs/var # The directory that'll be created by this bootstrap container MY_HOST_DIR=$HOST_VAR_DIR/lib/my_directory # Create it! mkdir -p "$MY_HOST_DIR" # Write the user-data to stdout (to the journal) and to our new path: tee /dev/stdout "$MY_HOST_DIR/bear.txt" < "$USER_DATA_DIR/user-data" # The bootstrap container can set the permissions which are seen by the host: chmod -R o+r "$MY_HOST_DIR" chown -R 1000:1000 "$MY_HOST_DIR" # Bootstrap containers *must* finish before boot continues. # # With this, the boot process will be delayed 120 seconds. You can check the # status of `preconfigured.target` and `bootstrap-containers@bear` to see # that this sleep kept the system from starting up the apiserver. # # From the admin container: # # systemctl status preconfigured.target bootstrap-containers@bear sleep 120 ``` -------------------------------- ### Input/Output Handling (Rust) Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/api-exec.md Handles the flow of data between the user's input and the child process on the server-side, and between the server and the client's process output. It uses channels to manage this communication efficiently. ```Rust // Server side: ReadFromChild and WriteToChild // Client side: ReadFromUser and ReadFromServer ``` -------------------------------- ### Get Update Status using apiclient Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/updater/README.md Retrieves the current status of system updates, including available updates, the chosen update, active and staging partition details, and the most recent command status. This is typically used after refreshing or preparing an update. It uses the `apiclient` tool to send a GET request to the `/updates/status` endpoint. ```shell apiclient get /updates/status ``` -------------------------------- ### Signal Handling (Rust) Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/api-exec.md Manages the handling of signals on the client side, allowing for graceful termination or interruption of the executed command based on received signals. ```Rust pub struct HandleSignals { // ... fields ... } impl HandleSignals { pub async fn run(self) { // ... signal handling logic ... } } ``` -------------------------------- ### Bootstrap Container TOML Configuration Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/bootstrap-containers/README.md Example TOML configuration for defining a bootstrap container named 'bear'. It specifies the source image URL and execution mode. The 'user-data' field contains base64-encoded data passed to the container. ```toml [settings.bootstrap-containers.bear] source="" mode="once" user-data="ypXCt82h4bSlwrfKlA==" ``` -------------------------------- ### API Model Definitions (Rust) Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/api-exec.md Defines the message structures (ServerMessage and ClientMessage) used for control messages over the WebSocket connection. These enums specify the types of control information exchanged between the client and server. ```Rust #[derive(Serialize, Deserialize, Debug)] pub enum ServerMessage { Initialize(Initialize), Heartbeat, // Keep-alive CapacityUpdate(CapacityUpdate), Output(OutputChunk), Exit(ExitStatus), } #[derive(Serialize, Deserialize, Debug)] pub enum ClientMessage { Initialize(Initialize), Heartbeat, Input(InputChunk), WindowSizeUpdate(WindowSizeUpdate), Signal(Signal), } ``` -------------------------------- ### Execute Command in Container with apiclient Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/README.md This snippet shows how to use the Bottlerocket API client ('apiclient') to execute a command within a running container task. It requires the API socket path and the name of the container task. The command executed is 'bash' in this example, within the container named 'al'. Navigate to the 'sources/api/apiclient' directory before running this command. ```shell cargo run -- --socket-path /tmp/bottlerocket-api.sock exec al bash ``` -------------------------------- ### API Exec Client WebSocket Handling (Rust) Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/api-exec.md Utilizes tokio-tungstenite for WebSocket support on the client side. It manages receiving messages from the server and sending control messages and process data through the established WebSocket connection. ```Rust pub async fn exec_client(url: Url) -> Result>, exec_client::Error> { let connect_async = connect_async(url).await; match connect_async { Ok((ws_stream, _)) => Ok(ws_stream), Err(e) => Err(exec_client::Error::from(e)), } } ``` -------------------------------- ### API Exec Server WebSocket Handling (Rust) Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/api-exec.md Implements the Actix Actor trait to handle WebSocket connections for the API server. It receives and processes incoming WebSocket messages, upgrading HTTP requests to establish communication channels for command execution. ```Rust impl Actor for ExecWebSocket { type Context = ws::WebsocketContext; fn started(&mut self, ctx: &mut Self::Context) { // ... setup logic ... } fn stopped(&mut self, _ctx: &mut Self::Context) { // ... cleanup logic ... } } #[post("/exec")] async fn exec(req: HttpRequest, stream: web::Payload) -> Result { ws::start(ExecWebSocket::new(), &req, stream) } ``` -------------------------------- ### Heartbeat Management (Rust) Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/api-exec.md Manages sending periodic ping and pong messages (heartbeats) over the WebSocket connection to ensure the connection remains active. It owns a thread for sending messages and provides a channel for external notification of heartbeat failures. ```Rust pub struct Heartbeat { // ... fields ... stop_tx: Sender<()> } impl Heartbeat { pub fn new(stop_tx: Sender<()>) -> Self { // ... initialization ... } pub async fn run(mut self, tx: Sender) { loop { // ... send ping ... tokio::select! { _ = tokio::time::sleep(HEARTBEAT_INTERVAL) => {}, _ = self.stop_rx.recv() => break, } } } } ``` -------------------------------- ### Package Structure for libwoof Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/packages/README.md Illustrates the directory structure for a sample Bottlerocket package, highlighting the presence of Cargo.toml for build configurations and libwoof.spec for RPM definitions. ```text packages/libwoof/ ├── Cargo.toml ├── libwoof.spec ``` -------------------------------- ### Ephemeral Storage: Initialize (Shell) Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/apiclient/README.md Initializes ephemeral storage by setting up storage devices as a RAID array and formatting them. This must be done before binding directories. ```shell apiclient ephemeral-storage init ``` -------------------------------- ### TOML Configuration for Bootstrap Command Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/bootstrap-commands/README.md This TOML snippet demonstrates the configuration of a bootstrap command, specifying the API commands to execute, whether they are essential, and the mode of execution. It illustrates how to set system properties like the message of the day (motd). ```toml [settings.bootstrap-commands.001-test-bootstrap-commands] commands = [[ "apiclient", "set", "motd=helloworld"]] essential = true mode = "always" ``` -------------------------------- ### Prepare System Update using apiclient Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/updater/README.md Requests that the chosen system update be downloaded and prepared for activation. The update is applied to disk but remains inactive until the 'activate-update' call is made. This command uses `apiclient` to send a POST request to the `/actions/prepare-update` endpoint. ```shell apiclient raw -u /actions/prepare-update -m POST ``` -------------------------------- ### Build Bottlerocket Core Kit (Shell) Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/README.md Commands to build the Bottlerocket Core Kit. This process can be executed on either an x86_64 or aarch64 host. Ensure you have the necessary build environment set up. ```shell make ``` ```shell make ARCH= ``` -------------------------------- ### TOML Frontmatter for schnauzer Templates Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/schnauzer/README.md This snippet demonstrates the TOML frontmatter required for schnauzer templates. It specifies required settings extensions and their versions, along with any helper functions to be imported. The frontmatter is separated from the template body by '+++'. ```toml [required-extensions] frobnicate = "v1" std = { version = "v1", helpers = ["base64_decode"] } # Use at least three `+` characters to separate the frontmatter from the template body. +++ { "enabled": settings.frobnicate.enabled, "frobnicate-key": "{{ base64_decode settings.frobnicate-key }}" } ``` -------------------------------- ### Ephemeral Storage API Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/apiclient/README.md Manage ephemeral storage on instances with local storage. This includes initializing the storage, binding directories, and listing storage information. ```APIDOC ## Ephemeral Storage API ### Description Manages ephemeral storage on instances with local instance storage (e.g., NVMe SSDs). ### Method `init`, `bind`, `list-disks`, `list-dirs` ### Endpoint `apiclient ephemeral-storage [command]` ### Parameters #### Command Parameters - **`init`**: Initializes the ephemeral storage by setting up RAID arrays and formatting. - **`bind`**: Binds directories to ephemeral storage. Can automatically bind platform-specific directories or accept custom directories. - **`--dirs` (array of strings)** - Optional - Custom directories to bind to ephemeral storage. - **`list-disks`**: Lists available disks for ephemeral storage. - **`list-dirs`**: Lists currently bound directories to ephemeral storage. ### Request Example #### Initialize ephemeral storage ```shell apiclient ephemeral-storage init ``` #### Bind default directories ```shell apiclient ephemeral-storage bind ``` #### Bind custom directories ```shell apiclient ephemeral-storage bind --dirs /var/lib/containerd /custom/path ``` #### List available disks ```shell apiclient ephemeral-storage list-disks ``` #### List bound directories ```shell apiclient ephemeral-storage list-dirs ``` ### Response #### Success Response - Output will vary based on the command executed. Typically, initialization and binding commands provide success messages or no output on success. Listing commands return JSON or text output detailing the storage status. ``` -------------------------------- ### Signpost CLI Usage and Subcommands Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/updater/signpost/README.md This snippet outlines the basic usage of the signpost command-line utility and lists its available subcommands. These commands are used to inspect and modify partition priority bits, crucial for Bottlerocket OS's boot selection and update processes. ```plain USAGE: signpost SUBCOMMANDS: status Show partition sets and priority status mark-successful-boot Mark the active partitions as successfully booted clear-inactive Clears inactive priority information to prepare writing images to disk mark-inactive-valid Marks the inactive partition as having a valid image upgrade-to-inactive Sets the inactive partitions as new upgrade partitions if marked valid cancel-upgrade Reverse upgrade-to-inactive rollback-to-inactive Deprioritizes the inactive partitions has-boot-ever-succeeded Checks whether boot has ever succeeded rewrite-table Rewrite the partition table with no changes to disk (used for testing this code) ``` -------------------------------- ### Publish Bottlerocket Core Kit Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/BUILDING.md Publishes the locally built Bottlerocket core kit image to the configured private registry using a Makefile target. Requires the vendor name to be specified. ```makefile make publish VENDOR= ``` -------------------------------- ### Activate System Update using apiclient Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/updater/README.md Marks the prepared system update to be activated upon the next host reboot. If the new version fails to boot, the system will automatically revert to the previous version. This command uses `apiclient` to send a POST request to the `/actions/activate-update` endpoint. ```shell apiclient raw -u /actions/activate-update -m POST ``` -------------------------------- ### Cargo.toml for libwoof Package Build Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/packages/README.md A sample Cargo.toml manifest file for the 'libwoof' package, specifying build metadata, external file sources with SHA512 checksums, build-time dependencies (glibc, libseccomp), and runtime dependencies. ```toml [package] name = "libwoof" version = "0.1.0" edition = "2021" publish = false build = "../build.rs" [lib] path = "../packages.rs" [[package.metadata.build-package.external-files]] url = "http://downloads.sourceforge.net/libwoof/libwoof-1.0.0.tar.xz" sha512 = "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" # RPM BuildRequires [build-dependencies] glibc = { path = "../glibc" } libseccomp = { path = "../libseccomp" } # RPM Requires [dependencies] # None ``` -------------------------------- ### Build Bottlerocket Core Kit Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/BUILDING.md Compiles the Bottlerocket core kit using the provided Makefile. Requires specifying the target architecture. ```makefile make ARCH= ``` -------------------------------- ### Serialize Rust structs to systemd unit format (Rust) Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/netdog/systemd-derive/README.md Shows how to instantiate structs defined with `SystemdUnit` and `SystemdUnitSection` macros and then serialize them into a systemd unit file string using the `to_string()` method. The output demonstrates the correct formatting for sections, key-value pairs, and repeated entries. ```rust let cfg = NetworkConfig { match: Some(MatchSection { name: Some("eno1".to_string()), }), network: Some(NetworkSection { addresses: vec!["1.2.3.4".to_string(), "2.3.4.5".to_string()], dhcp: Some("ipv4".to_string()), }), route: vec![ RouteSection { destination: Some("10.0.0.1".to_string()), }, RouteSection { destination: Some("11.0.0.1".to_string()), }, ], }; println!("{}", cfg.to_string()); ``` -------------------------------- ### Ephemeral Storage: List Information (Shell) Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/apiclient/README.md Lists available disks and currently bound directories for ephemeral storage management. ```shell apiclient ephemeral-storage list-disks ``` ```shell apiclient ephemeral-storage list-dirs ``` -------------------------------- ### Configure Go Non-Vendoring Dependency Bundling with Custom Paths (TOML) Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/packages/README.md This TOML configuration extends the Go dependency bundling for more complex scenarios with multiple `go.mod` files. It allows specifying the root path of the `go.mod` file and the desired output tarball name for the bundled dependencies. ```toml bundle-root-path = "libwoof-1.0.0/cmd" bundle-output-path = "bundled-cmd.tar.gz" bundle-modules = [ "go" ] ``` -------------------------------- ### List All Available Updates (Shell) Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/updater/updog/README.md This command lists all available updates from the TUF repository, including older versions. This is useful for understanding the update history or selecting a specific older version. ```shell # updog check-update --all aws-k8s-1.15 0.1.4 (v0.0) aws-k8s-1.15 0.1.2 (v0.0) aws-k8s-1.15 0.1.1 (v0.0) ``` -------------------------------- ### Configure Private Registry in Infra.toml Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/BUILDING.md Sets up the vendor configuration in `Infra.toml` to specify the private container registry where Bottlerocket kits will be published. ```toml [vendor.] registry = "####.dkr.ecr.us-west-2.amazonaws.com" ``` -------------------------------- ### Execute logdog command Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/logdog/README.md This snippet shows the basic command to execute logdog. It demonstrates how to initiate the log collection process and indicates the default output path for the generated tarball. ```shell logdog logs are at: /var/log/support/bottlerocket-logs.tar.gz ``` -------------------------------- ### TOML Configuration for Failing Bootstrap Command Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/bootstrap-commands/README.md This TOML snippet shows a bootstrap command configuration that is likely to fail. It uses the 'exec' command to run a host command, which may not work because the necessary services for 'exec' commands are launched after the 'bootstrap-commands.service'. ```toml [settings.bootstrap-commands.001-test-bootstrap-commands] commands = [[ "apiclient", "exec", "admin", "ls"]] essential = true mode = "always" ``` -------------------------------- ### Building a Bottlerocket Package Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/packages/README.md This command builds a specific package (e.g., `libwoof`) and its dependencies within the Bottlerocket environment. It uses `cargo make` with the `PACKAGE` environment variable set to the target package name and the `build-package` action. ```bash cargo make -e PACKAGE=libwoof build-package ``` -------------------------------- ### Refresh Available Updates using apiclient Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/updater/README.md Initiates a refresh of the list of available system updates. This is the first step in the update process. It uses the `apiclient` tool to send a POST request to the `/actions/refresh-updates` endpoint. ```shell apiclient raw -u /actions/refresh-updates -m POST ``` -------------------------------- ### Allowing Programs via Symlink Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/brush/README.md This demonstrates how to allow a program to be executed by brush. A symlink is created in the `allowed-programs` directory pointing to the actual program executable. Brush checks these symlinks to determine if a program is permitted. ```bash /usr/libexec/brush/allowed-programs/my-program -> ../path/to/program ``` -------------------------------- ### Fetch Instance Type using IMDSv2 Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/imdsclient/README.md Demonstrates how to fetch the instance type metadata using the imdsclient library. It automatically handles IMDSv2 session creation and token management. The method returns the instance type as a String. ```Rust use bottlerocket_imdsclient::imdsclient; #[tokio::main] async fn main() -> Result<(), Box> { let client = imdsclient::ImdsClient::new(); let instance_type = client.fetch_instance_type().await?; println!("Instance Type: {}", instance_type); Ok(()) } ``` -------------------------------- ### Transaction API Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/apiserver/README.md APIs for managing and committing transactions of settings changes. ```APIDOC ## GET /tx ### Description Retrieves pending changes within a specific transaction. ### Method GET ### Endpoint /tx ### Query Parameters - **tx** (string) - Required - The transaction ID to retrieve. ### Response #### Success Response (200) - **changes** (object) - A map detailing the pending changes in the transaction. #### Response Example ```json { "changes": { "settings.example.setting": { "old_value": "value", "new_value": "new_value" } } } ``` ## POST /tx/commit ### Description Commits the pending transaction, making the changes live. ### Method POST ### Endpoint /tx/commit ### Query Parameters - **tx** (string) - Required - The transaction ID to commit. ### Response #### Success Response (200) - **message** (string) - Confirmation of the commit operation. #### Response Example ```json { "message": "Transaction committed successfully." } ``` ## POST /tx/apply ### Description Applies the pending transaction changes to the system and restarts services as necessary. ### Method POST ### Endpoint /tx/apply ### Query Parameters - **tx** (string) - Required - The transaction ID to apply. ### Response #### Success Response (200) - **message** (string) - Confirmation of the apply operation. #### Response Example ```json { "message": "Transaction applied successfully." } ``` ## POST /tx/commit_and_apply ### Description Commits the pending transaction and then applies the changes to the system. ### Method POST ### Endpoint /tx/commit_and_apply ### Query Parameters - **tx** (string) - Required - The transaction ID to commit and apply. ### Response #### Success Response (200) - **message** (string) - Confirmation of the commit and apply operation. #### Response Example ```json { "message": "Transaction committed and applied successfully." } ``` ``` -------------------------------- ### Raw Mode: Commit and Apply Transactions (Shell) Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/apiclient/README.md Commits the staged settings changes, applying them to the system. This uses a POST request to the /tx/commit_and_apply endpoint. ```shell apiclient raw -m POST -u /tx/commit_and_apply ``` -------------------------------- ### Configure Go Non-Vendoring Dependency Bundling (TOML) Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/packages/README.md This configuration enables the Bottlerocket build tooling to automatically create Go vendored modules for non-vendoring Go packages. It specifies modules to bundle and the output tarball name. This is useful when Go dependencies are not included in the source commit. ```toml bundle-modules = [ "go" ] ``` -------------------------------- ### Configure Docker for OCI Artifacts Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/BUILDING.md Enables `buildkit` and `containerd-snapshotter` features in Docker's daemon configuration to ensure compatibility with OCI Images, which are used for storing Bottlerocket kits. ```json { "features": { "buildkit": true, "containerd-snapshotter": true } } ``` -------------------------------- ### Expanding RPM Macros Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/packages/README.md This shell command demonstrates how to expand RPM macros for a package named `libwoof` on an RPM-based system. It specifies paths to macro files and defines custom macro values for source directories and the package name. ```bash $ PKG=libwoof $ rpmspec \ --macros "/usr/lib/rpm/macros:macros/$(uname -m):macros/shared:macros/rust:macros/cargo" \ --define "_sourcedir packages/${PKG}" \ --parse packages/${PKG}/${PKG}.spec ``` -------------------------------- ### Raw Mode: Update Settings (Shell) Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/apiclient/README.md Updates system settings by sending a PATCH request with new JSON data to the /settings endpoint. This stages the changes in a transaction. ```shell apiclient raw -m PATCH -u /settings -d '{"motd": "my own value!"}' ``` -------------------------------- ### Rust Build Script for Packages Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/packages/README.md This Rust build script `build.rs` is used to build packages in the Bottlerocket Core Kit. It executes the `buildsys` tool with the `build-package` argument. If the build fails, the script exits with a non-zero status code. It assumes the `buildsys` tool is available in the environment. ```rust use std::process::{exit, Command}; fn main() -> Result<(), std::io::Error> { let ret = Command::new("buildsys").arg("build-package").status()?; if !ret.success() { exit(1); } Ok(()) } ``` -------------------------------- ### Reboot Host using apiclient Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/updater/README.md Initiates a reboot of the Bottlerocket host. This is typically the final step after activating a system update to apply the changes. The command uses `apiclient` to send a POST request to the `/actions/reboot` endpoint. ```shell apiclient raw -u /actions/reboot -m POST ``` -------------------------------- ### Force Immediate Update (Shell) Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/updater/updog/README.md This command forces an immediate update to the latest version, bypassing any wave-based release schedule limitations. This is useful for critical updates or when immediate deployment is required. ```shell # updog update --now Starting update to 0.1.4 ** Updating immediately ** Update applied: aws-k8s-1.15 0.1.4 ``` -------------------------------- ### Ephemeral Storage: Bind Directories (Shell) Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/apiclient/README.md Automatically binds appropriate directories to ephemeral storage for persistence across container restarts. Supports custom directory specification. ```shell apiclient ephemeral-storage bind ``` ```shell apiclient ephemeral-storage bind --dirs /var/lib/containerd /custom/path ``` -------------------------------- ### Generate Bottlerocket CIS Benchmark Report Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/apiclient/README.md Generates a Bottlerocket CIS Benchmark compliance report. By default, it evaluates against level 1 requirements. Options include specifying the benchmark level (-l) and output format (-f), such as 'json' for programmatic parsing. ```shell apiclient report cis ``` ```shell apiclient report cis -l 2 ``` ```shell apiclient report cis -f json ``` -------------------------------- ### Generate Kubernetes CIS Benchmark Report Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/apiclient/README.md Generates a Kubernetes CIS Benchmark compliance report. Similar to the Bottlerocket report, it defaults to level 1 and supports specifying the level (-l) and output format (-f) like 'json'. ```shell apiclient report cis-k8s ``` ```shell apiclient report cis-k8s -l 2 ``` ```shell apiclient report cis-k8s -f json ``` -------------------------------- ### Set Bottlerocket Settings using apiclient (Key-Value) Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/apiclient/README.md Modifies Bottlerocket system settings using a simple key-value format. The 'settings.' prefix is optional. For settings with complex keys or special characters, the entire argument should be quoted. This method is convenient for single or straightforward setting changes. ```shell apiclient set settings.x.y.z=VALUE apiclient set kernel.lockdown=integrity motd="hi there" apiclient set 'kubernetes.node-labels."my.label"=hello' ``` -------------------------------- ### API Access via Privileged Container (YAML) Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/README.md This YAML configuration demonstrates how to expose the Bottlerocket API socket to a privileged container. It involves mounting the host's API socket into the container, allowing it to interact with the Bottlerocket API. ```yaml containers: - name: my-api-access image: my-api-access volumeMounts: - name: socket mountPath: /run/api.sock privileged: true volumes: - name: socket hostPath: path: /run/api.sock ``` -------------------------------- ### Raw Mode: View Pending Transactions (Shell) Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/apiclient/README.md Displays all pending settings changes within the current transaction. Use /v2/tx for additional metadata. ```shell apiclient raw -u /tx ``` ```shell apiclient raw -u /v2/tx ``` -------------------------------- ### Brush TOML Configuration for Argument Restriction Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/brush/README.md This shows how to configure brush to restrict arguments for specific programs using a TOML file. You can define arguments that are required in a specific order or arguments that are explicitly blocked from being used. ```toml # Required args must appear in positional order. required-args = ["first", "second", "third"] # Blocked args must not appear. blocked-args = ["--spill-secrets"] ``` -------------------------------- ### Raw Mode: Custom Transactions (Shell) Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/apiclient/README.md Allows grouping sets of changes into custom transactions by appending a 'tx' parameter to URLs. Transactions are created automatically and cleaned up on reboot. ```shell apiclient raw -m PATCH -u "/settings?tx=FOO" -d '{"motd": "my own value!"}' ``` ```shell apiclient raw -m POST -u "/tx/commit_and_apply?tx=FOO" ``` -------------------------------- ### Define systemd unit structure with SystemdUnit macro (Rust) Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/netdog/systemd-derive/README.md Demonstrates the use of the `SystemdUnit` macro for a top-level struct representing a systemd unit file. It shows how nested structs and Vecs can represent sections and repeatable sections, respectively. Fields must be Options or Vecs implementing Display. ```rust use systemd_derive::{SystemdUnit, SystemdUnitSection}; #[derive(Debug, Default, SystemdUnit)] struct NetworkConfig { match: Option, network: Option, route: Vec, } #[derive(Debug, Default, SystemdUnitSection)] #[systemd(section = "Match")] struct MatchSection { #[systemd(entry = "Name")] name: Option, } #[derive(Debug, Default, SystemdUnitSection)] #[systemd(section = "Network")] struct NetworkSection { #[systemd(entry = "Address")] addresses: Vec, #[systemd(entry = "DHCP")] dhcp: Option, } #[derive(Debug, Default, SystemdUnitSection)] #[systemd(section = "Route")] struct RouteSection { #[systemd(entry = "Destination")] destination: Option, } ``` -------------------------------- ### Configure Twoliter.toml for Private Bottlerocket Core Kit Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/BUILDING.md This TOML configuration allows you to specify a private container registry for the Bottlerocket core kit and set a custom version. It is used in conjunction with the `twoliter update` command to manage dependencies. ```toml [vendor.my-vendor] registry = "####.dkr.ecr.us-west-2.amazonaws.com" [[kit]] name = "bottlerocket-core-kit" # Name of your ECR repo version = "2.x.y" # your version tag you want to test vendor = "my-vendor" ``` -------------------------------- ### Raw Mode API Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/apiclient/README.md Interact with the Bottlerocket API server using raw HTTP requests. This mode is similar to `curl` but understands Bottlerocket API specifics like default socket paths, hostnames, and content types. ```APIDOC ## Raw Mode API ### Description Allows making HTTP requests directly to a UNIX socket, with built-in understanding of Bottlerocket API server specifics. ### Method GET (default), POST, PATCH, etc. ### Endpoint `/settings`, `/tx`, `/v2/tx`, `/tx/commit_and_apply` (and others, specified with `-u`) ### Parameters #### Query Parameters - **tx** (string) - Optional - Specifies a transaction name to group changes. #### Request Body - **(JSON Object)** - Optional - Used for POST or PATCH requests to send data. - **field** (any type) - Required/Optional - Description of the field being sent in the request body. ### Request Example #### Fetch current settings ```shell apiclient raw -u /settings ``` #### Stage a setting change ```shell apiclient raw -m PATCH -u /settings -d '{"motd": "my own value!"}' ``` #### View pending transactions ```shell apiclient raw -u /tx ``` #### View pending transactions with metadata (v2) ```shell apiclient raw -u /v2/tx ``` #### Commit and apply settings ```shell apiclient raw -m POST -u /tx/commit_and_apply ``` ### Response #### Success Response (200) - **(JSON Object)** - The response from the API server, often containing system settings or transaction information. #### Response Example ```json {"motd":"...", "kubernetes": ...} ``` ``` -------------------------------- ### Execute Commands in Bottlerocket Host Containers using apiclient Source: https://github.com/bottlerocket-os/bottlerocket-core-kit/blob/develop/sources/api/apiclient/README.md Runs commands within Bottlerocket host containers, useful for debugging or inter-container operations. It supports specifying TTY behavior (`-t`/`--tty`, `-T`/`--no-tty`) and redirecting command output. This functions similarly to a slim SSH client over the existing API channel. ```shell apiclient exec admin bash apiclient exec admin cat /file > file ```