github.com/moby/docker@v26.1.3+incompatible/cmd/dockerd/daemon_unix.go (about)

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