2020 solo5_version :
2121 type : string
2222 required : true
23- runc_version :
23+ kind_version :
2424 required : true
2525 type : string
2626 secrets :
2727 GIT_CLONE_PAT :
2828 required : false
2929 workflow_dispatch :
30+
3031permissions :
3132 contents : read
3233
3334jobs :
34- test :
35- name : Kubernetes test
35+ setup :
36+ name : Setup Kubernetes using kind and install urunc
3637 runs-on : ${{ matrix.runner }}
3738 strategy :
3839 matrix :
4344 runner : ubuntu-22.04-arm
4445 fail-fast : false
4546 steps :
47+
48+ - name : Validate inputs (prevent command injection)
49+ shell : bash
50+ env :
51+ FIRECRACKER_VERSION : ${{ inputs.firecracker_version }}
52+ SOLO5_VERSION : ${{ inputs.solo5_version }}
53+ KIND_VERSION : ${{ inputs.kind_version }}
54+ run : |
55+ SAFE_FIRECRACKER_VERSION="$FIRECRACKER_VERSION"
56+ SAFE_SOLO5_VERSION="$SOLO5_VERSION"
57+ SAFE_KIND_VERSION="$KIND_VERSION"
58+
59+ for var in SAFE_FIRECRACKER_VERSION SAFE_SOLO5_VERSION SAFE_KIND_VERSION; do
60+ value="${!var}"
61+ if ! [[ "$value" =~ ^v?[0-9]+\.[0-9]+(\.[0-9]+)?$ ]]; then
62+ echo "Invalid format for $var: $value"
63+ exit 1
64+ fi
65+ done
66+
67+ steps :
4668 - name : Harden the runner (Audit all outbound calls)
4769 uses : step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
4870 with :
@@ -51,17 +73,17 @@ jobs:
5173 - name : Checkout repository
5274 uses : actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
5375
54- - name : Install base dependencies
55- run : |
56- sudo apt-get update
57- sudo apt-get install -y git wget build-essential libseccomp-dev pkg-config bc make
5876 - name : Install kind
77+ env :
78+ KIND_VERSION : ${{ inputs.kind_version }}
79+ run : |
5980 run : |
6081 ARCH=$(uname -m)
82+ SAFE_KIND="${KIND_VERSION}"
6183 if [ "$ARCH" = "x86_64" ]; then
62- curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.29.0 /kind-linux-amd64
84+ curl -Lo ./kind https://kind.sigs.k8s.io/dl/v${SAFE_KIND} /kind-linux-amd64
6385 elif [ "$ARCH" = "aarch64" ]; then
64- curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.29.0 /kind-linux-arm64
86+ curl -Lo ./kind https://kind.sigs.k8s.io/dl/v${SAFE_KIND} /kind-linux-arm64
6587 else
6688 echo "Unsupported architecture: $ARCH"
6789 exit 1
@@ -97,32 +119,46 @@ jobs:
97119 - name : Create kind cluster
98120 run : |
99121 sudo kind create cluster --name urunc-test --config kind-config.yaml
100- - name : Install dependencies inside kind node
122+
123+ - name : Install kubectl
101124 run : |
102- docker exec urunc-test-control-plane apt-get update
103- docker exec urunc-test-control-plane apt-get install -y git wget build-essential libseccomp-dev pkg-config bc
125+ ARCH=$(uname -m)
126+ if [ "$ARCH" = "x86_64" ]; then
127+ KUBECTL_ARCH="amd64"
128+ elif [ "$ARCH" = "aarch64" ]; then
129+ KUBECTL_ARCH="arm64"
130+ else
131+ echo "Unsupported architecture: $ARCH"
132+ exit 1
133+ fi
134+ curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/${KUBECTL_ARCH}/kubectl"
135+ chmod +x kubectl
136+ sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
104137
105- - name : Install runc inside kind node
138+ - name : Set up kubectl config
106139 run : |
107- docker exec urunc-test-control-plane bash -c '
108- if ! which runc; then
109- wget -q https://github.com/opencontainers/runc/releases/download/v${{ inputs.runc_version }}/runc.$(dpkg --print-architecture)
110- install -m 755 runc.$(dpkg --print-architecture) /usr/local/sbin/runc
111- rm -f ./runc.$(dpkg --print-architecture)
112- fi
113- '
140+ mkdir -p ~/.kube
141+ kind get kubeconfig --name urunc-test > ~/.kube/config
142+ chmod 600 ~/.kube/config
143+ export KUBECONFIG=~/.kube/config
144+ kubectl config use-context kind-urunc-test
145+ kubectl wait --for=condition=Ready nodes --all --timeout=200s
146+ kubectl cluster-info
114147
115- - name : Configure containerd inside kind node
148+ - name : Create RuntimeClass
116149 run : |
117- docker exec urunc-test-control-plane bash -c '
118- systemctl status containerd || containerd &
119- mkdir -p /etc/containerd
120- containerd config default > /etc/containerd/config.toml
121- '
122- - name : Set snapshotter to overlayfs
150+ cat <<EOF | kubectl apply -f -
151+ kind: RuntimeClass
152+ apiVersion: node.k8s.io/v1
153+ metadata:
154+ name: urunc
155+ handler: urunc
156+ EOF
157+
158+ - name : Install base dependencies inside kind
123159 run : |
124- docker exec urunc-test-control-plane bash -c \
125- 'sed -i "s/snapshotter = \"devmapper\"/snapshotter = \"overlayfs\"/g" /etc/containerd/ config.toml'
160+ docker exec urunc-test-control-plane apt-get update
161+ docker exec urunc-test-control-plane apt-get install -y git wget build-essential libseccomp-dev pkg- config bc
126162
127163 - name : Download urunc artifact
128164 uses : actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
@@ -136,9 +172,6 @@ jobs:
136172 name : containerd-shim-urunc-v2_${{ matrix.arch }}-${{ github.run_id }}
137173 path : ./artifacts
138174
139- - name : List artifacts dir
140- run : ls -lR ./artifacts
141-
142175 - name : Copy and install urunc binaries
143176 run : |
144177 docker exec urunc-test-control-plane mkdir -p /urunc-temp
@@ -165,23 +198,27 @@ jobs:
165198 run : |
166199 docker exec urunc-test-control-plane apt-get install -y qemu-system
167200
168-
169201 - name : Install Firecracker inside kind node
202+ if : matrix.arch == 'amd64'
203+ env :
204+ FC_VERSION : ${{ inputs.firecracker_version }}
170205 run : |
171- FC_VERSION ="${{ inputs.firecracker_version } }"
206+ SAFE_FC ="${FC_VERSION }"
172207 docker exec urunc-test-control-plane bash -c '
173208 ARCH=$(uname -m)
174- echo "Downloading Firecracker version: '"$FC_VERSION "'"
175- curl -fsSL https://github.com/firecracker-microvm/firecracker/releases/download/'"$FC_VERSION "'/firecracker-'"$FC_VERSION "'-${ARCH}.tgz | tar -xz
176- install -m 755 release-'"$FC_VERSION "'-${ARCH}/firecracker-'"$FC_VERSION "'-${ARCH} /usr/local/bin/firecracker
209+ echo "Downloading Firecracker version: '"$SAVE_FC "'"
210+ curl -fsSL https://github.com/firecracker-microvm/firecracker/releases/download/'"$SAFE_FC "'/firecracker-'"$SAFE_FC "'-${ARCH}.tgz | tar -xz
211+ install -m 755 release-'"$SAFE_FC "'-${ARCH}/firecracker-'"$SAFE_FC "'-${ARCH} /usr/local/bin/firecracker
177212 firecracker --version
178213 '
179214
180215 - name : Install Solo5 inside kind node
216+ env :
217+ SOLO5_VERSION : ${{ inputs.solo5_version }}
181218 run : |
182- SOLO5_VERSION ="${{ inputs.solo5_version } }"
219+ SAFE_SOLO5 ="${SOLO5_VERSION }"
183220 docker exec urunc-test-control-plane bash -c '
184- git clone -b "'"$SOLO5_VERSION "'" https://github.com/Solo5/solo5.git
221+ git clone -b "'"$SAFE_SOLO5 "'" https://github.com/Solo5/solo5.git
185222 cd solo5
186223 ./configure.sh && make -j$(nproc)
187224 install -m 755 tenders/hvt/solo5-hvt /usr/local/bin/
@@ -191,153 +228,19 @@ jobs:
191228 solo5-hvt --version
192229 '
193230
231+ - name : Configure containerd inside kind node
232+ run : |
233+ docker exec urunc-test-control-plane bash -c '
234+ systemctl status containerd || containerd &
235+ mkdir -p /etc/containerd
236+ containerd config default > /etc/containerd/config.toml
237+ '
238+
194239 - name : Add urunc to containerd config
195240 run : |
196241 docker exec urunc-test-control-plane bash -c "cat <<'EOF' >> /etc/containerd/config.toml
197242 [plugins.'io.containerd.cri.v1.runtime'.containerd.runtimes.urunc]
198243 runtime_type = \"io.containerd.urunc.v2\"
199244 container_annotations = [\"com.urunc.unikernel.*\"]
200245 pod_annotations = [\"com.urunc.unikernel.*\"]
201- snapshotter = \"overlayfs\"
202246 EOF"
203-
204-
205- - name : Restart containerd inside urunc-test-control-plane
206- run : |
207- docker exec urunc-test-control-plane bash -c "
208- systemctl stop containerd
209- rm -f /var/lib/containerd/io.containerd.metadata.v1.bolt/meta.db
210- systemctl restart containerd
211- sleep 10
212- systemctl status containerd
213- "
214- - name : Verify urunc installation
215- run : |
216- docker exec urunc-test-control-plane bash -c '
217- ls -la /usr/local/bin/urunc*
218- ls -la /usr/local/bin/containerd-shim-urunc-v2*
219- containerd --version
220- '
221-
222- - name : Install kubectl
223- run : |
224- ARCH=$(uname -m)
225- if [ "$ARCH" = "x86_64" ]; then
226- KUBECTL_ARCH="amd64"
227- elif [ "$ARCH" = "aarch64" ]; then
228- KUBECTL_ARCH="arm64"
229- else
230- echo "Unsupported architecture: $ARCH"
231- exit 1
232- fi
233- curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/${KUBECTL_ARCH}/kubectl"
234- chmod +x kubectl
235- sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
236-
237- - name : Set up kubectl config
238- run : |
239- mkdir -p ~/.kube
240- kind get kubeconfig --name urunc-test > ~/.kube/config
241- chmod 600 ~/.kube/config
242- export KUBECONFIG=~/.kube/config
243- kubectl config use-context kind-urunc-test
244- kubectl wait --for=condition=Ready nodes --all --timeout=200s
245- kubectl cluster-info
246-
247- - name : Create RuntimeClass
248- run : |
249- cat <<EOF | kubectl apply -f -
250- kind: RuntimeClass
251- apiVersion: node.k8s.io/v1
252- metadata:
253- name: urunc
254- handler: urunc
255- EOF
256- - name : Deploy hello world unikernel (amd64)
257- if : matrix.arch == 'amd64'
258- run : |
259- cat <<EOF | kubectl apply -f -
260- apiVersion: v1
261- kind: Pod
262- metadata:
263- name: hello-spt-rumprun-block
264- labels:
265- run: hello-spt-rumprun-block
266- spec:
267- runtimeClassName: urunc
268- restartPolicy: Never
269- containers:
270- - name: hello-spt-rumprun-block
271- image: harbor.nbfc.io/nubificus/urunc/hello-spt-rumprun-block:latest
272- imagePullPolicy: Always
273- ports:
274- - containerPort: 80
275- protocol: TCP
276- resources:
277- requests:
278- cpu: 10m
279- EOF
280-
281- - name : Verify hello-spt-rumprun-block deployment
282- if : matrix.arch == 'amd64'
283- run : |
284- kubectl wait --for=condition=Succeeded pod/hello-spt-rumprun-block --timeout=180s || true
285- kubectl logs hello-spt-rumprun-block | tee /tmp/logs.txt
286- if ! grep "Hello world" /tmp/logs.txt; then
287- echo "=== LOGS ==="
288- cat /tmp/logs.txt
289- exit 1
290- fi
291- kubectl describe pod hello-spt-rumprun-block || true
292-
293-
294- - name : Deploy hello world unikernel (arm64)
295- if : matrix.arch == 'arm64'
296- run : |
297- cat <<EOF | kubectl apply -f -
298- apiVersion: v1
299- kind: Pod
300- metadata:
301- name: hello-spt-rumprun-block
302- labels:
303- run: hello-spt-rumprun-block
304- spec:
305- runtimeClassName: urunc
306- restartPolicy: Never
307- containers:
308- - name: hello-spt-rumprun-block
309- image: harbor.nbfc.io/nubificus/urunc/hello-spt-rumprun-block:latest
310- imagePullPolicy: Always
311- ports:
312- - containerPort: 80
313- protocol: TCP
314- resources:
315- requests:
316- cpu: 10m
317- EOF
318-
319- - name : Verify hello world deployment (arm64)
320- if : matrix.arch == 'arm64'
321- run : |
322- kubectl wait --for=condition=Succeeded pod/hello-spt-rumprun-block --timeout=180s || true
323- kubectl logs hello-spt-rumprun-block | tee /tmp/logs.txt
324- grep "Hello world" /tmp/logs.txt
325- kubectl describe pod hello-spt-rumprun-block || true
326-
327- - name : Debug pod failure
328- if : failure()
329- run : |
330- echo "=== Debugging failure ==="
331- echo "=== Describe Pod ==="
332- if [ "${{ matrix.arch }}" = "amd64" ]; then
333- echo "=== Debugging hello-spt-rumprun-block (amd64) ==="
334- kubectl describe pod hello-spt-rumprun-block || true
335- echo "=== Logs ==="
336- kubectl logs hello-spt-rumprun-block || true
337- else
338- echo "=== Debugging hello-spt-rumprun-block (arm64) ==="
339- kubectl describe pod hello-spt-rumprun-block || true
340- echo "=== Logs ==="
341- kubectl logs hello-spt-rumprun-block || true
342- fi
343-
0 commit comments