... | ... |
@@ -244,6 +244,10 @@ type CustomBuildStrategy struct { |
244 | 244 |
// inside the Docker container. |
245 | 245 |
// TODO: Allow admins to enforce 'false' for this option |
246 | 246 |
ExposeDockerSocket bool |
247 |
+ |
|
248 |
+ // ForcePull describes if the controller should configure the build pod to always pull the images |
|
249 |
+ // for the builder or only pull if it is not present locally |
|
250 |
+ ForcePull bool |
|
247 | 251 |
} |
248 | 252 |
|
249 | 253 |
// DockerBuildStrategy defines input parameters specific to Docker build. |
... | ... |
@@ -229,6 +229,10 @@ type CustomBuildStrategy struct { |
229 | 229 |
// inside the Docker container. |
230 | 230 |
// TODO: Allow admins to enforce 'false' for this option |
231 | 231 |
ExposeDockerSocket bool `json:"exposeDockerSocket,omitempty" description:"allow running Docker commands (and build Docker images) from inside the container"` |
232 |
+ |
|
233 |
+ // ForcePull describes if the controller should configure the build pod to always pull the images |
|
234 |
+ // for the builder or only pull if it is not present locally |
|
235 |
+ ForcePull bool `json:"forcePull,omitempty" description:"forces pulling of builder image from remote registry if true"` |
|
232 | 236 |
} |
233 | 237 |
|
234 | 238 |
// DockerBuildStrategy defines input parameters specific to Docker build. |
... | ... |
@@ -220,6 +220,10 @@ type CustomBuildStrategy struct { |
220 | 220 |
// inside the Docker container. |
221 | 221 |
// TODO: Allow admins to enforce 'false' for this option |
222 | 222 |
ExposeDockerSocket bool `json:"exposeDockerSocket,omitempty"` |
223 |
+ |
|
224 |
+ // ForcePull describes if the controller should configure the build pod to always pull the images |
|
225 |
+ // for the builder or only pull if it is not present locally |
|
226 |
+ ForcePull bool `json:"forcePull,omitempty" description:"forces pulling of builder image from remote registry if true"` |
|
223 | 227 |
} |
224 | 228 |
|
225 | 229 |
// DockerBuildStrategy defines input parameters specific to Docker build. |
... | ... |
@@ -77,7 +77,12 @@ func (bs *CustomBuildStrategy) CreateBuildPod(build *buildapi.Build) (*kapi.Pod, |
77 | 77 |
return nil, err |
78 | 78 |
} |
79 | 79 |
|
80 |
- pod.Spec.Containers[0].ImagePullPolicy = kapi.PullIfNotPresent |
|
80 |
+ if !strategy.ForcePull { |
|
81 |
+ pod.Spec.Containers[0].ImagePullPolicy = kapi.PullIfNotPresent |
|
82 |
+ } else { |
|
83 |
+ glog.V(2).Infof("ForcePull is enabled for %s build", build.Name) |
|
84 |
+ pod.Spec.Containers[0].ImagePullPolicy = kapi.PullAlways |
|
85 |
+ } |
|
81 | 86 |
pod.Spec.Containers[0].Resources = build.Spec.Resources |
82 | 87 |
|
83 | 88 |
if strategy.ExposeDockerSocket { |
... | ... |
@@ -17,7 +17,7 @@ func TestCustomCreateBuildPod(t *testing.T) { |
17 | 17 |
Codec: latest.Codec, |
18 | 18 |
} |
19 | 19 |
|
20 |
- expectedBad := mockCustomBuild() |
|
20 |
+ expectedBad := mockCustomBuild(false) |
|
21 | 21 |
expectedBad.Spec.Strategy.CustomStrategy.From = kapi.ObjectReference{ |
22 | 22 |
Kind: "DockerImage", |
23 | 23 |
Name: "", |
... | ... |
@@ -26,7 +26,7 @@ func TestCustomCreateBuildPod(t *testing.T) { |
26 | 26 |
t.Errorf("Expected error when Image is empty, got nothing") |
27 | 27 |
} |
28 | 28 |
|
29 |
- expected := mockCustomBuild() |
|
29 |
+ expected := mockCustomBuild(false) |
|
30 | 30 |
actual, err := strategy.CreateBuildPod(expected) |
31 | 31 |
if err != nil { |
32 | 32 |
t.Fatalf("Unexpected error: %v", err) |
... | ... |
@@ -83,9 +83,19 @@ func TestCustomCreateBuildPod(t *testing.T) { |
83 | 83 |
t.Errorf("Expected %s variable to be set", name) |
84 | 84 |
} |
85 | 85 |
} |
86 |
+ |
|
87 |
+ expectedForcePull := mockCustomBuild(true) |
|
88 |
+ actualForcePull, fperr := strategy.CreateBuildPod(expectedForcePull) |
|
89 |
+ if fperr != nil { |
|
90 |
+ t.Fatalf("Unexpected error: %v", fperr) |
|
91 |
+ } |
|
92 |
+ containerForcePull := actualForcePull.Spec.Containers[0] |
|
93 |
+ if containerForcePull.ImagePullPolicy != kapi.PullAlways { |
|
94 |
+ t.Errorf("Expected %v, got %v", kapi.PullAlways, container.ImagePullPolicy) |
|
95 |
+ } |
|
86 | 96 |
} |
87 | 97 |
|
88 |
-func mockCustomBuild() *buildapi.Build { |
|
98 |
+func mockCustomBuild(forcePull bool) *buildapi.Build { |
|
89 | 99 |
return &buildapi.Build{ |
90 | 100 |
ObjectMeta: kapi.ObjectMeta{ |
91 | 101 |
Name: "customBuild", |
... | ... |
@@ -116,6 +126,7 @@ func mockCustomBuild() *buildapi.Build { |
116 | 116 |
{Name: "FOO", Value: "BAR"}, |
117 | 117 |
}, |
118 | 118 |
ExposeDockerSocket: true, |
119 |
+ ForcePull: forcePull, |
|
119 | 120 |
}, |
120 | 121 |
}, |
121 | 122 |
Output: buildapi.BuildOutput{ |
... | ... |
@@ -68,7 +68,7 @@ func isVolumeSourceEmpty(volumeSource kapi.VolumeSource) bool { |
68 | 68 |
} |
69 | 69 |
|
70 | 70 |
func TestSetupBuildEnvEmpty(t *testing.T) { |
71 |
- build := mockCustomBuild() |
|
71 |
+ build := mockCustomBuild(false) |
|
72 | 72 |
containerEnv := []kapi.EnvVar{ |
73 | 73 |
{Name: "BUILD", Value: ""}, |
74 | 74 |
{Name: "SOURCE_REPOSITORY", Value: build.Spec.Source.Git.URI}, |
... | ... |
@@ -289,6 +289,9 @@ func describeCustomStrategy(s *buildapi.CustomBuildStrategy, out *tabwriter.Writ |
289 | 289 |
if s.ExposeDockerSocket { |
290 | 290 |
formatString(out, "Expose Docker Socket", "yes") |
291 | 291 |
} |
292 |
+ if s.ForcePull { |
|
293 |
+ formatString(out, "Force Pull", "yes") |
|
294 |
+ } |
|
292 | 295 |
if s.PullSecret != nil { |
293 | 296 |
formatString(out, "Pull Secret Name", s.PullSecret.Name) |
294 | 297 |
} |