mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-11 17:12:51 +00:00
Support mounting volumes to containers
This commit is contained in:
@@ -134,6 +134,9 @@ type ContainerFilter struct {
|
||||
// Network is the container network to use.
|
||||
Network string `yaml:"network,omitempty"`
|
||||
|
||||
// Volumes are the directories to mount as container volumes.
|
||||
Volumes []string `yaml:"volumes,omitempty"`
|
||||
|
||||
// StorageMounts is a list of storage options that the container will have mounted.
|
||||
StorageMounts []StorageMount
|
||||
|
||||
@@ -335,6 +338,11 @@ func (c *ContainerFilter) getArgs() []string {
|
||||
args = append(args, "--mount", storageMount.String())
|
||||
}
|
||||
|
||||
// export volumes to the container
|
||||
for _, volume := range c.Volumes {
|
||||
args = append(args, "--volume", volume)
|
||||
}
|
||||
|
||||
// export the local environment vars to the container
|
||||
for _, pair := range os.Environ() {
|
||||
tokens := strings.Split(pair, "=")
|
||||
|
||||
@@ -141,6 +141,87 @@ metadata:
|
||||
assert.Equal(t, expected, cmd.Args)
|
||||
}
|
||||
|
||||
func TestFilter_command_volume(t *testing.T) {
|
||||
cfg, err := yaml.Parse(`apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: foo
|
||||
`)
|
||||
if !assert.NoError(t, err) {
|
||||
return
|
||||
}
|
||||
instance := &ContainerFilter{
|
||||
Image: "example.com:version",
|
||||
Volumes: []string{"/host-src:/container-dest:ro"},
|
||||
Config: cfg,
|
||||
}
|
||||
cmd, err := instance.getCommand()
|
||||
if !assert.NoError(t, err) {
|
||||
return
|
||||
}
|
||||
|
||||
expected := []string{
|
||||
"docker", "run",
|
||||
"--rm",
|
||||
"-i", "-a", "STDIN", "-a", "STDOUT", "-a", "STDERR",
|
||||
"--network", "none",
|
||||
"--user", "nobody",
|
||||
"--security-opt=no-new-privileges",
|
||||
"--volume", "/host-src:/container-dest:ro",
|
||||
}
|
||||
for _, e := range os.Environ() {
|
||||
// the process env
|
||||
tokens := strings.Split(e, "=")
|
||||
if tokens[0] == "" {
|
||||
continue
|
||||
}
|
||||
expected = append(expected, "-e", tokens[0])
|
||||
}
|
||||
expected = append(expected, "example.com:version")
|
||||
assert.Equal(t, expected, cmd.Args)
|
||||
}
|
||||
|
||||
func TestFilter_command_volumes(t *testing.T) {
|
||||
cfg, err := yaml.Parse(`apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: foo
|
||||
`)
|
||||
if !assert.NoError(t, err) {
|
||||
return
|
||||
}
|
||||
instance := &ContainerFilter{
|
||||
Image: "example.com:version",
|
||||
Volumes: []string{"/host-src1:/container-dest1:ro", "/host-src2:/container-dest2:rw"},
|
||||
Config: cfg,
|
||||
}
|
||||
cmd, err := instance.getCommand()
|
||||
if !assert.NoError(t, err) {
|
||||
return
|
||||
}
|
||||
|
||||
expected := []string{
|
||||
"docker", "run",
|
||||
"--rm",
|
||||
"-i", "-a", "STDIN", "-a", "STDOUT", "-a", "STDERR",
|
||||
"--network", "none",
|
||||
"--user", "nobody",
|
||||
"--security-opt=no-new-privileges",
|
||||
"--volume", "/host-src1:/container-dest1:ro",
|
||||
"--volume", "/host-src2:/container-dest2:rw",
|
||||
}
|
||||
for _, e := range os.Environ() {
|
||||
// the process env
|
||||
tokens := strings.Split(e, "=")
|
||||
if tokens[0] == "" {
|
||||
continue
|
||||
}
|
||||
expected = append(expected, "-e", tokens[0])
|
||||
}
|
||||
expected = append(expected, "example.com:version")
|
||||
assert.Equal(t, expected, cmd.Args)
|
||||
}
|
||||
|
||||
func TestFilter_Filter(t *testing.T) {
|
||||
cfg, err := yaml.Parse(`apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
@@ -355,6 +436,70 @@ container:
|
||||
`,
|
||||
},
|
||||
|
||||
{
|
||||
name: "volume",
|
||||
resource: `
|
||||
apiVersion: v1beta1
|
||||
kind: Example
|
||||
metadata:
|
||||
annotations:
|
||||
config.kubernetes.io/function: |-
|
||||
container:
|
||||
image: foo:v1.0.0
|
||||
volumes: ["/host-src:/container-dest:ro"]
|
||||
`,
|
||||
expectedFn: `
|
||||
container:
|
||||
image: foo:v1.0.0
|
||||
volumes:
|
||||
- /host-src:/container-dest:ro
|
||||
`,
|
||||
},
|
||||
|
||||
{
|
||||
name: "volumes as array",
|
||||
resource: `
|
||||
apiVersion: v1beta1
|
||||
kind: Example
|
||||
metadata:
|
||||
annotations:
|
||||
config.kubernetes.io/function: |-
|
||||
container:
|
||||
image: foo:v1.0.0
|
||||
volumes: ["/host-src1:/container-dest1:ro", "/host-src2:/container-dest2:rw"]
|
||||
`,
|
||||
expectedFn: `
|
||||
container:
|
||||
image: foo:v1.0.0
|
||||
volumes:
|
||||
- /host-src1:/container-dest1:ro
|
||||
- /host-src2:/container-dest2:rw
|
||||
`,
|
||||
},
|
||||
|
||||
{
|
||||
name: "volumes as list",
|
||||
resource: `
|
||||
apiVersion: v1beta1
|
||||
kind: Example
|
||||
metadata:
|
||||
annotations:
|
||||
config.kubernetes.io/function: |-
|
||||
container:
|
||||
image: foo:v1.0.0
|
||||
volumes:
|
||||
- "/host-src1:/container-dest1:ro"
|
||||
- "/host-src2:/container-dest2:rw"
|
||||
`,
|
||||
expectedFn: `
|
||||
container:
|
||||
image: foo:v1.0.0
|
||||
volumes:
|
||||
- /host-src1:/container-dest1:ro
|
||||
- /host-src2:/container-dest2:rw
|
||||
`,
|
||||
},
|
||||
|
||||
{
|
||||
name: "path",
|
||||
resource: `
|
||||
@@ -516,6 +661,76 @@ metadata:
|
||||
}
|
||||
}
|
||||
|
||||
func Test_GetContainerVolumeRequired(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
volumes []string
|
||||
}{
|
||||
{
|
||||
input: `apiVersion: v1
|
||||
kind: Foo
|
||||
metadata:
|
||||
name: foo
|
||||
configFn:
|
||||
container:
|
||||
image: gcr.io/kustomize-functions/example-tshirt:v0.1.0
|
||||
volumes: [ /host-src:/container-dest:ro ]
|
||||
`,
|
||||
volumes: []string{"/host-src:/container-dest:ro"},
|
||||
},
|
||||
{
|
||||
|
||||
input: `apiVersion: v1
|
||||
kind: Foo
|
||||
metadata:
|
||||
name: foo
|
||||
configFn:
|
||||
container:
|
||||
image: gcr.io/kustomize-functions/example-tshirt:v0.1.0
|
||||
`,
|
||||
volumes: []string(nil),
|
||||
},
|
||||
{
|
||||
input: `apiVersion: v1
|
||||
kind: Foo
|
||||
metadata:
|
||||
name: foo
|
||||
annotations:
|
||||
config.kubernetes.io/function: |
|
||||
container:
|
||||
image: gcr.io/kustomize-functions/example-tshirt:v0.1.0
|
||||
volumes: [ "/host-src1:/container-dest1:ro", "/host-src2:/container-dest2:rw" ]
|
||||
`,
|
||||
volumes: []string{"/host-src1:/container-dest1:ro", "/host-src2:/container-dest2:rw"},
|
||||
},
|
||||
{
|
||||
input: `apiVersion: v1
|
||||
kind: Foo
|
||||
metadata:
|
||||
name: foo
|
||||
annotations:
|
||||
config.kubernetes.io/function: |
|
||||
container:
|
||||
image: gcr.io/kustomize-functions/example-tshirt:v0.1.0
|
||||
volumes:
|
||||
- /host-src1:/container-dest1:ro
|
||||
- /host-src2:/container-dest2:rw
|
||||
`,
|
||||
volumes: []string{"/host-src1:/container-dest1:ro", "/host-src2:/container-dest2:rw"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
cfg, err := yaml.Parse(tc.input)
|
||||
if !assert.NoError(t, err) {
|
||||
return
|
||||
}
|
||||
|
||||
fn := GetFunctionSpec(cfg)
|
||||
assert.Equal(t, tc.volumes, fn.Container.Volumes)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilter_Filter_defaultNaming(t *testing.T) {
|
||||
cfg, err := yaml.Parse(`apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
|
||||
@@ -28,6 +28,9 @@ type FunctionSpec struct {
|
||||
|
||||
// Starlark is the spec for running a function as a starlark script
|
||||
Starlark StarlarkSpec `json:"starlark,omitempty" yaml:"starlark,omitempty"`
|
||||
|
||||
// Volumes are the directories to mount as container volumes
|
||||
Volumes []string `json:"volumes,omitempty" yaml:"volumes,omitempty"`
|
||||
}
|
||||
|
||||
// ContainerSpec defines a spec for running a function as a container
|
||||
@@ -37,6 +40,9 @@ type ContainerSpec struct {
|
||||
|
||||
// Network defines network specific configuration
|
||||
Network ContainerNetwork `json:"network,omitempty" yaml:"network,omitempty"`
|
||||
|
||||
// Volumes are the directories to mount as container volumes
|
||||
Volumes []string `json:"volumes,omitempty" yaml:"volumes,omitempty"`
|
||||
}
|
||||
|
||||
// ContainerNetwork
|
||||
@@ -68,6 +74,7 @@ func GetFunctionSpec(n *yaml.RNode) *FunctionSpec {
|
||||
path := meta.Annotations[kioutil.PathAnnotation]
|
||||
if fn := getFunctionSpecFromAnnotation(n, meta); fn != nil {
|
||||
fn.Network = ""
|
||||
fn.Volumes = []string{}
|
||||
fn.Path = path
|
||||
return fn
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user