@@ -18,24 +18,55 @@ package oci
1818
1919import (
2020 "context"
21+ "path/filepath"
22+
23+ "github.com/containerd/containerd/namespaces"
24+ "github.com/containerd/containerd/platforms"
2125
2226 "github.com/containerd/containerd/containers"
2327 specs "github.com/opencontainers/runtime-spec/specs-go"
2428)
2529
30+ const (
31+ rwm = "rwm"
32+ defaultRootfsPath = "rootfs"
33+ )
34+
35+ var (
36+ defaultUnixEnv = []string {
37+ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ,
38+ }
39+ )
40+
2641// Spec is a type alias to the OCI runtime spec to allow third part SpecOpts
2742// to be created without the "issues" with go vendoring and package imports
2843type Spec = specs.Spec
2944
3045// GenerateSpec will generate a default spec from the provided image
3146// for use as a containerd container
3247func GenerateSpec (ctx context.Context , client Client , c * containers.Container , opts ... SpecOpts ) (* Spec , error ) {
33- s , err := createDefaultSpec (ctx , c .ID )
48+ return GenerateSpecWithPlatform (ctx , client , platforms .DefaultString (), c , opts ... )
49+ }
50+
51+ // GenerateSpecWithPlatform will generate a default spec from the provided image
52+ // for use as a containerd container in the platform requested.
53+ func GenerateSpecWithPlatform (ctx context.Context , client Client , platform string , c * containers.Container , opts ... SpecOpts ) (* Spec , error ) {
54+ plat , err := platforms .Parse (platform )
3455 if err != nil {
3556 return nil , err
3657 }
3758
38- return s , ApplyOpts (ctx , client , c , s , opts ... )
59+ var s Spec
60+ if plat .OS == "windows" {
61+ err = populateDefaultWindowsSpec (ctx , & s , c .ID )
62+ } else {
63+ err = populateDefaultUnixSpec (ctx , & s , c .ID )
64+ }
65+ if err != nil {
66+ return nil , err
67+ }
68+
69+ return & s , ApplyOpts (ctx , client , c , & s , opts ... )
3970}
4071
4172// ApplyOpts applys the options to the given spec, injecting data from the
@@ -50,7 +81,173 @@ func ApplyOpts(ctx context.Context, client Client, c *containers.Container, s *S
5081 return nil
5182}
5283
53- func createDefaultSpec (ctx context.Context , id string ) (* Spec , error ) {
54- var s Spec
55- return & s , populateDefaultSpec (ctx , & s , id )
84+ func defaultUnixCaps () []string {
85+ return []string {
86+ "CAP_CHOWN" ,
87+ "CAP_DAC_OVERRIDE" ,
88+ "CAP_FSETID" ,
89+ "CAP_FOWNER" ,
90+ "CAP_MKNOD" ,
91+ "CAP_NET_RAW" ,
92+ "CAP_SETGID" ,
93+ "CAP_SETUID" ,
94+ "CAP_SETFCAP" ,
95+ "CAP_SETPCAP" ,
96+ "CAP_NET_BIND_SERVICE" ,
97+ "CAP_SYS_CHROOT" ,
98+ "CAP_KILL" ,
99+ "CAP_AUDIT_WRITE" ,
100+ }
101+ }
102+
103+ func defaultUnixNamespaces () []specs.LinuxNamespace {
104+ return []specs.LinuxNamespace {
105+ {
106+ Type : specs .PIDNamespace ,
107+ },
108+ {
109+ Type : specs .IPCNamespace ,
110+ },
111+ {
112+ Type : specs .UTSNamespace ,
113+ },
114+ {
115+ Type : specs .MountNamespace ,
116+ },
117+ {
118+ Type : specs .NetworkNamespace ,
119+ },
120+ }
121+ }
122+
123+ func populateDefaultUnixSpec (ctx context.Context , s * Spec , id string ) error {
124+ ns , err := namespaces .NamespaceRequired (ctx )
125+ if err != nil {
126+ return err
127+ }
128+
129+ * s = Spec {
130+ Version : specs .Version ,
131+ Root : & specs.Root {
132+ Path : defaultRootfsPath ,
133+ },
134+ Process : & specs.Process {
135+ Env : defaultUnixEnv ,
136+ Cwd : "/" ,
137+ NoNewPrivileges : true ,
138+ User : specs.User {
139+ UID : 0 ,
140+ GID : 0 ,
141+ },
142+ Capabilities : & specs.LinuxCapabilities {
143+ Bounding : defaultUnixCaps (),
144+ Permitted : defaultUnixCaps (),
145+ Inheritable : defaultUnixCaps (),
146+ Effective : defaultUnixCaps (),
147+ },
148+ Rlimits : []specs.POSIXRlimit {
149+ {
150+ Type : "RLIMIT_NOFILE" ,
151+ Hard : uint64 (1024 ),
152+ Soft : uint64 (1024 ),
153+ },
154+ },
155+ },
156+ Mounts : []specs.Mount {
157+ {
158+ Destination : "/proc" ,
159+ Type : "proc" ,
160+ Source : "proc" ,
161+ },
162+ {
163+ Destination : "/dev" ,
164+ Type : "tmpfs" ,
165+ Source : "tmpfs" ,
166+ Options : []string {"nosuid" , "strictatime" , "mode=755" , "size=65536k" },
167+ },
168+ {
169+ Destination : "/dev/pts" ,
170+ Type : "devpts" ,
171+ Source : "devpts" ,
172+ Options : []string {"nosuid" , "noexec" , "newinstance" , "ptmxmode=0666" , "mode=0620" , "gid=5" },
173+ },
174+ {
175+ Destination : "/dev/shm" ,
176+ Type : "tmpfs" ,
177+ Source : "shm" ,
178+ Options : []string {"nosuid" , "noexec" , "nodev" , "mode=1777" , "size=65536k" },
179+ },
180+ {
181+ Destination : "/dev/mqueue" ,
182+ Type : "mqueue" ,
183+ Source : "mqueue" ,
184+ Options : []string {"nosuid" , "noexec" , "nodev" },
185+ },
186+ {
187+ Destination : "/sys" ,
188+ Type : "sysfs" ,
189+ Source : "sysfs" ,
190+ Options : []string {"nosuid" , "noexec" , "nodev" , "ro" },
191+ },
192+ {
193+ Destination : "/run" ,
194+ Type : "tmpfs" ,
195+ Source : "tmpfs" ,
196+ Options : []string {"nosuid" , "strictatime" , "mode=755" , "size=65536k" },
197+ },
198+ },
199+ Linux : & specs.Linux {
200+ MaskedPaths : []string {
201+ "/proc/acpi" ,
202+ "/proc/kcore" ,
203+ "/proc/keys" ,
204+ "/proc/latency_stats" ,
205+ "/proc/timer_list" ,
206+ "/proc/timer_stats" ,
207+ "/proc/sched_debug" ,
208+ "/sys/firmware" ,
209+ "/proc/scsi" ,
210+ },
211+ ReadonlyPaths : []string {
212+ "/proc/asound" ,
213+ "/proc/bus" ,
214+ "/proc/fs" ,
215+ "/proc/irq" ,
216+ "/proc/sys" ,
217+ "/proc/sysrq-trigger" ,
218+ },
219+ CgroupsPath : filepath .Join ("/" , ns , id ),
220+ Resources : & specs.LinuxResources {
221+ Devices : []specs.LinuxDeviceCgroup {
222+ {
223+ Allow : false ,
224+ Access : rwm ,
225+ },
226+ },
227+ },
228+ Namespaces : defaultUnixNamespaces (),
229+ },
230+ }
231+ return nil
232+ }
233+
234+ func populateDefaultWindowsSpec (ctx context.Context , s * Spec , id string ) error {
235+ * s = Spec {
236+ Version : specs .Version ,
237+ Root : & specs.Root {},
238+ Process : & specs.Process {
239+ Cwd : `C:\` ,
240+ ConsoleSize : & specs.Box {
241+ Width : 80 ,
242+ Height : 20 ,
243+ },
244+ },
245+ Windows : & specs.Windows {
246+ IgnoreFlushesDuringBoot : true ,
247+ Network : & specs.WindowsNetwork {
248+ AllowUnqualifiedDNSQuery : true ,
249+ },
250+ },
251+ }
252+ return nil
56253}
0 commit comments