mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-10 08:20:59 +00:00
Merge pull request #1822 from joncwong/container-local-vol
Add Local Volume support to ContainerFilter
This commit is contained in:
@@ -25,7 +25,6 @@ import (
|
||||
// The full set of environment variables from the parent process
|
||||
// are passed to the container.
|
||||
type ContainerFilter struct {
|
||||
mountPath string
|
||||
|
||||
// Image is the container image to use to create a container.
|
||||
Image string `yaml:"image,omitempty"`
|
||||
@@ -33,6 +32,9 @@ type ContainerFilter struct {
|
||||
// Network is the container network to use.
|
||||
Network string `yaml:"network,omitempty"`
|
||||
|
||||
// StorageMounts is a list of storage options that the container will have mounted.
|
||||
StorageMounts []StorageMount
|
||||
|
||||
// Config is the API configuration for the container and passed through the
|
||||
// API_CONFIG env var to the container.
|
||||
// Typically a Kubernetes style Resource Config.
|
||||
@@ -44,8 +46,23 @@ type ContainerFilter struct {
|
||||
checkInput func(string)
|
||||
}
|
||||
|
||||
func (c *ContainerFilter) SetMountPath(path string) {
|
||||
c.mountPath = path
|
||||
// StorageMount represents a container's mounted storage option(s)
|
||||
type StorageMount struct {
|
||||
// Type of mount e.g. bind mount, local volume, etc.
|
||||
MountType string
|
||||
|
||||
// Source for the storage to be mounted.
|
||||
// For named volumes, this is the name of the volume.
|
||||
// For anonymous volumes, this field is omitted (empty string).
|
||||
// For bind mounts, this is the path to the file or directory on the host.
|
||||
Src string
|
||||
|
||||
// The path where the file or directory is mounted in the container.
|
||||
DstPath string
|
||||
}
|
||||
|
||||
func (s *StorageMount) String() string {
|
||||
return fmt.Sprintf("type=%s,src=%s,dst=%s:ro", s.MountType, s.Src, s.DstPath)
|
||||
}
|
||||
|
||||
// GrepFilter implements kio.GrepFilter
|
||||
@@ -105,9 +122,10 @@ func (c *ContainerFilter) getArgs() []string {
|
||||
// don't make fs readonly because things like heredoc rely on writing tmp files
|
||||
"--security-opt=no-new-privileges", // don't allow the user to escalate privileges
|
||||
}
|
||||
// mount the directory containing the function as read-only
|
||||
if c.mountPath != "" {
|
||||
args = append(args, "-v", fmt.Sprintf("%s:/local/:ro", c.mountPath))
|
||||
|
||||
// TODO(joncwong): Allow StorageMount fields to have default values.
|
||||
for _, storageMount := range c.StorageMounts {
|
||||
args = append(args, "--mount", storageMount.String())
|
||||
}
|
||||
|
||||
// export the local environment vars to the container
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@@ -62,7 +61,7 @@ metadata:
|
||||
assert.True(t, foundKyaml)
|
||||
}
|
||||
|
||||
func TestFilter_commandMountPath(t *testing.T) {
|
||||
func TestFilter_command_StorageMount(t *testing.T) {
|
||||
cfg, err := yaml.Parse(`apiversion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
@@ -71,12 +70,14 @@ metadata:
|
||||
if !assert.NoError(t, err) {
|
||||
return
|
||||
}
|
||||
bindMount := StorageMount{"bind", "/mount/path", "/local/"}
|
||||
localVol := StorageMount{"volume", "myvol", "/local/"}
|
||||
tmpfs := StorageMount{"tmpfs", "", "/local/"}
|
||||
instance := &ContainerFilter{
|
||||
Image: "example.com:version",
|
||||
Config: cfg,
|
||||
mountPath: filepath.Join("mount", "path"),
|
||||
Image: "example.com:version",
|
||||
Config: cfg,
|
||||
StorageMounts: []StorageMount{bindMount, localVol, tmpfs},
|
||||
}
|
||||
os.Setenv("KYAML_TEST", "FOO")
|
||||
cmd, err := instance.getCommand()
|
||||
if !assert.NoError(t, err) {
|
||||
return
|
||||
@@ -89,7 +90,9 @@ metadata:
|
||||
"--network", "none",
|
||||
"--user", "nobody",
|
||||
"--security-opt=no-new-privileges",
|
||||
"-v", fmt.Sprintf("%s:/local/:ro", filepath.Join("mount", "path")),
|
||||
"--mount", fmt.Sprintf("type=%s,src=%s,dst=%s:ro", "bind", "/mount/path", "/local/"),
|
||||
"--mount", fmt.Sprintf("type=%s,src=%s,dst=%s:ro", "volume", "myvol", "/local/"),
|
||||
"--mount", fmt.Sprintf("type=%s,src=%s,dst=%s:ro", "tmpfs", "", "/local/"),
|
||||
}
|
||||
for _, e := range os.Environ() {
|
||||
// the process env
|
||||
|
||||
@@ -16,6 +16,8 @@ import (
|
||||
// RunFns runs the set of configuration functions in a local directory against
|
||||
// the Resources in that directory
|
||||
type RunFns struct {
|
||||
StorageMounts []filters.StorageMount
|
||||
|
||||
// Path is the path to the directory containing functions
|
||||
Path string
|
||||
|
||||
@@ -90,8 +92,9 @@ func (r *RunFns) init() {
|
||||
// if containerFilterProvider hasn't been set, use the default
|
||||
if r.containerFilterProvider == nil {
|
||||
r.containerFilterProvider = func(image, path string, api *yaml.RNode) kio.Filter {
|
||||
cf := &filters.ContainerFilter{Image: image, Config: api}
|
||||
cf.SetMountPath(filepath.Join(r.Path, path))
|
||||
defaultMount := filters.StorageMount{}
|
||||
r.StorageMounts = append(r.StorageMounts, defaultMount)
|
||||
cf := &filters.ContainerFilter{Image: image, Config: api, StorageMounts: r.StorageMounts}
|
||||
return cf
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,10 @@ kind:
|
||||
return
|
||||
}
|
||||
filter := instance.containerFilterProvider("example.com:version", "", api)
|
||||
assert.Equal(t, &filters.ContainerFilter{Image: "example.com:version", Config: api}, filter)
|
||||
defaultMount:= filters.StorageMount{}
|
||||
mounts := []filters.StorageMount{}
|
||||
mounts = append(mounts, defaultMount)
|
||||
assert.Equal(t, &filters.ContainerFilter{Image: "example.com:version", Config: api, StorageMounts: mounts}, filter)
|
||||
}
|
||||
|
||||
func TestCmd_Execute(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user