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