Skip to content

Commit

Permalink
exec function working dir is the kustomization that referenced it
Browse files Browse the repository at this point in the history
  • Loading branch information
natasha41575 committed Aug 19, 2021
1 parent 28707bf commit e52bab4
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 2 deletions.
8 changes: 7 additions & 1 deletion api/internal/target/kusttarget.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/kio/kioutil"
"sigs.k8s.io/kustomize/kyaml/openapi"
"sigs.k8s.io/yaml"
)
Expand Down Expand Up @@ -262,7 +263,12 @@ func (kt *KustTarget) configureExternalGenerators() ([]resmap.Generator, error)
if err != nil {
return nil, err
}
return kt.pLdr.LoadGenerators(kt.ldr, kt.validator, ra.ResMap())
m := ra.ResMap()
err = m.AnnotateAll(kioutil.PathAnnotation, kt.ldr.Root())
if err != nil {
return nil, err
}
return kt.pLdr.LoadGenerators(kt.ldr, kt.validator, m)
}

func (kt *KustTarget) runTransformers(ra *accumulator.ResAccumulator) error {
Expand Down
125 changes: 125 additions & 0 deletions api/krusty/fnplugin_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
package krusty_test

import (
"os"
"os/exec"
"path/filepath"
"testing"

"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/api/internal/utils"
"sigs.k8s.io/kustomize/api/krusty"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
"sigs.k8s.io/kustomize/kyaml/filesys"
)

func TestFnExecGenerator(t *testing.T) {
Expand Down Expand Up @@ -82,6 +88,125 @@ spec:
`)
}

func TestFnExecGeneratorWithOverlay(t *testing.T) {
fSys := filesys.MakeFsOnDisk()
th := kusttest_test.MakeHarness(t)
o := th.MakeOptionsPluginsEnabled()
o.PluginConfig.FnpLoadingOptions.EnableExec = true
b := krusty.MakeKustomizer(&o)

tmpDir, err := filesys.NewTmpConfirmedDir()
assert.NoError(t, err)
base := filepath.Join(tmpDir.String(), "base")
prod := filepath.Join(tmpDir.String(), "prod")
assert.NoError(t, fSys.Mkdir(base))
assert.NoError(t, fSys.Mkdir(prod))
assert.NoError(t, fSys.WriteFile(filepath.Join(base, "kustomization.yaml"), []byte(`
resources:
- short_secret.yaml
generators:
- gener.yaml
`)))
assert.NoError(t, fSys.WriteFile(filepath.Join(prod, "kustomization.yaml"), []byte(`
resources:
- ../base
`)))
assert.NoError(t, fSys.WriteFile(filepath.Join(base, "short_secret.yaml"), []byte(`
apiVersion: v1
kind: Secret
metadata:
labels:
airshipit.org/ephemeral-user-data: "true"
name: node1-bmc-secret
type: Opaque
stringData:
userData: |
bootcmd:
- mkdir /mnt/vda
`)))
assert.NoError(t, fSys.WriteFile(filepath.Join(base, "exec.sh"), []byte(`#!/bin/sh
cat <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
annotations:
tshirt-size: small # this injects the resource reservations
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
EOF
`)))
assert.NoError(t, os.Chmod(filepath.Join(base, "exec.sh"), 0777))
assert.NoError(t, fSys.WriteFile(filepath.Join(base, "gener.yaml"), []byte(`
kind: executable
metadata:
name: demo
annotations:
config.kubernetes.io/function: |
exec:
path: ./exec.sh
spec:
`)))

m, err := b.Run(
fSys,
prod)
if utils.IsErrTimeout(err) {
// Don't fail on timeouts.
t.SkipNow()
}
assert.NoError(t, err)
yml, err := m.AsYaml()
assert.NoError(t, err)
assert.Equal(t, `apiVersion: v1
kind: Secret
metadata:
labels:
airshipit.org/ephemeral-user-data: "true"
name: node1-bmc-secret
stringData:
userData: |
bootcmd:
- mkdir /mnt/vda
type: Opaque
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
tshirt-size: small
labels:
app: nginx
name: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
`, string(yml))
assert.NoError(t, fSys.RemoveAll(tmpDir.String()))
}

func skipIfNoDocker(t *testing.T) {
if _, err := exec.LookPath("docker"); err != nil {
t.Skip("skipping because docker binary wasn't found in PATH")
Expand Down
4 changes: 4 additions & 0 deletions api/resmap/resmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ type ResMap interface {
// failing on any CurId collision.
AppendAll(ResMap) error

// AnnotateAll annotates all resources in the ResMap with
// the provided key value pair.
AnnotateAll(key string, value string) error

// AbsorbAll appends, replaces or merges the contents
// of another ResMap into self,
// allowing and sometimes demanding ID collisions.
Expand Down
13 changes: 13 additions & 0 deletions api/resmap/reswrangler.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,19 @@ func (m *resWrangler) append(res *resource.Resource) {
m.rList = append(m.rList, res)
}

// AnnotateAll implements ResMap
func (m *resWrangler) AnnotateAll(key string, value string) error {
return m.ApplyFilter(annotations.Filter{
Annotations: map[string]string{
key: value,
},
FsSlice: []types.FieldSpec{{
Path: "metadata/annotations",
CreateIfNotPresent: true,
}},
})
}

// Remove implements ResMap.
func (m *resWrangler) Remove(adios resid.ResId) error {
var rList []*resource.Resource
Expand Down
13 changes: 13 additions & 0 deletions kyaml/fn/runtime/exec/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ type Filter struct {
// Args are the arguments to the executable
Args []string `yaml:"args,omitempty"`

// WorkingDir is the working directory that the executable
// should run in
WorkingDir string

runtimeutil.FunctionFilter
}

Expand All @@ -28,6 +32,15 @@ func (c *Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
}

func (c *Filter) Run(reader io.Reader, writer io.Writer) error {
if c.WorkingDir != "" {
p, err := os.Getwd()
if err != nil {
return err
}
os.Chdir(c.WorkingDir)
defer os.Chdir(p)
}

cmd := exec.Command(c.Path, c.Args...)
cmd.Stdin = reader
cmd.Stdout = writer
Expand Down
14 changes: 13 additions & 1 deletion kyaml/runfn/runfn.go
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,19 @@ func (r *RunFns) ffp(spec runtimeutil.FunctionSpec, api *yaml.RNode, currentUser
}

if r.EnableExec && spec.Exec.Path != "" {
ef := &exec.Filter{Path: spec.Exec.Path}
currentDir, err := os.Getwd()
if err != nil {
return nil, err
}

wd, _, err := kioutil.GetFileAnnotations(api)
if err != nil || wd == "" || wd == "/" {
wd = currentDir
}
ef := &exec.Filter{
Path: spec.Exec.Path,
WorkingDir: wd,
}

ef.FunctionConfig = api
ef.GlobalScope = r.GlobalScope
Expand Down

0 comments on commit e52bab4

Please sign in to comment.