@@ -31,6 +31,7 @@ import (
3131 prototypes "github.com/gogo/protobuf/types"
3232 "github.com/golang/glog"
3333 imagespec "github.com/opencontainers/image-spec/specs-go/v1"
34+ "github.com/opencontainers/runc/libcontainer/devices"
3435 runtimespec "github.com/opencontainers/runtime-spec/specs-go"
3536 "github.com/opencontainers/runtime-tools/generate"
3637 "golang.org/x/net/context"
@@ -250,11 +251,17 @@ func (c *criContainerdService) generateContainerSpec(id string, sandboxPid uint3
250251 g .AddProcessEnv (e .GetKey (), e .GetValue ())
251252 }
252253
254+ // TODO: add setOCIPrivileged group all privileged logic together
255+ securityContext := config .GetLinux ().GetSecurityContext ()
256+
253257 // Add extra mounts first so that CRI specified mounts can override.
254- addOCIBindMounts (& g , append (extraMounts , config .GetMounts ()... ))
258+ addOCIBindMounts (& g , append (extraMounts , config .GetMounts ()... ), securityContext . GetPrivileged () )
255259
256- // TODO(random-liu): [P1] Set device mapping.
257- // Ref https://github.com/moby/moby/blob/master/oci/devices_linux.go.
260+ g .SetRootReadonly (securityContext .GetReadonlyRootfs ())
261+
262+ if err := addOCIDevices (& g , config .GetDevices (), securityContext .GetPrivileged ()); err != nil {
263+ return nil , fmt .Errorf ("failed to set devices mapping %+v: %v" , config .GetDevices (), err )
264+ }
258265
259266 // TODO(random-liu): [P1] Handle container logging, decorate and redirect to file.
260267
@@ -267,15 +274,11 @@ func (c *criContainerdService) generateContainerSpec(id string, sandboxPid uint3
267274
268275 g .SetProcessTerminal (config .GetTty ())
269276
270- securityContext := config .GetLinux ().GetSecurityContext ()
271-
272- if err := setOCICapabilities (& g , securityContext .GetCapabilities ()); err != nil {
277+ if err := setOCICapabilities (& g , securityContext .GetCapabilities (), securityContext .GetPrivileged ()); err != nil {
273278 return nil , fmt .Errorf ("failed to set capabilities %+v: %v" ,
274279 securityContext .GetCapabilities (), err )
275280 }
276281
277- // TODO(random-liu): [P0] Handle privileged.
278-
279282 // Set namespaces, share namespace with sandbox container.
280283 setOCINamespaces (& g , securityContext .GetNamespaceOptions (), sandboxPid )
281284
@@ -288,8 +291,6 @@ func (c *criContainerdService) generateContainerSpec(id string, sandboxPid uint3
288291 g .AddProcessAdditionalGid (uint32 (group ))
289292 }
290293
291- g .SetRootReadonly (securityContext .GetReadonlyRootfs ())
292-
293294 // TODO(random-liu): [P2] Add apparmor and seccomp.
294295
295296 return g .Spec (), nil
@@ -352,8 +353,70 @@ func addImageEnvs(g *generate.Generator, imageEnvs []string) error {
352353 return nil
353354}
354355
356+ func clearReadOnly (m * runtimespec.Mount ) {
357+ var opt []string
358+ for _ , o := range m .Options {
359+ if o != "ro" {
360+ opt = append (opt , o )
361+ }
362+ }
363+ m .Options = opt
364+ }
365+
366+ // addDevices set device mapping.
367+ func addOCIDevices (g * generate.Generator , devs []* runtime.Device , privileged bool ) error {
368+ spec := g .Spec ()
369+ if privileged {
370+ hostDevices , err := devices .HostDevices ()
371+ if err != nil {
372+ return err
373+ }
374+ for _ , hostDevice := range hostDevices {
375+ rd := runtimespec.LinuxDevice {
376+ Path : hostDevice .Path ,
377+ Type : string (hostDevice .Type ),
378+ Major : hostDevice .Major ,
379+ Minor : hostDevice .Minor ,
380+ UID : & hostDevice .Uid ,
381+ GID : & hostDevice .Gid ,
382+ }
383+ g .AddDevice (rd )
384+ }
385+ spec .Linux .Resources .Devices = []runtimespec.LinuxDeviceCgroup {
386+ {
387+ Allow : true ,
388+ Access : "rwm" ,
389+ },
390+ }
391+ return nil
392+ }
393+ for _ , device := range devs {
394+ dev , err := devices .DeviceFromPath (device .HostPath , device .Permissions )
395+ if err != nil {
396+ return err
397+ }
398+ rd := runtimespec.LinuxDevice {
399+ Path : device .ContainerPath ,
400+ Type : string (dev .Type ),
401+ Major : dev .Major ,
402+ Minor : dev .Minor ,
403+ UID : & dev .Uid ,
404+ GID : & dev .Gid ,
405+ }
406+ g .AddDevice (rd )
407+ spec .Linux .Resources .Devices = append (spec .Linux .Resources .Devices , runtimespec.LinuxDeviceCgroup {
408+ Allow : true ,
409+ Type : string (dev .Type ),
410+ Major : & dev .Major ,
411+ Minor : & dev .Minor ,
412+ Access : dev .Permissions ,
413+ })
414+ }
415+ return nil
416+ }
417+
355418// addOCIBindMounts adds bind mounts.
356- func addOCIBindMounts (g * generate.Generator , mounts []* runtime.Mount ) {
419+ func addOCIBindMounts (g * generate.Generator , mounts []* runtime.Mount , privileged bool ) {
357420 for _ , mount := range mounts {
358421 dst := mount .GetContainerPath ()
359422 src := mount .GetHostPath ()
@@ -364,6 +427,21 @@ func addOCIBindMounts(g *generate.Generator, mounts []*runtime.Mount) {
364427 // TODO(random-liu): [P1] Apply selinux label
365428 g .AddBindMount (src , dst , options )
366429 }
430+ if ! privileged {
431+ return
432+ }
433+ spec := g .Spec ()
434+ // clear readonly for /sys and cgroup
435+ for i , m := range spec .Mounts {
436+ if spec .Mounts [i ].Destination == "/sys" && ! spec .Root .Readonly {
437+ clearReadOnly (& spec .Mounts [i ])
438+ }
439+ if m .Type == "cgroup" {
440+ clearReadOnly (& spec .Mounts [i ])
441+ }
442+ }
443+ spec .Linux .ReadonlyPaths = nil
444+ spec .Linux .MaskedPaths = nil
367445}
368446
369447// setOCILinuxResource set container resource limit.
@@ -379,7 +457,12 @@ func setOCILinuxResource(g *generate.Generator, resources *runtime.LinuxContaine
379457}
380458
381459// setOCICapabilities adds/drops process capabilities.
382- func setOCICapabilities (g * generate.Generator , capabilities * runtime.Capability ) error {
460+ func setOCICapabilities (g * generate.Generator , capabilities * runtime.Capability , privileged bool ) error {
461+ if privileged {
462+ // Add all capabilities in privileged mode.
463+ g .SetupPrivileged (true )
464+ return nil
465+ }
383466 if capabilities == nil {
384467 return nil
385468 }
@@ -395,7 +478,6 @@ func setOCICapabilities(g *generate.Generator, capabilities *runtime.Capability)
395478 return err
396479 }
397480 }
398-
399481 return nil
400482}
401483
0 commit comments