From d43f7867282f04d3003c44ee96eb2324c6d2a0aa Mon Sep 17 00:00:00 2001 From: TomSweeneyRedHat Date: Tue, 14 Nov 2017 09:55:00 -0500 Subject: Add docker transport to push image before final failure Signed-off-by: TomSweeneyRedHat Closes: #42 Approved by: rhatdan --- libpod/runtime.go | 2 +- libpod/runtime_img.go | 31 +++++++++++++++++++------------ libpod/util.go | 13 +++++++++++++ test/kpod_push.bats | 12 ++++++++++++ 4 files changed, 45 insertions(+), 13 deletions(-) diff --git a/libpod/runtime.go b/libpod/runtime.go index 39b3677a2..956cc7275 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -53,7 +53,7 @@ var ( defaultRuntimeConfig = RuntimeConfig{ // Leave this empty so containers/storage will use its defaults StorageConfig: storage.StoreOptions{}, - ImageDefaultTransport: "docker://", + ImageDefaultTransport: DefaultTransport, InMemoryState: false, RuntimePath: "/usr/bin/runc", ConmonPath: "/usr/local/libexec/crio/conmon", diff --git a/libpod/runtime_img.go b/libpod/runtime_img.go index 873679b0a..4c81380bb 100644 --- a/libpod/runtime_img.go +++ b/libpod/runtime_img.go @@ -32,12 +32,6 @@ import ( // Runtime API -const ( - // DefaultRegistry is a prefix that we apply to an image name - // to check docker hub first for the image - DefaultRegistry = "docker://" -) - var ( // DockerArchive is the transport we prepend to an image name // when saving to docker-archive @@ -49,7 +43,7 @@ var ( // images to and from a directory DirTransport = "dir" // TransportNames are the supported transports in string form - TransportNames = [...]string{DefaultRegistry, DockerArchive, OCIArchive, "ostree:", "dir:"} + TransportNames = [...]string{DefaultTransport, DockerArchive, OCIArchive, "ostree:", "dir:"} // TarballTransport is the transport for importing a tar archive // and creating a filesystem image TarballTransport = "tarball" @@ -249,7 +243,7 @@ func (k *Image) Decompose() error { return nil } k.beenDecomposed = true - k.Transport = "docker://" + k.Transport = k.runtime.config.ImageDefaultTransport decomposeName := k.Name for _, transport := range TransportNames { if strings.HasPrefix(k.Name, transport) { @@ -460,7 +454,7 @@ func (ips imageDecomposeStruct) returnFQName() string { return fmt.Sprintf("%s%s/%s:%s", ips.transport, ips.registry, ips.imageName, ips.tag) } -func getRegistriesToTry(image string, store storage.Store) ([]*pullStruct, error) { +func getRegistriesToTry(image string, store storage.Store, defaultTransport string) ([]*pullStruct, error) { var pStructs []*pullStruct var imageError = fmt.Sprintf("unable to parse '%s'\n", image) imgRef, err := reference.Parse(image) @@ -483,7 +477,7 @@ func getRegistriesToTry(image string, store storage.Store) ([]*pullStruct, error tag, registry, hasDomain, - "docker://", + defaultTransport, } if pImage.hasRegistry { // If input has a registry, we have to assume they included an image @@ -651,7 +645,7 @@ func (r *Runtime) PullImage(imgName string, options CopyOptions) error { srcRef, err := alltransports.ParseImageName(imgName) if err != nil { // could be trying to pull from registry with short name - pullStructs, err = getRegistriesToTry(imgName, r.store) + pullStructs, err = getRegistriesToTry(imgName, r.store, r.config.ImageDefaultTransport) if err != nil { return errors.Wrap(err, "error getting default registries to try") } @@ -703,7 +697,20 @@ func (r *Runtime) PushImage(source string, destination string, options CopyOptio // Get the destination Image Reference dest, err := alltransports.ParseImageName(destination) if err != nil { - return errors.Wrapf(err, "error getting destination imageReference for %q", destination) + if hasTransport(destination) { + return errors.Wrapf(err, "error getting destination imageReference for %q", destination) + } + // Try adding the images default transport + destination2 := r.config.ImageDefaultTransport + destination + dest, err = alltransports.ParseImageName(destination2) + if err != nil { + // One last try with docker:// as the transport + destination2 = DefaultTransport + destination + dest, err = alltransports.ParseImageName(destination2) + if err != nil { + return errors.Wrapf(err, "error getting destination imageReference for %q", destination) + } + } } signaturePolicyPath := r.config.SignaturePolicyPath diff --git a/libpod/util.go b/libpod/util.go index 61546f23e..c8cbfa2fc 100644 --- a/libpod/util.go +++ b/libpod/util.go @@ -4,9 +4,17 @@ import ( "fmt" "os" "path/filepath" + "strings" "time" ) +// Runtime API constants +const ( + // DefaultTransport is a prefix that we apply to an image name + // to check docker hub first for the image + DefaultTransport = "docker://" +) + // WriteFile writes a provided string to a provided path func WriteFile(content string, path string) error { baseDir := filepath.Dir(path) @@ -42,3 +50,8 @@ func FuncTimer(funcName string) { elapsed := time.Since(time.Now()) fmt.Printf("%s executed in %d ms\n", funcName, elapsed) } + +// hasTransport determines if the image string contains '://', returns bool +func hasTransport(image string) bool { + return strings.Contains(image, "://") +} diff --git a/test/kpod_push.bats b/test/kpod_push.bats index 15672ba82..d9b1811cc 100644 --- a/test/kpod_push.bats +++ b/test/kpod_push.bats @@ -72,3 +72,15 @@ function setup() { echo "$output" [ "$status" -eq 0 ] } + +@test "kpod push without transport" { + run ${KPOD_BINARY} $KPOD_OPTIONS pull "$ALPINE" + echo "$output" + [ "$status" -eq 0 ] + # TODO: The following should fail until a registry is running in Travis CI. + run ${KPOD_BINARY} $KPOD_OPTIONS push "$ALPINE" localhost:5000/my-alpine + echo "$output" + [ "$status" -ne 0 ] + run ${KPOD_BINARY} $KPOD_OPTIONS rmi "$ALPINE" + echo "$output" +} -- cgit v1.2.3-54-g00ecf