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
54 changes: 54 additions & 0 deletions .github/workflows/smoke.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: smoke

on:
schedule:
- cron: "17 8 * * *"
workflow_dispatch:
pull_request:
types:
- opened
- synchronize
- reopened
- labeled

jobs:
smoke:
if: github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'smoke')
runs-on: ubuntu-latest
timeout-minutes: 90

steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod

- name: Install smoke tooling
run: |
set -euo pipefail
sudo apt-get update
sudo apt-get install -y ca-certificates curl iproute2 make openssl tar

mkdir -p "${RUNNER_TEMP}/bin"
echo "${RUNNER_TEMP}/bin" >> "${GITHUB_PATH}"

curl -fsSL -o "${RUNNER_TEMP}/bin/kind" "https://kind.sigs.k8s.io/dl/v0.29.0/kind-linux-amd64"
chmod +x "${RUNNER_TEMP}/bin/kind"

curl -fsSL -o "${RUNNER_TEMP}/bin/kubectl" "https://dl.k8s.io/release/v1.33.2/bin/linux/amd64/kubectl"
chmod +x "${RUNNER_TEMP}/bin/kubectl"

curl -fsSL "https://get.helm.sh/helm-v3.18.3-linux-amd64.tar.gz" | tar -xz -C "${RUNNER_TEMP}"
mv "${RUNNER_TEMP}/linux-amd64/helm" "${RUNNER_TEMP}/bin/helm"

curl -fsSL -o "${RUNNER_TEMP}/bin/yq" "https://github.com/mikefarah/yq/releases/download/v4.45.4/yq_linux_amd64"
chmod +x "${RUNNER_TEMP}/bin/yq"

curl -fsSL -o "${RUNNER_TEMP}/bin/devspace" "https://github.com/loft-sh/devspace/releases/download/v6.3.15/devspace-linux-amd64"
chmod +x "${RUNNER_TEMP}/bin/devspace"

- name: Run smoke
run: make smoke
7 changes: 6 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: help install-precommit setup-dev lint test test-install clean
.PHONY: help install-precommit setup-dev lint test test-install test-e2e smoke clean

help: ## Display this help message
@echo "Available targets:"
Expand Down Expand Up @@ -56,6 +56,11 @@ test: ## Run all tests
test-install: ## Run live DevSpace install diagnostics
CGO_ENABLED=1 go test -count=1 -v -timeout 5m ./tests/install

test-e2e: ## Run full ephemeral-cluster DevSpace e2e validation
go run ./tests/e2e/cmd/smoke

smoke: test-e2e ## Run expensive smoke validation

clean: ## Clean up generated files
@echo "Cleaning up..."
rm -rf charts/*/charts/
Expand Down
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,34 @@ dns-sd -q ns.dns.kube

**NOTE**: on macOS, do not rely on `dig` for testing DNS resolution.

### Ephemeral Smoke Validation

Run the full advertised deploy path against a throwaway local cluster:

```bash
make smoke
```

This creates an ephemeral `kind` cluster with an isolated kubeconfig, runs `devspace deploy`, runs the
live install diagnostics, and deletes the cluster. The direct e2e target is also available:

```bash
make test-e2e
```

Useful local overrides:

```bash
E2E_CLUSTER_NAME=my-smoke E2E_KEEP_CLUSTER=1 make smoke
E2E_DEVSPACE_ARGS="--profile o11y-grafana" make smoke
E2E_TIMEOUT=30m E2E_READY_TIMEOUT=10m make smoke
```

`E2E_CLUSTER_PROVIDER=kind` is the current default and only implemented provider. `vind` is reserved
as a future provider name. Timeout knobs use Go duration syntax and include `E2E_TIMEOUT`,
`E2E_CLUSTER_CREATE_WAIT`, `E2E_CLEANUP_TIMEOUT`, `E2E_READY_TIMEOUT`,
`E2E_READY_REPORT_INTERVAL`, `E2E_DIAGNOSTIC_TIMEOUT`, and `E2E_TEST_TIMEOUT`.

## Available Profiles

| Profile | Description | Components |
Expand Down
80 changes: 73 additions & 7 deletions devspace.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ profiles:
description: Network, Gateways, Ingress
activation:
- vars:
DEVSPACE_CONTEXT: "^(kind|docker-desktop|minikube|rancher-desktop|microk8s)$"
DEVSPACE_CONTEXT: "^(kind(?:-.+)?|docker-desktop|minikube|rancher-desktop|microk8s)$"
merge:
deployments:
metallb:
Expand Down Expand Up @@ -178,7 +178,7 @@ profiles:
description: Local DNS integration for development
activation:
- vars:
DEVSPACE_CONTEXT: "^(kind|docker-desktop|minikube|rancher-desktop|microk8s)$"
DEVSPACE_CONTEXT: "^(kind(?:-.+)?|docker-desktop|minikube|rancher-desktop|microk8s)$"
merge:
deployments:
etcd:
Expand Down Expand Up @@ -223,7 +223,7 @@ profiles:
description: Certificate Management
activation:
- vars:
DEVSPACE_CONTEXT: "^(kind|docker-desktop|minikube|rancher-desktop|microk8s)$"
DEVSPACE_CONTEXT: "^(kind(?:-.+)?|docker-desktop|minikube|rancher-desktop|microk8s)$"
merge:
deployments:
cert-manager:
Expand Down Expand Up @@ -281,7 +281,7 @@ profiles:
description: Auxiliary services
activation:
- vars:
DEVSPACE_CONTEXT: "^(kind|docker-desktop|minikube|rancher-desktop|microk8s)$"
DEVSPACE_CONTEXT: "^(kind(?:-.+)?|docker-desktop|minikube|rancher-desktop|microk8s)$"
merge:
deployments:
reloader:
Expand Down Expand Up @@ -312,7 +312,7 @@ profiles:
description: Cluster observability with Prometheus metrics and lightweight tracing
activation:
- vars:
DEVSPACE_CONTEXT: "^(kind|docker-desktop|minikube|rancher-desktop|microk8s)$"
DEVSPACE_CONTEXT: "^(kind(?:-.+)?|docker-desktop|minikube|rancher-desktop|microk8s)$"
merge:
deployments:
prometheus:
Expand Down Expand Up @@ -501,19 +501,34 @@ hooks:
silent: true
events: ["before:deploy:metallb"]

- name: update-cluster-dns-hook
- name: update-cluster-dns-hook-darwin
os: darwin
command: devspace run update-cluster-dns
events: ["after:deploy:cert-chain"]

- name: cert-chain-hook
- name: update-cluster-dns-hook-linux
os: linux
command: devspace run update-cluster-dns-linux
events: ["after:deploy:cert-chain"]

- name: cert-chain-hook-darwin
os: darwin
command: |
while ! devspace run import-root-ca; do
echo >&2 "I: Waiting for root CA to be available..."
sleep 5
done
events: ["after:deploy:cert-chain"]

- name: cert-chain-hook-linux
os: linux
command: |
while ! devspace run import-root-ca-linux; do
echo >&2 "I: Waiting for root CA to be available..."
sleep 5
done
events: ["after:deploy:cert-chain"]

- name: wait-for-trust-manager-hook
wait:
running: true
Expand Down Expand Up @@ -597,6 +612,21 @@ commands:
quit
EOF

update-cluster-dns-linux:
description: Make external cluster DNS available on a Linux host
section: network
command: |
DNS_IP="${DOCKER_CIDR_PREFIX}.254"
echo >&2 "I: Updating systemd-resolved DNS settings..."
LINK="$(ip route get "${DNS_IP}" | awk '{for (i = 1; i <= NF; i++) if ($i == "dev") {print $(i + 1); exit}}')"
if [ -z "${LINK}" ]; then
echo >&2 "E: Could not determine Linux route interface for ${DNS_IP}"
exit 1
fi
sudo resolvectl dns "${LINK}" "${DNS_IP}"
sudo resolvectl domain "${LINK}" "~kube"
sudo resolvectl flush-caches

reset-cluster-dns:
description: Reset DNS service
section: network
Expand All @@ -608,6 +638,20 @@ commands:
quit
EOF

reset-cluster-dns-linux:
description: Reset Linux systemd-resolved cluster DNS service
section: network
command: |
DNS_IP="${DOCKER_CIDR_PREFIX}.254"
echo >&2 "I: Resetting systemd-resolved DNS settings..."
LINK="$(ip route get "${DNS_IP}" | awk '{for (i = 1; i <= NF; i++) if ($i == "dev") {print $(i + 1); exit}}')"
if [ -z "${LINK}" ]; then
echo >&2 "E: Could not determine Linux route interface for ${DNS_IP}"
exit 1
fi
sudo resolvectl revert "${LINK}"
sudo resolvectl flush-caches

import-root-ca:
description: Import the root CA certificate of the cluster
section: network
Expand All @@ -630,6 +674,28 @@ commands:

echo >&2 "I: Root CA certificate imported successfully to system keychain."

import-root-ca-linux:
description: Import the root CA certificate of the cluster into the Linux trust store
section: network
command: |
CERTFILE=$(mktemp -t cluster-root-ca.XXXXXX.crt)
# Ensure cleanup on exit
trap 'rm -f "${CERTFILE}"' EXIT

echo >&2 "I: Extracting Root CA certificate..."
kubectl get secret -n istio-ingress cluster-root-ca-secret -o jsonpath='{.data.tls\.crt}' | base64 -d > "${CERTFILE}"
if [ ! -s "${CERTFILE}" ]; then
echo >&2 "E: Failed to extract certificate or certificate is empty"
exit 1
fi
openssl x509 -in "${CERTFILE}" -subject -issuer -dates -noout

echo >&2 "I: Adding certificate to Linux trust store..."
sudo install -m 0644 "${CERTFILE}" /usr/local/share/ca-certificates/devspace-starter-pack-cluster-root-ca.crt
sudo update-ca-certificates

echo >&2 "I: Root CA certificate imported successfully to Linux trust store."

port-forward-otel:
description: Forward the local OpenTelemetry Collector OTLP ports
section: observability
Expand Down
Loading
Loading