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  }