mirror of https://github.com/k3s-io/k3s
Move internal types of job from pkg/apis/extensions to pkg/apis/batch
parent
c5df0bf23e
commit
a3b4447305
|
@ -32,7 +32,7 @@ import (
|
|||
|
||||
var (
|
||||
test = flag.BoolP("test", "t", false, "set this flag to generate the client code for the testdata")
|
||||
inputVersions = flag.StringSlice("input", []string{"api/", "extensions/"}, "group/versions that client-gen will generate clients for. At most one version per group is allowed. Specified in the format \"group1/version1,group2/version2...\". Default to \"api/,extensions\"")
|
||||
inputVersions = flag.StringSlice("input", []string{"api/", "extensions/", "batch/"}, "group/versions that client-gen will generate clients for. At most one version per group is allowed. Specified in the format \"group1/version1,group2/version2...\". Default to \"api/,extensions/,batch/\"")
|
||||
clientsetName = flag.StringP("clientset-name", "n", "internalclientset", "the name of the generated clientset package.")
|
||||
clientsetPath = flag.String("clientset-path", "k8s.io/kubernetes/pkg/client/clientset_generated/", "the generated clientset will be output to <clientset-path>/<clientset-name>. Default to \"k8s.io/kubernetes/pkg/client/clientset_generated/\"")
|
||||
clientsetOnly = flag.Bool("clientset-only", false, "when set, client-gen only generates the clientset shell, without generating the individual typed clients")
|
||||
|
|
|
@ -60,6 +60,7 @@ func DefaultNameSystem() string {
|
|||
var fallbackPackages = []string{
|
||||
"k8s.io/kubernetes/pkg/api/unversioned",
|
||||
"k8s.io/kubernetes/pkg/apis/extensions",
|
||||
"k8s.io/kubernetes/pkg/apis/batch",
|
||||
}
|
||||
|
||||
func getInternalTypeFor(context *generator.Context, t *types.Type) (*types.Type, bool) {
|
||||
|
|
|
@ -29,6 +29,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
"k8s.io/kubernetes/pkg/api/validation"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
expvalidation "k8s.io/kubernetes/pkg/apis/extensions/validation"
|
||||
"k8s.io/kubernetes/pkg/capabilities"
|
||||
|
@ -109,7 +110,7 @@ func validateObject(obj runtime.Object) (errors field.ErrorList) {
|
|||
t.Namespace = api.NamespaceDefault
|
||||
}
|
||||
errors = expvalidation.ValidateDeployment(t)
|
||||
case *extensions.Job:
|
||||
case *batch.Job:
|
||||
if t.Namespace == "" {
|
||||
t.Namespace = api.NamespaceDefault
|
||||
}
|
||||
|
@ -237,7 +238,7 @@ func TestExampleObjectSchemas(t *testing.T) {
|
|||
"../docs/user-guide": {
|
||||
"multi-pod": nil,
|
||||
"pod": &api.Pod{},
|
||||
"job": &extensions.Job{},
|
||||
"job": &batch.Job{},
|
||||
"ingress": &extensions.Ingress{},
|
||||
"nginx-deployment": &extensions.Deployment{},
|
||||
"new-nginx-deployment": &extensions.Deployment{},
|
||||
|
@ -405,12 +406,12 @@ func TestExampleObjectSchemas(t *testing.T) {
|
|||
"javaweb-2": &api.Pod{},
|
||||
},
|
||||
"../examples/job/work-queue-1": {
|
||||
"job": &extensions.Job{},
|
||||
"job": &batch.Job{},
|
||||
},
|
||||
"../examples/job/work-queue-2": {
|
||||
"redis-pod": &api.Pod{},
|
||||
"redis-service": &api.Service{},
|
||||
"job": &extensions.Job{},
|
||||
"job": &batch.Job{},
|
||||
},
|
||||
"../examples/azure_file": {
|
||||
"azure": &api.Pod{},
|
||||
|
|
|
@ -28,6 +28,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/api/resource"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
|
@ -156,7 +157,7 @@ func FuzzerFor(t *testing.T, version unversioned.GroupVersion, src rand.Source)
|
|||
j.RollingUpdate = &rollingUpdate
|
||||
}
|
||||
},
|
||||
func(j *extensions.JobSpec, c fuzz.Continue) {
|
||||
func(j *batch.JobSpec, c fuzz.Continue) {
|
||||
c.FuzzNoCustom(j) // fuzz self without calling this function again
|
||||
completions := int(c.Rand.Int31())
|
||||
parallelism := int(c.Rand.Int31())
|
||||
|
|
|
@ -19,7 +19,6 @@ package batch
|
|||
import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
|
@ -47,8 +46,11 @@ func AddToScheme(scheme *runtime.Scheme) {
|
|||
// Adds the list of known types to api.Scheme.
|
||||
func addKnownTypes(scheme *runtime.Scheme) {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&extensions.Job{},
|
||||
&extensions.JobList{},
|
||||
&Job{},
|
||||
&JobList{},
|
||||
&api.ListOptions{},
|
||||
)
|
||||
}
|
||||
|
||||
func (obj *Job) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
|
||||
func (obj *JobList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
Copyright 2016 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 batch
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
)
|
||||
|
||||
// +genclient=true
|
||||
|
||||
// Job represents the configuration of a single job.
|
||||
type Job struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
// Standard object's metadata.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
|
||||
api.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec is a structure defining the expected behavior of a job.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status
|
||||
Spec JobSpec `json:"spec,omitempty"`
|
||||
|
||||
// Status is a structure describing current status of a job.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status
|
||||
Status JobStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// JobList is a collection of jobs.
|
||||
type JobList struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
// Standard list metadata
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
|
||||
unversioned.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Items is the list of Job.
|
||||
Items []Job `json:"items"`
|
||||
}
|
||||
|
||||
// JobSpec describes how the job execution will look like.
|
||||
type JobSpec struct {
|
||||
|
||||
// Parallelism specifies the maximum desired number of pods the job should
|
||||
// run at any given time. The actual number of pods running in steady state will
|
||||
// be less than this number when ((.spec.completions - .status.successful) < .spec.parallelism),
|
||||
// i.e. when the work left to do is less than max parallelism.
|
||||
Parallelism *int `json:"parallelism,omitempty"`
|
||||
|
||||
// Completions specifies the desired number of successfully finished pods the
|
||||
// job should be run with. Setting to nil means that the success of any
|
||||
// pod signals the success of all pods, and allows parallelism to have any positive
|
||||
// value. Setting to 1 means that parallelism is limited to 1 and the success of that
|
||||
// pod signals the success of the job.
|
||||
Completions *int `json:"completions,omitempty"`
|
||||
|
||||
// Optional duration in seconds relative to the startTime that the job may be active
|
||||
// before the system tries to terminate it; value must be positive integer
|
||||
ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty"`
|
||||
|
||||
// Selector is a label query over pods that should match the pod count.
|
||||
// Normally, the system sets this field for you.
|
||||
Selector *unversioned.LabelSelector `json:"selector,omitempty"`
|
||||
|
||||
// ManualSelector controls generation of pod labels and pod selectors.
|
||||
// Leave `manualSelector` unset unless you are certain what you are doing.
|
||||
// When false or unset, the system pick labels unique to this job
|
||||
// and appends those labels to the pod template. When true,
|
||||
// the user is responsible for picking unique labels and specifying
|
||||
// the selector. Failure to pick a unique label may cause this
|
||||
// and other jobs to not function correctly. However, You may see
|
||||
// `manualSelector=true` in jobs that were created with the old `extensions/v1beta1`
|
||||
// API.
|
||||
ManualSelector *bool `json:"manualSelector,omitempty"`
|
||||
|
||||
// Template is the object that describes the pod that will be created when
|
||||
// executing a job.
|
||||
Template api.PodTemplateSpec `json:"template"`
|
||||
}
|
||||
|
||||
// JobStatus represents the current state of a Job.
|
||||
type JobStatus struct {
|
||||
|
||||
// Conditions represent the latest available observations of an object's current state.
|
||||
Conditions []JobCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
|
||||
|
||||
// StartTime represents time when the job was acknowledged by the Job Manager.
|
||||
// It is not guaranteed to be set in happens-before order across separate operations.
|
||||
// It is represented in RFC3339 form and is in UTC.
|
||||
StartTime *unversioned.Time `json:"startTime,omitempty"`
|
||||
|
||||
// CompletionTime represents time when the job was completed. It is not guaranteed to
|
||||
// be set in happens-before order across separate operations.
|
||||
// It is represented in RFC3339 form and is in UTC.
|
||||
CompletionTime *unversioned.Time `json:"completionTime,omitempty"`
|
||||
|
||||
// Active is the number of actively running pods.
|
||||
Active int `json:"active,omitempty"`
|
||||
|
||||
// Succeeded is the number of pods which reached Phase Succeeded.
|
||||
Succeeded int `json:"succeeded,omitempty"`
|
||||
|
||||
// Failed is the number of pods which reached Phase Failed.
|
||||
Failed int `json:"failed,omitempty"`
|
||||
}
|
||||
|
||||
type JobConditionType string
|
||||
|
||||
// These are valid conditions of a job.
|
||||
const (
|
||||
// JobComplete means the job has completed its execution.
|
||||
JobComplete JobConditionType = "Complete"
|
||||
// JobFailed means the job has failed its execution.
|
||||
JobFailed JobConditionType = "Failed"
|
||||
)
|
||||
|
||||
// JobCondition describes current state of a job.
|
||||
type JobCondition struct {
|
||||
// Type of job condition, Complete or Failed.
|
||||
Type JobConditionType `json:"type"`
|
||||
// Status of the condition, one of True, False, Unknown.
|
||||
Status api.ConditionStatus `json:"status"`
|
||||
// Last time the condition was checked.
|
||||
LastProbeTime unversioned.Time `json:"lastProbeTime,omitempty"`
|
||||
// Last time the condition transit from one status to another.
|
||||
LastTransitionTime unversioned.Time `json:"lastTransitionTime,omitempty"`
|
||||
// (brief) reason for the condition's last transition.
|
||||
Reason string `json:"reason,omitempty"`
|
||||
// Human readable message indicating details about last transition.
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
|
@ -18,14 +18,22 @@ package v1
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
v1 "k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/conversion"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
func addConversionFuncs(scheme *runtime.Scheme) {
|
||||
// Add non-generated conversion functions
|
||||
err := scheme.AddConversionFuncs()
|
||||
err := scheme.AddConversionFuncs(
|
||||
Convert_batch_JobSpec_To_v1_JobSpec,
|
||||
Convert_v1_JobSpec_To_batch_JobSpec,
|
||||
)
|
||||
if err != nil {
|
||||
// If one of the conversion functions is malformed, detect it immediately.
|
||||
panic(err)
|
||||
|
@ -45,3 +53,91 @@ func addConversionFuncs(scheme *runtime.Scheme) {
|
|||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func Convert_batch_JobSpec_To_v1_JobSpec(in *batch.JobSpec, out *JobSpec, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*batch.JobSpec))(in)
|
||||
}
|
||||
if in.Parallelism != nil {
|
||||
out.Parallelism = new(int32)
|
||||
*out.Parallelism = int32(*in.Parallelism)
|
||||
} else {
|
||||
out.Parallelism = nil
|
||||
}
|
||||
if in.Completions != nil {
|
||||
out.Completions = new(int32)
|
||||
*out.Completions = int32(*in.Completions)
|
||||
} else {
|
||||
out.Completions = nil
|
||||
}
|
||||
if in.ActiveDeadlineSeconds != nil {
|
||||
out.ActiveDeadlineSeconds = new(int64)
|
||||
*out.ActiveDeadlineSeconds = *in.ActiveDeadlineSeconds
|
||||
} else {
|
||||
out.ActiveDeadlineSeconds = nil
|
||||
}
|
||||
// unable to generate simple pointer conversion for unversioned.LabelSelector -> v1.LabelSelector
|
||||
if in.Selector != nil {
|
||||
out.Selector = new(LabelSelector)
|
||||
if err := Convert_unversioned_LabelSelector_To_v1_LabelSelector(in.Selector, out.Selector, s); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.Selector = nil
|
||||
}
|
||||
if in.ManualSelector != nil {
|
||||
out.ManualSelector = new(bool)
|
||||
*out.ManualSelector = *in.ManualSelector
|
||||
} else {
|
||||
out.ManualSelector = nil
|
||||
}
|
||||
|
||||
if err := v1.Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(&in.Template, &out.Template, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_JobSpec_To_batch_JobSpec(in *JobSpec, out *batch.JobSpec, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*JobSpec))(in)
|
||||
}
|
||||
if in.Parallelism != nil {
|
||||
out.Parallelism = new(int)
|
||||
*out.Parallelism = int(*in.Parallelism)
|
||||
} else {
|
||||
out.Parallelism = nil
|
||||
}
|
||||
if in.Completions != nil {
|
||||
out.Completions = new(int)
|
||||
*out.Completions = int(*in.Completions)
|
||||
} else {
|
||||
out.Completions = nil
|
||||
}
|
||||
if in.ActiveDeadlineSeconds != nil {
|
||||
out.ActiveDeadlineSeconds = new(int64)
|
||||
*out.ActiveDeadlineSeconds = *in.ActiveDeadlineSeconds
|
||||
} else {
|
||||
out.ActiveDeadlineSeconds = nil
|
||||
}
|
||||
// unable to generate simple pointer conversion for v1.LabelSelector -> unversioned.LabelSelector
|
||||
if in.Selector != nil {
|
||||
out.Selector = new(unversioned.LabelSelector)
|
||||
if err := Convert_v1_LabelSelector_To_unversioned_LabelSelector(in.Selector, out.Selector, s); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.Selector = nil
|
||||
}
|
||||
if in.ManualSelector != nil {
|
||||
out.ManualSelector = new(bool)
|
||||
*out.ManualSelector = *in.ManualSelector
|
||||
} else {
|
||||
out.ManualSelector = nil
|
||||
}
|
||||
|
||||
if err := v1.Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(&in.Template, &out.Template, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
Copyright 2016 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 validation
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
unversionedvalidation "k8s.io/kubernetes/pkg/api/unversioned/validation"
|
||||
apivalidation "k8s.io/kubernetes/pkg/api/validation"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
// TODO: generalize for other controller objects that will follow the same pattern, such as ReplicaSet and DaemonSet, and
|
||||
// move to new location. Replace batch.Job with an interface.
|
||||
//
|
||||
// ValidateGeneratedSelector validates that the generated selector on a controller object match the controller object
|
||||
// metadata, and the labels on the pod template are as generated.
|
||||
func ValidateGeneratedSelector(obj *batch.Job) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if obj.Spec.ManualSelector != nil && *obj.Spec.ManualSelector {
|
||||
return allErrs
|
||||
}
|
||||
|
||||
if obj.Spec.Selector == nil {
|
||||
return allErrs // This case should already have been checked in caller. No need for more errors.
|
||||
}
|
||||
|
||||
// If somehow uid was unset then we would get "controller-uid=" as the selector
|
||||
// which is bad.
|
||||
if obj.ObjectMeta.UID == "" {
|
||||
allErrs = append(allErrs, field.Required(field.NewPath("metadata").Child("uid"), ""))
|
||||
}
|
||||
|
||||
// If somehow uid was unset then we would get "controller-uid=" as the selector
|
||||
// which is bad.
|
||||
if obj.ObjectMeta.UID == "" {
|
||||
allErrs = append(allErrs, field.Required(field.NewPath("metadata").Child("uid"), ""))
|
||||
}
|
||||
|
||||
// If selector generation was requested, then expected labels must be
|
||||
// present on pod template, and much match job's uid and name. The
|
||||
// generated (not-manual) selectors/labels ensure no overlap with other
|
||||
// controllers. The manual mode allows orphaning, adoption,
|
||||
// backward-compatibility, and experimentation with new
|
||||
// labeling/selection schemes. Automatic selector generation should
|
||||
// have placed certain labels on the pod, but this could have failed if
|
||||
// the user added coflicting labels. Validate that the expected
|
||||
// generated ones are there.
|
||||
|
||||
allErrs = append(allErrs, apivalidation.ValidateHasLabel(obj.Spec.Template.ObjectMeta, field.NewPath("spec").Child("template").Child("metadata"), "controller-uid", string(obj.UID))...)
|
||||
allErrs = append(allErrs, apivalidation.ValidateHasLabel(obj.Spec.Template.ObjectMeta, field.NewPath("spec").Child("template").Child("metadata"), "job-name", string(obj.Name))...)
|
||||
expectedLabels := make(map[string]string)
|
||||
expectedLabels["controller-uid"] = string(obj.UID)
|
||||
expectedLabels["job-name"] = string(obj.Name)
|
||||
// Whether manually or automatically generated, the selector of the job must match the pods it will produce.
|
||||
if selector, err := unversioned.LabelSelectorAsSelector(obj.Spec.Selector); err == nil {
|
||||
if !selector.Matches(labels.Set(expectedLabels)) {
|
||||
allErrs = append(allErrs, field.Invalid(field.NewPath("spec").Child("selector"), obj.Spec.Selector, "`selector` not auto-generated"))
|
||||
}
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateJob(job *batch.Job) field.ErrorList {
|
||||
// Jobs and rcs have the same name validation
|
||||
allErrs := apivalidation.ValidateObjectMeta(&job.ObjectMeta, true, apivalidation.ValidateReplicationControllerName, field.NewPath("metadata"))
|
||||
allErrs = append(allErrs, ValidateGeneratedSelector(job)...)
|
||||
allErrs = append(allErrs, ValidateJobSpec(&job.Spec, field.NewPath("spec"))...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateJobSpec(spec *batch.JobSpec, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
if spec.Parallelism != nil {
|
||||
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(*spec.Parallelism), fldPath.Child("parallelism"))...)
|
||||
}
|
||||
if spec.Completions != nil {
|
||||
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(*spec.Completions), fldPath.Child("completions"))...)
|
||||
}
|
||||
if spec.ActiveDeadlineSeconds != nil {
|
||||
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(*spec.ActiveDeadlineSeconds), fldPath.Child("activeDeadlineSeconds"))...)
|
||||
}
|
||||
if spec.Selector == nil {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("selector"), ""))
|
||||
} else {
|
||||
allErrs = append(allErrs, unversionedvalidation.ValidateLabelSelector(spec.Selector, fldPath.Child("selector"))...)
|
||||
}
|
||||
|
||||
// Whether manually or automatically generated, the selector of the job must match the pods it will produce.
|
||||
if selector, err := unversioned.LabelSelectorAsSelector(spec.Selector); err == nil {
|
||||
labels := labels.Set(spec.Template.Labels)
|
||||
if !selector.Matches(labels) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("template", "metadata", "labels"), spec.Template.Labels, "`selector` does not match template `labels`"))
|
||||
}
|
||||
}
|
||||
|
||||
allErrs = append(allErrs, apivalidation.ValidatePodTemplateSpec(&spec.Template, fldPath.Child("template"))...)
|
||||
if spec.Template.Spec.RestartPolicy != api.RestartPolicyOnFailure &&
|
||||
spec.Template.Spec.RestartPolicy != api.RestartPolicyNever {
|
||||
allErrs = append(allErrs, field.NotSupported(fldPath.Child("template", "spec", "restartPolicy"),
|
||||
spec.Template.Spec.RestartPolicy, []string{string(api.RestartPolicyOnFailure), string(api.RestartPolicyNever)}))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateJobStatus(status *batch.JobStatus, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.Active), fldPath.Child("active"))...)
|
||||
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.Succeeded), fldPath.Child("succeeded"))...)
|
||||
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.Failed), fldPath.Child("failed"))...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateJobUpdate(job, oldJob *batch.Job) field.ErrorList {
|
||||
allErrs := apivalidation.ValidateObjectMetaUpdate(&oldJob.ObjectMeta, &job.ObjectMeta, field.NewPath("metadata"))
|
||||
allErrs = append(allErrs, ValidateJobSpecUpdate(job.Spec, oldJob.Spec, field.NewPath("spec"))...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateJobUpdateStatus(job, oldJob *batch.Job) field.ErrorList {
|
||||
allErrs := apivalidation.ValidateObjectMetaUpdate(&oldJob.ObjectMeta, &job.ObjectMeta, field.NewPath("metadata"))
|
||||
allErrs = append(allErrs, ValidateJobStatusUpdate(job.Status, oldJob.Status)...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateJobSpecUpdate(spec, oldSpec batch.JobSpec, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
allErrs = append(allErrs, ValidateJobSpec(&spec, fldPath)...)
|
||||
allErrs = append(allErrs, apivalidation.ValidateImmutableField(spec.Completions, oldSpec.Completions, fldPath.Child("completions"))...)
|
||||
allErrs = append(allErrs, apivalidation.ValidateImmutableField(spec.Selector, oldSpec.Selector, fldPath.Child("selector"))...)
|
||||
allErrs = append(allErrs, apivalidation.ValidateImmutableField(spec.Template, oldSpec.Template, fldPath.Child("template"))...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateJobStatusUpdate(status, oldStatus batch.JobStatus) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
allErrs = append(allErrs, ValidateJobStatus(&status, field.NewPath("status"))...)
|
||||
return allErrs
|
||||
}
|
|
@ -0,0 +1,297 @@
|
|||
/*
|
||||
Copyright 2016 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 validation
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/types"
|
||||
)
|
||||
|
||||
func TestValidateJob(t *testing.T) {
|
||||
validManualSelector := &unversioned.LabelSelector{
|
||||
MatchLabels: map[string]string{"a": "b"},
|
||||
}
|
||||
validGeneratedSelector := &unversioned.LabelSelector{
|
||||
MatchLabels: map[string]string{"controller-uid": "1a2b3c", "job-name": "myjob"},
|
||||
}
|
||||
validPodTemplateSpecForManual := api.PodTemplateSpec{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: validManualSelector.MatchLabels,
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyOnFailure,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||
},
|
||||
}
|
||||
validPodTemplateSpecForGenerated := api.PodTemplateSpec{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: validGeneratedSelector.MatchLabels,
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyOnFailure,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||
},
|
||||
}
|
||||
successCases := map[string]batch.Job{
|
||||
"manual selector": {
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "myjob",
|
||||
Namespace: api.NamespaceDefault,
|
||||
UID: types.UID("1a2b3c"),
|
||||
},
|
||||
Spec: batch.JobSpec{
|
||||
Selector: validManualSelector,
|
||||
ManualSelector: newBool(true),
|
||||
Template: validPodTemplateSpecForManual,
|
||||
},
|
||||
},
|
||||
"generated selector": {
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "myjob",
|
||||
Namespace: api.NamespaceDefault,
|
||||
UID: types.UID("1a2b3c"),
|
||||
},
|
||||
Spec: batch.JobSpec{
|
||||
Selector: validGeneratedSelector,
|
||||
ManualSelector: newBool(false),
|
||||
Template: validPodTemplateSpecForGenerated,
|
||||
},
|
||||
},
|
||||
}
|
||||
for k, v := range successCases {
|
||||
if errs := ValidateJob(&v); len(errs) != 0 {
|
||||
t.Errorf("expected success for %s: %v", k, errs)
|
||||
}
|
||||
}
|
||||
negative := -1
|
||||
negative64 := int64(-1)
|
||||
errorCases := map[string]batch.Job{
|
||||
"spec.parallelism:must be greater than or equal to 0": {
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "myjob",
|
||||
Namespace: api.NamespaceDefault,
|
||||
UID: types.UID("1a2b3c"),
|
||||
},
|
||||
Spec: batch.JobSpec{
|
||||
Parallelism: &negative,
|
||||
ManualSelector: newBool(true),
|
||||
Template: validPodTemplateSpecForGenerated,
|
||||
},
|
||||
},
|
||||
"spec.completions:must be greater than or equal to 0": {
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "myjob",
|
||||
Namespace: api.NamespaceDefault,
|
||||
UID: types.UID("1a2b3c"),
|
||||
},
|
||||
Spec: batch.JobSpec{
|
||||
Completions: &negative,
|
||||
Selector: validManualSelector,
|
||||
ManualSelector: newBool(true),
|
||||
Template: validPodTemplateSpecForGenerated,
|
||||
},
|
||||
},
|
||||
"spec.activeDeadlineSeconds:must be greater than or equal to 0": {
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "myjob",
|
||||
Namespace: api.NamespaceDefault,
|
||||
UID: types.UID("1a2b3c"),
|
||||
},
|
||||
Spec: batch.JobSpec{
|
||||
ActiveDeadlineSeconds: &negative64,
|
||||
Selector: validManualSelector,
|
||||
ManualSelector: newBool(true),
|
||||
Template: validPodTemplateSpecForGenerated,
|
||||
},
|
||||
},
|
||||
"spec.selector:Required value": {
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "myjob",
|
||||
Namespace: api.NamespaceDefault,
|
||||
UID: types.UID("1a2b3c"),
|
||||
},
|
||||
Spec: batch.JobSpec{
|
||||
Template: validPodTemplateSpecForGenerated,
|
||||
},
|
||||
},
|
||||
"spec.template.metadata.labels: Invalid value: {\"y\":\"z\"}: `selector` does not match template `labels`": {
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "myjob",
|
||||
Namespace: api.NamespaceDefault,
|
||||
UID: types.UID("1a2b3c"),
|
||||
},
|
||||
Spec: batch.JobSpec{
|
||||
Selector: validManualSelector,
|
||||
ManualSelector: newBool(true),
|
||||
Template: api.PodTemplateSpec{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: map[string]string{"y": "z"},
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyOnFailure,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"spec.template.metadata.labels: Invalid value: {\"controller-uid\":\"4d5e6f\"}: `selector` does not match template `labels`": {
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "myjob",
|
||||
Namespace: api.NamespaceDefault,
|
||||
UID: types.UID("1a2b3c"),
|
||||
},
|
||||
Spec: batch.JobSpec{
|
||||
Selector: validManualSelector,
|
||||
ManualSelector: newBool(true),
|
||||
Template: api.PodTemplateSpec{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: map[string]string{"controller-uid": "4d5e6f"},
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyOnFailure,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"spec.template.spec.restartPolicy: Unsupported value": {
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "myjob",
|
||||
Namespace: api.NamespaceDefault,
|
||||
UID: types.UID("1a2b3c"),
|
||||
},
|
||||
Spec: batch.JobSpec{
|
||||
Selector: validManualSelector,
|
||||
ManualSelector: newBool(true),
|
||||
Template: api.PodTemplateSpec{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: validManualSelector.MatchLabels,
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for k, v := range errorCases {
|
||||
errs := ValidateJob(&v)
|
||||
if len(errs) == 0 {
|
||||
t.Errorf("expected failure for %s", k)
|
||||
} else {
|
||||
s := strings.Split(k, ":")
|
||||
err := errs[0]
|
||||
if err.Field != s[0] || !strings.Contains(err.Error(), s[1]) {
|
||||
t.Errorf("unexpected error: %v, expected: %s", err, k)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateJobUpdateStatus(t *testing.T) {
|
||||
type testcase struct {
|
||||
old batch.Job
|
||||
update batch.Job
|
||||
}
|
||||
|
||||
successCases := []testcase{
|
||||
{
|
||||
old: batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Status: batch.JobStatus{
|
||||
Active: 1,
|
||||
Succeeded: 2,
|
||||
Failed: 3,
|
||||
},
|
||||
},
|
||||
update: batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Status: batch.JobStatus{
|
||||
Active: 1,
|
||||
Succeeded: 1,
|
||||
Failed: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, successCase := range successCases {
|
||||
successCase.old.ObjectMeta.ResourceVersion = "1"
|
||||
successCase.update.ObjectMeta.ResourceVersion = "1"
|
||||
if errs := ValidateJobUpdateStatus(&successCase.update, &successCase.old); len(errs) != 0 {
|
||||
t.Errorf("expected success: %v", errs)
|
||||
}
|
||||
}
|
||||
|
||||
errorCases := map[string]testcase{
|
||||
"[status.active: Invalid value: -1: must be greater than or equal to 0, status.succeeded: Invalid value: -2: must be greater than or equal to 0]": {
|
||||
old: batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "abc",
|
||||
Namespace: api.NamespaceDefault,
|
||||
ResourceVersion: "10",
|
||||
},
|
||||
Status: batch.JobStatus{
|
||||
Active: 1,
|
||||
Succeeded: 2,
|
||||
Failed: 3,
|
||||
},
|
||||
},
|
||||
update: batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "abc",
|
||||
Namespace: api.NamespaceDefault,
|
||||
ResourceVersion: "10",
|
||||
},
|
||||
Status: batch.JobStatus{
|
||||
Active: -1,
|
||||
Succeeded: -2,
|
||||
Failed: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for testName, errorCase := range errorCases {
|
||||
errs := ValidateJobUpdateStatus(&errorCase.update, &errorCase.old)
|
||||
if len(errs) == 0 {
|
||||
t.Errorf("expected failure: %s", testName)
|
||||
continue
|
||||
}
|
||||
if errs.ToAggregate().Error() != testName {
|
||||
t.Errorf("expected '%s' got '%s'", errs.ToAggregate().Error(), testName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func newBool(val bool) *bool {
|
||||
p := new(bool)
|
||||
*p = val
|
||||
return p
|
||||
}
|
|
@ -19,6 +19,7 @@ package extensions
|
|||
import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
|
@ -52,8 +53,8 @@ func addKnownTypes(scheme *runtime.Scheme) {
|
|||
&DeploymentRollback{},
|
||||
&HorizontalPodAutoscaler{},
|
||||
&HorizontalPodAutoscalerList{},
|
||||
&Job{},
|
||||
&JobList{},
|
||||
&batch.Job{},
|
||||
&batch.JobList{},
|
||||
&ReplicationControllerDummy{},
|
||||
&Scale{},
|
||||
&ThirdPartyResource{},
|
||||
|
@ -78,8 +79,6 @@ func (obj *DeploymentList) GetObjectKind() unversioned.ObjectKind {
|
|||
func (obj *DeploymentRollback) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
|
||||
func (obj *HorizontalPodAutoscaler) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
|
||||
func (obj *HorizontalPodAutoscalerList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
|
||||
func (obj *Job) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
|
||||
func (obj *JobList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
|
||||
func (obj *ReplicationControllerDummy) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
|
||||
func (obj *Scale) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
|
||||
func (obj *ThirdPartyResource) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
|
||||
|
|
|
@ -496,127 +496,6 @@ type ThirdPartyResourceDataList struct {
|
|||
|
||||
// +genclient=true
|
||||
|
||||
// Job represents the configuration of a single job.
|
||||
type Job struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
// Standard object's metadata.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
|
||||
api.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec is a structure defining the expected behavior of a job.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status
|
||||
Spec JobSpec `json:"spec,omitempty"`
|
||||
|
||||
// Status is a structure describing current status of a job.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status
|
||||
Status JobStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// JobList is a collection of jobs.
|
||||
type JobList struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
// Standard list metadata
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
|
||||
unversioned.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Items is the list of Job.
|
||||
Items []Job `json:"items"`
|
||||
}
|
||||
|
||||
// JobSpec describes how the job execution will look like.
|
||||
type JobSpec struct {
|
||||
|
||||
// Parallelism specifies the maximum desired number of pods the job should
|
||||
// run at any given time. The actual number of pods running in steady state will
|
||||
// be less than this number when ((.spec.completions - .status.successful) < .spec.parallelism),
|
||||
// i.e. when the work left to do is less than max parallelism.
|
||||
Parallelism *int `json:"parallelism,omitempty"`
|
||||
|
||||
// Completions specifies the desired number of successfully finished pods the
|
||||
// job should be run with. Setting to nil means that the success of any
|
||||
// pod signals the success of all pods, and allows parallelism to have any positive
|
||||
// value. Setting to 1 means that parallelism is limited to 1 and the success of that
|
||||
// pod signals the success of the job.
|
||||
Completions *int `json:"completions,omitempty"`
|
||||
|
||||
// Optional duration in seconds relative to the startTime that the job may be active
|
||||
// before the system tries to terminate it; value must be positive integer
|
||||
ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty"`
|
||||
|
||||
// Selector is a label query over pods that should match the pod count.
|
||||
// Normally, the system sets this field for you.
|
||||
Selector *unversioned.LabelSelector `json:"selector,omitempty"`
|
||||
|
||||
// ManualSelector controls generation of pod labels and pod selectors.
|
||||
// Leave `manualSelector` unset unless you are certain what you are doing.
|
||||
// When false or unset, the system pick labels unique to this job
|
||||
// and appends those labels to the pod template. When true,
|
||||
// the user is responsible for picking unique labels and specifying
|
||||
// the selector. Failure to pick a unique label may cause this
|
||||
// and other jobs to not function correctly. However, You may see
|
||||
// `manualSelector=true` in jobs that were created with the old `extensions/v1beta1`
|
||||
// API.
|
||||
ManualSelector *bool `json:"manualSelector,omitempty"`
|
||||
|
||||
// Template is the object that describes the pod that will be created when
|
||||
// executing a job.
|
||||
Template api.PodTemplateSpec `json:"template"`
|
||||
}
|
||||
|
||||
// JobStatus represents the current state of a Job.
|
||||
type JobStatus struct {
|
||||
|
||||
// Conditions represent the latest available observations of an object's current state.
|
||||
Conditions []JobCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
|
||||
|
||||
// StartTime represents time when the job was acknowledged by the Job Manager.
|
||||
// It is not guaranteed to be set in happens-before order across separate operations.
|
||||
// It is represented in RFC3339 form and is in UTC.
|
||||
StartTime *unversioned.Time `json:"startTime,omitempty"`
|
||||
|
||||
// CompletionTime represents time when the job was completed. It is not guaranteed to
|
||||
// be set in happens-before order across separate operations.
|
||||
// It is represented in RFC3339 form and is in UTC.
|
||||
CompletionTime *unversioned.Time `json:"completionTime,omitempty"`
|
||||
|
||||
// Active is the number of actively running pods.
|
||||
Active int `json:"active,omitempty"`
|
||||
|
||||
// Succeeded is the number of pods which reached Phase Succeeded.
|
||||
Succeeded int `json:"succeeded,omitempty"`
|
||||
|
||||
// Failed is the number of pods which reached Phase Failed.
|
||||
Failed int `json:"failed,omitempty"`
|
||||
}
|
||||
|
||||
type JobConditionType string
|
||||
|
||||
// These are valid conditions of a job.
|
||||
const (
|
||||
// JobComplete means the job has completed its execution.
|
||||
JobComplete JobConditionType = "Complete"
|
||||
// JobFailed means the job has failed its execution.
|
||||
JobFailed JobConditionType = "Failed"
|
||||
)
|
||||
|
||||
// JobCondition describes current state of a job.
|
||||
type JobCondition struct {
|
||||
// Type of job condition, Complete or Failed.
|
||||
Type JobConditionType `json:"type"`
|
||||
// Status of the condition, one of True, False, Unknown.
|
||||
Status api.ConditionStatus `json:"status"`
|
||||
// Last time the condition was checked.
|
||||
LastProbeTime unversioned.Time `json:"lastProbeTime,omitempty"`
|
||||
// Last time the condition transit from one status to another.
|
||||
LastTransitionTime unversioned.Time `json:"lastTransitionTime,omitempty"`
|
||||
// (brief) reason for the condition's last transition.
|
||||
Reason string `json:"reason,omitempty"`
|
||||
// Human readable message indicating details about last transition.
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// +genclient=true
|
||||
|
||||
// Ingress is a collection of rules that allow inbound connections to reach the
|
||||
// endpoints defined by a backend. An Ingress can be configured to give services
|
||||
// externally-reachable urls, load balance traffic, terminate SSL, offer name
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
v1 "k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/conversion"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
|
@ -42,8 +43,9 @@ func addConversionFuncs(scheme *runtime.Scheme) {
|
|||
Convert_v1beta1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment,
|
||||
Convert_extensions_ReplicaSetSpec_To_v1beta1_ReplicaSetSpec,
|
||||
Convert_v1beta1_ReplicaSetSpec_To_extensions_ReplicaSetSpec,
|
||||
Convert_extensions_JobSpec_To_v1beta1_JobSpec,
|
||||
Convert_v1beta1_JobSpec_To_extensions_JobSpec,
|
||||
// batch
|
||||
Convert_batch_JobSpec_To_v1beta1_JobSpec,
|
||||
Convert_v1beta1_JobSpec_To_batch_JobSpec,
|
||||
)
|
||||
if err != nil {
|
||||
// If one of the conversion functions is malformed, detect it immediately.
|
||||
|
@ -312,9 +314,9 @@ func Convert_v1beta1_ReplicaSetSpec_To_extensions_ReplicaSetSpec(in *ReplicaSetS
|
|||
return nil
|
||||
}
|
||||
|
||||
func Convert_extensions_JobSpec_To_v1beta1_JobSpec(in *extensions.JobSpec, out *JobSpec, s conversion.Scope) error {
|
||||
func Convert_batch_JobSpec_To_v1beta1_JobSpec(in *batch.JobSpec, out *JobSpec, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*extensions.JobSpec))(in)
|
||||
defaulting.(func(*batch.JobSpec))(in)
|
||||
}
|
||||
if in.Parallelism != nil {
|
||||
out.Parallelism = new(int32)
|
||||
|
@ -364,7 +366,7 @@ func Convert_extensions_JobSpec_To_v1beta1_JobSpec(in *extensions.JobSpec, out *
|
|||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1beta1_JobSpec_To_extensions_JobSpec(in *JobSpec, out *extensions.JobSpec, s conversion.Scope) error {
|
||||
func Convert_v1beta1_JobSpec_To_batch_JobSpec(in *JobSpec, out *batch.JobSpec, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*JobSpec))(in)
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
versioned "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
|
||||
)
|
||||
|
||||
|
@ -55,7 +55,7 @@ func TestJobSpecConversion(t *testing.T) {
|
|||
|
||||
// Test internal -> v1beta1.
|
||||
for _, test := range tests {
|
||||
i := &extensions.JobSpec{
|
||||
i := &batch.JobSpec{
|
||||
ManualSelector: test.in,
|
||||
}
|
||||
v := versioned.JobSpec{}
|
||||
|
@ -72,7 +72,7 @@ func TestJobSpecConversion(t *testing.T) {
|
|||
i := &versioned.JobSpec{
|
||||
AutoSelector: test.in,
|
||||
}
|
||||
e := extensions.JobSpec{}
|
||||
e := batch.JobSpec{}
|
||||
if err := api.Scheme.Convert(i, &e); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
|
|
@ -382,136 +382,6 @@ func ValidateThirdPartyResourceData(obj *extensions.ThirdPartyResourceData) fiel
|
|||
return allErrs
|
||||
}
|
||||
|
||||
// TODO: generalize for other controller objects that will follow the same pattern, such as ReplicaSet and DaemonSet, and
|
||||
// move to new location. Replace extensions.Job with an interface.
|
||||
//
|
||||
// ValidateGeneratedSelector validates that the generated selector on a controller object match the controller object
|
||||
// metadata, and the labels on the pod template are as generated.
|
||||
func ValidateGeneratedSelector(obj *extensions.Job) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if obj.Spec.ManualSelector != nil && *obj.Spec.ManualSelector {
|
||||
return allErrs
|
||||
}
|
||||
|
||||
if obj.Spec.Selector == nil {
|
||||
return allErrs // This case should already have been checked in caller. No need for more errors.
|
||||
}
|
||||
|
||||
// If somehow uid was unset then we would get "controller-uid=" as the selector
|
||||
// which is bad.
|
||||
if obj.ObjectMeta.UID == "" {
|
||||
allErrs = append(allErrs, field.Required(field.NewPath("metadata").Child("uid"), ""))
|
||||
}
|
||||
|
||||
// If somehow uid was unset then we would get "controller-uid=" as the selector
|
||||
// which is bad.
|
||||
if obj.ObjectMeta.UID == "" {
|
||||
allErrs = append(allErrs, field.Required(field.NewPath("metadata").Child("uid"), ""))
|
||||
}
|
||||
|
||||
// If selector generation was requested, then expected labels must be
|
||||
// present on pod template, and much match job's uid and name. The
|
||||
// generated (not-manual) selectors/labels ensure no overlap with other
|
||||
// controllers. The manual mode allows orphaning, adoption,
|
||||
// backward-compatibility, and experimentation with new
|
||||
// labeling/selection schemes. Automatic selector generation should
|
||||
// have placed certain labels on the pod, but this could have failed if
|
||||
// the user added coflicting labels. Validate that the expected
|
||||
// generated ones are there.
|
||||
|
||||
allErrs = append(allErrs, apivalidation.ValidateHasLabel(obj.Spec.Template.ObjectMeta, field.NewPath("spec").Child("template").Child("metadata"), "controller-uid", string(obj.UID))...)
|
||||
allErrs = append(allErrs, apivalidation.ValidateHasLabel(obj.Spec.Template.ObjectMeta, field.NewPath("spec").Child("template").Child("metadata"), "job-name", string(obj.Name))...)
|
||||
expectedLabels := make(map[string]string)
|
||||
expectedLabels["controller-uid"] = string(obj.UID)
|
||||
expectedLabels["job-name"] = string(obj.Name)
|
||||
// Whether manually or automatically generated, the selector of the job must match the pods it will produce.
|
||||
if selector, err := unversioned.LabelSelectorAsSelector(obj.Spec.Selector); err == nil {
|
||||
if !selector.Matches(labels.Set(expectedLabels)) {
|
||||
allErrs = append(allErrs, field.Invalid(field.NewPath("spec").Child("selector"), obj.Spec.Selector, "`selector` not auto-generated"))
|
||||
}
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateJob(job *extensions.Job) field.ErrorList {
|
||||
// Jobs and rcs have the same name validation
|
||||
allErrs := apivalidation.ValidateObjectMeta(&job.ObjectMeta, true, apivalidation.ValidateReplicationControllerName, field.NewPath("metadata"))
|
||||
allErrs = append(allErrs, ValidateGeneratedSelector(job)...)
|
||||
allErrs = append(allErrs, ValidateJobSpec(&job.Spec, field.NewPath("spec"))...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateJobSpec(spec *extensions.JobSpec, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
if spec.Parallelism != nil {
|
||||
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(*spec.Parallelism), fldPath.Child("parallelism"))...)
|
||||
}
|
||||
if spec.Completions != nil {
|
||||
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(*spec.Completions), fldPath.Child("completions"))...)
|
||||
}
|
||||
if spec.ActiveDeadlineSeconds != nil {
|
||||
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(*spec.ActiveDeadlineSeconds), fldPath.Child("activeDeadlineSeconds"))...)
|
||||
}
|
||||
if spec.Selector == nil {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("selector"), ""))
|
||||
} else {
|
||||
allErrs = append(allErrs, unversionedvalidation.ValidateLabelSelector(spec.Selector, fldPath.Child("selector"))...)
|
||||
}
|
||||
|
||||
// Whether manually or automatically generated, the selector of the job must match the pods it will produce.
|
||||
if selector, err := unversioned.LabelSelectorAsSelector(spec.Selector); err == nil {
|
||||
labels := labels.Set(spec.Template.Labels)
|
||||
if !selector.Matches(labels) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("template", "metadata", "labels"), spec.Template.Labels, "`selector` does not match template `labels`"))
|
||||
}
|
||||
}
|
||||
|
||||
allErrs = append(allErrs, apivalidation.ValidatePodTemplateSpec(&spec.Template, fldPath.Child("template"))...)
|
||||
if spec.Template.Spec.RestartPolicy != api.RestartPolicyOnFailure &&
|
||||
spec.Template.Spec.RestartPolicy != api.RestartPolicyNever {
|
||||
allErrs = append(allErrs, field.NotSupported(fldPath.Child("template", "spec", "restartPolicy"),
|
||||
spec.Template.Spec.RestartPolicy, []string{string(api.RestartPolicyOnFailure), string(api.RestartPolicyNever)}))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateJobStatus(status *extensions.JobStatus, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.Active), fldPath.Child("active"))...)
|
||||
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.Succeeded), fldPath.Child("succeeded"))...)
|
||||
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.Failed), fldPath.Child("failed"))...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateJobUpdate(job, oldJob *extensions.Job) field.ErrorList {
|
||||
allErrs := apivalidation.ValidateObjectMetaUpdate(&oldJob.ObjectMeta, &job.ObjectMeta, field.NewPath("metadata"))
|
||||
allErrs = append(allErrs, ValidateJobSpecUpdate(job.Spec, oldJob.Spec, field.NewPath("spec"))...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateJobUpdateStatus(job, oldJob *extensions.Job) field.ErrorList {
|
||||
allErrs := apivalidation.ValidateObjectMetaUpdate(&oldJob.ObjectMeta, &job.ObjectMeta, field.NewPath("metadata"))
|
||||
allErrs = append(allErrs, ValidateJobStatusUpdate(job.Status, oldJob.Status)...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateJobSpecUpdate(spec, oldSpec extensions.JobSpec, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
allErrs = append(allErrs, ValidateJobSpec(&spec, fldPath)...)
|
||||
allErrs = append(allErrs, apivalidation.ValidateImmutableField(spec.Completions, oldSpec.Completions, fldPath.Child("completions"))...)
|
||||
allErrs = append(allErrs, apivalidation.ValidateImmutableField(spec.Selector, oldSpec.Selector, fldPath.Child("selector"))...)
|
||||
allErrs = append(allErrs, apivalidation.ValidateImmutableField(spec.Template, oldSpec.Template, fldPath.Child("template"))...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateJobStatusUpdate(status, oldStatus extensions.JobStatus) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
allErrs = append(allErrs, ValidateJobStatus(&status, field.NewPath("status"))...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateIngress tests if required fields in the Ingress are set.
|
||||
func ValidateIngress(ingress *extensions.Ingress) field.ErrorList {
|
||||
allErrs := apivalidation.ValidateObjectMeta(&ingress.ObjectMeta, true, ValidateIngressName, field.NewPath("metadata"))
|
||||
|
|
|
@ -25,7 +25,6 @@ import (
|
|||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/controller/podautoscaler"
|
||||
"k8s.io/kubernetes/pkg/types"
|
||||
"k8s.io/kubernetes/pkg/util/intstr"
|
||||
)
|
||||
|
||||
|
@ -989,270 +988,6 @@ func TestValidateDeploymentRollback(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestValidateJob(t *testing.T) {
|
||||
validManualSelector := &unversioned.LabelSelector{
|
||||
MatchLabels: map[string]string{"a": "b"},
|
||||
}
|
||||
validGeneratedSelector := &unversioned.LabelSelector{
|
||||
MatchLabels: map[string]string{"controller-uid": "1a2b3c", "job-name": "myjob"},
|
||||
}
|
||||
validPodTemplateSpecForManual := api.PodTemplateSpec{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: validManualSelector.MatchLabels,
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyOnFailure,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||
},
|
||||
}
|
||||
validPodTemplateSpecForGenerated := api.PodTemplateSpec{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: validGeneratedSelector.MatchLabels,
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyOnFailure,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||
},
|
||||
}
|
||||
successCases := map[string]extensions.Job{
|
||||
"manual selector": {
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "myjob",
|
||||
Namespace: api.NamespaceDefault,
|
||||
UID: types.UID("1a2b3c"),
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Selector: validManualSelector,
|
||||
ManualSelector: newBool(true),
|
||||
Template: validPodTemplateSpecForManual,
|
||||
},
|
||||
},
|
||||
"generated selector": {
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "myjob",
|
||||
Namespace: api.NamespaceDefault,
|
||||
UID: types.UID("1a2b3c"),
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Selector: validGeneratedSelector,
|
||||
ManualSelector: newBool(false),
|
||||
Template: validPodTemplateSpecForGenerated,
|
||||
},
|
||||
},
|
||||
}
|
||||
for k, v := range successCases {
|
||||
if errs := ValidateJob(&v); len(errs) != 0 {
|
||||
t.Errorf("expected success for %s: %v", k, errs)
|
||||
}
|
||||
}
|
||||
negative := -1
|
||||
negative64 := int64(-1)
|
||||
errorCases := map[string]extensions.Job{
|
||||
"spec.parallelism:must be greater than or equal to 0": {
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "myjob",
|
||||
Namespace: api.NamespaceDefault,
|
||||
UID: types.UID("1a2b3c"),
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Parallelism: &negative,
|
||||
ManualSelector: newBool(true),
|
||||
Template: validPodTemplateSpecForGenerated,
|
||||
},
|
||||
},
|
||||
"spec.completions:must be greater than or equal to 0": {
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "myjob",
|
||||
Namespace: api.NamespaceDefault,
|
||||
UID: types.UID("1a2b3c"),
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Completions: &negative,
|
||||
Selector: validManualSelector,
|
||||
ManualSelector: newBool(true),
|
||||
Template: validPodTemplateSpecForGenerated,
|
||||
},
|
||||
},
|
||||
"spec.activeDeadlineSeconds:must be greater than or equal to 0": {
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "myjob",
|
||||
Namespace: api.NamespaceDefault,
|
||||
UID: types.UID("1a2b3c"),
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
ActiveDeadlineSeconds: &negative64,
|
||||
Selector: validManualSelector,
|
||||
ManualSelector: newBool(true),
|
||||
Template: validPodTemplateSpecForGenerated,
|
||||
},
|
||||
},
|
||||
"spec.selector:Required value": {
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "myjob",
|
||||
Namespace: api.NamespaceDefault,
|
||||
UID: types.UID("1a2b3c"),
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Template: validPodTemplateSpecForGenerated,
|
||||
},
|
||||
},
|
||||
"spec.template.metadata.labels: Invalid value: {\"y\":\"z\"}: `selector` does not match template `labels`": {
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "myjob",
|
||||
Namespace: api.NamespaceDefault,
|
||||
UID: types.UID("1a2b3c"),
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Selector: validManualSelector,
|
||||
ManualSelector: newBool(true),
|
||||
Template: api.PodTemplateSpec{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: map[string]string{"y": "z"},
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyOnFailure,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"spec.template.metadata.labels: Invalid value: {\"controller-uid\":\"4d5e6f\"}: `selector` does not match template `labels`": {
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "myjob",
|
||||
Namespace: api.NamespaceDefault,
|
||||
UID: types.UID("1a2b3c"),
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Selector: validManualSelector,
|
||||
ManualSelector: newBool(true),
|
||||
Template: api.PodTemplateSpec{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: map[string]string{"controller-uid": "4d5e6f"},
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyOnFailure,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"spec.template.spec.restartPolicy: Unsupported value": {
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "myjob",
|
||||
Namespace: api.NamespaceDefault,
|
||||
UID: types.UID("1a2b3c"),
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Selector: validManualSelector,
|
||||
ManualSelector: newBool(true),
|
||||
Template: api.PodTemplateSpec{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Labels: validManualSelector.MatchLabels,
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for k, v := range errorCases {
|
||||
errs := ValidateJob(&v)
|
||||
if len(errs) == 0 {
|
||||
t.Errorf("expected failure for %s", k)
|
||||
} else {
|
||||
s := strings.Split(k, ":")
|
||||
err := errs[0]
|
||||
if err.Field != s[0] || !strings.Contains(err.Error(), s[1]) {
|
||||
t.Errorf("unexpected error: %v, expected: %s", err, k)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateJobUpdateStatus(t *testing.T) {
|
||||
type testcase struct {
|
||||
old extensions.Job
|
||||
update extensions.Job
|
||||
}
|
||||
|
||||
successCases := []testcase{
|
||||
{
|
||||
old: extensions.Job{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Status: extensions.JobStatus{
|
||||
Active: 1,
|
||||
Succeeded: 2,
|
||||
Failed: 3,
|
||||
},
|
||||
},
|
||||
update: extensions.Job{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
|
||||
Status: extensions.JobStatus{
|
||||
Active: 1,
|
||||
Succeeded: 1,
|
||||
Failed: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, successCase := range successCases {
|
||||
successCase.old.ObjectMeta.ResourceVersion = "1"
|
||||
successCase.update.ObjectMeta.ResourceVersion = "1"
|
||||
if errs := ValidateJobUpdateStatus(&successCase.update, &successCase.old); len(errs) != 0 {
|
||||
t.Errorf("expected success: %v", errs)
|
||||
}
|
||||
}
|
||||
|
||||
errorCases := map[string]testcase{
|
||||
"[status.active: Invalid value: -1: must be greater than or equal to 0, status.succeeded: Invalid value: -2: must be greater than or equal to 0]": {
|
||||
old: extensions.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "abc",
|
||||
Namespace: api.NamespaceDefault,
|
||||
ResourceVersion: "10",
|
||||
},
|
||||
Status: extensions.JobStatus{
|
||||
Active: 1,
|
||||
Succeeded: 2,
|
||||
Failed: 3,
|
||||
},
|
||||
},
|
||||
update: extensions.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "abc",
|
||||
Namespace: api.NamespaceDefault,
|
||||
ResourceVersion: "10",
|
||||
},
|
||||
Status: extensions.JobStatus{
|
||||
Active: -1,
|
||||
Succeeded: -2,
|
||||
Failed: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for testName, errorCase := range errorCases {
|
||||
errs := ValidateJobUpdateStatus(&errorCase.update, &errorCase.old)
|
||||
if len(errs) == 0 {
|
||||
t.Errorf("expected failure: %s", testName)
|
||||
continue
|
||||
}
|
||||
if errs.ToAggregate().Error() != testName {
|
||||
t.Errorf("expected '%s' got '%s'", errs.ToAggregate().Error(), testName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type ingressRules map[string]string
|
||||
|
||||
func TestValidateIngress(t *testing.T) {
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
"github.com/golang/glog"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
)
|
||||
|
@ -474,7 +475,7 @@ type StoreToJobLister struct {
|
|||
}
|
||||
|
||||
// Exists checks if the given job exists in the store.
|
||||
func (s *StoreToJobLister) Exists(job *extensions.Job) (bool, error) {
|
||||
func (s *StoreToJobLister) Exists(job *batch.Job) (bool, error) {
|
||||
_, exists, err := s.Store.Get(job)
|
||||
if err != nil {
|
||||
return false, err
|
||||
|
@ -483,17 +484,17 @@ func (s *StoreToJobLister) Exists(job *extensions.Job) (bool, error) {
|
|||
}
|
||||
|
||||
// StoreToJobLister lists all jobs in the store.
|
||||
func (s *StoreToJobLister) List() (jobs extensions.JobList, err error) {
|
||||
func (s *StoreToJobLister) List() (jobs batch.JobList, err error) {
|
||||
for _, c := range s.Store.List() {
|
||||
jobs.Items = append(jobs.Items, *(c.(*extensions.Job)))
|
||||
jobs.Items = append(jobs.Items, *(c.(*batch.Job)))
|
||||
}
|
||||
return jobs, nil
|
||||
}
|
||||
|
||||
// GetPodJobs returns a list of jobs managing a pod. Returns an error only if no matching jobs are found.
|
||||
func (s *StoreToJobLister) GetPodJobs(pod *api.Pod) (jobs []extensions.Job, err error) {
|
||||
func (s *StoreToJobLister) GetPodJobs(pod *api.Pod) (jobs []batch.Job, err error) {
|
||||
var selector labels.Selector
|
||||
var job extensions.Job
|
||||
var job batch.Job
|
||||
|
||||
if len(pod.Labels) == 0 {
|
||||
err = fmt.Errorf("no jobs found for pod %v because it has no labels", pod.Name)
|
||||
|
@ -501,7 +502,7 @@ func (s *StoreToJobLister) GetPodJobs(pod *api.Pod) (jobs []extensions.Job, err
|
|||
}
|
||||
|
||||
for _, m := range s.Store.List() {
|
||||
job = *m.(*extensions.Job)
|
||||
job = *m.(*batch.Job)
|
||||
if job.Namespace != pod.Namespace {
|
||||
continue
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/util/sets"
|
||||
|
@ -476,18 +477,18 @@ func TestStoreToJobLister(t *testing.T) {
|
|||
store := NewStore(MetaNamespaceKeyFunc)
|
||||
lister := StoreToJobLister{store}
|
||||
testCases := []struct {
|
||||
inJobs []*extensions.Job
|
||||
list func() ([]extensions.Job, error)
|
||||
inJobs []*batch.Job
|
||||
list func() ([]batch.Job, error)
|
||||
outJobNames sets.String
|
||||
expectErr bool
|
||||
msg string
|
||||
}{
|
||||
// Basic listing
|
||||
{
|
||||
inJobs: []*extensions.Job{
|
||||
inJobs: []*batch.Job{
|
||||
{ObjectMeta: api.ObjectMeta{Name: "basic"}},
|
||||
},
|
||||
list: func() ([]extensions.Job, error) {
|
||||
list: func() ([]batch.Job, error) {
|
||||
list, err := lister.List()
|
||||
return list.Items, err
|
||||
},
|
||||
|
@ -496,12 +497,12 @@ func TestStoreToJobLister(t *testing.T) {
|
|||
},
|
||||
// Listing multiple jobs
|
||||
{
|
||||
inJobs: []*extensions.Job{
|
||||
inJobs: []*batch.Job{
|
||||
{ObjectMeta: api.ObjectMeta{Name: "basic"}},
|
||||
{ObjectMeta: api.ObjectMeta{Name: "complex"}},
|
||||
{ObjectMeta: api.ObjectMeta{Name: "complex2"}},
|
||||
},
|
||||
list: func() ([]extensions.Job, error) {
|
||||
list: func() ([]batch.Job, error) {
|
||||
list, err := lister.List()
|
||||
return list.Items, err
|
||||
},
|
||||
|
@ -510,17 +511,17 @@ func TestStoreToJobLister(t *testing.T) {
|
|||
},
|
||||
// No pod labels
|
||||
{
|
||||
inJobs: []*extensions.Job{
|
||||
inJobs: []*batch.Job{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Selector: &unversioned.LabelSelector{
|
||||
MatchLabels: map[string]string{"foo": "baz"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
list: func() ([]extensions.Job, error) {
|
||||
list: func() ([]batch.Job, error) {
|
||||
pod := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{Name: "pod", Namespace: "ns"},
|
||||
}
|
||||
|
@ -532,12 +533,12 @@ func TestStoreToJobLister(t *testing.T) {
|
|||
},
|
||||
// No Job selectors
|
||||
{
|
||||
inJobs: []*extensions.Job{
|
||||
inJobs: []*batch.Job{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"},
|
||||
},
|
||||
},
|
||||
list: func() ([]extensions.Job, error) {
|
||||
list: func() ([]batch.Job, error) {
|
||||
pod := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "pod",
|
||||
|
@ -553,10 +554,10 @@ func TestStoreToJobLister(t *testing.T) {
|
|||
},
|
||||
// Matching labels to selectors and namespace
|
||||
{
|
||||
inJobs: []*extensions.Job{
|
||||
inJobs: []*batch.Job{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Selector: &unversioned.LabelSelector{
|
||||
MatchLabels: map[string]string{"foo": "bar"},
|
||||
},
|
||||
|
@ -564,14 +565,14 @@ func TestStoreToJobLister(t *testing.T) {
|
|||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "ns"},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Selector: &unversioned.LabelSelector{
|
||||
MatchLabels: map[string]string{"foo": "bar"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
list: func() ([]extensions.Job, error) {
|
||||
list: func() ([]batch.Job, error) {
|
||||
pod := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "pod",
|
||||
|
@ -586,10 +587,10 @@ func TestStoreToJobLister(t *testing.T) {
|
|||
},
|
||||
// Matching labels to selectors and namespace, error case
|
||||
{
|
||||
inJobs: []*extensions.Job{
|
||||
inJobs: []*batch.Job{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "foo"},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Selector: &unversioned.LabelSelector{
|
||||
MatchLabels: map[string]string{"foo": "bar"},
|
||||
},
|
||||
|
@ -597,14 +598,14 @@ func TestStoreToJobLister(t *testing.T) {
|
|||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "bar"},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Selector: &unversioned.LabelSelector{
|
||||
MatchLabels: map[string]string{"foo": "bar"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
list: func() ([]extensions.Job, error) {
|
||||
list: func() ([]batch.Job, error) {
|
||||
pod := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "pod",
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/errors"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/util/wait"
|
||||
"k8s.io/kubernetes/pkg/watch"
|
||||
|
@ -129,7 +130,7 @@ func ReplicaSetHasDesiredReplicas(c ExtensionsInterface, replicaSet *extensions.
|
|||
|
||||
// JobHasDesiredParallelism returns a condition that will be true if the desired parallelism count
|
||||
// for a job equals the current active counts or is less by an appropriate successful/unsuccessful count.
|
||||
func JobHasDesiredParallelism(c ExtensionsInterface, job *extensions.Job) wait.ConditionFunc {
|
||||
func JobHasDesiredParallelism(c BatchInterface, job *batch.Job) wait.ConditionFunc {
|
||||
|
||||
return func() (bool, error) {
|
||||
job, err := c.Jobs(job.Namespace).Get(job.Name)
|
||||
|
|
|
@ -18,7 +18,7 @@ package unversioned
|
|||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
|
@ -29,13 +29,13 @@ type JobsNamespacer interface {
|
|||
|
||||
// JobInterface exposes methods to work on Job resources.
|
||||
type JobInterface interface {
|
||||
List(opts api.ListOptions) (*extensions.JobList, error)
|
||||
Get(name string) (*extensions.Job, error)
|
||||
Create(job *extensions.Job) (*extensions.Job, error)
|
||||
Update(job *extensions.Job) (*extensions.Job, error)
|
||||
List(opts api.ListOptions) (*batch.JobList, error)
|
||||
Get(name string) (*batch.Job, error)
|
||||
Create(job *batch.Job) (*batch.Job, error)
|
||||
Update(job *batch.Job) (*batch.Job, error)
|
||||
Delete(name string, options *api.DeleteOptions) error
|
||||
Watch(opts api.ListOptions) (watch.Interface, error)
|
||||
UpdateStatus(job *extensions.Job) (*extensions.Job, error)
|
||||
UpdateStatus(job *batch.Job) (*batch.Job, error)
|
||||
}
|
||||
|
||||
// jobs implements JobsNamespacer interface
|
||||
|
@ -53,29 +53,29 @@ func newJobs(c *ExtensionsClient, namespace string) *jobs {
|
|||
var _ JobInterface = &jobs{}
|
||||
|
||||
// List returns a list of jobs that match the label and field selectors.
|
||||
func (c *jobs) List(opts api.ListOptions) (result *extensions.JobList, err error) {
|
||||
result = &extensions.JobList{}
|
||||
func (c *jobs) List(opts api.ListOptions) (result *batch.JobList, err error) {
|
||||
result = &batch.JobList{}
|
||||
err = c.r.Get().Namespace(c.ns).Resource("jobs").VersionedParams(&opts, api.ParameterCodec).Do().Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Get returns information about a particular job.
|
||||
func (c *jobs) Get(name string) (result *extensions.Job, err error) {
|
||||
result = &extensions.Job{}
|
||||
func (c *jobs) Get(name string) (result *batch.Job, err error) {
|
||||
result = &batch.Job{}
|
||||
err = c.r.Get().Namespace(c.ns).Resource("jobs").Name(name).Do().Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Create creates a new job.
|
||||
func (c *jobs) Create(job *extensions.Job) (result *extensions.Job, err error) {
|
||||
result = &extensions.Job{}
|
||||
func (c *jobs) Create(job *batch.Job) (result *batch.Job, err error) {
|
||||
result = &batch.Job{}
|
||||
err = c.r.Post().Namespace(c.ns).Resource("jobs").Body(job).Do().Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update updates an existing job.
|
||||
func (c *jobs) Update(job *extensions.Job) (result *extensions.Job, err error) {
|
||||
result = &extensions.Job{}
|
||||
func (c *jobs) Update(job *batch.Job) (result *batch.Job, err error) {
|
||||
result = &batch.Job{}
|
||||
err = c.r.Put().Namespace(c.ns).Resource("jobs").Name(job.Name).Body(job).Do().Into(result)
|
||||
return
|
||||
}
|
||||
|
@ -96,8 +96,8 @@ func (c *jobs) Watch(opts api.ListOptions) (watch.Interface, error) {
|
|||
}
|
||||
|
||||
// UpdateStatus takes the name of the job and the new status. Returns the server's representation of the job, and an error, if it occurs.
|
||||
func (c *jobs) UpdateStatus(job *extensions.Job) (result *extensions.Job, err error) {
|
||||
result = &extensions.Job{}
|
||||
func (c *jobs) UpdateStatus(job *batch.Job) (result *batch.Job, err error) {
|
||||
result = &batch.Job{}
|
||||
err = c.r.Put().Namespace(c.ns).Resource("jobs").Name(job.Name).SubResource("status").Body(job).Do().Into(result)
|
||||
return
|
||||
}
|
||||
|
@ -117,29 +117,29 @@ func newJobsV1(c *BatchClient, namespace string) *jobsV1 {
|
|||
var _ JobInterface = &jobsV1{}
|
||||
|
||||
// List returns a list of jobs that match the label and field selectors.
|
||||
func (c *jobsV1) List(opts api.ListOptions) (result *extensions.JobList, err error) {
|
||||
result = &extensions.JobList{}
|
||||
func (c *jobsV1) List(opts api.ListOptions) (result *batch.JobList, err error) {
|
||||
result = &batch.JobList{}
|
||||
err = c.r.Get().Namespace(c.ns).Resource("jobs").VersionedParams(&opts, api.ParameterCodec).Do().Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Get returns information about a particular job.
|
||||
func (c *jobsV1) Get(name string) (result *extensions.Job, err error) {
|
||||
result = &extensions.Job{}
|
||||
func (c *jobsV1) Get(name string) (result *batch.Job, err error) {
|
||||
result = &batch.Job{}
|
||||
err = c.r.Get().Namespace(c.ns).Resource("jobs").Name(name).Do().Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Create creates a new job.
|
||||
func (c *jobsV1) Create(job *extensions.Job) (result *extensions.Job, err error) {
|
||||
result = &extensions.Job{}
|
||||
func (c *jobsV1) Create(job *batch.Job) (result *batch.Job, err error) {
|
||||
result = &batch.Job{}
|
||||
err = c.r.Post().Namespace(c.ns).Resource("jobs").Body(job).Do().Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update updates an existing job.
|
||||
func (c *jobsV1) Update(job *extensions.Job) (result *extensions.Job, err error) {
|
||||
result = &extensions.Job{}
|
||||
func (c *jobsV1) Update(job *batch.Job) (result *batch.Job, err error) {
|
||||
result = &batch.Job{}
|
||||
err = c.r.Put().Namespace(c.ns).Resource("jobs").Name(job.Name).Body(job).Do().Into(result)
|
||||
return
|
||||
}
|
||||
|
@ -160,8 +160,8 @@ func (c *jobsV1) Watch(opts api.ListOptions) (watch.Interface, error) {
|
|||
}
|
||||
|
||||
// UpdateStatus takes the name of the job and the new status. Returns the server's representation of the job, and an error, if it occurs.
|
||||
func (c *jobsV1) UpdateStatus(job *extensions.Job) (result *extensions.Job, err error) {
|
||||
result = &extensions.Job{}
|
||||
func (c *jobsV1) UpdateStatus(job *batch.Job) (result *batch.Job, err error) {
|
||||
result = &batch.Job{}
|
||||
err = c.r.Put().Namespace(c.ns).Resource("jobs").Name(job.Name).SubResource("status").Body(job).Do().Into(result)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -51,8 +51,8 @@ func testListJob(t *testing.T, group testapi.TestGroup, resourceGroup string) {
|
|||
Path: group.ResourcePath(getJobsResourceName(), ns, ""),
|
||||
},
|
||||
Response: simple.Response{StatusCode: 200,
|
||||
Body: &extensions.JobList{
|
||||
Items: []extensions.Job{
|
||||
Body: &batch.JobList{
|
||||
Items: []batch.Job{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
|
@ -61,7 +61,7 @@ func testListJob(t *testing.T, group testapi.TestGroup, resourceGroup string) {
|
|||
"name": "baz",
|
||||
},
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Template: api.PodTemplateSpec{},
|
||||
},
|
||||
},
|
||||
|
@ -90,7 +90,7 @@ func testGetJob(t *testing.T, group testapi.TestGroup, resourceGroup string) {
|
|||
},
|
||||
Response: simple.Response{
|
||||
StatusCode: 200,
|
||||
Body: &extensions.Job{
|
||||
Body: &batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Labels: map[string]string{
|
||||
|
@ -98,7 +98,7 @@ func testGetJob(t *testing.T, group testapi.TestGroup, resourceGroup string) {
|
|||
"name": "baz",
|
||||
},
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Template: api.PodTemplateSpec{},
|
||||
},
|
||||
},
|
||||
|
@ -117,7 +117,7 @@ func TestGetJob(t *testing.T) {
|
|||
|
||||
func testUpdateJob(t *testing.T, group testapi.TestGroup, resourceGroup string) {
|
||||
ns := api.NamespaceDefault
|
||||
requestJob := &extensions.Job{
|
||||
requestJob := &batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: ns,
|
||||
|
@ -132,7 +132,7 @@ func testUpdateJob(t *testing.T, group testapi.TestGroup, resourceGroup string)
|
|||
},
|
||||
Response: simple.Response{
|
||||
StatusCode: 200,
|
||||
Body: &extensions.Job{
|
||||
Body: &batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Labels: map[string]string{
|
||||
|
@ -140,7 +140,7 @@ func testUpdateJob(t *testing.T, group testapi.TestGroup, resourceGroup string)
|
|||
"name": "baz",
|
||||
},
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Template: api.PodTemplateSpec{},
|
||||
},
|
||||
},
|
||||
|
@ -159,7 +159,7 @@ func TestUpdateJob(t *testing.T) {
|
|||
|
||||
func testUpdateJobStatus(t *testing.T, group testapi.TestGroup, resourceGroup string) {
|
||||
ns := api.NamespaceDefault
|
||||
requestJob := &extensions.Job{
|
||||
requestJob := &batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: ns,
|
||||
|
@ -174,7 +174,7 @@ func testUpdateJobStatus(t *testing.T, group testapi.TestGroup, resourceGroup st
|
|||
},
|
||||
Response: simple.Response{
|
||||
StatusCode: 200,
|
||||
Body: &extensions.Job{
|
||||
Body: &batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Labels: map[string]string{
|
||||
|
@ -182,10 +182,10 @@ func testUpdateJobStatus(t *testing.T, group testapi.TestGroup, resourceGroup st
|
|||
"name": "baz",
|
||||
},
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Template: api.PodTemplateSpec{},
|
||||
},
|
||||
Status: extensions.JobStatus{
|
||||
Status: batch.JobStatus{
|
||||
Active: 1,
|
||||
},
|
||||
},
|
||||
|
@ -225,7 +225,7 @@ func TestDeleteJob(t *testing.T) {
|
|||
|
||||
func testCreateJob(t *testing.T, group testapi.TestGroup, resourceGroup string) {
|
||||
ns := api.NamespaceDefault
|
||||
requestJob := &extensions.Job{
|
||||
requestJob := &batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: ns,
|
||||
|
@ -240,7 +240,7 @@ func testCreateJob(t *testing.T, group testapi.TestGroup, resourceGroup string)
|
|||
},
|
||||
Response: simple.Response{
|
||||
StatusCode: 200,
|
||||
Body: &extensions.Job{
|
||||
Body: &batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Labels: map[string]string{
|
||||
|
@ -248,7 +248,7 @@ func testCreateJob(t *testing.T, group testapi.TestGroup, resourceGroup string)
|
|||
"name": "baz",
|
||||
},
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Template: api.PodTemplateSpec{},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -18,7 +18,7 @@ package testclient
|
|||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
|
@ -29,44 +29,44 @@ type FakeJobs struct {
|
|||
Namespace string
|
||||
}
|
||||
|
||||
func (c *FakeJobs) Get(name string) (*extensions.Job, error) {
|
||||
obj, err := c.Fake.Invokes(NewGetAction("jobs", c.Namespace, name), &extensions.Job{})
|
||||
func (c *FakeJobs) Get(name string) (*batch.Job, error) {
|
||||
obj, err := c.Fake.Invokes(NewGetAction("jobs", c.Namespace, name), &batch.Job{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return obj.(*extensions.Job), err
|
||||
return obj.(*batch.Job), err
|
||||
}
|
||||
|
||||
func (c *FakeJobs) List(opts api.ListOptions) (*extensions.JobList, error) {
|
||||
obj, err := c.Fake.Invokes(NewListAction("jobs", c.Namespace, opts), &extensions.JobList{})
|
||||
func (c *FakeJobs) List(opts api.ListOptions) (*batch.JobList, error) {
|
||||
obj, err := c.Fake.Invokes(NewListAction("jobs", c.Namespace, opts), &batch.JobList{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return obj.(*extensions.JobList), err
|
||||
return obj.(*batch.JobList), err
|
||||
}
|
||||
|
||||
func (c *FakeJobs) Create(job *extensions.Job) (*extensions.Job, error) {
|
||||
func (c *FakeJobs) Create(job *batch.Job) (*batch.Job, error) {
|
||||
obj, err := c.Fake.Invokes(NewCreateAction("jobs", c.Namespace, job), job)
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return obj.(*extensions.Job), err
|
||||
return obj.(*batch.Job), err
|
||||
}
|
||||
|
||||
func (c *FakeJobs) Update(job *extensions.Job) (*extensions.Job, error) {
|
||||
func (c *FakeJobs) Update(job *batch.Job) (*batch.Job, error) {
|
||||
obj, err := c.Fake.Invokes(NewUpdateAction("jobs", c.Namespace, job), job)
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return obj.(*extensions.Job), err
|
||||
return obj.(*batch.Job), err
|
||||
}
|
||||
|
||||
func (c *FakeJobs) Delete(name string, options *api.DeleteOptions) error {
|
||||
_, err := c.Fake.Invokes(NewDeleteAction("jobs", c.Namespace, name), &extensions.Job{})
|
||||
_, err := c.Fake.Invokes(NewDeleteAction("jobs", c.Namespace, name), &batch.Job{})
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -74,13 +74,13 @@ func (c *FakeJobs) Watch(opts api.ListOptions) (watch.Interface, error) {
|
|||
return c.Fake.InvokesWatch(NewWatchAction("jobs", c.Namespace, opts))
|
||||
}
|
||||
|
||||
func (c *FakeJobs) UpdateStatus(job *extensions.Job) (result *extensions.Job, err error) {
|
||||
func (c *FakeJobs) UpdateStatus(job *batch.Job) (result *batch.Job, err error) {
|
||||
obj, err := c.Fake.Invokes(NewUpdateSubresourceAction("jobs", "status", c.Namespace, job), job)
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return obj.(*extensions.Job), err
|
||||
return obj.(*batch.Job), err
|
||||
}
|
||||
|
||||
// FakeJobs implements JobInterface. Meant to be embedded into a struct to get a default
|
||||
|
@ -92,44 +92,44 @@ type FakeJobsV1 struct {
|
|||
Namespace string
|
||||
}
|
||||
|
||||
func (c *FakeJobsV1) Get(name string) (*extensions.Job, error) {
|
||||
obj, err := c.Fake.Invokes(NewGetAction("jobs", c.Namespace, name), &extensions.Job{})
|
||||
func (c *FakeJobsV1) Get(name string) (*batch.Job, error) {
|
||||
obj, err := c.Fake.Invokes(NewGetAction("jobs", c.Namespace, name), &batch.Job{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return obj.(*extensions.Job), err
|
||||
return obj.(*batch.Job), err
|
||||
}
|
||||
|
||||
func (c *FakeJobsV1) List(opts api.ListOptions) (*extensions.JobList, error) {
|
||||
obj, err := c.Fake.Invokes(NewListAction("jobs", c.Namespace, opts), &extensions.JobList{})
|
||||
func (c *FakeJobsV1) List(opts api.ListOptions) (*batch.JobList, error) {
|
||||
obj, err := c.Fake.Invokes(NewListAction("jobs", c.Namespace, opts), &batch.JobList{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return obj.(*extensions.JobList), err
|
||||
return obj.(*batch.JobList), err
|
||||
}
|
||||
|
||||
func (c *FakeJobsV1) Create(job *extensions.Job) (*extensions.Job, error) {
|
||||
func (c *FakeJobsV1) Create(job *batch.Job) (*batch.Job, error) {
|
||||
obj, err := c.Fake.Invokes(NewCreateAction("jobs", c.Namespace, job), job)
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return obj.(*extensions.Job), err
|
||||
return obj.(*batch.Job), err
|
||||
}
|
||||
|
||||
func (c *FakeJobsV1) Update(job *extensions.Job) (*extensions.Job, error) {
|
||||
func (c *FakeJobsV1) Update(job *batch.Job) (*batch.Job, error) {
|
||||
obj, err := c.Fake.Invokes(NewUpdateAction("jobs", c.Namespace, job), job)
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return obj.(*extensions.Job), err
|
||||
return obj.(*batch.Job), err
|
||||
}
|
||||
|
||||
func (c *FakeJobsV1) Delete(name string, options *api.DeleteOptions) error {
|
||||
_, err := c.Fake.Invokes(NewDeleteAction("jobs", c.Namespace, name), &extensions.Job{})
|
||||
_, err := c.Fake.Invokes(NewDeleteAction("jobs", c.Namespace, name), &batch.Job{})
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -137,11 +137,11 @@ func (c *FakeJobsV1) Watch(opts api.ListOptions) (watch.Interface, error) {
|
|||
return c.Fake.InvokesWatch(NewWatchAction("jobs", c.Namespace, opts))
|
||||
}
|
||||
|
||||
func (c *FakeJobsV1) UpdateStatus(job *extensions.Job) (result *extensions.Job, err error) {
|
||||
func (c *FakeJobsV1) UpdateStatus(job *batch.Job) (result *batch.Job, err error) {
|
||||
obj, err := c.Fake.Invokes(NewUpdateSubresourceAction("jobs", "status", c.Namespace, job), job)
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return obj.(*extensions.Job), err
|
||||
return obj.(*batch.Job), err
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ import (
|
|||
"github.com/golang/glog"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/client/cache"
|
||||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
unversionedcore "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/unversioned"
|
||||
|
@ -53,7 +53,7 @@ type JobController struct {
|
|||
internalPodInformer framework.SharedInformer
|
||||
|
||||
// To allow injection of updateJobStatus for testing.
|
||||
updateHandler func(job *extensions.Job) error
|
||||
updateHandler func(job *batch.Job) error
|
||||
syncHandler func(jobKey string) error
|
||||
// podStoreSynced returns true if the pod store has been synced at least once.
|
||||
// Added as a member to the struct to allow injection for testing.
|
||||
|
@ -96,19 +96,19 @@ func NewJobController(podInformer framework.SharedInformer, kubeClient clientset
|
|||
jm.jobStore.Store, jm.jobController = framework.NewInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options api.ListOptions) (runtime.Object, error) {
|
||||
return jm.kubeClient.Extensions().Jobs(api.NamespaceAll).List(options)
|
||||
return jm.kubeClient.Batch().Jobs(api.NamespaceAll).List(options)
|
||||
},
|
||||
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
|
||||
return jm.kubeClient.Extensions().Jobs(api.NamespaceAll).Watch(options)
|
||||
return jm.kubeClient.Batch().Jobs(api.NamespaceAll).Watch(options)
|
||||
},
|
||||
},
|
||||
&extensions.Job{},
|
||||
&batch.Job{},
|
||||
// TODO: Can we have much longer period here?
|
||||
replicationcontroller.FullControllerResyncPeriod,
|
||||
framework.ResourceEventHandlerFuncs{
|
||||
AddFunc: jm.enqueueController,
|
||||
UpdateFunc: func(old, cur interface{}) {
|
||||
if job := cur.(*extensions.Job); !isJobFinished(job) {
|
||||
if job := cur.(*batch.Job); !isJobFinished(job) {
|
||||
jm.enqueueController(job)
|
||||
}
|
||||
},
|
||||
|
@ -155,7 +155,7 @@ func (jm *JobController) Run(workers int, stopCh <-chan struct{}) {
|
|||
}
|
||||
|
||||
// getPodJob returns the job managing the given pod.
|
||||
func (jm *JobController) getPodJob(pod *api.Pod) *extensions.Job {
|
||||
func (jm *JobController) getPodJob(pod *api.Pod) *batch.Job {
|
||||
jobs, err := jm.jobStore.GetPodJobs(pod)
|
||||
if err != nil {
|
||||
glog.V(4).Infof("No jobs found for pod %v, job controller will avoid syncing", pod.Name)
|
||||
|
@ -251,7 +251,7 @@ func (jm *JobController) deletePod(obj interface{}) {
|
|||
}
|
||||
}
|
||||
|
||||
// obj could be an *extensions.Job, or a DeletionFinalStateUnknown marker item.
|
||||
// obj could be an *batch.Job, or a DeletionFinalStateUnknown marker item.
|
||||
func (jm *JobController) enqueueController(obj interface{}) {
|
||||
key, err := controller.KeyFunc(obj)
|
||||
if err != nil {
|
||||
|
@ -314,7 +314,7 @@ func (jm *JobController) syncJob(key string) error {
|
|||
jm.queue.Add(key)
|
||||
return err
|
||||
}
|
||||
job := *obj.(*extensions.Job)
|
||||
job := *obj.(*batch.Job)
|
||||
|
||||
// Check the expectations of the job before counting active pods, otherwise a new pod can sneak in
|
||||
// and update the expectations after we've retrieved active pods from the store. If a new pod enters
|
||||
|
@ -366,7 +366,7 @@ func (jm *JobController) syncJob(key string) error {
|
|||
// update status values accordingly
|
||||
failed += active
|
||||
active = 0
|
||||
job.Status.Conditions = append(job.Status.Conditions, newCondition(extensions.JobFailed, "DeadlineExceeded", "Job was active longer than specified deadline"))
|
||||
job.Status.Conditions = append(job.Status.Conditions, newCondition(batch.JobFailed, "DeadlineExceeded", "Job was active longer than specified deadline"))
|
||||
jm.recorder.Event(&job, api.EventTypeNormal, "DeadlineExceeded", "Job was active longer than specified deadline")
|
||||
} else {
|
||||
if jobNeedsSync {
|
||||
|
@ -400,7 +400,7 @@ func (jm *JobController) syncJob(key string) error {
|
|||
}
|
||||
}
|
||||
if complete {
|
||||
job.Status.Conditions = append(job.Status.Conditions, newCondition(extensions.JobComplete, "", ""))
|
||||
job.Status.Conditions = append(job.Status.Conditions, newCondition(batch.JobComplete, "", ""))
|
||||
now := unversioned.Now()
|
||||
job.Status.CompletionTime = &now
|
||||
}
|
||||
|
@ -421,7 +421,7 @@ func (jm *JobController) syncJob(key string) error {
|
|||
}
|
||||
|
||||
// pastActiveDeadline checks if job has ActiveDeadlineSeconds field set and if it is exceeded.
|
||||
func pastActiveDeadline(job *extensions.Job) bool {
|
||||
func pastActiveDeadline(job *batch.Job) bool {
|
||||
if job.Spec.ActiveDeadlineSeconds == nil || job.Status.StartTime == nil {
|
||||
return false
|
||||
}
|
||||
|
@ -432,8 +432,8 @@ func pastActiveDeadline(job *extensions.Job) bool {
|
|||
return duration >= allowedDuration
|
||||
}
|
||||
|
||||
func newCondition(conditionType extensions.JobConditionType, reason, message string) extensions.JobCondition {
|
||||
return extensions.JobCondition{
|
||||
func newCondition(conditionType batch.JobConditionType, reason, message string) batch.JobCondition {
|
||||
return batch.JobCondition{
|
||||
Type: conditionType,
|
||||
Status: api.ConditionTrue,
|
||||
LastProbeTime: unversioned.Now(),
|
||||
|
@ -452,7 +452,7 @@ func getStatus(pods []api.Pod) (succeeded, failed int) {
|
|||
|
||||
// manageJob is the core method responsible for managing the number of running
|
||||
// pods according to what is specified in the job.Spec.
|
||||
func (jm *JobController) manageJob(activePods []*api.Pod, succeeded int, job *extensions.Job) int {
|
||||
func (jm *JobController) manageJob(activePods []*api.Pod, succeeded int, job *batch.Job) int {
|
||||
var activeLock sync.Mutex
|
||||
active := len(activePods)
|
||||
parallelism := *job.Spec.Parallelism
|
||||
|
@ -538,8 +538,8 @@ func (jm *JobController) manageJob(activePods []*api.Pod, succeeded int, job *ex
|
|||
return active
|
||||
}
|
||||
|
||||
func (jm *JobController) updateJobStatus(job *extensions.Job) error {
|
||||
_, err := jm.kubeClient.Extensions().Jobs(job.Namespace).UpdateStatus(job)
|
||||
func (jm *JobController) updateJobStatus(job *batch.Job) error {
|
||||
_, err := jm.kubeClient.Batch().Jobs(job.Namespace).UpdateStatus(job)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -554,9 +554,9 @@ func filterPods(pods []api.Pod, phase api.PodPhase) int {
|
|||
return result
|
||||
}
|
||||
|
||||
func isJobFinished(j *extensions.Job) bool {
|
||||
func isJobFinished(j *batch.Job) bool {
|
||||
for _, c := range j.Status.Conditions {
|
||||
if (c.Type == extensions.JobComplete || c.Type == extensions.JobFailed) && c.Status == api.ConditionTrue {
|
||||
if (c.Type == batch.JobComplete || c.Type == batch.JobFailed) && c.Status == api.ConditionTrue {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -564,7 +564,7 @@ func isJobFinished(j *extensions.Job) bool {
|
|||
}
|
||||
|
||||
// byCreationTimestamp sorts a list by creation timestamp, using their names as a tie breaker.
|
||||
type byCreationTimestamp []extensions.Job
|
||||
type byCreationTimestamp []batch.Job
|
||||
|
||||
func (o byCreationTimestamp) Len() int { return len(o) }
|
||||
func (o byCreationTimestamp) Swap(i, j int) { o[i], o[j] = o[j], o[i] }
|
||||
|
|
|
@ -24,7 +24,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
|
||||
"k8s.io/kubernetes/pkg/client/restclient"
|
||||
|
@ -37,13 +37,13 @@ import (
|
|||
|
||||
var alwaysReady = func() bool { return true }
|
||||
|
||||
func newJob(parallelism, completions int) *extensions.Job {
|
||||
j := &extensions.Job{
|
||||
func newJob(parallelism, completions int) *batch.Job {
|
||||
j := &batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foobar",
|
||||
Namespace: api.NamespaceDefault,
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Selector: &unversioned.LabelSelector{
|
||||
MatchLabels: map[string]string{"foo": "bar"},
|
||||
},
|
||||
|
@ -76,7 +76,7 @@ func newJob(parallelism, completions int) *extensions.Job {
|
|||
return j
|
||||
}
|
||||
|
||||
func getKey(job *extensions.Job, t *testing.T) string {
|
||||
func getKey(job *batch.Job, t *testing.T) string {
|
||||
if key, err := controller.KeyFunc(job); err != nil {
|
||||
t.Errorf("Unexpected error getting key for job %v: %v", job.Name, err)
|
||||
return ""
|
||||
|
@ -86,7 +86,7 @@ func getKey(job *extensions.Job, t *testing.T) string {
|
|||
}
|
||||
|
||||
// create count pods with the given phase for the given job
|
||||
func newPodList(count int, status api.PodPhase, job *extensions.Job) []api.Pod {
|
||||
func newPodList(count int, status api.PodPhase, job *batch.Job) []api.Pod {
|
||||
pods := []api.Pod{}
|
||||
for i := 0; i < count; i++ {
|
||||
newPod := api.Pod{
|
||||
|
@ -211,8 +211,8 @@ func TestControllerSyncJob(t *testing.T) {
|
|||
fakePodControl := controller.FakePodControl{Err: tc.podControllerError}
|
||||
manager.podControl = &fakePodControl
|
||||
manager.podStoreSynced = alwaysReady
|
||||
var actual *extensions.Job
|
||||
manager.updateHandler = func(job *extensions.Job) error {
|
||||
var actual *batch.Job
|
||||
manager.updateHandler = func(job *batch.Job) error {
|
||||
actual = job
|
||||
return nil
|
||||
}
|
||||
|
@ -257,7 +257,7 @@ func TestControllerSyncJob(t *testing.T) {
|
|||
t.Errorf("%s: .status.startTime was not set", name)
|
||||
}
|
||||
// validate conditions
|
||||
if tc.expectedComplete && !getCondition(actual, extensions.JobComplete) {
|
||||
if tc.expectedComplete && !getCondition(actual, batch.JobComplete) {
|
||||
t.Errorf("%s: expected completion condition. Got %#v", name, actual.Status.Conditions)
|
||||
}
|
||||
}
|
||||
|
@ -306,8 +306,8 @@ func TestSyncJobPastDeadline(t *testing.T) {
|
|||
fakePodControl := controller.FakePodControl{}
|
||||
manager.podControl = &fakePodControl
|
||||
manager.podStoreSynced = alwaysReady
|
||||
var actual *extensions.Job
|
||||
manager.updateHandler = func(job *extensions.Job) error {
|
||||
var actual *batch.Job
|
||||
manager.updateHandler = func(job *batch.Job) error {
|
||||
actual = job
|
||||
return nil
|
||||
}
|
||||
|
@ -355,13 +355,13 @@ func TestSyncJobPastDeadline(t *testing.T) {
|
|||
t.Errorf("%s: .status.startTime was not set", name)
|
||||
}
|
||||
// validate conditions
|
||||
if !getCondition(actual, extensions.JobFailed) {
|
||||
if !getCondition(actual, batch.JobFailed) {
|
||||
t.Errorf("%s: expected fail condition. Got %#v", name, actual.Status.Conditions)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getCondition(job *extensions.Job, condition extensions.JobConditionType) bool {
|
||||
func getCondition(job *batch.Job, condition batch.JobConditionType) bool {
|
||||
for _, v := range job.Status.Conditions {
|
||||
if v.Type == condition && v.Status == api.ConditionTrue {
|
||||
return true
|
||||
|
@ -376,8 +376,8 @@ func TestSyncPastDeadlineJobFinished(t *testing.T) {
|
|||
fakePodControl := controller.FakePodControl{}
|
||||
manager.podControl = &fakePodControl
|
||||
manager.podStoreSynced = alwaysReady
|
||||
var actual *extensions.Job
|
||||
manager.updateHandler = func(job *extensions.Job) error {
|
||||
var actual *batch.Job
|
||||
manager.updateHandler = func(job *batch.Job) error {
|
||||
actual = job
|
||||
return nil
|
||||
}
|
||||
|
@ -387,7 +387,7 @@ func TestSyncPastDeadlineJobFinished(t *testing.T) {
|
|||
job.Spec.ActiveDeadlineSeconds = &activeDeadlineSeconds
|
||||
start := unversioned.Unix(unversioned.Now().Time.Unix()-15, 0)
|
||||
job.Status.StartTime = &start
|
||||
job.Status.Conditions = append(job.Status.Conditions, newCondition(extensions.JobFailed, "DeadlineExceeded", "Job was active longer than specified deadline"))
|
||||
job.Status.Conditions = append(job.Status.Conditions, newCondition(batch.JobFailed, "DeadlineExceeded", "Job was active longer than specified deadline"))
|
||||
manager.jobStore.Store.Add(job)
|
||||
err := manager.syncJob(getKey(job, t))
|
||||
if err != nil {
|
||||
|
@ -412,7 +412,7 @@ func TestSyncJobComplete(t *testing.T) {
|
|||
manager.podStoreSynced = alwaysReady
|
||||
|
||||
job := newJob(1, 1)
|
||||
job.Status.Conditions = append(job.Status.Conditions, newCondition(extensions.JobComplete, "", ""))
|
||||
job.Status.Conditions = append(job.Status.Conditions, newCondition(batch.JobComplete, "", ""))
|
||||
manager.jobStore.Store.Add(job)
|
||||
err := manager.syncJob(getKey(job, t))
|
||||
if err != nil {
|
||||
|
@ -422,7 +422,7 @@ func TestSyncJobComplete(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatalf("Unexpected error when trying to get job from the store: %v", err)
|
||||
}
|
||||
actual := uncastJob.(*extensions.Job)
|
||||
actual := uncastJob.(*batch.Job)
|
||||
// Verify that after syncing a complete job, the conditions are the same.
|
||||
if got, expected := len(actual.Status.Conditions), 1; got != expected {
|
||||
t.Fatalf("Unexpected job status conditions amount; expected %d, got %d", expected, got)
|
||||
|
@ -435,7 +435,7 @@ func TestSyncJobDeleted(t *testing.T) {
|
|||
fakePodControl := controller.FakePodControl{}
|
||||
manager.podControl = &fakePodControl
|
||||
manager.podStoreSynced = alwaysReady
|
||||
manager.updateHandler = func(job *extensions.Job) error { return nil }
|
||||
manager.updateHandler = func(job *batch.Job) error { return nil }
|
||||
job := newJob(2, 2)
|
||||
err := manager.syncJob(getKey(job, t))
|
||||
if err != nil {
|
||||
|
@ -455,7 +455,7 @@ func TestSyncJobUpdateRequeue(t *testing.T) {
|
|||
fakePodControl := controller.FakePodControl{}
|
||||
manager.podControl = &fakePodControl
|
||||
manager.podStoreSynced = alwaysReady
|
||||
manager.updateHandler = func(job *extensions.Job) error { return fmt.Errorf("Fake error") }
|
||||
manager.updateHandler = func(job *batch.Job) error { return fmt.Errorf("Fake error") }
|
||||
job := newJob(2, 2)
|
||||
manager.jobStore.Store.Add(job)
|
||||
err := manager.syncJob(getKey(job, t))
|
||||
|
@ -475,14 +475,14 @@ func TestJobPodLookup(t *testing.T) {
|
|||
manager := NewJobControllerFromClient(clientset, controller.NoResyncPeriodFunc)
|
||||
manager.podStoreSynced = alwaysReady
|
||||
testCases := []struct {
|
||||
job *extensions.Job
|
||||
job *batch.Job
|
||||
pod *api.Pod
|
||||
|
||||
expectedName string
|
||||
}{
|
||||
// pods without labels don't match any job
|
||||
{
|
||||
job: &extensions.Job{
|
||||
job: &batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{Name: "basic"},
|
||||
},
|
||||
pod: &api.Pod{
|
||||
|
@ -492,9 +492,9 @@ func TestJobPodLookup(t *testing.T) {
|
|||
},
|
||||
// matching labels, different namespace
|
||||
{
|
||||
job: &extensions.Job{
|
||||
job: &batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Selector: &unversioned.LabelSelector{
|
||||
MatchLabels: map[string]string{"foo": "bar"},
|
||||
},
|
||||
|
@ -511,9 +511,9 @@ func TestJobPodLookup(t *testing.T) {
|
|||
},
|
||||
// matching ns and labels returns
|
||||
{
|
||||
job: &extensions.Job{
|
||||
job: &batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "ns"},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Selector: &unversioned.LabelSelector{
|
||||
MatchExpressions: []unversioned.LabelSelectorRequirement{
|
||||
{
|
||||
|
@ -566,7 +566,7 @@ func TestSyncJobExpectations(t *testing.T) {
|
|||
fakePodControl := controller.FakePodControl{}
|
||||
manager.podControl = &fakePodControl
|
||||
manager.podStoreSynced = alwaysReady
|
||||
manager.updateHandler = func(job *extensions.Job) error { return nil }
|
||||
manager.updateHandler = func(job *batch.Job) error { return nil }
|
||||
|
||||
job := newJob(2, 2)
|
||||
manager.jobStore.Store.Add(job)
|
||||
|
@ -602,7 +602,7 @@ func TestWatchJobs(t *testing.T) {
|
|||
manager := NewJobControllerFromClient(clientset, controller.NoResyncPeriodFunc)
|
||||
manager.podStoreSynced = alwaysReady
|
||||
|
||||
var testJob extensions.Job
|
||||
var testJob batch.Job
|
||||
received := make(chan struct{})
|
||||
|
||||
// The update sent through the fakeWatcher should make its way into the workqueue,
|
||||
|
@ -613,7 +613,7 @@ func TestWatchJobs(t *testing.T) {
|
|||
if !exists || err != nil {
|
||||
t.Errorf("Expected to find job under key %v", key)
|
||||
}
|
||||
job, ok := obj.(*extensions.Job)
|
||||
job, ok := obj.(*batch.Job)
|
||||
if !ok {
|
||||
t.Fatalf("unexpected type: %v %#v", reflect.TypeOf(obj), obj)
|
||||
}
|
||||
|
@ -637,10 +637,10 @@ func TestWatchJobs(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestIsJobFinished(t *testing.T) {
|
||||
job := &extensions.Job{
|
||||
Status: extensions.JobStatus{
|
||||
Conditions: []extensions.JobCondition{{
|
||||
Type: extensions.JobComplete,
|
||||
job := &batch.Job{
|
||||
Status: batch.JobStatus{
|
||||
Conditions: []batch.JobCondition{{
|
||||
Type: batch.JobComplete,
|
||||
Status: api.ConditionTrue,
|
||||
}},
|
||||
},
|
||||
|
@ -681,7 +681,7 @@ func TestWatchPods(t *testing.T) {
|
|||
close(received)
|
||||
return nil
|
||||
}
|
||||
job, ok := obj.(*extensions.Job)
|
||||
job, ok := obj.(*batch.Job)
|
||||
if !ok {
|
||||
t.Errorf("unexpected type: %v %#v", reflect.TypeOf(obj), obj)
|
||||
close(received)
|
||||
|
|
|
@ -33,6 +33,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/client/restclient"
|
||||
"k8s.io/kubernetes/pkg/client/unversioned/fake"
|
||||
|
@ -262,14 +263,14 @@ func TestDrain(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
job := extensions.Job{
|
||||
job := batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "job",
|
||||
Namespace: "default",
|
||||
CreationTimestamp: unversioned.Time{Time: time.Now()},
|
||||
SelfLink: "/apis/extensions/v1beta1/namespaces/default/jobs/job",
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Selector: &unversioned.LabelSelector{MatchLabels: labels},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -665,7 +665,7 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
|||
}
|
||||
pod, _, err := GetFirstPod(client, t.Namespace, selector)
|
||||
return pod, err
|
||||
case *extensions.Job:
|
||||
case *batch.Job:
|
||||
selector, err := unversioned.LabelSelectorAsSelector(t.Spec.Selector)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid label selector: %v", err)
|
||||
|
|
|
@ -1089,7 +1089,7 @@ func (d *JobDescriber) Describe(namespace, name string) (string, error) {
|
|||
return describeJob(job, events)
|
||||
}
|
||||
|
||||
func describeJob(job *extensions.Job, events *api.EventList) (string, error) {
|
||||
func describeJob(job *batch.Job, events *api.EventList) (string, error) {
|
||||
return tabbedString(func(out io.Writer) error {
|
||||
fmt.Fprintf(out, "Name:\t%s\n", job.Name)
|
||||
fmt.Fprintf(out, "Namespace:\t%s\n", job.Namespace)
|
||||
|
|
|
@ -36,6 +36,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/apis/apps"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
|
@ -795,7 +796,7 @@ func printReplicaSetList(list *extensions.ReplicaSetList, w io.Writer, options P
|
|||
return nil
|
||||
}
|
||||
|
||||
func printJob(job *extensions.Job, w io.Writer, options PrintOptions) error {
|
||||
func printJob(job *batch.Job, w io.Writer, options PrintOptions) error {
|
||||
name := job.Name
|
||||
namespace := job.Namespace
|
||||
containers := job.Spec.Template.Spec.Containers
|
||||
|
@ -848,7 +849,7 @@ func printJob(job *extensions.Job, w io.Writer, options PrintOptions) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func printJobList(list *extensions.JobList, w io.Writer, options PrintOptions) error {
|
||||
func printJobList(list *batch.JobList, w io.Writer, options PrintOptions) error {
|
||||
for _, job := range list.Items {
|
||||
if err := printJob(&job, w, options); err != nil {
|
||||
return err
|
||||
|
@ -1784,7 +1785,7 @@ func formatWideHeaders(wide bool, t reflect.Type) []string {
|
|||
if t.String() == "*api.ReplicationController" || t.String() == "*api.ReplicationControllerList" {
|
||||
return []string{"CONTAINER(S)", "IMAGE(S)", "SELECTOR"}
|
||||
}
|
||||
if t.String() == "*extensions.Job" || t.String() == "*extensions.JobList" {
|
||||
if t.String() == "*batch.Job" || t.String() == "*batch.JobList" {
|
||||
return []string{"CONTAINER(S)", "IMAGE(S)", "SELECTOR"}
|
||||
}
|
||||
if t.String() == "*api.Service" || t.String() == "*api.ServiceList" {
|
||||
|
|
|
@ -30,6 +30,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
kubectltesting "k8s.io/kubernetes/pkg/kubectl/testing"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
|
@ -1343,34 +1344,34 @@ func TestPrintDaemonSet(t *testing.T) {
|
|||
func TestPrintJob(t *testing.T) {
|
||||
completions := 2
|
||||
tests := []struct {
|
||||
job extensions.Job
|
||||
job batch.Job
|
||||
expect string
|
||||
}{
|
||||
{
|
||||
extensions.Job{
|
||||
batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "job1",
|
||||
CreationTimestamp: unversioned.Time{Time: time.Now().Add(1.9e9)},
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Completions: &completions,
|
||||
},
|
||||
Status: extensions.JobStatus{
|
||||
Status: batch.JobStatus{
|
||||
Succeeded: 1,
|
||||
},
|
||||
},
|
||||
"job1\t2\t1\t0s\n",
|
||||
},
|
||||
{
|
||||
extensions.Job{
|
||||
batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "job2",
|
||||
CreationTimestamp: unversioned.Time{Time: time.Now().AddDate(-10, 0, 0)},
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Completions: nil,
|
||||
},
|
||||
Status: extensions.JobStatus{
|
||||
Status: batch.JobStatus{
|
||||
Succeeded: 0,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/api/resource"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
batchv1 "k8s.io/kubernetes/pkg/apis/batch/v1"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
|
@ -280,12 +281,12 @@ func (JobV1Beta1) Generate(genericParams map[string]interface{}) (runtime.Object
|
|||
}
|
||||
podSpec.RestartPolicy = restartPolicy
|
||||
|
||||
job := extensions.Job{
|
||||
job := batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: name,
|
||||
Labels: labels,
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Selector: &unversioned.LabelSelector{
|
||||
MatchLabels: labels,
|
||||
},
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/resource"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
)
|
||||
|
||||
|
@ -721,7 +722,7 @@ func TestGenerateDeployment(t *testing.T) {
|
|||
func TestGenerateJob(t *testing.T) {
|
||||
tests := []struct {
|
||||
params map[string]interface{}
|
||||
expected *extensions.Job
|
||||
expected *batch.Job
|
||||
expectErr bool
|
||||
}{
|
||||
{
|
||||
|
@ -740,12 +741,12 @@ func TestGenerateJob(t *testing.T) {
|
|||
"limits": "cpu=400m,memory=200Mi",
|
||||
"restart": "OnFailure",
|
||||
},
|
||||
expected: &extensions.Job{
|
||||
expected: &batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Labels: map[string]string{"foo": "bar", "baz": "blah"},
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Selector: &unversioned.LabelSelector{
|
||||
MatchLabels: map[string]string{"foo": "bar", "baz": "blah"},
|
||||
},
|
||||
|
@ -807,8 +808,8 @@ func TestGenerateJob(t *testing.T) {
|
|||
if test.expectErr && err != nil {
|
||||
continue
|
||||
}
|
||||
if !reflect.DeepEqual(obj.(*extensions.Job), test.expected) {
|
||||
t.Errorf("\nexpected:\n%#v\nsaw:\n%#v", test.expected, obj.(*extensions.Job))
|
||||
if !reflect.DeepEqual(obj.(*batch.Job), test.expected) {
|
||||
t.Errorf("\nexpected:\n%#v\nsaw:\n%#v", test.expected, obj.(*batch.Job))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ func ScalerFor(kind unversioned.GroupKind, c client.Interface) (Scaler, error) {
|
|||
case extensions.Kind("ReplicaSet"):
|
||||
return &ReplicaSetScaler{c.Extensions()}, nil
|
||||
case extensions.Kind("Job"), batch.Kind("Job"):
|
||||
return &JobScaler{c.Extensions()}, nil // Either kind of job can be scaled with Extensions interface.
|
||||
return &JobScaler{c.Batch()}, nil // Either kind of job can be scaled with Batch interface.
|
||||
case extensions.Kind("Deployment"):
|
||||
return &DeploymentScaler{c.Extensions()}, nil
|
||||
}
|
||||
|
@ -252,7 +252,7 @@ func (scaler *ReplicaSetScaler) Scale(namespace, name string, newSize uint, prec
|
|||
}
|
||||
|
||||
// ValidateJob ensures that the preconditions match. Returns nil if they are valid, an error otherwise.
|
||||
func (precondition *ScalePrecondition) ValidateJob(job *extensions.Job) error {
|
||||
func (precondition *ScalePrecondition) ValidateJob(job *batch.Job) error {
|
||||
if precondition.Size != -1 && job.Spec.Parallelism == nil {
|
||||
return PreconditionError{"parallelism", strconv.Itoa(precondition.Size), "nil"}
|
||||
}
|
||||
|
@ -266,7 +266,7 @@ func (precondition *ScalePrecondition) ValidateJob(job *extensions.Job) error {
|
|||
}
|
||||
|
||||
type JobScaler struct {
|
||||
c client.ExtensionsInterface
|
||||
c client.BatchInterface
|
||||
}
|
||||
|
||||
// ScaleSimple is responsible for updating job's parallelism.
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
kerrors "k8s.io/kubernetes/pkg/api/errors"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
"k8s.io/kubernetes/pkg/client/unversioned/testclient"
|
||||
|
@ -252,17 +253,17 @@ type ErrorJobs struct {
|
|||
invalid bool
|
||||
}
|
||||
|
||||
func (c *ErrorJobs) Update(job *extensions.Job) (*extensions.Job, error) {
|
||||
func (c *ErrorJobs) Update(job *batch.Job) (*batch.Job, error) {
|
||||
if c.invalid {
|
||||
return nil, kerrors.NewInvalid(extensions.Kind(job.Kind), job.Name, nil)
|
||||
return nil, kerrors.NewInvalid(batch.Kind(job.Kind), job.Name, nil)
|
||||
}
|
||||
return nil, errors.New("Job update failure")
|
||||
}
|
||||
|
||||
func (c *ErrorJobs) Get(name string) (*extensions.Job, error) {
|
||||
func (c *ErrorJobs) Get(name string) (*batch.Job, error) {
|
||||
zero := 0
|
||||
return &extensions.Job{
|
||||
Spec: extensions.JobSpec{
|
||||
return &batch.Job{
|
||||
Spec: batch.JobSpec{
|
||||
Parallelism: &zero,
|
||||
},
|
||||
}, nil
|
||||
|
@ -316,7 +317,7 @@ func TestJobScale(t *testing.T) {
|
|||
if action, ok := actions[0].(testclient.GetAction); !ok || action.GetResource() != "jobs" || action.GetName() != name {
|
||||
t.Errorf("unexpected action: %v, expected get-replicationController %s", actions[0], name)
|
||||
}
|
||||
if action, ok := actions[1].(testclient.UpdateAction); !ok || action.GetResource() != "jobs" || *action.GetObject().(*extensions.Job).Spec.Parallelism != int(count) {
|
||||
if action, ok := actions[1].(testclient.UpdateAction); !ok || action.GetResource() != "jobs" || *action.GetObject().(*batch.Job).Spec.Parallelism != int(count) {
|
||||
t.Errorf("unexpected action %v, expected update-job with parallelism = %d", actions[1], count)
|
||||
}
|
||||
}
|
||||
|
@ -342,8 +343,8 @@ func TestJobScaleInvalid(t *testing.T) {
|
|||
|
||||
func TestJobScaleFailsPreconditions(t *testing.T) {
|
||||
ten := 10
|
||||
fake := testclient.NewSimpleFake(&extensions.Job{
|
||||
Spec: extensions.JobSpec{
|
||||
fake := testclient.NewSimpleFake(&batch.Job{
|
||||
Spec: batch.JobSpec{
|
||||
Parallelism: &ten,
|
||||
},
|
||||
})
|
||||
|
@ -366,7 +367,7 @@ func TestValidateJob(t *testing.T) {
|
|||
zero, ten, twenty := 0, 10, 20
|
||||
tests := []struct {
|
||||
preconditions ScalePrecondition
|
||||
job extensions.Job
|
||||
job batch.Job
|
||||
expectError bool
|
||||
test string
|
||||
}{
|
||||
|
@ -377,11 +378,11 @@ func TestValidateJob(t *testing.T) {
|
|||
},
|
||||
{
|
||||
preconditions: ScalePrecondition{-1, ""},
|
||||
job: extensions.Job{
|
||||
job: batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ResourceVersion: "foo",
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Parallelism: &ten,
|
||||
},
|
||||
},
|
||||
|
@ -390,11 +391,11 @@ func TestValidateJob(t *testing.T) {
|
|||
},
|
||||
{
|
||||
preconditions: ScalePrecondition{0, ""},
|
||||
job: extensions.Job{
|
||||
job: batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ResourceVersion: "foo",
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Parallelism: &zero,
|
||||
},
|
||||
},
|
||||
|
@ -403,11 +404,11 @@ func TestValidateJob(t *testing.T) {
|
|||
},
|
||||
{
|
||||
preconditions: ScalePrecondition{-1, "foo"},
|
||||
job: extensions.Job{
|
||||
job: batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ResourceVersion: "foo",
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Parallelism: &ten,
|
||||
},
|
||||
},
|
||||
|
@ -416,11 +417,11 @@ func TestValidateJob(t *testing.T) {
|
|||
},
|
||||
{
|
||||
preconditions: ScalePrecondition{10, "foo"},
|
||||
job: extensions.Job{
|
||||
job: batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ResourceVersion: "foo",
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Parallelism: &ten,
|
||||
},
|
||||
},
|
||||
|
@ -429,11 +430,11 @@ func TestValidateJob(t *testing.T) {
|
|||
},
|
||||
{
|
||||
preconditions: ScalePrecondition{10, "foo"},
|
||||
job: extensions.Job{
|
||||
job: batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ResourceVersion: "foo",
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Parallelism: &twenty,
|
||||
},
|
||||
},
|
||||
|
@ -442,7 +443,7 @@ func TestValidateJob(t *testing.T) {
|
|||
},
|
||||
{
|
||||
preconditions: ScalePrecondition{10, "foo"},
|
||||
job: extensions.Job{
|
||||
job: batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ResourceVersion: "foo",
|
||||
},
|
||||
|
@ -452,11 +453,11 @@ func TestValidateJob(t *testing.T) {
|
|||
},
|
||||
{
|
||||
preconditions: ScalePrecondition{10, "foo"},
|
||||
job: extensions.Job{
|
||||
job: batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ResourceVersion: "bar",
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Parallelism: &ten,
|
||||
},
|
||||
},
|
||||
|
@ -465,11 +466,11 @@ func TestValidateJob(t *testing.T) {
|
|||
},
|
||||
{
|
||||
preconditions: ScalePrecondition{10, "foo"},
|
||||
job: extensions.Job{
|
||||
job: batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ResourceVersion: "bar",
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Parallelism: &twenty,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -314,9 +314,9 @@ func (reaper *DaemonSetReaper) Stop(namespace, name string, timeout time.Duratio
|
|||
}
|
||||
|
||||
func (reaper *JobReaper) Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) error {
|
||||
jobs := reaper.Extensions().Jobs(namespace)
|
||||
jobs := reaper.Batch().Jobs(namespace)
|
||||
pods := reaper.Pods(namespace)
|
||||
scaler, err := ScalerFor(extensions.Kind("Job"), *reaper)
|
||||
scaler, err := ScalerFor(batch.Kind("Job"), *reaper)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
"k8s.io/kubernetes/pkg/client/unversioned/testclient"
|
||||
|
@ -388,26 +389,26 @@ func TestJobStop(t *testing.T) {
|
|||
{
|
||||
Name: "OnlyOneJob",
|
||||
Objs: []runtime.Object{
|
||||
&extensions.Job{ // GET
|
||||
&batch.Job{ // GET
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: ns,
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Parallelism: &zero,
|
||||
Selector: &unversioned.LabelSelector{
|
||||
MatchLabels: map[string]string{"k1": "v1"},
|
||||
},
|
||||
},
|
||||
},
|
||||
&extensions.JobList{ // LIST
|
||||
Items: []extensions.Job{
|
||||
&batch.JobList{ // LIST
|
||||
Items: []batch.Job{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: ns,
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Parallelism: &zero,
|
||||
Selector: &unversioned.LabelSelector{
|
||||
MatchLabels: map[string]string{"k1": "v1"},
|
||||
|
@ -424,26 +425,26 @@ func TestJobStop(t *testing.T) {
|
|||
{
|
||||
Name: "JobWithDeadPods",
|
||||
Objs: []runtime.Object{
|
||||
&extensions.Job{ // GET
|
||||
&batch.Job{ // GET
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: ns,
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Parallelism: &zero,
|
||||
Selector: &unversioned.LabelSelector{
|
||||
MatchLabels: map[string]string{"k1": "v1"},
|
||||
},
|
||||
},
|
||||
},
|
||||
&extensions.JobList{ // LIST
|
||||
Items: []extensions.Job{
|
||||
&batch.JobList{ // LIST
|
||||
Items: []batch.Job{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: ns,
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Parallelism: &zero,
|
||||
Selector: &unversioned.LabelSelector{
|
||||
MatchLabels: map[string]string{"k1": "v1"},
|
||||
|
|
|
@ -18,7 +18,7 @@ package etcd
|
|||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/registry/cachesize"
|
||||
|
@ -37,12 +37,12 @@ type REST struct {
|
|||
func NewREST(opts generic.RESTOptions) (*REST, *StatusREST) {
|
||||
prefix := "/jobs"
|
||||
|
||||
newListFunc := func() runtime.Object { return &extensions.JobList{} }
|
||||
newListFunc := func() runtime.Object { return &batch.JobList{} }
|
||||
storageInterface := opts.Decorator(
|
||||
opts.Storage, cachesize.GetWatchCacheSizeByResource(cachesize.Jobs), &extensions.Job{}, prefix, job.Strategy, newListFunc)
|
||||
opts.Storage, cachesize.GetWatchCacheSizeByResource(cachesize.Jobs), &batch.Job{}, prefix, job.Strategy, newListFunc)
|
||||
|
||||
store := &etcdgeneric.Etcd{
|
||||
NewFunc: func() runtime.Object { return &extensions.Job{} },
|
||||
NewFunc: func() runtime.Object { return &batch.Job{} },
|
||||
|
||||
// NewListFunc returns an object capable of storing results of an etcd list.
|
||||
NewListFunc: newListFunc,
|
||||
|
@ -58,13 +58,13 @@ func NewREST(opts generic.RESTOptions) (*REST, *StatusREST) {
|
|||
},
|
||||
// Retrieve the name field of a job
|
||||
ObjectNameFunc: func(obj runtime.Object) (string, error) {
|
||||
return obj.(*extensions.Job).Name, nil
|
||||
return obj.(*batch.Job).Name, nil
|
||||
},
|
||||
// Used to match objects based on labels/fields for list and watch
|
||||
PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher {
|
||||
return job.MatchJob(label, field)
|
||||
},
|
||||
QualifiedResource: extensions.Resource("jobs"),
|
||||
QualifiedResource: batch.Resource("jobs"),
|
||||
DeleteCollectionWorkers: opts.DeleteCollectionWorkers,
|
||||
|
||||
// Used to validate job creation
|
||||
|
@ -89,7 +89,7 @@ type StatusREST struct {
|
|||
}
|
||||
|
||||
func (r *StatusREST) New() runtime.Object {
|
||||
return &extensions.Job{}
|
||||
return &batch.Job{}
|
||||
}
|
||||
|
||||
// Update alters the status subset of an object.
|
||||
|
|
|
@ -21,9 +21,8 @@ import (
|
|||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
// Ensure that extensions/v1beta1 package is initialized.
|
||||
_ "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/registry/generic"
|
||||
|
@ -39,15 +38,15 @@ func newStorage(t *testing.T) (*REST, *StatusREST, *etcdtesting.EtcdTestServer)
|
|||
return jobStorage, statusStorage, server
|
||||
}
|
||||
|
||||
func validNewJob() *extensions.Job {
|
||||
func validNewJob() *batch.Job {
|
||||
completions := 1
|
||||
parallelism := 1
|
||||
return &extensions.Job{
|
||||
return &batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Completions: &completions,
|
||||
Parallelism: ¶llelism,
|
||||
Selector: &unversioned.LabelSelector{
|
||||
|
@ -84,8 +83,8 @@ func TestCreate(t *testing.T) {
|
|||
// valid
|
||||
validJob,
|
||||
// invalid (empty selector)
|
||||
&extensions.Job{
|
||||
Spec: extensions.JobSpec{
|
||||
&batch.Job{
|
||||
Spec: batch.JobSpec{
|
||||
Completions: validJob.Spec.Completions,
|
||||
Selector: &unversioned.LabelSelector{},
|
||||
Template: validJob.Spec.Template,
|
||||
|
@ -104,18 +103,18 @@ func TestUpdate(t *testing.T) {
|
|||
validNewJob(),
|
||||
// updateFunc
|
||||
func(obj runtime.Object) runtime.Object {
|
||||
object := obj.(*extensions.Job)
|
||||
object := obj.(*batch.Job)
|
||||
object.Spec.Parallelism = &two
|
||||
return object
|
||||
},
|
||||
// invalid updateFunc
|
||||
func(obj runtime.Object) runtime.Object {
|
||||
object := obj.(*extensions.Job)
|
||||
object := obj.(*batch.Job)
|
||||
object.Spec.Selector = &unversioned.LabelSelector{}
|
||||
return object
|
||||
},
|
||||
func(obj runtime.Object) runtime.Object {
|
||||
object := obj.(*extensions.Job)
|
||||
object := obj.(*batch.Job)
|
||||
object.Spec.Completions = &two
|
||||
return object
|
||||
},
|
||||
|
|
|
@ -22,8 +22,8 @@ import (
|
|||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions/validation"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/apis/batch/validation"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/registry/generic"
|
||||
|
@ -47,20 +47,20 @@ func (jobStrategy) NamespaceScoped() bool {
|
|||
|
||||
// PrepareForCreate clears the status of a job before creation.
|
||||
func (jobStrategy) PrepareForCreate(obj runtime.Object) {
|
||||
job := obj.(*extensions.Job)
|
||||
job.Status = extensions.JobStatus{}
|
||||
job := obj.(*batch.Job)
|
||||
job.Status = batch.JobStatus{}
|
||||
}
|
||||
|
||||
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
|
||||
func (jobStrategy) PrepareForUpdate(obj, old runtime.Object) {
|
||||
newJob := obj.(*extensions.Job)
|
||||
oldJob := old.(*extensions.Job)
|
||||
newJob := obj.(*batch.Job)
|
||||
oldJob := old.(*batch.Job)
|
||||
newJob.Status = oldJob.Status
|
||||
}
|
||||
|
||||
// Validate validates a new job.
|
||||
func (jobStrategy) Validate(ctx api.Context, obj runtime.Object) field.ErrorList {
|
||||
job := obj.(*extensions.Job)
|
||||
job := obj.(*batch.Job)
|
||||
// TODO: move UID generation earlier and do this in defaulting logic?
|
||||
if job.Spec.ManualSelector == nil || *job.Spec.ManualSelector == false {
|
||||
generateSelector(job)
|
||||
|
@ -71,7 +71,7 @@ func (jobStrategy) Validate(ctx api.Context, obj runtime.Object) field.ErrorList
|
|||
// generateSelector adds a selector to a job and labels to its template
|
||||
// which can be used to uniquely identify the pods created by that job,
|
||||
// if the user has requested this behavior.
|
||||
func generateSelector(obj *extensions.Job) {
|
||||
func generateSelector(obj *batch.Job) {
|
||||
if obj.Spec.Template.Labels == nil {
|
||||
obj.Spec.Template.Labels = make(map[string]string)
|
||||
}
|
||||
|
@ -133,8 +133,8 @@ func (jobStrategy) AllowCreateOnUpdate() bool {
|
|||
|
||||
// ValidateUpdate is the default update validation for an end user.
|
||||
func (jobStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) field.ErrorList {
|
||||
validationErrorList := validation.ValidateJob(obj.(*extensions.Job))
|
||||
updateErrorList := validation.ValidateJobUpdate(obj.(*extensions.Job), old.(*extensions.Job))
|
||||
validationErrorList := validation.ValidateJob(obj.(*batch.Job))
|
||||
updateErrorList := validation.ValidateJobUpdate(obj.(*batch.Job), old.(*batch.Job))
|
||||
return append(validationErrorList, updateErrorList...)
|
||||
}
|
||||
|
||||
|
@ -145,17 +145,17 @@ type jobStatusStrategy struct {
|
|||
var StatusStrategy = jobStatusStrategy{Strategy}
|
||||
|
||||
func (jobStatusStrategy) PrepareForUpdate(obj, old runtime.Object) {
|
||||
newJob := obj.(*extensions.Job)
|
||||
oldJob := old.(*extensions.Job)
|
||||
newJob := obj.(*batch.Job)
|
||||
oldJob := old.(*batch.Job)
|
||||
newJob.Spec = oldJob.Spec
|
||||
}
|
||||
|
||||
func (jobStatusStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) field.ErrorList {
|
||||
return validation.ValidateJobUpdateStatus(obj.(*extensions.Job), old.(*extensions.Job))
|
||||
return validation.ValidateJobUpdateStatus(obj.(*batch.Job), old.(*batch.Job))
|
||||
}
|
||||
|
||||
// JobSelectableFields returns a field set that represents the object for matching purposes.
|
||||
func JobToSelectableFields(job *extensions.Job) fields.Set {
|
||||
func JobToSelectableFields(job *batch.Job) fields.Set {
|
||||
objectMetaFieldsSet := generic.ObjectMetaFieldsSet(job.ObjectMeta, true)
|
||||
specificFieldsSet := fields.Set{
|
||||
"status.successful": strconv.Itoa(job.Status.Succeeded),
|
||||
|
@ -171,7 +171,7 @@ func MatchJob(label labels.Selector, field fields.Selector) generic.Matcher {
|
|||
Label: label,
|
||||
Field: field,
|
||||
GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
job, ok := obj.(*extensions.Job)
|
||||
job, ok := obj.(*batch.Job)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("Given object is not a job.")
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
apitesting "k8s.io/kubernetes/pkg/api/testing"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/types"
|
||||
)
|
||||
|
@ -57,17 +57,17 @@ func TestJobStrategy(t *testing.T) {
|
|||
Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||
},
|
||||
}
|
||||
job := &extensions.Job{
|
||||
job := &batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "myjob",
|
||||
Namespace: api.NamespaceDefault,
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Selector: validSelector,
|
||||
Template: validPodTemplateSpec,
|
||||
ManualSelector: newBool(true),
|
||||
},
|
||||
Status: extensions.JobStatus{
|
||||
Status: batch.JobStatus{
|
||||
Active: 11,
|
||||
},
|
||||
}
|
||||
|
@ -81,12 +81,12 @@ func TestJobStrategy(t *testing.T) {
|
|||
t.Errorf("Unexpected error validating %v", errs)
|
||||
}
|
||||
parallelism := 10
|
||||
updatedJob := &extensions.Job{
|
||||
updatedJob := &batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{Name: "bar", ResourceVersion: "4"},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Parallelism: ¶llelism,
|
||||
},
|
||||
Status: extensions.JobStatus{
|
||||
Status: batch.JobStatus{
|
||||
Active: 11,
|
||||
},
|
||||
}
|
||||
|
@ -114,13 +114,13 @@ func TestJobStrategyWithGeneration(t *testing.T) {
|
|||
Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||
},
|
||||
}
|
||||
job := &extensions.Job{
|
||||
job := &batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "myjob2",
|
||||
Namespace: api.NamespaceDefault,
|
||||
UID: theUID,
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Selector: nil,
|
||||
Template: validPodTemplateSpec,
|
||||
},
|
||||
|
@ -175,33 +175,33 @@ func TestJobStatusStrategy(t *testing.T) {
|
|||
}
|
||||
oldParallelism := 10
|
||||
newParallelism := 11
|
||||
oldJob := &extensions.Job{
|
||||
oldJob := &batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "myjob",
|
||||
Namespace: api.NamespaceDefault,
|
||||
ResourceVersion: "10",
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Selector: validSelector,
|
||||
Template: validPodTemplateSpec,
|
||||
Parallelism: &oldParallelism,
|
||||
},
|
||||
Status: extensions.JobStatus{
|
||||
Status: batch.JobStatus{
|
||||
Active: 11,
|
||||
},
|
||||
}
|
||||
newJob := &extensions.Job{
|
||||
newJob := &batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "myjob",
|
||||
Namespace: api.NamespaceDefault,
|
||||
ResourceVersion: "9",
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Selector: validSelector,
|
||||
Template: validPodTemplateSpec,
|
||||
Parallelism: &newParallelism,
|
||||
},
|
||||
Status: extensions.JobStatus{
|
||||
Status: batch.JobStatus{
|
||||
Active: 12,
|
||||
},
|
||||
}
|
||||
|
@ -226,7 +226,7 @@ func TestSelectableFieldLabelConversions(t *testing.T) {
|
|||
apitesting.TestSelectableFieldLabelConversionsOfKind(t,
|
||||
testapi.Extensions.GroupVersion().String(),
|
||||
"Job",
|
||||
labels.Set(JobToSelectableFields(&extensions.Job{})),
|
||||
labels.Set(JobToSelectableFields(&batch.Job{})),
|
||||
nil,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ import (
|
|||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/errors"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
|
@ -128,7 +128,7 @@ var _ = framework.KubeDescribe("V1Job", func() {
|
|||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
By("scale job up")
|
||||
scaler, err := kubectl.ScalerFor(extensions.Kind("Job"), f.Client)
|
||||
scaler, err := kubectl.ScalerFor(batch.Kind("Job"), f.Client)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
waitForScale := kubectl.NewRetryParams(5*time.Second, 1*time.Minute)
|
||||
waitForReplicas := kubectl.NewRetryParams(5*time.Second, 5*time.Minute)
|
||||
|
@ -153,7 +153,7 @@ var _ = framework.KubeDescribe("V1Job", func() {
|
|||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
By("scale job down")
|
||||
scaler, err := kubectl.ScalerFor(extensions.Kind("Job"), f.Client)
|
||||
scaler, err := kubectl.ScalerFor(batch.Kind("Job"), f.Client)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
waitForScale := kubectl.NewRetryParams(5*time.Second, 1*time.Minute)
|
||||
waitForReplicas := kubectl.NewRetryParams(5*time.Second, 5*time.Minute)
|
||||
|
@ -176,7 +176,7 @@ var _ = framework.KubeDescribe("V1Job", func() {
|
|||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
By("delete a job")
|
||||
reaper, err := kubectl.ReaperFor(extensions.Kind("Job"), f.Client)
|
||||
reaper, err := kubectl.ReaperFor(batch.Kind("Job"), f.Client)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
timeout := 1 * time.Minute
|
||||
err = reaper.Stop(f.Namespace.Name, job.Name, timeout, api.NewDeleteOptions(0))
|
||||
|
@ -203,12 +203,12 @@ var _ = framework.KubeDescribe("V1Job", func() {
|
|||
})
|
||||
|
||||
// newTestV1Job returns a job which does one of several testing behaviors.
|
||||
func newTestV1Job(behavior, name string, rPol api.RestartPolicy, parallelism, completions int) *extensions.Job {
|
||||
job := &extensions.Job{
|
||||
func newTestV1Job(behavior, name string, rPol api.RestartPolicy, parallelism, completions int) *batch.Job {
|
||||
job := &batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: name,
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Parallelism: ¶llelism,
|
||||
Completions: &completions,
|
||||
Template: api.PodTemplateSpec{
|
||||
|
@ -264,7 +264,7 @@ func newTestV1Job(behavior, name string, rPol api.RestartPolicy, parallelism, co
|
|||
return job
|
||||
}
|
||||
|
||||
func createV1Job(c *client.Client, ns string, job *extensions.Job) (*extensions.Job, error) {
|
||||
func createV1Job(c *client.Client, ns string, job *batch.Job) (*batch.Job, error) {
|
||||
return c.Batch().Jobs(ns).Create(job)
|
||||
}
|
||||
|
||||
|
@ -310,7 +310,7 @@ func waitForV1JobFail(c *client.Client, ns, jobName string) error {
|
|||
return false, err
|
||||
}
|
||||
for _, c := range curr.Status.Conditions {
|
||||
if c.Type == extensions.JobFailed && c.Status == api.ConditionTrue {
|
||||
if c.Type == batch.JobFailed && c.Status == api.ConditionTrue {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ import (
|
|||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/errors"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
|
@ -124,7 +124,7 @@ var _ = framework.KubeDescribe("Job", func() {
|
|||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
By("scale job up")
|
||||
scaler, err := kubectl.ScalerFor(extensions.Kind("Job"), f.Client)
|
||||
scaler, err := kubectl.ScalerFor(batch.Kind("Job"), f.Client)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
waitForScale := kubectl.NewRetryParams(5*time.Second, 1*time.Minute)
|
||||
waitForReplicas := kubectl.NewRetryParams(5*time.Second, 5*time.Minute)
|
||||
|
@ -149,7 +149,7 @@ var _ = framework.KubeDescribe("Job", func() {
|
|||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
By("scale job down")
|
||||
scaler, err := kubectl.ScalerFor(extensions.Kind("Job"), f.Client)
|
||||
scaler, err := kubectl.ScalerFor(batch.Kind("Job"), f.Client)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
waitForScale := kubectl.NewRetryParams(5*time.Second, 1*time.Minute)
|
||||
waitForReplicas := kubectl.NewRetryParams(5*time.Second, 5*time.Minute)
|
||||
|
@ -172,7 +172,7 @@ var _ = framework.KubeDescribe("Job", func() {
|
|||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
By("delete a job")
|
||||
reaper, err := kubectl.ReaperFor(extensions.Kind("Job"), f.Client)
|
||||
reaper, err := kubectl.ReaperFor(batch.Kind("Job"), f.Client)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
timeout := 1 * time.Minute
|
||||
err = reaper.Stop(f.Namespace.Name, job.Name, timeout, api.NewDeleteOptions(0))
|
||||
|
@ -199,12 +199,12 @@ var _ = framework.KubeDescribe("Job", func() {
|
|||
})
|
||||
|
||||
// newTestJob returns a job which does one of several testing behaviors.
|
||||
func newTestJob(behavior, name string, rPol api.RestartPolicy, parallelism, completions int) *extensions.Job {
|
||||
job := &extensions.Job{
|
||||
func newTestJob(behavior, name string, rPol api.RestartPolicy, parallelism, completions int) *batch.Job {
|
||||
job := &batch.Job{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: name,
|
||||
},
|
||||
Spec: extensions.JobSpec{
|
||||
Spec: batch.JobSpec{
|
||||
Parallelism: ¶llelism,
|
||||
Completions: &completions,
|
||||
ManualSelector: newBool(true),
|
||||
|
@ -261,7 +261,7 @@ func newTestJob(behavior, name string, rPol api.RestartPolicy, parallelism, comp
|
|||
return job
|
||||
}
|
||||
|
||||
func createJob(c *client.Client, ns string, job *extensions.Job) (*extensions.Job, error) {
|
||||
func createJob(c *client.Client, ns string, job *batch.Job) (*batch.Job, error) {
|
||||
return c.Extensions().Jobs(ns).Create(job)
|
||||
}
|
||||
|
||||
|
@ -307,7 +307,7 @@ func waitForJobFail(c *client.Client, ns, jobName string) error {
|
|||
return false, err
|
||||
}
|
||||
for _, c := range curr.Status.Conditions {
|
||||
if c.Type == extensions.JobFailed && c.Status == api.ConditionTrue {
|
||||
if c.Type == batch.JobFailed && c.Status == api.ConditionTrue {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue