dotcloud/docker

View on GitHub
cmd/dockerd/docker.go

Summary

Maintainability
A
35 mins
Test Coverage
package main

import (
    "context"
    "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/reexec"
    "github.com/docker/docker/pkg/rootless"
    "github.com/moby/buildkit/util/apicaps"
    "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()

            cli, err := newDaemonCLI(opts)
            if err != nil {
                return err
            }
            if opts.Validate {
                // If config wasn't OK we wouldn't have made it this far.
                _, _ = fmt.Fprintln(os.Stderr, "configuration OK")
                return nil
            }

            return runDaemon(cmd.Context(), cli)
        },
        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")
    flags.StringVar(&opts.configFile, "config-file", opts.configFile, "Daemon configuration file")
    configureCertsDir()
    opts.installFlags(flags)
    installConfigFlags(opts.daemonConfig, flags)
    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
    }
    ctx := context.Background()

    // 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.ExecuteContext(ctx); err != nil {
        onError(err)
    }
}