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