Skip to content
/ brownie Public

πŸͺ An OCI spec-compliant Linux container runtime; written in Go.

License

Notifications You must be signed in to change notification settings

nixpig/brownie

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

build

πŸͺ brownie

An experimental Linux container runtime, implementing the OCI Runtime Spec.

docker hello-world with brownie runtime

This is a personal project for me to explore and better understand the OCI Runtime Spec. It's not production-ready, and it probably never will be, but feel free to look around! If you're looking for a production-ready alternative to runc, take a look at youki, which I think is pretty cool.

brownie passes all passable tests in the opencontainers OCI runtime test suite. That doesn't mean that brownie is feature-complete...yet. See below for outstanding items.

πŸ—’οΈ To do (items remaining for me to consider this 'complete')

  • Unit tests Integration tests seem to be sufficing
  • Implement optional Seccomp
  • Implement optional AppArmor
  • Refactor and tidy-up

Installation

Caution

Some features may require sudo and make changes to your system.

Given this is an experimental project, take appropriate precautions.

Download pre-built binary

  1. Go to Releases and download the tarball for your architecture, e.g. brownie_0.0.1_linux_amd64.tar.gz.
  2. Extract the brownie binary from the tarball and put somewhere in $PATH, e.g. ~/.local/bin.

Build from source

Prerequisite: Compiler for Go installed (instructions).

git clone git@github.com:nixpig/brownie.git
cd brownie
make build
mv tmp/bin/brownie ~/.local/bin

I'm developing brownie on the following environment. Even with the same set up, YMMV.

  • Linux vagrant 6.8.0-31-generic #31-Ubuntu SMP PREEMPT_DYNAMIC Sat Apr 20 00:40:06 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
  • go version go1.23.4 linux/amd64
  • Docker version 27.3.1, build ce12230

You can spin up this VM from the included Vagrantfile, just run vagrant up.

Usage

Docker

By default, the Docker daemon uses the runc container runtime. brownie can be used as a drop-in replacement for runc.

You can find detailed instructions on how to configure alternative runtimes in the Docker docs. If you just want to quickly experiment, the following should suffice:

# 1. Stop any running Docker service
sudo systemctl stop docker.service

# 2. Start the Docker Daemon with added brownie runtime
sudo dockerd --add-runtime brownie=PATH_TO_BROWNIE_BINARY

# 3. Run a container using the brownie runtime
docker run -it --runtime brownie busybox sh

CLI

The brownie CLI implements the OCI Runtime Command Line Interface spec.

brownie create

Create a new container.

Usage:
  brownie create [flags] CONTAINER_ID

Examples:
  brownie create busybox

Flags:
  -b, --bundle string           Path to bundle directory
  -s, --console-socket string   Console socket
  -h, --help                    help for create
  -p, --pid-file string         File to write container PID to

brownie start

Start an existing container.

Usage:
  brownie start [flags] CONTAINER_ID

Examples:
  brownie start busybox

Flags:
  -h, --help   help for start

brownie kill

Send a signal to a running container.

Usage:
  brownie kill [flags] CONTAINER_ID SIGNAL

Examples:
  brownie kill busybox 9

Flags:
  -h, --help   help for kill

brownie delete

Delete a container.

Usage:
  brownie delete [flags] CONTAINER_ID

Examples:
  brownie delete busybox

Flags:
  -f, --force   force delete
  -h, --help    help for delete

brownie state

Get the state of a container.

Usage:
  brownie state [flags] CONTAINER_ID

Examples:
  brownie state busybox

Flags:
  -h, --help   help for state

Library

The container package of brownie can be used directly as a library (in the same way that the CLI does).

The consumer will be responsible for all of the necessary 'bookkeeping'.

Example

go get github.com/nixpig/brownie/container
package main

import "github.com/nixpig/brownie/container"

func main() {
  // TODO: example usage
}

Progress

My goal is for brownie to (eventually) pass all tests in the opencontainers OCI Runtime Spec tests. Below is progress against that goal.

βœ… Passing

Tests are run on every build in this Github Action.

  • default
  • ___
  • config_updates_without_affect
  • create
  • delete
  • hooks
  • hooks_stdin
  • hostname
  • kill
  • killsig
  • kill_no_effect
  • linux_devices
  • linux_masked_paths
  • linux_mount_label
  • linux_ns_itype
  • linux_ns_nopath
  • linux_ns_path
  • linux_ns_path_type
  • linux_readonly_paths
  • linux_rootfs_propagation
  • linux_sysctl
  • misc_props (flaky due to test suite trying to delete container before process has exiting and status updated to stopped)
  • mounts
  • poststart
  • poststop
  • prestart
  • prestart_fail
  • process
  • process_capabilities
  • process_capabilities_fail
  • process_oom_score_adj
  • ❌ process_rlimits
  • process_rlimits_fail
  • process_user
  • root_readonly_true
  • start
  • state
  • linux_uid_mappings

⚠️ Unsupported tests

cgroups v1 & v2 support

The OCI Runtime Spec test suite provided by opencontainers does not support cgroup v2.

The OCI Runtime Spec test suite provided by opencontainers does support cgroup v1.

brownie currently implements both cgroup v1 and v2. However, like runc and other container runtimes, the find x cgroup tests pass and the get x cgroup data tests fail.

Full list of cgroups tests
  • linux_cgroups_blkio
  • linux_cgroups_cpus
  • linux_cgroups_devices
  • linux_cgroups_hugetlb
  • linux_cgroups_memory
  • linux_cgroups_network
  • linux_cgroups_pids
  • linux_cgroups_relative_blkio
  • linux_cgroups_relative_cpus
  • linux_cgroups_relative_devices
  • linux_cgroups_relative_hugetlb
  • linux_cgroups_relative_memory
  • linux_cgroups_relative_network
  • linux_cgroups_relative_pids
  • delete_resources
  • delete_only_create_resources

Broken tests

Tests failed by runc and other container runtimes. In some cases the tests may be broken; in others, who knows. Either way, for my purposes, parity with other runtimes is more important than passing the tests.

  • pidfile
  • poststart_fail
  • poststop_fail

Tests that 'pass' (seemingly) regardless of whether the feature has been implemented. May indicate a bad test.

  • linux_process_apparmor_profile
  • linux_seccomp

Contributing

Given this is an exploratory personal project, I'm not interested in taking code contributions. However, if you have any comments/suggestions/feedback, do feel free to leave them in issues.

Inspiration

While this project was built entirely from scratch, inspiration was taken from existing runtimes, in no particular order:

License

MIT