mirror of
https://github.com/hanzoai/visor.git
synced 2026-09-24 17:04:14 +00:00
Integrate runsc features command with runsc shim
Refactored the `runsc features` logic into specutils Support direct in-memory lookup in the shim and avoid the fork/exec roundtrip Test result: http://sponge2/4543eb2c-c239-4459-8700-bf89ef081088 PiperOrigin-RevId: 919150093
This commit is contained in:
+13
-1
@@ -1,4 +1,4 @@
|
||||
load("//tools:defs.bzl", "go_library")
|
||||
load("//tools:defs.bzl", "go_library", "go_test")
|
||||
|
||||
package(
|
||||
default_applicable_licenses = ["//:license"],
|
||||
@@ -23,6 +23,7 @@ go_library(
|
||||
"//pkg/shim/v1/runsc:hibernate_go_proto",
|
||||
"//pkg/shim/v1/runsccmd",
|
||||
"//pkg/sync",
|
||||
"//runsc/specutils",
|
||||
"@com_github_burntsushi_toml//:go_default_library",
|
||||
"@com_github_containerd_containerd_api//runtime/task/v2:go_default_library",
|
||||
"@com_github_containerd_containerd_api//types:go_default_library",
|
||||
@@ -35,6 +36,17 @@ go_library(
|
||||
"@com_github_containerd_errdefs_pkg//errgrpc:go_default_library",
|
||||
"@com_github_containerd_log//:go_default_library",
|
||||
"@com_github_containerd_ttrpc//:go_default_library",
|
||||
"@com_github_containerd_typeurl_v2//:go_default_library",
|
||||
"@org_golang_x_sys//unix:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "v1_test",
|
||||
srcs = ["manager_test.go"],
|
||||
library = ":v1",
|
||||
deps = [
|
||||
"@com_github_containerd_typeurl_v2//:go_default_library",
|
||||
"@com_github_opencontainers_runtime_spec//specs-go/features:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
+17
-5
@@ -18,12 +18,11 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"time"
|
||||
|
||||
"io"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
types "github.com/containerd/containerd/api/types"
|
||||
"github.com/containerd/containerd/v2/core/mount"
|
||||
@@ -31,11 +30,13 @@ import (
|
||||
"github.com/containerd/containerd/v2/pkg/shim"
|
||||
"github.com/containerd/containerd/v2/pkg/sys"
|
||||
"github.com/containerd/log"
|
||||
typeurl "github.com/containerd/typeurl/v2"
|
||||
"golang.org/x/sys/unix"
|
||||
"gvisor.dev/gvisor/pkg/cleanup"
|
||||
"gvisor.dev/gvisor/pkg/shim/v1/proc"
|
||||
"gvisor.dev/gvisor/pkg/shim/v1/runsc"
|
||||
"gvisor.dev/gvisor/pkg/shim/v1/runsccmd"
|
||||
"gvisor.dev/gvisor/runsc/specutils"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -249,12 +250,23 @@ func getEnableGrouping() bool {
|
||||
}
|
||||
|
||||
func (m *manager) Info(ctx context.Context, optionsR io.Reader) (*types.RuntimeInfo, error) {
|
||||
return &types.RuntimeInfo{
|
||||
Name: "io.containerd.runsc.v1",
|
||||
info := &types.RuntimeInfo{
|
||||
Name: m.name,
|
||||
Version: &types.RuntimeVersion{
|
||||
Version: "v1.0.0",
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
feat := specutils.Features()
|
||||
if feat != nil {
|
||||
var err error
|
||||
info.Features, err = typeurl.MarshalAnyToProto(feat)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to marshal %T: %w", feat, err)
|
||||
}
|
||||
}
|
||||
|
||||
return info, nil
|
||||
}
|
||||
|
||||
func writeAddress(path, address string) error {
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
// Copyright 2026 The gVisor 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
|
||||
//
|
||||
// https://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 v1
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
|
||||
typeurl "github.com/containerd/typeurl/v2"
|
||||
"github.com/opencontainers/runtime-spec/specs-go/features"
|
||||
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestManagerInfo verifies that the Info() call returns the expected information
|
||||
// about the runtime.
|
||||
func TestManagerInfo(t *testing.T) {
|
||||
m := NewShimManager("io.containerd.runsc.v1")
|
||||
info, err := m.Info(context.Background(), bytes.NewReader(nil))
|
||||
if err != nil {
|
||||
t.Fatalf("Standalone ShimManager::Info call returned unexpected error: %v", err)
|
||||
}
|
||||
if info == nil {
|
||||
t.Fatalf("ShimManager::Info got nil, want non-nil RuntimeInfo")
|
||||
}
|
||||
if info.Features == nil {
|
||||
t.Fatalf("ShimManager::Info got nil, want populated Features struct from specutils")
|
||||
}
|
||||
|
||||
decoded, err := typeurl.UnmarshalAny(info.Features)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to deserialize info.Features Any proto: %v", err)
|
||||
}
|
||||
|
||||
_, ok := decoded.(*features.Features)
|
||||
if !ok {
|
||||
t.Fatalf("Decoded features is type %T, want *features.Features", decoded)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,7 +18,7 @@ go_library(
|
||||
"runtimeoptions.go",
|
||||
"runtimeoptions_cri.go",
|
||||
],
|
||||
visibility = ["//pkg/shim/v1/runsc:__pkg__"],
|
||||
visibility = ["//pkg/shim/v1:__subpackages__"],
|
||||
deps = ["@com_github_gogo_protobuf//proto:go_default_library"],
|
||||
)
|
||||
|
||||
|
||||
+1
-88
@@ -18,15 +18,12 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"sort"
|
||||
|
||||
"github.com/google/subcommands"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/opencontainers/runtime-spec/specs-go/features"
|
||||
"gvisor.dev/gvisor/runsc/config"
|
||||
"gvisor.dev/gvisor/runsc/flag"
|
||||
"gvisor.dev/gvisor/runsc/specutils"
|
||||
"gvisor.dev/gvisor/runsc/specutils/seccomp"
|
||||
)
|
||||
|
||||
// Features implements subcommands.Command for the "features" command.
|
||||
@@ -58,91 +55,7 @@ func (*Features) FetchSpec(_ *config.Config, _ *flag.FlagSet) (string, *specs.Sp
|
||||
|
||||
// Execute implements subcommands.Command.Execute.
|
||||
func (*Features) Execute(_ context.Context, _ *flag.FlagSet, args ...any) subcommands.ExitStatus {
|
||||
|
||||
feat := features.Features{
|
||||
OCIVersionMin: "1.0.0",
|
||||
OCIVersionMax: specs.Version,
|
||||
Hooks: []string{
|
||||
"prestart",
|
||||
"createRuntime",
|
||||
"createContainer",
|
||||
"startContainer",
|
||||
"poststart",
|
||||
"poststop",
|
||||
},
|
||||
MountOptions: specutils.KnownMountOptions(),
|
||||
Linux: &features.Linux{
|
||||
Namespaces: specutils.KnownNamespaces(),
|
||||
Capabilities: specutils.AllCapabilities().Bounding,
|
||||
Cgroup: &features.Cgroup{
|
||||
V1: boolPtr(true),
|
||||
V2: boolPtr(false),
|
||||
Systemd: boolPtr(false),
|
||||
SystemdUser: boolPtr(false),
|
||||
Rdma: boolPtr(false),
|
||||
},
|
||||
Seccomp: &features.Seccomp{
|
||||
Enabled: boolPtr(true),
|
||||
Actions: seccomp.KnownActions(),
|
||||
Operators: seccomp.KnownOperators(),
|
||||
Archs: seccomp.KnownArchs(),
|
||||
KnownFlags: seccomp.KnownFlags(),
|
||||
SupportedFlags: seccomp.SupportedFlags(),
|
||||
},
|
||||
Apparmor: &features.Apparmor{
|
||||
Enabled: boolPtr(false),
|
||||
},
|
||||
Selinux: &features.Selinux{
|
||||
Enabled: boolPtr(false),
|
||||
},
|
||||
IntelRdt: &features.IntelRdt{
|
||||
Enabled: boolPtr(false),
|
||||
},
|
||||
MountExtensions: &features.MountExtensions{
|
||||
IDMap: &features.IDMap{
|
||||
Enabled: boolPtr(false),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
tmpFs := flag.NewFlagSet("tmp", flag.ContinueOnError)
|
||||
config.RegisterFlags(tmpFs)
|
||||
annotations := make(map[string]string)
|
||||
tmpFs.VisitAll(func(f *flag.Flag) {
|
||||
key := "dev.gvisor.flag." + f.Name
|
||||
annotations[key] = f.DefValue
|
||||
})
|
||||
|
||||
// LINT.IfChange
|
||||
annotations["dev.gvisor.container-name-remap."] = ""
|
||||
annotations[specutils.AnnotationRootfsUpperTar] = ""
|
||||
annotations["dev.gvisor.internal.seccomp."] = ""
|
||||
annotations["dev.gvisor.internal.seccomp.cont"] = "RuntimeDefault"
|
||||
annotations[specutils.AnnotationTPU] = ""
|
||||
annotations[specutils.AnnotationCPUFeatures] = ""
|
||||
// LINT.ThenChange(../specutils/specutils.go)
|
||||
feat.Annotations = annotations
|
||||
|
||||
var unsafeAnnotations []string
|
||||
tmpFs.VisitAll(func(f *flag.Flag) {
|
||||
if !config.IsFlagSafeToOverride(f.Name) {
|
||||
unsafeAnnotations = append(unsafeAnnotations, "dev.gvisor.flag."+f.Name)
|
||||
}
|
||||
})
|
||||
|
||||
// LINT.IfChange
|
||||
unsafeAnnotations = append(unsafeAnnotations,
|
||||
"dev.gvisor.container-name-remap.",
|
||||
specutils.AnnotationRootfsUpperTar,
|
||||
"dev.gvisor.internal.seccomp.",
|
||||
specutils.AnnotationTPU,
|
||||
specutils.AnnotationCPUFeatures,
|
||||
)
|
||||
// LINT.ThenChange(../specutils/specutils.go)
|
||||
|
||||
sort.Strings(unsafeAnnotations)
|
||||
feat.PotentiallyUnsafeConfigAnnotations = unsafeAnnotations
|
||||
feat := specutils.Features()
|
||||
|
||||
enc := json.NewEncoder(os.Stdout)
|
||||
enc.SetIndent("", " ")
|
||||
|
||||
@@ -26,10 +26,12 @@ go_library(
|
||||
"//pkg/sentry/kernel/auth",
|
||||
"//runsc/config",
|
||||
"//runsc/flag",
|
||||
"//runsc/specutils/seccomp",
|
||||
"@com_github_cenkalti_backoff//:go_default_library",
|
||||
"@com_github_moby_sys_capability//:go_default_library",
|
||||
"@com_github_mohae_deepcopy//:go_default_library",
|
||||
"@com_github_opencontainers_runtime_spec//specs-go:go_default_library",
|
||||
"@com_github_opencontainers_runtime_spec//specs-go/features:go_default_library",
|
||||
"@org_golang_x_sys//unix:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -24,22 +24,26 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/cenkalti/backoff"
|
||||
"github.com/mohae/deepcopy"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/opencontainers/runtime-spec/specs-go/features"
|
||||
"golang.org/x/sys/unix"
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/log"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
|
||||
"gvisor.dev/gvisor/runsc/config"
|
||||
"gvisor.dev/gvisor/runsc/flag"
|
||||
"gvisor.dev/gvisor/runsc/specutils/seccomp"
|
||||
)
|
||||
|
||||
// LINT.IfChange
|
||||
// LINT.IfChange(features_annotations)
|
||||
const (
|
||||
// annotationFlagPrefix allows annotations to change the value of flags.
|
||||
//
|
||||
@@ -85,7 +89,7 @@ const (
|
||||
AnnotationCPUFeatures = "dev.gvisor.internal.cpufeatures"
|
||||
)
|
||||
|
||||
// LINT.ThenChange(../cmd/features.go)
|
||||
// LINT.ThenChange(:Features)
|
||||
|
||||
// ExePath must point to runsc binary, which is normally the same binary. It's
|
||||
// changed in tests that aren't linked in the same binary.
|
||||
@@ -94,6 +98,11 @@ var ExePath = "/proc/self/exe"
|
||||
// Version is the supported spec version.
|
||||
var Version = specs.Version
|
||||
|
||||
var (
|
||||
globalFeatures *features.Features
|
||||
featuresOnce sync.Once
|
||||
)
|
||||
|
||||
// LogSpecDebug writes the spec in a human-friendly format to the debug log.
|
||||
func LogSpecDebug(orig *specs.Spec, logSeccomp bool) {
|
||||
if log.IsLogging(log.Debug) {
|
||||
@@ -906,3 +915,101 @@ func AnnotationToBool(spec *specs.Spec, annotation string) bool {
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func boolPtr(b bool) *bool {
|
||||
return &b
|
||||
}
|
||||
|
||||
// Features returns the features supported by the runtime.
|
||||
func Features() *features.Features {
|
||||
featuresOnce.Do(func() {
|
||||
feat := features.Features{
|
||||
OCIVersionMin: "1.0.0",
|
||||
OCIVersionMax: specs.Version,
|
||||
Hooks: []string{
|
||||
"prestart",
|
||||
"createRuntime",
|
||||
"createContainer",
|
||||
"startContainer",
|
||||
"poststart",
|
||||
"poststop",
|
||||
},
|
||||
MountOptions: KnownMountOptions(),
|
||||
Linux: &features.Linux{
|
||||
Namespaces: KnownNamespaces(),
|
||||
Capabilities: AllCapabilities().Bounding,
|
||||
Cgroup: &features.Cgroup{
|
||||
V1: boolPtr(true),
|
||||
V2: boolPtr(false),
|
||||
Systemd: boolPtr(false),
|
||||
SystemdUser: boolPtr(false),
|
||||
Rdma: boolPtr(false),
|
||||
},
|
||||
Seccomp: &features.Seccomp{
|
||||
Enabled: boolPtr(true),
|
||||
Actions: seccomp.KnownActions(),
|
||||
Operators: seccomp.KnownOperators(),
|
||||
Archs: seccomp.KnownArchs(),
|
||||
KnownFlags: seccomp.KnownFlags(),
|
||||
SupportedFlags: seccomp.SupportedFlags(),
|
||||
},
|
||||
Apparmor: &features.Apparmor{
|
||||
Enabled: boolPtr(false),
|
||||
},
|
||||
Selinux: &features.Selinux{
|
||||
Enabled: boolPtr(false),
|
||||
},
|
||||
IntelRdt: &features.IntelRdt{
|
||||
Enabled: boolPtr(false),
|
||||
},
|
||||
MountExtensions: &features.MountExtensions{
|
||||
IDMap: &features.IDMap{
|
||||
Enabled: boolPtr(false),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
tmpFs := flag.NewFlagSet("tmp", flag.ContinueOnError)
|
||||
config.RegisterFlags(tmpFs)
|
||||
annotations := make(map[string]string)
|
||||
tmpFs.VisitAll(func(f *flag.Flag) {
|
||||
key := "dev.gvisor.flag." + f.Name
|
||||
annotations[key] = f.DefValue
|
||||
})
|
||||
|
||||
// LINT.IfChange
|
||||
annotations["dev.gvisor.container-name-remap."] = ""
|
||||
annotations[AnnotationRootfsUpperTar] = ""
|
||||
annotations["dev.gvisor.internal.seccomp."] = ""
|
||||
annotations["dev.gvisor.internal.seccomp.cont"] = "RuntimeDefault"
|
||||
annotations[AnnotationTPU] = ""
|
||||
annotations[AnnotationCPUFeatures] = ""
|
||||
// LINT.ThenChange(:features_annotations)
|
||||
feat.Annotations = annotations
|
||||
|
||||
var unsafeAnnotations []string
|
||||
tmpFs.VisitAll(func(f *flag.Flag) {
|
||||
if !config.IsFlagSafeToOverride(f.Name) {
|
||||
unsafeAnnotations = append(unsafeAnnotations, "dev.gvisor.flag."+f.Name)
|
||||
}
|
||||
})
|
||||
|
||||
// LINT.IfChange
|
||||
unsafeAnnotations = append(unsafeAnnotations,
|
||||
"dev.gvisor.container-name-remap.",
|
||||
AnnotationRootfsUpperTar,
|
||||
"dev.gvisor.internal.seccomp.",
|
||||
AnnotationTPU,
|
||||
AnnotationCPUFeatures,
|
||||
)
|
||||
// LINT.ThenChange(:features_annotations)
|
||||
|
||||
sort.Strings(unsafeAnnotations)
|
||||
feat.PotentiallyUnsafeConfigAnnotations = unsafeAnnotations
|
||||
|
||||
globalFeatures = &feat
|
||||
})
|
||||
|
||||
return globalFeatures
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user