Merge pull request #51465 from soltysh/cronjob_beta
Automatic merge from submit-queue (batch tested with PRs 50775, 51397, 51168, 51465, 51536) Enable batch/v1beta1.CronJobs by default This PR moves to CronJobs beta entirely, enabling `batch/v1beta1` by default. Related issue: #41039 @erictune @janetkuo ptal ```release-note Promote CronJobs to batch/v1beta1. ```
This commit is contained in:
@@ -34,7 +34,7 @@ func TestSetDefaultCronJob(t *testing.T) {
|
||||
original *batchv1beta1.CronJob
|
||||
expected *batchv1beta1.CronJob
|
||||
}{
|
||||
"empty batchv2alpha1.CronJob should default batchv2alpha1.ConcurrencyPolicy and Suspend": {
|
||||
"empty batchv1beta1.CronJob should default batchv1beta1.ConcurrencyPolicy and Suspend": {
|
||||
original: &batchv1beta1.CronJob{},
|
||||
expected: &batchv1beta1.CronJob{
|
||||
Spec: batchv1beta1.CronJobSpec{
|
||||
|
||||
@@ -20,7 +20,7 @@ go_library(
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/github.com/robfig/cron:go_default_library",
|
||||
"//vendor/k8s.io/api/batch/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/batch/v2alpha1:go_default_library",
|
||||
"//vendor/k8s.io/api/batch/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
@@ -50,7 +50,7 @@ go_test(
|
||||
"//pkg/api/install:go_default_library",
|
||||
"//pkg/apis/batch/install:go_default_library",
|
||||
"//vendor/k8s.io/api/batch/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/batch/v2alpha1:go_default_library",
|
||||
"//vendor/k8s.io/api/batch/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
|
||||
@@ -36,7 +36,7 @@ import (
|
||||
"github.com/golang/glog"
|
||||
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
batchv2alpha1 "k8s.io/api/batch/v2alpha1"
|
||||
batchv1beta1 "k8s.io/api/batch/v1beta1"
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -56,7 +56,7 @@ import (
|
||||
// Utilities for dealing with Jobs and CronJobs and time.
|
||||
|
||||
// controllerKind contains the schema.GroupVersionKind for this controller type.
|
||||
var controllerKind = batchv2alpha1.SchemeGroupVersion.WithKind("CronJob")
|
||||
var controllerKind = batchv1beta1.SchemeGroupVersion.WithKind("CronJob")
|
||||
|
||||
type CronJobController struct {
|
||||
kubeClient clientset.Interface
|
||||
@@ -116,7 +116,7 @@ func (jm *CronJobController) syncAll() {
|
||||
js := jl.Items
|
||||
glog.V(4).Infof("Found %d jobs", len(js))
|
||||
|
||||
sjl, err := jm.kubeClient.BatchV2alpha1().CronJobs(metav1.NamespaceAll).List(metav1.ListOptions{})
|
||||
sjl, err := jm.kubeClient.BatchV1beta1().CronJobs(metav1.NamespaceAll).List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
utilruntime.HandleError(fmt.Errorf("can't list CronJobs: %v", err))
|
||||
return
|
||||
@@ -134,7 +134,7 @@ func (jm *CronJobController) syncAll() {
|
||||
}
|
||||
|
||||
// cleanupFinishedJobs cleanups finished jobs created by a CronJob
|
||||
func cleanupFinishedJobs(sj *batchv2alpha1.CronJob, js []batchv1.Job, jc jobControlInterface,
|
||||
func cleanupFinishedJobs(sj *batchv1beta1.CronJob, js []batchv1.Job, jc jobControlInterface,
|
||||
sjc sjControlInterface, pc podControlInterface, recorder record.EventRecorder) {
|
||||
// If neither limits are active, there is no need to do anything.
|
||||
if sj.Spec.FailedJobsHistoryLimit == nil && sj.Spec.SuccessfulJobsHistoryLimit == nil {
|
||||
@@ -179,7 +179,7 @@ func cleanupFinishedJobs(sj *batchv2alpha1.CronJob, js []batchv1.Job, jc jobCont
|
||||
}
|
||||
|
||||
// removeOldestJobs removes the oldest jobs from a list of jobs
|
||||
func removeOldestJobs(sj *batchv2alpha1.CronJob, js []batchv1.Job, jc jobControlInterface,
|
||||
func removeOldestJobs(sj *batchv1beta1.CronJob, js []batchv1.Job, jc jobControlInterface,
|
||||
pc podControlInterface, maxJobs int32, recorder record.EventRecorder) {
|
||||
numToDelete := len(js) - int(maxJobs)
|
||||
if numToDelete <= 0 {
|
||||
@@ -200,7 +200,7 @@ func removeOldestJobs(sj *batchv2alpha1.CronJob, js []batchv1.Job, jc jobControl
|
||||
// All known jobs created by "sj" should be included in "js".
|
||||
// The current time is passed in to facilitate testing.
|
||||
// It has no receiver, to facilitate testing.
|
||||
func syncOne(sj *batchv2alpha1.CronJob, js []batchv1.Job, now time.Time, jc jobControlInterface, sjc sjControlInterface, pc podControlInterface, recorder record.EventRecorder) {
|
||||
func syncOne(sj *batchv1beta1.CronJob, js []batchv1.Job, now time.Time, jc jobControlInterface, sjc sjControlInterface, pc podControlInterface, recorder record.EventRecorder) {
|
||||
nameForLog := fmt.Sprintf("%s/%s", sj.Namespace, sj.Name)
|
||||
|
||||
childrenJobs := make(map[types.UID]bool)
|
||||
@@ -284,7 +284,7 @@ func syncOne(sj *batchv2alpha1.CronJob, js []batchv1.Job, now time.Time, jc jobC
|
||||
// can see easily that there was a missed execution.
|
||||
return
|
||||
}
|
||||
if sj.Spec.ConcurrencyPolicy == batchv2alpha1.ForbidConcurrent && len(sj.Status.Active) > 0 {
|
||||
if sj.Spec.ConcurrencyPolicy == batchv1beta1.ForbidConcurrent && len(sj.Status.Active) > 0 {
|
||||
// Regardless which source of information we use for the set of active jobs,
|
||||
// there is some risk that we won't see an active job when there is one.
|
||||
// (because we haven't seen the status update to the SJ or the created pod).
|
||||
@@ -297,7 +297,7 @@ func syncOne(sj *batchv2alpha1.CronJob, js []batchv1.Job, now time.Time, jc jobC
|
||||
glog.V(4).Infof("Not starting job for %s because of prior execution still running and concurrency policy is Forbid", nameForLog)
|
||||
return
|
||||
}
|
||||
if sj.Spec.ConcurrencyPolicy == batchv2alpha1.ReplaceConcurrent {
|
||||
if sj.Spec.ConcurrencyPolicy == batchv1beta1.ReplaceConcurrent {
|
||||
for _, j := range sj.Status.Active {
|
||||
// TODO: this should be replaced with server side job deletion
|
||||
// currently this mimics JobReaper from pkg/kubectl/stop.go
|
||||
@@ -353,7 +353,7 @@ func syncOne(sj *batchv2alpha1.CronJob, js []batchv1.Job, now time.Time, jc jobC
|
||||
}
|
||||
|
||||
// deleteJob reaps a job, deleting the job, the pobs and the reference in the active list
|
||||
func deleteJob(sj *batchv2alpha1.CronJob, job *batchv1.Job, jc jobControlInterface,
|
||||
func deleteJob(sj *batchv1beta1.CronJob, job *batchv1.Job, jc jobControlInterface,
|
||||
pc podControlInterface, recorder record.EventRecorder, reason string) bool {
|
||||
// TODO: this should be replaced with server side job deletion
|
||||
// currencontinuetly this mimics JobReaper from pkg/kubectl/stop.go
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
"time"
|
||||
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
batchv2alpha1 "k8s.io/api/batch/v2alpha1"
|
||||
batchV1beta1 "k8s.io/api/batch/v1beta1"
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
@@ -96,19 +96,19 @@ func startTimeStringToTime(startTime string) time.Time {
|
||||
}
|
||||
|
||||
// returns a cronJob with some fields filled in.
|
||||
func cronJob() batchv2alpha1.CronJob {
|
||||
return batchv2alpha1.CronJob{
|
||||
func cronJob() batchV1beta1.CronJob {
|
||||
return batchV1beta1.CronJob{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "mycronjob",
|
||||
Namespace: "snazzycats",
|
||||
UID: types.UID("1a2b3c"),
|
||||
SelfLink: "/apis/batch/v2alpha1/namespaces/snazzycats/cronjobs/mycronjob",
|
||||
SelfLink: "/apis/batch/v1beta1/namespaces/snazzycats/cronjobs/mycronjob",
|
||||
CreationTimestamp: metav1.Time{Time: justBeforeTheHour()},
|
||||
},
|
||||
Spec: batchv2alpha1.CronJobSpec{
|
||||
Spec: batchV1beta1.CronJobSpec{
|
||||
Schedule: "* * * * ?",
|
||||
ConcurrencyPolicy: batchv2alpha1.AllowConcurrent,
|
||||
JobTemplate: batchv2alpha1.JobTemplateSpec{
|
||||
ConcurrencyPolicy: batchV1beta1.AllowConcurrent,
|
||||
JobTemplate: batchV1beta1.JobTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: map[string]string{"a": "b"},
|
||||
Annotations: map[string]string{"x": "y"},
|
||||
@@ -152,15 +152,15 @@ func newJob(UID string) batchv1.Job {
|
||||
}
|
||||
|
||||
var (
|
||||
shortDead int64 = 10
|
||||
mediumDead int64 = 2 * 60 * 60
|
||||
longDead int64 = 1000000
|
||||
noDead int64 = -12345
|
||||
A batchv2alpha1.ConcurrencyPolicy = batchv2alpha1.AllowConcurrent
|
||||
f batchv2alpha1.ConcurrencyPolicy = batchv2alpha1.ForbidConcurrent
|
||||
R batchv2alpha1.ConcurrencyPolicy = batchv2alpha1.ReplaceConcurrent
|
||||
T bool = true
|
||||
F bool = false
|
||||
shortDead int64 = 10
|
||||
mediumDead int64 = 2 * 60 * 60
|
||||
longDead int64 = 1000000
|
||||
noDead int64 = -12345
|
||||
A batchV1beta1.ConcurrencyPolicy = batchV1beta1.AllowConcurrent
|
||||
f batchV1beta1.ConcurrencyPolicy = batchV1beta1.ForbidConcurrent
|
||||
R batchV1beta1.ConcurrencyPolicy = batchV1beta1.ReplaceConcurrent
|
||||
T bool = true
|
||||
F bool = false
|
||||
)
|
||||
|
||||
func TestSyncOne_RunOrNot(t *testing.T) {
|
||||
@@ -179,7 +179,7 @@ func TestSyncOne_RunOrNot(t *testing.T) {
|
||||
|
||||
testCases := map[string]struct {
|
||||
// sj spec
|
||||
concurrencyPolicy batchv2alpha1.ConcurrencyPolicy
|
||||
concurrencyPolicy batchV1beta1.ConcurrencyPolicy
|
||||
suspend bool
|
||||
schedule string
|
||||
deadline int64
|
||||
@@ -298,7 +298,7 @@ func TestSyncOne_RunOrNot(t *testing.T) {
|
||||
if controllerRef == nil {
|
||||
t.Errorf("%s: expected job to have ControllerRef: %#v", name, job)
|
||||
} else {
|
||||
if got, want := controllerRef.APIVersion, "batch/v2alpha1"; got != want {
|
||||
if got, want := controllerRef.APIVersion, "batch/v1beta1"; got != want {
|
||||
t.Errorf("%s: controllerRef.APIVersion = %q, want %q", name, got, want)
|
||||
}
|
||||
if got, want := controllerRef.Kind, "CronJob"; got != want {
|
||||
@@ -596,7 +596,7 @@ func TestSyncOne_Status(t *testing.T) {
|
||||
|
||||
testCases := map[string]struct {
|
||||
// sj spec
|
||||
concurrencyPolicy batchv2alpha1.ConcurrencyPolicy
|
||||
concurrencyPolicy batchV1beta1.ConcurrencyPolicy
|
||||
suspend bool
|
||||
schedule string
|
||||
deadline int64
|
||||
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
"sync"
|
||||
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
batchv2alpha1 "k8s.io/api/batch/v2alpha1"
|
||||
batchv1beta1 "k8s.io/api/batch/v1beta1"
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
@@ -33,7 +33,7 @@ import (
|
||||
// sjControlInterface is an interface that knows how to update CronJob status
|
||||
// created as an interface to allow testing.
|
||||
type sjControlInterface interface {
|
||||
UpdateStatus(sj *batchv2alpha1.CronJob) (*batchv2alpha1.CronJob, error)
|
||||
UpdateStatus(sj *batchv1beta1.CronJob) (*batchv1beta1.CronJob, error)
|
||||
}
|
||||
|
||||
// realSJControl is the default implementation of sjControlInterface.
|
||||
@@ -43,18 +43,18 @@ type realSJControl struct {
|
||||
|
||||
var _ sjControlInterface = &realSJControl{}
|
||||
|
||||
func (c *realSJControl) UpdateStatus(sj *batchv2alpha1.CronJob) (*batchv2alpha1.CronJob, error) {
|
||||
return c.KubeClient.BatchV2alpha1().CronJobs(sj.Namespace).UpdateStatus(sj)
|
||||
func (c *realSJControl) UpdateStatus(sj *batchv1beta1.CronJob) (*batchv1beta1.CronJob, error) {
|
||||
return c.KubeClient.BatchV1beta1().CronJobs(sj.Namespace).UpdateStatus(sj)
|
||||
}
|
||||
|
||||
// fakeSJControl is the default implementation of sjControlInterface.
|
||||
type fakeSJControl struct {
|
||||
Updates []batchv2alpha1.CronJob
|
||||
Updates []batchv1beta1.CronJob
|
||||
}
|
||||
|
||||
var _ sjControlInterface = &fakeSJControl{}
|
||||
|
||||
func (c *fakeSJControl) UpdateStatus(sj *batchv2alpha1.CronJob) (*batchv2alpha1.CronJob, error) {
|
||||
func (c *fakeSJControl) UpdateStatus(sj *batchv1beta1.CronJob) (*batchv1beta1.CronJob, error) {
|
||||
c.Updates = append(c.Updates, *sj)
|
||||
return sj, nil
|
||||
}
|
||||
@@ -85,7 +85,7 @@ type realJobControl struct {
|
||||
|
||||
var _ jobControlInterface = &realJobControl{}
|
||||
|
||||
func copyLabels(template *batchv2alpha1.JobTemplateSpec) labels.Set {
|
||||
func copyLabels(template *batchv1beta1.JobTemplateSpec) labels.Set {
|
||||
l := make(labels.Set)
|
||||
for k, v := range template.Labels {
|
||||
l[k] = v
|
||||
@@ -93,7 +93,7 @@ func copyLabels(template *batchv2alpha1.JobTemplateSpec) labels.Set {
|
||||
return l
|
||||
}
|
||||
|
||||
func copyAnnotations(template *batchv2alpha1.JobTemplateSpec) labels.Set {
|
||||
func copyAnnotations(template *batchv1beta1.JobTemplateSpec) labels.Set {
|
||||
a := make(labels.Set)
|
||||
for k, v := range template.Annotations {
|
||||
a[k] = v
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
"github.com/robfig/cron"
|
||||
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
batchv2alpha1 "k8s.io/api/batch/v2alpha1"
|
||||
batchv1beta1 "k8s.io/api/batch/v1beta1"
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
@@ -36,7 +36,7 @@ import (
|
||||
|
||||
// Utilities for dealing with Jobs and CronJobs and time.
|
||||
|
||||
func inActiveList(sj batchv2alpha1.CronJob, uid types.UID) bool {
|
||||
func inActiveList(sj batchv1beta1.CronJob, uid types.UID) bool {
|
||||
for _, j := range sj.Status.Active {
|
||||
if j.UID == uid {
|
||||
return true
|
||||
@@ -45,7 +45,7 @@ func inActiveList(sj batchv2alpha1.CronJob, uid types.UID) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func deleteFromActiveList(sj *batchv2alpha1.CronJob, uid types.UID) {
|
||||
func deleteFromActiveList(sj *batchv1beta1.CronJob, uid types.UID) {
|
||||
if sj == nil {
|
||||
return
|
||||
}
|
||||
@@ -111,7 +111,7 @@ func getNextStartTimeAfter(schedule string, now time.Time) (time.Time, error) {
|
||||
//
|
||||
// If there are too many (>100) unstarted times, just give up and return an empty slice.
|
||||
// If there were missed times prior to the last known start time, then those are not returned.
|
||||
func getRecentUnmetScheduleTimes(sj batchv2alpha1.CronJob, now time.Time) ([]time.Time, error) {
|
||||
func getRecentUnmetScheduleTimes(sj batchv1beta1.CronJob, now time.Time) ([]time.Time, error) {
|
||||
starts := []time.Time{}
|
||||
sched, err := cron.ParseStandard(sj.Spec.Schedule)
|
||||
if err != nil {
|
||||
@@ -170,7 +170,7 @@ func getRecentUnmetScheduleTimes(sj batchv2alpha1.CronJob, now time.Time) ([]tim
|
||||
}
|
||||
|
||||
// getJobFromTemplate makes a Job from a CronJob
|
||||
func getJobFromTemplate(sj *batchv2alpha1.CronJob, scheduledTime time.Time) (*batchv1.Job, error) {
|
||||
func getJobFromTemplate(sj *batchv1beta1.CronJob, scheduledTime time.Time) (*batchv1.Job, error) {
|
||||
// TODO: consider adding the following labels:
|
||||
// nominal-start-time=$RFC_3339_DATE_OF_INTENDED_START -- for user convenience
|
||||
// scheduled-job-name=$SJ_NAME -- for user convenience
|
||||
|
||||
@@ -22,7 +22,7 @@ import (
|
||||
"time"
|
||||
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
batchv2alpha1 "k8s.io/api/batch/v2alpha1"
|
||||
batchv1beta1 "k8s.io/api/batch/v1beta1"
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
@@ -37,17 +37,17 @@ func TestGetJobFromTemplate(t *testing.T) {
|
||||
var one int64 = 1
|
||||
var no bool = false
|
||||
|
||||
sj := batchv2alpha1.CronJob{
|
||||
sj := batchv1beta1.CronJob{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "mycronjob",
|
||||
Namespace: "snazzycats",
|
||||
UID: types.UID("1a2b3c"),
|
||||
SelfLink: "/apis/batch/v1/namespaces/snazzycats/jobs/mycronjob",
|
||||
},
|
||||
Spec: batchv2alpha1.CronJobSpec{
|
||||
Spec: batchv1beta1.CronJobSpec{
|
||||
Schedule: "* * * * ?",
|
||||
ConcurrencyPolicy: batchv2alpha1.AllowConcurrent,
|
||||
JobTemplate: batchv2alpha1.JobTemplateSpec{
|
||||
ConcurrencyPolicy: batchv1beta1.AllowConcurrent,
|
||||
JobTemplate: batchv1beta1.JobTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: map[string]string{"a": "b"},
|
||||
Annotations: map[string]string{"x": "y"},
|
||||
@@ -267,16 +267,16 @@ func TestGetRecentUnmetScheduleTimes(t *testing.T) {
|
||||
t.Errorf("test setup error: %v", err)
|
||||
}
|
||||
|
||||
sj := batchv2alpha1.CronJob{
|
||||
sj := batchv1beta1.CronJob{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "mycronjob",
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
UID: types.UID("1a2b3c"),
|
||||
},
|
||||
Spec: batchv2alpha1.CronJobSpec{
|
||||
Spec: batchv1beta1.CronJobSpec{
|
||||
Schedule: schedule,
|
||||
ConcurrencyPolicy: batchv2alpha1.AllowConcurrent,
|
||||
JobTemplate: batchv2alpha1.JobTemplateSpec{},
|
||||
ConcurrencyPolicy: batchv1beta1.AllowConcurrent,
|
||||
JobTemplate: batchv1beta1.JobTemplateSpec{},
|
||||
},
|
||||
}
|
||||
{
|
||||
|
||||
@@ -51,6 +51,7 @@ go_test(
|
||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||
"//vendor/k8s.io/api/apps/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/api/batch/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/batch/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/api/batch/v2alpha1:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/extensions/v1beta1:go_default_library",
|
||||
@@ -143,6 +144,7 @@ go_library(
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/k8s.io/api/apps/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/api/batch/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/batch/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/api/batch/v2alpha1:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/extensions/v1beta1:go_default_library",
|
||||
|
||||
@@ -108,6 +108,7 @@ go_library(
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/k8s.io/api/apps/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/api/batch/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/batch/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/api/batch/v2alpha1:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/extensions/v1beta1:go_default_library",
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
batchv1beta1 "k8s.io/api/batch/v1beta1"
|
||||
batchv2alpha1 "k8s.io/api/batch/v2alpha1"
|
||||
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
@@ -225,7 +226,11 @@ func RunRun(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *c
|
||||
generatorName := cmdutil.GetFlagString(cmd, "generator")
|
||||
schedule := cmdutil.GetFlagString(cmd, "schedule")
|
||||
if len(schedule) != 0 && len(generatorName) == 0 {
|
||||
generatorName = cmdutil.CronJobV2Alpha1GeneratorName
|
||||
if contains(resourcesList, batchv1beta1.SchemeGroupVersion.WithResource("cronjobs")) {
|
||||
generatorName = cmdutil.CronJobV1Beta1GeneratorName
|
||||
} else {
|
||||
generatorName = cmdutil.CronJobV2Alpha1GeneratorName
|
||||
}
|
||||
}
|
||||
if len(generatorName) == 0 {
|
||||
switch restartPolicy {
|
||||
|
||||
@@ -479,6 +479,7 @@ const (
|
||||
DeploymentBasicAppsV1Beta1GeneratorName = "deployment-basic/apps.v1beta1"
|
||||
JobV1GeneratorName = "job/v1"
|
||||
CronJobV2Alpha1GeneratorName = "cronjob/v2alpha1"
|
||||
CronJobV1Beta1GeneratorName = "cronjob/v1beta1"
|
||||
NamespaceV1GeneratorName = "namespace/v1"
|
||||
ResourceQuotaV1GeneratorName = "resourcequotas/v1"
|
||||
SecretV1GeneratorName = "secret/v1"
|
||||
@@ -528,6 +529,7 @@ func DefaultGenerators(cmdName string) map[string]kubectl.Generator {
|
||||
DeploymentAppsV1Beta1GeneratorName: kubectl.DeploymentAppsV1Beta1{},
|
||||
JobV1GeneratorName: kubectl.JobV1{},
|
||||
CronJobV2Alpha1GeneratorName: kubectl.CronJobV2Alpha1{},
|
||||
CronJobV1Beta1GeneratorName: kubectl.CronJobV1Beta1{},
|
||||
}
|
||||
case "autoscale":
|
||||
generator = map[string]kubectl.Generator{
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
|
||||
appsv1beta1 "k8s.io/api/apps/v1beta1"
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
batchv1beta1 "k8s.io/api/batch/v1beta1"
|
||||
batchv2alpha1 "k8s.io/api/batch/v2alpha1"
|
||||
"k8s.io/api/core/v1"
|
||||
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||
@@ -483,6 +484,107 @@ func (CronJobV2Alpha1) Generate(genericParams map[string]interface{}) (runtime.O
|
||||
return &cronJob, nil
|
||||
}
|
||||
|
||||
type CronJobV1Beta1 struct{}
|
||||
|
||||
func (CronJobV1Beta1) ParamNames() []GeneratorParam {
|
||||
return []GeneratorParam{
|
||||
{"labels", false},
|
||||
{"default-name", false},
|
||||
{"name", true},
|
||||
{"image", true},
|
||||
{"image-pull-policy", false},
|
||||
{"port", false},
|
||||
{"hostport", false},
|
||||
{"stdin", false},
|
||||
{"leave-stdin-open", false},
|
||||
{"tty", false},
|
||||
{"command", false},
|
||||
{"args", false},
|
||||
{"env", false},
|
||||
{"requests", false},
|
||||
{"limits", false},
|
||||
{"restart", false},
|
||||
{"schedule", true},
|
||||
{"serviceaccount", false},
|
||||
}
|
||||
}
|
||||
|
||||
func (CronJobV1Beta1) Generate(genericParams map[string]interface{}) (runtime.Object, error) {
|
||||
args, err := getArgs(genericParams)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
envs, err := getEnvs(genericParams)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
params, err := getParams(genericParams)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
name, err := getName(params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
labels, err := getLabels(params, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
podSpec, err := makePodSpec(params, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
imagePullPolicy := v1.PullPolicy(params["image-pull-policy"])
|
||||
if err = updatePodContainers(params, args, envs, imagePullPolicy, podSpec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
leaveStdinOpen, err := GetBool(params, "leave-stdin-open", false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
podSpec.Containers[0].StdinOnce = !leaveStdinOpen && podSpec.Containers[0].Stdin
|
||||
|
||||
if err := updatePodPorts(params, podSpec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
restartPolicy := v1.RestartPolicy(params["restart"])
|
||||
if len(restartPolicy) == 0 {
|
||||
restartPolicy = v1.RestartPolicyNever
|
||||
}
|
||||
podSpec.RestartPolicy = restartPolicy
|
||||
|
||||
cronJob := batchv1beta1.CronJob{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Labels: labels,
|
||||
},
|
||||
Spec: batchv1beta1.CronJobSpec{
|
||||
Schedule: params["schedule"],
|
||||
ConcurrencyPolicy: batchv1beta1.AllowConcurrent,
|
||||
JobTemplate: batchv1beta1.JobTemplateSpec{
|
||||
Spec: batchv1.JobSpec{
|
||||
Template: v1.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: labels,
|
||||
},
|
||||
Spec: *podSpec,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return &cronJob, nil
|
||||
}
|
||||
|
||||
type BasicReplicationController struct{}
|
||||
|
||||
func (BasicReplicationController) ParamNames() []GeneratorParam {
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
|
||||
appsv1beta1 "k8s.io/api/apps/v1beta1"
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
batchv1beta1 "k8s.io/api/batch/v1beta1"
|
||||
batchv2alpha1 "k8s.io/api/batch/v2alpha1"
|
||||
"k8s.io/api/core/v1"
|
||||
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||
@@ -922,7 +923,7 @@ func TestGenerateJob(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateCronJob(t *testing.T) {
|
||||
func TestGenerateCronJobAlpha(t *testing.T) {
|
||||
tests := []struct {
|
||||
params map[string]interface{}
|
||||
expected *batchv2alpha1.CronJob
|
||||
@@ -1020,6 +1021,104 @@ func TestGenerateCronJob(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateCronJobBeta(t *testing.T) {
|
||||
tests := []struct {
|
||||
params map[string]interface{}
|
||||
expected *batchv1beta1.CronJob
|
||||
expectErr bool
|
||||
}{
|
||||
{
|
||||
params: map[string]interface{}{
|
||||
"labels": "foo=bar,baz=blah",
|
||||
"name": "foo",
|
||||
"image": "someimage",
|
||||
"port": "80",
|
||||
"hostport": "80",
|
||||
"stdin": "true",
|
||||
"leave-stdin-open": "true",
|
||||
"command": "true",
|
||||
"args": []string{"bar", "baz", "blah"},
|
||||
"env": []string{"a=b", "c=d"},
|
||||
"requests": "cpu=100m,memory=100Mi",
|
||||
"limits": "cpu=400m,memory=200Mi",
|
||||
"restart": "OnFailure",
|
||||
"schedule": "0/5 * * * ?",
|
||||
},
|
||||
expected: &batchv1beta1.CronJob{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Labels: map[string]string{"foo": "bar", "baz": "blah"},
|
||||
},
|
||||
Spec: batchv1beta1.CronJobSpec{
|
||||
Schedule: "0/5 * * * ?",
|
||||
ConcurrencyPolicy: batchv1beta1.AllowConcurrent,
|
||||
JobTemplate: batchv1beta1.JobTemplateSpec{
|
||||
Spec: batchv1.JobSpec{
|
||||
Template: v1.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: map[string]string{"foo": "bar", "baz": "blah"},
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
RestartPolicy: v1.RestartPolicyOnFailure,
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Name: "foo",
|
||||
Image: "someimage",
|
||||
Stdin: true,
|
||||
StdinOnce: false,
|
||||
Ports: []v1.ContainerPort{
|
||||
{
|
||||
ContainerPort: 80,
|
||||
HostPort: 80,
|
||||
},
|
||||
},
|
||||
Command: []string{"bar", "baz", "blah"},
|
||||
Env: []v1.EnvVar{
|
||||
{
|
||||
Name: "a",
|
||||
Value: "b",
|
||||
},
|
||||
{
|
||||
Name: "c",
|
||||
Value: "d",
|
||||
},
|
||||
},
|
||||
Resources: v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("100m"),
|
||||
v1.ResourceMemory: resource.MustParse("100Mi"),
|
||||
},
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("400m"),
|
||||
v1.ResourceMemory: resource.MustParse("200Mi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
generator := CronJobV1Beta1{}
|
||||
for _, test := range tests {
|
||||
obj, err := generator.Generate(test.params)
|
||||
if !test.expectErr && err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if test.expectErr && err != nil {
|
||||
continue
|
||||
}
|
||||
if !reflect.DeepEqual(obj.(*batchv1beta1.CronJob), test.expected) {
|
||||
t.Errorf("\nexpected:\n%#v\nsaw:\n%#v", test.expected, obj.(*batchv1beta1.CronJob))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseEnv(t *testing.T) {
|
||||
tests := []struct {
|
||||
envArray []string
|
||||
|
||||
@@ -73,6 +73,7 @@ go_library(
|
||||
"//vendor/k8s.io/api/authorization/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/api/autoscaling/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/batch/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/batch/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/api/certificates/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/extensions/v1beta1:go_default_library",
|
||||
@@ -134,7 +135,7 @@ go_test(
|
||||
"//vendor/k8s.io/api/apps/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/api/autoscaling/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/batch/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/batch/v2alpha1:go_default_library",
|
||||
"//vendor/k8s.io/api/batch/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/api/certificates/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/extensions/v1beta1:go_default_library",
|
||||
|
||||
@@ -32,6 +32,7 @@ import (
|
||||
authorizationapiv1beta1 "k8s.io/api/authorization/v1beta1"
|
||||
autoscalingapiv1 "k8s.io/api/autoscaling/v1"
|
||||
batchapiv1 "k8s.io/api/batch/v1"
|
||||
batchapiv1beta1 "k8s.io/api/batch/v1beta1"
|
||||
certificatesapiv1beta1 "k8s.io/api/certificates/v1beta1"
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
extensionsapiv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||
@@ -381,9 +382,7 @@ func DefaultAPIResourceConfigSource() *serverstorage.ResourceConfig {
|
||||
apiv1.SchemeGroupVersion,
|
||||
extensionsapiv1beta1.SchemeGroupVersion,
|
||||
batchapiv1.SchemeGroupVersion,
|
||||
// TODO: enable batch/v1beta1 by default before 1.8 release, after issues
|
||||
// with CronJobs existing in multiple versions at once is solved
|
||||
// batchapiv1beta1.SchemeGroupVersion,
|
||||
batchapiv1beta1.SchemeGroupVersion,
|
||||
authenticationv1.SchemeGroupVersion,
|
||||
authenticationv1beta1.SchemeGroupVersion,
|
||||
autoscalingapiv1.SchemeGroupVersion,
|
||||
|
||||
@@ -29,7 +29,7 @@ import (
|
||||
appsapiv1beta1 "k8s.io/api/apps/v1beta1"
|
||||
autoscalingapiv1 "k8s.io/api/autoscaling/v1"
|
||||
batchapiv1 "k8s.io/api/batch/v1"
|
||||
batchapiv2alpha1 "k8s.io/api/batch/v2alpha1"
|
||||
batchapiv1beta1 "k8s.io/api/batch/v1beta1"
|
||||
certificatesapiv1beta1 "k8s.io/api/certificates/v1beta1"
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
extensionsapiv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||
@@ -80,6 +80,8 @@ func setUp(t *testing.T) (*etcdtesting.EtcdTestServer, Config, *assert.Assertion
|
||||
resourceEncoding.SetVersionEncoding(api.GroupName, api.Registry.GroupOrDie(api.GroupName).GroupVersion, schema.GroupVersion{Group: api.GroupName, Version: runtime.APIVersionInternal})
|
||||
resourceEncoding.SetVersionEncoding(autoscaling.GroupName, *testapi.Autoscaling.GroupVersion(), schema.GroupVersion{Group: autoscaling.GroupName, Version: runtime.APIVersionInternal})
|
||||
resourceEncoding.SetVersionEncoding(batch.GroupName, *testapi.Batch.GroupVersion(), schema.GroupVersion{Group: batch.GroupName, Version: runtime.APIVersionInternal})
|
||||
// FIXME (soltysh): this GroupVersionResource override should be configurable
|
||||
resourceEncoding.SetResourceEncoding(schema.GroupResource{Group: "batch", Resource: "cronjobs"}, schema.GroupVersion{Group: batch.GroupName, Version: "v1beta1"}, schema.GroupVersion{Group: batch.GroupName, Version: runtime.APIVersionInternal})
|
||||
resourceEncoding.SetVersionEncoding(apps.GroupName, *testapi.Apps.GroupVersion(), schema.GroupVersion{Group: apps.GroupName, Version: runtime.APIVersionInternal})
|
||||
resourceEncoding.SetVersionEncoding(extensions.GroupName, *testapi.Extensions.GroupVersion(), schema.GroupVersion{Group: extensions.GroupName, Version: runtime.APIVersionInternal})
|
||||
resourceEncoding.SetVersionEncoding(rbac.GroupName, *testapi.Rbac.GroupVersion(), schema.GroupVersion{Group: rbac.GroupName, Version: runtime.APIVersionInternal})
|
||||
@@ -193,7 +195,7 @@ func limitedAPIResourceConfigSource() *serverstorage.ResourceConfig {
|
||||
apiv1.SchemeGroupVersion,
|
||||
extensionsapiv1beta1.SchemeGroupVersion,
|
||||
batchapiv1.SchemeGroupVersion,
|
||||
batchapiv2alpha1.SchemeGroupVersion,
|
||||
batchapiv1beta1.SchemeGroupVersion,
|
||||
appsapiv1beta1.SchemeGroupVersion,
|
||||
autoscalingapiv1.SchemeGroupVersion,
|
||||
)
|
||||
|
||||
@@ -88,7 +88,7 @@ go_library(
|
||||
"//vendor/k8s.io/api/apps/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/api/autoscaling/v2alpha1:go_default_library",
|
||||
"//vendor/k8s.io/api/batch/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/batch/v2alpha1:go_default_library",
|
||||
"//vendor/k8s.io/api/batch/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/api/certificates/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/extensions/v1beta1:go_default_library",
|
||||
|
||||
@@ -29,7 +29,7 @@ import (
|
||||
appsv1beta1 "k8s.io/api/apps/v1beta1"
|
||||
autoscalingv2alpha1 "k8s.io/api/autoscaling/v2alpha1"
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
batchv2alpha1 "k8s.io/api/batch/v2alpha1"
|
||||
batchv1beta1 "k8s.io/api/batch/v1beta1"
|
||||
certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||
@@ -160,10 +160,10 @@ func AddHandlers(h printers.PrintHandler) {
|
||||
|
||||
cronJobColumnDefinitions := []metav1alpha1.TableColumnDefinition{
|
||||
{Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]},
|
||||
{Name: "Schedule", Type: "string", Description: batchv2alpha1.CronJobSpec{}.SwaggerDoc()["schedule"]},
|
||||
{Name: "Suspend", Type: "boolean", Description: batchv2alpha1.CronJobSpec{}.SwaggerDoc()["suspend"]},
|
||||
{Name: "Active", Type: "integer", Description: batchv2alpha1.CronJobStatus{}.SwaggerDoc()["active"]},
|
||||
{Name: "Last Schedule", Type: "string", Description: batchv2alpha1.CronJobStatus{}.SwaggerDoc()["lastScheduleTime"]},
|
||||
{Name: "Schedule", Type: "string", Description: batchv1beta1.CronJobSpec{}.SwaggerDoc()["schedule"]},
|
||||
{Name: "Suspend", Type: "boolean", Description: batchv1beta1.CronJobSpec{}.SwaggerDoc()["suspend"]},
|
||||
{Name: "Active", Type: "integer", Description: batchv1beta1.CronJobStatus{}.SwaggerDoc()["active"]},
|
||||
{Name: "Last Schedule", Type: "string", Description: batchv1beta1.CronJobStatus{}.SwaggerDoc()["lastScheduleTime"]},
|
||||
{Name: "Age", Type: "string", Description: metav1.ObjectMeta{}.SwaggerDoc()["creationTimestamp"]},
|
||||
{Name: "Containers", Type: "string", Priority: 1, Description: "Names of each container in the template."},
|
||||
{Name: "Images", Type: "string", Priority: 1, Description: "Images referenced by each container in the template."},
|
||||
|
||||
Reference in New Issue
Block a user