From a6733780ad22adf81dd3b71e5a27966c00987ac0 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Wed, 12 Aug 2026 00:52:14 +0200 Subject: [PATCH 1/2] fix linting Signed-off-by: Sebastiaan van Stijn --- pkg/adaptation/plugin_other.go | 2 +- pkg/runtime-tools/generate/helpers_other.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/adaptation/plugin_other.go b/pkg/adaptation/plugin_other.go index c092e289..2a28eb2f 100644 --- a/pkg/adaptation/plugin_other.go +++ b/pkg/adaptation/plugin_other.go @@ -25,6 +25,6 @@ import ( ) // getPeerPid returns the process id at the other end of the connection. -func getPeerPid(conn net.Conn) (int, error) { +func getPeerPid(net.Conn) (int, error) { return 0, fmt.Errorf("getPeerPid() unimplemented on %s", runtime.GOOS) } diff --git a/pkg/runtime-tools/generate/helpers_other.go b/pkg/runtime-tools/generate/helpers_other.go index ef82737e..229235ff 100644 --- a/pkg/runtime-tools/generate/helpers_other.go +++ b/pkg/runtime-tools/generate/helpers_other.go @@ -18,6 +18,6 @@ package generate -func ensurePropagation(path string, accepted ...string) error { +func ensurePropagation(string, ...string) error { return nil } From 6113b94b794d8801dd5358d43e3ec59af6031844 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Tue, 11 Aug 2026 16:58:28 +0200 Subject: [PATCH 2/2] Remove dependency on `github.com/opencontainers/runtime-tools` This copies the implementation that was added in [containerd@e01c004] as an internal package, so that we can remove the dependency on the (largely unmaintained) runtime-tools module, including its dependencies. [containerd@e01c004]: https://github.com/containerd/containerd/commit/e01c004cc6edaf1c671d91dc303ec1e302373d95 Co-authored-by: Tianon Gravi Signed-off-by: Sebastiaan van Stijn --- go.mod | 2 - go.sum | 18 - .../generate/generate_suite_test.go | 60 +-- .../internal/ocigen/spec_generator.go | 407 ++++++++++++++++++ 4 files changed, 428 insertions(+), 59 deletions(-) create mode 100644 pkg/runtime-tools/internal/ocigen/spec_generator.go diff --git a/go.mod b/go.mod index e03c8483..d1bf254a 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,6 @@ require ( github.com/onsi/ginkgo/v2 v2.19.1 github.com/onsi/gomega v1.34.0 github.com/opencontainers/runtime-spec v1.3.0 - github.com/opencontainers/runtime-tools v0.9.1-0.20251114084447-edf4cb3d2116 github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.8.4 github.com/tetratelabs/wazero v1.11.0 @@ -30,7 +29,6 @@ require ( github.com/golang/protobuf v1.5.3 // indirect github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 // indirect github.com/kr/pretty v0.3.1 // indirect - github.com/moby/sys/capability v0.4.0 // indirect github.com/planetscale/vtprotobuf v0.4.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect diff --git a/go.sum b/go.sum index df6b715c..4d8c40dd 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,3 @@ -github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= -github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/brianvoe/gofakeit/v7 v7.12.1 h1:df1tiI4SL1dR5Ix4D/r6a3a+nXBJ/OBGU5jEKRBmmqg= github.com/brianvoe/gofakeit/v7 v7.12.1/go.mod h1:QXuPeBw164PJCzCUZVmgpgHJ3Llj49jSLVkKPMtxtxA= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= @@ -22,10 +20,6 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= -github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/knqyf263/go-plugin v0.9.0 h1:CQs2+lOPIlkZVtcb835ZYDEoyyWJWLbSTWeCs0EwTwI= github.com/knqyf263/go-plugin v0.9.0/go.mod h1:2z5lCO1/pez6qGo8CvCxSlBFSEat4MEp1DrnA+f7w8Q= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -35,8 +29,6 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/moby/sys/capability v0.4.0 h1:4D4mI6KlNtWMCM1Z/K0i7RV1FkX+DBDHKVJpCndZoHk= -github.com/moby/sys/capability v0.4.0/go.mod h1:4g9IK291rVkms3LKCDOoYlnV8xKwoDTpIrNEE35Wq0I= github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg= github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4= github.com/onsi/ginkgo/v2 v2.19.1 h1:QXgq3Z8Crl5EL1WBAC98A5sEBHARrAJNzAmMxzLcRF0= @@ -45,10 +37,6 @@ github.com/onsi/gomega v1.34.0 h1:eSSPsPNp6ZpsG8X1OVmOTxig+CblTc4AxpPBykhe2Os= github.com/onsi/gomega v1.34.0/go.mod h1:MIKI8c+f+QLWk+hxbePD4i0LMJSExPaZOVfkoex4cAo= github.com/opencontainers/runtime-spec v1.3.0 h1:YZupQUdctfhpZy3TM39nN9Ika5CBWT5diQ8ibYCRkxg= github.com/opencontainers/runtime-spec v1.3.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-tools v0.9.1-0.20251114084447-edf4cb3d2116 h1:tAKu3NkKWZYpqBSOJKwTxT1wIGueiF7gcmcNgr5pNTY= -github.com/opencontainers/runtime-tools v0.9.1-0.20251114084447-edf4cb3d2116/go.mod h1:DKDEfzxvRkoQ6n9TGhxQgg2IM1lY4aM0eaQP4e3oElw= -github.com/opencontainers/selinux v1.9.1 h1:b4VPEF3O5JLZgdTDBmGepaaIbAo0GqoF6EBRq5f/g3Y= -github.com/opencontainers/selinux v1.9.1/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/planetscale/vtprotobuf v0.4.0 h1:NEI+g4woRaAZgeZ3sAvbtyvMBRjIv5kE7EWYQ8m4JwY= github.com/planetscale/vtprotobuf v0.4.0/go.mod h1:wm1N3qk9G/4+VM1WhpkLbvY/d8+0PbwYYpP5P5VhTks= @@ -68,12 +56,6 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/tetratelabs/wazero v1.11.0 h1:+gKemEuKCTevU4d7ZTzlsvgd1uaToIDtlQlmNbwqYhA= github.com/tetratelabs/wazero v1.11.0/go.mod h1:eV28rsN8Q+xwjogd7f4/Pp4xFxO7uOGbLcD/LzB1wiU= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c= diff --git a/pkg/runtime-tools/generate/generate_suite_test.go b/pkg/runtime-tools/generate/generate_suite_test.go index 20ea66b6..fbae7938 100644 --- a/pkg/runtime-tools/generate/generate_suite_test.go +++ b/pkg/runtime-tools/generate/generate_suite_test.go @@ -23,10 +23,10 @@ import ( . "github.com/onsi/gomega" rspec "github.com/opencontainers/runtime-spec/specs-go" - rgen "github.com/opencontainers/runtime-tools/generate" "github.com/containerd/nri/pkg/api" xgen "github.com/containerd/nri/pkg/runtime-tools/generate" + "github.com/containerd/nri/pkg/runtime-tools/internal/ocigen" ) func TestGenerate(t *testing.T) { @@ -42,8 +42,7 @@ var _ = Describe("Adjustment", func() { adjust *api.ContainerAdjustment ) - rg := &rgen.Generator{Config: spec} - xg := xgen.SpecGenerator(rg) + xg := xgen.SpecGenerator(ocigen.New(spec)) Expect(xg).ToNot(BeNil()) Expect(xg.Adjust(adjust)).To(Succeed()) @@ -60,8 +59,7 @@ var _ = Describe("Adjustment", func() { } ) - rg := &rgen.Generator{Config: spec} - xg := xgen.SpecGenerator(rg) + xg := xgen.SpecGenerator(ocigen.New(spec)) Expect(xg).ToNot(BeNil()) Expect(xg.Adjust(adjust)).To(Succeed()) @@ -82,8 +80,7 @@ var _ = Describe("Adjustment", func() { } ) - rg := &rgen.Generator{Config: spec} - xg := xgen.SpecGenerator(rg) + xg := xgen.SpecGenerator(ocigen.New(spec)) Expect(xg).ToNot(BeNil()) Expect(xg.Adjust(adjust)).To(Succeed()) @@ -104,8 +101,7 @@ var _ = Describe("Adjustment", func() { } ) - rg := &rgen.Generator{Config: spec} - xg := xgen.SpecGenerator(rg) + xg := xgen.SpecGenerator(ocigen.New(spec)) Expect(xg).ToNot(BeNil()) Expect(xg.Adjust(adjust)).To(Succeed()) @@ -128,8 +124,7 @@ var _ = Describe("Adjustment", func() { } ) - rg := &rgen.Generator{Config: spec} - xg := xgen.SpecGenerator(rg) + xg := xgen.SpecGenerator(ocigen.New(spec)) Expect(xg).ToNot(BeNil()) Expect(xg.Adjust(adjust)).To(Succeed()) @@ -151,8 +146,7 @@ var _ = Describe("Adjustment", func() { } ) - rg := &rgen.Generator{Config: spec} - xg := xgen.SpecGenerator(rg) + xg := xgen.SpecGenerator(ocigen.New(spec)) Expect(xg).ToNot(BeNil()) Expect(xg.Adjust(adjust)).To(Succeed()) @@ -171,8 +165,7 @@ var _ = Describe("Adjustment", func() { } ) - rg := &rgen.Generator{Config: spec} - xg := xgen.SpecGenerator(rg) + xg := xgen.SpecGenerator(ocigen.New(spec)) Expect(xg).ToNot(BeNil()) Expect(xg.Adjust(adjust)).To(Succeed()) @@ -191,8 +184,7 @@ var _ = Describe("Adjustment", func() { spec.Process.OOMScoreAdj = &oomScoreAdj expectedSpec.Process.OOMScoreAdj = &oomScoreAdj - rg := &rgen.Generator{Config: spec} - xg := xgen.SpecGenerator(rg) + xg := xgen.SpecGenerator(ocigen.New(spec)) Expect(xg).ToNot(BeNil()) Expect(xg.Adjust(adjust)).To(Succeed()) @@ -215,8 +207,7 @@ var _ = Describe("Adjustment", func() { } ) - rg := &rgen.Generator{Config: spec} - xg := xgen.SpecGenerator(rg) + xg := xgen.SpecGenerator(ocigen.New(spec)) Expect(xg).ToNot(BeNil()) Expect(xg.Adjust(adjust)).To(Succeed()) @@ -239,8 +230,7 @@ var _ = Describe("Adjustment", func() { } ) - rg := &rgen.Generator{Config: spec} - xg := xgen.SpecGenerator(rg) + xg := xgen.SpecGenerator(ocigen.New(spec)) Expect(xg).ToNot(BeNil()) Expect(xg.Adjust(adjust)).To(Succeed()) @@ -263,8 +253,7 @@ var _ = Describe("Adjustment", func() { } ) - rg := &rgen.Generator{Config: spec} - xg := xgen.SpecGenerator(rg) + xg := xgen.SpecGenerator(ocigen.New(spec)) Expect(xg).ToNot(BeNil()) Expect(xg.Adjust(adjust)).To(Succeed()) @@ -287,8 +276,7 @@ var _ = Describe("Adjustment", func() { } ) - rg := &rgen.Generator{Config: spec} - xg := xgen.SpecGenerator(rg) + xg := xgen.SpecGenerator(ocigen.New(spec)) Expect(xg).ToNot(BeNil()) Expect(xg.Adjust(adjust)).To(Succeed()) @@ -311,8 +299,7 @@ var _ = Describe("Adjustment", func() { } ) - rg := &rgen.Generator{Config: spec} - xg := xgen.SpecGenerator(rg) + xg := xgen.SpecGenerator(ocigen.New(spec)) Expect(xg).ToNot(BeNil()) Expect(xg.Adjust(adjust)).To(Succeed()) @@ -335,8 +322,7 @@ var _ = Describe("Adjustment", func() { } ) - rg := &rgen.Generator{Config: spec} - xg := xgen.SpecGenerator(rg) + xg := xgen.SpecGenerator(ocigen.New(spec)) Expect(xg).ToNot(BeNil()) Expect(xg.Adjust(adjust)).To(Succeed()) @@ -370,8 +356,7 @@ var _ = Describe("Adjustment", func() { } ) - rg := &rgen.Generator{Config: spec} - xg := xgen.SpecGenerator(rg) + xg := xgen.SpecGenerator(ocigen.New(spec)) Expect(xg).ToNot(BeNil()) Expect(xg.Adjust(adjust)).To(Succeed()) @@ -420,8 +405,7 @@ var _ = Describe("Adjustment", func() { } ) - rg := &rgen.Generator{Config: spec} - xg := xgen.SpecGenerator(rg) + xg := xgen.SpecGenerator(ocigen.New(spec)) Expect(xg).ToNot(BeNil()) Expect(xg.Adjust(adjust)).To(Succeed()) @@ -445,8 +429,8 @@ var _ = Describe("Adjustment", func() { spec.Linux.Sysctl = map[string]string{ "delete.me": "foobar", } - rg := &rgen.Generator{Config: spec} - xg := xgen.SpecGenerator(rg) + + xg := xgen.SpecGenerator(ocigen.New(spec)) Expect(xg).ToNot(BeNil()) Expect(xg.Adjust(adjust)).To(Succeed()) @@ -470,8 +454,7 @@ var _ = Describe("Adjustment", func() { }, } - rg := &rgen.Generator{Config: spec} - xg := xgen.SpecGenerator(rg) + xg := xgen.SpecGenerator(ocigen.New(spec)) Expect(xg).ToNot(BeNil()) Expect(xg.Adjust(adjust)).To(Succeed()) @@ -494,8 +477,7 @@ var _ = Describe("Adjustment", func() { }, } - rg := &rgen.Generator{Config: spec} - xg := xgen.SpecGenerator(rg) + xg := xgen.SpecGenerator(ocigen.New(spec)) Expect(xg).ToNot(BeNil()) Expect(xg.Adjust(adjust)).To(Succeed()) diff --git a/pkg/runtime-tools/internal/ocigen/spec_generator.go b/pkg/runtime-tools/internal/ocigen/spec_generator.go new file mode 100644 index 00000000..f3129045 --- /dev/null +++ b/pkg/runtime-tools/internal/ocigen/spec_generator.go @@ -0,0 +1,407 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package ocigen + +import ( + "fmt" + "strings" + + rspec "github.com/opencontainers/runtime-spec/specs-go" +) + +// Generator implements [generate.UnderlyingGenerator] directly on an *rspec.Spec, +// removing the need to import github.com/opencontainers/runtime-tools/generate. +type Generator struct { + spec *rspec.Spec +} + +// New creates a new Generator for modifying spec. +func New(spec *rspec.Spec) *Generator { + return &Generator{spec: spec} +} + +// Spec returns the generated OCI runtime specification. +func (g *Generator) Spec() *rspec.Spec { + return g.spec +} + +func (g *Generator) initConfig() { + if g.spec == nil { + g.spec = &rspec.Spec{} + } +} + +func (g *Generator) initProcess() { + g.initConfig() + if g.spec.Process == nil { + g.spec.Process = &rspec.Process{} + } +} + +func (g *Generator) initLinux() { + g.initConfig() + if g.spec.Linux == nil { + g.spec.Linux = &rspec.Linux{} + } +} + +func (g *Generator) initLinuxResources() { + g.initLinux() + if g.spec.Linux.Resources == nil { + g.spec.Linux.Resources = &rspec.LinuxResources{} + } +} + +func (g *Generator) initLinuxCPU() { + g.initLinuxResources() + if g.spec.Linux.Resources.CPU == nil { + g.spec.Linux.Resources.CPU = &rspec.LinuxCPU{} + } +} + +func (g *Generator) initLinuxMemory() { + g.initLinuxResources() + if g.spec.Linux.Resources.Memory == nil { + g.spec.Linux.Resources.Memory = &rspec.LinuxMemory{} + } +} + +func (g *Generator) initHooks() { + g.initConfig() + if g.spec.Hooks == nil { + g.spec.Hooks = &rspec.Hooks{} + } +} + +func (g *Generator) initAnnotations() { + g.initConfig() + if g.spec.Annotations == nil { + g.spec.Annotations = map[string]string{} + } +} + +func (g *Generator) initSysctl() { + g.initLinux() + if g.spec.Linux.Sysctl == nil { + g.spec.Linux.Sysctl = map[string]string{} + } +} + +// AddAnnotation adds or replaces an annotation in the specification. +func (g *Generator) AddAnnotation(key, value string) { + g.initAnnotations() + g.spec.Annotations[key] = value +} + +// RemoveAnnotation removes an annotation from the specification. +func (g *Generator) RemoveAnnotation(key string) { + if g.spec != nil && g.spec.Annotations != nil { + delete(g.spec.Annotations, key) + } +} + +// AddDevice adds a Linux device to the specification. +func (g *Generator) AddDevice(device rspec.LinuxDevice) { + g.initLinux() + for i, d := range g.spec.Linux.Devices { + if d.Path == device.Path { + g.spec.Linux.Devices[i] = device + return + } + } + g.spec.Linux.Devices = append(g.spec.Linux.Devices, device) +} + +// RemoveDevice removes the Linux device with the given path from the specification. +func (g *Generator) RemoveDevice(path string) { + if g.spec == nil || g.spec.Linux == nil { + return + } + for i, d := range g.spec.Linux.Devices { + if d.Path == path { + g.spec.Linux.Devices = append(g.spec.Linux.Devices[:i], g.spec.Linux.Devices[i+1:]...) + return + } + } +} + +// AddOrReplaceLinuxNamespace adds or replaces a Linux namespace in the specification. +func (g *Generator) AddOrReplaceLinuxNamespace(ns string, path string) error { + nsType, err := namespaceType(ns) + if err != nil { + return err + } + g.initLinux() + for i, n := range g.spec.Linux.Namespaces { + if n.Type == nsType { + g.spec.Linux.Namespaces[i].Path = path + return nil + } + } + g.spec.Linux.Namespaces = append(g.spec.Linux.Namespaces, rspec.LinuxNamespace{Type: nsType, Path: path}) + return nil +} + +// RemoveLinuxNamespace removes a Linux namespace from the specification. +func (g *Generator) RemoveLinuxNamespace(ns string) error { + nsType, err := namespaceType(ns) + if err != nil { + return err + } + if g.spec == nil || g.spec.Linux == nil { + return nil + } + for i, n := range g.spec.Linux.Namespaces { + if n.Type == nsType { + g.spec.Linux.Namespaces = append(g.spec.Linux.Namespaces[:i], g.spec.Linux.Namespaces[i+1:]...) + return nil + } + } + return nil +} + +func namespaceType(ns string) (rspec.LinuxNamespaceType, error) { + switch ns { + case "network": + return rspec.NetworkNamespace, nil + case "pid": + return rspec.PIDNamespace, nil + case "mount": + return rspec.MountNamespace, nil + case "ipc": + return rspec.IPCNamespace, nil + case "uts": + return rspec.UTSNamespace, nil + case "user": + return rspec.UserNamespace, nil + case "cgroup": + return rspec.CgroupNamespace, nil + case "time": + return rspec.TimeNamespace, nil + default: + return "", fmt.Errorf("unrecognized namespace %q", ns) + } +} + +// AddPreStartHook adds a pre-start hook to the specification. +func (g *Generator) AddPreStartHook(hook rspec.Hook) { + g.initHooks() + g.spec.Hooks.Prestart = append(g.spec.Hooks.Prestart, hook) //nolint:staticcheck +} + +// AddPostStartHook adds a post-start hook to the specification. +func (g *Generator) AddPostStartHook(hook rspec.Hook) { + g.initHooks() + g.spec.Hooks.Poststart = append(g.spec.Hooks.Poststart, hook) +} + +// AddPostStopHook adds a post-stop hook to the specification. +func (g *Generator) AddPostStopHook(hook rspec.Hook) { + g.initHooks() + g.spec.Hooks.Poststop = append(g.spec.Hooks.Poststop, hook) +} + +// AddProcessEnv adds or replaces an environment variable for the process. +func (g *Generator) AddProcessEnv(name, value string) { + if name == "" { + return + } + g.initProcess() + prefix := name + "=" + for i, e := range g.spec.Process.Env { + if strings.HasPrefix(e, prefix) { + g.spec.Process.Env[i] = prefix + value + return + } + } + g.spec.Process.Env = append(g.spec.Process.Env, prefix+value) +} + +// ClearProcessEnv removes all environment variables from the process. +func (g *Generator) ClearProcessEnv() { + if g.spec == nil || g.spec.Process == nil { + return + } + g.spec.Process.Env = []string{} +} + +// SetProcessArgs sets the process arguments. +func (g *Generator) SetProcessArgs(args []string) { + g.initProcess() + g.spec.Process.Args = args +} + +// SetProcessOOMScoreAdj sets the process OOM score adjustment. +func (g *Generator) SetProcessOOMScoreAdj(adj int) { + g.initProcess() + g.spec.Process.OOMScoreAdj = &adj +} + +// AddMount adds a mount to the specification. +func (g *Generator) AddMount(mnt rspec.Mount) { + g.initConfig() + g.spec.Mounts = append(g.spec.Mounts, mnt) +} + +// RemoveMount removes the mount with the given destination from the specification. +func (g *Generator) RemoveMount(dest string) { + if g.spec == nil { + return + } + for i, m := range g.spec.Mounts { + if m.Destination == dest { + g.spec.Mounts = append(g.spec.Mounts[:i], g.spec.Mounts[i+1:]...) + return + } + } +} + +// ClearMounts removes all mounts from the specification. +func (g *Generator) ClearMounts() { + if g.spec == nil { + return + } + g.spec.Mounts = []rspec.Mount{} +} + +// Mounts returns the mounts in the specification. +func (g *Generator) Mounts() []rspec.Mount { + if g.spec == nil { + return nil + } + return g.spec.Mounts +} + +// AddLinuxSysctl adds or replaces a Linux sysctl setting. +func (g *Generator) AddLinuxSysctl(key, value string) { + g.initSysctl() + g.spec.Linux.Sysctl[key] = value +} + +// RemoveLinuxSysctl removes a Linux sysctl setting. +func (g *Generator) RemoveLinuxSysctl(key string) { + if g.spec == nil || g.spec.Linux == nil || g.spec.Linux.Sysctl == nil { + return + } + delete(g.spec.Linux.Sysctl, key) +} + +// SetLinuxCgroupsPath sets the Linux cgroups path. +func (g *Generator) SetLinuxCgroupsPath(path string) { + g.initLinux() + g.spec.Linux.CgroupsPath = path +} + +// SetLinuxRootPropagation sets the Linux root filesystem propagation mode. +func (g *Generator) SetLinuxRootPropagation(rp string) error { + switch rp { + case "", "private", "rprivate", "slave", "rslave", "shared", "rshared", "unbindable", "runbindable": + default: + return fmt.Errorf("rootfs-propagation %q must be empty or one of (r)private|(r)slave|(r)shared|(r)unbindable", rp) + } + g.initLinux() + g.spec.Linux.RootfsPropagation = rp + return nil +} + +// AddLinuxResourcesDevice adds a Linux device cgroup rule. +func (g *Generator) AddLinuxResourcesDevice(allow bool, devType string, major, minor *int64, access string) { + g.initLinuxResources() + g.spec.Linux.Resources.Devices = append(g.spec.Linux.Resources.Devices, rspec.LinuxDeviceCgroup{ + Allow: allow, + Type: devType, + Major: major, + Minor: minor, + Access: access, + }) +} + +// AddLinuxResourcesHugepageLimit adds or replaces a Linux hugepage limit. +func (g *Generator) AddLinuxResourcesHugepageLimit(pageSize string, limit uint64) { + g.initLinuxResources() + for i, h := range g.spec.Linux.Resources.HugepageLimits { + if h.Pagesize == pageSize { + g.spec.Linux.Resources.HugepageLimits[i].Limit = limit + return + } + } + g.spec.Linux.Resources.HugepageLimits = append(g.spec.Linux.Resources.HugepageLimits, + rspec.LinuxHugepageLimit{Pagesize: pageSize, Limit: limit}) +} + +// AddLinuxResourcesUnified adds or replaces a unified cgroup resource setting. +func (g *Generator) AddLinuxResourcesUnified(key, val string) { + g.initLinuxResources() + if g.spec.Linux.Resources.Unified == nil { + g.spec.Linux.Resources.Unified = map[string]string{} + } + g.spec.Linux.Resources.Unified[key] = val +} + +// SetLinuxResourcesCPUShares sets the Linux CPU shares. +func (g *Generator) SetLinuxResourcesCPUShares(shares uint64) { + g.initLinuxCPU() + g.spec.Linux.Resources.CPU.Shares = &shares +} + +// SetLinuxResourcesCPUQuota sets the Linux CPU quota. +func (g *Generator) SetLinuxResourcesCPUQuota(quota int64) { + g.initLinuxCPU() + g.spec.Linux.Resources.CPU.Quota = "a +} + +// SetLinuxResourcesCPUPeriod sets the Linux CPU period. +func (g *Generator) SetLinuxResourcesCPUPeriod(period uint64) { + g.initLinuxCPU() + g.spec.Linux.Resources.CPU.Period = &period +} + +// SetLinuxResourcesCPURealtimeRuntime sets the Linux CPU realtime runtime. +func (g *Generator) SetLinuxResourcesCPURealtimeRuntime(time int64) { + g.initLinuxCPU() + g.spec.Linux.Resources.CPU.RealtimeRuntime = &time +} + +// SetLinuxResourcesCPURealtimePeriod sets the Linux CPU realtime period. +func (g *Generator) SetLinuxResourcesCPURealtimePeriod(period uint64) { + g.initLinuxCPU() + g.spec.Linux.Resources.CPU.RealtimePeriod = &period +} + +// SetLinuxResourcesCPUCpus sets the Linux CPUs available to the process. +func (g *Generator) SetLinuxResourcesCPUCpus(cpus string) { + g.initLinuxCPU() + g.spec.Linux.Resources.CPU.Cpus = cpus +} + +// SetLinuxResourcesCPUMems sets the Linux memory nodes available to the process. +func (g *Generator) SetLinuxResourcesCPUMems(mems string) { + g.initLinuxCPU() + g.spec.Linux.Resources.CPU.Mems = mems +} + +// SetLinuxResourcesMemoryLimit sets the Linux memory limit. +func (g *Generator) SetLinuxResourcesMemoryLimit(limit int64) { + g.initLinuxMemory() + g.spec.Linux.Resources.Memory.Limit = &limit +} + +// SetLinuxResourcesMemorySwap sets the Linux memory swap limit. +func (g *Generator) SetLinuxResourcesMemorySwap(swap int64) { + g.initLinuxMemory() + g.spec.Linux.Resources.Memory.Swap = &swap +}