Merge pull request #3664 from thockin/pull-if

Pull if
This commit is contained in:
Tim Hockin 2015-01-21 13:05:28 -08:00
commit 30219f8dfa
13 changed files with 186 additions and 17 deletions

View File

@ -15,7 +15,7 @@ All users of the cluster will have access to any private registry in the `.docke
## Preloading Images
Be default, the kubelet will try to pull each image from the specified registry.
However, if the `imagePullPolicy` property of the container is set to `PullIfNotPresent` or `PullNever`,
However, if the `imagePullPolicy` property of the container is set to `IfNotPresent` or `Never`,
then a local image is used (preferentially or exclusively, respectively).
This can be used to preload certain images for speed or as an alternative to authenticating to a private registry.

View File

@ -131,6 +131,10 @@ var apiObjectFuzzer = fuzz.New().NilChance(.5).NumElements(1, 1).Funcs(
c.RandString(): c.RandString(),
}
},
func(p *internal.PullPolicy, c fuzz.Continue) {
policies := []internal.PullPolicy{internal.PullAlways, internal.PullNever, internal.PullIfNotPresent}
*p = policies[c.Rand.Intn(len(policies))]
},
)
func TestInternalRoundTrip(t *testing.T) {

View File

@ -146,7 +146,6 @@ func fuzzerFor(t *testing.T, version string, src rand.Source) *fuzz.Fuzzer {
c.RandString(): c.RandString(),
}
},
func(q *resource.Quantity, c fuzz.Continue) {
// Real Quantity fuzz testing is done elsewhere;
// this limited subset of functionality survives
@ -156,6 +155,10 @@ func fuzzerFor(t *testing.T, version string, src rand.Source) *fuzz.Fuzzer {
//q.Amount.SetScale(inf.Scale(-c.Intn(12)))
q.Amount.SetUnscaled(c.Int63n(1000))
},
func(p *api.PullPolicy, c fuzz.Continue) {
policies := []api.PullPolicy{api.PullAlways, api.PullNever, api.PullIfNotPresent}
*p = policies[c.Rand.Intn(len(policies))]
},
)
return f
}

View File

@ -291,11 +291,11 @@ type PullPolicy string
const (
// PullAlways means that kubelet always attempts to pull the latest image. Container will fail If the pull fails.
PullAlways PullPolicy = "PullAlways"
PullAlways PullPolicy = "Always"
// PullNever means that kubelet never pulls an image, but only uses a local image. Container will fail if the image isn't present
PullNever PullPolicy = "PullNever"
PullNever PullPolicy = "Never"
// PullIfNotPresent means that kubelet pulls if the image isn't present on disk. Container will fail if the image isn't present and the pull fails.
PullIfNotPresent PullPolicy = "PullIfNotPresent"
PullIfNotPresent PullPolicy = "IfNotPresent"
)
// Container represents a single container that is expected to be run on the host.

View File

@ -707,6 +707,39 @@ func init() {
}
return nil
},
func(in *newer.PullPolicy, out *PullPolicy, s conversion.Scope) error {
switch *in {
case newer.PullAlways:
*out = PullAlways
case newer.PullNever:
*out = PullNever
case newer.PullIfNotPresent:
*out = PullIfNotPresent
case "":
*out = ""
default:
// Let unknown values through - they will get caught by validation
*out = PullPolicy(*in)
}
return nil
},
func(in *PullPolicy, out *newer.PullPolicy, s conversion.Scope) error {
switch *in {
case PullAlways:
*out = newer.PullAlways
case PullNever:
*out = newer.PullNever
case PullIfNotPresent:
*out = newer.PullIfNotPresent
case "":
*out = ""
default:
// Let unknown values through - they will get caught by validation
*out = newer.PullPolicy(*in)
}
return nil
},
)
if err != nil {
// If one of the conversion functions is malformed, detect it immediately.

View File

@ -270,3 +270,49 @@ func TestServiceEmptySelector(t *testing.T) {
t.Errorf("unexpected selector: %#v", obj)
}
}
func TestPullPolicyConversion(t *testing.T) {
table := []struct {
versioned current.PullPolicy
internal newer.PullPolicy
}{
{
versioned: current.PullAlways,
internal: newer.PullAlways,
}, {
versioned: current.PullNever,
internal: newer.PullNever,
}, {
versioned: current.PullIfNotPresent,
internal: newer.PullIfNotPresent,
}, {
versioned: "",
internal: "",
}, {
versioned: "invalid value",
internal: "invalid value",
},
}
for _, item := range table {
var got newer.PullPolicy
err := Convert(&item.versioned, &got)
if err != nil {
t.Errorf("Unexpected error: %v", err)
continue
}
if e, a := item.internal, got; e != a {
t.Errorf("Expected: %q, got %q", e, a)
}
}
for _, item := range table {
var got current.PullPolicy
err := Convert(&item.internal, &got)
if err != nil {
t.Errorf("Unexpected error: %v", err)
continue
}
if e, a := item.versioned, got; e != a {
t.Errorf("Expected: %q, got %q", e, a)
}
}
}

View File

@ -620,6 +620,39 @@ func init() {
}
return nil
},
func(in *newer.PullPolicy, out *PullPolicy, s conversion.Scope) error {
switch *in {
case newer.PullAlways:
*out = PullAlways
case newer.PullNever:
*out = PullNever
case newer.PullIfNotPresent:
*out = PullIfNotPresent
case "":
*out = ""
default:
// Let unknown values through - they will get caught by validation
*out = PullPolicy(*in)
}
return nil
},
func(in *PullPolicy, out *newer.PullPolicy, s conversion.Scope) error {
switch *in {
case PullAlways:
*out = newer.PullAlways
case PullNever:
*out = newer.PullNever
case PullIfNotPresent:
*out = newer.PullIfNotPresent
case "":
*out = ""
default:
// Let unknown values through - they will get caught by validation
*out = newer.PullPolicy(*in)
}
return nil
},
)
if err != nil {
// If one of the conversion functions is malformed, detect it immediately.

View File

@ -100,3 +100,49 @@ func TestNodeConversion(t *testing.T) {
t.Errorf("unexpected encoding: %s - %#v", m["kind"], string(data))
}
}
func TestPullPolicyConversion(t *testing.T) {
table := []struct {
versioned current.PullPolicy
internal newer.PullPolicy
}{
{
versioned: current.PullAlways,
internal: newer.PullAlways,
}, {
versioned: current.PullNever,
internal: newer.PullNever,
}, {
versioned: current.PullIfNotPresent,
internal: newer.PullIfNotPresent,
}, {
versioned: "",
internal: "",
}, {
versioned: "invalid value",
internal: "invalid value",
},
}
for _, item := range table {
var got newer.PullPolicy
err := newer.Scheme.Convert(&item.versioned, &got)
if err != nil {
t.Errorf("Unexpected error: %v", err)
continue
}
if e, a := item.internal, got; e != a {
t.Errorf("Expected: %q, got %q", e, a)
}
}
for _, item := range table {
var got current.PullPolicy
err := newer.Scheme.Convert(&item.internal, &got)
if err != nil {
t.Errorf("Unexpected error: %v", err)
continue
}
if e, a := item.versioned, got; e != a {
t.Errorf("Expected: %q, got %q", e, a)
}
}
}

View File

@ -309,11 +309,11 @@ type PullPolicy string
const (
// PullAlways means that kubelet always attempts to pull the latest image. Container will fail If the pull fails.
PullAlways PullPolicy = "PullAlways"
PullAlways PullPolicy = "Always"
// PullNever means that kubelet never pulls an image, but only uses a local image. Container will fail if the image isn't present
PullNever PullPolicy = "PullNever"
PullNever PullPolicy = "Never"
// PullIfNotPresent means that kubelet pulls if the image isn't present on disk. Container will fail if the image isn't present and the pull fails.
PullIfNotPresent PullPolicy = "PullIfNotPresent"
PullIfNotPresent PullPolicy = "IfNotPresent"
)
// Container represents a single container that is expected to be run on the host.

View File

@ -118,6 +118,10 @@ var apiObjectFuzzer = fuzz.New().NilChance(.5).NumElements(1, 1).Funcs(
c.RandString(): c.RandString(),
}
},
func(p *api.PullPolicy, c fuzz.Continue) {
policies := []api.PullPolicy{api.PullAlways, api.PullNever, api.PullIfNotPresent}
*p = policies[c.Rand.Intn(len(policies))]
},
)
func TestLoad(t *testing.T) {

View File

@ -227,27 +227,27 @@ func TestValidatePullPolicy(t *testing.T) {
}
testCases := map[string]T{
"NotPresent1": {
api.Container{Name: "abc", Image: "image:latest", ImagePullPolicy: "PullIfNotPresent"},
api.Container{Name: "abc", Image: "image:latest", ImagePullPolicy: "IfNotPresent"},
api.PullIfNotPresent,
},
"NotPresent2": {
api.Container{Name: "abc1", Image: "image", ImagePullPolicy: "PullIfNotPresent"},
api.Container{Name: "abc1", Image: "image", ImagePullPolicy: "IfNotPresent"},
api.PullIfNotPresent,
},
"Always1": {
api.Container{Name: "123", Image: "image:latest", ImagePullPolicy: "PullAlways"},
api.Container{Name: "123", Image: "image:latest", ImagePullPolicy: "Always"},
api.PullAlways,
},
"Always2": {
api.Container{Name: "1234", Image: "image", ImagePullPolicy: "PullAlways"},
api.Container{Name: "1234", Image: "image", ImagePullPolicy: "Always"},
api.PullAlways,
},
"Never1": {
api.Container{Name: "abc-123", Image: "image:latest", ImagePullPolicy: "PullNever"},
api.Container{Name: "abc-123", Image: "image:latest", ImagePullPolicy: "Never"},
api.PullNever,
},
"Never2": {
api.Container{Name: "abc-1234", Image: "image", ImagePullPolicy: "PullNever"},
api.Container{Name: "abc-1234", Image: "image", ImagePullPolicy: "Never"},
api.PullNever,
},
"DefaultToNotPresent": {api.Container{Name: "notPresent", Image: "image"}, api.PullIfNotPresent},

View File

@ -157,7 +157,7 @@ func TestExtractFromHTTP(t *testing.T) {
Name: "1",
Image: "foo",
TerminationMessagePath: "/dev/termination-log",
ImagePullPolicy: "PullIfNotPresent"}},
ImagePullPolicy: "IfNotPresent"}},
},
},
api.BoundPod{
@ -171,7 +171,7 @@ func TestExtractFromHTTP(t *testing.T) {
Name: "1",
Image: "foo",
TerminationMessagePath: "/dev/termination-log",
ImagePullPolicy: "PullIfNotPresent"}},
ImagePullPolicy: "IfNotPresent"}},
},
}),
},

View File

@ -487,7 +487,7 @@ func TestSyncPodsCreatesNetAndContainerPullsImage(t *testing.T) {
},
Spec: api.PodSpec{
Containers: []api.Container{
{Name: "bar", Image: "something", ImagePullPolicy: "PullIfNotPresent"},
{Name: "bar", Image: "something", ImagePullPolicy: "IfNotPresent"},
},
},
},