Skip to content

Commit e0cc92b

Browse files
authored
Merge branch 'main' into dependabot/docker/distroless/static-c0f429e
2 parents 9abe64a + 8833668 commit e0cc92b

File tree

10 files changed

+227
-308
lines changed

10 files changed

+227
-308
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ jobs:
2020
helm_install_smoke_test:
2121
uses: ./.github/workflows/helm-chart-smoketest.yml
2222

23+
helm_node_scaling_test:
24+
uses: ./.github/workflows/helm-chart-node-scaling-test.yml
25+
2326
unit_tests:
2427
name: Test
2528
runs-on: ubuntu-latest
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
name: Helm Node Scaling Test
2+
3+
on:
4+
workflow_call:
5+
6+
env:
7+
SHIM_SPIN_VERSION: v0.19.0
8+
DOCKER_BUILD_SUMMARY: false
9+
10+
jobs:
11+
helm-node-scaling-test:
12+
runs-on: ubuntu-22.04
13+
steps:
14+
- uses: actions/checkout@v4
15+
16+
- name: Install helm
17+
uses: Azure/setup-helm@v4
18+
with:
19+
version: v3.15.4
20+
21+
- name: Set up QEMU
22+
uses: docker/setup-qemu-action@v3
23+
24+
- name: Set up Docker Buildx
25+
uses: docker/setup-buildx-action@v3
26+
27+
- name: Build RCM
28+
uses: docker/build-push-action@v6
29+
with:
30+
context: .
31+
file: ./Dockerfile
32+
platforms: linux/amd64
33+
cache-from: type=gha
34+
cache-to: type=gha,mode=max
35+
load: true
36+
tags: |
37+
runtime-class-manager:chart-test
38+
39+
- name: Build node installer
40+
uses: docker/build-push-action@v6
41+
with:
42+
context: .
43+
file: ./images/installer/Dockerfile
44+
platforms: linux/amd64
45+
cache-from: type=gha
46+
cache-to: type=gha,mode=max
47+
load: true
48+
tags: |
49+
node-installer:chart-test
50+
51+
- name: Build shim downloader
52+
uses: docker/build-push-action@v6
53+
with:
54+
context: ./images/downloader
55+
file: ./images/downloader/Dockerfile
56+
platforms: linux/amd64
57+
cache-from: type=gha
58+
cache-to: type=gha,mode=max
59+
load: true
60+
tags: |
61+
shim-downloader:chart-test
62+
63+
- name: create kind config
64+
run: |
65+
cat << EOF > kind-config.yaml
66+
kind: Cluster
67+
apiVersion: kind.x-k8s.io/v1alpha4
68+
nodes:
69+
- role: control-plane
70+
- role: worker
71+
labels:
72+
spin: true
73+
EOF
74+
75+
- name: fetch kindscaler script
76+
run: |
77+
curl -so kindscaler.sh https://raw.githubusercontent.com/lobuhi/kindscaler/refs/heads/main/kindscaler.sh
78+
chmod +x kindscaler.sh
79+
80+
- name: create kind cluster
81+
uses: helm/kind-action@v1
82+
with:
83+
cluster_name: kind
84+
config: kind-config.yaml
85+
86+
- name: import images into kind cluster
87+
run: |
88+
kind load docker-image runtime-class-manager:chart-test
89+
kind load docker-image node-installer:chart-test
90+
kind load docker-image shim-downloader:chart-test
91+
92+
- name: helm install runtime-class-manager
93+
run: |
94+
helm install rcm \
95+
--namespace rcm \
96+
--create-namespace \
97+
--debug \
98+
--set image.repository=runtime-class-manager \
99+
--set image.tag=chart-test \
100+
--set rcm.nodeInstallerImage.repository=node-installer \
101+
--set rcm.nodeInstallerImage.tag=chart-test \
102+
--set rcm.shimDownloaderImage.repository=shim-downloader \
103+
--set rcm.shimDownloaderImage.tag=chart-test \
104+
deploy/helm
105+
106+
- name: apply Spin shim
107+
run: |
108+
# Ensure shim binary is compatible with runner arch
109+
yq -i '.spec.fetchStrategy.anonHttp.location = "https://github.com/spinkube/containerd-shim-spin/releases/download/${{ env.SHIM_SPIN_VERSION }}/containerd-shim-spin-v2-linux-x86_64.tar.gz"' \
110+
config/samples/test_shim_spin.yaml
111+
kubectl apply -f config/samples/test_shim_spin.yaml
112+
113+
- name: verify shim is installed into one node
114+
run: |
115+
timeout 1m bash -c 'until [[ "$(kubectl get node -l spin=true -l spin-v2=provisioned -o name | wc -l)" == "1" ]]; do sleep 2; done'
116+
timeout 1m bash -c 'until [[ "$(kubectl get shim.runtime.spinkube.dev/spin-v2 -o json | jq -r '.status.nodesReady')" == "1" ]]; do sleep 2; done'
117+
118+
- name: scale kind worker nodes to 2
119+
run: ./kindscaler.sh kind -r worker -c 1
120+
121+
- name: re-import images into kind cluster, for new node
122+
run: |
123+
kind load docker-image runtime-class-manager:chart-test
124+
kind load docker-image node-installer:chart-test
125+
kind load docker-image shim-downloader:chart-test
126+
127+
- name: verify shim is installed into two nodes
128+
run: |
129+
timeout 1m bash -c 'until [[ "$(kubectl get node -l spin=true -l spin-v2=provisioned -o name | wc -l)" == "2" ]]; do sleep 2; done'
130+
timeout 1m bash -c 'until [[ "$(kubectl get shim.runtime.spinkube.dev/spin-v2 -o json | jq -r '.status.nodesReady')" == "2" ]]; do sleep 2; done'
131+
132+
- name: delete Spin Shim
133+
run: kubectl delete -f config/samples/test_shim_spin.yaml
134+
135+
- name: verify shim is uninstalled from both nodes
136+
run: |
137+
timeout 1m bash -c 'until [[ "$(kubectl get node -l spin=true -l spin-v2=provisioned -o name | wc -l)" == "0" ]]; do sleep 2; done'
138+
timeout 1m bash -c 'until ! kubectl get shims.runtime.spinkube.dev/spin-v2; do sleep 2; done'
139+
140+
- name: debug
141+
if: failure()
142+
run: |
143+
kubectl get pods -A
144+
kubectl describe shim spin-v2
145+
kubectl describe runtimeclass wasmtime-spin-v2
146+
kubectl describe -n rcm pod -l job-name=kind-worker-spin-v2-install || true
147+
kubectl logs -n rcm -l app.kubernetes.io/name=runtime-class-manager || true
148+
kubectl describe -n rcm pod -l app.kubernetes.io/name=runtime-class-manager || true
149+
kubectl describe nodes

.github/workflows/helm-chart-smoketest.yml

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,9 @@ on:
44
workflow_call:
55

66
env:
7-
# TODO: bump to a more recent K8S_VERSION once rcm supports containerd 2.0+
8-
# see https://github.com/spinframework/runtime-class-manager/issues/371
9-
# For k3d in particular, containerd 2.0 is used starting with k3s image tag v1.32.2-k3s1
10-
K8S_VERSION: v1.32.1
7+
K8S_VERSION: v1.32.3
118
MICROK8S_CHANNEL: 1.32/stable
12-
SHIM_SPIN_VERSION: v0.18.0
9+
SHIM_SPIN_VERSION: v0.19.0
1310
DOCKER_BUILD_SUMMARY: false
1411

1512
jobs:

.github/workflows/scorecard.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,6 @@ jobs:
6868
# Upload the results to GitHub's code scanning dashboard (optional).
6969
# Commenting out will disable upload of results to your repo's Code Scanning dashboard
7070
- name: "Upload to code-scanning"
71-
uses: github/codeql-action/upload-sarif@6bb031afdd8eb862ea3fc1848194185e076637e5 # v3.28.11
71+
uses: github/codeql-action/upload-sarif@45775bd8235c68ba998cffa5171334d58593da47 # v3.28.15
7272
with:
7373
sarif_file: results.sarif

config/samples/test_shim_spin.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ spec:
1515
fetchStrategy:
1616
type: anonymousHttp
1717
anonHttp:
18-
location: "https://github.com/spinframework/containerd-shim-spin/releases/download/v0.15.1/containerd-shim-spin-v2-linux-aarch64.tar.gz"
18+
location: "https://github.com/spinframework/containerd-shim-spin/releases/download/v0.19.0/containerd-shim-spin-v2-linux-aarch64.tar.gz"
1919

2020
runtimeClass:
2121
# Note: this name is used by the Spin Operator project as its default:

internal/containerd/configure.go

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ func (c *Config) AddRuntime(shimPath string) error {
4949
runtimeName := shim.RuntimeName(path.Base(shimPath))
5050
l := slog.With("runtime", runtimeName)
5151

52-
cfg := generateConfig(shimPath, runtimeName)
53-
5452
// Containerd config file needs to exist, otherwise return the error
5553
data, err := afero.ReadFile(c.hostFs, c.configPath)
5654
if err != nil {
@@ -63,6 +61,8 @@ func (c *Config) AddRuntime(shimPath string) error {
6361
return nil
6462
}
6563

64+
cfg := generateConfig(shimPath, runtimeName, data)
65+
6666
// Open file in append mode
6767
file, err := c.hostFs.OpenFile(c.configPath, os.O_APPEND|os.O_WRONLY, 0o644) //nolint:mnd // file permissions
6868
if err != nil {
@@ -83,8 +83,6 @@ func (c *Config) RemoveRuntime(shimPath string) (changed bool, err error) {
8383
runtimeName := shim.RuntimeName(path.Base(shimPath))
8484
l := slog.With("runtime", runtimeName)
8585

86-
cfg := generateConfig(shimPath, runtimeName)
87-
8886
// Containerd config file needs to exist, otherwise return the error
8987
data, err := afero.ReadFile(c.hostFs, c.configPath)
9088
if err != nil {
@@ -97,6 +95,8 @@ func (c *Config) RemoveRuntime(shimPath string) (changed bool, err error) {
9795
return false, nil
9896
}
9997

98+
cfg := generateConfig(shimPath, runtimeName, data)
99+
100100
// Convert the file data to a string and replace the target string with an empty string.
101101
modifiedData := strings.ReplaceAll(string(data), cfg, "")
102102

@@ -113,10 +113,17 @@ func (c *Config) RestartRuntime() error {
113113
return c.restarter.Restart()
114114
}
115115

116-
func generateConfig(shimPath string, runtimeName string) string {
116+
func generateConfig(shimPath string, runtimeName string, configData []byte) string {
117+
// Config domain for containerd 1.0 (config version 2)
118+
domain := "io.containerd.grpc.v1.cri"
119+
if strings.Contains(string(configData), "version = 3") {
120+
// Config domain for containerd 2.0 (config version 3)
121+
domain = "io.containerd.cri.v1.runtime"
122+
}
123+
117124
return fmt.Sprintf(`
118125
# RCM runtime config for %s
119-
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.%s]
126+
[plugins."%s".containerd.runtimes.%s]
120127
runtime_type = "%s"
121-
`, runtimeName, runtimeName, shimPath)
128+
`, runtimeName, domain, runtimeName, shimPath)
122129
}

internal/containerd/configure_test.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,3 +201,58 @@ func TestConfig_RemoveRuntime(t *testing.T) {
201201
})
202202
}
203203
}
204+
205+
func TestGenerateConfig_ContainerdVersions(t *testing.T) {
206+
type fields struct {
207+
hostFs afero.Fs
208+
configPath string
209+
}
210+
type args struct {
211+
shimPath string
212+
}
213+
tests := []struct {
214+
name string
215+
fields fields
216+
args args
217+
wantErr bool
218+
wantFileContent string
219+
}{
220+
{"containerd 1.x", fields{
221+
hostFs: tests.FixtureFs("../../testdata/node-installer/containerd/1.x"),
222+
configPath: "/etc/containerd/config.toml",
223+
}, args{"/opt/rcm/bin/containerd-shim-spin-v1"}, false, `version = 2
224+
# RCM runtime config for spin-v1
225+
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.spin-v1]
226+
runtime_type = "/opt/rcm/bin/containerd-shim-spin-v1"
227+
`},
228+
{"containerd 2.x", fields{
229+
hostFs: tests.FixtureFs("../../testdata/node-installer/containerd/2.x"),
230+
configPath: "/etc/containerd/config.toml",
231+
}, args{"/opt/rcm/bin/containerd-shim-spin-v1"}, false, `version = 3
232+
# RCM runtime config for spin-v1
233+
[plugins."io.containerd.cri.v1.runtime".containerd.runtimes.spin-v1]
234+
runtime_type = "/opt/rcm/bin/containerd-shim-spin-v1"
235+
`},
236+
}
237+
for _, tt := range tests {
238+
t.Run(tt.name, func(t *testing.T) {
239+
c := &Config{
240+
hostFs: tt.fields.hostFs,
241+
configPath: tt.fields.configPath,
242+
}
243+
err := c.AddRuntime(tt.args.shimPath)
244+
245+
if tt.wantErr {
246+
require.Error(t, err)
247+
return
248+
}
249+
250+
require.NoError(t, err)
251+
252+
gotContent, err := afero.ReadFile(c.hostFs, c.configPath)
253+
require.NoError(t, err)
254+
255+
assert.Equal(t, tt.wantFileContent, string(gotContent))
256+
})
257+
}
258+
}

0 commit comments

Comments
 (0)