mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-14 22:33:34 +00:00
Merge pull request #17278 from ZJU-SEL/fix-nil-tag
Auto commit by PR queue bot
This commit is contained in:
commit
810181fb7b
@ -60,6 +60,9 @@ pull an image if it already exists. If you would like to always force a pull
|
|||||||
you must set a pull image policy of `Always` or specify a `:latest` tag on
|
you must set a pull image policy of `Always` or specify a `:latest` tag on
|
||||||
your image.
|
your image.
|
||||||
|
|
||||||
|
If you did not specify tag of your image, it will be assumed as `:latest`, with
|
||||||
|
pull image policy of `Always` correspondingly.
|
||||||
|
|
||||||
## Using a Private Registry
|
## Using a Private Registry
|
||||||
|
|
||||||
Private registries may require keys to read images from them.
|
Private registries may require keys to read images from them.
|
||||||
|
@ -17,11 +17,10 @@ limitations under the License.
|
|||||||
package v1
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
"k8s.io/kubernetes/pkg/util"
|
||||||
"k8s.io/kubernetes/pkg/util/intstr"
|
"k8s.io/kubernetes/pkg/util/intstr"
|
||||||
|
"k8s.io/kubernetes/pkg/util/parsers"
|
||||||
)
|
)
|
||||||
|
|
||||||
func addDefaultingFuncs() {
|
func addDefaultingFuncs() {
|
||||||
@ -67,10 +66,10 @@ func addDefaultingFuncs() {
|
|||||||
},
|
},
|
||||||
func(obj *Container) {
|
func(obj *Container) {
|
||||||
if obj.ImagePullPolicy == "" {
|
if obj.ImagePullPolicy == "" {
|
||||||
// TODO(dchen1107): Move ParseImageName code to pkg/util
|
_, tag := parsers.ParseImageName(obj.Image)
|
||||||
parts := strings.Split(obj.Image, ":")
|
|
||||||
// Check image tag
|
// Check image tag
|
||||||
if parts[len(parts)-1] == "latest" {
|
|
||||||
|
if tag == "latest" {
|
||||||
obj.ImagePullPolicy = PullAlways
|
obj.ImagePullPolicy = PullAlways
|
||||||
} else {
|
} else {
|
||||||
obj.ImagePullPolicy = PullIfNotPresent
|
obj.ImagePullPolicy = PullIfNotPresent
|
||||||
|
@ -111,7 +111,7 @@ func TestReadPodsFromFile(t *testing.T) {
|
|||||||
Name: "image",
|
Name: "image",
|
||||||
Image: "test/image",
|
Image: "test/image",
|
||||||
TerminationMessagePath: "/dev/termination-log",
|
TerminationMessagePath: "/dev/termination-log",
|
||||||
ImagePullPolicy: "IfNotPresent",
|
ImagePullPolicy: "Always",
|
||||||
SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults()}},
|
SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults()}},
|
||||||
SecurityContext: &api.PodSecurityContext{},
|
SecurityContext: &api.PodSecurityContext{},
|
||||||
},
|
},
|
||||||
|
@ -199,7 +199,7 @@ func TestExtractPodsFromHTTP(t *testing.T) {
|
|||||||
},
|
},
|
||||||
Spec: api.PodSpec{
|
Spec: api.PodSpec{
|
||||||
NodeName: hostname,
|
NodeName: hostname,
|
||||||
Containers: []api.Container{{Name: "2", Image: "bar", ImagePullPolicy: ""}},
|
Containers: []api.Container{{Name: "2", Image: "bar:bartag", ImagePullPolicy: ""}},
|
||||||
SecurityContext: &api.PodSecurityContext{},
|
SecurityContext: &api.PodSecurityContext{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -247,7 +247,7 @@ func TestExtractPodsFromHTTP(t *testing.T) {
|
|||||||
|
|
||||||
Containers: []api.Container{{
|
Containers: []api.Container{{
|
||||||
Name: "2",
|
Name: "2",
|
||||||
Image: "bar",
|
Image: "bar:bartag",
|
||||||
TerminationMessagePath: "/dev/termination-log",
|
TerminationMessagePath: "/dev/termination-log",
|
||||||
ImagePullPolicy: "IfNotPresent",
|
ImagePullPolicy: "IfNotPresent",
|
||||||
}},
|
}},
|
||||||
|
@ -25,7 +25,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/docker/pkg/jsonmessage"
|
"github.com/docker/docker/pkg/jsonmessage"
|
||||||
"github.com/docker/docker/pkg/parsers"
|
|
||||||
docker "github.com/fsouza/go-dockerclient"
|
docker "github.com/fsouza/go-dockerclient"
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
@ -35,6 +34,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/types"
|
"k8s.io/kubernetes/pkg/types"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
"k8s.io/kubernetes/pkg/util"
|
||||||
utilerrors "k8s.io/kubernetes/pkg/util/errors"
|
utilerrors "k8s.io/kubernetes/pkg/util/errors"
|
||||||
|
"k8s.io/kubernetes/pkg/util/parsers"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -115,10 +115,6 @@ func newDockerPuller(client DockerInterface, qps float32, burst int) DockerPulle
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseImageName(image string) (string, string) {
|
|
||||||
return parsers.ParseRepositoryTag(image)
|
|
||||||
}
|
|
||||||
|
|
||||||
func filterHTTPError(err error, image string) error {
|
func filterHTTPError(err error, image string) error {
|
||||||
// docker/docker/pull/11314 prints detailed error info for docker pull.
|
// docker/docker/pull/11314 prints detailed error info for docker pull.
|
||||||
// When it hits 502, it returns a verbose html output including an inline svg,
|
// When it hits 502, it returns a verbose html output including an inline svg,
|
||||||
@ -136,12 +132,8 @@ func filterHTTPError(err error, image string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p dockerPuller) Pull(image string, secrets []api.Secret) error {
|
func (p dockerPuller) Pull(image string, secrets []api.Secret) error {
|
||||||
repoToPull, tag := parseImageName(image)
|
|
||||||
|
|
||||||
// If no tag was specified, use the default "latest".
|
// If no tag was specified, use the default "latest".
|
||||||
if len(tag) == 0 {
|
repoToPull, tag := parsers.ParseImageName(image)
|
||||||
tag = "latest"
|
|
||||||
}
|
|
||||||
|
|
||||||
opts := docker.PullImageOptions{
|
opts := docker.PullImageOptions{
|
||||||
Repository: repoToPull,
|
Repository: repoToPull,
|
||||||
|
@ -37,6 +37,7 @@ import (
|
|||||||
kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
|
kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
|
||||||
"k8s.io/kubernetes/pkg/types"
|
"k8s.io/kubernetes/pkg/types"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
"k8s.io/kubernetes/pkg/util"
|
||||||
|
"k8s.io/kubernetes/pkg/util/parsers"
|
||||||
)
|
)
|
||||||
|
|
||||||
func verifyCalls(t *testing.T, fakeDocker *FakeDockerClient, calls []string) {
|
func verifyCalls(t *testing.T, fakeDocker *FakeDockerClient, calls []string) {
|
||||||
@ -204,16 +205,16 @@ func TestParseImageName(t *testing.T) {
|
|||||||
name string
|
name string
|
||||||
tag string
|
tag string
|
||||||
}{
|
}{
|
||||||
{"ubuntu", "ubuntu", ""},
|
{"ubuntu", "ubuntu", "latest"},
|
||||||
{"ubuntu:2342", "ubuntu", "2342"},
|
{"ubuntu:2342", "ubuntu", "2342"},
|
||||||
{"ubuntu:latest", "ubuntu", "latest"},
|
{"ubuntu:latest", "ubuntu", "latest"},
|
||||||
{"foo/bar:445566", "foo/bar", "445566"},
|
{"foo/bar:445566", "foo/bar", "445566"},
|
||||||
{"registry.example.com:5000/foobar", "registry.example.com:5000/foobar", ""},
|
{"registry.example.com:5000/foobar", "registry.example.com:5000/foobar", "latest"},
|
||||||
{"registry.example.com:5000/foobar:5342", "registry.example.com:5000/foobar", "5342"},
|
{"registry.example.com:5000/foobar:5342", "registry.example.com:5000/foobar", "5342"},
|
||||||
{"registry.example.com:5000/foobar:latest", "registry.example.com:5000/foobar", "latest"},
|
{"registry.example.com:5000/foobar:latest", "registry.example.com:5000/foobar", "latest"},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
name, tag := parseImageName(test.imageName)
|
name, tag := parsers.ParseImageName(test.imageName)
|
||||||
if name != test.name || tag != test.tag {
|
if name != test.name || tag != test.tag {
|
||||||
t.Errorf("Expected name/tag: %s/%s, got %s/%s", test.name, test.tag, name, tag)
|
t.Errorf("Expected name/tag: %s/%s, got %s/%s", test.name, test.tag, name, tag)
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,6 @@ import (
|
|||||||
appctypes "github.com/appc/spec/schema/types"
|
appctypes "github.com/appc/spec/schema/types"
|
||||||
"github.com/coreos/go-systemd/unit"
|
"github.com/coreos/go-systemd/unit"
|
||||||
rktapi "github.com/coreos/rkt/api/v1alpha"
|
rktapi "github.com/coreos/rkt/api/v1alpha"
|
||||||
"github.com/docker/docker/pkg/parsers"
|
|
||||||
docker "github.com/fsouza/go-dockerclient"
|
docker "github.com/fsouza/go-dockerclient"
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
@ -50,6 +49,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/types"
|
"k8s.io/kubernetes/pkg/types"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
"k8s.io/kubernetes/pkg/util"
|
||||||
utilexec "k8s.io/kubernetes/pkg/util/exec"
|
utilexec "k8s.io/kubernetes/pkg/util/exec"
|
||||||
|
"k8s.io/kubernetes/pkg/util/parsers"
|
||||||
"k8s.io/kubernetes/pkg/util/sets"
|
"k8s.io/kubernetes/pkg/util/sets"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -390,23 +390,12 @@ func setApp(app *appctypes.App, c *api.Container, opts *kubecontainer.RunContain
|
|||||||
return setIsolators(app, c)
|
return setIsolators(app, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseImageName parses a docker image string into two parts: repo and tag.
|
|
||||||
// If tag is empty, return the defaultImageTag.
|
|
||||||
func parseImageName(image string) (string, string) {
|
|
||||||
repoToPull, tag := parsers.ParseRepositoryTag(image)
|
|
||||||
// If no tag was specified, use the default "latest".
|
|
||||||
if len(tag) == 0 {
|
|
||||||
tag = defaultImageTag
|
|
||||||
}
|
|
||||||
return repoToPull, tag
|
|
||||||
}
|
|
||||||
|
|
||||||
// getImageManifest invokes 'rkt image cat-manifest' to retrive the image manifest
|
// getImageManifest invokes 'rkt image cat-manifest' to retrive the image manifest
|
||||||
// for the image.
|
// for the image.
|
||||||
func (r *Runtime) getImageManifest(image string) (*appcschema.ImageManifest, error) {
|
func (r *Runtime) getImageManifest(image string) (*appcschema.ImageManifest, error) {
|
||||||
var manifest appcschema.ImageManifest
|
var manifest appcschema.ImageManifest
|
||||||
|
|
||||||
repoToPull, tag := parseImageName(image)
|
repoToPull, tag := parsers.ParseImageName(image)
|
||||||
imgName, err := appctypes.SanitizeACIdentifier(repoToPull)
|
imgName, err := appctypes.SanitizeACIdentifier(repoToPull)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -930,7 +919,7 @@ func (r *Runtime) PullImage(image kubecontainer.ImageSpec, pullSecrets []api.Sec
|
|||||||
img := image.Image
|
img := image.Image
|
||||||
// TODO(yifan): The credential operation is a copy from dockertools package,
|
// TODO(yifan): The credential operation is a copy from dockertools package,
|
||||||
// Need to resolve the code duplication.
|
// Need to resolve the code duplication.
|
||||||
repoToPull, _ := parseImageName(img)
|
repoToPull, _ := parsers.ParseImageName(img)
|
||||||
keyring, err := credentialprovider.MakeDockerKeyring(pullSecrets, r.dockerKeyring)
|
keyring, err := credentialprovider.MakeDockerKeyring(pullSecrets, r.dockerKeyring)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -956,7 +945,7 @@ func (r *Runtime) PullImage(image kubecontainer.ImageSpec, pullSecrets []api.Sec
|
|||||||
|
|
||||||
// TODO(yifan): Searching the image via 'rkt images' might not be the most efficient way.
|
// TODO(yifan): Searching the image via 'rkt images' might not be the most efficient way.
|
||||||
func (r *Runtime) IsImagePresent(image kubecontainer.ImageSpec) (bool, error) {
|
func (r *Runtime) IsImagePresent(image kubecontainer.ImageSpec) (bool, error) {
|
||||||
repoToPull, tag := parseImageName(image.Image)
|
repoToPull, tag := parsers.ParseImageName(image.Image)
|
||||||
// Example output of 'rkt image list --fields=name':
|
// Example output of 'rkt image list --fields=name':
|
||||||
//
|
//
|
||||||
// NAME
|
// NAME
|
||||||
|
36
pkg/util/parsers/parsers.go
Normal file
36
pkg/util/parsers/parsers.go
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package parsers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/docker/docker/pkg/parsers"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
defaultImageTag = "latest"
|
||||||
|
)
|
||||||
|
|
||||||
|
// parseImageName parses a docker image string into two parts: repo and tag.
|
||||||
|
// If tag is empty, return the defaultImageTag.
|
||||||
|
func ParseImageName(image string) (string, string) {
|
||||||
|
repoToPull, tag := parsers.ParseRepositoryTag(image)
|
||||||
|
// If no tag was specified, use the default "latest".
|
||||||
|
if len(tag) == 0 {
|
||||||
|
tag = defaultImageTag
|
||||||
|
}
|
||||||
|
return repoToPull, tag
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user