Skip to content

Commit 5c2e238

Browse files
authored
chore(deps): upgrade containerd to 2.3.2 (#85)
Signed-off-by: Bartek Mucha <bartosz.mucha@arm.com>
1 parent 8829e76 commit 5c2e238

166 files changed

Lines changed: 6904 additions & 8500 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.

.github/workflows/ci.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,5 +67,11 @@ jobs:
6767
- name: Install podman
6868
run: sudo apt-get update -qq && sudo apt-get install -y podman
6969

70+
- name: Report container runtime versions
71+
run: |
72+
containerd --version || true
73+
docker --version || true
74+
podman --version || true
75+
7076
- name: Run e2e tests
7177
run: go test -v -timeout 5m ./e2e/...

cmd/containerd-shim-remoteproc-v1/main.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,22 @@ package main
22

33
import (
44
"context"
5+
"fmt"
6+
"os"
57

68
"github.com/arm/remoteproc-runtime/internal/shim"
79
containerdshim "github.com/containerd/containerd/v2/pkg/shim"
810
)
911

1012
func main() {
13+
ctx := context.Background()
1114
manager := shim.NewManager("io.containerd.remoteproc.v1")
12-
containerdshim.Run(context.Background(), manager)
15+
if handled, err := runStartCompat(ctx, manager); handled {
16+
if err != nil {
17+
fmt.Fprintf(os.Stderr, "%s: %s", manager.Name(), err)
18+
os.Exit(1)
19+
}
20+
return
21+
}
22+
containerdshim.RunShim(ctx, manager)
1323
}
Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"flag"
7+
"fmt"
8+
"io"
9+
"os"
10+
11+
bootapi "github.com/containerd/containerd/api/runtime/bootstrap/v1"
12+
"github.com/containerd/containerd/v2/pkg/namespaces"
13+
"github.com/containerd/containerd/v2/pkg/protobuf/proto"
14+
containerdshim "github.com/containerd/containerd/v2/pkg/shim"
15+
"github.com/containerd/log"
16+
)
17+
18+
type legacyBootstrapParams struct {
19+
// Version is the version of shim parameters (expected 2 for shim v2).
20+
Version int `json:"version"`
21+
// Address is the address containerd should use to connect to shim.
22+
Address string `json:"address"`
23+
// Protocol is either TTRPC or GRPC.
24+
Protocol string `json:"protocol"`
25+
}
26+
27+
type shimFlags struct {
28+
debug bool
29+
version bool
30+
info bool
31+
id string
32+
namespace string
33+
socket string
34+
debugSocket string
35+
bundle string
36+
address string
37+
publishBinary string
38+
action string
39+
}
40+
41+
// runStartCompat handles the shim "start" action for both containerd 2.2.x and
42+
// 2.3.x callers. containerd 2.2.x invokes shims using legacy CLI/env/stdin
43+
// fields and requires a JSON bootstrap response, while containerd 2.3.x sends a
44+
// bootstrap/v1 BootstrapParams protobuf on stdin and expects a BootstrapResult
45+
// protobuf on stdout.
46+
//
47+
// The legacy start response handling is adapted from containerd's 2.2 shim
48+
// runner:
49+
// - Source: https://github.com/containerd/containerd/blob/main/pkg/shim/shim.go
50+
// - Version: v2.2.5
51+
// - Commit: e53c7c1516c3b2bff98eb76f1f4117477e6f4e66
52+
// - License: Apache-2.0
53+
func runStartCompat(ctx context.Context, manager containerdshim.Shim) (bool, error) {
54+
flags, ok := parseShimFlags(os.Args[1:])
55+
if !ok || flags.version || flags.info || flags.action != "start" {
56+
return false, nil
57+
}
58+
if flags.namespace == "" {
59+
return true, fmt.Errorf("shim namespace cannot be empty")
60+
}
61+
62+
// Match containerd's shim runner limit: stdin should only contain bootstrap
63+
// params or legacy runtime options, so cap it to avoid unbounded reads.
64+
input, err := io.ReadAll(io.LimitReader(os.Stdin, 10<<20))
65+
if err != nil {
66+
return true, fmt.Errorf("failed to read stdin: %w", err)
67+
}
68+
69+
parsed := parseBootstrapParams(input, flags)
70+
params := parsed.params
71+
if parsed.modern {
72+
// Modern bootstrap params from containerd 2.3+ may include a socket dir.
73+
// Since this compat path handles "start" before RunShim, persist it here too.
74+
if dir := params.GetSocketDir(); dir != "" {
75+
if err := writeCompatSocketDir(dir); err != nil {
76+
return true, fmt.Errorf("failed to write socket-dir: %w", err)
77+
}
78+
}
79+
}
80+
81+
ctx = log.WithLogger(ctx, log.G(ctx).WithField("runtime", manager.Name()))
82+
ctx = namespaces.WithNamespace(ctx, flags.namespace)
83+
result, err := manager.Start(ctx, params)
84+
if err != nil {
85+
return true, err
86+
}
87+
88+
buildResponse := buildJSONBootstrapResponse
89+
if parsed.modern {
90+
buildResponse = buildProtobufBootstrapResponse
91+
}
92+
data, err := buildResponse(result)
93+
if err != nil {
94+
return true, err
95+
}
96+
_, err = os.Stdout.Write(data)
97+
return true, err
98+
}
99+
100+
func buildProtobufBootstrapResponse(result *bootapi.BootstrapResult) ([]byte, error) {
101+
data, err := proto.Marshal(result)
102+
if err != nil {
103+
return nil, fmt.Errorf("failed to marshal bootstrap result: %w", err)
104+
}
105+
return data, nil
106+
}
107+
108+
func buildJSONBootstrapResponse(result *bootapi.BootstrapResult) ([]byte, error) {
109+
legacy := legacyBootstrapParams{
110+
Version: int(result.GetVersion()),
111+
Address: result.GetAddress(),
112+
Protocol: result.GetProtocol(),
113+
}
114+
data, err := json.Marshal(&legacy)
115+
if err != nil {
116+
return nil, fmt.Errorf("failed to marshal bootstrap result to json: %w", err)
117+
}
118+
return data, nil
119+
}
120+
121+
func parseShimFlags(args []string) (shimFlags, bool) {
122+
var flags shimFlags
123+
fs := flag.NewFlagSet(os.Args[0], flag.ContinueOnError)
124+
fs.SetOutput(io.Discard)
125+
126+
fs.BoolVar(&flags.debug, "debug", false, "enable debug output in logs")
127+
fs.BoolVar(&flags.version, "v", false, "")
128+
fs.BoolVar(&flags.version, "version", false, "show the shim version and exit")
129+
fs.BoolVar(&flags.info, "info", false, "get the option protobuf from stdin, print the shim info protobuf to stdout, and exit")
130+
fs.StringVar(&flags.namespace, "namespace", "", "namespace that owns the shim")
131+
fs.StringVar(&flags.id, "id", "", "id of the task")
132+
fs.StringVar(&flags.socket, "socket", "", "socket path to serve")
133+
fs.StringVar(&flags.debugSocket, "debug-socket", "", "debug socket path to serve")
134+
fs.StringVar(&flags.bundle, "bundle", "", "path to the bundle if not workdir")
135+
fs.StringVar(&flags.address, "address", "", "grpc address back to main containerd")
136+
fs.StringVar(&flags.publishBinary, "publish-binary", "", "path to publish binary")
137+
138+
if err := fs.Parse(args); err != nil {
139+
return shimFlags{}, false
140+
}
141+
flags.action = fs.Arg(0)
142+
return flags, true
143+
}
144+
145+
type parsedBootstrapParams struct {
146+
params *bootapi.BootstrapParams
147+
modern bool
148+
}
149+
150+
func parseBootstrapParams(input []byte, flags shimFlags) parsedBootstrapParams {
151+
var params bootapi.BootstrapParams
152+
// Protobuf unmarshalling can succeed against legacy runtime options because
153+
// unknown fields are ignored. Validate required bootstrap fields before
154+
// treating stdin as a modern containerd 2.3+ BootstrapParams payload.
155+
if len(input) > 0 && proto.Unmarshal(input, &params) == nil && validModernBootstrapParams(&params) && crossCheckBootstrapParams(&params, flags) {
156+
return parsedBootstrapParams{params: &params, modern: true}
157+
}
158+
159+
params = bootapi.BootstrapParams{
160+
InstanceID: flags.id,
161+
Namespace: flags.namespace,
162+
LogLevel: bootapi.LogLevel_LOG_LEVEL_INFO,
163+
ContainerdGrpcAddress: firstNonEmpty(flags.address, os.Getenv("GRPC_ADDRESS")),
164+
ContainerdTtrpcAddress: os.Getenv("TTRPC_ADDRESS"),
165+
ContainerdBinary: flags.publishBinary,
166+
}
167+
if flags.debug {
168+
params.LogLevel = bootapi.LogLevel_LOG_LEVEL_DEBUG
169+
}
170+
return parsedBootstrapParams{params: &params}
171+
}
172+
173+
func validModernBootstrapParams(params *bootapi.BootstrapParams) bool {
174+
hasIdentity := params.GetInstanceID() != "" && params.GetNamespace() != ""
175+
hasContainerdAddress := params.GetContainerdGrpcAddress() != "" || params.GetContainerdTtrpcAddress() != ""
176+
177+
return hasIdentity && hasContainerdAddress
178+
}
179+
180+
func crossCheckBootstrapParams(params *bootapi.BootstrapParams, flags shimFlags) bool {
181+
// containerd 2.3+ sends modern BootstrapParams on stdin but still includes
182+
// legacy CLI fields for compatibility. When those fields are present, require
183+
// them to agree with the protobuf payload so containerd 2.2 legacy runtime
184+
// options are not mistaken for modern bootstrap params. If a future
185+
// containerd drops the legacy flags, these checks are skipped.
186+
if flags.id != "" && params.GetInstanceID() != flags.id {
187+
return false
188+
}
189+
if flags.namespace != "" && params.GetNamespace() != flags.namespace {
190+
return false
191+
}
192+
if flags.address != "" && params.GetContainerdGrpcAddress() != flags.address {
193+
return false
194+
}
195+
return true
196+
}
197+
198+
func firstNonEmpty(values ...string) string {
199+
for _, value := range values {
200+
if value != "" {
201+
return value
202+
}
203+
}
204+
return ""
205+
}
206+
207+
func writeCompatSocketDir(dir string) error {
208+
const socketDirLink = "s"
209+
if _, err := os.Lstat(socketDirLink); err == nil {
210+
if err := os.Remove(socketDirLink); err != nil {
211+
return fmt.Errorf("remove existing socket dir link: %w", err)
212+
}
213+
}
214+
return os.Symlink(dir, socketDirLink)
215+
}

docs/DEVELOPMENT.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This guide covers how to build, test, and contribute to this project.
44

55
## Prerequisites
66

7-
- Go 1.25 or higher
7+
- Go 1.26 or higher
88
- [LimaVM](https://lima-vm.io) (for e2e testing)
99
- [Remoteproc Simulator](https://github.com/arm/remoteproc-simulator) (for e2e testing and manual testing without hardware)
1010

@@ -57,7 +57,7 @@ go test -v -race ./internal/...
5757
If you're developing on a non-Linux operating system, you can run the tests using Docker:
5858

5959
```bash
60-
docker run --rm -v $(pwd):/app -w /app golang:1.25 go test -v ./internal/...
60+
docker run --rm -v $(pwd):/app -w /app golang:1.26 go test -v ./internal/...
6161
```
6262

6363
To improve feedback loop performance, you can use Docker volumes to cache Go modules and build artifacts:
@@ -73,7 +73,7 @@ docker run --rm \
7373
-w /app \
7474
-v go-mod-cache:/go/pkg/mod \
7575
-v go-build-cache:/root/.cache/go-build \
76-
golang:1.25 \
76+
golang:1.26 \
7777
go test -v ./internal/...
7878
```
7979

go.mod

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
module github.com/arm/remoteproc-runtime
22

3-
go 1.26.1
3+
go 1.26.3
44

55
require (
6-
github.com/containerd/containerd/api v1.10.0
7-
github.com/containerd/containerd/v2 v2.2.5
6+
github.com/containerd/containerd/api v1.11.1
7+
github.com/containerd/containerd/v2 v2.3.2
88
github.com/containerd/errdefs v1.0.0
99
github.com/containerd/log v0.1.0
1010
github.com/containerd/plugin v1.1.0
@@ -17,19 +17,18 @@ require (
1717
)
1818

1919
require (
20-
github.com/Microsoft/go-winio v0.6.2 // indirect
21-
github.com/Microsoft/hcsshim v0.14.1 // indirect
22-
github.com/containerd/cgroups/v3 v3.1.2 // indirect
20+
github.com/Microsoft/go-winio v0.6.3-0.20251027160822-ad3df93bed29 // indirect
21+
github.com/Microsoft/hcsshim v0.15.0-rc.1 // indirect
22+
github.com/containerd/cgroups/v3 v3.1.3 // indirect
2323
github.com/containerd/console v1.0.5 // indirect
24-
github.com/containerd/continuity v0.4.5 // indirect
24+
github.com/containerd/continuity v0.5.0 // indirect
2525
github.com/containerd/errdefs/pkg v0.3.0 // indirect
2626
github.com/containerd/fifo v1.1.0 // indirect
2727
github.com/containerd/go-runc v1.1.0 // indirect
2828
github.com/containerd/typeurl/v2 v2.2.3 // indirect
29-
github.com/davecgh/go-spew v1.1.1 // indirect
29+
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
3030
github.com/gogo/protobuf v1.3.2 // indirect
3131
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
32-
github.com/google/go-cmp v0.7.0 // indirect
3332
github.com/inconshreveable/mousetrap v1.1.0 // indirect
3433
github.com/kr/pretty v0.1.0 // indirect
3534
github.com/mdlayher/socket v0.5.1 // indirect
@@ -45,9 +44,9 @@ require (
4544
golang.org/x/net v0.55.0 // indirect
4645
golang.org/x/sync v0.21.0 // indirect
4746
golang.org/x/text v0.38.0 // indirect
48-
google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516 // indirect
47+
google.golang.org/genproto/googleapis/rpc v0.0.0-20260406210006-6f92a3bedf2d // indirect
4948
google.golang.org/grpc v1.80.0 // indirect
50-
google.golang.org/protobuf v1.36.11 // indirect
49+
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect
5150
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
5251
gopkg.in/yaml.v3 v3.0.1 // indirect
5352
)

0 commit comments

Comments
 (0)