@@ -4,10 +4,13 @@ import (
44 "context"
55 "encoding/json"
66 "fmt"
7+ "os"
8+ "strconv"
79 "time"
810
911 "github.com/drycc/builder/pkg/k8s"
1012 "github.com/pborman/uuid"
13+ batchv1 "k8s.io/api/batch/v1"
1114 corev1 "k8s.io/api/core/v1"
1215 apierrors "k8s.io/apimachinery/pkg/api/errors"
1316 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -27,7 +30,7 @@ const (
2730 imagebuilderConfigPath = "/etc/imagebuilder"
2831)
2932
30- func imagebuilderPodName (appName , shortSha string ) string {
33+ func imagebuilderJobName (appName , shortSha string ) string {
3134 uid := uuid .New ()[:8 ]
3235 // NOTE(bacongobbler): pod names cannot exceed 63 characters in length, so we truncate
3336 // the application name to stay under that limit when adding all the extra metadata to the name
@@ -37,7 +40,7 @@ func imagebuilderPodName(appName, shortSha string) string {
3740 return fmt .Sprintf ("imagebuild-%s-%s-%s" , appName , shortSha , uid )
3841}
3942
40- func createBuilderPod (
43+ func createBuilderJob (
4144 debug bool ,
4245 name ,
4346 namespace string ,
@@ -54,9 +57,9 @@ func createBuilderPod(
5457 pullPolicy corev1.PullPolicy ,
5558 securityContext corev1.SecurityContext ,
5659 nodeSelector map [string ]string ,
57- ) * corev1. Pod {
60+ ) * batchv1. Job {
5861
59- pod := buildPod (debug , name , namespace , pullPolicy , securityContext , nodeSelector , env )
62+ job := buildJob (debug , name , namespace , pullPolicy , securityContext , nodeSelector , env )
6063
6164 // inject application envvars as a special envvar which will be handled by imagebuilder to
6265 // inject them as build-time variables.
@@ -67,47 +70,67 @@ func createBuilderPod(
6770 // So we need to translate the map into json.
6871 if _ , ok := env ["DRYCC_DOCKER_BUILD_ARGS_ENABLED" ]; ok {
6972 imageBuildArgs , _ := json .Marshal (env )
70- addEnvToPod ( pod , "DOCKER_BUILD_ARGS" , string (imageBuildArgs ))
73+ addEnvToJob ( job , "DOCKER_BUILD_ARGS" , string (imageBuildArgs ))
7174 }
75+ job .Spec .Template .Spec .Containers [0 ].Name = builderName
76+ job .Spec .Template .Spec .Containers [0 ].Image = builderImage
7277
73- pod .Spec .Containers [0 ].Name = builderName
74- pod .Spec .Containers [0 ].Image = builderImage
75-
76- addEnvToPod (pod , tarPath , tarKey )
77- addEnvToPod (pod , sourceVersion , gitShortHash )
78- addEnvToPod (pod , "IMG_NAME" , imageName )
79- addEnvToPod (pod , builderStorage , storageType )
78+ addEnvToJob (job , tarPath , tarKey )
79+ addEnvToJob (job , sourceVersion , gitShortHash )
80+ addEnvToJob (job , "IMG_NAME" , imageName )
81+ addEnvToJob (job , builderStorage , storageType )
8082 // inject existing DRYCC_REGISTRY_PROXY_HOST and PORT info to imagebuilder
8183 // see https://github.com/drycc/imagebuilder/issues/83
82- addEnvToPod ( pod , "DRYCC_REGISTRY_PROXY_HOST" , registryHost )
83- addEnvToPod ( pod , "DRYCC_REGISTRY_PROXY_PORT" , registryPort )
84+ addEnvToJob ( job , "DRYCC_REGISTRY_PROXY_HOST" , registryHost )
85+ addEnvToJob ( job , "DRYCC_REGISTRY_PROXY_PORT" , registryPort )
8486
8587 for key , value := range builderImageEnv {
86- addEnvToPod ( pod , key , value )
88+ addEnvToJob ( job , key , value )
8789 }
8890
89- return & pod
91+ return & job
92+ }
93+
94+ func newInt32 (i int32 ) * int32 {
95+ return & i
9096}
9197
92- func buildPod (
98+ func buildJob (
9399 debug bool ,
94100 name ,
95101 namespace string ,
96102 //pullPolicy api.PullPolicy,
97103 pullPolicy corev1.PullPolicy ,
98104 securityContext corev1.SecurityContext ,
99105 nodeSelector map [string ]string ,
100- env map [string ]interface {}) corev1.Pod {
101- pod := corev1.Pod {
102- Spec : corev1.PodSpec {
103- RestartPolicy : corev1 .RestartPolicyNever ,
104- Containers : []corev1.Container {
105- {
106- ImagePullPolicy : pullPolicy ,
107- SecurityContext : & securityContext ,
106+ env map [string ]interface {}) batchv1.Job {
107+ TTLSecondsAfterFinished := newInt32 (21600 )
108+ if os .Getenv ("TTL_SECONDS_AFTER_FINISHED" ) != "" {
109+ ttl , err := strconv .ParseInt (os .Getenv ("TTL_SECONDS_AFTER_FINISHED" ), 10 , 32 )
110+ if err == nil {
111+ TTLSecondsAfterFinished = newInt32 (int32 (ttl ))
112+ }
113+ }
114+
115+ job := batchv1.Job {
116+ Spec : batchv1.JobSpec {
117+ BackoffLimit : newInt32 (0 ),
118+ TTLSecondsAfterFinished : TTLSecondsAfterFinished ,
119+ Template : corev1.PodTemplateSpec {
120+ ObjectMeta : metav1.ObjectMeta {
121+ Labels : map [string ]string {
122+ "heritage" : name ,
123+ },
124+ },
125+ Spec : corev1.PodSpec {
126+ Containers : []corev1.Container {
127+ {
128+ ImagePullPolicy : pullPolicy ,
129+ SecurityContext : & securityContext ,
130+ },
131+ },
108132 },
109133 },
110- Volumes : []corev1.Volume {},
111134 },
112135 ObjectMeta : metav1.ObjectMeta {
113136 Name : name ,
@@ -117,8 +140,10 @@ func buildPod(
117140 },
118141 },
119142 }
120-
121- pod .Spec .Volumes = append (pod .Spec .Volumes , corev1.Volume {
143+ job .Spec .Template .Spec .RestartPolicy = corev1 .RestartPolicyNever
144+ job .Spec .Template .Spec .Containers [0 ].ImagePullPolicy = pullPolicy
145+ job .Spec .Template .Spec .Containers [0 ].SecurityContext = & securityContext
146+ job .Spec .Template .Spec .Volumes = append (job .Spec .Template .Spec .Volumes , corev1.Volume {
122147 Name : objectStore ,
123148 VolumeSource : corev1.VolumeSource {
124149 Secret : & corev1.SecretVolumeSource {
@@ -127,14 +152,14 @@ func buildPod(
127152 },
128153 })
129154
130- pod .Spec .Containers [0 ].VolumeMounts = []corev1.VolumeMount {
155+ job . Spec . Template .Spec .Containers [0 ].VolumeMounts = []corev1.VolumeMount {
131156 {
132157 Name : objectStore ,
133158 MountPath : objectStorePath ,
134159 ReadOnly : true ,
135160 },
136161 }
137- pod .Spec .Volumes = append (pod .Spec .Volumes , corev1.Volume {
162+ job .Spec .Template . Spec . Volumes = append (job . Spec . Template .Spec .Volumes , corev1.Volume {
138163 Name : imagebuilderConfig ,
139164 VolumeSource : corev1.VolumeSource {
140165 ConfigMap : & corev1.ConfigMapVolumeSource {
@@ -145,35 +170,35 @@ func buildPod(
145170 },
146171 })
147172
148- pod .Spec .Containers [0 ].VolumeMounts = append (pod .Spec .Containers [0 ].VolumeMounts , corev1.VolumeMount {
173+ job .Spec .Template . Spec . Containers [0 ].VolumeMounts = append (job . Spec . Template .Spec .Containers [0 ].VolumeMounts , corev1.VolumeMount {
149174 Name : imagebuilderConfig ,
150175 MountPath : imagebuilderConfigPath ,
151176 ReadOnly : true ,
152177 })
153178
154- if len (pod .Spec .Containers ) > 0 {
179+ if len (job . Spec . Template .Spec .Containers ) > 0 {
155180 for k , v := range env {
156- pod .Spec .Containers [0 ].Env = append (pod .Spec .Containers [0 ].Env , corev1.EnvVar {
181+ job .Spec .Template . Spec . Containers [0 ].Env = append (job . Spec . Template .Spec .Containers [0 ].Env , corev1.EnvVar {
157182 Name : k ,
158183 Value : fmt .Sprintf ("%v" , v ),
159184 })
160185 }
161186 }
162187
163188 if len (nodeSelector ) > 0 {
164- pod .Spec .NodeSelector = nodeSelector
189+ job . Spec . Template .Spec .NodeSelector = nodeSelector
165190 }
166191
167192 if debug {
168- addEnvToPod ( pod , debugKey , "1" )
193+ addEnvToJob ( job , debugKey , "1" )
169194 }
170195
171- return pod
196+ return job
172197}
173198
174- func addEnvToPod ( pod corev1. Pod , key , value string ) {
175- if len (pod .Spec .Containers ) > 0 {
176- pod .Spec .Containers [0 ].Env = append (pod .Spec .Containers [0 ].Env , corev1.EnvVar {
199+ func addEnvToJob ( job batchv1. Job , key , value string ) {
200+ if len (job . Spec . Template .Spec .Containers ) > 0 {
201+ job .Spec .Template . Spec . Containers [0 ].Env = append (job . Spec . Template .Spec .Containers [0 ].Env , corev1.EnvVar {
177202 Name : key ,
178203 Value : value ,
179204 })
0 commit comments