Skip to content

Commit

Permalink
Merge pull request #15 from pubg/bug/fix-cronjob-patch
Browse files Browse the repository at this point in the history
fix: CronJob에서 patch가 미동작 하는 문제 수정
  • Loading branch information
bitofsky authored Jan 19, 2022
2 parents 5c16504 + f90eeca commit e298d42
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 28 deletions.
28 changes: 4 additions & 24 deletions controller/onUpdateImageHash.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package controller

import (
"encoding/json"
"fmt"

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

type Container struct {
Name string `json:"name"`
Image string `json:"image"`
}

type ImageStrategicPatch struct {
Spec struct {
Template struct {
Spec struct {
Containers []Container `json:"containers,omitempty"`
InitContainers []Container `json:"initContainers,omitempty"`
} `json:"spec"`
} `json:"template"`
} `json:"spec"`
}

func (c *Controller) getPatchMapByUpdates(updates []imageUpdateNotify) map[string][]patch {
// key 별로 kubernetes patch apply를 위한 리스트를 생성
patchMap := make(map[string][]patch)
Expand Down Expand Up @@ -74,9 +57,8 @@ func (c *Controller) getPatchMapByUpdates(updates []imageUpdateNotify) map[strin

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

imageStrategicPatch := ImageStrategicPatch{}
Containers := make([]Container, 0)
InitContainers := make([]Container, 0)
Containers := make([]util.Container, 0)
InitContainers := make([]util.Container, 0)
namespace, name := util.GetNamespaceNameByKey(key)

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

// 이미지 변경 체크
if currentContainer.Image != patch.imageString {
container := Container{
container := util.Container{
Name: patch.containerName,
Image: patch.imageString,
}
Expand All @@ -127,9 +109,7 @@ func (c *Controller) applyPatchList(key string, patchList []patch) error {
return nil
}

imageStrategicPatch.Spec.Template.Spec.Containers = Containers
imageStrategicPatch.Spec.Template.Spec.InitContainers = InitContainers
patchString, err := json.Marshal(imageStrategicPatch)
patchString, err := util.GetImageStrategicPatchJson(obj, Containers, InitContainers)

if err != nil {
return fmt.Errorf("[%s] OnUpdateImageString patch marshal error %+v, err=%s", c.resource, patchList, err)
Expand Down
22 changes: 18 additions & 4 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/pubg/kube-image-deployer/remoteRegistry/docker"
"github.com/pubg/kube-image-deployer/watcher"
appV1 "k8s.io/api/apps/v1"
batchV1 "k8s.io/api/batch/v1"
batchV1beta1 "k8s.io/api/batch/v1beta1"
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
Expand All @@ -31,6 +32,7 @@ var (
offStatefulsets = *flag.Bool("off-statefulsets", false, "disable statefulsets")
offDaemonsets = *flag.Bool("off-daemonsets", false, "disable daemonsets")
offCronjobs = *flag.Bool("off-cronjobs", false, "disable cronjobs")
useCronJobV1 = *flag.Bool("use-cronjob-v1", false, "use cronjob version v1 instead of v1beta1")
imageStringCacheTTLSec = *flag.Uint("image-hash-cache-ttl-sec", 60, "image hash cache TTL in seconds")
imageCheckIntervalSec = *flag.Uint("image-check-interval-sec", 10, "image check interval in seconds")
controllerWatchKey = *flag.String("controller-watch-key", "kube-image-deployer", "controller watch key")
Expand Down Expand Up @@ -68,6 +70,9 @@ func init() {
if os.Getenv("OFF_CRONJOBS") != "" {
offCronjobs = true
}
if os.Getenv("USE_CRONJOB_V1") != "" {
useCronJobV1 = true
}
if os.Getenv("IMAGE_HASH_CACHE_TTL_SEC") != "" {
if v, err := strconv.ParseUint(os.Getenv("IMAGE_HASH_CACHE_TTL_SEC"), 10, 32); err == nil {
imageStringCacheTTLSec = uint(v)
Expand Down Expand Up @@ -100,6 +105,7 @@ func init() {
"offStatefulsets": offStatefulsets,
"offDaemonsets": offDaemonsets,
"offCronjobs": offCronjobs,
"useCronJobV1": useCronJobV1,
"imageStringCacheTTLSec": imageStringCacheTTLSec,
"imageCheckIntervalSec": imageCheckIntervalSec,
"controllerWatchKey": controllerWatchKey,
Expand Down Expand Up @@ -181,11 +187,19 @@ func runWatchers(stopCh chan struct{}) {
}

if !offCronjobs { // cronjobs watcher
applyStrategicMergePatch := func(namespace string, name string, data []byte) error {
_, err := clientset.BatchV1beta1().CronJobs(namespace).Patch(context.TODO(), name, types.StrategicMergePatchType, data, metaV1.PatchOptions{})
return err
if useCronJobV1 {
applyStrategicMergePatch := func(namespace string, name string, data []byte) error {
_, err := clientset.BatchV1().CronJobs(namespace).Patch(context.TODO(), name, types.StrategicMergePatchType, data, metaV1.PatchOptions{})
return err
}
go watcher.NewWatcher("cronjobs", stopCh, logger, cache.NewFilteredListWatchFromClient(clientset.BatchV1().RESTClient(), "cronjobs", controllerWatchNamespace, optionsModifier), &batchV1.CronJob{}, imageNotifier, controllerWatchKey, applyStrategicMergePatch)
} else {
applyStrategicMergePatch := func(namespace string, name string, data []byte) error {
_, err := clientset.BatchV1beta1().CronJobs(namespace).Patch(context.TODO(), name, types.StrategicMergePatchType, data, metaV1.PatchOptions{})
return err
}
go watcher.NewWatcher("cronjobs", stopCh, logger, cache.NewFilteredListWatchFromClient(clientset.BatchV1beta1().RESTClient(), "cronjobs", controllerWatchNamespace, optionsModifier), &batchV1beta1.CronJob{}, imageNotifier, controllerWatchKey, applyStrategicMergePatch)
}
go watcher.NewWatcher("cronjobs", stopCh, logger, cache.NewFilteredListWatchFromClient(clientset.BatchV1beta1().RESTClient(), "cronjobs", controllerWatchNamespace, optionsModifier), &batchV1beta1.CronJob{}, imageNotifier, controllerWatchKey, applyStrategicMergePatch)
}
}

Expand Down
2 changes: 2 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ offDeployments = *flag.Bool("off-deployments", false, "disable deploym
offStatefulsets = *flag.Bool("off-statefulsets", false, "disable statefulsets")
offDaemonsets = *flag.Bool("off-daemonsets", false, "disable daemonsets")
offCronjobs = *flag.Bool("off-cronjobs", false, "disable cronjobs")
useCronJobV1 = *flag.Bool("use-cronjob-v1", false, "use cronjob version v1 instead of v1beta1")
imageStringCacheTTLSec = *flag.Uint("image-hash-cache-ttl-sec", 60, "image hash cache TTL in seconds")
imageCheckIntervalSec = *flag.Uint("image-check-interval-sec", 10, "image check interval in seconds")
controllerWatchKey = *flag.String("controller-watch-key", "kube-image-deployer", "controller watch key")
Expand All @@ -35,6 +36,7 @@ OFF_DEPLOYMENTS=<true>
OFF_STATEFULSETS=<true>
OFF_DAEMONSETS=<true>
OFF_CRONJOBS=<true>
USE_CRONJOB_V1=<true>
IMAGE_HASH_CACHE_TTL_SEC=<uint>
IMAGE_CHECK_INTERVAL_SEC=<uint>
CONTROLLER_WATCH_KEY=<kube-image-deployer>
Expand Down
60 changes: 60 additions & 0 deletions util/kubernetes.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,47 @@
package util

import (
"encoding/json"
"fmt"
"strings"

appV1 "k8s.io/api/apps/v1"
batchV1 "k8s.io/api/batch/v1"
batchV1Beta1 "k8s.io/api/batch/v1beta1"
coreV1 "k8s.io/api/core/v1"
)

type Container struct {
Name string `json:"name"`
Image string `json:"image"`
}

type ImageStrategicPatch struct {
Spec struct {
Template struct {
Spec struct {
Containers []Container `json:"containers,omitempty"`
InitContainers []Container `json:"initContainers,omitempty"`
} `json:"spec"`
} `json:"template"`
} `json:"spec"`
}

type ImageStrategicPatchCronJob struct {
Spec struct {
JobTemplate struct {
Spec struct {
Template struct {
Spec struct {
Containers []Container `json:"containers,omitempty"`
InitContainers []Container `json:"initContainers,omitempty"`
} `json:"spec"`
} `json:"template"`
} `json:"spec"`
} `json:"jobTemplate"`
} `json:"spec"`
}

func GetAnnotations(obj interface{}) (map[string]string, error) {
switch t := obj.(type) {
case *appV1.Deployment:
Expand All @@ -17,6 +50,8 @@ func GetAnnotations(obj interface{}) (map[string]string, error) {
return t.Annotations, nil
case *appV1.DaemonSet:
return t.Annotations, nil
case *batchV1Beta1.CronJob:
return t.Annotations, nil
case *batchV1.CronJob:
return t.Annotations, nil
default:
Expand All @@ -32,6 +67,8 @@ func GetContainers(obj interface{}) ([]coreV1.Container, error) {
return t.Spec.Template.Spec.Containers, nil
case *appV1.DaemonSet:
return t.Spec.Template.Spec.Containers, nil
case *batchV1Beta1.CronJob:
return t.Spec.JobTemplate.Spec.Template.Spec.Containers, nil
case *batchV1.CronJob:
return t.Spec.JobTemplate.Spec.Template.Spec.Containers, nil
default:
Expand All @@ -47,6 +84,8 @@ func GetInitContainers(obj interface{}) ([]coreV1.Container, error) {
return t.Spec.Template.Spec.InitContainers, nil
case *appV1.DaemonSet:
return t.Spec.Template.Spec.InitContainers, nil
case *batchV1Beta1.CronJob:
return t.Spec.JobTemplate.Spec.Template.Spec.InitContainers, nil
case *batchV1.CronJob:
return t.Spec.JobTemplate.Spec.Template.Spec.InitContainers, nil
default:
Expand Down Expand Up @@ -91,3 +130,24 @@ func GetNamespaceNameByKey(key string) (namespace string, name string) {
}
return
}

func GetImageStrategicPatchJson(obj interface{}, containers, initContainers []Container) ([]byte, error) {
var imageStrategicPatch interface{}

switch obj.(type) {
case *batchV1Beta1.CronJob:
imageStrategicPatch := ImageStrategicPatchCronJob{}
imageStrategicPatch.Spec.JobTemplate.Spec.Template.Spec.Containers = containers
imageStrategicPatch.Spec.JobTemplate.Spec.Template.Spec.InitContainers = initContainers
case *batchV1.CronJob:
imageStrategicPatch := ImageStrategicPatchCronJob{}
imageStrategicPatch.Spec.JobTemplate.Spec.Template.Spec.Containers = containers
imageStrategicPatch.Spec.JobTemplate.Spec.Template.Spec.InitContainers = initContainers
default:
imageStrategicPatch := ImageStrategicPatch{}
imageStrategicPatch.Spec.Template.Spec.Containers = containers
imageStrategicPatch.Spec.Template.Spec.InitContainers = initContainers
}
patchJson, err := json.Marshal(imageStrategicPatch)
return patchJson, err
}

0 comments on commit e298d42

Please sign in to comment.