diff --git a/internal/controller/function_controller.go b/internal/controller/function_controller.go index deb0860..dc2ae50 100644 --- a/internal/controller/function_controller.go +++ b/internal/controller/function_controller.go @@ -18,6 +18,7 @@ package controller import ( "context" + "errors" "fmt" "strconv" "strings" @@ -218,17 +219,16 @@ func (r *FunctionReconciler) reconcileDeployment(ctx context.Context, function * logger := log.FromContext(ctx) logger.Info("Reconciling Function") - deployed, err := r.isDeployed(ctx, metadata.Name, function.Namespace) - if err != nil { - function.MarkDeployNotReady("DeployFailed", "Failed to check deployment status: %s", err.Error()) - return fmt.Errorf("failed to check if function is already deployed: %w", err) - } - - if !deployed { + initialDesc, err := r.FuncCliManager.Describe(ctx, metadata.Name, function.Namespace) + if errors.Is(err, funccli.ErrFunctionNotFound) { logger.Info("Function is not deployed") function.MarkDeployNotReady("NotDeployed", "Function not deployed yet") return nil } + if err != nil { + function.MarkDeployNotReady("DeployFailed", "Failed to check deployment status: %s", err.Error()) + return fmt.Errorf("failed to check if function is already deployed: %w", err) + } // function is deployed -> update status with metadata information deployer := metadata.Deploy.Deployer @@ -241,7 +241,7 @@ func (r *FunctionReconciler) reconcileDeployment(ctx context.Context, function * applyLastDeployedAnnotation(ctx, function) // Function is deployed - check middleware version - return r.handleMiddlewareUpdate(ctx, function, repo, metadata) + return r.handleMiddlewareUpdate(ctx, function, repo, metadata, &initialDesc) } // middlewareCheck is a sealed interface representing the result of inspecting a function's @@ -279,12 +279,7 @@ type autoUpdateStatus struct { source string // "function" or "operator" } -func (r *FunctionReconciler) checkMiddlewareState(ctx context.Context, function *v1alpha1.Function, metadata *funcfn.Function) (middlewareCheck, error) { - desc, err := r.FuncCliManager.Describe(ctx, metadata.Name, function.Namespace) - if err != nil { - return nil, fmt.Errorf("failed to describe function: %w", err) - } - +func (r *FunctionReconciler) checkMiddlewareState(ctx context.Context, function *v1alpha1.Function, metadata *funcfn.Function, desc *funcfn.Instance) (middlewareCheck, error) { autoUpdate, err := r.getAutoUpdateStatus(ctx, function) if err != nil { return nil, fmt.Errorf("failed to check middleware update setting: %w", err) @@ -326,10 +321,10 @@ func (r *FunctionReconciler) getAutoUpdateStatus(ctx context.Context, function * } // handleMiddlewareUpdate checks if the function is using the latest middleware and redeploys if needed -func (r *FunctionReconciler) handleMiddlewareUpdate(ctx context.Context, function *v1alpha1.Function, repo *git.Repository, metadata *funcfn.Function) error { +func (r *FunctionReconciler) handleMiddlewareUpdate(ctx context.Context, function *v1alpha1.Function, repo *git.Repository, metadata *funcfn.Function, desc *funcfn.Instance) error { logger := log.FromContext(ctx) - check, err := r.checkMiddlewareState(ctx, function, metadata) + check, err := r.checkMiddlewareState(ctx, function, metadata, desc) if err != nil { function.MarkMiddlewareNotUpToDate("MiddlewareCheckFailed", "Failed to check middleware: %s", err) return err @@ -412,19 +407,6 @@ func markServiceStatus(ready string, function *v1alpha1.Function) { } } -func (r *FunctionReconciler) isDeployed(ctx context.Context, name, namespace string) (bool, error) { - _, err := r.FuncCliManager.Describe(ctx, name, namespace) - if err != nil { - if strings.Contains(err.Error(), "not found") || strings.Contains(err.Error(), "no describe function") { - return false, nil - } - - return false, fmt.Errorf("failed to describe function: %w", err) - } - - return true, nil -} - // SetupWithManager sets up the controller with the Manager. func (r *FunctionReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). diff --git a/internal/funccli/manager.go b/internal/funccli/manager.go index d988739..59b290c 100644 --- a/internal/funccli/manager.go +++ b/internal/funccli/manager.go @@ -20,6 +20,8 @@ import ( funcfn "knative.dev/func/pkg/functions" ) +var ErrFunctionNotFound = fmt.Errorf("function not found") + const ( githubAPIURL = "https://api.github.com/repos/knative/func/releases/latest" defaultCheckInterval = 5 * time.Minute @@ -190,6 +192,9 @@ func (m *managerImpl) Run(ctx context.Context, dir string, args ...string) (stri func (m *managerImpl) Describe(ctx context.Context, name, namespace string) (funcfn.Instance, error) { out, err := m.Run(ctx, "", "describe", "-n", namespace, "-o", "json", name) if err != nil { + if strings.Contains(err.Error(), "not found") || strings.Contains(err.Error(), "no describe function") { + return funcfn.Instance{}, ErrFunctionNotFound + } return funcfn.Instance{}, fmt.Errorf("failed to describe function: %q. %w", out, err) }