Skip to content

Commit

Permalink
make function volumes dependency-free
Browse files Browse the repository at this point in the history
Signed-off-by: Zuhair AlSader <zuhair@koor.tech>
  • Loading branch information
zalsader committed Apr 27, 2023
1 parent cfc793b commit ad218dc
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 32 deletions.
2 changes: 1 addition & 1 deletion cmd/config_volumes.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ func runAddVolumesPrompt(ctx context.Context, f fn.Function) (err error) {
case optionSecret:
newVolume.Secret = &selectedResource
case optionPersistentVolumeClaim:
newVolume.PresistentVolumeClaim = &fn.PersistentVolumeClaim{ClaimName: selectedResource}
newVolume.PresistentVolumeClaim = &fn.PersistentVolumeClaim{ClaimName: &selectedResource}
case optionEmptyDir:
newVolume.EmptyDir = &fn.EmptyDir{}
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/functions/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ func (f Function) ImageName() (image string, err error) {
// registry/parent-namespace/namespace ('quay.io/project/alice') provided
image = f.Registry + "/" + f.Name
} else if len(registryTokens) > 3 { // the name of the image is also provided `quay.io/alice/my.function.name`
return "", fmt.Errorf("registry should be either 'namespace', 'registry/namespace' or 'registry/parent/namespace', the name of the image will be derived from the function name.")
return "", fmt.Errorf("registry should be either 'namespace', 'registry/namespace' or 'registry/parent/namespace', the name of the image will be derived from the function name")
}

// Explicitly append :latest tag. We expect source control to drive
Expand Down
34 changes: 23 additions & 11 deletions pkg/functions/function_volumes.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
package functions

import (
"fmt"

corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
)
import "fmt"

type Volume struct {
Secret *string `yaml:"secret,omitempty" jsonschema:"oneof_required=secret"`
Expand All @@ -18,25 +13,30 @@ type Volume struct {
type PersistentVolumeClaim struct {
// claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume.
// More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
ClaimName string `yaml:"claimName"`
ClaimName *string `yaml:"claimName,omitempty"`
// readOnly Will force the ReadOnly setting in VolumeMounts.
// Default false.
ReadOnly bool `yaml:"readOnly,omitempty"`
}

const (
StorageMediumDefault = "" // use whatever the default is for the node, assume anything we don't explicitly handle is this
StorageMediumMemory = "Memory" // use memory (e.g. tmpfs on linux)
)

type EmptyDir struct {
// medium represents what type of storage medium should back this directory.
// The default is "" which means to use the node's default medium.
// Must be an empty string (default) or Memory.
// More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir
Medium corev1.StorageMedium `yaml:"medium,omitempty"`
Medium string `yaml:"medium,omitempty"`
// sizeLimit is the total amount of local storage required for this EmptyDir volume.
// The size limit is also applicable for memory medium.
// The maximum usage on memory medium EmptyDir would be the minimum value between
// the SizeLimit specified here and the sum of memory limits of all containers in a pod.
// The default is nil which means that the limit is undefined.
// More info: http://kubernetes.io/docs/user-guide/volumes#emptydir
SizeLimit *resource.Quantity `yaml:"sizeLimit,omitempty"`
SizeLimit *string `yaml:"sizeLimit,omitempty"`
}

func (v Volume) String() string {
Expand All @@ -46,9 +46,18 @@ func (v Volume) String() string {
} else if v.Secret != nil {
result = fmt.Sprintf("Secret \"%s\"", *v.Secret)
} else if v.PresistentVolumeClaim != nil {
result = fmt.Sprintf("PersistentVolumeClaim \"%s\"", v.PresistentVolumeClaim.ClaimName)
result = "PersistentVolumeClaim"
if v.PresistentVolumeClaim.ClaimName != nil {
result += fmt.Sprintf(" \"%s\"", *v.PresistentVolumeClaim.ClaimName)
}
} else if v.EmptyDir != nil {
result = "EmptyDir"
if v.EmptyDir.Medium == StorageMediumMemory {
result += " in memory"
}
if v.EmptyDir.SizeLimit != nil {
result += fmt.Sprintf(" with size limit \"%s\"", *v.EmptyDir.SizeLimit)
}
} else {
result = "No volume type"
}
Expand Down Expand Up @@ -85,11 +94,14 @@ func validateVolumes(volumes []Volume) (errors []string) {

if vol.PresistentVolumeClaim != nil {
numVolumes++
if vol.PresistentVolumeClaim.ClaimName == nil {
errors = append(errors, fmt.Sprintf("volume entry #%d (%s) is missing claim name", i, vol))
}
}

if vol.EmptyDir != nil {
numVolumes++
if vol.EmptyDir.Medium != corev1.StorageMediumDefault && vol.EmptyDir.Medium != corev1.StorageMediumMemory {
if vol.EmptyDir.Medium != StorageMediumDefault && vol.EmptyDir.Medium != StorageMediumMemory {
errors = append(errors, fmt.Sprintf("volume entry #%d (%s) has invalid storage medium (%s)", i, vol, vol.EmptyDir.Medium))
}
}
Expand Down
6 changes: 4 additions & 2 deletions pkg/functions/function_volumes_unit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ func Test_validateVolumes(t *testing.T) {
secret := "secret"
secret2 := "secret2"
cm := "configMap"
pvcName := "pvc"
pvc := &PersistentVolumeClaim{
ClaimName: "pvc",
ClaimName: &pvcName,
}
emptyDir := &EmptyDir{}

Expand Down Expand Up @@ -192,8 +193,9 @@ func Test_validateVolumesString(t *testing.T) {
path := "path"

cm := "configMap"
pvcName := "pvc"
pvc := &PersistentVolumeClaim{
ClaimName: "pvc",
ClaimName: &pvcName,
}

tests := []struct {
Expand Down
2 changes: 1 addition & 1 deletion pkg/functions/invoke.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func invoke(ctx context.Context, c *Client, f Function, target string, m InvokeM
body, err = sendEvent(ctx, route, m, c.transport, verbose)
return meta, body, err
default:
err = fmt.Errorf("format '%v' not supported.", format)
err = fmt.Errorf("format '%v' not supported", format)
return
}
}
Expand Down
19 changes: 13 additions & 6 deletions pkg/knative/deployer.go
Original file line number Diff line number Diff line change
Expand Up @@ -750,34 +750,41 @@ func processVolumes(volumes []fn.Volume, referencedSecrets, referencedConfigMaps
}
}
} else if vol.PresistentVolumeClaim != nil {
volumeName = "pvc-" + vol.PresistentVolumeClaim.ClaimName
volumeName = "pvc-" + *vol.PresistentVolumeClaim.ClaimName

if !createdVolumes.Has(volumeName) {
newVolumes = append(newVolumes, corev1.Volume{
Name: volumeName,
VolumeSource: corev1.VolumeSource{
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
ClaimName: vol.PresistentVolumeClaim.ClaimName,
ClaimName: *vol.PresistentVolumeClaim.ClaimName,
ReadOnly: vol.PresistentVolumeClaim.ReadOnly,
},
},
})
createdVolumes.Insert(volumeName)

if !referencedPVCs.Has(vol.PresistentVolumeClaim.ClaimName) {
referencedPVCs.Insert(vol.PresistentVolumeClaim.ClaimName)
if !referencedPVCs.Has(*vol.PresistentVolumeClaim.ClaimName) {
referencedPVCs.Insert(*vol.PresistentVolumeClaim.ClaimName)
}
}
} else if vol.EmptyDir != nil {
volumeName = "empty-dir-" + rand.String(7)

if !createdVolumes.Has(volumeName) {

sizeLimit, err := resource.ParseQuantity(*vol.EmptyDir.SizeLimit)

if err != nil {
return nil, nil, fmt.Errorf("invalid quantity for sizeLimit: %s. Error: %s", *vol.EmptyDir.SizeLimit, err)
}

newVolumes = append(newVolumes, corev1.Volume{
Name: volumeName,
VolumeSource: corev1.VolumeSource{
EmptyDir: &corev1.EmptyDirVolumeSource{
Medium: vol.EmptyDir.Medium,
SizeLimit: vol.EmptyDir.SizeLimit,
Medium: corev1.StorageMedium(vol.EmptyDir.Medium),
SizeLimit: &sizeLimit,
},
},
})
Expand Down
11 changes: 1 addition & 10 deletions schema/func_yaml-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,7 @@
"description": "medium represents what type of storage medium should back this directory.\nThe default is \"\" which means to use the node's default medium.\nMust be an empty string (default) or Memory.\nMore info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir"
},
"sizeLimit": {
"$schema": "http://json-schema.org/draft-04/schema#",
"$ref": "#/definitions/Quantity",
"type": "string",
"description": "sizeLimit is the total amount of local storage required for this EmptyDir volume.\nThe size limit is also applicable for memory medium.\nThe maximum usage on memory medium EmptyDir would be the minimum value between\nthe SizeLimit specified here and the sum of memory limits of all containers in a pod.\nThe default is nil which means that the limit is undefined.\nMore info: http://kubernetes.io/docs/user-guide/volumes#emptydir"
}
},
Expand Down Expand Up @@ -243,9 +242,6 @@
"type": "object"
},
"PersistentVolumeClaim": {
"required": [
"claimName"
],
"properties": {
"claimName": {
"type": "string",
Expand All @@ -259,11 +255,6 @@
"additionalProperties": false,
"type": "object"
},
"Quantity": {
"properties": {},
"additionalProperties": false,
"type": "object"
},
"ResourcesLimitsOptions": {
"properties": {
"cpu": {
Expand Down

0 comments on commit ad218dc

Please sign in to comment.