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

feat: add pvc-size flag to deploy command (#851) #1598

56 changes: 34 additions & 22 deletions cmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import (
"github.com/AlecAivazis/survey/v2"
"github.com/ory/viper"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/api/resource"
"knative.dev/client/pkg/util"

"knative.dev/func/pkg/builders"
"knative.dev/func/pkg/builders/buildpacks"
"knative.dev/func/pkg/builders/s2i"
Expand Down Expand Up @@ -79,7 +79,7 @@ DESCRIPTION
EXAMPLES

o Deploy the function
$ {{.Name}} deploy
$ {{rootCmdUse}} deploy
grafvonb marked this conversation as resolved.
Show resolved Hide resolved

o Deploy the function using interactive prompts. This is useful for the first
deployment, since most settings will be remembered for future deployments.
Expand Down Expand Up @@ -116,7 +116,7 @@ EXAMPLES

`,
SuggestFor: []string{"delpoy", "deplyo"},
PreRunE: bindEnv("confirm", "env", "git-url", "git-branch", "git-dir", "remote", "build", "builder", "builder-image", "image", "registry", "push", "platform", "namespace", "path", "verbose"),
PreRunE: bindEnv("confirm", "env", "git-url", "git-branch", "git-dir", "remote", "build", "builder", "builder-image", "image", "registry", "push", "platform", "namespace", "path", "verbose", "pvc-size"),
RunE: func(cmd *cobra.Command, args []string) error {
return runDeploy(cmd, newClient)
},
Expand All @@ -137,8 +137,8 @@ EXAMPLES
// Flags
//
// Globally-Configurable Flags:
// Options whose value may be defined globally may also exist on the
// contextually relevant function; but sets are flattened via cfg.Apply(f)
// Options whose value may be defined globally may also exist on the
// contextually relevant function; but sets are flattened via cfg.Apply(f)
cmd.Flags().StringP("builder", "b", cfg.Builder,
fmt.Sprintf("Builder to use when creating the function's container. Currently supported builders are %s.", KnownBuilders()))
cmd.Flags().StringP("registry", "r", cfg.Registry,
Expand All @@ -147,10 +147,10 @@ EXAMPLES
"Deploy into a specific namespace. Will use function's current namespace by default if already deployed, and the currently active namespace if it can be determined. (Env: $FUNC_NAMESPACE)")

// Function-Context Flags:
// Options whose value is avaolable on the function with context only
// Options whose value is available on the function with context only
// (persisted but not globally configurable)
builderImage := f.Build.BuilderImages[f.Build.Builder]
cmd.Flags().StringP("builder-image", "", builderImage,
cmd.Flags().String("builder-image", builderImage,
"Specify a custom builder image for use by the builder other than its default. ($FUNC_BUILDER_IMAGE)")
cmd.Flags().StringP("image", "i", f.Image, "Full image name in the form [registry]/[namespace]/[name]:[tag]@[digest]. This option takes precedence over --registry. Specifying digest is optional, but if it is given, 'build' and 'push' phases are disabled. (Env: $FUNC_IMAGE)")

Expand All @@ -162,19 +162,21 @@ EXAMPLES
cmd.Flags().StringP("git-branch", "t", f.Build.Git.Revision,
"Git revision (branch) to be used when deploying via the Git repository (Env: $FUNC_GIT_BRANCH)")
cmd.Flags().StringP("git-dir", "d", f.Build.Git.ContextDir,
"Directory in the Git repository containing the function (default is the root) (Env: $FUNC_GIT_DIR))")
cmd.Flags().BoolP("remote", "", f.Deploy.Remote,
"Trigger a remote deployment. Default is to deploy and build from the local system (Env: $FUNC_REMOTE)")
"Directory in the Git repository containing the function (default is the root) (Env: $FUNC_GIT_DIR)")
cmd.Flags().Bool("remote", f.Deploy.Remote,
"Trigger a remote deployment. Default is to deploy and build from the local system (Env: $FUNC_REMOTE)")
cmd.Flags().String("pvc-size", fn.DefaultPersistentVolumeClaimSize,
"Configure the PVC size used by a pipeline during remote build.")

// Static Flags:
// Options which have statc defaults only (not globally configurable nor
// Options which have static defaults only (not globally configurable nor
// persisted with the function)
cmd.Flags().StringP("build", "", "auto",
cmd.Flags().String("build", "auto",
"Build the function. [auto|true|false]. (Env: $FUNC_BUILD)")
cmd.Flags().Lookup("build").NoOptDefVal = "true" // register `--build` as equivalient to `--build=true`
cmd.Flags().BoolP("push", "u", true,
"Push the function image to registry before deploying. (Env: $FUNC_PUSH)")
cmd.Flags().StringP("platform", "", "",
cmd.Flags().String("platform", "",
matejvasek marked this conversation as resolved.
Show resolved Hide resolved
"Optionally specify a specific platform to build for (e.g. linux/amd64). (Env: $FUNC_PLATFORM)")

matejvasek marked this conversation as resolved.
Show resolved Hide resolved
// Oft-shared flags:
Expand Down Expand Up @@ -369,6 +371,9 @@ type deployConfig struct {
// Remote indicates the deployment (and possibly build) process are to
// be triggered in a remote environment rather than run locally.
Remote bool

// PVCSize configures the PVC size used by the pipeline if --remote flag is set.
PVCSize string
}

// newDeployConfig creates a buildConfig populated from command flags and
Expand All @@ -383,10 +388,11 @@ func newDeployConfig(cmd *cobra.Command) (c deployConfig) {
GitURL: viper.GetString("git-url"),
Namespace: viper.GetString("namespace"),
Remote: viper.GetBool("remote"),
PVCSize: viper.GetString("pvc-size"),
}
// NOTE: .Env shold be viper.GetStringSlice, but this returns unparsed
// NOTE: .Env should be viper.GetStringSlice, but this returns unparsed
// results and appears to be an open issue since 2017:
// https://github.com/spf13/viper/issues/380
// https://github.com/spf13/viper/issues/380
var err error
if c.Env, err = cmd.Flags().GetStringArray("env"); err != nil {
fmt.Fprintf(cmd.OutOrStdout(), "error reading envs: %v", err)
Expand All @@ -402,7 +408,7 @@ func (c deployConfig) Configure(f fn.Function) (fn.Function, error) {

// Bubble configure request
//
// The member values on the config object now take absolute precidence
// The member values on the config object now take absolute precedence
// because they include 1) static config 2) user's global config
// 3) Environment variables and 4) flag values (which were set with their
// default being 1-3).
Expand All @@ -411,9 +417,15 @@ func (c deployConfig) Configure(f fn.Function) (fn.Function, error) {
// Configure basic members
f.Build.Git.URL = c.GitURL
f.Build.Git.ContextDir = c.GitDir
f.Build.Git.Revision = c.GitBranch // TODO: shouild match; perhaps "refSpec"
f.Build.Git.Revision = c.GitBranch // TODO: should match; perhaps "refSpec"
f.Deploy.Namespace = c.Namespace
f.Deploy.Remote = c.Remote
// Validate if PVC size can be parsed to quantity
_, err = resource.ParseQuantity(c.PVCSize)
if err != nil {
return f, fmt.Errorf("cannot parse the provided PVC size '%s' due to: %w", c.PVCSize, err)
}
f.Build.PVCSize = c.PVCSize

// ImageDigest
// Parsed off f.Image if provided. Deploying adds the ability to specify a
Expand Down Expand Up @@ -456,7 +468,7 @@ func applyEnvs(current []fn.Env, args []string) (final []fn.Env, err error) {
return
}

// Prompt the user with value of config members, allowing for interaractive changes.
// Prompt the user with value of config members, allowing for interactive changes.
// Skipped if not in an interactive terminal (non-TTY), or if --yes (agree to
// all prompts) was explicitly set.
func (c deployConfig) Prompt() (deployConfig, error) {
Expand Down Expand Up @@ -519,7 +531,7 @@ func (c deployConfig) Validate(cmd *cobra.Command) (err error) {
}

// Check Image Digest was included
// (will be set on the function during .Configure
// (will be set on the function during .Configure)
var digest string
if digest, err = imageDigest(c.Image); err != nil {
return
Expand Down Expand Up @@ -561,7 +573,7 @@ func (c deployConfig) Validate(cmd *cobra.Command) (err error) {

// NOTE: There is no explicit check for --registry or --image here, because
// this logic is baked into core, which will validate the cases and return
// an fn.ErrNameRequired, fn.ErrImageRequired etc as needed.
// an fn.ErrNameRequired, fn.ErrImageRequired etc. as needed.

return
}
Expand Down Expand Up @@ -619,7 +631,7 @@ func printDeployMessages(out io.Writer, cfg deployConfig) {
// Namespace Changing
// -------------------
// If the target namespace is provided but differs from active, warn because
// the function wont be visible to other commands such as kubectl unless
// the function won't be visible to other commands such as kubectl unless
// context namespace is switched.
activeNamespace, err := k8s.GetNamespace("")
if err == nil && targetNamespace != "" && targetNamespace != activeNamespace {
Expand All @@ -640,7 +652,7 @@ func printDeployMessages(out io.Writer, cfg deployConfig) {
// However, when building _locally_ thereafter, the deploy command should
// prefer the local source code, ignoring the values for --git-url etc.
// Since this might be confusing, a warning is issued below that the local
// function source does include a reference to a git reposotiry, but that it
// function source does include a reference to a git repository, but that it
// will be ignored in favor of the local source code since --remote was not
// specified.
if !cfg.Remote && (cfg.GitURL != "" || cfg.GitBranch != "" || cfg.GitDir != "") {
Expand Down
9 changes: 5 additions & 4 deletions docs/reference/func_deploy.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,17 +108,18 @@ func deploy
--builder-image string Specify a custom builder image for use by the builder other than its default. ($FUNC_BUILDER_IMAGE)
-c, --confirm Prompt to confirm options interactively (Env: $FUNC_CONFIRM)
-e, --env stringArray Environment variable to set in the form NAME=VALUE. You may provide this flag multiple times for setting multiple environment variables. To unset, specify the environment variable name followed by a "-" (e.g., NAME-).
-t, --git-branch string Git revision (branch) to be used when deploying via a git repository (Env: $FUNC_GIT_BRANCH)
-d, --git-dir string Directory in the repo to find the function (default is the root) (Env: $FUNC_GIT_DIR)
-g, --git-url string Repo url to push the code to be built (Env: $FUNC_GIT_URL)
-t, --git-branch string Git revision (branch) to be used when deploying via the Git repository (Env: $FUNC_GIT_BRANCH)
-d, --git-dir string Directory in the Git repository containing the function (default is the root) (Env: $FUNC_GIT_DIR)
-g, --git-url string Repository url containing the function to build (Env: $FUNC_GIT_URL)
-h, --help help for deploy
-i, --image string Full image name in the form [registry]/[namespace]/[name]:[tag]@[digest]. This option takes precedence over --registry. Specifying digest is optional, but if it is given, 'build' and 'push' phases are disabled. (Env: $FUNC_IMAGE)
-n, --namespace string Deploy into a specific namespace. Will use function's current namespace by default if already deployed, and the currently active namespace if it can be determined. (Env: $FUNC_NAMESPACE)
-p, --path string Path to the function. Default is current directory (Env: $FUNC_PATH)
--platform string Optionally specify a specific platform to build for (e.g. linux/amd64). (Env: $FUNC_PLATFORM)
-u, --push Push the function image to registry before deploying. (Env: $FUNC_PUSH) (default true)
--pvc-size string Configure the PVC size used by a pipeline during remote build. (default "256Mi")
-r, --registry string Container registry + registry namespace. (ex 'ghcr.io/myuser'). The full image name is automatically determined using this along with function name. (Env: $FUNC_REGISTRY)
--remote Trigger a remote deployment. Default is to deploy and build from the local system (Env: $FUNC_REMOTE)
--remote Trigger a remote deployment. Default is to deploy and build from the local system (Env: $FUNC_REMOTE)
-v, --verbose Print verbose logs ($FUNC_VERBOSE)
```

Expand Down
10 changes: 10 additions & 0 deletions pkg/functions/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ const (
// existence indicates the function has been built, and whose content is
// a fingerprint of the filesystem at the time of the build.
buildstamp = "built"

// DefaultPersistentVolumeClaimSize represents default size of PVC created for a Pipeline
DefaultPersistentVolumeClaimSize string = "256Mi"
)

// Function
Expand Down Expand Up @@ -115,6 +118,10 @@ type BuildSpec struct {

// Build Env variables to be set
BuildEnvs []Env `yaml:"buildEnvs,omitempty"`

// PVCSize specifies the size of persistent volume claim used to store function
// when using deployment and remote build process (only relevant when Remote is true).
PVCSize string `yaml:"pvcSize,omitempty"`
}

// RunSpec
Expand Down Expand Up @@ -172,6 +179,9 @@ func NewFunctionWith(defaults Function) Function {
if defaults.Build.BuilderImages == nil {
defaults.Build.BuilderImages = make(map[string]string)
}
if defaults.Build.PVCSize == "" {
defaults.Build.PVCSize = DefaultPersistentVolumeClaimSize
}
if defaults.Deploy.Annotations == nil {
defaults.Deploy.Annotations = make(map[string]string)
}
Expand Down
7 changes: 0 additions & 7 deletions pkg/pipelines/tekton/defaults.go

This file was deleted.

2 changes: 1 addition & 1 deletion pkg/pipelines/tekton/pipelines_pac_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ func (pp *PipelinesProvider) createClusterResources(ctx context.Context, f fn.Fu
metadata.RegistryPassword = creds.Password
metadata.RegistryServer = registry

err = createPipelinePersistentVolumeClaim(ctx, f, pp.namespace, labels, DefaultPersistentVolumeClaimSize)
err = createPipelinePersistentVolumeClaim(ctx, f, pp.namespace, labels)
if err != nil {
return err
}
Expand Down
10 changes: 7 additions & 3 deletions pkg/pipelines/tekton/pipeplines_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ func (pp *PipelinesProvider) Run(ctx context.Context, f fn.Function) error {
labels = pp.decorator.UpdateLabels(f, labels)
}

err = createPipelinePersistentVolumeClaim(ctx, f, pp.namespace, labels, DefaultPersistentVolumeClaimSize)
err = createPipelinePersistentVolumeClaim(ctx, f, pp.namespace, labels)
if err != nil {
return err
}
Expand Down Expand Up @@ -448,8 +448,12 @@ func getFailedPipelineRunLog(ctx context.Context, pr *v1beta1.PipelineRun, names
// allows simple mocking in unit tests, use with caution regarding concurrency
var createPersistentVolumeClaim = k8s.CreatePersistentVolumeClaim

func createPipelinePersistentVolumeClaim(ctx context.Context, f fn.Function, namespace string, labels map[string]string, size int64) error {
err := createPersistentVolumeClaim(ctx, getPipelinePvcName(f), namespace, labels, f.Deploy.Annotations, corev1.ReadWriteOnce, *resource.NewQuantity(size, resource.DecimalSI))
func createPipelinePersistentVolumeClaim(ctx context.Context, f fn.Function, namespace string, labels map[string]string) error {
pvcs, err := resource.ParseQuantity(f.Build.PVCSize)
if err != nil {
return fmt.Errorf("PVC size value cannot be parsed due to: %v", err)
}
err = createPersistentVolumeClaim(ctx, getPipelinePvcName(f), namespace, labels, f.Deploy.Annotations, corev1.ReadWriteOnce, pvcs)
if err != nil && !errors.IsAlreadyExists(err) {
return fmt.Errorf("problem creating persistent volume claim: %v", err)
}
Expand Down
12 changes: 6 additions & 6 deletions pkg/pipelines/tekton/pipeplines_provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func Test_createPipelinePersistentVolumeClaim(t *testing.T) {
f fn.Function
namespace string
labels map[string]string
size int64
size string
}
tests := []struct {
name string
Expand All @@ -96,7 +96,7 @@ func Test_createPipelinePersistentVolumeClaim(t *testing.T) {
f: fn.Function{},
namespace: "test-ns",
labels: nil,
size: DefaultPersistentVolumeClaimSize,
size: fn.DefaultPersistentVolumeClaimSize,
},
mock: func(ctx context.Context, name, namespaceOverride string, labels map[string]string, annotations map[string]string, accessMode corev1.PersistentVolumeAccessMode, resourceRequest resource.Quantity) (err error) {
return errors.New("creation of pvc failed")
Expand All @@ -110,7 +110,7 @@ func Test_createPipelinePersistentVolumeClaim(t *testing.T) {
f: fn.Function{},
namespace: "test-ns",
labels: nil,
size: DefaultPersistentVolumeClaimSize,
size: fn.DefaultPersistentVolumeClaimSize,
},
mock: func(ctx context.Context, name, namespaceOverride string, labels map[string]string, annotations map[string]string, accessMode corev1.PersistentVolumeAccessMode, resourceRequest resource.Quantity) (err error) {
return &apiErrors.StatusError{ErrStatus: metav1.Status{Reason: metav1.StatusReasonAlreadyExists}}
Expand All @@ -119,13 +119,13 @@ func Test_createPipelinePersistentVolumeClaim(t *testing.T) {
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// save current function and restore it at the end
t.Run(tt.name, func(t *testing.T) { // save current function and restore it at the end
old := createPersistentVolumeClaim
defer func() { createPersistentVolumeClaim = old }()

createPersistentVolumeClaim = tt.mock
if err := createPipelinePersistentVolumeClaim(tt.args.ctx, tt.args.f, tt.args.namespace, tt.args.labels, tt.args.size); (err != nil) != tt.wantErr {
tt.args.f.Build.PVCSize = tt.args.size
if err := createPipelinePersistentVolumeClaim(tt.args.ctx, tt.args.f, tt.args.namespace, tt.args.labels); (err != nil) != tt.wantErr {
t.Errorf("createPipelinePersistentVolumeClaim() error = %v, wantErr %v", err, tt.wantErr)
}
})
Expand Down
4 changes: 4 additions & 0 deletions schema/func_yaml-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@
},
"type": "array",
"description": "Build Env variables to be set"
},
"pvcSize": {
"type": "string",
"description": "PVCSize specifies the size of persistent volume claim used to store function\nwhen using deployment and remote build process (only relevant when Remote is true)."
}
},
"additionalProperties": false,
Expand Down