mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-06 18:54:06 +00:00
Job status updates.
Added status REST storage. Added validation for Status Updates. Changed job controller to update status rather than just job (which ignores status updates).
This commit is contained in:
parent
b113b5ac2a
commit
95a44be2ef
@ -312,6 +312,21 @@ func ValidateJobSpec(spec *experimental.JobSpec) errs.ValidationErrorList {
|
|||||||
return allErrs
|
return allErrs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ValidateJobStatus(status *experimental.JobStatus) errs.ValidationErrorList {
|
||||||
|
allErrs := errs.ValidationErrorList{}
|
||||||
|
|
||||||
|
if status.Active < 0 {
|
||||||
|
allErrs = append(allErrs, errs.NewFieldInvalid("active", status.Active, isNegativeErrorMsg))
|
||||||
|
}
|
||||||
|
if status.Successful < 0 {
|
||||||
|
allErrs = append(allErrs, errs.NewFieldInvalid("successful", status.Successful, isNegativeErrorMsg))
|
||||||
|
}
|
||||||
|
if status.Unsuccessful < 0 {
|
||||||
|
allErrs = append(allErrs, errs.NewFieldInvalid("unsuccessful", status.Unsuccessful, isNegativeErrorMsg))
|
||||||
|
}
|
||||||
|
return allErrs
|
||||||
|
}
|
||||||
|
|
||||||
func ValidateJobUpdate(oldJob, job *experimental.Job) errs.ValidationErrorList {
|
func ValidateJobUpdate(oldJob, job *experimental.Job) errs.ValidationErrorList {
|
||||||
allErrs := errs.ValidationErrorList{}
|
allErrs := errs.ValidationErrorList{}
|
||||||
allErrs = append(allErrs, apivalidation.ValidateObjectMetaUpdate(&oldJob.ObjectMeta, &job.ObjectMeta).Prefix("metadata")...)
|
allErrs = append(allErrs, apivalidation.ValidateObjectMetaUpdate(&oldJob.ObjectMeta, &job.ObjectMeta).Prefix("metadata")...)
|
||||||
@ -319,6 +334,13 @@ func ValidateJobUpdate(oldJob, job *experimental.Job) errs.ValidationErrorList {
|
|||||||
return allErrs
|
return allErrs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ValidateJobUpdateStatus(oldJob, job *experimental.Job) errs.ValidationErrorList {
|
||||||
|
allErrs := errs.ValidationErrorList{}
|
||||||
|
allErrs = append(allErrs, apivalidation.ValidateObjectMetaUpdate(&oldJob.ObjectMeta, &job.ObjectMeta).Prefix("metadata")...)
|
||||||
|
allErrs = append(allErrs, ValidateJobStatusUpdate(oldJob.Status, job.Status).Prefix("status")...)
|
||||||
|
return allErrs
|
||||||
|
}
|
||||||
|
|
||||||
func ValidateJobSpecUpdate(oldSpec, spec experimental.JobSpec) errs.ValidationErrorList {
|
func ValidateJobSpecUpdate(oldSpec, spec experimental.JobSpec) errs.ValidationErrorList {
|
||||||
allErrs := errs.ValidationErrorList{}
|
allErrs := errs.ValidationErrorList{}
|
||||||
allErrs = append(allErrs, ValidateJobSpec(&spec)...)
|
allErrs = append(allErrs, ValidateJobSpec(&spec)...)
|
||||||
@ -333,3 +355,9 @@ func ValidateJobSpecUpdate(oldSpec, spec experimental.JobSpec) errs.ValidationEr
|
|||||||
}
|
}
|
||||||
return allErrs
|
return allErrs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ValidateJobStatusUpdate(oldStatus, status experimental.JobStatus) errs.ValidationErrorList {
|
||||||
|
allErrs := errs.ValidationErrorList{}
|
||||||
|
allErrs = append(allErrs, ValidateJobStatus(&status)...)
|
||||||
|
return allErrs
|
||||||
|
}
|
||||||
|
@ -44,7 +44,7 @@ type JobController struct {
|
|||||||
kubeClient client.Interface
|
kubeClient client.Interface
|
||||||
podControl controller.PodControlInterface
|
podControl controller.PodControlInterface
|
||||||
|
|
||||||
// To allow injection of updateJob for testing.
|
// To allow injection of updateJobStatus for testing.
|
||||||
updateHandler func(job *experimental.Job) error
|
updateHandler func(job *experimental.Job) error
|
||||||
syncHandler func(jobKey string) error
|
syncHandler func(jobKey string) error
|
||||||
// podStoreSynced returns true if the pod store has been synced at least once.
|
// podStoreSynced returns true if the pod store has been synced at least once.
|
||||||
@ -127,7 +127,7 @@ func NewJobController(kubeClient client.Interface) *JobController {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
jm.updateHandler = jm.updateJob
|
jm.updateHandler = jm.updateJobStatus
|
||||||
jm.syncHandler = jm.syncJob
|
jm.syncHandler = jm.syncJob
|
||||||
jm.podStoreSynced = jm.podController.HasSynced
|
jm.podStoreSynced = jm.podController.HasSynced
|
||||||
return jm
|
return jm
|
||||||
@ -433,8 +433,8 @@ func (jm *JobController) manageJob(activePods []*api.Pod, successful, unsuccessf
|
|||||||
return active
|
return active
|
||||||
}
|
}
|
||||||
|
|
||||||
func (jm *JobController) updateJob(job *experimental.Job) error {
|
func (jm *JobController) updateJobStatus(job *experimental.Job) error {
|
||||||
_, err := jm.kubeClient.Experimental().Jobs(job.Namespace).Update(job)
|
_, err := jm.kubeClient.Experimental().Jobs(job.Namespace).UpdateStatus(job)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -960,7 +960,7 @@ func (m *Master) experimental(c *Config) *apiserver.APIGroupVersion {
|
|||||||
thirdPartyResourceStorage := thirdpartyresourceetcd.NewREST(c.ExpDatabaseStorage)
|
thirdPartyResourceStorage := thirdpartyresourceetcd.NewREST(c.ExpDatabaseStorage)
|
||||||
daemonSetStorage := daemonetcd.NewREST(c.ExpDatabaseStorage)
|
daemonSetStorage := daemonetcd.NewREST(c.ExpDatabaseStorage)
|
||||||
deploymentStorage := deploymentetcd.NewStorage(c.ExpDatabaseStorage)
|
deploymentStorage := deploymentetcd.NewStorage(c.ExpDatabaseStorage)
|
||||||
jobStorage := jobetcd.NewREST(c.ExpDatabaseStorage)
|
jobStorage, jobStatusStorage := jobetcd.NewREST(c.ExpDatabaseStorage)
|
||||||
|
|
||||||
thirdPartyControl := ThirdPartyController{
|
thirdPartyControl := ThirdPartyController{
|
||||||
master: m,
|
master: m,
|
||||||
@ -982,6 +982,7 @@ func (m *Master) experimental(c *Config) *apiserver.APIGroupVersion {
|
|||||||
strings.ToLower("deployments"): deploymentStorage.Deployment,
|
strings.ToLower("deployments"): deploymentStorage.Deployment,
|
||||||
strings.ToLower("deployments/scale"): deploymentStorage.Scale,
|
strings.ToLower("deployments/scale"): deploymentStorage.Scale,
|
||||||
strings.ToLower("jobs"): jobStorage,
|
strings.ToLower("jobs"): jobStorage,
|
||||||
|
strings.ToLower("jobs/status"): jobStatusStorage,
|
||||||
}
|
}
|
||||||
|
|
||||||
return &apiserver.APIGroupVersion{
|
return &apiserver.APIGroupVersion{
|
||||||
|
@ -38,7 +38,7 @@ type REST struct {
|
|||||||
var jobPrefix = "/jobs"
|
var jobPrefix = "/jobs"
|
||||||
|
|
||||||
// NewREST returns a RESTStorage object that will work against Jobs.
|
// NewREST returns a RESTStorage object that will work against Jobs.
|
||||||
func NewREST(s storage.Interface) *REST {
|
func NewREST(s storage.Interface) (*REST, *StatusREST) {
|
||||||
store := &etcdgeneric.Etcd{
|
store := &etcdgeneric.Etcd{
|
||||||
NewFunc: func() runtime.Object { return &experimental.Job{} },
|
NewFunc: func() runtime.Object { return &experimental.Job{} },
|
||||||
|
|
||||||
@ -73,5 +73,22 @@ func NewREST(s storage.Interface) *REST {
|
|||||||
Storage: s,
|
Storage: s,
|
||||||
}
|
}
|
||||||
|
|
||||||
return &REST{store}
|
statusStore := *store
|
||||||
|
statusStore.UpdateStrategy = job.StatusStrategy
|
||||||
|
|
||||||
|
return &REST{store}, &StatusREST{store: &statusStore}
|
||||||
|
}
|
||||||
|
|
||||||
|
// StatusREST implements the REST endpoint for changing the status of a resourcequota.
|
||||||
|
type StatusREST struct {
|
||||||
|
store *etcdgeneric.Etcd
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *StatusREST) New() runtime.Object {
|
||||||
|
return &experimental.Job{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update alters the status subset of an object.
|
||||||
|
func (r *StatusREST) Update(ctx api.Context, obj runtime.Object) (runtime.Object, bool, error) {
|
||||||
|
return r.store.Update(ctx, obj)
|
||||||
}
|
}
|
||||||
|
@ -30,9 +30,10 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/tools"
|
"k8s.io/kubernetes/pkg/tools"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
|
func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient) {
|
||||||
etcdStorage, fakeClient := registrytest.NewEtcdStorage(t, "experimental")
|
etcdStorage, fakeClient := registrytest.NewEtcdStorage(t, "experimental")
|
||||||
return NewREST(etcdStorage), fakeClient
|
storage, statusStorage := NewREST(etcdStorage)
|
||||||
|
return storage, statusStorage, fakeClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func validNewJob() *experimental.Job {
|
func validNewJob() *experimental.Job {
|
||||||
@ -68,7 +69,7 @@ func validNewJob() *experimental.Job {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCreate(t *testing.T) {
|
func TestCreate(t *testing.T) {
|
||||||
storage, fakeClient := newStorage(t)
|
storage, _, fakeClient := newStorage(t)
|
||||||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||||
validJob := validNewJob()
|
validJob := validNewJob()
|
||||||
validJob.ObjectMeta = api.ObjectMeta{}
|
validJob.ObjectMeta = api.ObjectMeta{}
|
||||||
@ -87,7 +88,7 @@ func TestCreate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestUpdate(t *testing.T) {
|
func TestUpdate(t *testing.T) {
|
||||||
storage, fakeClient := newStorage(t)
|
storage, _, fakeClient := newStorage(t)
|
||||||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||||
two := 2
|
two := 2
|
||||||
test.TestUpdate(
|
test.TestUpdate(
|
||||||
@ -114,25 +115,25 @@ func TestUpdate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDelete(t *testing.T) {
|
func TestDelete(t *testing.T) {
|
||||||
storage, fakeClient := newStorage(t)
|
storage, _, fakeClient := newStorage(t)
|
||||||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||||
test.TestDelete(validNewJob())
|
test.TestDelete(validNewJob())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGet(t *testing.T) {
|
func TestGet(t *testing.T) {
|
||||||
storage, fakeClient := newStorage(t)
|
storage, _, fakeClient := newStorage(t)
|
||||||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||||
test.TestGet(validNewJob())
|
test.TestGet(validNewJob())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestList(t *testing.T) {
|
func TestList(t *testing.T) {
|
||||||
storage, fakeClient := newStorage(t)
|
storage, _, fakeClient := newStorage(t)
|
||||||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||||
test.TestList(validNewJob())
|
test.TestList(validNewJob())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestWatch(t *testing.T) {
|
func TestWatch(t *testing.T) {
|
||||||
storage, fakeClient := newStorage(t)
|
storage, _, fakeClient := newStorage(t)
|
||||||
test := registrytest.New(t, fakeClient, storage.Etcd)
|
test := registrytest.New(t, fakeClient, storage.Etcd)
|
||||||
test.TestWatch(
|
test.TestWatch(
|
||||||
validNewJob(),
|
validNewJob(),
|
||||||
@ -151,3 +152,5 @@ func TestWatch(t *testing.T) {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: test update /status
|
||||||
|
@ -79,6 +79,22 @@ func (jobStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) fiel
|
|||||||
return append(validationErrorList, updateErrorList...)
|
return append(validationErrorList, updateErrorList...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type jobStatusStrategy struct {
|
||||||
|
jobStrategy
|
||||||
|
}
|
||||||
|
|
||||||
|
var StatusStrategy = jobStatusStrategy{Strategy}
|
||||||
|
|
||||||
|
func (jobStatusStrategy) PrepareForUpdate(obj, old runtime.Object) {
|
||||||
|
newJob := obj.(*experimental.Job)
|
||||||
|
oldJob := old.(*experimental.Job)
|
||||||
|
newJob.Spec = oldJob.Spec
|
||||||
|
}
|
||||||
|
|
||||||
|
func (jobStatusStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) fielderrors.ValidationErrorList {
|
||||||
|
return validation.ValidateJobUpdateStatus(obj.(*experimental.Job), old.(*experimental.Job))
|
||||||
|
}
|
||||||
|
|
||||||
// JobSelectableFields returns a field set that represents the object for matching purposes.
|
// JobSelectableFields returns a field set that represents the object for matching purposes.
|
||||||
func JobToSelectableFields(job *experimental.Job) fields.Set {
|
func JobToSelectableFields(job *experimental.Job) fields.Set {
|
||||||
return fields.Set{
|
return fields.Set{
|
||||||
|
Loading…
Reference in New Issue
Block a user