github.com/Heebron/moby@v0.0.0-20221111184709-6eab4f55faf7/libcontainerd/remote/client_linux.go (about)

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