| package main | |
| import ( | |
| "fmt" | |
| "os" | |
| "os/signal" | |
| "syscall" | |
| "github.com/containerd/log" | |
| "github.com/docker/docker/daemon/config" | |
| "github.com/docker/docker/dockerversion" | |
| "github.com/docker/docker/pkg/rootless" | |
| "github.com/moby/buildkit/util/apicaps" | |
| "github.com/moby/sys/reexec" | |
| "github.com/moby/term" | |
| "github.com/spf13/cobra" | |
| "go.opentelemetry.io/otel" | |
| "go.opentelemetry.io/otel/metric/noop" | |
| ) | |
| var honorXDG bool | |
| func newDaemonCommand() (*cobra.Command, error) { | |
| // FIXME(thaJeztah): config.New also looks up default binary-path, but this code is also executed when running "--version". | |
| cfg, err := config.New() | |
| if err != nil { | |
| return nil, err | |
| } | |
| opts := newDaemonOptions(cfg) | |
| cmd := &cobra.Command{ | |
| Use: "dockerd [OPTIONS]", | |
| Short: "A self-sufficient runtime for containers.", | |
| SilenceUsage: true, | |
| SilenceErrors: true, | |
| Args: NoArgs, | |
| RunE: func(cmd *cobra.Command, args []string) error { | |
| opts.flags = cmd.Flags() | |
| return runDaemon(opts) | |
| }, | |
| DisableFlagsInUseLine: true, | |
| Version: fmt.Sprintf("%s, build %s", dockerversion.Version, dockerversion.GitCommit), | |
| } | |
| SetupRootCommand(cmd) | |
| flags := cmd.Flags() | |
| flags.BoolP("version", "v", false, "Print version information and quit") | |
| defaultDaemonConfigFile, err := getDefaultDaemonConfigFile() | |
| if err != nil { | |
| return nil, err | |
| } | |
| flags.StringVar(&opts.configFile, "config-file", defaultDaemonConfigFile, "Daemon configuration file") | |
| configureCertsDir() | |
| opts.installFlags(flags) | |
| if err := installConfigFlags(opts.daemonConfig, flags); err != nil { | |
| return nil, err | |
| } | |
| installServiceFlags(flags) | |
| return cmd, nil | |
| } | |
| func init() { | |
| if dockerversion.ProductName != "" { | |
| apicaps.ExportedProduct = dockerversion.ProductName | |
| } | |
| // When running with RootlessKit, $XDG_RUNTIME_DIR, $XDG_DATA_HOME, and $XDG_CONFIG_HOME needs to be | |
| // honored as the default dirs, because we are unlikely to have permissions to access the system-wide | |
| // directories. | |
| // | |
| // Note that even running with --rootless, when not running with RootlessKit, honorXDG needs to be kept false, | |
| // because the system-wide directories in the current mount namespace are expected to be accessible. | |
| // ("rootful" dockerd in rootless dockerd, #38702) | |
| honorXDG = rootless.RunningWithRootlessKit() | |
| } | |
| func main() { | |
| if reexec.Init() { | |
| return | |
| } | |
| // Ignore SIGPIPE events. These are generated by systemd when journald is restarted while | |
| // the docker daemon is not restarted and also running under systemd. | |
| // Fixes https://github.com/docker/docker/issues/19728 | |
| signal.Ignore(syscall.SIGPIPE) | |
| // Workaround OTEL memory leak | |
| // See: https://github.com/open-telemetry/opentelemetry-go-contrib/issues/5190 | |
| // The need for this workaround is checked by the TestOtelMeterLeak test | |
| // TODO: Remove this workaround after upgrading to v1.30.0 | |
| otel.SetMeterProvider(noop.MeterProvider{}) | |
| // Set terminal emulation based on platform as required. | |
| _, stdout, stderr := term.StdStreams() | |
| onError := func(err error) { | |
| fmt.Fprintf(stderr, "%s\n", err) | |
| os.Exit(1) | |
| } | |
| // initial log formatting; this setting is updated after the daemon configuration is loaded. | |
| err := log.SetFormat(log.TextFormat) | |
| if err != nil { | |
| onError(err) | |
| } | |
| initLogging(stdout, stderr) | |
| configureGRPCLog() | |
| cmd, err := newDaemonCommand() | |
| if err != nil { | |
| onError(err) | |
| } | |
| cmd.SetOut(stdout) | |
| if err := cmd.Execute(); err != nil { | |
| onError(err) | |
| } | |
| } |