mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-01 00:23:56 +08:00 
			
		
		
		
	build: add docker output for non-moby drivers
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
This commit is contained in:
		| @@ -13,6 +13,7 @@ import ( | |||||||
|  |  | ||||||
| 	"github.com/containerd/containerd/platforms" | 	"github.com/containerd/containerd/platforms" | ||||||
| 	"github.com/docker/distribution/reference" | 	"github.com/docker/distribution/reference" | ||||||
|  | 	dockerclient "github.com/docker/docker/client" | ||||||
| 	"github.com/docker/docker/pkg/urlutil" | 	"github.com/docker/docker/pkg/urlutil" | ||||||
| 	"github.com/moby/buildkit/client" | 	"github.com/moby/buildkit/client" | ||||||
| 	"github.com/moby/buildkit/session" | 	"github.com/moby/buildkit/session" | ||||||
| @@ -61,6 +62,10 @@ type DriverInfo struct { | |||||||
| 	Err      error | 	Err      error | ||||||
| } | } | ||||||
|  |  | ||||||
|  | type DockerAPI interface { | ||||||
|  | 	DockerAPI(name string) (dockerclient.APIClient, error) | ||||||
|  | } | ||||||
|  |  | ||||||
| func getFirstDriver(drivers []DriverInfo) (driver.Driver, error) { | func getFirstDriver(drivers []DriverInfo) (driver.Driver, error) { | ||||||
| 	err := errors.Errorf("no drivers found") | 	err := errors.Errorf("no drivers found") | ||||||
| 	for _, di := range drivers { | 	for _, di := range drivers { | ||||||
| @@ -74,7 +79,7 @@ func getFirstDriver(drivers []DriverInfo) (driver.Driver, error) { | |||||||
| 	return nil, err | 	return nil, err | ||||||
| } | } | ||||||
|  |  | ||||||
| func Build(ctx context.Context, drivers []DriverInfo, opt map[string]Options, pw progress.Writer) (map[string]*client.SolveResponse, error) { | func Build(ctx context.Context, drivers []DriverInfo, opt map[string]Options, docker DockerAPI, pw progress.Writer) (map[string]*client.SolveResponse, error) { | ||||||
| 	if len(drivers) == 0 { | 	if len(drivers) == 0 { | ||||||
| 		return nil, errors.Errorf("driver required for build") | 		return nil, errors.Errorf("driver required for build") | ||||||
| 	} | 	} | ||||||
| @@ -83,7 +88,6 @@ func Build(ctx context.Context, drivers []DriverInfo, opt map[string]Options, pw | |||||||
| 		return nil, errors.Errorf("multiple drivers currently not supported") | 		return nil, errors.Errorf("multiple drivers currently not supported") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	pwOld := pw |  | ||||||
| 	d, err := getFirstDriver(drivers) | 	d, err := getFirstDriver(drivers) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| @@ -91,10 +95,10 @@ func Build(ctx context.Context, drivers []DriverInfo, opt map[string]Options, pw | |||||||
| 	_, isDefaultMobyDriver := d.(interface { | 	_, isDefaultMobyDriver := d.(interface { | ||||||
| 		IsDefaultMobyDriver() | 		IsDefaultMobyDriver() | ||||||
| 	}) | 	}) | ||||||
| 	c, pw, err := driver.Boot(ctx, d, pw) | 	c, err := driver.Boot(ctx, d, pw) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		close(pwOld.Status()) | 		close(pw.Status()) | ||||||
| 		<-pwOld.Done() | 		<-pw.Done() | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -173,10 +177,16 @@ func Build(ctx context.Context, drivers []DriverInfo, opt map[string]Options, pw | |||||||
| 			} | 			} | ||||||
| 			if e.Type == "docker" { | 			if e.Type == "docker" { | ||||||
| 				if e.Output == nil { | 				if e.Output == nil { | ||||||
| 					if !isDefaultMobyDriver { | 					if isDefaultMobyDriver { | ||||||
| 						return nil, errors.Errorf("loading to docker currently not implemented, specify dest file or -") | 						e.Type = "image" | ||||||
|  | 					} else { | ||||||
|  | 						w, cancel, err := newDockerLoader(ctx, docker, e.Attrs["context"], mw) | ||||||
|  | 						if err != nil { | ||||||
|  | 							return nil, err | ||||||
|  | 						} | ||||||
|  | 						defer cancel() | ||||||
|  | 						opt.Exports[i].Output = w | ||||||
| 					} | 					} | ||||||
| 					e.Type = "image" |  | ||||||
| 				} else if !d.Features()[driver.DockerExporter] { | 				} else if !d.Features()[driver.DockerExporter] { | ||||||
| 					return nil, notSupported(d, driver.DockerExporter) | 					return nil, notSupported(d, driver.DockerExporter) | ||||||
| 				} | 				} | ||||||
| @@ -245,6 +255,7 @@ func Build(ctx context.Context, drivers []DriverInfo, opt map[string]Options, pw | |||||||
|  |  | ||||||
| 		var statusCh chan *client.SolveStatus | 		var statusCh chan *client.SolveStatus | ||||||
| 		if pw != nil { | 		if pw != nil { | ||||||
|  | 			pw = progress.ResetTime(pw) | ||||||
| 			statusCh = pw.Status() | 			statusCh = pw.Status() | ||||||
| 			eg.Go(func() error { | 			eg.Go(func() error { | ||||||
| 				<-pw.Done() | 				<-pw.Done() | ||||||
| @@ -380,5 +391,54 @@ func LoadInputs(inp Inputs, target *client.SolveOpt) (func(), error) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func notSupported(d driver.Driver, f driver.Feature) error { | func notSupported(d driver.Driver, f driver.Feature) error { | ||||||
| 	return errors.Errorf("%s feature is currently not supported for %s driver. Please switch to a different driver (eg. \"docker buildx new\")", f, d.Factory().Name()) | 	return errors.Errorf("%s feature is currently not supported for %s driver. Please switch to a different driver (eg. \"docker buildx create\")", f, d.Factory().Name()) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func newDockerLoader(ctx context.Context, d DockerAPI, name string, mw *progress.MultiWriter) (io.WriteCloser, func(), error) { | ||||||
|  | 	c, err := d.DockerAPI(name) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	pr, pw := io.Pipe() | ||||||
|  | 	started := make(chan struct{}) | ||||||
|  | 	w := &waitingWriter{ | ||||||
|  | 		PipeWriter: pw, | ||||||
|  | 		f: func() { | ||||||
|  | 			resp, err := c.ImageLoad(ctx, pr, false) | ||||||
|  | 			if err != nil { | ||||||
|  | 				pr.CloseWithError(err) | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 			prog := mw.WithPrefix("", false) | ||||||
|  | 			close(started) | ||||||
|  | 			progress.FromReader(prog, "importing to docker", resp.Body) | ||||||
|  | 		}, | ||||||
|  | 		started: started, | ||||||
|  | 	} | ||||||
|  | 	return w, func() { | ||||||
|  | 		pr.Close() | ||||||
|  | 	}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type waitingWriter struct { | ||||||
|  | 	*io.PipeWriter | ||||||
|  | 	f       func() | ||||||
|  | 	once    sync.Once | ||||||
|  | 	mu      sync.Mutex | ||||||
|  | 	err     error | ||||||
|  | 	started chan struct{} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (w *waitingWriter) Write(dt []byte) (int, error) { | ||||||
|  | 	w.once.Do(func() { | ||||||
|  | 		go w.f() | ||||||
|  | 	}) | ||||||
|  | 	return w.PipeWriter.Write(dt) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (w *waitingWriter) Close() error { | ||||||
|  | 	err := w.PipeWriter.Close() | ||||||
|  | 	<-w.started | ||||||
|  | 	return err | ||||||
| } | } | ||||||
|   | |||||||
| @@ -127,7 +127,7 @@ func buildTargets(ctx context.Context, dockerCli command.Cli, opts map[string]bu | |||||||
| 	defer cancel() | 	defer cancel() | ||||||
| 	pw := progress.NewPrinter(ctx2, os.Stderr, progressMode) | 	pw := progress.NewPrinter(ctx2, os.Stderr, progressMode) | ||||||
|  |  | ||||||
| 	_, err = build.Build(ctx, dis, opts, pw) | 	_, err = build.Build(ctx, dis, opts, dockerAPI(dockerCli), pw) | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -166,7 +166,7 @@ func boot(ctx context.Context, ngi *nginfo) (bool, error) { | |||||||
| 		func(idx int) { | 		func(idx int) { | ||||||
| 			eg.Go(func() error { | 			eg.Go(func() error { | ||||||
| 				pw := mw.WithPrefix(ngi.ng.Nodes[idx].Name, len(toBoot) > 1) | 				pw := mw.WithPrefix(ngi.ng.Nodes[idx].Name, len(toBoot) > 1) | ||||||
| 				_, _, err := driver.Boot(ctx, ngi.drivers[idx].di.Driver, pw) | 				_, err := driver.Boot(ctx, ngi.drivers[idx].di.Driver, pw) | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
| 					ngi.drivers[idx].err = err | 					ngi.drivers[idx].err = err | ||||||
| 				} | 				} | ||||||
|   | |||||||
| @@ -299,3 +299,18 @@ func loadNodeGroupData(ctx context.Context, dockerCli command.Cli, ngi *nginfo) | |||||||
|  |  | ||||||
| 	return eg.Wait() | 	return eg.Wait() | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func dockerAPI(dockerCli command.Cli) *api { | ||||||
|  | 	return &api{dockerCli: dockerCli} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type api struct { | ||||||
|  | 	dockerCli command.Cli | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (a *api) DockerAPI(name string) (dockerclient.APIClient, error) { | ||||||
|  | 	if name == "" { | ||||||
|  | 		name = a.dockerCli.CurrentContext() | ||||||
|  | 	} | ||||||
|  | 	return clientForEndpoint(a.dockerCli, name) | ||||||
|  | } | ||||||
|   | |||||||
| @@ -2,7 +2,6 @@ package driver | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
| 	"github.com/moby/buildkit/client" | 	"github.com/moby/buildkit/client" | ||||||
| 	"github.com/pkg/errors" | 	"github.com/pkg/errors" | ||||||
| @@ -52,24 +51,24 @@ type Driver interface { | |||||||
| 	Features() map[Feature]bool | 	Features() map[Feature]bool | ||||||
| } | } | ||||||
|  |  | ||||||
| func Boot(ctx context.Context, d Driver, pw progress.Writer) (*client.Client, progress.Writer, error) { | func Boot(ctx context.Context, d Driver, pw progress.Writer) (*client.Client, error) { | ||||||
| 	try := 0 | 	try := 0 | ||||||
| 	for { | 	for { | ||||||
| 		info, err := d.Info(ctx) | 		info, err := d.Info(ctx) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, nil, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
| 		try++ | 		try++ | ||||||
| 		if info.Status != Running { | 		if info.Status != Running { | ||||||
| 			if try > 2 { | 			if try > 2 { | ||||||
| 				return nil, nil, errors.Errorf("failed to bootstrap %T driver in attempts", d) | 				return nil, errors.Errorf("failed to bootstrap %T driver in attempts", d) | ||||||
| 			} | 			} | ||||||
| 			if err := d.Bootstrap(ctx, func(s *client.SolveStatus) { | 			if err := d.Bootstrap(ctx, func(s *client.SolveStatus) { | ||||||
| 				if pw != nil { | 				if pw != nil { | ||||||
| 					pw.Status() <- s | 					pw.Status() <- s | ||||||
| 				} | 				} | ||||||
| 			}); err != nil { | 			}); err != nil { | ||||||
| 				return nil, nil, err | 				return nil, err | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -78,72 +77,8 @@ func Boot(ctx context.Context, d Driver, pw progress.Writer) (*client.Client, pr | |||||||
| 			if errors.Cause(err) == ErrNotRunning && try <= 2 { | 			if errors.Cause(err) == ErrNotRunning && try <= 2 { | ||||||
| 				continue | 				continue | ||||||
| 			} | 			} | ||||||
| 			return nil, nil, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
| 		return c, newResetWriter(pw), nil | 		return c, nil | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func newResetWriter(in progress.Writer) progress.Writer { |  | ||||||
| 	w := &pw{Writer: in, status: make(chan *client.SolveStatus), tm: time.Now()} |  | ||||||
| 	go func() { |  | ||||||
| 		for { |  | ||||||
| 			select { |  | ||||||
| 			case <-in.Done(): |  | ||||||
| 				return |  | ||||||
| 			case st, ok := <-w.status: |  | ||||||
| 				if !ok { |  | ||||||
| 					close(in.Status()) |  | ||||||
| 					return |  | ||||||
| 				} |  | ||||||
| 				if w.diff == nil { |  | ||||||
| 					for _, v := range st.Vertexes { |  | ||||||
| 						if v.Started != nil { |  | ||||||
| 							d := v.Started.Sub(w.tm) |  | ||||||
| 							w.diff = &d |  | ||||||
| 						} |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 				if w.diff != nil { |  | ||||||
| 					for _, v := range st.Vertexes { |  | ||||||
| 						if v.Started != nil { |  | ||||||
| 							d := v.Started.Add(-*w.diff) |  | ||||||
| 							v.Started = &d |  | ||||||
| 						} |  | ||||||
| 						if v.Completed != nil { |  | ||||||
| 							d := v.Completed.Add(-*w.diff) |  | ||||||
| 							v.Completed = &d |  | ||||||
| 						} |  | ||||||
| 					} |  | ||||||
| 					for _, v := range st.Statuses { |  | ||||||
| 						if v.Started != nil { |  | ||||||
| 							d := v.Started.Add(-*w.diff) |  | ||||||
| 							v.Started = &d |  | ||||||
| 						} |  | ||||||
| 						if v.Completed != nil { |  | ||||||
| 							d := v.Completed.Add(-*w.diff) |  | ||||||
| 							v.Completed = &d |  | ||||||
| 						} |  | ||||||
| 						v.Timestamp = v.Timestamp.Add(-*w.diff) |  | ||||||
| 					} |  | ||||||
| 					for _, v := range st.Logs { |  | ||||||
| 						v.Timestamp = v.Timestamp.Add(-*w.diff) |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 				in.Status() <- st |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	}() |  | ||||||
| 	return w |  | ||||||
| } |  | ||||||
|  |  | ||||||
| type pw struct { |  | ||||||
| 	progress.Writer |  | ||||||
| 	tm     time.Time |  | ||||||
| 	diff   *time.Duration |  | ||||||
| 	status chan *client.SolveStatus |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (p *pw) Status() chan *client.SolveStatus { |  | ||||||
| 	return p.status |  | ||||||
| } |  | ||||||
|   | |||||||
							
								
								
									
										40
									
								
								util/progress/fromreader.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								util/progress/fromreader.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | |||||||
|  | package progress | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"io" | ||||||
|  | 	"io/ioutil" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
|  | 	"github.com/moby/buildkit/client" | ||||||
|  | 	"github.com/moby/buildkit/identity" | ||||||
|  | 	"github.com/opencontainers/go-digest" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func FromReader(w Writer, name string, rc io.ReadCloser) { | ||||||
|  | 	status := w.Status() | ||||||
|  | 	dgst := digest.FromBytes([]byte(identity.NewID())) | ||||||
|  | 	tm := time.Now() | ||||||
|  |  | ||||||
|  | 	vtx := client.Vertex{ | ||||||
|  | 		Digest:  dgst, | ||||||
|  | 		Name:    name, | ||||||
|  | 		Started: &tm, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	status <- &client.SolveStatus{ | ||||||
|  | 		Vertexes: []*client.Vertex{&vtx}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	_, err := io.Copy(ioutil.Discard, rc) | ||||||
|  |  | ||||||
|  | 	tm2 := time.Now() | ||||||
|  | 	vtx2 := vtx | ||||||
|  | 	vtx2.Completed = &tm2 | ||||||
|  | 	if err != nil { | ||||||
|  | 		vtx2.Error = err.Error() | ||||||
|  | 	} | ||||||
|  | 	status <- &client.SolveStatus{ | ||||||
|  | 		Vertexes: []*client.Vertex{&vtx2}, | ||||||
|  | 	} | ||||||
|  | 	close(status) | ||||||
|  | } | ||||||
							
								
								
									
										71
									
								
								util/progress/reset.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								util/progress/reset.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | |||||||
|  | package progress | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
|  | 	"github.com/moby/buildkit/client" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func ResetTime(in Writer) Writer { | ||||||
|  | 	w := &pw{Writer: in, status: make(chan *client.SolveStatus), tm: time.Now()} | ||||||
|  | 	go func() { | ||||||
|  | 		for { | ||||||
|  | 			select { | ||||||
|  | 			case <-in.Done(): | ||||||
|  | 				return | ||||||
|  | 			case st, ok := <-w.status: | ||||||
|  | 				if !ok { | ||||||
|  | 					close(in.Status()) | ||||||
|  | 					return | ||||||
|  | 				} | ||||||
|  | 				if w.diff == nil { | ||||||
|  | 					for _, v := range st.Vertexes { | ||||||
|  | 						if v.Started != nil { | ||||||
|  | 							d := v.Started.Sub(w.tm) | ||||||
|  | 							w.diff = &d | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 				if w.diff != nil { | ||||||
|  | 					for _, v := range st.Vertexes { | ||||||
|  | 						if v.Started != nil { | ||||||
|  | 							d := v.Started.Add(-*w.diff) | ||||||
|  | 							v.Started = &d | ||||||
|  | 						} | ||||||
|  | 						if v.Completed != nil { | ||||||
|  | 							d := v.Completed.Add(-*w.diff) | ||||||
|  | 							v.Completed = &d | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 					for _, v := range st.Statuses { | ||||||
|  | 						if v.Started != nil { | ||||||
|  | 							d := v.Started.Add(-*w.diff) | ||||||
|  | 							v.Started = &d | ||||||
|  | 						} | ||||||
|  | 						if v.Completed != nil { | ||||||
|  | 							d := v.Completed.Add(-*w.diff) | ||||||
|  | 							v.Completed = &d | ||||||
|  | 						} | ||||||
|  | 						v.Timestamp = v.Timestamp.Add(-*w.diff) | ||||||
|  | 					} | ||||||
|  | 					for _, v := range st.Logs { | ||||||
|  | 						v.Timestamp = v.Timestamp.Add(-*w.diff) | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 				in.Status() <- st | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	}() | ||||||
|  | 	return w | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type pw struct { | ||||||
|  | 	Writer | ||||||
|  | 	tm     time.Time | ||||||
|  | 	diff   *time.Duration | ||||||
|  | 	status chan *client.SolveStatus | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *pw) Status() chan *client.SolveStatus { | ||||||
|  | 	return p.status | ||||||
|  | } | ||||||
							
								
								
									
										22
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							| @@ -139,10 +139,10 @@ github.com/docker/compose-on-kubernetes/api/compose/impersonation | |||||||
| # github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible | # github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible | ||||||
| github.com/docker/distribution/reference | github.com/docker/distribution/reference | ||||||
| github.com/docker/distribution/digestset | github.com/docker/distribution/digestset | ||||||
|  | github.com/docker/distribution/registry/api/errcode | ||||||
| github.com/docker/distribution/manifest/manifestlist | github.com/docker/distribution/manifest/manifestlist | ||||||
| github.com/docker/distribution | github.com/docker/distribution | ||||||
| github.com/docker/distribution/manifest/schema2 | github.com/docker/distribution/manifest/schema2 | ||||||
| github.com/docker/distribution/registry/api/errcode |  | ||||||
| github.com/docker/distribution/registry/api/v2 | github.com/docker/distribution/registry/api/v2 | ||||||
| github.com/docker/distribution/registry/client | github.com/docker/distribution/registry/client | ||||||
| github.com/docker/distribution/registry/client/auth | github.com/docker/distribution/registry/client/auth | ||||||
| @@ -154,8 +154,8 @@ github.com/docker/distribution/registry/storage/cache/memory | |||||||
| github.com/docker/distribution/uuid | github.com/docker/distribution/uuid | ||||||
| github.com/docker/distribution/metrics | github.com/docker/distribution/metrics | ||||||
| # github.com/docker/docker v1.14.0-0.20190410063227-d9d9eccdc862 | # github.com/docker/docker v1.14.0-0.20190410063227-d9d9eccdc862 | ||||||
| github.com/docker/docker/pkg/urlutil |  | ||||||
| github.com/docker/docker/client | github.com/docker/docker/client | ||||||
|  | github.com/docker/docker/pkg/urlutil | ||||||
| github.com/docker/docker/api/types | github.com/docker/docker/api/types | ||||||
| github.com/docker/docker/api/types/container | github.com/docker/docker/api/types/container | ||||||
| github.com/docker/docker/api/types/network | github.com/docker/docker/api/types/network | ||||||
| @@ -163,21 +163,22 @@ github.com/docker/docker/pkg/stdcopy | |||||||
| github.com/docker/docker/pkg/namesgenerator | github.com/docker/docker/pkg/namesgenerator | ||||||
| github.com/docker/docker/api/types/mount | github.com/docker/docker/api/types/mount | ||||||
| github.com/docker/docker/api/types/versions | github.com/docker/docker/api/types/versions | ||||||
|  | github.com/docker/docker/api | ||||||
| github.com/docker/docker/api/types/events | github.com/docker/docker/api/types/events | ||||||
| github.com/docker/docker/api/types/filters | github.com/docker/docker/api/types/filters | ||||||
|  | github.com/docker/docker/api/types/image | ||||||
| github.com/docker/docker/api/types/registry | github.com/docker/docker/api/types/registry | ||||||
|  | github.com/docker/docker/api/types/swarm | ||||||
|  | github.com/docker/docker/api/types/time | ||||||
|  | github.com/docker/docker/api/types/volume | ||||||
|  | github.com/docker/docker/errdefs | ||||||
| github.com/docker/docker/pkg/homedir | github.com/docker/docker/pkg/homedir | ||||||
| github.com/docker/docker/pkg/system | github.com/docker/docker/pkg/system | ||||||
| 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/api/types/blkiodev | github.com/docker/docker/api/types/blkiodev | ||||||
| github.com/docker/docker/api/types/swarm |  | ||||||
| github.com/docker/docker/api |  | ||||||
| github.com/docker/docker/api/types/image |  | ||||||
| github.com/docker/docker/api/types/time |  | ||||||
| github.com/docker/docker/api/types/volume |  | ||||||
| github.com/docker/docker/errdefs |  | ||||||
| github.com/docker/docker/api/types/strslice | github.com/docker/docker/api/types/strslice | ||||||
|  | github.com/docker/docker/api/types/swarm/runtime | ||||||
| github.com/docker/docker/pkg/jsonmessage | github.com/docker/docker/pkg/jsonmessage | ||||||
| github.com/docker/docker/pkg/idtools | github.com/docker/docker/pkg/idtools | ||||||
| github.com/docker/docker/pkg/mount | github.com/docker/docker/pkg/mount | ||||||
| @@ -186,7 +187,6 @@ github.com/docker/docker/pkg/ioutils | |||||||
| github.com/docker/docker/pkg/stringid | github.com/docker/docker/pkg/stringid | ||||||
| github.com/docker/docker/pkg/tarsum | github.com/docker/docker/pkg/tarsum | ||||||
| github.com/docker/docker/registry/resumable | github.com/docker/docker/registry/resumable | ||||||
| github.com/docker/docker/api/types/swarm/runtime |  | ||||||
| github.com/docker/docker/pkg/fileutils | github.com/docker/docker/pkg/fileutils | ||||||
| github.com/docker/docker/pkg/longpath | github.com/docker/docker/pkg/longpath | ||||||
| # github.com/docker/docker-credential-helpers v0.6.1 | # github.com/docker/docker-credential-helpers v0.6.1 | ||||||
| @@ -196,8 +196,8 @@ github.com/docker/docker-credential-helpers/credentials | |||||||
| github.com/docker/go/canonical/json | github.com/docker/go/canonical/json | ||||||
| # github.com/docker/go-connections v0.4.0 | # github.com/docker/go-connections v0.4.0 | ||||||
| github.com/docker/go-connections/nat | github.com/docker/go-connections/nat | ||||||
| github.com/docker/go-connections/tlsconfig |  | ||||||
| github.com/docker/go-connections/sockets | github.com/docker/go-connections/sockets | ||||||
|  | github.com/docker/go-connections/tlsconfig | ||||||
| # github.com/docker/go-events v0.0.0-20170721190031-9461782956ad | # github.com/docker/go-events v0.0.0-20170721190031-9461782956ad | ||||||
| github.com/docker/go-events | github.com/docker/go-events | ||||||
| # github.com/docker/go-metrics v0.0.0-20170502235133-d466d4f6fd96 | # github.com/docker/go-metrics v0.0.0-20170502235133-d466d4f6fd96 | ||||||
| @@ -396,10 +396,10 @@ golang.org/x/net/http2 | |||||||
| golang.org/x/net/context | golang.org/x/net/context | ||||||
| golang.org/x/net/context/ctxhttp | golang.org/x/net/context/ctxhttp | ||||||
| golang.org/x/net/trace | golang.org/x/net/trace | ||||||
|  | golang.org/x/net/proxy | ||||||
| golang.org/x/net/http/httpguts | golang.org/x/net/http/httpguts | ||||||
| golang.org/x/net/http2/hpack | golang.org/x/net/http2/hpack | ||||||
| golang.org/x/net/idna | golang.org/x/net/idna | ||||||
| golang.org/x/net/proxy |  | ||||||
| golang.org/x/net/internal/timeseries | golang.org/x/net/internal/timeseries | ||||||
| golang.org/x/net/internal/socks | golang.org/x/net/internal/socks | ||||||
| # golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f | # golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Tonis Tiigi
					Tonis Tiigi