github.com/rumpl/bof@v23.0.0-rc.2+incompatible/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  		supervisor.WithOOMScore(cli.Config.OOMScoreAdjust),
    66  	}
    67  
    68  	return opts, nil
    69  }
    70  
    71  // setupConfigReloadTrap configures the SIGHUP signal to reload the configuration.
    72  func (cli *DaemonCli) setupConfigReloadTrap() {
    73  	c := make(chan os.Signal, 1)
    74  	signal.Notify(c, unix.SIGHUP)
    75  	go func() {
    76  		for range c {
    77  			cli.reloadConfig()
    78  		}
    79  	}()
    80  }
    81  
    82  // getSwarmRunRoot gets the root directory for swarm to store runtime state
    83  // For example, the control socket
    84  func (cli *DaemonCli) getSwarmRunRoot() string {
    85  	return filepath.Join(cli.Config.ExecRoot, "swarm")
    86  }
    87  
    88  // allocateDaemonPort ensures that there are no containers
    89  // that try to use any port allocated for the docker server.
    90  func allocateDaemonPort(addr string) error {
    91  	host, port, err := net.SplitHostPort(addr)
    92  	if err != nil {
    93  		return errors.Wrap(err, "error parsing tcp address")
    94  	}
    95  
    96  	intPort, err := strconv.Atoi(port)
    97  	if err != nil {
    98  		return errors.Wrap(err, "error parsing tcp address")
    99  	}
   100  
   101  	var hostIPs []net.IP
   102  	if parsedIP := net.ParseIP(host); parsedIP != nil {
   103  		hostIPs = append(hostIPs, parsedIP)
   104  	} else if hostIPs, err = net.LookupIP(host); err != nil {
   105  		return errors.Errorf("failed to lookup %s address in host specification", host)
   106  	}
   107  
   108  	pa := portallocator.Get()
   109  	for _, hostIP := range hostIPs {
   110  		if _, err := pa.RequestPort(hostIP, "tcp", intPort); err != nil {
   111  			return errors.Errorf("failed to allocate daemon listening port %d (err: %v)", intPort, err)
   112  		}
   113  	}
   114  	return nil
   115  }
   116  
   117  func newCgroupParent(config *config.Config) string {
   118  	cgroupParent := "docker"
   119  	useSystemd := daemon.UsingSystemd(config)
   120  	if useSystemd {
   121  		cgroupParent = "system.slice"
   122  	}
   123  	if config.CgroupParent != "" {
   124  		cgroupParent = config.CgroupParent
   125  	}
   126  	if useSystemd {
   127  		cgroupParent = cgroupParent + ":" + "docker" + ":"
   128  	}
   129  	return cgroupParent
   130  }
   131  
   132  func (cli *DaemonCli) initContainerD(ctx context.Context) (func(time.Duration) error, error) {
   133  	var waitForShutdown func(time.Duration) error
   134  	if cli.Config.ContainerdAddr == "" {
   135  		systemContainerdAddr, ok, err := systemContainerdRunning(honorXDG)
   136  		if err != nil {
   137  			return nil, errors.Wrap(err, "could not determine whether the system containerd is running")
   138  		}
   139  		if !ok {
   140  			logrus.Debug("Containerd not running, starting daemon managed containerd")
   141  			opts, err := cli.getContainerdDaemonOpts()
   142  			if err != nil {
   143  				return nil, errors.Wrap(err, "failed to generate containerd options")
   144  			}
   145  
   146  			r, err := supervisor.Start(ctx, filepath.Join(cli.Config.Root, "containerd"), filepath.Join(cli.Config.ExecRoot, "containerd"), opts...)
   147  			if err != nil {
   148  				return nil, errors.Wrap(err, "failed to start containerd")
   149  			}
   150  			logrus.Debug("Started daemon managed containerd")
   151  			cli.Config.ContainerdAddr = r.Address()
   152  
   153  			// Try to wait for containerd to shutdown
   154  			waitForShutdown = r.WaitTimeout
   155  		} else {
   156  			cli.Config.ContainerdAddr = systemContainerdAddr
   157  		}
   158  	}
   159  
   160  	return waitForShutdown, nil
   161  }