Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .github/kind-kvm-multinode-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraMounts:
- hostPath: /dev/kvm
containerPath: /dev/kvm
- hostPath: /tmp/smolvm-kind-control-plane-var-lib
containerPath: /var/lib/smolvm
- hostPath: /tmp/smolvm-kind-control-plane-var-run
containerPath: /var/run/smolvm
- role: worker
extraMounts:
- hostPath: /dev/kvm
containerPath: /dev/kvm
- hostPath: /tmp/smolvm-kind-worker-var-lib
containerPath: /var/lib/smolvm
- hostPath: /tmp/smolvm-kind-worker-var-run
containerPath: /var/run/smolvm
- role: worker
extraMounts:
- hostPath: /dev/kvm
containerPath: /dev/kvm
- hostPath: /tmp/smolvm-kind-worker2-var-lib
containerPath: /var/lib/smolvm
- hostPath: /tmp/smolvm-kind-worker2-var-run
containerPath: /var/run/smolvm
159 changes: 152 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,27 @@ on:
pull_request:
workflow_dispatch:

permissions:
contents: read
packages: write

jobs:
lint:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
cache: true
- name: Run linters
run: make lint

envtest:
name: envtest controller
runs-on: ubuntu-latest
needs: [lint]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
Expand All @@ -25,22 +42,77 @@ jobs:
name: envtest-reports
path: reports/

release-artifact:
name: install artifact reproducibility
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
cache: true
- name: Build reproducible install artifact
run: make rc-artifacts VERSION=ci IMG=ghcr.io/${{ github.repository }}/smolvm-operator:${{ github.sha }} RUNTIME_IMG=ghcr.io/${{ github.repository }}/smolvm-runtime:${{ github.sha }}
- name: Upload install artifact
uses: actions/upload-artifact@v4
with:
name: install-artifact
path: dist/

container-images:
name: immutable container images
runs-on: ubuntu-latest
if: github.event_name != 'pull_request'
steps:
- uses: actions/checkout@v4
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and publish immutable images
run: |
docker build -t ghcr.io/${{ github.repository }}/smolvm-operator:${{ github.sha }} .
docker build -f Dockerfile.runtime --build-arg SMOLVM_VERSION=0.8.1 -t ghcr.io/${{ github.repository }}/smolvm-runtime:${{ github.sha }} .
docker push ghcr.io/${{ github.repository }}/smolvm-operator:${{ github.sha }}
docker push ghcr.io/${{ github.repository }}/smolvm-runtime:${{ github.sha }}

kind-e2e:
name: kind topology e2e
runs-on: ubuntu-latest
needs: [envtest, release-artifact]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
cache: true
- name: Prepare KVM-backed multi-node kind mounts
run: |
set -euxo pipefail
test -e /dev/kvm
sudo chmod 666 /dev/kvm
for node in control-plane worker worker2; do
sudo mkdir -p "/tmp/smolvm-kind-${node}-var-lib" "/tmp/smolvm-kind-${node}-var-run"
sudo chmod 777 "/tmp/smolvm-kind-${node}-var-lib" "/tmp/smolvm-kind-${node}-var-run"
done
- name: Build e2e images and manifest
run: |
docker build -t smolvm-operator:e2e .
docker build -f Dockerfile.runtime --build-arg SMOLVM_VERSION=0.8.1 -t smolvm-runtime:e2e .
make build-installer IMG=smolvm-operator:e2e RUNTIME_IMG=smolvm-runtime:e2e
- uses: helm/kind-action@v1
with:
cluster_name: kind
- name: Run deployed-topology e2e test
config: .github/kind-kvm-multinode-config.yaml
- name: Load e2e images
run: |
kind load docker-image smolvm-operator:e2e --name kind
kind load docker-image smolvm-runtime:e2e --name kind
- name: Run deployed topology e2e
env:
RUN_E2E: "true"
KIND_CLUSTER: kind
E2E_INSTALL_MANIFEST: dist/install.yaml
run: make test-e2e-report
- name: Upload e2e reports
if: always()
Expand All @@ -52,33 +124,106 @@ jobs:
smolvm-runtime-e2e:
name: smolvm runtime lifecycle e2e
runs-on: ubuntu-latest
needs: [envtest, release-artifact]
timeout-minutes: 45
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
cache: true
- name: Prepare KVM-backed kind mounts
- name: Prepare KVM-backed multi-node kind mounts
run: |
set -euxo pipefail
test -e /dev/kvm
sudo chmod 666 /dev/kvm
sudo mkdir -p /tmp/smolvm-kind-var-lib /tmp/smolvm-kind-var-run
sudo chmod 777 /tmp/smolvm-kind-var-lib /tmp/smolvm-kind-var-run
for node in control-plane worker worker2; do
sudo mkdir -p "/tmp/smolvm-kind-${node}-var-lib" "/tmp/smolvm-kind-${node}-var-run"
sudo chmod 777 "/tmp/smolvm-kind-${node}-var-lib" "/tmp/smolvm-kind-${node}-var-run"
done
- name: Build runtime e2e images and manifest
run: |
docker build -t smolvm-operator:runtime-e2e .
docker build -f Dockerfile.runtime --build-arg SMOLVM_VERSION=0.8.1 -t smolvm-runtime:runtime-e2e .
make build-installer IMG=smolvm-operator:runtime-e2e RUNTIME_IMG=smolvm-runtime:runtime-e2e
- uses: helm/kind-action@v1
with:
cluster_name: runtime
config: .github/kind-runtime-config.yaml
config: .github/kind-kvm-multinode-config.yaml
- name: Load runtime e2e images
run: |
kind load docker-image smolvm-operator:runtime-e2e --name runtime
kind load docker-image smolvm-runtime:runtime-e2e --name runtime
- name: Run runtime lifecycle e2e
env:
RUN_E2E: "true"
KIND_CLUSTER: runtime
E2E_INSTALL_MANIFEST: dist/install.yaml
RUNTIME_E2E: "true"
KIND_CLUSTER: runtime
run: make test-runtime-e2e-report
- name: Upload runtime logs
if: always()
uses: actions/upload-artifact@v4
with:
name: runtime-e2e-logs
path: reports/

release-hardening-e2e:
name: upgrade multi-node and failure gates
runs-on: ubuntu-latest
needs: [envtest, release-artifact]
if: ${{ vars.PREVIOUS_INSTALL_MANIFEST_URL != '' }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
cache: true
- name: Prepare KVM-backed multi-node kind mounts
run: |
set -euxo pipefail
test -e /dev/kvm
sudo chmod 666 /dev/kvm
for node in control-plane worker worker2; do
sudo mkdir -p "/tmp/smolvm-kind-${node}-var-lib" "/tmp/smolvm-kind-${node}-var-run"
sudo chmod 777 "/tmp/smolvm-kind-${node}-var-lib" "/tmp/smolvm-kind-${node}-var-run"
done
- name: Build hardening e2e images and manifests
env:
PREVIOUS_INSTALL_MANIFEST_URL: ${{ vars.PREVIOUS_INSTALL_MANIFEST_URL }}
run: |
set -euxo pipefail
if [ -z "$PREVIOUS_INSTALL_MANIFEST_URL" ]; then
echo "PREVIOUS_INSTALL_MANIFEST_URL repository variable is required for upgrade e2e" >&2
exit 1
fi
mkdir -p dist
curl -fsSL "$PREVIOUS_INSTALL_MANIFEST_URL" -o dist/previous-install.yaml
docker build -t smolvm-operator:rc .
docker build -f Dockerfile.runtime --build-arg SMOLVM_VERSION=0.8.1 -t smolvm-runtime:rc .
make build-installer IMG=smolvm-operator:rc RUNTIME_IMG=smolvm-runtime:rc
cp dist/install.yaml dist/rc-install.yaml
- uses: helm/kind-action@v1
with:
cluster_name: hardening
config: .github/kind-kvm-multinode-config.yaml
- name: Load hardening images
run: |
kind load docker-image smolvm-operator:rc --name hardening
kind load docker-image smolvm-runtime:rc --name hardening
- name: Run upgrade, multi-node, and failure checks
env:
RUN_E2E: "true"
E2E_INSTALL_MANIFEST: dist/rc-install.yaml
PREVIOUS_INSTALL_MANIFEST: dist/previous-install.yaml
RC_INSTALL_MANIFEST: dist/rc-install.yaml
run: |
make test-upgrade-e2e-report
make test-multinode-e2e-report
make test-failure-e2e-report
- name: Upload release hardening reports
if: always()
uses: actions/upload-artifact@v4
with:
name: release-hardening-reports
path: reports/
19 changes: 1 addition & 18 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,21 @@ run:
allow-parallel-runners: true

issues:
# don't skip warning about doc comments
# don't exclude the default set of lint
exclude-use-default: false
# restore some of the defaults
# (fill in the rest as needed)
exclude-rules:
- path: "api/*"
linters:
- lll
- path: "internal/*"
linters:
- dupl
- lll

linters:
disable-all: true
enable:
- dupl
- errcheck
- exportloopref
- goconst
- gocyclo
- gofmt
- goimports
- gosimple
- govet
- ineffassign
- lll
- misspell
- nakedret
- prealloc
- staticcheck
- typecheck
- unconvert
- unparam
- unused
56 changes: 45 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,30 @@ test-e2e:
go test ./test/e2e/ -v -ginkgo.v

.PHONY: test-e2e-report
test-e2e-report: gotestsum ## Run e2e tests and write a JUnit report under reports/.
test-e2e-report: gotestsum ## Run deployed topology e2e tests and write a JUnit report under reports/.
mkdir -p reports
$(GOTESTSUM) --format testname --junitfile reports/e2e.xml -- ./test/e2e/ -v -ginkgo.v
$(GOTESTSUM) --format testname --junitfile reports/e2e.xml -- ./test/e2e/ -v -ginkgo.v -ginkgo.label-filter='multinode || failure'

.PHONY: test-runtime-e2e-report
test-runtime-e2e-report: ## Run runtime lifecycle e2e tests and write a Ginkgo JUnit report under reports/.
mkdir -p reports
go test ./test/e2e -v -ginkgo.v -ginkgo.label-filter=runtime -ginkgo.junit-report=reports/runtime.xml

.PHONY: test-upgrade-e2e-report
test-upgrade-e2e-report: ## Run deployed upgrade e2e tests and write a Ginkgo JUnit report under reports/.
mkdir -p reports
go test ./test/e2e -v -ginkgo.v -ginkgo.label-filter=upgrade -ginkgo.junit-report=reports/upgrade.xml

.PHONY: test-multinode-e2e-report
test-multinode-e2e-report: ## Run deployed multi-node e2e tests and write a Ginkgo JUnit report under reports/.
mkdir -p reports
go test ./test/e2e -v -ginkgo.v -ginkgo.label-filter=multinode -ginkgo.junit-report=reports/multinode.xml

.PHONY: test-failure-e2e-report
test-failure-e2e-report: ## Run deployed failure-recovery e2e tests and write a Ginkgo JUnit report under reports/.
mkdir -p reports
go test ./test/e2e -v -ginkgo.v -ginkgo.label-filter=failure -ginkgo.junit-report=reports/failure.xml

.PHONY: lint
lint: golangci-lint ## Run golangci-lint linter & yamllint
$(GOLANGCI_LINT) run
Expand Down Expand Up @@ -139,15 +154,34 @@ docker-buildx: ## Build and push docker image for the manager for cross-platform
rm Dockerfile.cross

.PHONY: build-installer
build-installer: manifests generate kustomize ## Generate a consolidated YAML with CRDs and deployment.
build-installer: manifests generate kustomize ## Generate a consolidated install manifest without mutating config/.
mkdir -p dist
@if [ -d "config/crd" ]; then \
$(KUSTOMIZE) build config/crd > dist/install.yaml; \
fi
echo "---" >> dist/install.yaml # Add a document separator before appending
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
cd config/runtime && $(KUSTOMIZE) edit set image smolvm-runtime=${RUNTIME_IMG}
$(KUSTOMIZE) build config/default >> dist/install.yaml
out="$$(pwd)/dist/install.yaml"; \
tmpdir="$$(mktemp -d)"; \
trap 'rm -rf "$${tmpdir}"' EXIT; \
cp -R config "$${tmpdir}/config"; \
cd "$${tmpdir}/config/manager" && $(KUSTOMIZE) edit set image controller=${IMG}; \
cd "$${tmpdir}/config/runtime" && $(KUSTOMIZE) edit set image smolvm-runtime=${RUNTIME_IMG}; \
$(KUSTOMIZE) build "$${tmpdir}/config/default" > "$${out}"

.PHONY: release-artifacts
release-artifacts: build-installer ## Generate versioned release artifacts under dist/.
@if [ -z "$(VERSION)" ]; then echo "VERSION is required" >&2; exit 1; fi
cp dist/install.yaml dist/smolvm-operator-$(VERSION).yaml
shasum -a 256 dist/smolvm-operator-$(VERSION).yaml > dist/smolvm-operator-$(VERSION).yaml.sha256

.PHONY: verify-release-artifacts
verify-release-artifacts: release-artifacts ## Verify release artifacts are reproducible for the current inputs.
tmp="$$(mktemp)"; \
cp dist/smolvm-operator-$(VERSION).yaml "$${tmp}"; \
$(MAKE) release-artifacts VERSION=$(VERSION) IMG=$(IMG) RUNTIME_IMG=$(RUNTIME_IMG); \
cmp "$${tmp}" dist/smolvm-operator-$(VERSION).yaml

.PHONY: rc-check
rc-check: lint test-report test-e2e-report test-runtime-e2e-report test-upgrade-e2e-report test-multinode-e2e-report test-failure-e2e-report ## Run the release-candidate validation suite.

.PHONY: rc-artifacts
rc-artifacts: verify-release-artifacts ## Generate and verify RC install artifacts. Requires VERSION, IMG, and RUNTIME_IMG.

##@ Deployment

Expand Down Expand Up @@ -192,7 +226,7 @@ GOTESTSUM ?= $(LOCALBIN)/gotestsum-$(GOTESTSUM_VERSION)
KUSTOMIZE_VERSION ?= v5.3.0
CONTROLLER_TOOLS_VERSION ?= v0.19.0
ENVTEST_VERSION ?= latest
GOLANGCI_LINT_VERSION ?= v1.54.2
GOLANGCI_LINT_VERSION ?= v1.64.8
GOTESTSUM_VERSION ?= v1.13.0

.PHONY: kustomize
Expand Down
3 changes: 2 additions & 1 deletion cmd/runtime-agent/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,8 @@ func storageGiB(path string) int64 {
if err := syscall.Statfs(path, &stat); err != nil {
return 0
}
return int64(stat.Bavail) * int64(stat.Bsize) / 1024 / 1024 / 1024
bytesAvailable := uint64(stat.Bavail) * uint64(stat.Bsize) //nolint:unconvert
return int64(bytesAvailable / 1024 / 1024 / 1024)
}

func getenv(key, fallback string) string {
Expand Down
Loading
Loading