Skip to content

Commit e298d42

Browse files
authored
Merge pull request #15 from pubg/bug/fix-cronjob-patch
fix: CronJob에서 patch가 미동작 하는 문제 수정
2 parents 5c16504 + f90eeca commit e298d42

File tree

4 files changed

+84
-28
lines changed

4 files changed

+84
-28
lines changed

controller/onUpdateImageHash.go

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package controller
22

33
import (
4-
"encoding/json"
54
"fmt"
65

76
"github.com/pubg/kube-image-deployer/util"
@@ -22,22 +21,6 @@ type imageUpdateNotify struct {
2221
imageString string
2322
}
2423

25-
type Container struct {
26-
Name string `json:"name"`
27-
Image string `json:"image"`
28-
}
29-
30-
type ImageStrategicPatch struct {
31-
Spec struct {
32-
Template struct {
33-
Spec struct {
34-
Containers []Container `json:"containers,omitempty"`
35-
InitContainers []Container `json:"initContainers,omitempty"`
36-
} `json:"spec"`
37-
} `json:"template"`
38-
} `json:"spec"`
39-
}
40-
4124
func (c *Controller) getPatchMapByUpdates(updates []imageUpdateNotify) map[string][]patch {
4225
// key 별로 kubernetes patch apply를 위한 리스트를 생성
4326
patchMap := make(map[string][]patch)
@@ -74,9 +57,8 @@ func (c *Controller) getPatchMapByUpdates(updates []imageUpdateNotify) map[strin
7457

7558
func (c *Controller) applyPatchList(key string, patchList []patch) error {
7659

77-
imageStrategicPatch := ImageStrategicPatch{}
78-
Containers := make([]Container, 0)
79-
InitContainers := make([]Container, 0)
60+
Containers := make([]util.Container, 0)
61+
InitContainers := make([]util.Container, 0)
8062
namespace, name := util.GetNamespaceNameByKey(key)
8163

8264
if namespace == "" || name == "" {
@@ -109,7 +91,7 @@ func (c *Controller) applyPatchList(key string, patchList []patch) error {
10991

11092
// 이미지 변경 체크
11193
if currentContainer.Image != patch.imageString {
112-
container := Container{
94+
container := util.Container{
11395
Name: patch.containerName,
11496
Image: patch.imageString,
11597
}
@@ -127,9 +109,7 @@ func (c *Controller) applyPatchList(key string, patchList []patch) error {
127109
return nil
128110
}
129111

130-
imageStrategicPatch.Spec.Template.Spec.Containers = Containers
131-
imageStrategicPatch.Spec.Template.Spec.InitContainers = InitContainers
132-
patchString, err := json.Marshal(imageStrategicPatch)
112+
patchString, err := util.GetImageStrategicPatchJson(obj, Containers, InitContainers)
133113

134114
if err != nil {
135115
return fmt.Errorf("[%s] OnUpdateImageString patch marshal error %+v, err=%s", c.resource, patchList, err)

main.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/pubg/kube-image-deployer/remoteRegistry/docker"
1616
"github.com/pubg/kube-image-deployer/watcher"
1717
appV1 "k8s.io/api/apps/v1"
18+
batchV1 "k8s.io/api/batch/v1"
1819
batchV1beta1 "k8s.io/api/batch/v1beta1"
1920
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2021
"k8s.io/apimachinery/pkg/types"
@@ -31,6 +32,7 @@ var (
3132
offStatefulsets = *flag.Bool("off-statefulsets", false, "disable statefulsets")
3233
offDaemonsets = *flag.Bool("off-daemonsets", false, "disable daemonsets")
3334
offCronjobs = *flag.Bool("off-cronjobs", false, "disable cronjobs")
35+
useCronJobV1 = *flag.Bool("use-cronjob-v1", false, "use cronjob version v1 instead of v1beta1")
3436
imageStringCacheTTLSec = *flag.Uint("image-hash-cache-ttl-sec", 60, "image hash cache TTL in seconds")
3537
imageCheckIntervalSec = *flag.Uint("image-check-interval-sec", 10, "image check interval in seconds")
3638
controllerWatchKey = *flag.String("controller-watch-key", "kube-image-deployer", "controller watch key")
@@ -68,6 +70,9 @@ func init() {
6870
if os.Getenv("OFF_CRONJOBS") != "" {
6971
offCronjobs = true
7072
}
73+
if os.Getenv("USE_CRONJOB_V1") != "" {
74+
useCronJobV1 = true
75+
}
7176
if os.Getenv("IMAGE_HASH_CACHE_TTL_SEC") != "" {
7277
if v, err := strconv.ParseUint(os.Getenv("IMAGE_HASH_CACHE_TTL_SEC"), 10, 32); err == nil {
7378
imageStringCacheTTLSec = uint(v)
@@ -100,6 +105,7 @@ func init() {
100105
"offStatefulsets": offStatefulsets,
101106
"offDaemonsets": offDaemonsets,
102107
"offCronjobs": offCronjobs,
108+
"useCronJobV1": useCronJobV1,
103109
"imageStringCacheTTLSec": imageStringCacheTTLSec,
104110
"imageCheckIntervalSec": imageCheckIntervalSec,
105111
"controllerWatchKey": controllerWatchKey,
@@ -181,11 +187,19 @@ func runWatchers(stopCh chan struct{}) {
181187
}
182188

183189
if !offCronjobs { // cronjobs watcher
184-
applyStrategicMergePatch := func(namespace string, name string, data []byte) error {
185-
_, err := clientset.BatchV1beta1().CronJobs(namespace).Patch(context.TODO(), name, types.StrategicMergePatchType, data, metaV1.PatchOptions{})
186-
return err
190+
if useCronJobV1 {
191+
applyStrategicMergePatch := func(namespace string, name string, data []byte) error {
192+
_, err := clientset.BatchV1().CronJobs(namespace).Patch(context.TODO(), name, types.StrategicMergePatchType, data, metaV1.PatchOptions{})
193+
return err
194+
}
195+
go watcher.NewWatcher("cronjobs", stopCh, logger, cache.NewFilteredListWatchFromClient(clientset.BatchV1().RESTClient(), "cronjobs", controllerWatchNamespace, optionsModifier), &batchV1.CronJob{}, imageNotifier, controllerWatchKey, applyStrategicMergePatch)
196+
} else {
197+
applyStrategicMergePatch := func(namespace string, name string, data []byte) error {
198+
_, err := clientset.BatchV1beta1().CronJobs(namespace).Patch(context.TODO(), name, types.StrategicMergePatchType, data, metaV1.PatchOptions{})
199+
return err
200+
}
201+
go watcher.NewWatcher("cronjobs", stopCh, logger, cache.NewFilteredListWatchFromClient(clientset.BatchV1beta1().RESTClient(), "cronjobs", controllerWatchNamespace, optionsModifier), &batchV1beta1.CronJob{}, imageNotifier, controllerWatchKey, applyStrategicMergePatch)
187202
}
188-
go watcher.NewWatcher("cronjobs", stopCh, logger, cache.NewFilteredListWatchFromClient(clientset.BatchV1beta1().RESTClient(), "cronjobs", controllerWatchNamespace, optionsModifier), &batchV1beta1.CronJob{}, imageNotifier, controllerWatchKey, applyStrategicMergePatch)
189203
}
190204
}
191205

readme.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ offDeployments = *flag.Bool("off-deployments", false, "disable deploym
1919
offStatefulsets = *flag.Bool("off-statefulsets", false, "disable statefulsets")
2020
offDaemonsets = *flag.Bool("off-daemonsets", false, "disable daemonsets")
2121
offCronjobs = *flag.Bool("off-cronjobs", false, "disable cronjobs")
22+
useCronJobV1 = *flag.Bool("use-cronjob-v1", false, "use cronjob version v1 instead of v1beta1")
2223
imageStringCacheTTLSec = *flag.Uint("image-hash-cache-ttl-sec", 60, "image hash cache TTL in seconds")
2324
imageCheckIntervalSec = *flag.Uint("image-check-interval-sec", 10, "image check interval in seconds")
2425
controllerWatchKey = *flag.String("controller-watch-key", "kube-image-deployer", "controller watch key")
@@ -35,6 +36,7 @@ OFF_DEPLOYMENTS=<true>
3536
OFF_STATEFULSETS=<true>
3637
OFF_DAEMONSETS=<true>
3738
OFF_CRONJOBS=<true>
39+
USE_CRONJOB_V1=<true>
3840
IMAGE_HASH_CACHE_TTL_SEC=<uint>
3941
IMAGE_CHECK_INTERVAL_SEC=<uint>
4042
CONTROLLER_WATCH_KEY=<kube-image-deployer>

util/kubernetes.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,47 @@
11
package util
22

33
import (
4+
"encoding/json"
45
"fmt"
56
"strings"
67

78
appV1 "k8s.io/api/apps/v1"
89
batchV1 "k8s.io/api/batch/v1"
10+
batchV1Beta1 "k8s.io/api/batch/v1beta1"
911
coreV1 "k8s.io/api/core/v1"
1012
)
1113

14+
type Container struct {
15+
Name string `json:"name"`
16+
Image string `json:"image"`
17+
}
18+
19+
type ImageStrategicPatch struct {
20+
Spec struct {
21+
Template struct {
22+
Spec struct {
23+
Containers []Container `json:"containers,omitempty"`
24+
InitContainers []Container `json:"initContainers,omitempty"`
25+
} `json:"spec"`
26+
} `json:"template"`
27+
} `json:"spec"`
28+
}
29+
30+
type ImageStrategicPatchCronJob struct {
31+
Spec struct {
32+
JobTemplate struct {
33+
Spec struct {
34+
Template struct {
35+
Spec struct {
36+
Containers []Container `json:"containers,omitempty"`
37+
InitContainers []Container `json:"initContainers,omitempty"`
38+
} `json:"spec"`
39+
} `json:"template"`
40+
} `json:"spec"`
41+
} `json:"jobTemplate"`
42+
} `json:"spec"`
43+
}
44+
1245
func GetAnnotations(obj interface{}) (map[string]string, error) {
1346
switch t := obj.(type) {
1447
case *appV1.Deployment:
@@ -17,6 +50,8 @@ func GetAnnotations(obj interface{}) (map[string]string, error) {
1750
return t.Annotations, nil
1851
case *appV1.DaemonSet:
1952
return t.Annotations, nil
53+
case *batchV1Beta1.CronJob:
54+
return t.Annotations, nil
2055
case *batchV1.CronJob:
2156
return t.Annotations, nil
2257
default:
@@ -32,6 +67,8 @@ func GetContainers(obj interface{}) ([]coreV1.Container, error) {
3267
return t.Spec.Template.Spec.Containers, nil
3368
case *appV1.DaemonSet:
3469
return t.Spec.Template.Spec.Containers, nil
70+
case *batchV1Beta1.CronJob:
71+
return t.Spec.JobTemplate.Spec.Template.Spec.Containers, nil
3572
case *batchV1.CronJob:
3673
return t.Spec.JobTemplate.Spec.Template.Spec.Containers, nil
3774
default:
@@ -47,6 +84,8 @@ func GetInitContainers(obj interface{}) ([]coreV1.Container, error) {
4784
return t.Spec.Template.Spec.InitContainers, nil
4885
case *appV1.DaemonSet:
4986
return t.Spec.Template.Spec.InitContainers, nil
87+
case *batchV1Beta1.CronJob:
88+
return t.Spec.JobTemplate.Spec.Template.Spec.InitContainers, nil
5089
case *batchV1.CronJob:
5190
return t.Spec.JobTemplate.Spec.Template.Spec.InitContainers, nil
5291
default:
@@ -91,3 +130,24 @@ func GetNamespaceNameByKey(key string) (namespace string, name string) {
91130
}
92131
return
93132
}
133+
134+
func GetImageStrategicPatchJson(obj interface{}, containers, initContainers []Container) ([]byte, error) {
135+
var imageStrategicPatch interface{}
136+
137+
switch obj.(type) {
138+
case *batchV1Beta1.CronJob:
139+
imageStrategicPatch := ImageStrategicPatchCronJob{}
140+
imageStrategicPatch.Spec.JobTemplate.Spec.Template.Spec.Containers = containers
141+
imageStrategicPatch.Spec.JobTemplate.Spec.Template.Spec.InitContainers = initContainers
142+
case *batchV1.CronJob:
143+
imageStrategicPatch := ImageStrategicPatchCronJob{}
144+
imageStrategicPatch.Spec.JobTemplate.Spec.Template.Spec.Containers = containers
145+
imageStrategicPatch.Spec.JobTemplate.Spec.Template.Spec.InitContainers = initContainers
146+
default:
147+
imageStrategicPatch := ImageStrategicPatch{}
148+
imageStrategicPatch.Spec.Template.Spec.Containers = containers
149+
imageStrategicPatch.Spec.Template.Spec.InitContainers = initContainers
150+
}
151+
patchJson, err := json.Marshal(imageStrategicPatch)
152+
return patchJson, err
153+
}

0 commit comments

Comments
 (0)