github.com/demonoid81/moby@v0.0.0-20200517203328-62dd8e17c460/libcontainerd/remote/client_linux.go (about) 1 package remote // import "github.com/demonoid81/moby/libcontainerd/remote" 2 3 import ( 4 "context" 5 "fmt" 6 "os" 7 "path/filepath" 8 "strings" 9 10 "github.com/containerd/containerd" 11 "github.com/containerd/containerd/cio" 12 "github.com/containerd/containerd/containers" 13 libcontainerdtypes "github.com/demonoid81/moby/libcontainerd/types" 14 "github.com/demonoid81/moby/pkg/idtools" 15 specs "github.com/opencontainers/runtime-spec/specs-go" 16 "github.com/sirupsen/logrus" 17 ) 18 19 const ( 20 runtimeName = "io.containerd.runtime.v1.linux" 21 shimV2RuntimeName = "io.containerd.runc.v2" 22 ) 23 24 func summaryFromInterface(i interface{}) (*libcontainerdtypes.Summary, error) { 25 return &libcontainerdtypes.Summary{}, nil 26 } 27 28 func (c *client) UpdateResources(ctx context.Context, containerID string, resources *libcontainerdtypes.Resources) error { 29 p, err := c.getProcess(ctx, containerID, libcontainerdtypes.InitProcessName) 30 if err != nil { 31 return err 32 } 33 34 // go doesn't like the alias in 1.8, this means this need to be 35 // platform specific 36 return p.(containerd.Task).Update(ctx, containerd.WithResources((*specs.LinuxResources)(resources))) 37 } 38 39 func hostIDFromMap(id uint32, mp []specs.LinuxIDMapping) int { 40 for _, m := range mp { 41 if id >= m.ContainerID && id <= m.ContainerID+m.Size-1 { 42 return int(m.HostID + id - m.ContainerID) 43 } 44 } 45 return 0 46 } 47 48 func getSpecUser(ociSpec *specs.Spec) (int, int) { 49 var ( 50 uid int 51 gid int 52 ) 53 54 for _, ns := range ociSpec.Linux.Namespaces { 55 if ns.Type == specs.UserNamespace { 56 uid = hostIDFromMap(0, ociSpec.Linux.UIDMappings) 57 gid = hostIDFromMap(0, ociSpec.Linux.GIDMappings) 58 break 59 } 60 } 61 62 return uid, gid 63 } 64 65 // WithBundle creates the bundle for the container 66 func WithBundle(bundleDir string, ociSpec *specs.Spec) containerd.NewContainerOpts { 67 return func(ctx context.Context, client *containerd.Client, c *containers.Container) error { 68 if c.Labels == nil { 69 c.Labels = make(map[string]string) 70 } 71 uid, gid := getSpecUser(ociSpec) 72 if uid == 0 && gid == 0 { 73 c.Labels[DockerContainerBundlePath] = bundleDir 74 return idtools.MkdirAllAndChownNew(bundleDir, 0755, idtools.Identity{UID: 0, GID: 0}) 75 } 76 77 p := string(filepath.Separator) 78 components := strings.Split(bundleDir, string(filepath.Separator)) 79 for _, d := range components[1:] { 80 p = filepath.Join(p, d) 81 fi, err := os.Stat(p) 82 if err != nil && !os.IsNotExist(err) { 83 return err 84 } 85 if os.IsNotExist(err) || fi.Mode()&1 == 0 { 86 p = fmt.Sprintf("%s.%d.%d", p, uid, gid) 87 if err := idtools.MkdirAndChown(p, 0700, idtools.Identity{UID: uid, GID: gid}); err != nil && !os.IsExist(err) { 88 return err 89 } 90 } 91 } 92 if c.Labels == nil { 93 c.Labels = make(map[string]string) 94 } 95 c.Labels[DockerContainerBundlePath] = p 96 return nil 97 } 98 } 99 100 func withLogLevel(_ logrus.Level) containerd.NewTaskOpts { 101 panic("Not implemented") 102 } 103 104 func newFIFOSet(bundleDir, processID string, withStdin, withTerminal bool) *cio.FIFOSet { 105 config := cio.Config{ 106 Terminal: withTerminal, 107 Stdout: filepath.Join(bundleDir, processID+"-stdout"), 108 } 109 paths := []string{config.Stdout} 110 111 if withStdin { 112 config.Stdin = filepath.Join(bundleDir, processID+"-stdin") 113 paths = append(paths, config.Stdin) 114 } 115 if !withTerminal { 116 config.Stderr = filepath.Join(bundleDir, processID+"-stderr") 117 paths = append(paths, config.Stderr) 118 } 119 closer := func() error { 120 for _, path := range paths { 121 if err := os.RemoveAll(path); err != nil { 122 logrus.Warnf("libcontainerd: failed to remove fifo %v: %v", path, err) 123 } 124 } 125 return nil 126 } 127 128 return cio.NewFIFOSet(config, closer) 129 } 130 131 func (c *client) newDirectIO(ctx context.Context, fifos *cio.FIFOSet) (*cio.DirectIO, error) { 132 return cio.NewDirectIO(ctx, fifos) 133 }