# cisak — Container Installation Swiss Army Knife
`cisak` is a small, opinionated CLI tool that automates the download, verification, and installation of the core OCI container runtime stack:
| [runc](https://github.com/opencontainers/runc) | v1.4.2 |
| [CNI plugins](https://github.com/containernetworking/plugins) | v1.9.1 |
| [containerd](https://github.com/containerd/containerd) | v2.2.3 |
Every binary is cryptographically verified before it is written to disk (GPG for runc, SHA-512 for CNI plugins, SHA-256 for containerd). Each external command is shown to you and requires explicit confirmation before it runs, unless you pass `--assume-yes`.
---
## Table of contents
- [Prerequisites](#prerequisites)
- [Installation](#installation)
- [Usage](#usage)
- [Global flags](#global-flags)
- [`generate` — scaffold a config file](#generate)
- [`run` — install the runtime stack](#run)
- [Configuration reference](#configuration-reference)
- [What `run` does, step by step](#what-run-does-step-by-step)
- [Directory layout after installation](#directory-layout-after-installation)
- [Building from source](#building-from-source)
---
## Prerequisites
The following tools must be available on `PATH`:
| `curl` | Download release assets |
| `gpg` | Verify the runc binary signature |
| `sha512sum` | Verify the CNI plugins archive |
| `sha256sum` | Verify the containerd archive |
| `tar` | Extract tarballs |
| `sudo` | Write to system directories (escalated automatically when needed) |
On a Debian/Ubuntu host all of these (except Docker) are present by default.
---
## Installation
Install from [crates.io](https://crates.io/crates/cisak):
```bash
cargo install cisak
```
Or build from source:
```bash
cargo build --release
sudo cp target/release/cisak /usr/local/bin/cisak
```
---
## Usage
```
cisak [OPTIONS] <COMMAND>
Options:
-y, --assume-yes Skip all y/N confirmations (assume yes)
-h, --help Print help
-V, --version Print version
Commands:
generate Generate a config.toml file in the current directory
run Download, verify, and install runc + CNI plugins + containerd
```
### Global flags
| `--assume-yes` | `-y` | Suppress all interactive prompts; every command is executed automatically |
### `generate`
```bash
cisak generate
```
Writes a `config.toml` scaffold to the current working directory. Fails if the file already exists. Edit the version fields as needed before running `cisak run`.
---
### `run`
```bash
# Interactive (default) — you confirm each external command
cisak run
# Non-interactive — useful in CI / provisioning scripts
cisak -y run
```
Reads `config.toml` from the current directory and installs:
1. **runc** — installed to the path specified by `runtime.binary` (default `/usr/local/sbin/runc`)
2. **CNI plugins** — extracted into `cni.install_dir` (default `/opt/cni/bin`)
3. **containerd** — extracted into `containerd.install_dir/bin/` (default `/usr/local/bin/`)
Each section is optional; omitting `[cni]` or `[containerd]` from the config skips that component.
---
## Configuration reference
```toml
# Generated by cisak
[runtime]
name = "runc"
version = "v1.4.2"
binary = "/usr/local/sbin/runc" # optional — default shown
[cni]
version = "v1.9.1"
install_dir = "/opt/cni/bin" # optional — default shown
[containerd]
# Binaries land in <install_dir>/bin/ (e.g. /usr/local/bin/containerd)
version = "v2.2.3"
install_dir = "/usr/local" # optional — default shown
```
| `runtime.name` | ✓ | — | Runtime name (informational) |
| `runtime.version` | ✓ | — | runc release tag, e.g. `v1.4.2` |
| `runtime.binary` | | `/usr/local/sbin/runc` | Destination path for the runc binary |
| `cni.version` | ✓* | — | CNI plugins release tag |
| `cni.install_dir` | | `/opt/cni/bin` | Directory the tarball is extracted into |
| `containerd.version` | ✓* | — | containerd release tag |
| `containerd.install_dir` | | `/usr/local` | Prefix; binaries land in `<prefix>/bin/` |
\* Required when the section is present.
---
## What `run` does, step by step
```
1. Read config.toml
── runc ──────────────────────────────────────────────────────
2. Check / import GPG key C2428CD7…
3. curl → /tmp/…/runc.amd64
4. curl → /tmp/…/runc.amd64.asc
5. gpg --verify runc.amd64.asc runc.amd64
6. sudo install -m 0755 runc.amd64 /usr/local/sbin/runc
── CNI plugins ───────────────────────────────────────────────
7. curl → /tmp/…/cni-plugins-linux-amd64-<ver>.tgz
8. curl → /tmp/…/cni-plugins-linux-amd64-<ver>.tgz.sha512
9. sha512sum --check (run from the temp directory)
10. tar -C /opt/cni/bin -xzf cni-plugins-linux-amd64-<ver>.tgz
── containerd ────────────────────────────────────────────────
11. curl → /tmp/…/containerd-<ver>-linux-amd64.tar.gz
12. curl → /tmp/…/containerd-<ver>-linux-amd64.tar.gz.sha256sum
13. sha256sum --check (run from the temp directory)
14. tar -C /usr/local -xzf containerd-<ver>-linux-amd64.tar.gz
```
Steps that write to system directories automatically retry with `sudo` if the unprivileged attempt fails.
---
## Directory layout after installation
```
/usr/local/sbin/runc ← runc binary
/opt/cni/bin/ ← CNI plugin binaries
bridge
host-local
loopback
…
/usr/local/bin/ ← containerd binaries
containerd
containerd-shim-runc-v2
ctr
…
```
---
## Building from source
```bash
# Requires Rust 1.70+ (2021 edition)
git clone https://github.com/rodolfovillaruz/cisak
cd cisak
cargo build --release
```
Run the test suite:
```bash
cargo test
```
Lint and format:
```bash
cargo clippy -- -D warnings
cargo fmt --check
```
---
## License
This project is licensed under the [MIT License](LICENSE).