func runLogs(dockerCli *command.DockerCli, opts *logsOptions) error { ctx := context.Background() options := types.ContainerLogsOptions{ ShowStdout: true, ShowStderr: true, Since: opts.since, Timestamps: opts.timestamps, Follow: opts.follow, Tail: opts.tail, Details: opts.details, } responseBody, err := dockerCli.Client().ContainerLogs(ctx, opts.container, options) if err != nil { return err } defer responseBody.Close() c, err := dockerCli.Client().ContainerInspect(ctx, opts.container) if err != nil { return err } if c.Config.Tty { _, err = io.Copy(dockerCli.Out(), responseBody) } else { _, err = stdcopy.StdCopy(dockerCli.Out(), dockerCli.Err(), responseBody) } return err }
// NewImageCommand returns a cobra command for `image` subcommands func NewImageCommand(dockerCli *command.DockerCli) *cobra.Command { cmd := &cobra.Command{ Use: "image", Short: "Manage images", Args: cli.NoArgs, Run: func(cmd *cobra.Command, args []string) { fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString()) }, } cmd.AddCommand( NewBuildCommand(dockerCli), NewHistoryCommand(dockerCli), NewImportCommand(dockerCli), NewLoadCommand(dockerCli), NewPullCommand(dockerCli), NewPushCommand(dockerCli), NewSaveCommand(dockerCli), NewTagCommand(dockerCli), newListCommand(dockerCli), newRemoveCommand(dockerCli), newInspectCommand(dockerCli), NewPruneCommand(dockerCli), ) return cmd }
func runConfig(dockerCli *command.DockerCli, opts configOptions) error { bundle, err := loadBundlefile(dockerCli.Err(), opts.namespace, opts.bundlefile) if err != nil { return err } return bundlefile.Print(dockerCli.Out(), bundle) }
func newCreateCommand(dockerCli *command.DockerCli) *cobra.Command { opts := createOptions{ driverOpts: *opts.NewMapOpts(nil, nil), labels: opts.NewListOpts(opts.ValidateEnv), } cmd := &cobra.Command{ Use: "create [OPTIONS] [VOLUME]", Short: "Create a volume", Args: cli.RequiresMaxArgs(1), RunE: func(cmd *cobra.Command, args []string) error { if len(args) == 1 { if opts.name != "" { fmt.Fprint(dockerCli.Err(), "Conflicting options: either specify --name or provide positional arg, not both\n") return cli.StatusError{StatusCode: 1} } opts.name = args[0] } return runCreate(dockerCli, opts) }, } flags := cmd.Flags() flags.StringVarP(&opts.driver, "driver", "d", "local", "Specify volume driver name") flags.StringVar(&opts.name, "name", "", "Specify volume name") flags.Lookup("name").Hidden = true flags.VarP(&opts.driverOpts, "opt", "o", "Set driver specific options") flags.Var(&opts.labels, "label", "Set metadata for a volume") return cmd }
// NewImageCommand returns a cobra command for `image` subcommands func NewImageCommand(dockerCli *command.DockerCli) *cobra.Command { cmd := &cobra.Command{ Use: "image", Short: "Manage images", Args: cli.NoArgs, Run: func(cmd *cobra.Command, args []string) { cmd.SetOutput(dockerCli.Err()) cmd.HelpFunc()(cmd, args) }, } cmd.AddCommand( NewBuildCommand(dockerCli), NewHistoryCommand(dockerCli), NewImportCommand(dockerCli), NewLoadCommand(dockerCli), NewPullCommand(dockerCli), NewPushCommand(dockerCli), NewSaveCommand(dockerCli), NewTagCommand(dockerCli), newListCommand(dockerCli), newRemoveCommand(dockerCli), newInspectCommand(dockerCli), NewPruneCommand(dockerCli), ) return cmd }
func runLogs(dockerCli *command.DockerCli, opts *logsOptions) error { ctx := context.Background() options := types.ContainerLogsOptions{ ShowStdout: true, ShowStderr: true, Since: opts.since, Timestamps: opts.timestamps, Follow: opts.follow, Tail: opts.tail, Details: opts.details, } client := dockerCli.Client() responseBody, err := client.ServiceLogs(ctx, opts.service, options) if err != nil { return err } defer responseBody.Close() resolver := idresolver.New(client, opts.noResolve) stdout := &logWriter{ctx: ctx, opts: opts, r: resolver, w: dockerCli.Out()} stderr := &logWriter{ctx: ctx, opts: opts, r: resolver, w: dockerCli.Err()} // TODO(aluzzardi): Do an io.Copy for services with TTY enabled. _, err = stdcopy.StdCopy(stdout, stderr, responseBody) return err }
// ForwardAllSignals forwards signals to the container func ForwardAllSignals(ctx context.Context, cli *command.DockerCli, cid string) chan os.Signal { sigc := make(chan os.Signal, 128) signal.CatchAll(sigc) go func() { for s := range sigc { if s == signal.SIGCHLD || s == signal.SIGPIPE { continue } var sig string for sigStr, sigN := range signal.SignalMap { if sigN == s { sig = sigStr break } } if sig == "" { fmt.Fprintf(cli.Err(), "Unsupported signal: %v. Discarding.\n", s) continue } if err := cli.Client().ContainerKill(ctx, cid, sig); err != nil { logrus.Debugf("Error sending signal: %s", err) } } }() return sigc }
func runServiceScale(dockerCli *command.DockerCli, serviceID string, scale uint64) error { client := dockerCli.Client() ctx := context.Background() service, _, err := client.ServiceInspectWithRaw(ctx, serviceID) if err != nil { return err } serviceMode := &service.Spec.Mode if serviceMode.Replicated == nil { return fmt.Errorf("scale can only be used with replicated mode") } serviceMode.Replicated.Replicas = &scale response, err := client.ServiceUpdate(ctx, service.ID, service.Version, service.Spec, types.ServiceUpdateOptions{}) if err != nil { return err } for _, warning := range response.Warnings { fmt.Fprintln(dockerCli.Err(), warning) } fmt.Fprintf(dockerCli.Out(), "%s scaled to %d\n", serviceID, scale) return nil }
func runLogs(dockerCli *command.DockerCli, opts *logsOptions) error { ctx := context.Background() c, err := dockerCli.Client().ContainerInspect(ctx, opts.container) if err != nil { return err } if !validDrivers[c.HostConfig.LogConfig.Type] { return fmt.Errorf("\"logs\" command is supported only for \"json-file\" and \"journald\" logging drivers (got: %s)", c.HostConfig.LogConfig.Type) } options := types.ContainerLogsOptions{ ShowStdout: true, ShowStderr: true, Since: opts.since, Timestamps: opts.timestamps, Follow: opts.follow, Tail: opts.tail, Details: opts.details, } responseBody, err := dockerCli.Client().ContainerLogs(ctx, opts.container, options) if err != nil { return err } defer responseBody.Close() if c.Config.Tty { _, err = io.Copy(dockerCli.Out(), responseBody) } else { _, err = stdcopy.StdCopy(dockerCli.Out(), dockerCli.Err(), responseBody) } return err }
func newDockerCommand(dockerCli *command.DockerCli) *cobra.Command { opts := cliflags.NewClientOptions() var flags *pflag.FlagSet cmd := &cobra.Command{ Use: "docker [OPTIONS] COMMAND [ARG...]", Short: "A self-sufficient runtime for containers", SilenceUsage: true, SilenceErrors: true, TraverseChildren: true, Args: noArgs, RunE: func(cmd *cobra.Command, args []string) error { if opts.Version { showVersion() return nil } cmd.SetOutput(dockerCli.Err()) cmd.HelpFunc()(cmd, args) return nil }, PersistentPreRunE: func(cmd *cobra.Command, args []string) error { // flags must be the top-level command flags, not cmd.Flags() opts.Common.SetDefaultOptions(flags) dockerPreRun(opts) return dockerCli.Initialize(opts) }, } cli.SetupRootCommand(cmd) cmd.SetHelpFunc(func(ccmd *cobra.Command, args []string) { var err error if dockerCli.Client() == nil { // flags must be the top-level command flags, not cmd.Flags() opts.Common.SetDefaultOptions(flags) dockerPreRun(opts) err = dockerCli.Initialize(opts) } if err != nil || !dockerCli.HasExperimental() { hideExperimentalFeatures(ccmd) } if err := ccmd.Help(); err != nil { ccmd.Println(err) } }) flags = cmd.Flags() flags.BoolVarP(&opts.Version, "version", "v", false, "Print version information and quit") flags.StringVar(&opts.ConfigDir, "config", cliconfig.ConfigDir(), "Location of client config files") opts.Common.InstallFlags(flags) cmd.SetOutput(dockerCli.Out()) cmd.AddCommand(newDaemonCommand()) commands.AddCommands(cmd, dockerCli) return cmd }
func runCreate(dockerCli *command.DockerCli, flags *pflag.FlagSet, opts *createOptions, copts *runconfigopts.ContainerOptions) error { config, hostConfig, networkingConfig, err := runconfigopts.Parse(flags, copts) if err != nil { reportError(dockerCli.Err(), "create", err.Error(), true) return cli.StatusError{StatusCode: 125} } response, err := createContainer(context.Background(), dockerCli, config, hostConfig, networkingConfig, hostConfig.ContainerIDFile, opts.name) if err != nil { return err } fmt.Fprintf(dockerCli.Out(), "%s\n", response.ID) return nil }
func deployCompose(ctx context.Context, dockerCli *command.DockerCli, opts deployOptions) error { configDetails, err := getConfigDetails(opts) if err != nil { return err } config, err := loader.Load(configDetails) if err != nil { if fpe, ok := err.(*loader.ForbiddenPropertiesError); ok { return fmt.Errorf("Compose file contains unsupported options:\n\n%s\n", propertyWarnings(fpe.Properties)) } return err } unsupportedProperties := loader.GetUnsupportedProperties(configDetails) if len(unsupportedProperties) > 0 { fmt.Fprintf(dockerCli.Err(), "Ignoring unsupported options: %s\n\n", strings.Join(unsupportedProperties, ", ")) } deprecatedProperties := loader.GetDeprecatedProperties(configDetails) if len(deprecatedProperties) > 0 { fmt.Fprintf(dockerCli.Err(), "Ignoring deprecated options:\n\n%s\n\n", propertyWarnings(deprecatedProperties)) } if err := checkDaemonIsSwarmManager(ctx, dockerCli); err != nil { return err } namespace := convert.NewNamespace(opts.namespace) serviceNetworks := getServicesDeclaredNetworks(config.Services) networks, externalNetworks := convert.Networks(namespace, config.Networks, serviceNetworks) if err := validateExternalNetworks(ctx, dockerCli, externalNetworks); err != nil { return err } if err := createNetworks(ctx, dockerCli, namespace, networks); err != nil { return err } services, err := convert.Services(namespace, config) if err != nil { return err } return deployServices(ctx, dockerCli, services, namespace, opts.sendRegistryAuth) }
// NewSystemCommand returns a cobra command for `system` subcommands func NewSystemCommand(dockerCli *command.DockerCli) *cobra.Command { cmd := &cobra.Command{ Use: "system", Short: "Manage Docker", Args: cli.NoArgs, Run: func(cmd *cobra.Command, args []string) { fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString()) }, } cmd.AddCommand( NewEventsCommand(dockerCli), NewInfoCommand(dockerCli), ) return cmd }
func runCreate(dockerCli *command.DockerCli, opts *serviceOptions) error { apiClient := dockerCli.Client() createOpts := types.ServiceCreateOptions{} service, err := opts.ToService() if err != nil { return err } specifiedSecrets := opts.secrets.Value() if len(specifiedSecrets) > 0 { // parse and validate secrets secrets, err := parseSecrets(apiClient, specifiedSecrets) if err != nil { return err } service.TaskTemplate.ContainerSpec.Secrets = secrets } ctx := context.Background() if err := resolveServiceImageDigest(dockerCli, &service); err != nil { return err } // only send auth if flag was set if opts.registryAuth { // Retrieve encoded auth token from the image reference encodedAuth, err := command.RetrieveAuthTokenFromImage(ctx, dockerCli, opts.image) if err != nil { return err } createOpts.EncodedRegistryAuth = encodedAuth } response, err := apiClient.ServiceCreate(ctx, service, createOpts) if err != nil { return err } for _, warning := range response.Warnings { fmt.Fprintln(dockerCli.Err(), warning) } fmt.Fprintf(dockerCli.Out(), "%s\n", response.ID) return nil }
// NewCheckpointCommand returns the `checkpoint` subcommand (only in experimental) func NewCheckpointCommand(dockerCli *command.DockerCli) *cobra.Command { cmd := &cobra.Command{ Use: "checkpoint", Short: "Manage checkpoints", Args: cli.NoArgs, Run: func(cmd *cobra.Command, args []string) { fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString()) }, } cmd.AddCommand( newCreateCommand(dockerCli), newListCommand(dockerCli), newRemoveCommand(dockerCli), ) return cmd }
func startContainersWithoutAttachments(dockerCli *command.DockerCli, ctx context.Context, containers []string) error { var failedContainers []string for _, container := range containers { if err := dockerCli.Client().ContainerStart(ctx, container, types.ContainerStartOptions{}); err != nil { fmt.Fprintf(dockerCli.Err(), "%s\n", err) failedContainers = append(failedContainers, container) } else { fmt.Fprintf(dockerCli.Out(), "%s\n", container) } } if len(failedContainers) > 0 { return fmt.Errorf("Error: failed to start containers: %v", strings.Join(failedContainers, ", ")) } return nil }
func runRename(dockerCli *command.DockerCli, opts *renameOptions) error { ctx := context.Background() oldName := strings.TrimSpace(opts.oldName) newName := strings.TrimSpace(opts.newName) if oldName == "" || newName == "" { return errors.New("Error: Neither old nor new names may be empty") } if err := dockerCli.Client().ContainerRename(ctx, oldName, newName); err != nil { fmt.Fprintln(dockerCli.Err(), err) return fmt.Errorf("Error: failed to rename container named %s", oldName) } return nil }
// NewSecretCommand returns a cobra command for `secret` subcommands func NewSecretCommand(dockerCli *command.DockerCli) *cobra.Command { cmd := &cobra.Command{ Use: "secret", Short: "Manage Docker secrets", Args: cli.NoArgs, Run: func(cmd *cobra.Command, args []string) { fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString()) }, } cmd.AddCommand( newSecretListCommand(dockerCli), newSecretCreateCommand(dockerCli), newSecretInspectCommand(dockerCli), newSecretRemoveCommand(dockerCli), ) return cmd }
func runLogout(dockerCli *command.DockerCli, serverAddress string) error { ctx := context.Background() var isDefaultRegistry bool if serverAddress == "" { serverAddress = dockerCli.ElectAuthServer(ctx) isDefaultRegistry = true } var ( loggedIn bool regsToLogout []string hostnameAddress = serverAddress regsToTry = []string{serverAddress} ) if !isDefaultRegistry { hostnameAddress = registry.ConvertToHostname(serverAddress) // the tries below are kept for backward compatibily where a user could have // saved the registry in one of the following format. regsToTry = append(regsToTry, hostnameAddress, "http://"+hostnameAddress, "https://"+hostnameAddress) } // check if we're logged in based on the records in the config file // which means it couldn't have user/pass cause they may be in the creds store for _, s := range regsToTry { if _, ok := dockerCli.ConfigFile().AuthConfigs[s]; ok { loggedIn = true regsToLogout = append(regsToLogout, s) } } if !loggedIn { fmt.Fprintf(dockerCli.Out(), "Not logged in to %s\n", hostnameAddress) return nil } fmt.Fprintf(dockerCli.Out(), "Removing login credentials for %s\n", hostnameAddress) for _, r := range regsToLogout { if err := command.EraseCredentials(dockerCli.ConfigFile(), r); err != nil { fmt.Fprintf(dockerCli.Err(), "WARNING: could not erase credentials: %v\n", err) } } return nil }
// NewSwarmCommand returns a cobra command for `swarm` subcommands func NewSwarmCommand(dockerCli *command.DockerCli) *cobra.Command { cmd := &cobra.Command{ Use: "swarm", Short: "Manage Docker Swarm", Args: cli.NoArgs, Run: func(cmd *cobra.Command, args []string) { fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString()) }, } cmd.AddCommand( newInitCommand(dockerCli), newJoinCommand(dockerCli), newJoinTokenCommand(dockerCli), newUpdateCommand(dockerCli), newLeaveCommand(dockerCli), ) return cmd }
// NewStackCommand returns a cobra command for `stack` subcommands func NewStackCommand(dockerCli *command.DockerCli) *cobra.Command { cmd := &cobra.Command{ Use: "stack", Short: "Manage Docker stacks", Args: cli.NoArgs, Run: func(cmd *cobra.Command, args []string) { fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString()) }, } cmd.AddCommand( newConfigCommand(dockerCli), newDeployCommand(dockerCli), newRemoveCommand(dockerCli), newServicesCommand(dockerCli), newPsCommand(dockerCli), ) return cmd }
// NewVolumeCommand returns a cobra command for `volume` subcommands func NewVolumeCommand(dockerCli *command.DockerCli) *cobra.Command { cmd := &cobra.Command{ Use: "volume COMMAND", Short: "Manage volumes", Long: volumeDescription, Args: cli.NoArgs, Run: func(cmd *cobra.Command, args []string) { fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString()) }, } cmd.AddCommand( newCreateCommand(dockerCli), newInspectCommand(dockerCli), newListCommand(dockerCli), newRemoveCommand(dockerCli), ) return cmd }
// NewCheckpointCommand returns the `checkpoint` subcommand (only in experimental) func NewCheckpointCommand(dockerCli *command.DockerCli) *cobra.Command { cmd := &cobra.Command{ Use: "checkpoint", Short: "Manage checkpoints", Args: cli.NoArgs, Run: func(cmd *cobra.Command, args []string) { cmd.SetOutput(dockerCli.Err()) cmd.HelpFunc()(cmd, args) }, Tags: map[string]string{"experimental": "", "version": "1.25"}, } cmd.AddCommand( newCreateCommand(dockerCli), newListCommand(dockerCli), newRemoveCommand(dockerCli), ) return cmd }
func runRemove(dockerCli *command.DockerCli, opts *removeOptions) error { client := dockerCli.Client() ctx := context.Background() status := 0 for _, name := range opts.volumes { if err := client.VolumeRemove(ctx, name, opts.force); err != nil { fmt.Fprintf(dockerCli.Err(), "%s\n", err) status = 1 continue } fmt.Fprintf(dockerCli.Out(), "%s\n", name) } if status != 0 { return cli.StatusError{StatusCode: status} } return nil }
// NewSystemCommand returns a cobra command for `system` subcommands func NewSystemCommand(dockerCli *command.DockerCli) *cobra.Command { cmd := &cobra.Command{ Use: "system", Short: "Manage Docker", Args: cli.NoArgs, Run: func(cmd *cobra.Command, args []string) { cmd.SetOutput(dockerCli.Err()) cmd.HelpFunc()(cmd, args) }, } cmd.AddCommand( NewEventsCommand(dockerCli), NewInfoCommand(dockerCli), NewDiskUsageCommand(dockerCli), NewPruneCommand(dockerCli), ) return cmd }
// NewNetworkCommand returns a cobra command for `network` subcommands func NewNetworkCommand(dockerCli *command.DockerCli) *cobra.Command { cmd := &cobra.Command{ Use: "network", Short: "Manage Docker networks", Args: cli.NoArgs, Run: func(cmd *cobra.Command, args []string) { fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString()) }, } cmd.AddCommand( newConnectCommand(dockerCli), newCreateCommand(dockerCli), newDisconnectCommand(dockerCli), newInspectCommand(dockerCli), newListCommand(dockerCli), newRemoveCommand(dockerCli), ) return cmd }
// NewNodeCommand returns a cobra command for `node` subcommands func NewNodeCommand(dockerCli *command.DockerCli) *cobra.Command { cmd := &cobra.Command{ Use: "node", Short: "Manage Docker Swarm nodes", Args: cli.NoArgs, Run: func(cmd *cobra.Command, args []string) { fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString()) }, } cmd.AddCommand( newDemoteCommand(dockerCli), newInspectCommand(dockerCli), newListCommand(dockerCli), newPromoteCommand(dockerCli), newRemoveCommand(dockerCli), newPsCommand(dockerCli), newUpdateCommand(dockerCli), ) return cmd }
// NewServiceCommand returns a cobra command for `service` subcommands func NewServiceCommand(dockerCli *command.DockerCli) *cobra.Command { cmd := &cobra.Command{ Use: "service", Short: "Manage services", Args: cli.NoArgs, Run: func(cmd *cobra.Command, args []string) { fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString()) }, } cmd.AddCommand( newCreateCommand(dockerCli), newInspectCommand(dockerCli), newPsCommand(dockerCli), newListCommand(dockerCli), newRemoveCommand(dockerCli), newScaleCommand(dockerCli), newUpdateCommand(dockerCli), ) return cmd }
// NewVolumeCommand returns a cobra command for `volume` subcommands func NewVolumeCommand(dockerCli *command.DockerCli) *cobra.Command { cmd := &cobra.Command{ Use: "volume COMMAND", Short: "Manage volumes", Long: volumeDescription, Args: cli.NoArgs, Run: func(cmd *cobra.Command, args []string) { cmd.SetOutput(dockerCli.Err()) cmd.HelpFunc()(cmd, args) }, } cmd.AddCommand( newCreateCommand(dockerCli), newInspectCommand(dockerCli), newListCommand(dockerCli), newRemoveCommand(dockerCli), NewPruneCommand(dockerCli), ) return cmd }
// NewStackCommand returns a cobra command for `stack` subcommands func NewStackCommand(dockerCli *command.DockerCli) *cobra.Command { cmd := &cobra.Command{ Use: "stack", Short: "Manage Docker stacks", Args: cli.NoArgs, Run: func(cmd *cobra.Command, args []string) { cmd.SetOutput(dockerCli.Err()) cmd.HelpFunc()(cmd, args) }, Tags: map[string]string{"experimental": "", "version": "1.25"}, } cmd.AddCommand( newDeployCommand(dockerCli), newListCommand(dockerCli), newRemoveCommand(dockerCli), newServicesCommand(dockerCli), newPsCommand(dockerCli), ) return cmd }