Skip to content

Commit a418956

Browse files
committed
api: apply sysctl adjustments
Signed-off-by: Samuel Karp <[email protected]>
1 parent 8705f9b commit a418956

5 files changed

Lines changed: 120 additions & 0 deletions

File tree

pkg/adaptation/result.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,9 @@ func (r *result) adjust(rpl *ContainerAdjustment, plugin string) error {
235235
if err := r.adjustNamespaces(rpl.Linux.Namespaces, plugin); err != nil {
236236
return err
237237
}
238+
if err := r.adjustSysctl(rpl.Linux.Sysctl, plugin); err != nil {
239+
return err
240+
}
238241
}
239242
if err := r.adjustRlimits(rpl.Rlimits, plugin); err != nil {
240243
return err
@@ -451,6 +454,41 @@ func (r *result) adjustNamespaces(namespaces []*LinuxNamespace, plugin string) e
451454
return nil
452455
}
453456

457+
func (r *result) adjustSysctl(sysctl map[string]string, plugin string) error {
458+
if len(sysctl) == 0 {
459+
return nil
460+
}
461+
462+
create, id := r.request.create, r.request.create.Container.Id
463+
del := map[string]struct{}{}
464+
for k := range sysctl {
465+
if key, marked := IsMarkedForRemoval(k); marked {
466+
del[key] = struct{}{}
467+
delete(sysctl, k)
468+
}
469+
}
470+
471+
for k, v := range sysctl {
472+
if _, ok := del[k]; ok {
473+
r.owners.ClearSysctl(id, k, plugin)
474+
delete(create.Container.Linux.Sysctl, k)
475+
r.reply.adjust.Linux.Sysctl[MarkForRemoval(k)] = ""
476+
}
477+
if err := r.owners.ClaimSysctl(id, k, plugin); err != nil {
478+
return err
479+
}
480+
create.Container.Linux.Sysctl[k] = v
481+
r.reply.adjust.Linux.Sysctl[k] = v
482+
delete(del, k)
483+
}
484+
485+
for k := range del {
486+
r.reply.adjust.Annotations[MarkForRemoval(k)] = ""
487+
}
488+
489+
return nil
490+
}
491+
454492
func (r *result) adjustCDIDevices(devices []*CDIDevice, plugin string) error {
455493
if len(devices) == 0 {
456494
return nil

pkg/api/adjustment.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,15 @@ func (a *ContainerAdjustment) SetLinuxSeccompPolicy(seccomp *LinuxSeccomp) {
310310
a.Linux.SeccompPolicy = seccomp
311311
}
312312

313+
// SetLinuxSysctl records setting a sysctl for a container.
314+
func (a *ContainerAdjustment) SetLinuxSysctl(key, value string) {
315+
a.initLinux()
316+
if a.Linux.Sysctl == nil {
317+
a.Linux.Sysctl = make(map[string]string)
318+
}
319+
a.Linux.Sysctl[key] = value
320+
}
321+
313322
//
314323
// Initializing a container adjustment and container update.
315324
//

pkg/api/owners.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,10 @@ func (o *OwningPlugins) ClaimSeccompPolicy(id, plugin string) error {
172172
return o.mustOwnersFor(id).ClaimSeccompPolicy(plugin)
173173
}
174174

175+
func (o *OwningPlugins) ClaimSysctl(id, key, plugin string) error {
176+
return o.mustOwnersFor(id).ClaimSysctl(key, plugin)
177+
}
178+
175179
func (o *OwningPlugins) ClearAnnotation(id, key, plugin string) {
176180
o.mustOwnersFor(id).ClearAnnotation(key, plugin)
177181
}
@@ -192,6 +196,10 @@ func (o *OwningPlugins) ClearArgs(id, plugin string) {
192196
o.mustOwnersFor(id).ClearArgs(plugin)
193197
}
194198

199+
func (o *OwningPlugins) ClearSysctl(id, key, plugin string) {
200+
o.mustOwnersFor(id).ClearSysctl(key, plugin)
201+
}
202+
195203
func (o *OwningPlugins) AnnotationOwner(id, key string) (string, bool) {
196204
return o.ownersFor(id).compoundOwner(Field_Annotations.Key(), key)
197205
}
@@ -324,6 +332,10 @@ func (o *OwningPlugins) SeccompPolicyOwner(id string) (string, bool) {
324332
return o.ownersFor(id).simpleOwner(Field_SeccompPolicy.Key())
325333
}
326334

335+
func (o *OwningPlugins) SysctlOwner(id, key string) (string, bool) {
336+
return o.ownersFor(id).compoundOwner(Field_Sysctl.Key(), key)
337+
}
338+
327339
func (o *OwningPlugins) mustOwnersFor(id string) *FieldOwners {
328340
f, ok := o.Owners[id]
329341
if !ok {
@@ -546,6 +558,10 @@ func (f *FieldOwners) ClaimSeccompPolicy(plugin string) error {
546558
return f.claimSimple(Field_SeccompPolicy.Key(), plugin)
547559
}
548560

561+
func (f *FieldOwners) ClaimSysctl(key, plugin string) error {
562+
return f.claimCompound(Field_Sysctl.Key(), key, plugin)
563+
}
564+
549565
func (f *FieldOwners) clearCompound(field int32, key, plugin string) {
550566
m, ok := f.Compound[field]
551567
if !ok {
@@ -580,6 +596,10 @@ func (f *FieldOwners) ClearArgs(plugin string) {
580596
f.clearSimple(Field_Args.Key(), plugin)
581597
}
582598

599+
func (f *FieldOwners) ClearSysctl(key, plugin string) {
600+
f.clearCompound(Field_Sysctl.Key(), key, plugin)
601+
}
602+
583603
func (f *FieldOwners) Conflict(field int32, plugin, other string, qualifiers ...string) error {
584604
return fmt.Errorf("plugins %q and %q both tried to set %s",
585605
plugin, other, qualify(field, qualifiers...))

pkg/runtime-tools/generate/generate.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,15 @@ type UnderlyingGenerator interface {
4747
AddLinuxResourcesHugepageLimit(pageSize string, limit uint64)
4848
AddLinuxResourcesUnified(key, val string)
4949
AddMount(mnt rspec.Mount)
50+
AddLinuxSysctl(key, value string)
5051
ClearMounts()
5152
ClearProcessEnv()
5253
Mounts() []rspec.Mount
5354
RemoveAnnotation(key string)
5455
RemoveDevice(path string)
5556
RemoveLinuxNamespace(ns string) error
5657
RemoveMount(dest string)
58+
RemoveLinuxSysctl(key string)
5759
SetProcessArgs(args []string)
5860
SetLinuxCgroupsPath(path string)
5961
SetLinuxResourcesCPUCpus(cpus string)
@@ -80,6 +82,7 @@ type Generator struct {
8082
Config *rspec.Spec
8183
filterLabels func(map[string]string) (map[string]string, error)
8284
filterAnnotations func(map[string]string) (map[string]string, error)
85+
filterSysctl func(map[string]string) (map[string]string, error)
8386
resolveBlockIO func(string) (*rspec.LinuxBlockIO, error)
8487
resolveRdt func(string) (*rspec.LinuxIntelRdt, error)
8588
injectCDIDevices func(*rspec.Spec, []string) error
@@ -94,6 +97,7 @@ func SpecGenerator(gg UnderlyingGenerator, opts ...GeneratorOption) *Generator {
9497
}
9598
g.filterLabels = nopFilter
9699
g.filterAnnotations = nopFilter
100+
g.filterSysctl = nopFilter
97101
for _, o := range opts {
98102
o(g)
99103
}
@@ -169,6 +173,9 @@ func (g *Generator) Adjust(adjust *nri.ContainerAdjustment) error {
169173
if err := g.AdjustNamespaces(adjust.GetLinux().GetNamespaces()); err != nil {
170174
return err
171175
}
176+
if err := g.AdjustSysctl(adjust.GetLinux().GetSysctl()); err != nil {
177+
return err
178+
}
172179

173180
resources := adjust.GetLinux().GetResources()
174181
if err := g.AdjustResources(resources); err != nil {
@@ -457,6 +464,24 @@ func (g *Generator) AdjustNamespaces(namespaces []*nri.LinuxNamespace) error {
457464
return nil
458465
}
459466

467+
// AdjustSysctl adds, replaces, or removes the sysctl settings in the OCI Spec.
468+
func (g *Generator) AdjustSysctl(sysctl map[string]string) error {
469+
var err error
470+
471+
if sysctl, err = g.filterSysctl(sysctl); err != nil {
472+
return err
473+
}
474+
for k, v := range sysctl {
475+
if key, marked := nri.IsMarkedForRemoval(k); marked {
476+
g.RemoveLinuxSysctl(key)
477+
} else {
478+
g.AddLinuxSysctl(k, v)
479+
}
480+
}
481+
482+
return nil
483+
}
484+
460485
// AdjustDevices adjusts the (Linux) devices in the OCI Spec.
461486
func (g *Generator) AdjustDevices(devices []*nri.LinuxDevice) {
462487
for _, d := range devices {

pkg/runtime-tools/generate/generate_suite_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,34 @@ var _ = Describe("Adjustment", func() {
429429
})
430430
})
431431

432+
When("has a sysctl adjustment", func() {
433+
It("adjusts Spec correctly", func() {
434+
var (
435+
spec = makeSpec()
436+
adjust = &api.ContainerAdjustment{
437+
Linux: &api.LinuxContainerAdjustment{
438+
Sysctl: map[string]string{
439+
"net.ipv4.ip_forward": "1",
440+
api.MarkForRemoval("delete.me"): "",
441+
},
442+
},
443+
}
444+
)
445+
spec.Linux.Sysctl = map[string]string{
446+
"delete.me": "foobar",
447+
}
448+
rg := &rgen.Generator{Config: spec}
449+
xg := xgen.SpecGenerator(rg)
450+
451+
Expect(xg).ToNot(BeNil())
452+
Expect(xg.Adjust(adjust)).To(Succeed())
453+
Expect(spec.Linux.Sysctl).To(Equal(map[string]string{
454+
"net.ipv4.ip_forward": "1",
455+
}))
456+
457+
})
458+
})
459+
432460
})
433461

434462
type specOption func(*rspec.Spec)

0 commit comments

Comments
 (0)