Skip to content

Commit 1dca8fd

Browse files
committed
Build spind VM orchestration tooling
1 parent 2444846 commit 1dca8fd

210 files changed

Lines changed: 25202 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.editorconfig

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
end_of_line = lf
6+
indent_size = 2
7+
indent_style = tab
8+
insert_final_newline = true
9+
trim_trailing_whitespace = true
10+
11+
[*.{js,jsx,ts,tsx}]
12+
indent_style = space
13+
max_line_length = 100
14+
15+
[*.{json,yaml,yml,toml}]
16+
indent_style = space
17+
18+
[*.md]
19+
trim_trailing_whitespace = false
20+
indent_style = space

.envrc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/usr/bin/env bash
2+
3+
# Automatically sets up your devbox environment whenever you cd into this
4+
# directory via our direnv integration:
5+
6+
eval "$(devbox generate direnv --print-envrc)"
7+
8+
# check out https://www.jetify.com/docs/devbox/ide_configuration/direnv/
9+
# for more details

.github/workflows/ci.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
8+
jobs:
9+
ci:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
13+
- uses: jetify-com/devbox-install-action@8c6a66ed6273138b1915457069de78cb52fe3bd7 # v0.15.0
14+
with:
15+
enable-cache: "true"
16+
- run: devbox run -- task ci
17+
18+
ci-macos:
19+
runs-on: macos-15-intel
20+
steps:
21+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
22+
- uses: jetify-com/devbox-install-action@8c6a66ed6273138b1915457069de78cb52fe3bd7 # v0.15.0
23+
with:
24+
enable-cache: "true"
25+
- run: devbox run -- task ci:macos

.gitignore

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
bin/
2+
node_modules/
3+
js/
4+
dist/
5+
*.tsbuildinfo
6+
coverage/
7+
*.lcov
8+
logs/
9+
*.log
10+
.env
11+
.env.*
12+
!.env.example
13+
!.envrc
14+
.cache/
15+
.DS_Store
16+
.review/
17+
result
18+
.devbox/

README.md

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# spind
2+
3+
spind is a fast local development environment for people who build web applications that use the Kubernetes API, and for people who build Kubernetes Operators.
4+
5+
It supports kind-based Kubernetes environments and makes clean environments fast to create, reset, and start.
6+
7+
## Why spind?
8+
9+
Kubernetes development and testing often need a clean Kubernetes environment. Creating that environment every time is slow.
10+
11+
Common setup steps can take seconds or minutes:
12+
13+
- `kind create cluster` can take about 30 seconds.
14+
- `helm install` can take several minutes.
15+
- End-to-end tests and integration tests often need a clean cluster.
16+
- CI runs can spend several minutes only preparing the environment.
17+
18+
During development, you often create an environment, test something, break it, delete it, and create it again. That wait makes the development loop slow.
19+
20+
spind reduces setup time from minutes to less than 1000 ms by restoring a ready VM snapshot.
21+
22+
This makes development, manual checks, end-to-end tests, integration tests, CI, and CD faster.
23+
24+
## How it works
25+
26+
spind is built around microVMs and snapshots.
27+
28+
On macOS, spind starts a small Linux VM with Virtualization.framework. On Linux, spind starts a small Linux VM with Cloud Hypervisor.
29+
30+
The Linux VM is not a special Kubernetes system. It is a small Docker machine. You can use your normal Docker client, kind, kubectl, and helm.
31+
32+
spind sets up the runtime VM once, then saves that ready state as a snapshot. After that, spind restores from the snapshot. This lets you start an environment where the kind cluster and Helm charts are already prepared.
33+
34+
## Use cases
35+
36+
- Web applications that use the Kubernetes API
37+
- Kubernetes Operator development
38+
- Local Kubernetes development with kind
39+
- Clean environments for end-to-end tests and integration tests
40+
- Faster Kubernetes environment setup in CI/CD
41+
42+
## Install
43+
44+
Install spind with `go install`.
45+
46+
```sh
47+
go install github.com/suin/spind/cmd/spind@latest
48+
```
49+
50+
After installing, check your host dependencies.
51+
52+
```sh
53+
spind doctor
54+
```
55+
56+
## Dependencies
57+
58+
`spind doctor` checks the dependencies needed on your current host. This section gives the basic list.
59+
60+
Common:
61+
62+
- Go
63+
- Docker CLI
64+
65+
macOS:
66+
67+
- Apple Swift compiler
68+
- `codesign`
69+
- Xcode Command Line Tools
70+
- A macOS environment that supports Virtualization.framework
71+
72+
Linux:
73+
74+
- A Linux environment with KVM support
75+
- `/dev/kvm`
76+
- `cloud-hypervisor`
77+
- `passt`
78+
- `virtiofsd`
79+
80+
Docker image builds need the Docker CLI. On Linux, `passt` and `virtiofsd` are also used for Docker host support, snapshot restore support, and host path sharing.
81+
82+
## Basic usage
83+
84+
Put `spind.yaml` in your project root.
85+
86+
```yaml
87+
name: sample
88+
image: docker
89+
kind: true
90+
setup:
91+
- "kind create cluster"
92+
- "kubectl --context kind-kind wait node --all --for=condition=Ready --timeout=180s"
93+
```
94+
95+
Start the development environment.
96+
97+
```sh
98+
spind up
99+
```
100+
101+
On the first run, spind creates a VM, runs the commands in `setup`, and saves the ready state as a snapshot. Later runs restore from that snapshot.
102+
103+
## Development
104+
105+
Use these commands when working on this repository.
106+
107+
```sh
108+
task build
109+
task check
110+
task test
111+
task test:ts
112+
```
113+
114+
Run end-to-end tests:
115+
116+
```sh
117+
task e2e
118+
```
119+
120+
## Design docs
121+
122+
Detailed design notes are in `docs/design/`.
123+
124+
- `docs/design/minimum-cli.md`
125+
- `docs/design/project-up.md`
126+
- `docs/design/docker-host.md`
127+
- `docs/design/kind-ready-snapshot.md`
128+
- `docs/design/snapshot.md`
129+
- `docs/design/roadmap.md`

Taskfile.yml

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
version: "3"
2+
3+
vars:
4+
BIN_DIR: bin
5+
SPIND_BIN: "{{.BIN_DIR}}/spind"
6+
GUEST_AGENT_BIN: "{{.BIN_DIR}}/spind-guest-agent"
7+
8+
tasks:
9+
default:
10+
desc: List available tasks
11+
cmds:
12+
- task --list
13+
14+
# Quality gates
15+
check:
16+
desc: Run all checks
17+
cmds:
18+
- task: format:check
19+
- task: lint
20+
- task: typecheck
21+
- task: test
22+
23+
ci:
24+
desc: Run CI pipeline (frozen install + all checks)
25+
cmds:
26+
- bun install --frozen-lockfile
27+
- task: check
28+
29+
ci:macos:
30+
desc: Run macOS CI pipeline (frozen install + e2e)
31+
cmds:
32+
- bun install --frozen-lockfile
33+
- task: e2e
34+
35+
format:
36+
desc: Format source files
37+
cmds:
38+
- bunx oxfmt --write .
39+
40+
format:check:
41+
desc: Check source formatting
42+
cmds:
43+
- bunx oxfmt --check .
44+
45+
lint:
46+
desc: Run the linter
47+
cmds:
48+
- bunx oxlint
49+
50+
test:
51+
desc: Run Go tests
52+
cmds:
53+
- go list ./... | grep -v '/node_modules/' | xargs go test
54+
55+
typecheck:
56+
desc: Type check without emitting
57+
cmds:
58+
- bunx tsc -b --noEmit
59+
60+
# Build tasks
61+
build:
62+
desc: Build local spind binaries
63+
cmds:
64+
- mkdir -p {{.BIN_DIR}}
65+
- go build -o {{.SPIND_BIN}} ./cmd/spind
66+
- CGO_ENABLED=0 GOOS=linux GOARCH="$(go env GOARCH)" go build -o {{.GUEST_AGENT_BIN}} ./cmd/agent
67+
- |
68+
if [ "$(uname -s)" = "Darwin" ]; then
69+
{{.SPIND_BIN}} prepare-vz-runner
70+
else
71+
echo "skipping managed Virtualization.framework runner build on $(uname -s)"
72+
fi
73+
74+
build:ts:
75+
desc: Build TypeScript files
76+
cmds:
77+
- bunx tsc -b
78+
79+
build-image-docker:
80+
desc: Build the Docker image
81+
deps:
82+
- build
83+
cmds:
84+
- "{{.SPIND_BIN}} image build docker --force"
85+
86+
clean:
87+
desc: Clean build artifacts
88+
cmds:
89+
- rm -rf js *.tsbuildinfo
90+
91+
# End-to-end tests
92+
e2e:
93+
desc: Run end-to-end tests
94+
deps:
95+
- build-image-docker
96+
cmds:
97+
- bun test tests/e2e --timeout 2700000 --bail
98+
env:
99+
EXECA_VERBOSE: short # "short" | "full" | "none"

0 commit comments

Comments
 (0)