diff --git a/api/server/router/container/backend.go b/api/server/router/container/backend.go index 145a1b7424..bbac65bdce 100644 --- a/api/server/router/container/backend.go +++ b/api/server/router/container/backend.go @@ -4,11 +4,11 @@ import ( "io" "time" + "github.com/docker/docker/api/types/backend" "github.com/docker/docker/daemon/exec" "github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/version" "github.com/docker/engine-api/types" - "github.com/docker/engine-api/types/backend" "github.com/docker/engine-api/types/container" ) @@ -55,7 +55,7 @@ type monitorBackend interface { ContainerStats(name string, config *backend.ContainerStatsConfig) error ContainerTop(name string, psArgs string) (*types.ContainerProcessList, error) - Containers(config *backend.ContainersConfig) ([]*types.Container, error) + Containers(config *types.ContainerListOptions) ([]*types.Container, error) } // attachBackend includes function to implement to provide container attaching functionality. diff --git a/api/server/router/container/container_routes.go b/api/server/router/container/container_routes.go index cd429e1d72..4e485a8c63 100644 --- a/api/server/router/container/container_routes.go +++ b/api/server/router/container/container_routes.go @@ -13,6 +13,7 @@ import ( "github.com/Sirupsen/logrus" "github.com/docker/distribution/registry/api/errcode" "github.com/docker/docker/api/server/httputils" + "github.com/docker/docker/api/types/backend" derr "github.com/docker/docker/errors" "github.com/docker/docker/pkg/ioutils" "github.com/docker/docker/pkg/signal" @@ -20,9 +21,8 @@ import ( "github.com/docker/docker/runconfig" "github.com/docker/docker/utils" "github.com/docker/engine-api/types" - "github.com/docker/engine-api/types/backend" "github.com/docker/engine-api/types/container" - timetypes "github.com/docker/engine-api/types/time" + "github.com/docker/engine-api/types/filters" "golang.org/x/net/context" "golang.org/x/net/websocket" ) @@ -31,13 +31,17 @@ func (s *containerRouter) getContainersJSON(ctx context.Context, w http.Response if err := httputils.ParseForm(r); err != nil { return err } + filter, err := filters.FromParam(r.Form.Get("filters")) + if err != nil { + return err + } - config := &backend.ContainersConfig{ - All: httputils.BoolValue(r, "all"), - Size: httputils.BoolValue(r, "size"), - Since: r.Form.Get("since"), - Before: r.Form.Get("before"), - Filters: r.Form.Get("filters"), + config := &types.ContainerListOptions{ + All: httputils.BoolValue(r, "all"), + Size: httputils.BoolValue(r, "size"), + Since: r.Form.Get("since"), + Before: r.Form.Get("before"), + Filter: filter, } if tmpLimit := r.Form.Get("limit"); tmpLimit != "" { @@ -102,15 +106,6 @@ func (s *containerRouter) getContainersLogs(ctx context.Context, w http.Response return fmt.Errorf("Bad parameters: you must choose at least one stream") } - var since time.Time - if r.Form.Get("since") != "" { - s, n, err := timetypes.ParseTimestamps(r.Form.Get("since"), 0) - if err != nil { - return err - } - since = time.Unix(s, n) - } - var closeNotifier <-chan bool if notifier, ok := w.(http.CloseNotifier); ok { closeNotifier = notifier.CloseNotify() @@ -134,14 +129,16 @@ func (s *containerRouter) getContainersLogs(ctx context.Context, w http.Response defer output.Close() logsConfig := &backend.ContainerLogsConfig{ - Follow: httputils.BoolValue(r, "follow"), - Timestamps: httputils.BoolValue(r, "timestamps"), - Since: since, - Tail: r.Form.Get("tail"), - UseStdout: stdout, - UseStderr: stderr, - OutStream: output, - Stop: closeNotifier, + ContainerLogsOptions: types.ContainerLogsOptions{ + Follow: httputils.BoolValue(r, "follow"), + Timestamps: httputils.BoolValue(r, "timestamps"), + Since: r.Form.Get("since"), + Tail: r.Form.Get("tail"), + ShowStdout: stdout, + ShowStderr: stderr, + }, + OutStream: output, + Stop: closeNotifier, } if err := s.backend.ContainerLogs(containerName, logsConfig); err != nil { diff --git a/api/server/router/image/backend.go b/api/server/router/image/backend.go index e312307d93..73e8216025 100644 --- a/api/server/router/image/backend.go +++ b/api/server/router/image/backend.go @@ -32,7 +32,7 @@ type imageBackend interface { } type importExportBackend interface { - LoadImage(inTar io.ReadCloser, outStream io.Writer) error + LoadImage(inTar io.ReadCloser, outStream io.Writer, quiet bool) error ImportImage(src string, newRef reference.Named, msg string, inConfig io.ReadCloser, outStream io.Writer, config *container.Config) error ExportImage(names []string, outStream io.Writer) error } diff --git a/api/server/router/image/image_routes.go b/api/server/router/image/image_routes.go index bf95d5592f..c84317aec8 100644 --- a/api/server/router/image/image_routes.go +++ b/api/server/router/image/image_routes.go @@ -269,7 +269,7 @@ func (s *imageRouter) getImagesGet(ctx context.Context, w http.ResponseWriter, r return nil } -func (s *router) postImagesLoad(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { +func (s *imageRouter) postImagesLoad(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { if err := httputils.ParseForm(r); err != nil { return err } diff --git a/api/types/backend/backend.go b/api/types/backend/backend.go new file mode 100644 index 0000000000..517887014c --- /dev/null +++ b/api/types/backend/backend.go @@ -0,0 +1,51 @@ +// Package backend includes types to send information to server backends. +// TODO(calavera): This package is pending of extraction to engine-api +// when the server package is clean of daemon dependencies. +package backend + +import ( + "io" + "net/http" + + "github.com/docker/engine-api/types" +) + +// ContainerAttachWithLogsConfig holds the streams to use when connecting to a container to view logs. +type ContainerAttachWithLogsConfig struct { + Hijacker http.Hijacker + Upgrade bool + UseStdin bool + UseStdout bool + UseStderr bool + Logs bool + Stream bool + DetachKeys []byte +} + +// ContainerWsAttachWithLogsConfig attach with websockets, since all +// stream data is delegated to the websocket to handle there. +type ContainerWsAttachWithLogsConfig struct { + InStream io.ReadCloser // Reader to attach to stdin of container + OutStream io.Writer // Writer to attach to stdout of container + ErrStream io.Writer // Writer to attach to stderr of container + Logs bool // If true return log output + Stream bool // If true return stream output + DetachKeys []byte +} + +// ContainerLogsConfig holds configs for logging operations. Exists +// for users of the backend to to pass it a logging configuration. +type ContainerLogsConfig struct { + types.ContainerLogsOptions + OutStream io.Writer + Stop <-chan bool +} + +// ContainerStatsConfig holds information for configuring the runtime +// behavior of a backend.ContainerStats() call. +type ContainerStatsConfig struct { + Stream bool + OutStream io.Writer + Stop <-chan bool + Version string +} diff --git a/daemon/attach.go b/daemon/attach.go index aabc77082a..4faa460e37 100644 --- a/daemon/attach.go +++ b/daemon/attach.go @@ -6,11 +6,11 @@ import ( "time" "github.com/Sirupsen/logrus" + "github.com/docker/docker/api/types/backend" "github.com/docker/docker/container" "github.com/docker/docker/daemon/logger" derr "github.com/docker/docker/errors" "github.com/docker/docker/pkg/stdcopy" - "github.com/docker/engine-api/types/backend" ) // ContainerAttachWithLogs attaches to logs according to the config passed in. See ContainerAttachWithLogsConfig. @@ -81,7 +81,7 @@ func (daemon *Daemon) ContainerWsAttachWithLogs(prefixOrName string, c *backend. // ContainerAttachOnBuild attaches streams to the container cID. If stream is true, it streams the output. func (daemon *Daemon) ContainerAttachOnBuild(cID string, stdin io.ReadCloser, stdout, stderr io.Writer, stream bool) error { - return daemon.ContainerWsAttachWithLogs(cID, &ContainerWsAttachWithLogsConfig{ + return daemon.ContainerWsAttachWithLogs(cID, &backend.ContainerWsAttachWithLogsConfig{ InStream: stdin, OutStream: stdout, ErrStream: stderr, diff --git a/daemon/list.go b/daemon/list.go index 5761ca40c5..c674225324 100644 --- a/daemon/list.go +++ b/daemon/list.go @@ -10,7 +10,6 @@ import ( "github.com/docker/docker/container" "github.com/docker/docker/image" "github.com/docker/engine-api/types" - "github.com/docker/engine-api/types/backend" "github.com/docker/engine-api/types/filters" networktypes "github.com/docker/engine-api/types/network" "github.com/docker/go-connections/nat" @@ -45,7 +44,7 @@ func (daemon *Daemon) List() []*container.Container { } // listContext is the daemon generated filtering to iterate over containers. -// This is created based on the user specification from backend.ContainersConfig. +// This is created based on the user specification from types.ContainerListOptions. type listContext struct { // idx is the container iteration index for this context idx int @@ -65,17 +64,17 @@ type listContext struct { // sinceFilter is a filter to stop the filtering when the iterator arrive to the given container // this is used for --filter=since= and --since=, the latter is deprecated. sinceFilter *container.Container - // ContainersConfig is the filters set by the user - *backend.ContainersConfig + // ContainerListOptions is the filters set by the user + *types.ContainerListOptions } // Containers returns the list of containers to show given the user's filtering. -func (daemon *Daemon) Containers(config *backend.ContainersConfig) ([]*types.Container, error) { +func (daemon *Daemon) Containers(config *types.ContainerListOptions) ([]*types.Container, error) { return daemon.reduceContainers(config, daemon.transformContainer) } // reduceContainers parses the user's filtering options and generates the list of containers to return based on a reducer. -func (daemon *Daemon) reduceContainers(config *backend.ContainersConfig, reducer containerReducer) ([]*types.Container, error) { +func (daemon *Daemon) reduceContainers(config *types.ContainerListOptions, reducer containerReducer) ([]*types.Container, error) { containers := []*types.Container{} ctx, err := daemon.foldFilter(config) @@ -118,14 +117,11 @@ func (daemon *Daemon) reducePsContainer(container *container.Container, ctx *lis } // foldFilter generates the container filter based on the user's filtering options. -func (daemon *Daemon) foldFilter(config *backend.ContainersConfig) (*listContext, error) { - psFilters, err := filters.FromParam(config.Filters) - if err != nil { - return nil, err - } +func (daemon *Daemon) foldFilter(config *types.ContainerListOptions) (*listContext, error) { + psFilters := config.Filter var filtExited []int - err = psFilters.WalkValues("exited", func(value string) error { + err := psFilters.WalkValues("exited", func(value string) error { code, err := strconv.Atoi(value) if err != nil { return err @@ -201,14 +197,14 @@ func (daemon *Daemon) foldFilter(config *backend.ContainersConfig) (*listContext } return &listContext{ - filters: psFilters, - ancestorFilter: ancestorFilter, - images: imagesFilter, - exitAllowed: filtExited, - beforeFilter: beforeContFilter, - sinceFilter: sinceContFilter, - ContainersConfig: config, - names: daemon.nameIndex.GetAll(), + filters: psFilters, + ancestorFilter: ancestorFilter, + images: imagesFilter, + exitAllowed: filtExited, + beforeFilter: beforeContFilter, + sinceFilter: sinceContFilter, + ContainerListOptions: config, + names: daemon.nameIndex.GetAll(), }, nil } diff --git a/daemon/logs.go b/daemon/logs.go index bb6586f272..23f9e321d2 100644 --- a/daemon/logs.go +++ b/daemon/logs.go @@ -3,14 +3,16 @@ package daemon import ( "io" "strconv" + "time" "github.com/Sirupsen/logrus" + "github.com/docker/docker/api/types/backend" "github.com/docker/docker/container" "github.com/docker/docker/daemon/logger" "github.com/docker/docker/daemon/logger/jsonfilelog" derr "github.com/docker/docker/errors" "github.com/docker/docker/pkg/stdcopy" - "github.com/docker/engine-api/types/backend" + timetypes "github.com/docker/engine-api/types/time" ) // ContainerLogs hooks up a container's stdout and stderr streams @@ -21,7 +23,7 @@ func (daemon *Daemon) ContainerLogs(containerName string, config *backend.Contai return derr.ErrorCodeNoSuchContainer.WithArgs(containerName) } - if !(config.UseStdout || config.UseStderr) { + if !(config.ShowStdout || config.ShowStderr) { return derr.ErrorCodeNeedStream } @@ -49,8 +51,17 @@ func (daemon *Daemon) ContainerLogs(containerName string, config *backend.Contai } logrus.Debug("logs: begin stream") + + var since time.Time + if config.Since != "" { + s, n, err := timetypes.ParseTimestamps(config.Since, 0) + if err != nil { + return err + } + since = time.Unix(s, n) + } readConfig := logger.ReadConfig{ - Since: config.Since, + Since: since, Tail: tailLines, Follow: follow, } @@ -73,10 +84,10 @@ func (daemon *Daemon) ContainerLogs(containerName string, config *backend.Contai if config.Timestamps { logLine = append([]byte(msg.Timestamp.Format(logger.TimeFormat)+" "), logLine...) } - if msg.Source == "stdout" && config.UseStdout { + if msg.Source == "stdout" && config.ShowStdout { outStream.Write(logLine) } - if msg.Source == "stderr" && config.UseStderr { + if msg.Source == "stderr" && config.ShowStderr { errStream.Write(logLine) } } diff --git a/daemon/stats.go b/daemon/stats.go index a1e41283d8..65933a4f00 100644 --- a/daemon/stats.go +++ b/daemon/stats.go @@ -5,10 +5,10 @@ import ( "errors" "runtime" + "github.com/docker/docker/api/types/backend" "github.com/docker/docker/daemon/execdriver" "github.com/docker/docker/pkg/version" "github.com/docker/engine-api/types" - "github.com/docker/engine-api/types/backend" "github.com/docker/engine-api/types/versions/v1p20" )