Fixes hacks from progressreader refactor

related to #10959

Signed-off-by: bobby abbott <ttobbaybbob@gmail.com>
This commit is contained in:
bobby abbott 2015-03-17 19:18:41 -07:00
parent 667452ec63
commit 0cd6c05d81
18 changed files with 77 additions and 94 deletions

View File

@ -22,9 +22,11 @@ import (
"github.com/docker/docker/graph" "github.com/docker/docker/graph"
"github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/archive"
"github.com/docker/docker/pkg/fileutils" "github.com/docker/docker/pkg/fileutils"
"github.com/docker/docker/pkg/jsonmessage"
flag "github.com/docker/docker/pkg/mflag" flag "github.com/docker/docker/pkg/mflag"
"github.com/docker/docker/pkg/parsers" "github.com/docker/docker/pkg/parsers"
"github.com/docker/docker/pkg/progressreader" "github.com/docker/docker/pkg/progressreader"
"github.com/docker/docker/pkg/streamformatter"
"github.com/docker/docker/pkg/symlink" "github.com/docker/docker/pkg/symlink"
"github.com/docker/docker/pkg/units" "github.com/docker/docker/pkg/units"
"github.com/docker/docker/pkg/urlutil" "github.com/docker/docker/pkg/urlutil"
@ -198,7 +200,7 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
// Setup an upload progress bar // Setup an upload progress bar
// FIXME: ProgressReader shouldn't be this annoying to use // FIXME: ProgressReader shouldn't be this annoying to use
if context != nil { if context != nil {
sf := utils.NewStreamFormatter(false) sf := streamformatter.NewStreamFormatter(false)
body = progressreader.New(progressreader.Config{ body = progressreader.New(progressreader.Config{
In: context, In: context,
Out: cli.out, Out: cli.out,
@ -291,7 +293,7 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
headers.Set("Content-Type", "application/tar") headers.Set("Content-Type", "application/tar")
} }
err = cli.stream("POST", fmt.Sprintf("/build?%s", v.Encode()), body, cli.out, headers) err = cli.stream("POST", fmt.Sprintf("/build?%s", v.Encode()), body, cli.out, headers)
if jerr, ok := err.(*utils.JSONError); ok { if jerr, ok := err.(*jsonmessage.JSONError); ok {
// If no error code is set, default to 1 // If no error code is set, default to 1
if jerr.Code == 0 { if jerr.Code == 0 {
jerr.Code = 1 jerr.Code = 1

View File

@ -19,11 +19,11 @@ import (
"github.com/docker/docker/api" "github.com/docker/docker/api"
"github.com/docker/docker/autogen/dockerversion" "github.com/docker/docker/autogen/dockerversion"
"github.com/docker/docker/engine" "github.com/docker/docker/engine"
"github.com/docker/docker/pkg/jsonmessage"
"github.com/docker/docker/pkg/signal" "github.com/docker/docker/pkg/signal"
"github.com/docker/docker/pkg/stdcopy" "github.com/docker/docker/pkg/stdcopy"
"github.com/docker/docker/pkg/term" "github.com/docker/docker/pkg/term"
"github.com/docker/docker/registry" "github.com/docker/docker/registry"
"github.com/docker/docker/utils"
) )
var ( var (
@ -164,7 +164,7 @@ func (cli *DockerCli) streamHelper(method, path string, setRawTerminal bool, in
} }
if api.MatchesContentType(resp.Header.Get("Content-Type"), "application/json") { if api.MatchesContentType(resp.Header.Get("Content-Type"), "application/json") {
return utils.DisplayJSONMessagesStream(resp.Body, stdout, cli.outFd, cli.isTerminalOut) return jsonmessage.DisplayJSONMessagesStream(resp.Body, stdout, cli.outFd, cli.isTerminalOut)
} }
if stdout != nil || stderr != nil { if stdout != nil || stderr != nil {
// When TTY is ON, use regular copy // When TTY is ON, use regular copy

View File

@ -32,6 +32,7 @@ import (
"github.com/docker/docker/pkg/listenbuffer" "github.com/docker/docker/pkg/listenbuffer"
"github.com/docker/docker/pkg/parsers" "github.com/docker/docker/pkg/parsers"
"github.com/docker/docker/pkg/stdcopy" "github.com/docker/docker/pkg/stdcopy"
"github.com/docker/docker/pkg/streamformatter"
"github.com/docker/docker/pkg/version" "github.com/docker/docker/pkg/version"
"github.com/docker/docker/registry" "github.com/docker/docker/registry"
"github.com/docker/docker/utils" "github.com/docker/docker/utils"
@ -595,7 +596,7 @@ func postImagesCreate(eng *engine.Engine, version version.Version, w http.Respon
if !job.Stdout.Used() { if !job.Stdout.Used() {
return err return err
} }
sf := utils.NewStreamFormatter(version.GreaterThan("1.0")) sf := streamformatter.NewStreamFormatter(version.GreaterThan("1.0"))
w.Write(sf.FormatError(err)) w.Write(sf.FormatError(err))
} }
@ -680,7 +681,7 @@ func postImagesPush(eng *engine.Engine, version version.Version, w http.Response
if !job.Stdout.Used() { if !job.Stdout.Used() {
return err return err
} }
sf := utils.NewStreamFormatter(version.GreaterThan("1.0")) sf := streamformatter.NewStreamFormatter(version.GreaterThan("1.0"))
w.Write(sf.FormatError(err)) w.Write(sf.FormatError(err))
} }
return nil return nil
@ -1107,7 +1108,7 @@ func postBuild(eng *engine.Engine, version version.Version, w http.ResponseWrite
if !job.Stdout.Used() { if !job.Stdout.Used() {
return err return err
} }
sf := utils.NewStreamFormatter(version.GreaterThanOrEqualTo("1.8")) sf := streamformatter.NewStreamFormatter(version.GreaterThanOrEqualTo("1.8"))
w.Write(sf.FormatError(err)) w.Write(sf.FormatError(err))
} }
return nil return nil

View File

@ -33,6 +33,7 @@ import (
"github.com/docker/docker/daemon" "github.com/docker/docker/daemon"
"github.com/docker/docker/engine" "github.com/docker/docker/engine"
"github.com/docker/docker/pkg/fileutils" "github.com/docker/docker/pkg/fileutils"
"github.com/docker/docker/pkg/streamformatter"
"github.com/docker/docker/pkg/stringid" "github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/pkg/symlink" "github.com/docker/docker/pkg/symlink"
"github.com/docker/docker/pkg/tarsum" "github.com/docker/docker/pkg/tarsum"
@ -105,7 +106,7 @@ type Builder struct {
// Deprecated, original writer used for ImagePull. To be removed. // Deprecated, original writer used for ImagePull. To be removed.
OutOld io.Writer OutOld io.Writer
StreamFormatter *utils.StreamFormatter StreamFormatter *streamformatter.StreamFormatter
Config *runconfig.Config // runconfig for cmd, run, entrypoint etc. Config *runconfig.Config // runconfig for cmd, run, entrypoint etc.

View File

@ -26,6 +26,7 @@ import (
"github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/archive"
"github.com/docker/docker/pkg/chrootarchive" "github.com/docker/docker/pkg/chrootarchive"
"github.com/docker/docker/pkg/ioutils" "github.com/docker/docker/pkg/ioutils"
"github.com/docker/docker/pkg/jsonmessage"
"github.com/docker/docker/pkg/parsers" "github.com/docker/docker/pkg/parsers"
"github.com/docker/docker/pkg/progressreader" "github.com/docker/docker/pkg/progressreader"
"github.com/docker/docker/pkg/stringid" "github.com/docker/docker/pkg/stringid"
@ -601,7 +602,7 @@ func (b *Builder) run(c *daemon.Container) error {
// Wait for it to finish // Wait for it to finish
if ret, _ := c.WaitStop(-1 * time.Second); ret != 0 { if ret, _ := c.WaitStop(-1 * time.Second); ret != 0 {
err := &utils.JSONError{ err := &jsonmessage.JSONError{
Message: fmt.Sprintf("The command %v returned a non-zero code: %d", b.Config.Cmd, ret), Message: fmt.Sprintf("The command %v returned a non-zero code: %d", b.Config.Cmd, ret),
Code: ret, Code: ret,
} }

View File

@ -17,6 +17,7 @@ import (
"github.com/docker/docker/graph" "github.com/docker/docker/graph"
"github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/archive"
"github.com/docker/docker/pkg/parsers" "github.com/docker/docker/pkg/parsers"
"github.com/docker/docker/pkg/streamformatter"
"github.com/docker/docker/pkg/urlutil" "github.com/docker/docker/pkg/urlutil"
"github.com/docker/docker/registry" "github.com/docker/docker/registry"
"github.com/docker/docker/runconfig" "github.com/docker/docker/runconfig"
@ -127,16 +128,16 @@ func (b *BuilderJob) CmdBuild(job *engine.Job) error {
} }
defer context.Close() defer context.Close()
sf := utils.NewStreamFormatter(job.GetenvBool("json")) sf := streamformatter.NewStreamFormatter(job.GetenvBool("json"))
builder := &Builder{ builder := &Builder{
Daemon: b.Daemon, Daemon: b.Daemon,
Engine: b.Engine, Engine: b.Engine,
OutStream: &utils.StdoutFormater{ OutStream: &streamformatter.StdoutFormater{
Writer: job.Stdout, Writer: job.Stdout,
StreamFormatter: sf, StreamFormatter: sf,
}, },
ErrStream: &utils.StderrFormater{ ErrStream: &streamformatter.StderrFormater{
Writer: job.Stdout, Writer: job.Stdout,
StreamFormatter: sf, StreamFormatter: sf,
}, },

View File

@ -10,23 +10,23 @@ import (
"time" "time"
"github.com/docker/docker/engine" "github.com/docker/docker/engine"
"github.com/docker/docker/pkg/jsonmessage"
"github.com/docker/docker/pkg/parsers/filters" "github.com/docker/docker/pkg/parsers/filters"
"github.com/docker/docker/utils"
) )
const eventsLimit = 64 const eventsLimit = 64
type listener chan<- *utils.JSONMessage type listener chan<- *jsonmessage.JSONMessage
type Events struct { type Events struct {
mu sync.RWMutex mu sync.RWMutex
events []*utils.JSONMessage events []*jsonmessage.JSONMessage
subscribers []listener subscribers []listener
} }
func New() *Events { func New() *Events {
return &Events{ return &Events{
events: make([]*utils.JSONMessage, 0, eventsLimit), events: make([]*jsonmessage.JSONMessage, 0, eventsLimit),
} }
} }
@ -63,7 +63,7 @@ func (e *Events) Get(job *engine.Job) error {
timeout.Stop() timeout.Stop()
} }
listener := make(chan *utils.JSONMessage) listener := make(chan *jsonmessage.JSONMessage)
e.subscribe(listener) e.subscribe(listener)
defer e.unsubscribe(listener) defer e.unsubscribe(listener)
@ -107,7 +107,7 @@ func (e *Events) SubscribersCount(job *engine.Job) error {
return nil return nil
} }
func writeEvent(job *engine.Job, event *utils.JSONMessage, eventFilters filters.Args) error { func writeEvent(job *engine.Job, event *jsonmessage.JSONMessage, eventFilters filters.Args) error {
isFiltered := func(field string, filter []string) bool { isFiltered := func(field string, filter []string) bool {
if len(filter) == 0 { if len(filter) == 0 {
return false return false
@ -170,7 +170,7 @@ func (e *Events) subscribersCount() int {
func (e *Events) log(action, id, from string) { func (e *Events) log(action, id, from string) {
e.mu.Lock() e.mu.Lock()
now := time.Now().UTC().Unix() now := time.Now().UTC().Unix()
jm := &utils.JSONMessage{Status: action, ID: id, From: from, Time: now} jm := &jsonmessage.JSONMessage{Status: action, ID: id, From: from, Time: now}
if len(e.events) == cap(e.events) { if len(e.events) == cap(e.events) {
// discard oldest event // discard oldest event
copy(e.events, e.events[1:]) copy(e.events, e.events[1:])

View File

@ -9,13 +9,13 @@ import (
"time" "time"
"github.com/docker/docker/engine" "github.com/docker/docker/engine"
"github.com/docker/docker/utils" "github.com/docker/docker/pkg/jsonmessage"
) )
func TestEventsPublish(t *testing.T) { func TestEventsPublish(t *testing.T) {
e := New() e := New()
l1 := make(chan *utils.JSONMessage) l1 := make(chan *jsonmessage.JSONMessage)
l2 := make(chan *utils.JSONMessage) l2 := make(chan *jsonmessage.JSONMessage)
e.subscribe(l1) e.subscribe(l1)
e.subscribe(l2) e.subscribe(l2)
count := e.subscribersCount() count := e.subscribersCount()
@ -61,7 +61,7 @@ func TestEventsPublish(t *testing.T) {
func TestEventsPublishTimeout(t *testing.T) { func TestEventsPublishTimeout(t *testing.T) {
e := New() e := New()
l := make(chan *utils.JSONMessage) l := make(chan *jsonmessage.JSONMessage)
e.subscribe(l) e.subscribe(l)
c := make(chan struct{}) c := make(chan struct{})
@ -108,9 +108,9 @@ func TestLogEvents(t *testing.T) {
} }
buf = bytes.NewBuffer(buf.Bytes()) buf = bytes.NewBuffer(buf.Bytes())
dec := json.NewDecoder(buf) dec := json.NewDecoder(buf)
var msgs []utils.JSONMessage var msgs []jsonmessage.JSONMessage
for { for {
var jm utils.JSONMessage var jm jsonmessage.JSONMessage
if err := dec.Decode(&jm); err != nil { if err := dec.Decode(&jm); err != nil {
if err == io.EOF { if err == io.EOF {
break break
@ -138,8 +138,8 @@ func TestEventsCountJob(t *testing.T) {
if err := e.Install(eng); err != nil { if err := e.Install(eng); err != nil {
t.Fatal(err) t.Fatal(err)
} }
l1 := make(chan *utils.JSONMessage) l1 := make(chan *jsonmessage.JSONMessage)
l2 := make(chan *utils.JSONMessage) l2 := make(chan *jsonmessage.JSONMessage)
e.subscribe(l1) e.subscribe(l1)
e.subscribe(l2) e.subscribe(l2)
job := eng.Job("subscribers_count") job := eng.Job("subscribers_count")

View File

@ -18,6 +18,7 @@ import (
"github.com/docker/docker/image" "github.com/docker/docker/image"
"github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/archive"
"github.com/docker/docker/pkg/progressreader" "github.com/docker/docker/pkg/progressreader"
"github.com/docker/docker/pkg/streamformatter"
"github.com/docker/docker/pkg/stringid" "github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/pkg/truncindex" "github.com/docker/docker/pkg/truncindex"
"github.com/docker/docker/runconfig" "github.com/docker/docker/runconfig"
@ -198,7 +199,7 @@ func (graph *Graph) Register(img *image.Image, layerData archive.ArchiveReader)
// The archive is stored on disk and will be automatically deleted as soon as has been read. // The archive is stored on disk and will be automatically deleted as soon as has been read.
// If output is not nil, a human-readable progress bar will be written to it. // If output is not nil, a human-readable progress bar will be written to it.
// FIXME: does this belong in Graph? How about MktempFile, let the caller use it for archives? // FIXME: does this belong in Graph? How about MktempFile, let the caller use it for archives?
func (graph *Graph) TempLayerArchive(id string, sf *utils.StreamFormatter, output io.Writer) (*archive.TempArchive, error) { func (graph *Graph) TempLayerArchive(id string, sf *streamformatter.StreamFormatter, output io.Writer) (*archive.TempArchive, error) {
image, err := graph.Get(id) image, err := graph.Get(id)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -11,6 +11,7 @@ import (
"github.com/docker/docker/engine" "github.com/docker/docker/engine"
"github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/archive"
"github.com/docker/docker/pkg/progressreader" "github.com/docker/docker/pkg/progressreader"
"github.com/docker/docker/pkg/streamformatter"
"github.com/docker/docker/runconfig" "github.com/docker/docker/runconfig"
"github.com/docker/docker/utils" "github.com/docker/docker/utils"
) )
@ -23,7 +24,7 @@ func (s *TagStore) CmdImport(job *engine.Job) error {
src = job.Args[0] src = job.Args[0]
repo = job.Args[1] repo = job.Args[1]
tag string tag string
sf = utils.NewStreamFormatter(job.GetenvBool("json")) sf = streamformatter.NewStreamFormatter(job.GetenvBool("json"))
archive archive.ArchiveReader archive archive.ArchiveReader
resp *http.Response resp *http.Response
stdoutBuffer = bytes.NewBuffer(nil) stdoutBuffer = bytes.NewBuffer(nil)

View File

@ -15,6 +15,7 @@ import (
"github.com/docker/docker/engine" "github.com/docker/docker/engine"
"github.com/docker/docker/image" "github.com/docker/docker/image"
"github.com/docker/docker/pkg/progressreader" "github.com/docker/docker/pkg/progressreader"
"github.com/docker/docker/pkg/streamformatter"
"github.com/docker/docker/pkg/stringid" "github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/registry" "github.com/docker/docker/registry"
"github.com/docker/docker/utils" "github.com/docker/docker/utils"
@ -28,7 +29,7 @@ func (s *TagStore) CmdPull(job *engine.Job) error {
var ( var (
localName = job.Args[0] localName = job.Args[0]
tag string tag string
sf = utils.NewStreamFormatter(job.GetenvBool("json")) sf = streamformatter.NewStreamFormatter(job.GetenvBool("json"))
authConfig = &registry.AuthConfig{} authConfig = &registry.AuthConfig{}
metaHeaders map[string][]string metaHeaders map[string][]string
) )
@ -107,7 +108,7 @@ func (s *TagStore) CmdPull(job *engine.Job) error {
return nil return nil
} }
func (s *TagStore) pullRepository(r *registry.Session, out io.Writer, repoInfo *registry.RepositoryInfo, askedTag string, sf *utils.StreamFormatter, parallel bool) error { func (s *TagStore) pullRepository(r *registry.Session, out io.Writer, repoInfo *registry.RepositoryInfo, askedTag string, sf *streamformatter.StreamFormatter, parallel bool) error {
out.Write(sf.FormatStatus("", "Pulling repository %s", repoInfo.CanonicalName)) out.Write(sf.FormatStatus("", "Pulling repository %s", repoInfo.CanonicalName))
repoData, err := r.GetRepositoryData(repoInfo.RemoteName) repoData, err := r.GetRepositoryData(repoInfo.RemoteName)
@ -265,7 +266,7 @@ func (s *TagStore) pullRepository(r *registry.Session, out io.Writer, repoInfo *
return nil return nil
} }
func (s *TagStore) pullImage(r *registry.Session, out io.Writer, imgID, endpoint string, token []string, sf *utils.StreamFormatter) (bool, error) { func (s *TagStore) pullImage(r *registry.Session, out io.Writer, imgID, endpoint string, token []string, sf *streamformatter.StreamFormatter) (bool, error) {
history, err := r.GetRemoteHistory(imgID, endpoint, token) history, err := r.GetRemoteHistory(imgID, endpoint, token)
if err != nil { if err != nil {
return false, err return false, err
@ -363,7 +364,7 @@ func (s *TagStore) pullImage(r *registry.Session, out io.Writer, imgID, endpoint
return layers_downloaded, nil return layers_downloaded, nil
} }
func WriteStatus(requestedTag string, out io.Writer, sf *utils.StreamFormatter, layers_downloaded bool) { func WriteStatus(requestedTag string, out io.Writer, sf *streamformatter.StreamFormatter, layers_downloaded bool) {
if layers_downloaded { if layers_downloaded {
out.Write(sf.FormatStatus("", "Status: Downloaded newer image for %s", requestedTag)) out.Write(sf.FormatStatus("", "Status: Downloaded newer image for %s", requestedTag))
} else { } else {
@ -382,7 +383,7 @@ type downloadInfo struct {
err chan error err chan error
} }
func (s *TagStore) pullV2Repository(eng *engine.Engine, r *registry.Session, out io.Writer, repoInfo *registry.RepositoryInfo, tag string, sf *utils.StreamFormatter, parallel bool) error { func (s *TagStore) pullV2Repository(eng *engine.Engine, r *registry.Session, out io.Writer, repoInfo *registry.RepositoryInfo, tag string, sf *streamformatter.StreamFormatter, parallel bool) error {
endpoint, err := r.V2RegistryEndpoint(repoInfo.Index) endpoint, err := r.V2RegistryEndpoint(repoInfo.Index)
if err != nil { if err != nil {
if repoInfo.Index.Official { if repoInfo.Index.Official {
@ -428,7 +429,7 @@ func (s *TagStore) pullV2Repository(eng *engine.Engine, r *registry.Session, out
return nil return nil
} }
func (s *TagStore) pullV2Tag(eng *engine.Engine, r *registry.Session, out io.Writer, endpoint *registry.Endpoint, repoInfo *registry.RepositoryInfo, tag string, sf *utils.StreamFormatter, parallel bool, auth *registry.RequestAuthorization) (bool, error) { func (s *TagStore) pullV2Tag(eng *engine.Engine, r *registry.Session, out io.Writer, endpoint *registry.Endpoint, repoInfo *registry.RepositoryInfo, tag string, sf *streamformatter.StreamFormatter, parallel bool, auth *registry.RequestAuthorization) (bool, error) {
log.Debugf("Pulling tag from V2 registry: %q", tag) log.Debugf("Pulling tag from V2 registry: %q", tag)
manifestBytes, manifestDigest, err := r.GetV2ImageManifest(endpoint, repoInfo.RemoteName, tag, auth) manifestBytes, manifestDigest, err := r.GetV2ImageManifest(endpoint, repoInfo.RemoteName, tag, auth)

View File

@ -17,6 +17,7 @@ import (
"github.com/docker/docker/engine" "github.com/docker/docker/engine"
"github.com/docker/docker/image" "github.com/docker/docker/image"
"github.com/docker/docker/pkg/progressreader" "github.com/docker/docker/pkg/progressreader"
"github.com/docker/docker/pkg/streamformatter"
"github.com/docker/docker/pkg/stringid" "github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/registry" "github.com/docker/docker/registry"
"github.com/docker/docker/runconfig" "github.com/docker/docker/runconfig"
@ -130,7 +131,7 @@ type imagePushData struct {
// lookupImageOnEndpoint checks the specified endpoint to see if an image exists // lookupImageOnEndpoint checks the specified endpoint to see if an image exists
// and if it is absent then it sends the image id to the channel to be pushed. // and if it is absent then it sends the image id to the channel to be pushed.
func lookupImageOnEndpoint(wg *sync.WaitGroup, r *registry.Session, out io.Writer, sf *utils.StreamFormatter, func lookupImageOnEndpoint(wg *sync.WaitGroup, r *registry.Session, out io.Writer, sf *streamformatter.StreamFormatter,
images chan imagePushData, imagesToPush chan string) { images chan imagePushData, imagesToPush chan string) {
defer wg.Done() defer wg.Done()
for image := range images { for image := range images {
@ -144,7 +145,7 @@ func lookupImageOnEndpoint(wg *sync.WaitGroup, r *registry.Session, out io.Write
} }
func (s *TagStore) pushImageToEndpoint(endpoint string, out io.Writer, remoteName string, imageIDs []string, func (s *TagStore) pushImageToEndpoint(endpoint string, out io.Writer, remoteName string, imageIDs []string,
tags map[string][]string, repo *registry.RepositoryData, sf *utils.StreamFormatter, r *registry.Session) error { tags map[string][]string, repo *registry.RepositoryData, sf *streamformatter.StreamFormatter, r *registry.Session) error {
workerCount := len(imageIDs) workerCount := len(imageIDs)
// start a maximum of 5 workers to check if images exist on the specified endpoint. // start a maximum of 5 workers to check if images exist on the specified endpoint.
if workerCount > 5 { if workerCount > 5 {
@ -203,7 +204,7 @@ func (s *TagStore) pushImageToEndpoint(endpoint string, out io.Writer, remoteNam
// pushRepository pushes layers that do not already exist on the registry. // pushRepository pushes layers that do not already exist on the registry.
func (s *TagStore) pushRepository(r *registry.Session, out io.Writer, func (s *TagStore) pushRepository(r *registry.Session, out io.Writer,
repoInfo *registry.RepositoryInfo, localRepo map[string]string, repoInfo *registry.RepositoryInfo, localRepo map[string]string,
tag string, sf *utils.StreamFormatter) error { tag string, sf *streamformatter.StreamFormatter) error {
log.Debugf("Local repo: %s", localRepo) log.Debugf("Local repo: %s", localRepo)
out = utils.NewWriteFlusher(out) out = utils.NewWriteFlusher(out)
imgList, tags, err := s.getImageList(localRepo, tag) imgList, tags, err := s.getImageList(localRepo, tag)
@ -238,7 +239,7 @@ func (s *TagStore) pushRepository(r *registry.Session, out io.Writer,
return err return err
} }
func (s *TagStore) pushImage(r *registry.Session, out io.Writer, imgID, ep string, token []string, sf *utils.StreamFormatter) (checksum string, err error) { func (s *TagStore) pushImage(r *registry.Session, out io.Writer, imgID, ep string, token []string, sf *streamformatter.StreamFormatter) (checksum string, err error) {
out = utils.NewWriteFlusher(out) out = utils.NewWriteFlusher(out)
jsonRaw, err := ioutil.ReadFile(path.Join(s.graph.Root, imgID, "json")) jsonRaw, err := ioutil.ReadFile(path.Join(s.graph.Root, imgID, "json"))
if err != nil { if err != nil {
@ -292,7 +293,7 @@ func (s *TagStore) pushImage(r *registry.Session, out io.Writer, imgID, ep strin
return imgData.Checksum, nil return imgData.Checksum, nil
} }
func (s *TagStore) pushV2Repository(r *registry.Session, localRepo Repository, out io.Writer, repoInfo *registry.RepositoryInfo, tag string, sf *utils.StreamFormatter) error { func (s *TagStore) pushV2Repository(r *registry.Session, localRepo Repository, out io.Writer, repoInfo *registry.RepositoryInfo, tag string, sf *streamformatter.StreamFormatter) error {
endpoint, err := r.V2RegistryEndpoint(repoInfo.Index) endpoint, err := r.V2RegistryEndpoint(repoInfo.Index)
if err != nil { if err != nil {
if repoInfo.Index.Official { if repoInfo.Index.Official {
@ -442,7 +443,7 @@ func (s *TagStore) pushV2Repository(r *registry.Session, localRepo Repository, o
} }
// PushV2Image pushes the image content to the v2 registry, first buffering the contents to disk // PushV2Image pushes the image content to the v2 registry, first buffering the contents to disk
func (s *TagStore) pushV2Image(r *registry.Session, img *image.Image, endpoint *registry.Endpoint, imageName string, sf *utils.StreamFormatter, out io.Writer, auth *registry.RequestAuthorization) (string, error) { func (s *TagStore) pushV2Image(r *registry.Session, img *image.Image, endpoint *registry.Endpoint, imageName string, sf *streamformatter.StreamFormatter, out io.Writer, auth *registry.RequestAuthorization) (string, error) {
out.Write(sf.FormatProgress(stringid.TruncateID(img.ID), "Buffering to Disk", nil)) out.Write(sf.FormatProgress(stringid.TruncateID(img.ID), "Buffering to Disk", nil))
image, err := s.graph.Get(img.ID) image, err := s.graph.Get(img.ID)
@ -498,7 +499,7 @@ func (s *TagStore) CmdPush(job *engine.Job) error {
} }
var ( var (
localName = job.Args[0] localName = job.Args[0]
sf = utils.NewStreamFormatter(job.GetenvBool("json")) sf = streamformatter.NewStreamFormatter(job.GetenvBool("json"))
authConfig = &registry.AuthConfig{} authConfig = &registry.AuthConfig{}
metaHeaders map[string][]string metaHeaders map[string][]string
) )

View File

@ -1,4 +1,4 @@
package utils package jsonmessage
import ( import (
"encoding/json" "encoding/json"

View File

@ -1,4 +1,4 @@
package utils package jsonmessage
import ( import (
"testing" "testing"

View File

@ -1,37 +1,16 @@
package progressreader package progressreader
import ( import (
"github.com/docker/docker/pkg/jsonmessage"
"github.com/docker/docker/pkg/streamformatter"
"io" "io"
) )
type StreamFormatter interface {
FormatProg(string, string, interface{}) []byte
FormatStatus(string, string, ...interface{}) []byte
FormatError(error) []byte
}
type PR_JSONProgress interface {
GetCurrent() int
GetTotal() int
}
type JSONProg struct {
Current int
Total int
}
func (j *JSONProg) GetCurrent() int {
return j.Current
}
func (j *JSONProg) GetTotal() int {
return j.Total
}
// Reader with progress bar // Reader with progress bar
type Config struct { type Config struct {
In io.ReadCloser // Stream to read from In io.ReadCloser // Stream to read from
Out io.Writer // Where to send progress bar to Out io.Writer // Where to send progress bar to
Formatter StreamFormatter Formatter *streamformatter.StreamFormatter
Size int Size int
Current int Current int
LastUpdate int LastUpdate int
@ -54,7 +33,7 @@ func (config *Config) Read(p []byte) (n int, err error) {
} }
} }
if config.Current-config.LastUpdate > updateEvery || err != nil { if config.Current-config.LastUpdate > updateEvery || err != nil {
config.Out.Write(config.Formatter.FormatProg(config.ID, config.Action, &JSONProg{Current: config.Current, Total: config.Size})) config.Out.Write(config.Formatter.FormatProgress(config.ID, config.Action, &jsonmessage.JSONProgress{Current: config.Current, Total: config.Size}))
config.LastUpdate = config.Current config.LastUpdate = config.Current
} }
// Send newline when complete // Send newline when complete
@ -64,6 +43,6 @@ func (config *Config) Read(p []byte) (n int, err error) {
return read, err return read, err
} }
func (config *Config) Close() error { func (config *Config) Close() error {
config.Out.Write(config.Formatter.FormatProg(config.ID, config.Action, &JSONProg{Current: config.Current, Total: config.Size})) config.Out.Write(config.Formatter.FormatProgress(config.ID, config.Action, &jsonmessage.JSONProgress{Current: config.Current, Total: config.Size}))
return config.In.Close() return config.In.Close()
} }

View File

@ -1,9 +1,9 @@
package utils package streamformatter
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/docker/docker/pkg/progressreader" "github.com/docker/docker/pkg/jsonmessage"
"io" "io"
) )
@ -21,7 +21,7 @@ var streamNewlineBytes = []byte(streamNewline)
func (sf *StreamFormatter) FormatStream(str string) []byte { func (sf *StreamFormatter) FormatStream(str string) []byte {
if sf.json { if sf.json {
b, err := json.Marshal(&JSONMessage{Stream: str}) b, err := json.Marshal(&jsonmessage.JSONMessage{Stream: str})
if err != nil { if err != nil {
return sf.FormatError(err) return sf.FormatError(err)
} }
@ -33,7 +33,7 @@ func (sf *StreamFormatter) FormatStream(str string) []byte {
func (sf *StreamFormatter) FormatStatus(id, format string, a ...interface{}) []byte { func (sf *StreamFormatter) FormatStatus(id, format string, a ...interface{}) []byte {
str := fmt.Sprintf(format, a...) str := fmt.Sprintf(format, a...)
if sf.json { if sf.json {
b, err := json.Marshal(&JSONMessage{ID: id, Status: str}) b, err := json.Marshal(&jsonmessage.JSONMessage{ID: id, Status: str})
if err != nil { if err != nil {
return sf.FormatError(err) return sf.FormatError(err)
} }
@ -44,33 +44,25 @@ func (sf *StreamFormatter) FormatStatus(id, format string, a ...interface{}) []b
func (sf *StreamFormatter) FormatError(err error) []byte { func (sf *StreamFormatter) FormatError(err error) []byte {
if sf.json { if sf.json {
jsonError, ok := err.(*JSONError) jsonError, ok := err.(*jsonmessage.JSONError)
if !ok { if !ok {
jsonError = &JSONError{Message: err.Error()} jsonError = &jsonmessage.JSONError{Message: err.Error()}
} }
if b, err := json.Marshal(&JSONMessage{Error: jsonError, ErrorMessage: err.Error()}); err == nil { if b, err := json.Marshal(&jsonmessage.JSONMessage{Error: jsonError, ErrorMessage: err.Error()}); err == nil {
return append(b, streamNewlineBytes...) return append(b, streamNewlineBytes...)
} }
return []byte("{\"error\":\"format error\"}" + streamNewline) return []byte("{\"error\":\"format error\"}" + streamNewline)
} }
return []byte("Error: " + err.Error() + streamNewline) return []byte("Error: " + err.Error() + streamNewline)
} }
func (sf *StreamFormatter) FormatProg(id, action string, p interface{}) []byte {
switch progress := p.(type) { func (sf *StreamFormatter) FormatProgress(id, action string, progress *jsonmessage.JSONProgress) []byte {
case *JSONProgress:
return sf.FormatProgress(id, action, progress)
case progressreader.PR_JSONProgress:
return sf.FormatProgress(id, action, &JSONProgress{Current: progress.GetCurrent(), Total: progress.GetTotal()})
}
return nil
}
func (sf *StreamFormatter) FormatProgress(id, action string, progress *JSONProgress) []byte {
if progress == nil { if progress == nil {
progress = &JSONProgress{} progress = &jsonmessage.JSONProgress{}
} }
if sf.json { if sf.json {
b, err := json.Marshal(&JSONMessage{ b, err := json.Marshal(&jsonmessage.JSONMessage{
Status: action, Status: action,
ProgressMessage: progress.String(), ProgressMessage: progress.String(),
Progress: progress, Progress: progress,

View File

@ -1,8 +1,9 @@
package utils package streamformatter
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"github.com/docker/docker/pkg/jsonmessage"
"reflect" "reflect"
"testing" "testing"
) )
@ -33,7 +34,7 @@ func TestFormatSimpleError(t *testing.T) {
func TestFormatJSONError(t *testing.T) { func TestFormatJSONError(t *testing.T) {
sf := NewStreamFormatter(true) sf := NewStreamFormatter(true)
err := &JSONError{Code: 50, Message: "Json error"} err := &jsonmessage.JSONError{Code: 50, Message: "Json error"}
res := sf.FormatError(err) res := sf.FormatError(err)
if string(res) != `{"errorDetail":{"code":50,"message":"Json error"},"error":"Json error"}`+"\r\n" { if string(res) != `{"errorDetail":{"code":50,"message":"Json error"},"error":"Json error"}`+"\r\n" {
t.Fatalf("%q", res) t.Fatalf("%q", res)
@ -42,13 +43,13 @@ func TestFormatJSONError(t *testing.T) {
func TestFormatProgress(t *testing.T) { func TestFormatProgress(t *testing.T) {
sf := NewStreamFormatter(true) sf := NewStreamFormatter(true)
progress := &JSONProgress{ progress := &jsonmessage.JSONProgress{
Current: 15, Current: 15,
Total: 30, Total: 30,
Start: 1, Start: 1,
} }
res := sf.FormatProgress("id", "action", progress) res := sf.FormatProgress("id", "action", progress)
msg := &JSONMessage{} msg := &jsonmessage.JSONMessage{}
if err := json.Unmarshal(res, msg); err != nil { if err := json.Unmarshal(res, msg); err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -23,6 +23,7 @@ import (
"github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/archive"
"github.com/docker/docker/pkg/fileutils" "github.com/docker/docker/pkg/fileutils"
"github.com/docker/docker/pkg/ioutils" "github.com/docker/docker/pkg/ioutils"
"github.com/docker/docker/pkg/jsonmessage"
"github.com/docker/docker/pkg/stringutils" "github.com/docker/docker/pkg/stringutils"
) )
@ -254,7 +255,7 @@ func NewWriteFlusher(w io.Writer) *WriteFlusher {
} }
func NewHTTPRequestError(msg string, res *http.Response) error { func NewHTTPRequestError(msg string, res *http.Response) error {
return &JSONError{ return &jsonmessage.JSONError{
Message: msg, Message: msg,
Code: res.StatusCode, Code: res.StatusCode,
} }