dedup GetPassthroughAnnotations
Signed-off-by: Jin Dong <djdongjin95@gmail.com>
This commit is contained in:
		| @@ -795,12 +795,12 @@ func (c *criService) buildLinuxSpec( | |||||||
| 		specOpts = append(specOpts, oci.WithRdt(rdtClass, "", "")) | 		specOpts = append(specOpts, oci.WithRdt(rdtClass, "", "")) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	for pKey, pValue := range getPassthroughAnnotations(sandboxConfig.Annotations, | 	for pKey, pValue := range util.GetPassthroughAnnotations(sandboxConfig.Annotations, | ||||||
| 		ociRuntime.PodAnnotations) { | 		ociRuntime.PodAnnotations) { | ||||||
| 		specOpts = append(specOpts, customopts.WithAnnotation(pKey, pValue)) | 		specOpts = append(specOpts, customopts.WithAnnotation(pKey, pValue)) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	for pKey, pValue := range getPassthroughAnnotations(config.Annotations, | 	for pKey, pValue := range util.GetPassthroughAnnotations(config.Annotations, | ||||||
| 		ociRuntime.ContainerAnnotations) { | 		ociRuntime.ContainerAnnotations) { | ||||||
| 		specOpts = append(specOpts, customopts.WithAnnotation(pKey, pValue)) | 		specOpts = append(specOpts, customopts.WithAnnotation(pKey, pValue)) | ||||||
| 	} | 	} | ||||||
| @@ -930,12 +930,12 @@ func (c *criService) buildWindowsSpec( | |||||||
| 	// when trying to run the init process. | 	// when trying to run the init process. | ||||||
| 	specOpts = append(specOpts, oci.WithUser(username)) | 	specOpts = append(specOpts, oci.WithUser(username)) | ||||||
|  |  | ||||||
| 	for pKey, pValue := range getPassthroughAnnotations(sandboxConfig.Annotations, | 	for pKey, pValue := range util.GetPassthroughAnnotations(sandboxConfig.Annotations, | ||||||
| 		ociRuntime.PodAnnotations) { | 		ociRuntime.PodAnnotations) { | ||||||
| 		specOpts = append(specOpts, customopts.WithAnnotation(pKey, pValue)) | 		specOpts = append(specOpts, customopts.WithAnnotation(pKey, pValue)) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	for pKey, pValue := range getPassthroughAnnotations(config.Annotations, | 	for pKey, pValue := range util.GetPassthroughAnnotations(config.Annotations, | ||||||
| 		ociRuntime.ContainerAnnotations) { | 		ociRuntime.ContainerAnnotations) { | ||||||
| 		specOpts = append(specOpts, customopts.WithAnnotation(pKey, pValue)) | 		specOpts = append(specOpts, customopts.WithAnnotation(pKey, pValue)) | ||||||
| 	} | 	} | ||||||
| @@ -982,12 +982,12 @@ func (c *criService) buildDarwinSpec( | |||||||
|  |  | ||||||
| 	specOpts = append(specOpts, customopts.WithDarwinMounts(c.os, config, extraMounts)) | 	specOpts = append(specOpts, customopts.WithDarwinMounts(c.os, config, extraMounts)) | ||||||
|  |  | ||||||
| 	for pKey, pValue := range getPassthroughAnnotations(sandboxConfig.Annotations, | 	for pKey, pValue := range util.GetPassthroughAnnotations(sandboxConfig.Annotations, | ||||||
| 		ociRuntime.PodAnnotations) { | 		ociRuntime.PodAnnotations) { | ||||||
| 		specOpts = append(specOpts, customopts.WithAnnotation(pKey, pValue)) | 		specOpts = append(specOpts, customopts.WithAnnotation(pKey, pValue)) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	for pKey, pValue := range getPassthroughAnnotations(config.Annotations, | 	for pKey, pValue := range util.GetPassthroughAnnotations(config.Annotations, | ||||||
| 		ociRuntime.ContainerAnnotations) { | 		ociRuntime.ContainerAnnotations) { | ||||||
| 		specOpts = append(specOpts, customopts.WithAnnotation(pKey, pValue)) | 		specOpts = append(specOpts, customopts.WithAnnotation(pKey, pValue)) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -273,25 +273,6 @@ func unknownContainerStatus() containerstore.Status { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| // getPassthroughAnnotations filters requested pod annotations by comparing |  | ||||||
| // against permitted annotations for the given runtime. |  | ||||||
| func getPassthroughAnnotations(podAnnotations map[string]string, |  | ||||||
| 	runtimePodAnnotations []string) (passthroughAnnotations map[string]string) { |  | ||||||
| 	passthroughAnnotations = make(map[string]string) |  | ||||||
|  |  | ||||||
| 	for podAnnotationKey, podAnnotationValue := range podAnnotations { |  | ||||||
| 		for _, pattern := range runtimePodAnnotations { |  | ||||||
| 			// Use path.Match instead of filepath.Match here. |  | ||||||
| 			// filepath.Match treated `\\` as path separator |  | ||||||
| 			// on windows, which is not what we want. |  | ||||||
| 			if ok, _ := path.Match(pattern, podAnnotationKey); ok { |  | ||||||
| 				passthroughAnnotations[podAnnotationKey] = podAnnotationValue |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return passthroughAnnotations |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // copyResourcesToStatus copys container resource contraints from spec to | // copyResourcesToStatus copys container resource contraints from spec to | ||||||
| // container status. | // container status. | ||||||
| // This will need updates when new fields are added to ContainerResources. | // This will need updates when new fields are added to ContainerResources. | ||||||
|   | |||||||
| @@ -262,121 +262,6 @@ func TestEnvDeduplication(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestPassThroughAnnotationsFilter(t *testing.T) { |  | ||||||
| 	for _, test := range []struct { |  | ||||||
| 		desc                   string |  | ||||||
| 		podAnnotations         map[string]string |  | ||||||
| 		runtimePodAnnotations  []string |  | ||||||
| 		passthroughAnnotations map[string]string |  | ||||||
| 	}{ |  | ||||||
| 		{ |  | ||||||
| 			desc:                   "should support direct match", |  | ||||||
| 			podAnnotations:         map[string]string{"c": "d", "d": "e"}, |  | ||||||
| 			runtimePodAnnotations:  []string{"c"}, |  | ||||||
| 			passthroughAnnotations: map[string]string{"c": "d"}, |  | ||||||
| 		}, |  | ||||||
| 		{ |  | ||||||
| 			desc: "should support wildcard match", |  | ||||||
| 			podAnnotations: map[string]string{ |  | ||||||
| 				"t.f":  "j", |  | ||||||
| 				"z.g":  "o", |  | ||||||
| 				"z":    "o", |  | ||||||
| 				"y.ca": "b", |  | ||||||
| 				"y":    "b", |  | ||||||
| 			}, |  | ||||||
| 			runtimePodAnnotations: []string{"*.f", "z*g", "y.c*"}, |  | ||||||
| 			passthroughAnnotations: map[string]string{ |  | ||||||
| 				"t.f":  "j", |  | ||||||
| 				"z.g":  "o", |  | ||||||
| 				"y.ca": "b", |  | ||||||
| 			}, |  | ||||||
| 		}, |  | ||||||
| 		{ |  | ||||||
| 			desc: "should support wildcard match all", |  | ||||||
| 			podAnnotations: map[string]string{ |  | ||||||
| 				"t.f":  "j", |  | ||||||
| 				"z.g":  "o", |  | ||||||
| 				"z":    "o", |  | ||||||
| 				"y.ca": "b", |  | ||||||
| 				"y":    "b", |  | ||||||
| 			}, |  | ||||||
| 			runtimePodAnnotations: []string{"*"}, |  | ||||||
| 			passthroughAnnotations: map[string]string{ |  | ||||||
| 				"t.f":  "j", |  | ||||||
| 				"z.g":  "o", |  | ||||||
| 				"z":    "o", |  | ||||||
| 				"y.ca": "b", |  | ||||||
| 				"y":    "b", |  | ||||||
| 			}, |  | ||||||
| 		}, |  | ||||||
| 		{ |  | ||||||
| 			desc: "should support match including path separator", |  | ||||||
| 			podAnnotations: map[string]string{ |  | ||||||
| 				"matchend.com/end":    "1", |  | ||||||
| 				"matchend.com/end1":   "2", |  | ||||||
| 				"matchend.com/1end":   "3", |  | ||||||
| 				"matchmid.com/mid":    "4", |  | ||||||
| 				"matchmid.com/mi1d":   "5", |  | ||||||
| 				"matchmid.com/mid1":   "6", |  | ||||||
| 				"matchhead.com/head":  "7", |  | ||||||
| 				"matchhead.com/1head": "8", |  | ||||||
| 				"matchhead.com/head1": "9", |  | ||||||
| 				"matchall.com/abc":    "10", |  | ||||||
| 				"matchall.com/def":    "11", |  | ||||||
| 				"end/matchend":        "12", |  | ||||||
| 				"end1/matchend":       "13", |  | ||||||
| 				"1end/matchend":       "14", |  | ||||||
| 				"mid/matchmid":        "15", |  | ||||||
| 				"mi1d/matchmid":       "16", |  | ||||||
| 				"mid1/matchmid":       "17", |  | ||||||
| 				"head/matchhead":      "18", |  | ||||||
| 				"1head/matchhead":     "19", |  | ||||||
| 				"head1/matchhead":     "20", |  | ||||||
| 				"abc/matchall":        "21", |  | ||||||
| 				"def/matchall":        "22", |  | ||||||
| 				"match1/match2":       "23", |  | ||||||
| 				"nomatch/nomatch":     "24", |  | ||||||
| 			}, |  | ||||||
| 			runtimePodAnnotations: []string{ |  | ||||||
| 				"matchend.com/end*", |  | ||||||
| 				"matchmid.com/mi*d", |  | ||||||
| 				"matchhead.com/*head", |  | ||||||
| 				"matchall.com/*", |  | ||||||
| 				"end*/matchend", |  | ||||||
| 				"mi*d/matchmid", |  | ||||||
| 				"*head/matchhead", |  | ||||||
| 				"*/matchall", |  | ||||||
| 				"match*/match*", |  | ||||||
| 			}, |  | ||||||
| 			passthroughAnnotations: map[string]string{ |  | ||||||
| 				"matchend.com/end":    "1", |  | ||||||
| 				"matchend.com/end1":   "2", |  | ||||||
| 				"matchmid.com/mid":    "4", |  | ||||||
| 				"matchmid.com/mi1d":   "5", |  | ||||||
| 				"matchhead.com/head":  "7", |  | ||||||
| 				"matchhead.com/1head": "8", |  | ||||||
| 				"matchall.com/abc":    "10", |  | ||||||
| 				"matchall.com/def":    "11", |  | ||||||
| 				"end/matchend":        "12", |  | ||||||
| 				"end1/matchend":       "13", |  | ||||||
| 				"mid/matchmid":        "15", |  | ||||||
| 				"mi1d/matchmid":       "16", |  | ||||||
| 				"head/matchhead":      "18", |  | ||||||
| 				"1head/matchhead":     "19", |  | ||||||
| 				"abc/matchall":        "21", |  | ||||||
| 				"def/matchall":        "22", |  | ||||||
| 				"match1/match2":       "23", |  | ||||||
| 			}, |  | ||||||
| 		}, |  | ||||||
| 	} { |  | ||||||
| 		test := test |  | ||||||
| 		t.Run(test.desc, func(t *testing.T) { |  | ||||||
| 			passthroughAnnotations := getPassthroughAnnotations(test.podAnnotations, test.runtimePodAnnotations) |  | ||||||
| 			assert.Equal(t, test.passthroughAnnotations, passthroughAnnotations) |  | ||||||
| 		}) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func TestEnsureRemoveAllNotExist(t *testing.T) { | func TestEnsureRemoveAllNotExist(t *testing.T) { | ||||||
| 	// should never return an error for a non-existent path | 	// should never return an error for a non-existent path | ||||||
| 	if err := ensureRemoveAll(context.Background(), "/non/existent/path"); err != nil { | 	if err := ensureRemoveAll(context.Background(), "/non/existent/path"); err != nil { | ||||||
|   | |||||||
| @@ -19,7 +19,6 @@ package podsandbox | |||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"path" |  | ||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
|  |  | ||||||
| 	"github.com/containerd/log" | 	"github.com/containerd/log" | ||||||
| @@ -93,25 +92,6 @@ func buildLabels(configLabels, imageConfigLabels map[string]string, containerTyp | |||||||
| 	return labels | 	return labels | ||||||
| } | } | ||||||
|  |  | ||||||
| // getPassthroughAnnotations filters requested pod annotations by comparing |  | ||||||
| // against permitted annotations for the given runtime. |  | ||||||
| func getPassthroughAnnotations(podAnnotations map[string]string, |  | ||||||
| 	runtimePodAnnotations []string) (passthroughAnnotations map[string]string) { |  | ||||||
| 	passthroughAnnotations = make(map[string]string) |  | ||||||
|  |  | ||||||
| 	for podAnnotationKey, podAnnotationValue := range podAnnotations { |  | ||||||
| 		for _, pattern := range runtimePodAnnotations { |  | ||||||
| 			// Use path.Match instead of filepath.Match here. |  | ||||||
| 			// filepath.Match treated `\\` as path separator |  | ||||||
| 			// on windows, which is not what we want. |  | ||||||
| 			if ok, _ := path.Match(pattern, podAnnotationKey); ok { |  | ||||||
| 				passthroughAnnotations[podAnnotationKey] = podAnnotationValue |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return passthroughAnnotations |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // runtimeSpec returns a default runtime spec used in cri-containerd. | // runtimeSpec returns a default runtime spec used in cri-containerd. | ||||||
| func (c *Controller) runtimeSpec(id string, baseSpecFile string, opts ...oci.SpecOpts) (*runtimespec.Spec, error) { | func (c *Controller) runtimeSpec(id string, baseSpecFile string, opts ...oci.SpecOpts) (*runtimespec.Spec, error) { | ||||||
| 	// GenerateSpec needs namespace. | 	// GenerateSpec needs namespace. | ||||||
|   | |||||||
| @@ -131,121 +131,6 @@ func TestEnvDeduplication(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestPassThroughAnnotationsFilter(t *testing.T) { |  | ||||||
| 	for _, test := range []struct { |  | ||||||
| 		desc                   string |  | ||||||
| 		podAnnotations         map[string]string |  | ||||||
| 		runtimePodAnnotations  []string |  | ||||||
| 		passthroughAnnotations map[string]string |  | ||||||
| 	}{ |  | ||||||
| 		{ |  | ||||||
| 			desc:                   "should support direct match", |  | ||||||
| 			podAnnotations:         map[string]string{"c": "d", "d": "e"}, |  | ||||||
| 			runtimePodAnnotations:  []string{"c"}, |  | ||||||
| 			passthroughAnnotations: map[string]string{"c": "d"}, |  | ||||||
| 		}, |  | ||||||
| 		{ |  | ||||||
| 			desc: "should support wildcard match", |  | ||||||
| 			podAnnotations: map[string]string{ |  | ||||||
| 				"t.f":  "j", |  | ||||||
| 				"z.g":  "o", |  | ||||||
| 				"z":    "o", |  | ||||||
| 				"y.ca": "b", |  | ||||||
| 				"y":    "b", |  | ||||||
| 			}, |  | ||||||
| 			runtimePodAnnotations: []string{"*.f", "z*g", "y.c*"}, |  | ||||||
| 			passthroughAnnotations: map[string]string{ |  | ||||||
| 				"t.f":  "j", |  | ||||||
| 				"z.g":  "o", |  | ||||||
| 				"y.ca": "b", |  | ||||||
| 			}, |  | ||||||
| 		}, |  | ||||||
| 		{ |  | ||||||
| 			desc: "should support wildcard match all", |  | ||||||
| 			podAnnotations: map[string]string{ |  | ||||||
| 				"t.f":  "j", |  | ||||||
| 				"z.g":  "o", |  | ||||||
| 				"z":    "o", |  | ||||||
| 				"y.ca": "b", |  | ||||||
| 				"y":    "b", |  | ||||||
| 			}, |  | ||||||
| 			runtimePodAnnotations: []string{"*"}, |  | ||||||
| 			passthroughAnnotations: map[string]string{ |  | ||||||
| 				"t.f":  "j", |  | ||||||
| 				"z.g":  "o", |  | ||||||
| 				"z":    "o", |  | ||||||
| 				"y.ca": "b", |  | ||||||
| 				"y":    "b", |  | ||||||
| 			}, |  | ||||||
| 		}, |  | ||||||
| 		{ |  | ||||||
| 			desc: "should support match including path separator", |  | ||||||
| 			podAnnotations: map[string]string{ |  | ||||||
| 				"matchend.com/end":    "1", |  | ||||||
| 				"matchend.com/end1":   "2", |  | ||||||
| 				"matchend.com/1end":   "3", |  | ||||||
| 				"matchmid.com/mid":    "4", |  | ||||||
| 				"matchmid.com/mi1d":   "5", |  | ||||||
| 				"matchmid.com/mid1":   "6", |  | ||||||
| 				"matchhead.com/head":  "7", |  | ||||||
| 				"matchhead.com/1head": "8", |  | ||||||
| 				"matchhead.com/head1": "9", |  | ||||||
| 				"matchall.com/abc":    "10", |  | ||||||
| 				"matchall.com/def":    "11", |  | ||||||
| 				"end/matchend":        "12", |  | ||||||
| 				"end1/matchend":       "13", |  | ||||||
| 				"1end/matchend":       "14", |  | ||||||
| 				"mid/matchmid":        "15", |  | ||||||
| 				"mi1d/matchmid":       "16", |  | ||||||
| 				"mid1/matchmid":       "17", |  | ||||||
| 				"head/matchhead":      "18", |  | ||||||
| 				"1head/matchhead":     "19", |  | ||||||
| 				"head1/matchhead":     "20", |  | ||||||
| 				"abc/matchall":        "21", |  | ||||||
| 				"def/matchall":        "22", |  | ||||||
| 				"match1/match2":       "23", |  | ||||||
| 				"nomatch/nomatch":     "24", |  | ||||||
| 			}, |  | ||||||
| 			runtimePodAnnotations: []string{ |  | ||||||
| 				"matchend.com/end*", |  | ||||||
| 				"matchmid.com/mi*d", |  | ||||||
| 				"matchhead.com/*head", |  | ||||||
| 				"matchall.com/*", |  | ||||||
| 				"end*/matchend", |  | ||||||
| 				"mi*d/matchmid", |  | ||||||
| 				"*head/matchhead", |  | ||||||
| 				"*/matchall", |  | ||||||
| 				"match*/match*", |  | ||||||
| 			}, |  | ||||||
| 			passthroughAnnotations: map[string]string{ |  | ||||||
| 				"matchend.com/end":    "1", |  | ||||||
| 				"matchend.com/end1":   "2", |  | ||||||
| 				"matchmid.com/mid":    "4", |  | ||||||
| 				"matchmid.com/mi1d":   "5", |  | ||||||
| 				"matchhead.com/head":  "7", |  | ||||||
| 				"matchhead.com/1head": "8", |  | ||||||
| 				"matchall.com/abc":    "10", |  | ||||||
| 				"matchall.com/def":    "11", |  | ||||||
| 				"end/matchend":        "12", |  | ||||||
| 				"end1/matchend":       "13", |  | ||||||
| 				"mid/matchmid":        "15", |  | ||||||
| 				"mi1d/matchmid":       "16", |  | ||||||
| 				"head/matchhead":      "18", |  | ||||||
| 				"1head/matchhead":     "19", |  | ||||||
| 				"abc/matchall":        "21", |  | ||||||
| 				"def/matchall":        "22", |  | ||||||
| 				"match1/match2":       "23", |  | ||||||
| 			}, |  | ||||||
| 		}, |  | ||||||
| 	} { |  | ||||||
| 		test := test |  | ||||||
| 		t.Run(test.desc, func(t *testing.T) { |  | ||||||
| 			passthroughAnnotations := getPassthroughAnnotations(test.podAnnotations, test.runtimePodAnnotations) |  | ||||||
| 			assert.Equal(t, test.passthroughAnnotations, passthroughAnnotations) |  | ||||||
| 		}) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func TestEnsureRemoveAllNotExist(t *testing.T) { | func TestEnsureRemoveAllNotExist(t *testing.T) { | ||||||
| 	// should never return an error for a non-existent path | 	// should never return an error for a non-existent path | ||||||
| 	if err := ensureRemoveAll(context.Background(), "/non/existent/path"); err != nil { | 	if err := ensureRemoveAll(context.Background(), "/non/existent/path"); err != nil { | ||||||
|   | |||||||
| @@ -33,6 +33,7 @@ import ( | |||||||
| 	"github.com/containerd/containerd/v2/core/snapshots" | 	"github.com/containerd/containerd/v2/core/snapshots" | ||||||
| 	"github.com/containerd/containerd/v2/internal/cri/annotations" | 	"github.com/containerd/containerd/v2/internal/cri/annotations" | ||||||
| 	customopts "github.com/containerd/containerd/v2/internal/cri/opts" | 	customopts "github.com/containerd/containerd/v2/internal/cri/opts" | ||||||
|  | 	"github.com/containerd/containerd/v2/internal/cri/util" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func (c *Controller) sandboxContainerSpec(id string, config *runtime.PodSandboxConfig, | func (c *Controller) sandboxContainerSpec(id string, config *runtime.PodSandboxConfig, | ||||||
| @@ -187,7 +188,7 @@ func (c *Controller) sandboxContainerSpec(id string, config *runtime.PodSandboxC | |||||||
|  |  | ||||||
| 	specOpts = append(specOpts, customopts.WithPodOOMScoreAdj(int(defaultSandboxOOMAdj), c.config.RestrictOOMScoreAdj)) | 	specOpts = append(specOpts, customopts.WithPodOOMScoreAdj(int(defaultSandboxOOMAdj), c.config.RestrictOOMScoreAdj)) | ||||||
|  |  | ||||||
| 	for pKey, pValue := range getPassthroughAnnotations(config.Annotations, | 	for pKey, pValue := range util.GetPassthroughAnnotations(config.Annotations, | ||||||
| 		runtimePodAnnotations) { | 		runtimePodAnnotations) { | ||||||
| 		specOpts = append(specOpts, customopts.WithAnnotation(pKey, pValue)) | 		specOpts = append(specOpts, customopts.WithAnnotation(pKey, pValue)) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -28,6 +28,7 @@ import ( | |||||||
| 	"github.com/containerd/containerd/v2/core/snapshots" | 	"github.com/containerd/containerd/v2/core/snapshots" | ||||||
| 	"github.com/containerd/containerd/v2/internal/cri/annotations" | 	"github.com/containerd/containerd/v2/internal/cri/annotations" | ||||||
| 	customopts "github.com/containerd/containerd/v2/internal/cri/opts" | 	customopts "github.com/containerd/containerd/v2/internal/cri/opts" | ||||||
|  | 	"github.com/containerd/containerd/v2/internal/cri/util" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func (c *Controller) sandboxContainerSpec(id string, config *runtime.PodSandboxConfig, | func (c *Controller) sandboxContainerSpec(id string, config *runtime.PodSandboxConfig, | ||||||
| @@ -75,7 +76,7 @@ func (c *Controller) sandboxContainerSpec(id string, config *runtime.PodSandboxC | |||||||
| 	// when trying to run the init process. | 	// when trying to run the init process. | ||||||
| 	specOpts = append(specOpts, oci.WithUser(username)) | 	specOpts = append(specOpts, oci.WithUser(username)) | ||||||
|  |  | ||||||
| 	for pKey, pValue := range getPassthroughAnnotations(config.Annotations, | 	for pKey, pValue := range util.GetPassthroughAnnotations(config.Annotations, | ||||||
| 		runtimePodAnnotations) { | 		runtimePodAnnotations) { | ||||||
| 		specOpts = append(specOpts, customopts.WithAnnotation(pKey, pValue)) | 		specOpts = append(specOpts, customopts.WithAnnotation(pKey, pValue)) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -18,6 +18,7 @@ package util | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
|  | 	"path" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/containerd/containerd/v2/pkg/namespaces" | 	"github.com/containerd/containerd/v2/pkg/namespaces" | ||||||
| @@ -44,3 +45,22 @@ func NamespacedContext() context.Context { | |||||||
| func WithNamespace(ctx context.Context) context.Context { | func WithNamespace(ctx context.Context) context.Context { | ||||||
| 	return namespaces.WithNamespace(ctx, constants.K8sContainerdNamespace) | 	return namespaces.WithNamespace(ctx, constants.K8sContainerdNamespace) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // GetPassthroughAnnotations filters requested pod annotations by comparing | ||||||
|  | // against permitted annotations for the given runtime. | ||||||
|  | func GetPassthroughAnnotations(podAnnotations map[string]string, | ||||||
|  | 	runtimePodAnnotations []string) (passthroughAnnotations map[string]string) { | ||||||
|  | 	passthroughAnnotations = make(map[string]string) | ||||||
|  |  | ||||||
|  | 	for podAnnotationKey, podAnnotationValue := range podAnnotations { | ||||||
|  | 		for _, pattern := range runtimePodAnnotations { | ||||||
|  | 			// Use path.Match instead of filepath.Match here. | ||||||
|  | 			// filepath.Match treated `\\` as path separator | ||||||
|  | 			// on windows, which is not what we want. | ||||||
|  | 			if ok, _ := path.Match(pattern, podAnnotationKey); ok { | ||||||
|  | 				passthroughAnnotations[podAnnotationKey] = podAnnotationValue | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return passthroughAnnotations | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										138
									
								
								internal/cri/util/util_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								internal/cri/util/util_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,138 @@ | |||||||
|  | /* | ||||||
|  |    Copyright The containerd Authors. | ||||||
|  |  | ||||||
|  |    Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |    you may not use this file except in compliance with the License. | ||||||
|  |    You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |        http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |    Unless required by applicable law or agreed to in writing, software | ||||||
|  |    distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |    See the License for the specific language governing permissions and | ||||||
|  |    limitations under the License. | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | package util | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"testing" | ||||||
|  |  | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func TestPassThroughAnnotationsFilter(t *testing.T) { | ||||||
|  | 	for _, test := range []struct { | ||||||
|  | 		desc                   string | ||||||
|  | 		podAnnotations         map[string]string | ||||||
|  | 		runtimePodAnnotations  []string | ||||||
|  | 		passthroughAnnotations map[string]string | ||||||
|  | 	}{ | ||||||
|  | 		{ | ||||||
|  | 			desc:                   "should support direct match", | ||||||
|  | 			podAnnotations:         map[string]string{"c": "d", "d": "e"}, | ||||||
|  | 			runtimePodAnnotations:  []string{"c"}, | ||||||
|  | 			passthroughAnnotations: map[string]string{"c": "d"}, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			desc: "should support wildcard match", | ||||||
|  | 			podAnnotations: map[string]string{ | ||||||
|  | 				"t.f":  "j", | ||||||
|  | 				"z.g":  "o", | ||||||
|  | 				"z":    "o", | ||||||
|  | 				"y.ca": "b", | ||||||
|  | 				"y":    "b", | ||||||
|  | 			}, | ||||||
|  | 			runtimePodAnnotations: []string{"*.f", "z*g", "y.c*"}, | ||||||
|  | 			passthroughAnnotations: map[string]string{ | ||||||
|  | 				"t.f":  "j", | ||||||
|  | 				"z.g":  "o", | ||||||
|  | 				"y.ca": "b", | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			desc: "should support wildcard match all", | ||||||
|  | 			podAnnotations: map[string]string{ | ||||||
|  | 				"t.f":  "j", | ||||||
|  | 				"z.g":  "o", | ||||||
|  | 				"z":    "o", | ||||||
|  | 				"y.ca": "b", | ||||||
|  | 				"y":    "b", | ||||||
|  | 			}, | ||||||
|  | 			runtimePodAnnotations: []string{"*"}, | ||||||
|  | 			passthroughAnnotations: map[string]string{ | ||||||
|  | 				"t.f":  "j", | ||||||
|  | 				"z.g":  "o", | ||||||
|  | 				"z":    "o", | ||||||
|  | 				"y.ca": "b", | ||||||
|  | 				"y":    "b", | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			desc: "should support match including path separator", | ||||||
|  | 			podAnnotations: map[string]string{ | ||||||
|  | 				"matchend.com/end":    "1", | ||||||
|  | 				"matchend.com/end1":   "2", | ||||||
|  | 				"matchend.com/1end":   "3", | ||||||
|  | 				"matchmid.com/mid":    "4", | ||||||
|  | 				"matchmid.com/mi1d":   "5", | ||||||
|  | 				"matchmid.com/mid1":   "6", | ||||||
|  | 				"matchhead.com/head":  "7", | ||||||
|  | 				"matchhead.com/1head": "8", | ||||||
|  | 				"matchhead.com/head1": "9", | ||||||
|  | 				"matchall.com/abc":    "10", | ||||||
|  | 				"matchall.com/def":    "11", | ||||||
|  | 				"end/matchend":        "12", | ||||||
|  | 				"end1/matchend":       "13", | ||||||
|  | 				"1end/matchend":       "14", | ||||||
|  | 				"mid/matchmid":        "15", | ||||||
|  | 				"mi1d/matchmid":       "16", | ||||||
|  | 				"mid1/matchmid":       "17", | ||||||
|  | 				"head/matchhead":      "18", | ||||||
|  | 				"1head/matchhead":     "19", | ||||||
|  | 				"head1/matchhead":     "20", | ||||||
|  | 				"abc/matchall":        "21", | ||||||
|  | 				"def/matchall":        "22", | ||||||
|  | 				"match1/match2":       "23", | ||||||
|  | 				"nomatch/nomatch":     "24", | ||||||
|  | 			}, | ||||||
|  | 			runtimePodAnnotations: []string{ | ||||||
|  | 				"matchend.com/end*", | ||||||
|  | 				"matchmid.com/mi*d", | ||||||
|  | 				"matchhead.com/*head", | ||||||
|  | 				"matchall.com/*", | ||||||
|  | 				"end*/matchend", | ||||||
|  | 				"mi*d/matchmid", | ||||||
|  | 				"*head/matchhead", | ||||||
|  | 				"*/matchall", | ||||||
|  | 				"match*/match*", | ||||||
|  | 			}, | ||||||
|  | 			passthroughAnnotations: map[string]string{ | ||||||
|  | 				"matchend.com/end":    "1", | ||||||
|  | 				"matchend.com/end1":   "2", | ||||||
|  | 				"matchmid.com/mid":    "4", | ||||||
|  | 				"matchmid.com/mi1d":   "5", | ||||||
|  | 				"matchhead.com/head":  "7", | ||||||
|  | 				"matchhead.com/1head": "8", | ||||||
|  | 				"matchall.com/abc":    "10", | ||||||
|  | 				"matchall.com/def":    "11", | ||||||
|  | 				"end/matchend":        "12", | ||||||
|  | 				"end1/matchend":       "13", | ||||||
|  | 				"mid/matchmid":        "15", | ||||||
|  | 				"mi1d/matchmid":       "16", | ||||||
|  | 				"head/matchhead":      "18", | ||||||
|  | 				"1head/matchhead":     "19", | ||||||
|  | 				"abc/matchall":        "21", | ||||||
|  | 				"def/matchall":        "22", | ||||||
|  | 				"match1/match2":       "23", | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 	} { | ||||||
|  | 		test := test | ||||||
|  | 		t.Run(test.desc, func(t *testing.T) { | ||||||
|  | 			passthroughAnnotations := GetPassthroughAnnotations(test.podAnnotations, test.runtimePodAnnotations) | ||||||
|  | 			assert.Equal(t, test.passthroughAnnotations, passthroughAnnotations) | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user
	 Jin Dong
					Jin Dong