Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

exec function working dir is the kustomization that referenced it #4125

Merged
merged 5 commits into from
Aug 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions api/internal/plugins/fnplugin/fnplugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ func NewFnPlugin(o *types.FnPluginLoadingOptions) *FnPlugin {
StorageMounts: toStorageMounts(o.Mounts),
Env: o.Env,
AsCurrentUser: o.AsCurrentUser,
WorkingDir: o.WorkingDir,
},
}
}
Expand Down
5 changes: 5 additions & 0 deletions api/internal/plugins/loader/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ func (l *Loader) Config() *types.PluginConfig {
return l.pc
}

// SetWorkDir sets the working directory for this loader's plugins
func (l *Loader) SetWorkDir(wd string) {
l.pc.FnpLoadingOptions.WorkingDir = wd
}

func (l *Loader) LoadGenerators(
ldr ifc.Loader, v ifc.Validator, rm resmap.ResMap) ([]resmap.Generator, error) {
var result []resmap.Generator
Expand Down
5 changes: 3 additions & 2 deletions api/internal/target/kusttarget.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,13 @@ func NewKustTarget(
validator ifc.Validator,
rFactory *resmap.Factory,
pLdr *loader.Loader) *KustTarget {
pLdrCopy := *pLdr
pLdrCopy.SetWorkDir(ldr.Root())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #4350 for why this directory may not be the right choice.

return &KustTarget{
ldr: ldr,
validator: validator,
rFactory: rFactory,
pLdr: pLdr,
pLdr: &pLdrCopy,
}
}

Expand Down Expand Up @@ -295,7 +297,6 @@ func (kt *KustTarget) configureExternalTransformers(transformers []string) ([]re
ra.AppendAll(rm)
}
ra, err := kt.accumulateResources(ra, transformerPaths, &resource.Origin{})

if err != nil {
return nil, err
}
Expand Down
149 changes: 140 additions & 9 deletions api/krusty/fnplugin_test.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,61 @@
package krusty_test

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

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

const generateDeploymentDotSh = `#!/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
`

func TestFnExecGenerator(t *testing.T) {
// Function plugins should not need the env setup done by MakeEnhancedHarness
th := kusttest_test.MakeHarness(t)
fSys := filesys.MakeFsOnDisk()

th.WriteK(".", `
th := kusttest_test.MakeHarnessWithFs(t, fSys)
o := th.MakeOptionsPluginsEnabled()
o.PluginConfig.FnpLoadingOptions.EnableExec = true

tmpDir, err := filesys.NewTmpConfirmedDir()
assert.NoError(t, err)
th.WriteK(tmpDir.String(), `
resources:
- short_secret.yaml
generators:
- gener.yaml
`)

// Create some additional resource just to make sure everything is added
th.WriteF("short_secret.yaml", `
th.WriteF(filepath.Join(tmpDir.String(), "short_secret.yaml"),
`
apiVersion: v1
kind: Secret
metadata:
Expand All @@ -32,23 +68,117 @@ stringData:
bootcmd:
- mkdir /mnt/vda
`)
th.WriteF(filepath.Join(tmpDir.String(), "generateDeployment.sh"), generateDeploymentDotSh)

th.WriteF("gener.yaml", `
assert.NoError(t, os.Chmod(filepath.Join(tmpDir.String(), "generateDeployment.sh"), 0777))
th.WriteF(filepath.Join(tmpDir.String(), "gener.yaml"), `
kind: executable
metadata:
name: demo
annotations:
config.kubernetes.io/function: |
exec:
path: ./fnplugin_test/fnexectest.sh
path: ./generateDeployment.sh
spec:
`)

m := th.Run(tmpDir.String(), o)
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 TestFnExecGeneratorWithOverlay(t *testing.T) {
fSys := filesys.MakeFsOnDisk()

th := kusttest_test.MakeHarnessWithFs(t, fSys)
o := th.MakeOptionsPluginsEnabled()
o.PluginConfig.FnpLoadingOptions.EnableExec = true
m := th.Run(".", o)
th.AssertActualEqualsExpected(m, `

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))
th.WriteK(base, `
resources:
- short_secret.yaml
generators:
- gener.yaml
`)
th.WriteK(prod, `
resources:
- ../base
`)
th.WriteF(filepath.Join(base, "short_secret.yaml"),
`
apiVersion: v1
kind: Secret
metadata:
labels:
airshipit.org/ephemeral-user-data: "true"
name: node1-bmc-secret
type: Opaque
stringData:
userData: |
bootcmd:
- mkdir /mnt/vda
`)
th.WriteF(filepath.Join(base, "generateDeployment.sh"), generateDeploymentDotSh)

assert.NoError(t, os.Chmod(filepath.Join(base, "generateDeployment.sh"), 0777))
th.WriteF(filepath.Join(base, "gener.yaml"), `
kind: executable
metadata:
name: demo
annotations:
config.kubernetes.io/function: |
exec:
path: ./generateDeployment.sh
spec:
`)

m := th.Run(prod, o)
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"
Expand Down Expand Up @@ -79,7 +209,8 @@ spec:
containers:
- image: nginx
name: nginx
`)
`, string(yml))
assert.NoError(t, fSys.RemoveAll(tmpDir.String()))
}

func skipIfNoDocker(t *testing.T) {
Expand Down
24 changes: 0 additions & 24 deletions api/krusty/fnplugin_test/fnexectest.sh

This file was deleted.

2 changes: 2 additions & 0 deletions api/types/pluginrestrictions.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,6 @@ type FnPluginLoadingOptions struct {
Env []string
// Run as uid and gid of the command executor
AsCurrentUser bool
// Run in this working directory
WorkingDir string
}
8 changes: 8 additions & 0 deletions cmd/config/internal/commands/run-fns.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package commands
import (
"fmt"
"io"
"os"
"strings"

"github.com/spf13/cobra"
Expand Down Expand Up @@ -73,6 +74,7 @@ func GetRunFnRunner(name string) *RunFnRunner {
"a list of environment variables to be used by functions")
r.Command.Flags().BoolVar(
&r.AsCurrentUser, "as-current-user", false, "use the uid and gid of the command executor to run the function in the container")

return r
}

Expand Down Expand Up @@ -302,6 +304,11 @@ func (r *RunFnRunner) preRunE(c *cobra.Command, args []string) error {
// parse mounts to set storageMounts
storageMounts := toStorageMounts(r.Mounts)

wd, err := os.Getwd()
if err != nil {
return err
}

r.RunFns = runfn.RunFns{
FunctionPaths: r.FnPaths,
GlobalScope: r.GlobalScope,
Expand All @@ -317,6 +324,7 @@ func (r *RunFnRunner) preRunE(c *cobra.Command, args []string) error {
LogSteps: r.LogSteps,
Env: r.Env,
AsCurrentUser: r.AsCurrentUser,
WorkingDir: wd,
}

// don't consider args for the function
Expand Down
18 changes: 12 additions & 6 deletions cmd/config/internal/commands/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ import (

"github.com/spf13/cobra"
"github.com/stretchr/testify/assert"

"sigs.k8s.io/kustomize/kyaml/runfn"
)

// TestRunFnCommand_preRunE verifies that preRunE correctly parses the commandline
// flags and arguments into the RunFns structure to be executed.
func TestRunFnCommand_preRunE(t *testing.T) {
wd, err := os.Getwd()
assert.NoError(t, err)
tests := []struct {
name string
args []string
Expand Down Expand Up @@ -201,6 +202,7 @@ apiVersion: v1
Path: "dir",
EnableStarlark: true,
Env: []string{},
WorkingDir: wd,
},
},
{
Expand Down Expand Up @@ -254,6 +256,7 @@ apiVersion: v1
Path: "dir",
ResultsDir: "foo/",
Env: []string{},
WorkingDir: wd,
},
expected: `
metadata:
Expand Down Expand Up @@ -286,18 +289,20 @@ apiVersion: v1
args: []string{"run", "dir", "--log-steps"},
path: "dir",
expectedStruct: &runfn.RunFns{
Path: "dir",
LogSteps: true,
Env: []string{},
Path: "dir",
LogSteps: true,
Env: []string{},
WorkingDir: wd,
},
},
{
name: "envs",
args: []string{"run", "dir", "--env", "FOO=BAR", "-e", "BAR"},
path: "dir",
expectedStruct: &runfn.RunFns{
Path: "dir",
Env: []string{"FOO=BAR", "BAR"},
Path: "dir",
Env: []string{"FOO=BAR", "BAR"},
WorkingDir: wd,
},
},
{
Expand All @@ -308,6 +313,7 @@ apiVersion: v1
Path: "dir",
AsCurrentUser: true,
Env: []string{},
WorkingDir: wd,
},
},
}
Expand Down
Loading