diff --git a/pkg/api/validation/validation.go b/pkg/api/validation/validation.go index 9e460d89a2..63d9ef5fff 100644 --- a/pkg/api/validation/validation.go +++ b/pkg/api/validation/validation.go @@ -536,6 +536,10 @@ func validatePullPolicy(ctr *api.Container) errs.ValidationErrorList { func validateContainers(containers []api.Container, volumes util.StringSet) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} + if len(containers) == 0 { + return append(allErrs, errs.NewFieldRequired("")) + } + allNames := util.StringSet{} for i, ctr := range containers { cErrs := errs.ValidationErrorList{} diff --git a/pkg/api/validation/validation_test.go b/pkg/api/validation/validation_test.go index d4c7318968..331f6f4429 100644 --- a/pkg/api/validation/validation_test.go +++ b/pkg/api/validation/validation_test.go @@ -723,6 +723,11 @@ func TestValidatePodSpec(t *testing.T) { Volumes: []api.Volume{{}}, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + }, + "no containers": { + RestartPolicy: api.RestartPolicyAlways, + DNSPolicy: api.DNSClusterFirst, }, "bad container": { Containers: []api.Container{{}}, @@ -732,10 +737,12 @@ func TestValidatePodSpec(t *testing.T) { "bad DNS policy": { DNSPolicy: api.DNSPolicy("invalid"), RestartPolicy: api.RestartPolicyAlways, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, }, "bad restart policy": { RestartPolicy: "UnknowPolicy", DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, }, } for k, v := range failureCases { @@ -784,6 +791,7 @@ func TestValidatePod(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, }, }, "bad namespace": { @@ -791,6 +799,7 @@ func TestValidatePod(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, }, }, "bad spec": { @@ -810,12 +819,13 @@ func TestValidatePod(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, }, }, } for k, v := range errorCases { if errs := ValidatePod(&v); len(errs) == 0 { - t.Errorf("expected failure for %s", k) + t.Errorf("expected failure for %q", k) } } } @@ -1216,6 +1226,7 @@ func TestValidateReplicationControllerUpdate(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, }, }, } @@ -1227,6 +1238,7 @@ func TestValidateReplicationControllerUpdate(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, Volumes: []api.Volume{{Name: "gcepd", VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{"my-PD", "ext4", 1, false}}}}, }, }, @@ -1376,6 +1388,7 @@ func TestValidateReplicationController(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, }, }, } @@ -1388,6 +1401,7 @@ func TestValidateReplicationController(t *testing.T) { Volumes: []api.Volume{{Name: "gcepd", VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{"my-PD", "ext4", 1, false}}}}, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, }, }, } @@ -1518,6 +1532,7 @@ func TestValidateReplicationController(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyOnFailure, DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, }, ObjectMeta: api.ObjectMeta{ Labels: validSelector, @@ -1536,6 +1551,7 @@ func TestValidateReplicationController(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyNever, DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, }, ObjectMeta: api.ObjectMeta{ Labels: validSelector, diff --git a/pkg/kubelet/config/config_test.go b/pkg/kubelet/config/config_test.go index 0fcd5b802c..11ec7a3b6d 100644 --- a/pkg/kubelet/config/config_test.go +++ b/pkg/kubelet/config/config_test.go @@ -62,6 +62,7 @@ func CreateValidPod(name, namespace, source string) api.Pod { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, }, } } diff --git a/pkg/kubelet/config/http_test.go b/pkg/kubelet/config/http_test.go index 59baba517b..a004c971b9 100644 --- a/pkg/kubelet/config/http_test.go +++ b/pkg/kubelet/config/http_test.go @@ -151,8 +151,9 @@ func TestExtractFromHTTP(t *testing.T) { }), }, { - desc: "Single manifest without ID", - manifests: v1beta1.ContainerManifest{Version: "v1beta1", UUID: "111"}, + desc: "Single manifest without ID", + manifests: v1beta1.ContainerManifest{Version: "v1beta1", UUID: "111", + Containers: []v1beta1.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}}, expected: CreatePodUpdate(kubelet.SET, kubelet.HTTPSource, api.Pod{ @@ -165,6 +166,11 @@ func TestExtractFromHTTP(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, + Containers: []api.Container{{ + Name: "ctr", + Image: "image", + TerminationMessagePath: "/dev/termination-log", + ImagePullPolicy: "IfNotPresent"}}, }, }), },