mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
LCOW: pull goes to correct stores
Signed-off-by: John Howard <jhoward@microsoft.com>
This commit is contained in:
parent
8f53780694
commit
a1fe1dc791
7 changed files with 70 additions and 16 deletions
|
@ -40,7 +40,7 @@ type importExportBackend interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
type registryBackend interface {
|
type registryBackend interface {
|
||||||
PullImage(ctx context.Context, image, tag string, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error
|
PullImage(ctx context.Context, image, tag, platform string, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error
|
||||||
PushImage(ctx context.Context, image, tag string, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error
|
PushImage(ctx context.Context, image, tag string, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error
|
||||||
SearchRegistryForImages(ctx context.Context, filtersArgs string, term string, limit int, authConfig *types.AuthConfig, metaHeaders map[string][]string) (*registry.SearchResults, error)
|
SearchRegistryForImages(ctx context.Context, filtersArgs string, term string, limit int, authConfig *types.AuthConfig, metaHeaders map[string][]string) (*registry.SearchResults, error)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -17,6 +18,7 @@ import (
|
||||||
"github.com/docker/docker/api/types/versions"
|
"github.com/docker/docker/api/types/versions"
|
||||||
"github.com/docker/docker/pkg/ioutils"
|
"github.com/docker/docker/pkg/ioutils"
|
||||||
"github.com/docker/docker/pkg/streamformatter"
|
"github.com/docker/docker/pkg/streamformatter"
|
||||||
|
"github.com/docker/docker/pkg/system"
|
||||||
"github.com/docker/docker/registry"
|
"github.com/docker/docker/registry"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
@ -85,6 +87,41 @@ func (s *imageRouter) postImagesCreate(ctx context.Context, w http.ResponseWrite
|
||||||
)
|
)
|
||||||
defer output.Close()
|
defer output.Close()
|
||||||
|
|
||||||
|
// TODO @jhowardmsft LCOW Support: Eventually we will need an API change
|
||||||
|
// so that platform comes from (for example) r.Form.Get("platform"). For
|
||||||
|
// the initial implementation, we assume that the platform is the
|
||||||
|
// runtime OS of the host. It will also need a validation function such
|
||||||
|
// as below which should be called after getting it from the API.
|
||||||
|
//
|
||||||
|
// Ensures the requested platform is valid and normalized
|
||||||
|
//func validatePlatform(req string) (string, error) {
|
||||||
|
// req = strings.ToLower(req)
|
||||||
|
// if req == "" {
|
||||||
|
// req = runtime.GOOS // default to host platform
|
||||||
|
// }
|
||||||
|
// valid := []string{runtime.GOOS}
|
||||||
|
//
|
||||||
|
// if runtime.GOOS == "windows" && system.LCOWSupported() {
|
||||||
|
// valid = append(valid, "linux")
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// for _, item := range valid {
|
||||||
|
// if req == item {
|
||||||
|
// return req, nil
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return "", fmt.Errorf("invalid platform requested: %s", req)
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
// And in the call-site:
|
||||||
|
// if platform, err = validatePlatform(platform); err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
platform := runtime.GOOS
|
||||||
|
if platform == "windows" && system.LCOWSupported() {
|
||||||
|
platform = "linux"
|
||||||
|
}
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
|
||||||
if image != "" { //pull
|
if image != "" { //pull
|
||||||
|
@ -106,12 +143,13 @@ func (s *imageRouter) postImagesCreate(ctx context.Context, w http.ResponseWrite
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.backend.PullImage(ctx, image, tag, metaHeaders, authConfig, output)
|
err = s.backend.PullImage(ctx, image, tag, platform, metaHeaders, authConfig, output)
|
||||||
} else { //import
|
} else { //import
|
||||||
src := r.Form.Get("fromSrc")
|
src := r.Form.Get("fromSrc")
|
||||||
// 'err' MUST NOT be defined within this block, we need any error
|
// 'err' MUST NOT be defined within this block, we need any error
|
||||||
// generated from the download to be available to the output
|
// generated from the download to be available to the output
|
||||||
// stream processing below
|
// stream processing below
|
||||||
|
// TODO @jhowardmsft LCOW Support: This will need extending for the platform too.
|
||||||
err = s.backend.ImportImage(src, repo, tag, message, r.Body, output, r.Form["changes"])
|
err = s.backend.ImportImage(src, repo, tag, message, r.Body, output, r.Form["changes"])
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -129,7 +129,12 @@ func (daemon *Daemon) pullForBuilder(ctx context.Context, name string, authConfi
|
||||||
pullRegistryAuth = &resolvedConfig
|
pullRegistryAuth = &resolvedConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := daemon.pullImageWithReference(ctx, ref, nil, pullRegistryAuth, output); err != nil {
|
// TODO @jhowardmsft LCOW Support: For now, use the runtime operating system of the host.
|
||||||
|
// When it gets to the builder part, this will need revisiting. There would have to be
|
||||||
|
// some indication from the user either through CLI flag to build, or through an explicit
|
||||||
|
// mechanism in a dockerfile such as a parser directive extension or an addition to
|
||||||
|
// the FROM statement syntax.
|
||||||
|
if err := daemon.pullImageWithReference(ctx, ref, runtime.GOOS, nil, pullRegistryAuth, output); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return daemon.GetImage(name)
|
return daemon.GetImage(name)
|
||||||
|
|
|
@ -30,7 +30,7 @@ type Backend interface {
|
||||||
FindNetwork(idName string) (libnetwork.Network, error)
|
FindNetwork(idName string) (libnetwork.Network, error)
|
||||||
SetupIngress(clustertypes.NetworkCreateRequest, string) (<-chan struct{}, error)
|
SetupIngress(clustertypes.NetworkCreateRequest, string) (<-chan struct{}, error)
|
||||||
ReleaseIngress() (<-chan struct{}, error)
|
ReleaseIngress() (<-chan struct{}, error)
|
||||||
PullImage(ctx context.Context, image, tag string, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error
|
PullImage(ctx context.Context, image, tag, platform string, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error
|
||||||
CreateManagedContainer(config types.ContainerCreateConfig) (container.ContainerCreateCreatedBody, error)
|
CreateManagedContainer(config types.ContainerCreateConfig) (container.ContainerCreateCreatedBody, error)
|
||||||
ContainerStart(name string, hostConfig *container.HostConfig, checkpoint string, checkpointDir string) error
|
ContainerStart(name string, hostConfig *container.HostConfig, checkpoint string, checkpointDir string) error
|
||||||
ContainerStop(name string, seconds *int) error
|
ContainerStop(name string, seconds *int) error
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
@ -20,6 +21,7 @@ import (
|
||||||
containerpkg "github.com/docker/docker/container"
|
containerpkg "github.com/docker/docker/container"
|
||||||
"github.com/docker/docker/daemon/cluster/convert"
|
"github.com/docker/docker/daemon/cluster/convert"
|
||||||
executorpkg "github.com/docker/docker/daemon/cluster/executor"
|
executorpkg "github.com/docker/docker/daemon/cluster/executor"
|
||||||
|
"github.com/docker/docker/pkg/system"
|
||||||
"github.com/docker/libnetwork"
|
"github.com/docker/libnetwork"
|
||||||
"github.com/docker/swarmkit/agent/exec"
|
"github.com/docker/swarmkit/agent/exec"
|
||||||
"github.com/docker/swarmkit/api"
|
"github.com/docker/swarmkit/api"
|
||||||
|
@ -88,7 +90,13 @@ func (c *containerAdapter) pullImage(ctx context.Context) error {
|
||||||
pr, pw := io.Pipe()
|
pr, pw := io.Pipe()
|
||||||
metaHeaders := map[string][]string{}
|
metaHeaders := map[string][]string{}
|
||||||
go func() {
|
go func() {
|
||||||
err := c.backend.PullImage(ctx, c.container.image(), "", metaHeaders, authConfig, pw)
|
// TODO @jhowardmsft LCOW Support: This will need revisiting as
|
||||||
|
// the stack is built up to include LCOW support for swarm.
|
||||||
|
platform := runtime.GOOS
|
||||||
|
if platform == "windows" && system.LCOWSupported() {
|
||||||
|
platform = "linux"
|
||||||
|
}
|
||||||
|
err := c.backend.PullImage(ctx, c.container.image(), "", platform, metaHeaders, authConfig, pw)
|
||||||
pw.CloseWithError(err)
|
pw.CloseWithError(err)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ import (
|
||||||
|
|
||||||
// PullImage initiates a pull operation. image is the repository name to pull, and
|
// PullImage initiates a pull operation. image is the repository name to pull, and
|
||||||
// tag may be either empty, or indicate a specific tag to pull.
|
// tag may be either empty, or indicate a specific tag to pull.
|
||||||
func (daemon *Daemon) PullImage(ctx context.Context, image, tag string, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error {
|
func (daemon *Daemon) PullImage(ctx context.Context, image, tag, platform string, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error {
|
||||||
// Special case: "pull -a" may send an image name with a
|
// Special case: "pull -a" may send an image name with a
|
||||||
// trailing :. This is ugly, but let's not break API
|
// trailing :. This is ugly, but let's not break API
|
||||||
// compatibility.
|
// compatibility.
|
||||||
|
@ -43,10 +43,10 @@ func (daemon *Daemon) PullImage(ctx context.Context, image, tag string, metaHead
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return daemon.pullImageWithReference(ctx, ref, metaHeaders, authConfig, outStream)
|
return daemon.pullImageWithReference(ctx, ref, platform, metaHeaders, authConfig, outStream)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (daemon *Daemon) pullImageWithReference(ctx context.Context, ref reference.Named, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error {
|
func (daemon *Daemon) pullImageWithReference(ctx context.Context, ref reference.Named, platform string, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error {
|
||||||
// Include a buffer so that slow client connections don't affect
|
// Include a buffer so that slow client connections don't affect
|
||||||
// transfer performance.
|
// transfer performance.
|
||||||
progressChan := make(chan progress.Progress, 100)
|
progressChan := make(chan progress.Progress, 100)
|
||||||
|
@ -60,11 +60,10 @@ func (daemon *Daemon) pullImageWithReference(ctx context.Context, ref reference.
|
||||||
close(writesDone)
|
close(writesDone)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------
|
// Default to the host OS platform in case it hasn't been populated with an explicit value.
|
||||||
// TODO @jhowardmsft LCOW. For now, use just the store for the host OS. This will
|
if platform == "" {
|
||||||
// need some work to complete - we won't know the platform until after metadata
|
platform = runtime.GOOS
|
||||||
// is pulled from the repository. This affects plugin as well to complete.
|
}
|
||||||
// ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
imagePullConfig := &distribution.ImagePullConfig{
|
imagePullConfig := &distribution.ImagePullConfig{
|
||||||
Config: distribution.Config{
|
Config: distribution.Config{
|
||||||
|
@ -73,12 +72,13 @@ func (daemon *Daemon) pullImageWithReference(ctx context.Context, ref reference.
|
||||||
ProgressOutput: progress.ChanOutput(progressChan),
|
ProgressOutput: progress.ChanOutput(progressChan),
|
||||||
RegistryService: daemon.RegistryService,
|
RegistryService: daemon.RegistryService,
|
||||||
ImageEventLogger: daemon.LogImageEvent,
|
ImageEventLogger: daemon.LogImageEvent,
|
||||||
MetadataStore: daemon.stores[runtime.GOOS].distributionMetadataStore,
|
MetadataStore: daemon.stores[platform].distributionMetadataStore,
|
||||||
ImageStore: distribution.NewImageConfigStoreFromStore(daemon.stores[runtime.GOOS].imageStore),
|
ImageStore: distribution.NewImageConfigStoreFromStore(daemon.stores[platform].imageStore),
|
||||||
ReferenceStore: daemon.stores[runtime.GOOS].referenceStore,
|
ReferenceStore: daemon.stores[platform].referenceStore,
|
||||||
},
|
},
|
||||||
DownloadManager: daemon.downloadManager,
|
DownloadManager: daemon.downloadManager,
|
||||||
Schema2Types: distribution.ImageTypes,
|
Schema2Types: distribution.ImageTypes,
|
||||||
|
Platform: platform,
|
||||||
}
|
}
|
||||||
|
|
||||||
err := distribution.Pull(ctx, ref, imagePullConfig)
|
err := distribution.Pull(ctx, ref, imagePullConfig)
|
||||||
|
|
|
@ -59,6 +59,9 @@ type ImagePullConfig struct {
|
||||||
// Schema2Types is the valid schema2 configuration types allowed
|
// Schema2Types is the valid schema2 configuration types allowed
|
||||||
// by the pull operation.
|
// by the pull operation.
|
||||||
Schema2Types []string
|
Schema2Types []string
|
||||||
|
// Platform is the requested platform of the image being pulled to ensure it can be validated
|
||||||
|
// when the host platform supports multiple image operating systems.
|
||||||
|
Platform string
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImagePushConfig stores push configuration.
|
// ImagePushConfig stores push configuration.
|
||||||
|
|
Loading…
Add table
Reference in a new issue