Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
d8d69d1a
Commit
d8d69d1a
authored
Dec 23, 2016
by
peay
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove jobs that do not exist from active list of CronJob
parent
5f0ece92
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
79 additions
and
11 deletions
+79
-11
cronjob_controller.go
pkg/controller/cronjob/cronjob_controller.go
+14
-0
cronjob_controller_test.go
pkg/controller/cronjob/cronjob_controller_test.go
+0
-0
cronjob.go
test/e2e/cronjob.go
+65
-11
No files found.
pkg/controller/cronjob/cronjob_controller.go
View file @
d8d69d1a
...
@@ -42,6 +42,7 @@ import (
...
@@ -42,6 +42,7 @@ import (
v1core
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1"
v1core
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1"
"k8s.io/kubernetes/pkg/client/record"
"k8s.io/kubernetes/pkg/client/record"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/types"
utilerrors
"k8s.io/kubernetes/pkg/util/errors"
utilerrors
"k8s.io/kubernetes/pkg/util/errors"
"k8s.io/kubernetes/pkg/util/metrics"
"k8s.io/kubernetes/pkg/util/metrics"
utilruntime
"k8s.io/kubernetes/pkg/util/runtime"
utilruntime
"k8s.io/kubernetes/pkg/util/runtime"
...
@@ -127,8 +128,10 @@ func (jm *CronJobController) SyncAll() {
...
@@ -127,8 +128,10 @@ func (jm *CronJobController) SyncAll() {
func
SyncOne
(
sj
batch
.
CronJob
,
js
[]
batch
.
Job
,
now
time
.
Time
,
jc
jobControlInterface
,
sjc
sjControlInterface
,
pc
podControlInterface
,
recorder
record
.
EventRecorder
)
{
func
SyncOne
(
sj
batch
.
CronJob
,
js
[]
batch
.
Job
,
now
time
.
Time
,
jc
jobControlInterface
,
sjc
sjControlInterface
,
pc
podControlInterface
,
recorder
record
.
EventRecorder
)
{
nameForLog
:=
fmt
.
Sprintf
(
"%s/%s"
,
sj
.
Namespace
,
sj
.
Name
)
nameForLog
:=
fmt
.
Sprintf
(
"%s/%s"
,
sj
.
Namespace
,
sj
.
Name
)
childrenJobs
:=
make
(
map
[
types
.
UID
]
bool
)
for
i
:=
range
js
{
for
i
:=
range
js
{
j
:=
js
[
i
]
j
:=
js
[
i
]
childrenJobs
[
j
.
ObjectMeta
.
UID
]
=
true
found
:=
inActiveList
(
sj
,
j
.
ObjectMeta
.
UID
)
found
:=
inActiveList
(
sj
,
j
.
ObjectMeta
.
UID
)
if
!
found
&&
!
IsJobFinished
(
&
j
)
{
if
!
found
&&
!
IsJobFinished
(
&
j
)
{
recorder
.
Eventf
(
&
sj
,
v1
.
EventTypeWarning
,
"UnexpectedJob"
,
"Saw a job that the controller did not create or forgot: %v"
,
j
.
Name
)
recorder
.
Eventf
(
&
sj
,
v1
.
EventTypeWarning
,
"UnexpectedJob"
,
"Saw a job that the controller did not create or forgot: %v"
,
j
.
Name
)
...
@@ -148,6 +151,17 @@ func SyncOne(sj batch.CronJob, js []batch.Job, now time.Time, jc jobControlInter
...
@@ -148,6 +151,17 @@ func SyncOne(sj batch.CronJob, js []batch.Job, now time.Time, jc jobControlInter
recorder
.
Eventf
(
&
sj
,
v1
.
EventTypeNormal
,
"SawCompletedJob"
,
"Saw completed job: %v"
,
j
.
Name
)
recorder
.
Eventf
(
&
sj
,
v1
.
EventTypeNormal
,
"SawCompletedJob"
,
"Saw completed job: %v"
,
j
.
Name
)
}
}
}
}
// Remove any job reference from the active list if the corresponding job does not exist any more.
// Otherwise, the cronjob may be stuck in active mode forever even though there is no matching
// job running.
for
_
,
j
:=
range
sj
.
Status
.
Active
{
if
found
:=
childrenJobs
[
j
.
UID
];
!
found
{
recorder
.
Eventf
(
&
sj
,
v1
.
EventTypeNormal
,
"MissingJob"
,
"Active job went missing: %v"
,
j
.
Name
)
deleteFromActiveList
(
&
sj
,
j
.
UID
)
}
}
updatedSJ
,
err
:=
sjc
.
UpdateStatus
(
&
sj
)
updatedSJ
,
err
:=
sjc
.
UpdateStatus
(
&
sj
)
if
err
!=
nil
{
if
err
!=
nil
{
glog
.
Errorf
(
"Unable to update status for %s (rv = %s): %v"
,
nameForLog
,
sj
.
ResourceVersion
,
err
)
glog
.
Errorf
(
"Unable to update status for %s (rv = %s): %v"
,
nameForLog
,
sj
.
ResourceVersion
,
err
)
...
...
pkg/controller/cronjob/cronjob_controller_test.go
View file @
d8d69d1a
This diff is collapsed.
Click to expand it.
test/e2e/cronjob.go
View file @
d8d69d1a
...
@@ -23,12 +23,16 @@ import (
...
@@ -23,12 +23,16 @@ import (
.
"github.com/onsi/ginkgo"
.
"github.com/onsi/ginkgo"
.
"github.com/onsi/gomega"
.
"github.com/onsi/gomega"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/api/v1"
batchinternal
"k8s.io/kubernetes/pkg/apis/batch"
batchv1
"k8s.io/kubernetes/pkg/apis/batch/v1"
batchv1
"k8s.io/kubernetes/pkg/apis/batch/v1"
batch
"k8s.io/kubernetes/pkg/apis/batch/v2alpha1"
batch
"k8s.io/kubernetes/pkg/apis/batch/v2alpha1"
metav1
"k8s.io/kubernetes/pkg/apis/meta/v1"
metav1
"k8s.io/kubernetes/pkg/apis/meta/v1"
clientset
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
clientset
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
"k8s.io/kubernetes/pkg/controller/job"
"k8s.io/kubernetes/pkg/controller/job"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/runtime/schema"
"k8s.io/kubernetes/pkg/runtime/schema"
"k8s.io/kubernetes/pkg/util/wait"
"k8s.io/kubernetes/pkg/util/wait"
"k8s.io/kubernetes/test/e2e/framework"
"k8s.io/kubernetes/test/e2e/framework"
...
@@ -83,7 +87,7 @@ var _ = framework.KubeDescribe("CronJob", func() {
...
@@ -83,7 +87,7 @@ var _ = framework.KubeDescribe("CronJob", func() {
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
By
(
"Ensuring no jobs are scheduled"
)
By
(
"Ensuring no jobs are scheduled"
)
err
=
waitForNoJobs
(
f
.
ClientSet
,
f
.
Namespace
.
Name
,
cronJob
.
Name
)
err
=
waitForNoJobs
(
f
.
ClientSet
,
f
.
Namespace
.
Name
,
cronJob
.
Name
,
false
)
Expect
(
err
)
.
To
(
HaveOccurred
())
Expect
(
err
)
.
To
(
HaveOccurred
())
By
(
"Ensuring no job exists by listing jobs explicitly"
)
By
(
"Ensuring no job exists by listing jobs explicitly"
)
...
@@ -172,13 +176,55 @@ var _ = framework.KubeDescribe("CronJob", func() {
...
@@ -172,13 +176,55 @@ var _ = framework.KubeDescribe("CronJob", func() {
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
By
(
"Ensuring no unexpected event has happened"
)
By
(
"Ensuring no unexpected event has happened"
)
err
=
checkNo
UnexpectedEvents
(
f
.
ClientSet
,
f
.
Namespace
.
Name
,
cronJob
.
Name
)
err
=
checkNo
EventWithReason
(
f
.
ClientSet
,
f
.
Namespace
.
Name
,
cronJob
.
Name
,
[]
string
{
"MissingJob"
,
"UnexpectedJob"
}
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
By
(
"Removing cronjob"
)
By
(
"Removing cronjob"
)
err
=
deleteCronJob
(
f
.
ClientSet
,
f
.
Namespace
.
Name
,
cronJob
.
Name
)
err
=
deleteCronJob
(
f
.
ClientSet
,
f
.
Namespace
.
Name
,
cronJob
.
Name
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
})
})
// deleted jobs should be removed from the active list
It
(
"should remove from active list jobs that have been deleted"
,
func
()
{
By
(
"Creating a ForbidConcurrent cronjob"
)
cronJob
:=
newTestCronJob
(
"forbid"
,
"*/1 * * * ?"
,
batch
.
ForbidConcurrent
,
true
)
cronJob
,
err
:=
createCronJob
(
f
.
ClientSet
,
f
.
Namespace
.
Name
,
cronJob
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
By
(
"Ensuring a job is scheduled"
)
err
=
waitForActiveJobs
(
f
.
ClientSet
,
f
.
Namespace
.
Name
,
cronJob
.
Name
,
1
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
By
(
"Ensuring exactly one is scheduled"
)
cronJob
,
err
=
getCronJob
(
f
.
ClientSet
,
f
.
Namespace
.
Name
,
cronJob
.
Name
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
Expect
(
cronJob
.
Status
.
Active
)
.
Should
(
HaveLen
(
1
))
By
(
"Deleting the job"
)
job
:=
cronJob
.
Status
.
Active
[
0
]
reaper
,
err
:=
kubectl
.
ReaperFor
(
batchinternal
.
Kind
(
"Job"
),
f
.
InternalClientset
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
timeout
:=
1
*
time
.
Minute
err
=
reaper
.
Stop
(
f
.
Namespace
.
Name
,
job
.
Name
,
timeout
,
api
.
NewDeleteOptions
(
0
))
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
By
(
"Ensuring job was deleted"
)
_
,
err
=
getJob
(
f
.
ClientSet
,
f
.
Namespace
.
Name
,
job
.
Name
)
Expect
(
err
)
.
To
(
HaveOccurred
())
Expect
(
errors
.
IsNotFound
(
err
))
.
To
(
BeTrue
())
By
(
"Ensuring there are no active jobs in the cronjob"
)
err
=
waitForNoJobs
(
f
.
ClientSet
,
f
.
Namespace
.
Name
,
cronJob
.
Name
,
true
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
By
(
"Ensuring MissingJob event has occured"
)
err
=
checkNoEventWithReason
(
f
.
ClientSet
,
f
.
Namespace
.
Name
,
cronJob
.
Name
,
[]
string
{
"MissingJob"
})
Expect
(
err
)
.
To
(
HaveOccurred
())
By
(
"Removing cronjob"
)
err
=
deleteCronJob
(
f
.
ClientSet
,
f
.
Namespace
.
Name
,
cronJob
.
Name
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
})
})
})
// newTestCronJob returns a cronjob which does one of several testing behaviors.
// newTestCronJob returns a cronjob which does one of several testing behaviors.
...
@@ -254,15 +300,22 @@ func waitForActiveJobs(c clientset.Interface, ns, cronJobName string, active int
...
@@ -254,15 +300,22 @@ func waitForActiveJobs(c clientset.Interface, ns, cronJobName string, active int
})
})
}
}
// Wait for no jobs to appear.
// Wait for jobs to appear in the active list of a cronjob or not.
func
waitForNoJobs
(
c
clientset
.
Interface
,
ns
,
jobName
string
)
error
{
// When failIfNonEmpty is set, this fails if the active set of jobs is still non-empty after
// the timeout. When failIfNonEmpty is not set, this fails if the active set of jobs is still
// empty after the timeout.
func
waitForNoJobs
(
c
clientset
.
Interface
,
ns
,
jobName
string
,
failIfNonEmpty
bool
)
error
{
return
wait
.
Poll
(
framework
.
Poll
,
cronJobTimeout
,
func
()
(
bool
,
error
)
{
return
wait
.
Poll
(
framework
.
Poll
,
cronJobTimeout
,
func
()
(
bool
,
error
)
{
curr
,
err
:=
c
.
BatchV2alpha1
()
.
CronJobs
(
ns
)
.
Get
(
jobName
,
metav1
.
GetOptions
{})
curr
,
err
:=
c
.
BatchV2alpha1
()
.
CronJobs
(
ns
)
.
Get
(
jobName
,
metav1
.
GetOptions
{})
if
err
!=
nil
{
if
err
!=
nil
{
return
false
,
err
return
false
,
err
}
}
if
failIfNonEmpty
{
return
len
(
curr
.
Status
.
Active
)
==
0
,
nil
}
else
{
return
len
(
curr
.
Status
.
Active
)
!=
0
,
nil
return
len
(
curr
.
Status
.
Active
)
!=
0
,
nil
}
})
})
}
}
...
@@ -310,20 +363,21 @@ func waitForAnyFinishedJob(c clientset.Interface, ns string) error {
...
@@ -310,20 +363,21 @@ func waitForAnyFinishedJob(c clientset.Interface, ns string) error {
})
})
}
}
// checkNoUnexpectedEvents checks unexpected events didn't happen.
// checkNoEventWithReason checks no events with a reason within a list has occured
// Currently only "UnexpectedJob" is checked.
func
checkNoEventWithReason
(
c
clientset
.
Interface
,
ns
,
cronJobName
string
,
reasons
[]
string
)
error
{
func
checkNoUnexpectedEvents
(
c
clientset
.
Interface
,
ns
,
cronJobName
string
)
error
{
sj
,
err
:=
c
.
BatchV2alpha1
()
.
CronJobs
(
ns
)
.
Get
(
cronJobName
,
metav1
.
GetOptions
{})
sj
,
err
:=
c
.
BatchV2alpha1
()
.
CronJobs
(
ns
)
.
Get
(
cronJobName
,
metav1
.
GetOptions
{})
if
err
!=
nil
{
if
err
!=
nil
{
return
fmt
.
Errorf
(
"
e
rror in getting cronjob %s/%s: %v"
,
ns
,
cronJobName
,
err
)
return
fmt
.
Errorf
(
"
E
rror in getting cronjob %s/%s: %v"
,
ns
,
cronJobName
,
err
)
}
}
events
,
err
:=
c
.
Core
()
.
Events
(
ns
)
.
Search
(
sj
)
events
,
err
:=
c
.
Core
()
.
Events
(
ns
)
.
Search
(
sj
)
if
err
!=
nil
{
if
err
!=
nil
{
return
fmt
.
Errorf
(
"
e
rror in listing events: %s"
,
err
)
return
fmt
.
Errorf
(
"
E
rror in listing events: %s"
,
err
)
}
}
for
_
,
e
:=
range
events
.
Items
{
for
_
,
e
:=
range
events
.
Items
{
if
e
.
Reason
==
"UnexpectedJob"
{
for
_
,
reason
:=
range
reasons
{
return
fmt
.
Errorf
(
"found unexpected event: %#v"
,
e
)
if
e
.
Reason
==
reason
{
return
fmt
.
Errorf
(
"Found event with reason %s: %#v"
,
reason
,
e
)
}
}
}
}
}
return
nil
return
nil
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment