Path: blob/main/components/ws-daemon/pkg/libcontainer/specconv/example.go
2501 views
// Copyright The libcontainer authors12// Licensed under the Apache License, Version 2.0 (the "License");3// you may not use this file except in compliance with the License.4// You may obtain a copy of the License at56// http://www.apache.org/licenses/LICENSE-2.078// Unless required by applicable law or agreed to in writing, software9// distributed under the License is distributed on an "AS IS" BASIS,10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11// See the License for the specific language governing permissions and12// limitations under the License.1314// Copied from: https://github.com/opencontainers/runc/blob/364ec0f1b4fa188ad96049c590ecb42fa70ea165/libcontainer/specconv/example.go#L115package specconv1617import (18"os"19"path/filepath"20"strings"2122"github.com/opencontainers/runc/libcontainer/cgroups"23"github.com/opencontainers/runtime-spec/specs-go"24)2526// Example returns an example spec file, with many options set so a user can27// see what a standard spec file looks like.28func Example() *specs.Spec {29spec := &specs.Spec{30Version: specs.Version,31Root: &specs.Root{32Path: "rootfs",33Readonly: true,34},35Process: &specs.Process{36Terminal: true,37User: specs.User{},38Args: []string{39"sh",40},41Env: []string{42"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",43"TERM=xterm",44},45Cwd: "/",46NoNewPrivileges: true,47Capabilities: &specs.LinuxCapabilities{48Bounding: []string{49"CAP_AUDIT_WRITE",50"CAP_KILL",51"CAP_NET_BIND_SERVICE",52},53Permitted: []string{54"CAP_AUDIT_WRITE",55"CAP_KILL",56"CAP_NET_BIND_SERVICE",57},58Ambient: []string{59"CAP_AUDIT_WRITE",60"CAP_KILL",61"CAP_NET_BIND_SERVICE",62},63Effective: []string{64"CAP_AUDIT_WRITE",65"CAP_KILL",66"CAP_NET_BIND_SERVICE",67},68},69Rlimits: []specs.POSIXRlimit{70{71Type: "RLIMIT_NOFILE",72Hard: uint64(1024),73Soft: uint64(1024),74},75},76},77Hostname: "runc",78Mounts: []specs.Mount{79{80Destination: "/proc",81Type: "proc",82Source: "proc",83Options: nil,84},85{86Destination: "/dev",87Type: "tmpfs",88Source: "tmpfs",89Options: []string{"nosuid", "strictatime", "mode=755", "size=65536k"},90},91{92Destination: "/dev/pts",93Type: "devpts",94Source: "devpts",95Options: []string{"nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620", "gid=5"},96},97{98Destination: "/dev/shm",99Type: "tmpfs",100Source: "shm",101Options: []string{"nosuid", "noexec", "nodev", "mode=1777", "size=65536k"},102},103{104Destination: "/dev/mqueue",105Type: "mqueue",106Source: "mqueue",107Options: []string{"nosuid", "noexec", "nodev"},108},109{110Destination: "/sys",111Type: "sysfs",112Source: "sysfs",113Options: []string{"nosuid", "noexec", "nodev", "ro"},114},115{116Destination: "/sys/fs/cgroup",117Type: "cgroup",118Source: "cgroup",119Options: []string{"nosuid", "noexec", "nodev", "relatime", "ro"},120},121},122Linux: &specs.Linux{123MaskedPaths: []string{124"/proc/acpi",125"/proc/asound",126"/proc/kcore",127"/proc/keys",128"/proc/latency_stats",129"/proc/timer_list",130"/proc/timer_stats",131"/proc/sched_debug",132"/sys/firmware",133"/proc/scsi",134},135ReadonlyPaths: []string{136"/proc/bus",137"/proc/fs",138"/proc/irq",139"/proc/sys",140"/proc/sysrq-trigger",141},142Resources: &specs.LinuxResources{143Devices: []specs.LinuxDeviceCgroup{144{145Allow: false,146Access: "rwm",147},148},149},150Namespaces: []specs.LinuxNamespace{151{152Type: specs.PIDNamespace,153},154{155Type: specs.NetworkNamespace,156},157{158Type: specs.IPCNamespace,159},160{161Type: specs.UTSNamespace,162},163{164Type: specs.MountNamespace,165},166},167},168}169if cgroups.IsCgroup2UnifiedMode() {170spec.Linux.Namespaces = append(spec.Linux.Namespaces, specs.LinuxNamespace{171Type: specs.CgroupNamespace,172})173}174return spec175}176177// ToRootless converts the given spec file into one that should work with178// rootless containers (euid != 0), by removing incompatible options and adding others that179// are needed.180func ToRootless(spec *specs.Spec) {181var namespaces []specs.LinuxNamespace182183// Remove networkns from the spec.184for _, ns := range spec.Linux.Namespaces {185switch ns.Type {186case specs.NetworkNamespace, specs.UserNamespace:187// Do nothing.188default:189namespaces = append(namespaces, ns)190}191}192// Add userns to the spec.193namespaces = append(namespaces, specs.LinuxNamespace{194Type: specs.UserNamespace,195})196spec.Linux.Namespaces = namespaces197198// Add mappings for the current user.199spec.Linux.UIDMappings = []specs.LinuxIDMapping{{200HostID: uint32(os.Geteuid()),201ContainerID: 0,202Size: 1,203}}204spec.Linux.GIDMappings = []specs.LinuxIDMapping{{205HostID: uint32(os.Getegid()),206ContainerID: 0,207Size: 1,208}}209210// Fix up mounts.211var mounts []specs.Mount212for _, mount := range spec.Mounts {213// Replace the /sys mount with an rbind.214if filepath.Clean(mount.Destination) == "/sys" {215mounts = append(mounts, specs.Mount{216Source: "/sys",217Destination: "/sys",218Type: "none",219Options: []string{"rbind", "nosuid", "noexec", "nodev", "ro"},220})221continue222}223224// Remove all gid= and uid= mappings.225var options []string226for _, option := range mount.Options {227if !strings.HasPrefix(option, "gid=") && !strings.HasPrefix(option, "uid=") {228options = append(options, option)229}230}231232mount.Options = options233mounts = append(mounts, mount)234}235spec.Mounts = mounts236237// Remove cgroup settings.238spec.Linux.Resources = nil239}240241242