Skip to content

Commit 56b744d

Browse files
authored
refactor: fuse sidecar serverless platform (#4816)
* Stage to use `serverless.fluid.io/platform` to indicate serverless platform Signed-off-by: trafalgarzzz <trafalgarz@outlook.com> * Refactor `matchedKey` and `matchedValue` to a more common utility function Signed-off-by: trafalgarzzz <trafalgarz@outlook.com> * Add unit tests for `KeyMatched` and `KeyValueMatched` Signed-off-by: trafalgarzzz <trafalgarz@outlook.com> * Remove unprivileged sidecar option Signed-off-by: trafalgarzzz <trafalgarz@outlook.com> * Refactor annotaions Signed-off-by: trafalgarzzz <trafalgarz@outlook.com> * Refactor annotaions Signed-off-by: trafalgarzzz <trafalgarz@outlook.com> * Add unit tests Signed-off-by: trafalgarzzz <trafalgarz@outlook.com> * go fmt Signed-off-by: trafalgarzzz <trafalgarz@outlook.com> * lower platform string Signed-off-by: trafalgarzzz <trafalgarz@outlook.com> * Rename `PlatformDefault` and `PlatformUnprivileged` Signed-off-by: trafalgarzzz <trafalgarz@outlook.com> --------- Signed-off-by: trafalgarzzz <trafalgarz@outlook.com>
1 parent e617c95 commit 56b744d

11 files changed

Lines changed: 327 additions & 204 deletions

File tree

pkg/application/inject/fuse/injector.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -162,9 +162,9 @@ func (s *Injector) inject(in runtime.Object, runtimeInfos map[string]base.Runtim
162162
continue
163163
}
164164

165-
platform := s.getServerlessPlatformFromMeta(podSpecs.MetaObj)
166-
if len(platform) == 0 {
167-
return out, fmt.Errorf("can't find any supported platform-specific mutator in pod's metadata")
165+
platform, err := s.getServerlessPlatformFromMeta(podSpecs.MetaObj)
166+
if err != nil {
167+
return out, fmt.Errorf("fail to get serverless platform from pod's meta: %v", err)
168168
}
169169

170170
mutatorBuildArgs := mutator.MutatorBuildArgs{
@@ -173,7 +173,6 @@ func (s *Injector) inject(in runtime.Object, runtimeInfos map[string]base.Runtim
173173
Specs: podSpecs,
174174
Options: common.FuseSidecarInjectOption{
175175
EnableCacheDir: utils.InjectCacheDirEnabled(podSpecs.MetaObj.Labels),
176-
EnableUnprivilegedSidecar: utils.FuseSidecarUnprivileged(podSpecs.MetaObj.Labels),
177176
SkipSidecarPostStartInject: utils.SkipSidecarPostStartInject(podSpecs.MetaObj.Labels),
178177
},
179178
ExtraArgs: mutator.FindExtraArgsFromMetadata(podSpecs.MetaObj, platform),
@@ -257,6 +256,6 @@ func (s *Injector) shouldInject(pod common.FluidObject) (should bool, err error)
257256
return should, nil
258257
}
259258

260-
func (s *Injector) getServerlessPlatformFromMeta(metaObj metav1.ObjectMeta) string {
261-
return utils.GetServerlessPlatform(metaObj.Labels)
259+
func (s *Injector) getServerlessPlatformFromMeta(metaObj metav1.ObjectMeta) (string, error) {
260+
return utils.GetServerlessPlatform(metaObj)
262261
}

pkg/application/inject/fuse/mutator/mutator.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ func (args MutatorBuildArgs) String() string {
5050
}
5151

5252
var mutatorBuildFn map[string]func(MutatorBuildArgs) Mutator = map[string]func(MutatorBuildArgs) Mutator{
53-
utils.PlatformDefault: NewDefaultMutator,
54-
utils.PlatformUnprivileged: NewUnprivilegedMutator,
53+
utils.ServerlessPlatformDefault: NewDefaultMutator,
54+
utils.ServerlessPlatformUnprivileged: NewUnprivilegedMutator,
5555
}
5656

5757
func BuildMutator(args MutatorBuildArgs, platform string) (Mutator, error) {

pkg/common/constants.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -197,10 +197,11 @@ const (
197197
)
198198

199199
const (
200-
EnvServerlessPlatformKey = "KEY_SERVERLESS_PLATFORM"
201-
EnvServerlessPlatformVal = "VALUE_SERVERLESS_PLATFORM"
202-
EnvDisableApplicationController = "KEY_DISABLE_APP_CONTROLLER"
203-
EnvImagePullSecretsKey = "IMAGE_PULL_SECRETS"
200+
// DEPRECATED: env variable for Fluid webhook to determine the serverless platform.
201+
// Use commmon.AnnotationServerlessPlatform instead.
202+
DeprecatedEnvServerlessPlatformKey = "KEY_SERVERLESS_PLATFORM"
203+
EnvDisableApplicationController = "KEY_DISABLE_APP_CONTROLLER"
204+
EnvImagePullSecretsKey = "IMAGE_PULL_SECRETS"
204205
)
205206

206207
const (

pkg/common/label.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,12 @@ const (
107107
AnnotationDataFlowCustomizedAffinityPrefix = "affinity.dataflow.fluid.io."
108108
)
109109

110+
const (
111+
// AnnotationServerlessPlatform is an annotation key name for the platform type of serverless.
112+
// i.e. serverless.fluid.io/platform
113+
AnnotationServerlessPlatform = "serverless." + LabelAnnotationPrefix + "platform"
114+
)
115+
110116
var (
111117
// LabelAnnotationPodSchedRegex is the fluid cache label for scheduling pod, format: 'fluid.io/dataset.{dataset name}.sched]'
112118
// use string literal to meet security check.

pkg/common/types.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,14 +169,12 @@ type FuseMountInfo struct {
169169
// FuseSidecarInjectOption are options for webhook to inject fuse sidecar containers
170170
type FuseSidecarInjectOption struct {
171171
EnableCacheDir bool
172-
EnableUnprivilegedSidecar bool
173172
SkipSidecarPostStartInject bool
174173
}
175174

176175
func (f FuseSidecarInjectOption) String() string {
177-
return fmt.Sprintf("EnableCacheDir=%v;EnableUnprivilegedSidecar=%v;SkipSidecarPostStartInject=%v",
176+
return fmt.Sprintf("EnableCacheDir=%v;SkipSidecarPostStartInject=%v",
178177
f.EnableCacheDir,
179-
f.EnableUnprivilegedSidecar,
180178
f.SkipSidecarPostStartInject)
181179
}
182180

pkg/ctrl/watch/pod.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ func ShouldInQueue(pod *corev1.Pod) bool {
104104
}
105105

106106
// ignore if it's not fluid label pod
107-
if !utils.FuseSidecarPrivileged(pod.Labels) {
107+
if !utils.FuseSidecarPrivileged(pod.ObjectMeta) {
108108
log.Info("Privileged fuse sidecar is not enabled.", "labels", pod.Labels)
109109
return false
110110
}

pkg/utils/annotations.go

Lines changed: 64 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -17,26 +17,25 @@ limitations under the License.
1717
package utils
1818

1919
import (
20+
"fmt"
2021
stdlog "log"
2122
"os"
2223

2324
"github.com/fluid-cloudnative/fluid/pkg/common"
25+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2426
)
2527

2628
var (
27-
ServerlessPlatformKey string = ""
28-
ServerlessPlatformVal string = ""
29-
disableApplicationController string = ""
29+
// DEPRECATED: the label key for Fluid webhook to determine serverless platform.
30+
// It's replaced by commmon.AnnotationServerlessPlatform.
31+
DeprecatedServerlessPlatformKey string = ""
32+
disableApplicationController string = ""
3033
)
3134

3235
func init() {
33-
if envVal, exists := os.LookupEnv(common.EnvServerlessPlatformKey); exists {
34-
ServerlessPlatformKey = envVal
35-
stdlog.Printf("Found %s value %s, using it as ServerlessPlatformLabelKey", common.EnvServerlessPlatformKey, envVal)
36-
}
37-
if envVal, exists := os.LookupEnv(common.EnvServerlessPlatformVal); exists {
38-
ServerlessPlatformVal = envVal
39-
stdlog.Printf("Found %s value %s, using it as ServerlessPlatformLabelValue", common.EnvServerlessPlatformVal, envVal)
36+
if envVal, exists := os.LookupEnv(common.DeprecatedEnvServerlessPlatformKey); exists {
37+
DeprecatedServerlessPlatformKey = envVal
38+
stdlog.Printf("Found %s value %s, using it as ServerlessPlatformLabelKey", common.DeprecatedEnvServerlessPlatformKey, envVal)
4039
}
4140
if envVal, exists := os.LookupEnv(common.EnvDisableApplicationController); exists {
4241
disableApplicationController = envVal
@@ -62,7 +61,7 @@ func InjectCacheDirEnabled(infos map[string]string) (match bool) {
6261
}
6362

6463
func SkipSidecarPostStartInject(infos map[string]string) (match bool) {
65-
return matchedValue(infos, common.InjectSidecarPostStart, common.False)
64+
return KeyValueMatched(infos, common.InjectSidecarPostStart, common.False)
6665
}
6766

6867
func AppContainerPostStartInjectEnabled(infos map[string]string) (match bool) {
@@ -71,62 +70,89 @@ func AppContainerPostStartInjectEnabled(infos map[string]string) (match bool) {
7170

7271
// ---- Utils functions to decide serverless platform ----
7372
const (
74-
PlatformDefault = "Default"
75-
PlatformUnprivileged = "Unprivileged"
73+
ServerlessPlatformDefault = "default"
74+
ServerlessPlatformUnprivileged = "unprivileged"
7675
)
7776

78-
func GetServerlessPlatform(infos map[string]string) (platform string) {
79-
if matchedKey(infos, ServerlessPlatformKey) {
80-
return infos[ServerlessPlatformKey]
77+
func GetServerlessPlatform(metaObj metav1.ObjectMeta) (platform string, err error) {
78+
metaLabels := metaObj.Labels
79+
metaAnnotations := metaObj.Annotations
80+
81+
// Setting both DeprecatedServerlessPlatformKey and common.InjectServerless is not allowed
82+
if KeyMatched(metaLabels, DeprecatedServerlessPlatformKey) && enabled(metaLabels, common.InjectServerless) {
83+
err = fmt.Errorf("\"%s\" and \"%s\" is not allowed to set together, remove \"%s\" and retry", DeprecatedServerlessPlatformKey, common.InjectServerless, DeprecatedServerlessPlatformKey)
84+
return
85+
}
86+
87+
// handle deprecated serverless platform key.
88+
if KeyMatched(metaLabels, DeprecatedServerlessPlatformKey) {
89+
platform = metaLabels[DeprecatedServerlessPlatformKey]
90+
return
8191
}
8292

83-
if enabled(infos, common.InjectServerless) || enabled(infos, common.InjectFuseSidecar) {
84-
if enabled(infos, common.InjectUnprivilegedFuseSidecar) {
85-
return PlatformUnprivileged
93+
// handle deprecated common.InjectFuseSidecar. In this case,
94+
// only two platforms are supported: PlatformDefault and PlatformUnprivileged
95+
if enabled(metaLabels, common.InjectFuseSidecar) {
96+
if enabled(metaLabels, common.InjectUnprivilegedFuseSidecar) {
97+
platform = ServerlessPlatformUnprivileged
8698
} else {
87-
return PlatformDefault
99+
platform = ServerlessPlatformDefault
100+
}
101+
return
102+
}
103+
104+
if enabled(metaLabels, common.InjectServerless) {
105+
if enabled(metaLabels, common.InjectUnprivilegedFuseSidecar) {
106+
platform = ServerlessPlatformUnprivileged
107+
return
108+
}
109+
110+
// Setting common.InjectServerless in labels and common.AnnotationServerlessPlatform in annotations
111+
// together to indicate the serverless platform
112+
if KeyMatched(metaAnnotations, common.AnnotationServerlessPlatform) {
113+
platform = metaAnnotations[common.AnnotationServerlessPlatform]
114+
return
88115
}
116+
117+
platform = ServerlessPlatformDefault
118+
return
89119
}
90120

91121
// default to an empty platform, meaning no platform is found
92-
return ""
122+
return "", fmt.Errorf("no serverless platform can be found from Pod's metadata")
93123
}
94124

95125
// ServerlessEnabled decides if fuse sidecar should be injected, whether privileged or unprivileged
96-
// - serverlessPlatform implies injecting unprivileged fuse sidecar
97-
// - serverless.fluid.io/inject=true implies injecting (privileged/unprivileged) fuse sidecar,
126+
// We don't have to know which serverless platform it is using here.
127+
// - serverless.fluid.io/inject=true implies injecting fuse sidecar.
128+
// - [deprecated] serverlessPlatform implies injecting fuse sidecar according to the deprecated env variable. It's deprecated by common.AnnotationServerlessPlatform.
98129
// - [deprecated] fuse.sidecar.fluid.io/inject=true is the deprecated version of serverless.fluid.io/inject=true
99130
func ServerlessEnabled(infos map[string]string) (match bool) {
100-
return serverlessPlatformMatched(infos) || enabled(infos, common.InjectServerless) || enabled(infos, common.InjectFuseSidecar)
101-
}
102-
103-
// FuseSidecarUnprivileged decides if the injected fuse sidecar should be unprivileged, only used when fuse sidecar should be injected
104-
// - serverlessPlatform implies injecting unprivileged fuse sidecar
105-
// - serverless.fluid.io/inject=true + unprivileged.sidecar.fluid.io/inject=true implies injecting unprivileged fuse sidecar,
106-
func FuseSidecarUnprivileged(infos map[string]string) (match bool) {
107-
return serverlessPlatformMatched(infos) || (ServerlessEnabled(infos) && enabled(infos, common.InjectUnprivilegedFuseSidecar))
131+
return enabled(infos, common.InjectServerless) || serverlessPlatformMatched(infos) || enabled(infos, common.InjectFuseSidecar)
108132
}
109133

110134
// FuseSidecarPrivileged decides if the injected fuse sidecar should be privileged, only used when fuse sidecar should be injected
111-
// - sidecar is privileged only when setting serverless.fluid.io/inject=true without unprivileged.sidecar.fluid.io/inject=true
112-
func FuseSidecarPrivileged(infos map[string]string) (match bool) {
113-
return enabled(infos, common.InjectServerless) && !(enabled(infos, common.InjectUnprivilegedFuseSidecar))
135+
// TODO: The func is used for Fluid App controller to determine if it's a pod should be watched. It could be better to use another way(e.g. a special label)to indicate this.
136+
func FuseSidecarPrivileged(metaObj metav1.ObjectMeta) (match bool) {
137+
// error can be ignored here because platform equals to "" when error is not nil
138+
platform, _ := GetServerlessPlatform(metaObj)
139+
return platform == ServerlessPlatformDefault
114140
}
115141

116142
func InjectSidecarDone(infos map[string]string) (match bool) {
117143
return enabled(infos, common.InjectSidecarDone)
118144
}
119145

120146
func AppControllerDisabled(info map[string]string) (match bool) {
121-
return matchedKey(info, disableApplicationController)
147+
return KeyMatched(info, disableApplicationController)
122148
}
123149

124150
func serverlessPlatformMatched(infos map[string]string) (match bool) {
125-
if len(ServerlessPlatformKey) == 0 {
151+
if len(DeprecatedServerlessPlatformKey) == 0 {
126152
return
127153
}
128154

129-
return matchedKey(infos, ServerlessPlatformKey)
155+
return KeyMatched(infos, DeprecatedServerlessPlatformKey)
130156
}
131157

132158
func SkipPrecheckEnable(infos map[string]string) (match bool) {
@@ -135,27 +161,5 @@ func SkipPrecheckEnable(infos map[string]string) (match bool) {
135161

136162
// enabled checks if the given name has a value of "true"
137163
func enabled(infos map[string]string, name string) (match bool) {
138-
return matchedValue(infos, name, common.True)
139-
}
140-
141-
// matchedValue checks if the given name has the expected value
142-
func matchedValue(infos map[string]string, name string, val string) (match bool) {
143-
for key, value := range infos {
144-
if key == name && value == val {
145-
match = true
146-
break
147-
}
148-
}
149-
return
150-
}
151-
152-
// matchedKey checks if the given name exists
153-
func matchedKey(infos map[string]string, name string) (match bool) {
154-
for key := range infos {
155-
if key == name {
156-
match = true
157-
break
158-
}
159-
}
160-
return
164+
return KeyValueMatched(infos, name, common.True)
161165
}

0 commit comments

Comments
 (0)