Skip to content

Commit f4bd638

Browse files
authored
[kpt deployer] Customize the manipulated resource directory. (#4819)
* Add new config .kpt.fn.sinkDir * Remove unnecessary tmp dir if user does not want to export the resource output.
1 parent fed5d71 commit f4bd638

File tree

4 files changed

+99
-79
lines changed

4 files changed

+99
-79
lines changed

docs/content/en/schemas/v2beta8.json

+7-1
Original file line numberDiff line numberDiff line change
@@ -1768,6 +1768,11 @@
17681768
"type": "string",
17691769
"description": "docker network name to run the kpt function containers (default \"bridge\").",
17701770
"x-intellij-html-description": "docker network name to run the kpt function containers (default "bridge")."
1771+
},
1772+
"sinkDir": {
1773+
"type": "string",
1774+
"description": "directory to where the manipulated resource output is stored.",
1775+
"x-intellij-html-description": "directory to where the manipulated resource output is stored."
17711776
}
17721777
},
17731778
"preferredOrder": [
@@ -1776,7 +1781,8 @@
17761781
"networkName",
17771782
"globalScope",
17781783
"network",
1779-
"mount"
1784+
"mount",
1785+
"sinkDir"
17801786
],
17811787
"additionalProperties": false,
17821788
"description": "adds additional configurations used when calling `kpt fn`.",

pkg/skaffold/deploy/kpt/kpt.go

+41-30
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ import (
4545
const (
4646
inventoryTemplate = "inventory-template.yaml"
4747
kptHydrated = ".kpt-hydrated"
48-
pipeline = ".pipeline"
48+
tmpSinkDir = ".tmp-sink-dir"
4949
kptFnAnnotation = "config.kubernetes.io/function"
5050
kptFnLocalConfig = "config.kubernetes.io/local-config"
5151
)
@@ -72,7 +72,12 @@ func NewDeployer(cfg types.Config, labels map[string]string) *Deployer {
7272
// outputs them to the applyDir, and runs `kpt live apply` against applyDir to create resources in the cluster.
7373
// `kpt live apply` supports automated pruning declaratively via resources in the applyDir.
7474
func (k *Deployer) Deploy(ctx context.Context, out io.Writer, builds []build.Artifact) ([]string, error) {
75-
manifests, err := k.renderManifests(ctx, out, builds)
75+
flags, err := k.getKptFnRunArgs()
76+
if err != nil {
77+
return []string{}, err
78+
}
79+
80+
manifests, err := k.renderManifests(ctx, out, builds, flags)
7681
if err != nil {
7782
return nil, err
7883
}
@@ -93,6 +98,12 @@ func (k *Deployer) Deploy(ctx context.Context, out io.Writer, builds []build.Art
9398
}
9499

95100
manifest.Write(manifests.String(), filepath.Join(applyDir, "resources.yaml"), out)
101+
// Hydrated config is stored in applyDir, no need to dup the config in temporary sink dir.
102+
if k.Fn.SinkDir == tmpSinkDir {
103+
if err := os.RemoveAll(tmpSinkDir); err != nil {
104+
return nil, fmt.Errorf("deleting temporary directory %s: %w", k.Fn.SinkDir, err)
105+
}
106+
}
96107

97108
cmd := exec.CommandContext(ctx, "kpt", kptCommandArgs(applyDir, []string{"live", "apply"}, k.getKptLiveApplyArgs(), nil)...)
98109
cmd.Stdout = out
@@ -149,7 +160,12 @@ func (k *Deployer) Cleanup(ctx context.Context, out io.Writer) error {
149160

150161
// Render hydrates manifests using both kustomization and kpt functions.
151162
func (k *Deployer) Render(ctx context.Context, out io.Writer, builds []build.Artifact, _ bool, filepath string) error {
152-
manifests, err := k.renderManifests(ctx, out, builds)
163+
flags, err := k.getKptFnRunArgs()
164+
if err != nil {
165+
return err
166+
}
167+
168+
manifests, err := k.renderManifests(ctx, out, builds, flags)
153169
if err != nil {
154170
return err
155171
}
@@ -160,21 +176,21 @@ func (k *Deployer) Render(ctx context.Context, out io.Writer, builds []build.Art
160176
// renderManifests handles a majority of the hydration process for manifests.
161177
// This involves reading configs from a source directory, running kustomize build, running kpt pipelines,
162178
// adding image digests, and adding run-id labels.
163-
func (k *Deployer) renderManifests(ctx context.Context, _ io.Writer, builds []build.Artifact) (manifest.ManifestList, error) {
179+
func (k *Deployer) renderManifests(ctx context.Context, _ io.Writer, builds []build.Artifact,
180+
flags []string) (manifest.ManifestList, error) {
164181
debugHelpersRegistry, err := config.GetDebugHelpersRegistry(k.globalConfig)
165182
if err != nil {
166183
return nil, fmt.Errorf("retrieving debug helpers registry: %w", err)
167184
}
185+
if k.Fn.SinkDir == "" {
186+
k.Fn.SinkDir = tmpSinkDir
187+
}
168188

169-
// .pipeline is a temp dir used to store output between steps of the desired workflow
170-
// This can be removed once kpt can fully support the desired workflow independently.
171-
if err := os.RemoveAll(filepath.Join(pipeline, k.Dir)); err != nil {
172-
return nil, fmt.Errorf("deleting temporary directory %s: %w", filepath.Join(pipeline, k.Dir), err)
189+
if err := os.RemoveAll(filepath.Join(k.Fn.SinkDir, k.Dir)); err != nil {
190+
return nil, fmt.Errorf("deleting temporary directory %s: %w", filepath.Join(k.Fn.SinkDir, k.Dir), err)
173191
}
174-
// 0755 is a permission setting where the owner can read, write, and execute.
175-
// Others can read and execute but not modify the directory.
176-
if err := os.MkdirAll(filepath.Join(pipeline, k.Dir), 0755); err != nil {
177-
return nil, fmt.Errorf("creating temporary directory %s: %w", filepath.Join(pipeline, k.Dir), err)
192+
if err := os.MkdirAll(filepath.Join(k.Fn.SinkDir, k.Dir), os.ModePerm); err != nil {
193+
return nil, fmt.Errorf("creating temporary directory %s: %w", filepath.Join(k.Fn.SinkDir, k.Dir), err)
178194
}
179195

180196
if err := k.readConfigs(ctx); err != nil {
@@ -185,7 +201,7 @@ func (k *Deployer) renderManifests(ctx context.Context, _ io.Writer, builds []bu
185201
return nil, fmt.Errorf("kustomize build: %w", err)
186202
}
187203

188-
manifests, err := k.kptFnRun(ctx)
204+
manifests, err := k.kptFnRun(ctx, flags)
189205
if err != nil {
190206
return nil, fmt.Errorf("running kpt functions: %w", err)
191207
}
@@ -213,15 +229,15 @@ func (k *Deployer) renderManifests(ctx context.Context, _ io.Writer, builds []bu
213229
}
214230

215231
// readConfigs uses `kpt fn source` to read config manifests from k.Dir
216-
// and uses `kpt fn sink` to output those manifests to .pipeline.
232+
// and uses `kpt fn sink` to output those manifests to sinkDir.
217233
func (k *Deployer) readConfigs(ctx context.Context) error {
218234
cmd := exec.CommandContext(ctx, "kpt", kptCommandArgs(k.Dir, []string{"fn", "source"}, nil, nil)...)
219235
b, err := util.RunCmdOut(cmd)
220236
if err != nil {
221237
return err
222238
}
223239

224-
cmd = exec.CommandContext(ctx, "kpt", kptCommandArgs(filepath.Join(pipeline, k.Dir), []string{"fn", "sink"}, nil, nil)...)
240+
cmd = exec.CommandContext(ctx, "kpt", kptCommandArgs(filepath.Join(k.Fn.SinkDir, k.Dir), []string{"fn", "sink"}, nil, nil)...)
225241
cmd.Stdin = bytes.NewBuffer(b)
226242
if _, err := util.RunCmdOut(cmd); err != nil {
227243
return err
@@ -237,7 +253,8 @@ func (k *Deployer) kustomizeBuild(ctx context.Context) error {
237253
return nil
238254
}
239255

240-
cmd := exec.CommandContext(ctx, "kustomize", append([]string{"build"}, kustomize.BuildCommandArgs([]string{"-o", filepath.Join(pipeline, k.Dir)}, k.Dir)...)...)
256+
cmd := exec.CommandContext(ctx, "kustomize", append([]string{"build"},
257+
kustomize.BuildCommandArgs([]string{"-o", filepath.Join(k.Fn.SinkDir, k.Dir)}, k.Dir)...)...)
241258
if _, err := util.RunCmdOut(cmd); err != nil {
242259
return err
243260
}
@@ -247,28 +264,22 @@ func (k *Deployer) kustomizeBuild(ctx context.Context) error {
247264
return fmt.Errorf("finding kustomization dependencies: %w", err)
248265
}
249266

250-
// Kustomize build outputs hydrated configs to .pipeline, so the dry configs must be removed.
267+
// Kustomize build outputs hydrated configs to sinkDir, so the dry configs must be removed.
251268
for _, v := range deps {
252-
if err := os.RemoveAll(filepath.Join(pipeline, v)); err != nil {
269+
if err := os.RemoveAll(filepath.Join(k.Fn.SinkDir, v)); err != nil {
253270
return err
254271
}
255272
}
256273

257274
return nil
258275
}
259276

260-
// kptFnRun does a dry run with the specified kpt functions (fn-path XOR image) against .pipeline.
261-
// If neither fn-path nor image are specified, functions will attempt to be discovered in .pipeline.
277+
// kptFnRun does a dry run with the specified kpt functions (fn-path XOR image) against sinkDir.
278+
// If neither fn-path nor image are specified, functions will attempt to be discovered in sinkDir.
262279
// An error occurs if both fn-path and image are specified.
263-
func (k *Deployer) kptFnRun(ctx context.Context) (manifest.ManifestList, error) {
280+
func (k *Deployer) kptFnRun(ctx context.Context, flags []string) (manifest.ManifestList, error) {
264281
var manifests manifest.ManifestList
265-
266-
flags, err := k.getKptFnRunArgs()
267-
if err != nil {
268-
return nil, fmt.Errorf("getting kpt fn run args: %w", err)
269-
}
270-
271-
cmd := exec.CommandContext(ctx, "kpt", kptCommandArgs(pipeline, []string{"fn", "run"}, flags, nil)...)
282+
cmd := exec.CommandContext(ctx, "kpt", kptCommandArgs(k.Fn.SinkDir, []string{"fn", "run"}, flags, nil)...)
272283
out, err := util.RunCmdOut(cmd)
273284
if err != nil {
274285
return nil, err
@@ -282,7 +293,7 @@ func (k *Deployer) kptFnRun(ctx context.Context) (manifest.ManifestList, error)
282293
}
283294

284295
// excludeKptFn adds an annotation "config.kubernetes.io/local-config: 'true'" to kpt function.
285-
// This will exclude kpt functions from deployed to the cluster in kpt live apply.
296+
// This will exclude kpt functions from deployed to the cluster in `kpt live apply`.
286297
func (k *Deployer) excludeKptFn(originalManifest manifest.ManifestList) (manifest.ManifestList, error) {
287298
var newManifest manifest.ManifestList
288299
for _, yByte := range originalManifest {
@@ -332,7 +343,7 @@ func (k *Deployer) getApplyDir(ctx context.Context) (string, error) {
332343

333344
// 0755 is a permission setting where the owner can read, write, and execute.
334345
// Others can read and execute but not modify the directory.
335-
if err := os.MkdirAll(kptHydrated, 0755); err != nil {
346+
if err := os.MkdirAll(kptHydrated, os.ModePerm); err != nil {
336347
return "", fmt.Errorf("applyDir was unspecified. creating applyDir: %w", err)
337348
}
338349

0 commit comments

Comments
 (0)