Skip to content

Commit ce6c548

Browse files
Update Origin admission controllers to handle init containers
1 parent 8e37516 commit ce6c548

File tree

6 files changed

+105
-44
lines changed

6 files changed

+105
-44
lines changed

pkg/build/admission/overrides/admission.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ func applyForcePullToPod(attributes admission.Attributes) error {
9191
if err != nil {
9292
return err
9393
}
94+
for i := range pod.Spec.InitContainers {
95+
glog.V(5).Infof("Setting ImagePullPolicy to PullAlways on init container %s of pod %s/%s", pod.Spec.InitContainers[i].Name, pod.Namespace, pod.Name)
96+
pod.Spec.InitContainers[i].ImagePullPolicy = kapi.PullAlways
97+
}
9498
for i := range pod.Spec.Containers {
9599
glog.V(5).Infof("Setting ImagePullPolicy to PullAlways on container %s of pod %s/%s", pod.Spec.Containers[i].Name, pod.Namespace, pod.Name)
96100
pod.Spec.Containers[i].ImagePullPolicy = kapi.PullAlways

pkg/build/admission/overrides/admission_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ func TestBuildOverrideForcePull(t *testing.T) {
5151
if pod.Spec.Containers[0].ImagePullPolicy != kapi.PullAlways {
5252
t.Errorf("%s (%s): image pull policy is not PullAlways", test.name, op)
5353
}
54+
if pod.Spec.InitContainers[0].ImagePullPolicy != kapi.PullAlways {
55+
t.Errorf("%s (%s): image pull policy is not PullAlways", test.name, op)
56+
}
5457
case strategy.DockerStrategy != nil:
5558
if strategy.DockerStrategy.ForcePull == false {
5659
t.Errorf("%s (%s): force pull was false", test.name, op)

pkg/build/admission/testutil/pod.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,13 @@ func (p *TestPod) WithAnnotation(name, value string) *TestPod {
2626
}
2727

2828
func (p *TestPod) WithEnvVar(name, value string) *TestPod {
29+
if len(p.Spec.InitContainers) == 0 {
30+
p.Spec.InitContainers = append(p.Spec.InitContainers, kapi.Container{})
31+
}
2932
if len(p.Spec.Containers) == 0 {
3033
p.Spec.Containers = append(p.Spec.Containers, kapi.Container{})
3134
}
35+
p.Spec.InitContainers[0].Env = append(p.Spec.InitContainers[0].Env, kapi.EnvVar{Name: name, Value: value})
3236
p.Spec.Containers[0].Env = append(p.Spec.Containers[0].Env, kapi.EnvVar{Name: name, Value: value})
3337
return p
3438
}
@@ -46,6 +50,18 @@ func (p *TestPod) WithBuild(t *testing.T, build *buildapi.Build, version string)
4650
return p.WithAnnotation(buildapi.BuildAnnotation, build.Name).WithEnvVar("BUILD", string(encodedBuild))
4751
}
4852

53+
func (p *TestPod) InitEnvValue(name string) string {
54+
if len(p.Spec.InitContainers) == 0 {
55+
return ""
56+
}
57+
for _, ev := range p.Spec.InitContainers[0].Env {
58+
if ev.Name == name {
59+
return ev.Value
60+
}
61+
}
62+
return ""
63+
}
64+
4965
func (p *TestPod) EnvValue(name string) string {
5066
if len(p.Spec.Containers) == 0 {
5167
return ""

pkg/quota/admission/clusterresourceoverride/admission.go

Lines changed: 49 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -155,54 +155,61 @@ func (a *clusterResourceOverridePlugin) Admit(attr admission.Attributes) error {
155155

156156
// Reuse LimitRanger logic to apply limit/req defaults from the project. Ignore validation
157157
// errors, assume that LimitRanger will run after this plugin to validate.
158-
glog.V(5).Infof("%s: initial pod limits are: %#v", api.PluginName, pod.Spec.Containers[0].Resources)
158+
glog.V(5).Infof("%s: initial pod limits are: %#v", api.PluginName, pod.Spec)
159159
if err := a.LimitRanger.Admit(attr); err != nil {
160160
glog.V(5).Infof("%s: error from LimitRanger: %#v", api.PluginName, err)
161161
}
162-
glog.V(5).Infof("%s: pod limits after LimitRanger are: %#v", api.PluginName, pod.Spec.Containers[0].Resources)
163-
for _, container := range pod.Spec.Containers {
164-
resources := container.Resources
165-
memLimit, memFound := resources.Limits[kapi.ResourceMemory]
166-
if memFound && a.config.memoryRequestToLimitRatio != 0 {
167-
// memory is measured in whole bytes.
168-
// the plugin rounds down to the nearest MiB rather than bytes to improve ease of use for end-users.
169-
amount := memLimit.Value() * int64(a.config.memoryRequestToLimitRatio*100) / 100
170-
// TODO: move into resource.Quantity
171-
var mod int64
172-
switch memLimit.Format {
173-
case resource.BinarySI:
174-
mod = 1024 * 1024
175-
default:
176-
mod = 1000 * 1000
177-
}
178-
if rem := amount % mod; rem != 0 {
179-
amount = amount - rem
180-
}
181-
q := resource.NewQuantity(int64(amount), memLimit.Format)
182-
if memFloor.Cmp(*q) > 0 {
183-
q = memFloor.Copy()
184-
}
185-
resources.Requests[kapi.ResourceMemory] = *q
162+
for i := range pod.Spec.InitContainers {
163+
updateContainerResources(a.config, &pod.Spec.InitContainers[i])
164+
}
165+
for i := range pod.Spec.Containers {
166+
updateContainerResources(a.config, &pod.Spec.Containers[i])
167+
}
168+
glog.V(5).Infof("%s: pod limits after overrides are: %#v", api.PluginName, pod.Spec)
169+
return nil
170+
}
171+
172+
func updateContainerResources(config *internalConfig, container *kapi.Container) {
173+
resources := container.Resources
174+
memLimit, memFound := resources.Limits[kapi.ResourceMemory]
175+
if memFound && config.memoryRequestToLimitRatio != 0 {
176+
// memory is measured in whole bytes.
177+
// the plugin rounds down to the nearest MiB rather than bytes to improve ease of use for end-users.
178+
amount := memLimit.Value() * int64(config.memoryRequestToLimitRatio*100) / 100
179+
// TODO: move into resource.Quantity
180+
var mod int64
181+
switch memLimit.Format {
182+
case resource.BinarySI:
183+
mod = 1024 * 1024
184+
default:
185+
mod = 1000 * 1000
186+
}
187+
if rem := amount % mod; rem != 0 {
188+
amount = amount - rem
186189
}
187-
if memFound && a.config.limitCPUToMemoryRatio != 0 {
188-
amount := float64(memLimit.Value()) * a.config.limitCPUToMemoryRatio * cpuBaseScaleFactor
189-
q := resource.NewMilliQuantity(int64(amount), resource.DecimalSI)
190-
if cpuFloor.Cmp(*q) > 0 {
191-
q = cpuFloor.Copy()
192-
}
193-
resources.Limits[kapi.ResourceCPU] = *q
190+
q := resource.NewQuantity(int64(amount), memLimit.Format)
191+
if memFloor.Cmp(*q) > 0 {
192+
q = memFloor.Copy()
194193
}
194+
resources.Requests[kapi.ResourceMemory] = *q
195+
}
196+
if memFound && config.limitCPUToMemoryRatio != 0 {
197+
amount := float64(memLimit.Value()) * config.limitCPUToMemoryRatio * cpuBaseScaleFactor
198+
q := resource.NewMilliQuantity(int64(amount), resource.DecimalSI)
199+
if cpuFloor.Cmp(*q) > 0 {
200+
q = cpuFloor.Copy()
201+
}
202+
resources.Limits[kapi.ResourceCPU] = *q
203+
}
195204

196-
cpuLimit, cpuFound := resources.Limits[kapi.ResourceCPU]
197-
if cpuFound && a.config.cpuRequestToLimitRatio != 0 {
198-
amount := float64(cpuLimit.MilliValue()) * a.config.cpuRequestToLimitRatio
199-
q := resource.NewMilliQuantity(int64(amount), cpuLimit.Format)
200-
if cpuFloor.Cmp(*q) > 0 {
201-
q = cpuFloor.Copy()
202-
}
203-
resources.Requests[kapi.ResourceCPU] = *q
205+
cpuLimit, cpuFound := resources.Limits[kapi.ResourceCPU]
206+
if cpuFound && config.cpuRequestToLimitRatio != 0 {
207+
amount := float64(cpuLimit.MilliValue()) * config.cpuRequestToLimitRatio
208+
q := resource.NewMilliQuantity(int64(amount), cpuLimit.Format)
209+
if cpuFloor.Cmp(*q) > 0 {
210+
q = cpuFloor.Copy()
204211
}
212+
resources.Requests[kapi.ResourceCPU] = *q
205213
}
206-
glog.V(5).Infof("%s: pod limits after overrides are: %#v", api.PluginName, pod.Spec.Containers[0].Resources)
207-
return nil
214+
208215
}

pkg/quota/admission/clusterresourceoverride/admission_test.go

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,18 @@ func TestLimitRequestAdmission(t *testing.T) {
225225
t.Errorf("%s: admission controller returned error: %v", test.name, err)
226226
continue
227227
}
228-
resources := test.pod.Spec.Containers[0].Resources // only test one container
228+
resources := test.pod.Spec.InitContainers[0].Resources // only test one container
229+
if actual := resources.Requests[kapi.ResourceMemory]; test.expectedMemRequest.Cmp(actual) != 0 {
230+
t.Errorf("%s: memory requests do not match; %v should be %v", test.name, actual, test.expectedMemRequest)
231+
}
232+
if actual := resources.Requests[kapi.ResourceCPU]; test.expectedCpuRequest.Cmp(actual) != 0 {
233+
t.Errorf("%s: cpu requests do not match; %v should be %v", test.name, actual, test.expectedCpuRequest)
234+
}
235+
if actual := resources.Limits[kapi.ResourceCPU]; test.expectedCpuLimit.Cmp(actual) != 0 {
236+
t.Errorf("%s: cpu limits do not match; %v should be %v", test.name, actual, test.expectedCpuLimit)
237+
}
238+
239+
resources = test.pod.Spec.Containers[0].Resources // only test one container
229240
if actual := resources.Requests[kapi.ResourceMemory]; test.expectedMemRequest.Cmp(actual) != 0 {
230241
t.Errorf("%s: memory requests do not match; %v should be %v", test.name, actual, test.expectedMemRequest)
231242
}
@@ -241,6 +252,11 @@ func TestLimitRequestAdmission(t *testing.T) {
241252
func testBestEffortPod() *kapi.Pod {
242253
return &kapi.Pod{
243254
Spec: kapi.PodSpec{
255+
InitContainers: []kapi.Container{
256+
{
257+
Resources: kapi.ResourceRequirements{},
258+
},
259+
},
244260
Containers: []kapi.Container{
245261
{
246262
Resources: kapi.ResourceRequirements{},
@@ -253,6 +269,20 @@ func testBestEffortPod() *kapi.Pod {
253269
func testPod(memLimit string, memRequest string, cpuLimit string, cpuRequest string) *kapi.Pod {
254270
return &kapi.Pod{
255271
Spec: kapi.PodSpec{
272+
InitContainers: []kapi.Container{
273+
{
274+
Resources: kapi.ResourceRequirements{
275+
Limits: kapi.ResourceList{
276+
kapi.ResourceCPU: resource.MustParse(cpuLimit),
277+
kapi.ResourceMemory: resource.MustParse(memLimit),
278+
},
279+
Requests: kapi.ResourceList{
280+
kapi.ResourceCPU: resource.MustParse(cpuRequest),
281+
kapi.ResourceMemory: resource.MustParse(memRequest),
282+
},
283+
},
284+
},
285+
},
256286
Containers: []kapi.Container{
257287
{
258288
Resources: kapi.ResourceRequirements{

test/extended/setup.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ function os::test::extended::setup {
3434
if [[ -z $(os::build::find-binary openshift) ]]; then
3535
hack/build-go.sh
3636
fi
37-
37+
3838
os::util::environment::setup_time_vars
3939

4040
# ensure proper relative directories are set
@@ -228,6 +228,7 @@ readonly CONFORMANCE_TESTS=(
228228
"\[volumes\] Test local storage quota FSGroup"
229229
"test deployment should run a deployment to completion"
230230
"Variable Expansion"
231+
"init containers"
231232
"Clean up pods on node kubelet"
232233
"\[Feature\:SecurityContext\]"
233234
"should create a LimitRange with defaults"

0 commit comments

Comments
 (0)