github.com/rawahars/moby@v24.0.4+incompatible/cmd/dockerd/options.go (about) 1 package main 2 3 import ( 4 "os" 5 "path/filepath" 6 7 "github.com/docker/docker/daemon/config" 8 "github.com/docker/docker/opts" 9 "github.com/docker/docker/pkg/homedir" 10 "github.com/docker/go-connections/tlsconfig" 11 "github.com/spf13/pflag" 12 ) 13 14 const ( 15 // DefaultCaFile is the default filename for the CA pem file 16 DefaultCaFile = "ca.pem" 17 // DefaultKeyFile is the default filename for the key pem file 18 DefaultKeyFile = "key.pem" 19 // DefaultCertFile is the default filename for the cert pem file 20 DefaultCertFile = "cert.pem" 21 // FlagTLSVerify is the flag name for the TLS verification option 22 FlagTLSVerify = "tlsverify" 23 // FlagTLS is the flag name for the TLS option 24 FlagTLS = "tls" 25 // DefaultTLSValue is the default value used for setting the tls option for tcp connections 26 DefaultTLSValue = false 27 ) 28 29 var ( 30 // The configDir (and "DOCKER_CONFIG" environment variable) is now only used 31 // for the default location for TLS certificates to secure the daemon API. 32 // It is a leftover from when the "docker" and "dockerd" CLI shared the 33 // same binary, allowing the DOCKER_CONFIG environment variable to set 34 // the location for certificates to be used by both. 35 // 36 // We need to change this, as there's various issues: 37 // 38 // - DOCKER_CONFIG only affects TLS certificates, but does not change the 39 // location for the actual *daemon configuration* (which defaults to 40 // "/etc/docker/daemon.json"). 41 // - If no value is set, configDir uses "~/.docker/" as default, but does 42 // not take $XDG_CONFIG_HOME into account (it uses pkg/homedir.Get, which 43 // is not XDG_CONFIG_HOME-aware). 44 // - Using the home directory can be problematic in cases where the CLI and 45 // daemon actually live on the same host; if DOCKER_CONFIG is set to set 46 // the "docker" CLI configuration path (and if the daemon shares that 47 // environment variable, e.g. "sudo -E dockerd"), the daemon may create 48 // the "~/.docker/" directory, but now the directory may be owned by "root". 49 // 50 // We should: 51 // 52 // - deprecate DOCKER_CONFIG for the daemon 53 // - decide where the TLS certs should live by default ("/etc/docker/"?) 54 // - look at "when" (and when _not_) XDG_CONFIG_HOME should be used. Its 55 // needed for rootless, but perhaps could be used for non-rootless(?) 56 // - When changing the location for TLS config, (ideally) they should 57 // live in a directory separate from "non-sensitive" (configuration-) 58 // files, so that general configuration can be shared (dotfiles repo 59 // etc) separate from "sensitive" config (TLS certificates). 60 // 61 // TODO(thaJeztah): deprecate DOCKER_CONFIG and re-design daemon config locations. See https://github.com/moby/moby/issues/44640 62 configDir = os.Getenv("DOCKER_CONFIG") 63 configFileDir = ".docker" 64 dockerCertPath = os.Getenv("DOCKER_CERT_PATH") 65 dockerTLSVerify = os.Getenv("DOCKER_TLS_VERIFY") != "" 66 ) 67 68 type daemonOptions struct { 69 configFile string 70 daemonConfig *config.Config 71 flags *pflag.FlagSet 72 Debug bool 73 Hosts []string 74 LogLevel string 75 TLS bool 76 TLSVerify bool 77 TLSOptions *tlsconfig.Options 78 Validate bool 79 } 80 81 // defaultCertPath uses $DOCKER_CONFIG or ~/.docker, and does not look up 82 // $XDG_CONFIG_HOME. See the comment on configDir above for further details. 83 func defaultCertPath() string { 84 if configDir == "" { 85 // Set the default path if DOCKER_CONFIG is not set. 86 configDir = filepath.Join(homedir.Get(), configFileDir) 87 } 88 return configDir 89 } 90 91 // newDaemonOptions returns a new daemonFlags 92 func newDaemonOptions(config *config.Config) *daemonOptions { 93 return &daemonOptions{ 94 daemonConfig: config, 95 } 96 } 97 98 // installFlags adds flags for the common options on the FlagSet 99 func (o *daemonOptions) installFlags(flags *pflag.FlagSet) { 100 if dockerCertPath == "" { 101 dockerCertPath = defaultCertPath() 102 } 103 104 flags.BoolVarP(&o.Debug, "debug", "D", false, "Enable debug mode") 105 flags.BoolVar(&o.Validate, "validate", false, "Validate daemon configuration and exit") 106 flags.StringVarP(&o.LogLevel, "log-level", "l", "info", `Set the logging level ("debug"|"info"|"warn"|"error"|"fatal")`) 107 flags.BoolVar(&o.TLS, FlagTLS, DefaultTLSValue, "Use TLS; implied by --tlsverify") 108 flags.BoolVar(&o.TLSVerify, FlagTLSVerify, dockerTLSVerify || DefaultTLSValue, "Use TLS and verify the remote") 109 110 // TODO(thaJeztah): set default TLSOptions in config.New() 111 o.TLSOptions = &tlsconfig.Options{} 112 tlsOptions := o.TLSOptions 113 flags.StringVar(&tlsOptions.CAFile, "tlscacert", filepath.Join(dockerCertPath, DefaultCaFile), "Trust certs signed only by this CA") 114 flags.StringVar(&tlsOptions.CertFile, "tlscert", filepath.Join(dockerCertPath, DefaultCertFile), "Path to TLS certificate file") 115 flags.StringVar(&tlsOptions.KeyFile, "tlskey", filepath.Join(dockerCertPath, DefaultKeyFile), "Path to TLS key file") 116 117 hostOpt := opts.NewNamedListOptsRef("hosts", &o.Hosts, opts.ValidateHost) 118 flags.VarP(hostOpt, "host", "H", "Daemon socket(s) to connect to") 119 } 120 121 // setDefaultOptions sets default values for options after flag parsing is 122 // complete 123 func (o *daemonOptions) setDefaultOptions() { 124 // Regardless of whether the user sets it to true or false, if they 125 // specify --tlsverify at all then we need to turn on TLS 126 // TLSVerify can be true even if not set due to DOCKER_TLS_VERIFY env var, so we need 127 // to check that here as well 128 if o.flags.Changed(FlagTLSVerify) || o.TLSVerify { 129 o.TLS = true 130 } 131 132 if o.TLS && !o.flags.Changed(FlagTLSVerify) { 133 // Enable tls verification unless explicitly disabled 134 o.TLSVerify = true 135 } 136 137 if !o.TLS { 138 o.TLSOptions = nil 139 } else { 140 o.TLSOptions.InsecureSkipVerify = !o.TLSVerify 141 142 // Reset CertFile and KeyFile to empty string if the user did not specify 143 // the respective flags and the respective default files were not found. 144 if !o.flags.Changed("tlscert") { 145 if _, err := os.Stat(o.TLSOptions.CertFile); os.IsNotExist(err) { 146 o.TLSOptions.CertFile = "" 147 } 148 } 149 if !o.flags.Changed("tlskey") { 150 if _, err := os.Stat(o.TLSOptions.KeyFile); os.IsNotExist(err) { 151 o.TLSOptions.KeyFile = "" 152 } 153 } 154 } 155 }