capabilities.go 2.01 KB
Newer Older
songlinfeng's avatar
songlinfeng committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/**
# Copyright (c) 2024, HCUOpt CORPORATION.  All rights reserved.
**/

package modifier

import (
	"dtk-container-toolkit/internal/logger"
	"dtk-container-toolkit/internal/oci"

	"github.com/opencontainers/runtime-spec/specs-go"
)

func NewCapModifier(logger logger.Interface, toAddCaps []string, toRemoveCaps []string) oci.SpecModifier {
	return &capModifier{
		logger:       logger,
		toAddCaps:    toAddCaps,
		toRemoveCaps: toRemoveCaps,
	}
}

type capModifier struct {
	logger       logger.Interface
	toAddCaps    []string
	toRemoveCaps []string
}

var _ oci.SpecModifier = (*capModifier)(nil)

func (m *capModifier) Modify(spec *specs.Spec) error {
	if spec == nil || spec.Process == nil || spec.Process.Capabilities == nil {
		return nil
	}

	bounding := spec.Process.Capabilities.Bounding
	effective := spec.Process.Capabilities.Effective
	permitted := spec.Process.Capabilities.Permitted

	if len(m.toAddCaps) != 0 {
		for _, cap := range m.toAddCaps {
			bounding = append(bounding, cap)
			effective = append(effective, cap)
			permitted = append(permitted, cap)
		}
		bounding = unqiueCaps(bounding)
		effective = unqiueCaps(effective)
		permitted = unqiueCaps(permitted)
	}

	if len(m.toRemoveCaps) != 0 {
		bounding = removeCaps(bounding, m.toRemoveCaps)
		effective = removeCaps(effective, m.toRemoveCaps)
		permitted = removeCaps(permitted, m.toRemoveCaps)
	}

	spec.Process.Capabilities.Bounding = bounding
	spec.Process.Capabilities.Effective = effective
	spec.Process.Capabilities.Permitted = permitted

	return nil
}

func unqiueCaps(caps []string) []string {
	var uCaps []string

	mCaps := make(map[string]bool)

	for _, v := range caps {
		if _, ok := mCaps[v]; !ok {
			mCaps[v] = true
			uCaps = append(uCaps, v)
		}
	}

	return uCaps
}

func removeCaps(orgCaps []string, reCaps []string) []string {
	toRemove := make(map[string]bool)
	for _, cap := range reCaps {
		toRemove[cap] = true
	}

	var caps []string
	for _, v := range orgCaps {
		if _, ok := toRemove[v]; ok {
			continue
		}
		caps = append(caps, v)
	}

	return caps
}