From 64f30333f080075cf11e7faee89c24d35a862754 Mon Sep 17 00:00:00 2001 From: Yuwen Ma Date: Thu, 17 Sep 2020 13:05:31 -0700 Subject: [PATCH] [kpt deployer] Improve skaffold.yaml docs. * kpt.Dir is required, adding the explanation on the default config. * kpt.applyDir is removed from top-tier config. * Rewrote the kpt.Live struct to clarify the config scope and which configs should be considered together. * Improve the kpt option docstring for skaffold users. --- docs/content/en/schemas/v2beta8.json | 144 +++++++++++++++------------ pkg/skaffold/deploy/kpt.go | 30 +++--- pkg/skaffold/deploy/kpt_test.go | 90 +++++++++++------ pkg/skaffold/schema/latest/config.go | 48 +++++---- 4 files changed, 185 insertions(+), 127 deletions(-) diff --git a/docs/content/en/schemas/v2beta8.json b/docs/content/en/schemas/v2beta8.json index 27c22d6f4c9..934b1448452 100755 --- a/docs/content/en/schemas/v2beta8.json +++ b/docs/content/en/schemas/v2beta8.json @@ -1605,17 +1605,75 @@ "description": "configures Kaniko caching. If a cache is specified, Kaniko will use a remote cache which will speed up builds.", "x-intellij-html-description": "configures Kaniko caching. If a cache is specified, Kaniko will use a remote cache which will speed up builds." }, - "KptDeploy": { + "KptApplyInventory": { + "properties": { + "dir": { + "type": "string", + "description": "equivalent to the dir in `kpt live apply `. If not provided, kpt deployer will create a hidden directory `.kpt-hydrated` to store the manipulated resource output and the kpt inventory-template.yaml file.", + "x-intellij-html-description": "equivalent to the dir in kpt live apply <dir>. If not provided, kpt deployer will create a hidden directory .kpt-hydrated to store the manipulated resource output and the kpt inventory-template.yaml file." + }, + "inventoryID": { + "type": "string", + "description": "*alpha* identifier for a group of applied resources. This value is only needed when the `kpt live` is working on a pre-applied cluster resources.", + "x-intellij-html-description": "alpha identifier for a group of applied resources. This value is only needed when the kpt live is working on a pre-applied cluster resources." + }, + "inventoryNamespace": { + "type": "string", + "description": "*alpha* sets the inventory namespace.", + "x-intellij-html-description": "alpha sets the inventory namespace." + } + }, + "preferredOrder": [ + "dir", + "inventoryID", + "inventoryNamespace" + ], + "additionalProperties": false, + "description": "sets the kpt inventory directory.", + "x-intellij-html-description": "sets the kpt inventory directory." + }, + "KptApplyOptions": { "properties": { - "applyDir": { + "pollPeriod": { "type": "string", - "description": "path to the directory to deploy to the cluster.", - "x-intellij-html-description": "path to the directory to deploy to the cluster." + "description": "sets for the polling period for resource statuses. Default to 2s.", + "x-intellij-html-description": "sets for the polling period for resource statuses. Default to 2s." }, + "prunePropagationPolicy": { + "type": "string", + "description": "sets the propagation policy for pruning. Possible settings are Background, Foreground, Orphan. Default to \"Background\".", + "x-intellij-html-description": "sets the propagation policy for pruning. Possible settings are Background, Foreground, Orphan. Default to "Background"." + }, + "pruneTimeout": { + "type": "string", + "description": "sets the time threshold to wait for all pruned resources to be deleted.", + "x-intellij-html-description": "sets the time threshold to wait for all pruned resources to be deleted." + }, + "reconcileTimeout": { + "type": "string", + "description": "sets the time threshold to wait for all resources to reach the current status.", + "x-intellij-html-description": "sets the time threshold to wait for all resources to reach the current status." + } + }, + "preferredOrder": [ + "pollPeriod", + "prunePropagationPolicy", + "pruneTimeout", + "reconcileTimeout" + ], + "additionalProperties": false, + "description": "adds additional configurations used when calling `kpt live apply`.", + "x-intellij-html-description": "adds additional configurations used when calling kpt live apply." + }, + "KptDeploy": { + "required": [ + "dir" + ], + "properties": { "dir": { "type": "string", - "description": "path to the directory to run kpt functions against.", - "x-intellij-html-description": "path to the directory to run kpt functions against." + "description": "path to the config directory (Required). By default, the Dir contains the application configurations, [kustomize config files](https://kubectl.docs.kubernetes.io/pages/examples/kustomize.html) and [declarative kpt functions](https://googlecontainertools.github.io/kpt/guides/consumer/function/#declarative-run).", + "x-intellij-html-description": "path to the config directory (Required). By default, the Dir contains the application configurations, kustomize config files and declarative kpt functions." }, "fn": { "$ref": "#/definitions/KptFn", @@ -1629,7 +1687,6 @@ } }, "preferredOrder": [ - "applyDir", "dir", "fn", "live" @@ -1642,19 +1699,19 @@ "properties": { "fnPath": { "type": "string", - "description": "a directory to read functions from instead of the configuration directory.", - "x-intellij-html-description": "a directory to read functions from instead of the configuration directory." + "description": "directory to discover the declarative kpt functions. If not provided, kpt deployer uses `kpt.Dir`.", + "x-intellij-html-description": "directory to discover the declarative kpt functions. If not provided, kpt deployer uses kpt.Dir." }, "globalScope": { "type": "boolean", - "description": "sets global scope for functions.", - "x-intellij-html-description": "sets global scope for functions.", + "description": "sets the global scope for the kpt functions. see `kpt help fn run`.", + "x-intellij-html-description": "sets the global scope for the kpt functions. see kpt help fn run.", "default": "false" }, "image": { "type": "string", - "description": "an image to be run as a function in lieu of running functions from a directory.", - "x-intellij-html-description": "an image to be run as a function in lieu of running functions from a directory." + "description": "a kpt function image to run the configs imperatively. If provided, kpt.fn.fnPath will be ignored.", + "x-intellij-html-description": "a kpt function image to run the configs imperatively. If provided, kpt.fn.fnPath will be ignored." }, "mount": { "items": { @@ -1667,14 +1724,14 @@ }, "network": { "type": "boolean", - "description": "enables network access for functions that declare it.", - "x-intellij-html-description": "enables network access for functions that declare it.", + "description": "enables network access for the kpt function containers.", + "x-intellij-html-description": "enables network access for the kpt function containers.", "default": "false" }, "networkName": { "type": "string", - "description": "docker network to run the container in (default \"bridge\").", - "x-intellij-html-description": "docker network to run the container in (default "bridge")." + "description": "docker network name to run the kpt function containers (default \"bridge\").", + "x-intellij-html-description": "docker network name to run the kpt function containers (default "bridge")." } }, "preferredOrder": [ @@ -1692,63 +1749,24 @@ "KptLive": { "properties": { "apply": { - "$ref": "#/definitions/KptLiveApply", + "$ref": "#/definitions/KptApplyInventory", + "description": "sets the kpt inventory directory.", + "x-intellij-html-description": "sets the kpt inventory directory." + }, + "options": { + "$ref": "#/definitions/KptApplyOptions", "description": "adds additional configurations for `kpt live apply` commands.", "x-intellij-html-description": "adds additional configurations for kpt live apply commands." - }, - "inventoryID": { - "type": "string", - "description": "identifier for a group of applied resources. This configuration is used when users do not specify `KptDeploy.ApplyDir` and `.kpt-hydrated/inventory-template.yaml` does not exist.", - "x-intellij-html-description": "identifier for a group of applied resources. This configuration is used when users do not specify KptDeploy.ApplyDir and .kpt-hydrated/inventory-template.yaml does not exist." - }, - "inventoryNamespace": { - "type": "string", - "description": "sets the namespace scope for `kpt live init`.", - "x-intellij-html-description": "sets the namespace scope for kpt live init." } }, "preferredOrder": [ "apply", - "inventoryID", - "inventoryNamespace" + "options" ], "additionalProperties": false, "description": "adds additional configurations used when calling `kpt live`.", "x-intellij-html-description": "adds additional configurations used when calling kpt live." }, - "KptLiveApply": { - "properties": { - "pollPeriod": { - "type": "string", - "description": "sets for the polling period for resource statuses. Default to 2s.", - "x-intellij-html-description": "sets for the polling period for resource statuses. Default to 2s." - }, - "prunePropagationPolicy": { - "type": "string", - "description": "sets the propagation policy for pruning. Possible settings are Background, Foreground, Orphan. Default to \"Background\".", - "x-intellij-html-description": "sets the propagation policy for pruning. Possible settings are Background, Foreground, Orphan. Default to "Background"." - }, - "pruneTimeout": { - "type": "string", - "description": "sets the time threshold to wait for all pruned resources to be deleted.", - "x-intellij-html-description": "sets the time threshold to wait for all pruned resources to be deleted." - }, - "reconcileTimeout": { - "type": "string", - "description": "sets the time threshold to wait for all resources to reach the current status.", - "x-intellij-html-description": "sets the time threshold to wait for all resources to reach the current status." - } - }, - "preferredOrder": [ - "pollPeriod", - "prunePropagationPolicy", - "pruneTimeout", - "reconcileTimeout" - ], - "additionalProperties": false, - "description": "adds additional configurations used when calling `kpt live apply`.", - "x-intellij-html-description": "adds additional configurations used when calling kpt live apply." - }, "KubectlDeploy": { "properties": { "flags": { diff --git a/pkg/skaffold/deploy/kpt.go b/pkg/skaffold/deploy/kpt.go index 6beb10a34d7..7256c59bd3a 100644 --- a/pkg/skaffold/deploy/kpt.go +++ b/pkg/skaffold/deploy/kpt.go @@ -273,11 +273,11 @@ func (k *KptDeployer) kptFnRun(ctx context.Context) (deploy.ManifestList, error) // getApplyDir returns the path to applyDir if specified by the user. Otherwise, getApplyDir // creates a hidden directory named .kpt-hydrated in place of applyDir. func (k *KptDeployer) getApplyDir(ctx context.Context) (string, error) { - if k.ApplyDir != "" { - if _, err := os.Stat(k.ApplyDir); os.IsNotExist(err) { + if k.Live.Apply.Dir != "" { + if _, err := os.Stat(k.Live.Apply.Dir); os.IsNotExist(err) { return "", err } - return k.ApplyDir, nil + return k.Live.Apply.Dir, nil } // 0755 is a permission setting where the owner can read, write, and execute. @@ -393,20 +393,20 @@ func (k *KptDeployer) getKptFnRunArgs() ([]string, error) { func (k *KptDeployer) getKptLiveApplyArgs() []string { var flags []string - if len(k.Live.Apply.PollPeriod) > 0 { - flags = append(flags, "--poll-period", k.Live.Apply.PollPeriod) + if len(k.Live.Options.PollPeriod) > 0 { + flags = append(flags, "--poll-period", k.Live.Options.PollPeriod) } - if len(k.Live.Apply.PrunePropagationPolicy) > 0 { - flags = append(flags, "--prune-propagation-policy", k.Live.Apply.PrunePropagationPolicy) + if len(k.Live.Options.PrunePropagationPolicy) > 0 { + flags = append(flags, "--prune-propagation-policy", k.Live.Options.PrunePropagationPolicy) } - if len(k.Live.Apply.PruneTimeout) > 0 { - flags = append(flags, "--prune-timeout", k.Live.Apply.PruneTimeout) + if len(k.Live.Options.PruneTimeout) > 0 { + flags = append(flags, "--prune-timeout", k.Live.Options.PruneTimeout) } - if len(k.Live.Apply.ReconcileTimeout) > 0 { - flags = append(flags, "--reconcile-timeout", k.Live.Apply.ReconcileTimeout) + if len(k.Live.Options.ReconcileTimeout) > 0 { + flags = append(flags, "--reconcile-timeout", k.Live.Options.ReconcileTimeout) } return flags @@ -416,12 +416,12 @@ func (k *KptDeployer) getKptLiveApplyArgs() []string { func (k *KptDeployer) getKptLiveInitArgs() []string { var flags []string - if len(k.Live.InventoryID) > 0 { - flags = append(flags, "--inventory-id", k.Live.InventoryID) + if len(k.Live.Apply.InventoryID) > 0 { + flags = append(flags, "--inventory-id", k.Live.Apply.InventoryID) } - if len(k.Live.InventoryNamespace) > 0 { - flags = append(flags, "--namespace", k.Live.InventoryNamespace) + if len(k.Live.Apply.InventoryNamespace) > 0 { + flags = append(flags, "--namespace", k.Live.Apply.InventoryNamespace) } return flags diff --git a/pkg/skaffold/deploy/kpt_test.go b/pkg/skaffold/deploy/kpt_test.go index 6aa3cfb0c0b..97c839b16a4 100644 --- a/pkg/skaffold/deploy/kpt_test.go +++ b/pkg/skaffold/deploy/kpt_test.go @@ -77,8 +77,12 @@ spec: { description: "invalid user specified applyDir", kpt: latest.KptDeploy{ - Dir: ".", - ApplyDir: "invalid_path", + Dir: ".", + Live: latest.KptLive{ + Apply: latest.KptApplyInventory{ + Dir: "invalid_path", + }, + }, }, commands: testutil. CmdRunOut("kpt fn source .", ``). @@ -89,9 +93,13 @@ spec: { description: "kustomization and specified kpt fn", kpt: latest.KptDeploy{ - Dir: ".", - Fn: latest.KptFn{FnPath: "kpt-func.yaml"}, - ApplyDir: "valid_path", + Dir: ".", + Fn: latest.KptFn{FnPath: "kpt-func.yaml"}, + Live: latest.KptLive{ + Apply: latest.KptApplyInventory{ + Dir: "valid_path", + }, + }, }, kustomizations: map[string]string{"Kustomization": `resources: - foo.yaml`}, @@ -119,10 +127,12 @@ spec: { description: "user specifies reconcile timeout and poll period", kpt: latest.KptDeploy{ - Dir: ".", - ApplyDir: "valid_path", + Dir: ".", Live: latest.KptLive{ - Apply: latest.KptLiveApply{ + Apply: latest.KptApplyInventory{ + Dir: "valid_path", + }, + Options: latest.KptApplyOptions{ PollPeriod: "5s", ReconcileTimeout: "2m", }, @@ -137,10 +147,12 @@ spec: { description: "user specifies invalid reconcile timeout and poll period", kpt: latest.KptDeploy{ - Dir: ".", - ApplyDir: "valid_path", + Dir: ".", Live: latest.KptLive{ - Apply: latest.KptLiveApply{ + Apply: latest.KptApplyInventory{ + Dir: "valid_path", + }, + Options: latest.KptApplyOptions{ PollPeriod: "foo", ReconcileTimeout: "bar", }, @@ -155,10 +167,12 @@ spec: { description: "user specifies prune propagation policy and prune timeout", kpt: latest.KptDeploy{ - Dir: ".", - ApplyDir: "valid_path", + Dir: ".", Live: latest.KptLive{ - Apply: latest.KptLiveApply{ + Apply: latest.KptApplyInventory{ + Dir: "valid_path", + }, + Options: latest.KptApplyOptions{ PrunePropagationPolicy: "Orphan", PruneTimeout: "2m", }, @@ -173,10 +187,12 @@ spec: { description: "user specifies invalid prune propagation policy and prune timeout", kpt: latest.KptDeploy{ - Dir: ".", - ApplyDir: "valid_path", + Dir: ".", Live: latest.KptLive{ - Apply: latest.KptLiveApply{ + Apply: latest.KptApplyInventory{ + Dir: "valid_path", + }, + Options: latest.KptApplyOptions{ PrunePropagationPolicy: "foo", PruneTimeout: "bar", }, @@ -200,10 +216,10 @@ spec: kpt: test.kpt, }, nil) - if k.ApplyDir == "valid_path" { + if k.Live.Apply.Dir == "valid_path" { // 0755 is a permission setting where the owner can read, write, and execute. // Others can read and execute but not modify the directory. - os.Mkdir(k.ApplyDir, 0755) + os.Mkdir(k.Live.Apply.Dir, 0755) } _, err := k.Deploy(context.Background(), ioutil.Discard, test.builds) @@ -377,7 +393,11 @@ func TestKpt_Cleanup(t *testing.T) { k := NewKptDeployer(&kptConfig{ workingDir: ".", kpt: latest.KptDeploy{ - ApplyDir: test.applyDir, + Live: latest.KptLive{ + Apply: latest.KptApplyInventory{ + Dir: test.applyDir, + }, + }, }, }, nil) @@ -739,7 +759,6 @@ spec: func TestKpt_GetApplyDir(t *testing.T) { tests := []struct { description string - applyDir string live latest.KptLive expected string commands util.Command @@ -747,13 +766,21 @@ func TestKpt_GetApplyDir(t *testing.T) { }{ { description: "specified an invalid applyDir", - applyDir: "invalid_path", - shouldErr: true, + live: latest.KptLive{ + Apply: latest.KptApplyInventory{ + Dir: "invalid_path", + }, + }, + shouldErr: true, }, { description: "specified a valid applyDir", - applyDir: "valid_path", - expected: "valid_path", + live: latest.KptLive{ + Apply: latest.KptApplyInventory{ + Dir: "valid_path", + }, + }, + expected: "valid_path", }, { description: "unspecified applyDir", @@ -763,8 +790,10 @@ func TestKpt_GetApplyDir(t *testing.T) { { description: "unspecified applyDir with specified inventory-id and namespace", live: latest.KptLive{ - InventoryID: "1a23bcde-4f56-7891-a2bc-de34fabcde5f6", - InventoryNamespace: "foo", + Apply: latest.KptApplyInventory{ + InventoryID: "1a23bcde-4f56-7891-a2bc-de34fabcde5f6", + InventoryNamespace: "foo", + }, }, expected: ".kpt-hydrated", commands: testutil.CmdRunOut("kpt live init .kpt-hydrated --inventory-id 1a23bcde-4f56-7891-a2bc-de34fabcde5f6 --namespace foo", ""), @@ -779,10 +808,10 @@ func TestKpt_GetApplyDir(t *testing.T) { t.Override(&util.DefaultExecCommand, test.commands) tmpDir := t.NewTempDir().Chdir() - if test.applyDir == test.expected { + if test.live.Apply.Dir == test.expected { // 0755 is a permission setting where the owner can read, write, and execute. // Others can read and execute but not modify the directory. - os.Mkdir(test.applyDir, 0755) + os.Mkdir(test.live.Apply.Dir, 0755) } if test.description == "existing template resource in .kpt-hydrated" { @@ -792,8 +821,7 @@ func TestKpt_GetApplyDir(t *testing.T) { k := NewKptDeployer(&kptConfig{ workingDir: ".", kpt: latest.KptDeploy{ - ApplyDir: test.applyDir, - Live: test.live, + Live: test.live, }, }, nil) diff --git a/pkg/skaffold/schema/latest/config.go b/pkg/skaffold/schema/latest/config.go index 32c09c7be42..24510670b03 100644 --- a/pkg/skaffold/schema/latest/config.go +++ b/pkg/skaffold/schema/latest/config.go @@ -532,11 +532,11 @@ type KustomizeDeploy struct { // KptDeploy *alpha* uses the `kpt` CLI to manage and deploy manifests. type KptDeploy struct { - // ApplyDir is the path to the directory to deploy to the cluster. - ApplyDir string `yaml:"applyDir,omitempty"` - - // Dir is the path to the directory to run kpt functions against. - Dir string `yaml:"dir,omitempty"` + // Dir is the path to the config directory (Required). + // By default, the Dir contains the application configurations, + // [kustomize config files](https://kubectl.docs.kubernetes.io/pages/examples/kustomize.html) + // and [declarative kpt functions](https://googlecontainertools.github.io/kpt/guides/consumer/function/#declarative-run). + Dir string `yaml:"dir" yamltags:"required"` // Fn adds additional configurations for `kpt fn`. Fn KptFn `yaml:"fn,omitempty"` @@ -547,19 +547,21 @@ type KptDeploy struct { // KptFn adds additional configurations used when calling `kpt fn`. type KptFn struct { - // FnPath is a directory to read functions from instead of the configuration directory. + // FnPath is the directory to discover the declarative kpt functions. + // If not provided, kpt deployer uses `kpt.Dir`. FnPath string `yaml:"fnPath,omitempty"` - // Image is an image to be run as a function in lieu of running functions from a directory. + // Image is a kpt function image to run the configs imperatively. If provided, kpt.fn.fnPath + // will be ignored. Image string `yaml:"image,omitempty"` - // NetworkName is the docker network to run the container in (default "bridge"). + // NetworkName is the docker network name to run the kpt function containers (default "bridge"). NetworkName string `yaml:"networkName,omitempty"` - // GlobalScope sets global scope for functions. + // GlobalScope sets the global scope for the kpt functions. see `kpt help fn run`. GlobalScope bool `yaml:"globalScope,omitempty"` - // Network enables network access for functions that declare it. + // Network enables network access for the kpt function containers. Network bool `yaml:"network,omitempty"` // Mount is a list of storage options to mount to the fn image. @@ -568,20 +570,30 @@ type KptFn struct { // KptLive adds additional configurations used when calling `kpt live`. type KptLive struct { - // Apply adds additional configurations for `kpt live apply` commands. - Apply KptLiveApply `yaml:"apply,omitempty"` + // Apply sets the kpt inventory directory. + Apply KptApplyInventory `yaml:"apply,omitempty"` + + // Options adds additional configurations for `kpt live apply` commands. + Options KptApplyOptions `yaml:"options,omitempty"` +} + +// KptApplyInventory sets the kpt inventory directory. +type KptApplyInventory struct { + // Dir is equivalent to the dir in `kpt live apply `. If not provided, + // kpt deployer will create a hidden directory `.kpt-hydrated` to store the manipulated + // resource output and the kpt inventory-template.yaml file. + Dir string `yaml:"dir,omitempty"` - // InventoryID is the identifier for a group of applied resources. - // This configuration is used when users do not specify `KptDeploy.ApplyDir` - // and `.kpt-hydrated/inventory-template.yaml` does not exist. + // InventoryID *alpha* is the identifier for a group of applied resources. + // This value is only needed when the `kpt live` is working on a pre-applied cluster resources. InventoryID string `yaml:"inventoryID,omitempty"` - // InventoryNamespace sets the namespace scope for `kpt live init`. + // InventoryNamespace *alpha* sets the inventory namespace. InventoryNamespace string `yaml:"inventoryNamespace,omitempty"` } -// KptLiveApply adds additional configurations used when calling `kpt live apply`. -type KptLiveApply struct { +// KptApplyOptions adds additional configurations used when calling `kpt live apply`. +type KptApplyOptions struct { // PollPeriod sets for the polling period for resource statuses. Default to 2s. PollPeriod string `yaml:"pollPeriod,omitempty"`