Skip to content
Open
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ spec:
- jsonPath: .status.apiServerObservedGeneration
name: Server Applied
type: integer
- jsonPath: .status.functionRunnerObservedGeneration
name: FnRunner Applied
type: integer
- jsonPath: .status.controllerObservedGeneration
name: Controller Applied
type: integer
Expand Down Expand Up @@ -923,12 +920,6 @@ spec:
description: Contains an error message if one occurred whilst trying
to apply the FunctionConfig
type: string
functionRunnerObservedGeneration:
description: FunctionRunnerObservedGeneration indicates which generation
of the config the function-runner has applied to the executable
and pod evaluator
format: int64
type: integer
type: object
type: object
served: true
Expand Down
3 changes: 0 additions & 3 deletions api/porchconfig/v1alpha1/function_config_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (
// +kubebuilder:subresource:status
// +kubebuilder:resource:path=functionconfigs,singular=functionconfig
// +kubebuilder:printcolumn:name="Server Applied",type=integer,JSONPath=`.status.apiServerObservedGeneration`
// +kubebuilder:printcolumn:name="FnRunner Applied",type=integer,JSONPath=`.status.functionRunnerObservedGeneration`
// +kubebuilder:printcolumn:name="Controller Applied",type=integer,JSONPath=`.status.controllerObservedGeneration`
type FunctionConfig struct {
metav1.TypeMeta `json:",inline"`
Expand Down Expand Up @@ -57,8 +56,6 @@ type FunctionConfigStatus struct {

// ApiServerObservedGeneration indicates which generation of the config the porch server has applied to the build-in runtime
ApiServerObservedGeneration int64 `json:"apiServerObservedGeneration,omitempty"`
// FunctionRunnerObservedGeneration indicates which generation of the config the function-runner has applied to the executable and pod evaluator
FunctionRunnerObservedGeneration int64 `json:"functionRunnerObservedGeneration,omitempty"`
// ControllerObservedGeneration indicates which generation of the config the porch controller has applied to its builtin runtime
ControllerObservedGeneration int64 `json:"controllerObservedGeneration,omitempty"`
// Contains an error message if one occurred whilst trying to apply the FunctionConfig
Expand Down
23 changes: 8 additions & 15 deletions controllers/functionconfigs/functionconfigreconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,29 +186,29 @@ func (s *FunctionConfigStore) GetBinaryFromCache(image string) (string, bool) {
return "", false
}

func (s *FunctionConfigStore) GetBinaryFromCacheByConstraint(image, tag string) (string, bool) {
func (s *FunctionConfigStore) GetBinaryFromCacheByConstraint(image, tag string) (string, string, bool) {
s.mu.RLock()
defer s.mu.RUnlock()

parsedImage := imageutil.Parse(image)
cacheEntry, ok := s.binaryExecutorCache[parsedImage.BaseName]
if !ok {
return "", false
return "", "", false
}

if !cacheEntry.PrefixRegex.MatchString(parsedImage.Prefix()) {
return "", false
return "", "", false
}

cacheKeys := slices.Collect(maps.Keys(cacheEntry.Tags))

selectedKey, err := imageutil.FindBestSemverMatch(tag, cacheKeys)
if err != nil {
return "", false
return "", "", false
}
selectedBinary, ok := cacheEntry.Tags[selectedKey]

return selectedBinary, ok
return selectedBinary, selectedKey, ok
}

func (s *FunctionConfigStore) GetExecCache() map[string]BuiltInCacheEntry {
Expand Down Expand Up @@ -246,9 +246,8 @@ func (s *FunctionConfigStore) List() []*configapi.FunctionConfig {
type ReconcilerFor string

const (
ReconcilerForFunctionRunner ReconcilerFor = "function-runner"
ReconcilerForServer ReconcilerFor = "server"
ReconcilerForController ReconcilerFor = "controller"
ReconcilerForServer ReconcilerFor = "server"
ReconcilerForController ReconcilerFor = "controller"
)

type Reconciler struct {
Expand Down Expand Up @@ -292,15 +291,13 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (res ctrl.
}

defer func() {
patch := client.MergeFrom(obj.DeepCopy())
patch := client.MergeFromWithOptions(obj.DeepCopy())

if finalErr != nil {
obj.Status.Error = finalErr.Error()
} else {
obj.Status.Error = ""
switch r.For {
case ReconcilerForFunctionRunner:
obj.Status.FunctionRunnerObservedGeneration = obj.Generation
case ReconcilerForServer:
obj.Status.ApiServerObservedGeneration = obj.Generation
case ReconcilerForController:
Expand Down Expand Up @@ -342,8 +339,6 @@ func (r *Reconciler) removeFinalizer(ctx context.Context, obj *configapi.Functio
patch := client.MergeFrom(obj.DeepCopy())

switch r.For {
case ReconcilerForFunctionRunner:
controllerutil.RemoveFinalizer(obj, FunctionRunnerFinalizer)
case ReconcilerForServer:
controllerutil.RemoveFinalizer(obj, ServerFinalizer)
case ReconcilerForController:
Expand All @@ -363,8 +358,6 @@ func (r *Reconciler) addFinalizer(ctx context.Context, obj *configapi.FunctionCo

updated := false
switch r.For {
case ReconcilerForFunctionRunner:
updated = controllerutil.AddFinalizer(obj, FunctionRunnerFinalizer)
case ReconcilerForServer:
updated = controllerutil.AddFinalizer(obj, ServerFinalizer)
case ReconcilerForController:
Expand Down
10 changes: 1 addition & 9 deletions controllers/functionconfigs/functionconfigreconciler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,10 +230,6 @@ func TestFinalizersAdded(t *testing.T) {
forValue ReconcilerFor
finalizer string
}{
string(ReconcilerForFunctionRunner): {
forValue: ReconcilerForFunctionRunner,
finalizer: FunctionRunnerFinalizer,
},
string(ReconcilerForServer): {
forValue: ReconcilerForServer,
finalizer: ServerFinalizer,
Expand Down Expand Up @@ -339,7 +335,7 @@ func TestGetBinaryFromCacheByConstraint(t *testing.T) {

for name, tc := range tests {
t.Run(name, func(t *testing.T) {
path, found := store.GetBinaryFromCacheByConstraint(tc.image, tc.constraint)
path, _, found := store.GetBinaryFromCacheByConstraint(tc.image, tc.constraint)
assert.Equal(t, tc.wantFound, found)
if tc.wantFound {
assert.Equal(t, tc.wantPath, path)
Expand Down Expand Up @@ -493,10 +489,6 @@ func TestFinalizersRemoved(t *testing.T) {
forValue ReconcilerFor
finalizer string
}{
string(ReconcilerForFunctionRunner): {
forValue: ReconcilerForFunctionRunner,
finalizer: FunctionRunnerFinalizer,
},
string(ReconcilerForServer): {
forValue: ReconcilerForServer,
finalizer: ServerFinalizer,
Expand Down
6 changes: 5 additions & 1 deletion controllers/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,11 @@ func setupFunctionConfigReconciler(mgr ctrl.Manager) (*functionconfigs.FunctionC
if prefix == "" {
prefix = runneroptions.GHCRImagePrefix
}
functionConfigStore := functionconfigs.NewFunctionConfigStore(prefix, "")
functionCacheDir := os.Getenv("FUNCTION_CACHE_DIR")
if functionCacheDir == "" {
functionCacheDir = "/home/nonroot/functions"
}
functionConfigStore := functionconfigs.NewFunctionConfigStore(prefix, functionCacheDir)

rec := &functionconfigs.Reconciler{
Client: mgr.GetClient(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package packagerevision

import (
"context"
"flag"
"fmt"
"os"
Expand All @@ -24,8 +25,10 @@ import (
"github.com/kptdev/porch/controllers/packagerevisions/pkg/webhooks"
"github.com/kptdev/porch/pkg/cache/contentcache"
"github.com/kptdev/porch/pkg/engine"
"github.com/kptdev/porch/pkg/engine/podevaluator"
porch "github.com/kptdev/porch/pkg/registry/porch"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
)

Expand All @@ -35,6 +38,7 @@ const (
defaultRenderRequeueDelay = 2 * time.Second
defaultRepoOperationRetryAttempts = 3
defaultMaxGRPCMessageSize = 6 * 1024 * 1024 // 6MB
defaultPodNamespace = "porch-fn-system"
)

func (r *PackageRevisionReconciler) InitDefaults() {
Expand Down Expand Up @@ -78,21 +82,60 @@ func (r *PackageRevisionReconciler) Init(mgr ctrl.Manager) error {
)

fnRunnerAddr := os.Getenv("FUNCTION_RUNNER_ADDRESS")
functionRuntime, err := engine.NewMultiFunctionRuntime(fnRunnerAddr, r.MaxGRPCMessageSize, r.FunctionConfigStore)
if err != nil {
return fmt.Errorf("failed to create function runtime: %w", err)
}
opts := runneroptions.RunnerOptions{}
wrapperServerImage := os.Getenv("WRAPPER_SERVER_IMAGE")

prefix := os.Getenv("DEFAULT_IMAGE_PREFIX")
if prefix == "" {
prefix = runneroptions.GHCRImagePrefix
}

var podOpts *podevaluator.PodEvaluatorOptions
var kubeClient client.WithWatch
if wrapperServerImage != "" {
podNamespace := os.Getenv("POD_NAMESPACE")
if podNamespace == "" {
podNamespace = defaultPodNamespace
}
var err error
kubeClient, err = client.NewWithWatch(mgr.GetConfig(), client.Options{Scheme: mgr.GetScheme()})
if err != nil {
return fmt.Errorf("failed to create kube client for pod evaluator: %w", err)
}
podOpts = &podevaluator.PodEvaluatorOptions{
PodNamespace: podNamespace,
WrapperServerImage: wrapperServerImage,
WarmUpPodCacheOnStartup: true,
MaxGrpcMessageSize: r.MaxGRPCMessageSize,
DefaultImagePrefix: prefix,
MaxWaitlistLength: 1,
MaxParallelPodsPerFunction: 2,
}
}

functionRuntime, err := engine.NewMultiFunctionRuntime(context.Background(), engine.MultiFunctionRuntimeOptions{
GRPCAddress: fnRunnerAddr,
MaxGrpcMessageSize: r.MaxGRPCMessageSize,
FunctionConfigStore: r.FunctionConfigStore,
PodEvaluator: podOpts,
KubeClient: kubeClient,
DefaultImagePrefix: prefix,
})
if err != nil {
return fmt.Errorf("failed to create function runtime: %w", err)
}
opts := runneroptions.RunnerOptions{}
opts.InitDefaults(prefix)
r.Renderer = newKptRenderer(functionRuntime, opts)
if fnRunnerAddr != "" {
ctrl.Log.WithName(r.Name()).Info("function runtime enabled (builtin + fn-runner)", "address", fnRunnerAddr)
} else {
ctrl.Log.WithName(r.Name()).Info("function runtime enabled (builtin only, FUNCTION_RUNNER_ADDRESS not set)")
switch {
case fnRunnerAddr != "" && wrapperServerImage != "":
log.Info("function runtime enabled (builtin + fn-runner + pod evaluator)",
"fnRunner", fnRunnerAddr, "podNamespace", podOpts.PodNamespace)
case fnRunnerAddr != "":
log.Info("function runtime enabled (builtin + fn-runner)", "address", fnRunnerAddr)
case wrapperServerImage != "":
log.Info("function runtime enabled (builtin + pod evaluator)", "podNamespace", podOpts.PodNamespace)
default:
log.Info("function runtime enabled (builtin only)")
}

// Register PackageRevision validating webhook.
Expand Down
6 changes: 0 additions & 6 deletions deployments/porch/2-function-runner.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,9 @@ spec:
runAsGroup: 10001
command:
- /home/nonroot/server
- --pod-namespace=porch-fn-system
- --max-request-body-size=6291456 # Keep this in sync with porch-server's corresponding argument
- --max-parallel-pods-per-function=2
- --max-waitlist-length=1
- --warm-up-pod-cache=true
- --functions=/home/nonroot/functions
env:
- name: WRAPPER_SERVER_IMAGE
value: ghcr.io/kptdev/porch-wrapper-server:latest
- name: OTEL_METRICS_EXPORTER
value: "prometheus"
- name: OTEL_EXPORTER_PROMETHEUS_HOST
Expand Down
8 changes: 7 additions & 1 deletion deployments/porch/3-porch-server.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ spec:
value: "9464" # Default value, showing for visibility
- name: OTEL_TRACES_EXPORTER
value: none
- name: WRAPPER_SERVER_IMAGE
value: ghcr.io/kptdev/porch-wrapper-server:latest
args:
- --function-runner=function-runner:9445
- --cache-directory=/cache
Expand All @@ -92,6 +94,10 @@ spec:
- --max-request-body-size=6291456 # Keep this in sync with function-runner's corresponding argument
- --cache-type=db
- --disable-admission-plugins=MutatingAdmissionPolicy # This can be enabled once kindest/node 1.36.1 is released
- --max-parallel-pods-per-function=2
- --max-waitlist-length=1
- --warm-up-pod-cache=true
- --functions=/home/nonroot/functions
ports:
- containerPort: 9464
name: metrics
Expand Down Expand Up @@ -125,7 +131,7 @@ spec:
periodSeconds: 10
failureThreshold: 6
successThreshold: 1
timeoutSeconds: 5
timeoutSeconds: 5
---
apiVersion: v1
kind: Service
Expand Down
6 changes: 6 additions & 0 deletions deployments/porch/6-rbac-bind.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ roleRef:
kind: Role
name: porch-function-executor
subjects:
- kind: ServiceAccount
name: porch-server
namespace: porch-system
- kind: ServiceAccount
name: porch-controllers
namespace: porch-system
- kind: ServiceAccount
name: porch-fn-runner
namespace: porch-system
6 changes: 6 additions & 0 deletions deployments/porch/9-controllers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ spec:
value: "true"
- name: GIT_CACHE_DIR
value: "/cache"
- name: FUNCTION_CACHE_DIR
value: "/home/nonroot/functions"
- name: POD_NAMESPACE
value: "porch-fn-system"
- name: WRAPPER_SERVER_IMAGE
value: ghcr.io/kptdev/porch-wrapper-server:latest
- name: OTEL_SERVICE_NAME
value: porch-controllers
- name: OTEL_METRICS_EXPORTER
Expand Down
Loading
Loading