feat: remote storage class (#2693)

* feat: remote storage class

* why isn't the schema regenerated on each make
This commit is contained in:
Luke Kingland 2025-02-19 16:35:47 +09:00 committed by GitHub
parent d548e3fe45
commit 1d26629b51
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 55 additions and 33 deletions

View File

@ -35,7 +35,7 @@ SYNOPSIS
[-b|--build] [--builder] [--builder-image] [-p|--push]
[--domain] [--platform] [--build-timestamp] [--pvc-size]
[--service-account] [-c|--confirm] [-v|--verbose]
[--registry-insecure]
[--registry-insecure] [--remote-storage-class]
DESCRIPTION
@ -127,7 +127,7 @@ EXAMPLES
`,
SuggestFor: []string{"delpoy", "deplyo"},
PreRunE: bindEnv("build", "build-timestamp", "builder", "builder-image", "confirm", "domain", "env", "git-branch", "git-dir", "git-url", "image", "namespace", "path", "platform", "push", "pvc-size", "service-account", "registry", "registry-insecure", "remote", "username", "password", "token", "verbose"),
PreRunE: bindEnv("build", "build-timestamp", "builder", "builder-image", "confirm", "domain", "env", "git-branch", "git-dir", "git-url", "image", "namespace", "path", "platform", "push", "pvc-size", "service-account", "registry", "registry-insecure", "remote", "username", "password", "token", "verbose", "remote-storage-class"),
RunE: func(cmd *cobra.Command, args []string) error {
return runDeploy(cmd, newClient)
},
@ -179,6 +179,8 @@ EXAMPLES
"Directory in the Git repository containing the function (default is the root) ($FUNC_GIT_DIR)")
cmd.Flags().BoolP("remote", "R", f.Local.Remote,
"Trigger a remote deployment. Default is to deploy and build from the local system ($FUNC_REMOTE)")
cmd.Flags().StringP("remote-storage-class", "", f.Build.RemoteStorageClass,
"Specify a storage class to use for the volume on-cluster during remote builds")
cmd.Flags().String("pvc-size", f.Build.PVCSize,
"When triggering a remote deployment, set a custom volume size to allocate for the build operation ($FUNC_PVC_SIZE)")
cmd.Flags().String("service-account", f.Deploy.ServiceAccountName,
@ -517,6 +519,10 @@ type deployConfig struct {
// be triggered in a remote environment rather than run locally.
Remote bool
// RemoteStorageClass defines the storage class to use for the remote
// volume when building on-cluster.
RemoteStorageClass string
// PVCSize configures the PVC size used by the pipeline if --remote flag is set.
PVCSize string
@ -538,6 +544,7 @@ func newDeployConfig(cmd *cobra.Command) deployConfig {
GitURL: viper.GetString("git-url"),
Namespace: viper.GetString("namespace"),
Remote: viper.GetBool("remote"),
RemoteStorageClass: viper.GetString("remote-storage-class"),
PVCSize: viper.GetString("pvc-size"),
Timestamp: viper.GetBool("build-timestamp"),
ServiceAccountName: viper.GetString("service-account"),
@ -573,6 +580,7 @@ func (c deployConfig) Configure(f fn.Function) (fn.Function, error) {
f.Build.Git.URL = c.GitURL
f.Build.Git.ContextDir = c.GitDir
f.Build.Git.Revision = c.GitBranch // TODO: should match; perhaps "refSpec"
f.Build.RemoteStorageClass = c.RemoteStorageClass
f.Deploy.ServiceAccountName = c.ServiceAccountName
f.Local.Remote = c.Remote

View File

@ -14,7 +14,7 @@ SYNOPSIS
[-b|--build] [--builder] [--builder-image] [-p|--push]
[--domain] [--platform] [--build-timestamp] [--pvc-size]
[--service-account] [-c|--confirm] [-v|--verbose]
[--registry-insecure]
[--registry-insecure] [--remote-storage-class]
DESCRIPTION
@ -113,28 +113,29 @@ func deploy
### Options
```
--build string[="true"] Build the function. [auto|true|false]. ($FUNC_BUILD) (default "auto")
--build-timestamp Use the actual time as the created time for the docker image. This is only useful for buildpacks builder.
-b, --builder string Builder to use when creating the function's container. Currently supported builders are "pack" and "s2i". (default "pack")
--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 ($FUNC_CONFIRM)
--domain string Domain to use for the function's route. Cluster must be configured with domain matching for the given domain (ignored if unrecognized) ($FUNC_DOMAIN)
-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 the Git repository ($FUNC_GIT_BRANCH)
-d, --git-dir string Directory in the Git repository containing the function (default is the root) ($FUNC_GIT_DIR)
-g, --git-url string Repository url containing the function to build ($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. ($FUNC_IMAGE)
-n, --namespace string Deploy into a specific namespace. Will use the function's current namespace by default if already deployed, and the currently active context if it can be determined. ($FUNC_NAMESPACE) (default "default")
-p, --path string Path to the function. Default is current directory ($FUNC_PATH)
--platform string Optionally specify a specific platform to build for (e.g. linux/amd64). ($FUNC_PLATFORM)
-u, --push Push the function image to registry before deploying. ($FUNC_PUSH) (default true)
--pvc-size string When triggering a remote deployment, set a custom volume size to allocate for the build operation ($FUNC_PVC_SIZE)
-r, --registry string Container registry + registry namespace. (ex 'ghcr.io/myuser'). The full image name is automatically determined using this along with function name. ($FUNC_REGISTRY)
--registry-insecure Skip TLS certificate verification when communicating in HTTPS with the registry ($FUNC_REGISTRY_INSECURE)
-R, --remote Trigger a remote deployment. Default is to deploy and build from the local system ($FUNC_REMOTE)
--service-account string Service account to be used in the deployed function ($FUNC_SERVICE_ACCOUNT)
-v, --verbose Print verbose logs ($FUNC_VERBOSE)
--build string[="true"] Build the function. [auto|true|false]. ($FUNC_BUILD) (default "auto")
--build-timestamp Use the actual time as the created time for the docker image. This is only useful for buildpacks builder.
-b, --builder string Builder to use when creating the function's container. Currently supported builders are "pack" and "s2i". (default "pack")
--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 ($FUNC_CONFIRM)
--domain string Domain to use for the function's route. Cluster must be configured with domain matching for the given domain (ignored if unrecognized) ($FUNC_DOMAIN)
-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 the Git repository ($FUNC_GIT_BRANCH)
-d, --git-dir string Directory in the Git repository containing the function (default is the root) ($FUNC_GIT_DIR)
-g, --git-url string Repository url containing the function to build ($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. ($FUNC_IMAGE)
-n, --namespace string Deploy into a specific namespace. Will use the function's current namespace by default if already deployed, and the currently active context if it can be determined. ($FUNC_NAMESPACE) (default "default")
-p, --path string Path to the function. Default is current directory ($FUNC_PATH)
--platform string Optionally specify a specific platform to build for (e.g. linux/amd64). ($FUNC_PLATFORM)
-u, --push Push the function image to registry before deploying. ($FUNC_PUSH) (default true)
--pvc-size string When triggering a remote deployment, set a custom volume size to allocate for the build operation ($FUNC_PVC_SIZE)
-r, --registry string Container registry + registry namespace. (ex 'ghcr.io/myuser'). The full image name is automatically determined using this along with function name. ($FUNC_REGISTRY)
--registry-insecure Skip TLS certificate verification when communicating in HTTPS with the registry ($FUNC_REGISTRY_INSECURE)
-R, --remote Trigger a remote deployment. Default is to deploy and build from the local system ($FUNC_REMOTE)
--remote-storage-class string Specify a storage class to use for the volume on-cluster during remote builds
--service-account string Service account to be used in the deployed function ($FUNC_SERVICE_ACCOUNT)
-v, --verbose Print verbose logs ($FUNC_VERBOSE)
```
### SEE ALSO

View File

@ -141,6 +141,10 @@ type BuildSpec struct {
// when using deployment and remote build process (only relevant when Remote is true).
PVCSize string `yaml:"pvcSize,omitempty"`
// RemoteStorageClass specifies the storage class to use for the volume used
// on-cluster during when built remotely.
RemoteStorageClass string `yaml:"remoteStorageClass,omitempty"`
// Image stores last built image name NOT in func.yaml, but instead
// in .func/built-image
Image string `yaml:"-"`

View File

@ -32,7 +32,7 @@ func GetPersistentVolumeClaim(ctx context.Context, name, namespaceOverride strin
return client.CoreV1().PersistentVolumeClaims(namespace).Get(ctx, name, metav1.GetOptions{})
}
func CreatePersistentVolumeClaim(ctx context.Context, name, namespaceOverride string, labels map[string]string, annotations map[string]string, accessMode corev1.PersistentVolumeAccessMode, resourceRequest resource.Quantity) (err error) {
func CreatePersistentVolumeClaim(ctx context.Context, name, namespaceOverride string, labels map[string]string, annotations map[string]string, accessMode corev1.PersistentVolumeAccessMode, resourceRequest resource.Quantity, storageClassName string) (err error) {
client, namespace, err := NewClientAndResolvedNamespace(namespaceOverride)
if err != nil {
return
@ -52,8 +52,13 @@ func CreatePersistentVolumeClaim(ctx context.Context, name, namespaceOverride st
},
},
}
pvc.Spec.Resources.Requests[corev1.ResourceStorage] = resourceRequest
if storageClassName != "" {
pvc.Spec.StorageClassName = &storageClassName
}
_, err = client.CoreV1().PersistentVolumeClaims(namespace).Create(ctx, pvc, metav1.CreateOptions{})
return
}

View File

@ -34,8 +34,8 @@ func TestUploadToVolume(t *testing.T) {
testingPVCName := "testing-pvc-" + rnd
err = k8s.CreatePersistentVolumeClaim(ctx, testingPVCName, testingNS,
nil, nil,
corev1.ReadWriteOnce, *resource.NewQuantity(1024, resource.DecimalSI))
nil, nil, corev1.ReadWriteOnce,
*resource.NewQuantity(1024, resource.DecimalSI), "")
if err != nil {
t.Fatal(err)
}

View File

@ -568,7 +568,7 @@ func createPipelinePersistentVolumeClaim(ctx context.Context, f fn.Function, nam
return fmt.Errorf("PVC size value could not be parsed. %w", err)
}
}
err = createPersistentVolumeClaim(ctx, getPipelinePvcName(f), namespace, labels, f.Deploy.Annotations, corev1.ReadWriteOnce, pvcs)
err = createPersistentVolumeClaim(ctx, getPipelinePvcName(f), namespace, labels, f.Deploy.Annotations, corev1.ReadWriteOnce, pvcs, f.Build.RemoteStorageClass)
if err != nil && !k8serrors.IsAlreadyExists(err) {
return fmt.Errorf("problem creating persistent volume claim: %v", err)
}

View File

@ -74,7 +74,7 @@ func TestSourcesAsTarStream(t *testing.T) {
}
func Test_createPipelinePersistentVolumeClaim(t *testing.T) {
type mockType func(ctx context.Context, name, namespaceOverride string, labels map[string]string, annotations map[string]string, accessMode corev1.PersistentVolumeAccessMode, resourceRequest resource.Quantity) (err error)
type mockType func(ctx context.Context, name, namespaceOverride string, labels map[string]string, annotations map[string]string, accessMode corev1.PersistentVolumeAccessMode, resourceRequest resource.Quantity, storageClass string) (err error)
type args struct {
ctx context.Context
@ -98,7 +98,7 @@ func Test_createPipelinePersistentVolumeClaim(t *testing.T) {
labels: nil,
size: DefaultPersistentVolumeClaimSize.String(),
},
mock: func(ctx context.Context, name, namespaceOverride string, labels map[string]string, annotations map[string]string, accessMode corev1.PersistentVolumeAccessMode, resourceRequest resource.Quantity) (err error) {
mock: func(ctx context.Context, name, namespaceOverride string, labels map[string]string, annotations map[string]string, accessMode corev1.PersistentVolumeAccessMode, resourceRequest resource.Quantity, storageClass string) (err error) {
return errors.New("creation of pvc failed")
},
wantErr: true,
@ -112,7 +112,7 @@ func Test_createPipelinePersistentVolumeClaim(t *testing.T) {
labels: nil,
size: DefaultPersistentVolumeClaimSize.String(),
},
mock: func(ctx context.Context, name, namespaceOverride string, labels map[string]string, annotations map[string]string, accessMode corev1.PersistentVolumeAccessMode, resourceRequest resource.Quantity) (err error) {
mock: func(ctx context.Context, name, namespaceOverride string, labels map[string]string, annotations map[string]string, accessMode corev1.PersistentVolumeAccessMode, resourceRequest resource.Quantity, storageClass string) (err error) {
return &apiErrors.StatusError{ErrStatus: metav1.Status{Reason: metav1.StatusReasonAlreadyExists}}
},
wantErr: false,
@ -126,7 +126,7 @@ func Test_createPipelinePersistentVolumeClaim(t *testing.T) {
labels: nil,
size: DefaultPersistentVolumeClaimSize.String(),
},
mock: func(ctx context.Context, name, namespaceOverride string, labels map[string]string, annotations map[string]string, accessMode corev1.PersistentVolumeAccessMode, resourceRequest resource.Quantity) (err error) {
mock: func(ctx context.Context, name, namespaceOverride string, labels map[string]string, annotations map[string]string, accessMode corev1.PersistentVolumeAccessMode, resourceRequest resource.Quantity, storageClass string) (err error) {
return errors.New("no namespace defined")
},
wantErr: true,

View File

@ -44,6 +44,10 @@
"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)."
},
"remoteStorageClass": {
"type": "string",
"description": "RemoteStorageClass specifies the storage class to use for the volume used\non-cluster during when built remotely."
}
},
"additionalProperties": false,