github.com/Heebron/moby@v0.0.0-20221111184709-6eab4f55faf7/cmd/dockerd/daemon_unix.go (about)

     1  //go:build !windows
     2  // +build !windows
     3  
     4  package main
     5  
     6  import (
     7  	"context"
     8  	"net"
     9  	"os"
    10  	"os/signal"
    11  	"path/filepath"
    12  	"strconv"
    13  	"time"
    14  
    15  	"github.com/docker/docker/daemon"
    16  	"github.com/docker/docker/daemon/config"
    17  	"github.com/docker/docker/libcontainerd/supervisor"
    18  	"github.com/docker/docker/libnetwork/portallocator"
    19  	"github.com/docker/docker/pkg/homedir"
    20  	"github.com/pkg/errors"
    21  	"github.com/sirupsen/logrus"
    22  	"golang.org/x/sys/unix"
    23  )
    24  
    25  func getDefaultDaemonConfigDir() (string, error) {
    26  	if !honorXDG {
    27  		return "/etc/docker", nil
    28  	}
    29  	// NOTE: CLI uses ~/.docker while the daemon uses ~/.config/docker, because
    30  	// ~/.docker was not designed to store daemon configurations.
    31  	// In future, the daemon directory may be renamed to ~/.config/moby-engine (?).
    32  	configHome, err := homedir.GetConfigHome()
    33  	if err != nil {
    34  		return "", nil
    35  	}
    36  	return filepath.Join(configHome, "docker"), nil
    37  }
    38  
    39  func getDefaultDaemonConfigFile() (string, error) {
    40  	dir, err := getDefaultDaemonConfigDir()
    41  	if err != nil {
    42  		return "", err
    43  	}
    44  	return filepath.Join(dir, "daemon.json"), nil
    45  }
    46  
    47  // setDefaultUmask sets the umask to 0022 to avoid problems
    48  // caused by custom umask
    49  func setDefaultUmask() error {
    50  	desiredUmask := 0022
    51  	unix.Umask(desiredUmask)
    52  	if umask := unix.Umask(desiredUmask); umask != desiredUmask {
    53  		return errors.Errorf("failed to set umask: expected %#o, got %#o", desiredUmask, umask)
    54  	}
    55  
    56  	return nil
    57  }
    58  
    59  func getDaemonConfDir(_ string) (string, error) {
    60  	return getDefaultDaemonConfigDir()
    61  }
    62  
    63  func (cli *DaemonCli) getPlatformContainerdDaemonOpts() ([]supervisor.DaemonOpt, error) {
    64  	opts := []supervisor.DaemonOpt{
    65  		// TODO(thaJeztah) change this to use /proc/self/oom_score_adj instead,
    66  		// which would allow us to set the correct score even if dockerd's score
    67  		// was set through other means (such as systemd or "manually").
    68  		supervisor.WithOOMScore(cli.Config.OOMScoreAdjust),
    69  	}
    70  
    71  	return opts, nil
    72  }
    73  
    74  // setupConfigReloadTrap configures the SIGHUP signal to reload the configuration.
    75  func (cli *DaemonCli) setupConfigReloadTrap() {
    76  	c := make(chan os.Signal, 1)
    77  	signal.Notify(c, unix.SIGHUP)
    78  	go func() {
    79  		for range c {
    80  			cli.reloadConfig()
    81  		}
    82  	}()
    83  }
    84  
    85  // getSwarmRunRoot gets the root directory for swarm to store runtime state
    86  // For example, the control socket
    87  func (cli *DaemonCli) getSwarmRunRoot() string {
    88  	return filepath.Join(cli.Config.ExecRoot, "swarm")
    89  }
    90  
    91  // allocateDaemonPort ensures that there are no containers
    92  // that try to use any port allocated for the docker server.
    93  func allocateDaemonPort(addr string) error {
    94  	host, port, err := net.SplitHostPort(addr)
    95  	if err != nil {
    96  		return errors.Wrap(err, "error parsing tcp address")
    97  	}
    98  
    99  	intPort, err := strconv.Atoi(port)
   100  	if err != nil {
   101  		return errors.Wrap(err, "error parsing tcp address")
   102  	}
   103  
   104  	var hostIPs []net.IP
   105  	if parsedIP := net.ParseIP(host); parsedIP != nil {
   106  		hostIPs = append(hostIPs, parsedIP)
   107  	} else if hostIPs, err = net.LookupIP(host); err != nil {
   108  		return errors.Errorf("failed to lookup %s address in host specification", host)
   109  	}
   110  
   111  	pa := portallocator.Get()
   112  	for _, hostIP := range hostIPs {
   113  		if _, err := pa.RequestPort(hostIP, "tcp", intPort); err != nil {
   114  			return errors.Errorf("failed to allocate daemon listening port %d (err: %v)", intPort, err)
   115  		}
   116  	}
   117  	return nil
   118  }
   119  
   120  func newCgroupParent(config *config.Config) string {
   121  	cgroupParent := "docker"
   122  	useSystemd := daemon.UsingSystemd(config)
   123  	if useSystemd {
   124  		cgroupParent = "system.slice"
   125  	}
   126  	if config.CgroupParent != "" {
   127  		cgroupParent = config.CgroupParent
   128  	}
   129  	if useSystemd {
   130  		cgroupParent = cgroupParent + ":" + "docker" + ":"
   131  	}
   132  	return cgroupParent
   133  }
   134  
   135  func (cli *DaemonCli) initContainerd(ctx context.Context) (func(time.Duration) error, error) {
   136  	if cli.ContainerdAddr != "" {
   137  		// use system containerd at the given address.
   138  		return nil, nil
   139  	}
   140  
   141  	systemContainerdAddr, ok, err := systemContainerdRunning(honorXDG)
   142  	if err != nil {
   143  		return nil, errors.Wrap(err, "could not determine whether the system containerd is running")
   144  	}
   145  	if ok {
   146  		// detected a system containerd at the given address.
   147  		cli.ContainerdAddr = systemContainerdAddr
   148  		return nil, nil
   149  	}
   150  
   151  	logrus.Info("containerd not running, starting managed containerd")
   152  	opts, err := cli.getContainerdDaemonOpts()
   153  	if err != nil {
   154  		return nil, errors.Wrap(err, "failed to generate containerd options")
   155  	}
   156  
   157  	r, err := supervisor.Start(ctx, filepath.Join(cli.Root, "containerd"), filepath.Join(cli.ExecRoot, "containerd"), opts...)
   158  	if err != nil {
   159  		return nil, errors.Wrap(err, "failed to start containerd")
   160  	}
   161  	cli.ContainerdAddr = r.Address()
   162  
   163  	// Try to wait for containerd to shutdown
   164  	return r.WaitTimeout, nil
   165  }