feat: operator v0.1.16 — job stdout -> status.Message (feature B)
- FunctionJobReconciler: added KubeClient field (kubernetes.Interface) - getJobPodOutput(): reads pod logs via typed client after job succeeds - main.go: inject kubernetes.NewForConfigOrDie into FunctionJobReconciler - rbac.yaml: add pods/pods/log get/list/watch permissions - examples/simple-python/: job->function chain demo (Python) - examples/simple-node/: job->function chain demo (Node.js) sless_job.X.message now contains the return value of the function
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
// Изменено: 2026-03-08 (fix: RequeueAfter для poll статуса Job)
|
// Изменено: 2026-03-09 (feature B: захват stdout пода Job в status.Message)
|
||||||
// FunctionJobReconciler — контроллер одноразовых запусков функций.
|
// FunctionJobReconciler — контроллер одноразовых запусков функций.
|
||||||
// При создании FunctionJob:
|
// При создании FunctionJob:
|
||||||
// 1. Ждёт пока Function станет Ready
|
// 1. Ждёт пока Function станет Ready
|
||||||
@@ -12,8 +12,11 @@
|
|||||||
package controllers
|
package controllers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
batchv1 "k8s.io/api/batch/v1"
|
batchv1 "k8s.io/api/batch/v1"
|
||||||
@@ -22,6 +25,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/api/resource"
|
"k8s.io/apimachinery/pkg/api/resource"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/client-go/kubernetes"
|
||||||
ctrl "sigs.k8s.io/controller-runtime"
|
ctrl "sigs.k8s.io/controller-runtime"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||||
@@ -33,7 +37,8 @@ import (
|
|||||||
type FunctionJobReconciler struct {
|
type FunctionJobReconciler struct {
|
||||||
client.Client
|
client.Client
|
||||||
Scheme *runtime.Scheme
|
Scheme *runtime.Scheme
|
||||||
RegistrySecret string // имя k8s Secret с docker credentials (для imagePullSecrets)
|
RegistrySecret string // имя k8s Secret с docker credentials (для imagePullSecrets)
|
||||||
|
KubeClient kubernetes.Interface // typed client для чтения логов подов (logs API недоступен через controller-runtime client)
|
||||||
}
|
}
|
||||||
|
|
||||||
//+kubebuilder:rbac:groups=sless.kube5s.ru,resources=functionjobs,verbs=get;list;watch;create;update;patch;delete
|
//+kubebuilder:rbac:groups=sless.kube5s.ru,resources=functionjobs,verbs=get;list;watch;create;update;patch;delete
|
||||||
@@ -188,7 +193,8 @@ func (r *FunctionJobReconciler) syncJobStatus(ctx context.Context, fj *slessv1al
|
|||||||
now := metav1.Now()
|
now := metav1.Now()
|
||||||
fj.Status.Phase = slessv1alpha1.FunctionJobPhaseSucceeded
|
fj.Status.Phase = slessv1alpha1.FunctionJobPhaseSucceeded
|
||||||
fj.Status.CompletionTime = &now
|
fj.Status.CompletionTime = &now
|
||||||
fj.Status.Message = "completed successfully"
|
// Захватываем stdout пода — это return value функции (runner делает print(json.dumps(result)))
|
||||||
|
fj.Status.Message = getJobPodOutput(ctx, r.KubeClient, job.Namespace, job.Name)
|
||||||
} else if job.Status.Failed > 0 {
|
} else if job.Status.Failed > 0 {
|
||||||
now := metav1.Now()
|
now := metav1.Now()
|
||||||
fj.Status.Phase = slessv1alpha1.FunctionJobPhaseFailed
|
fj.Status.Phase = slessv1alpha1.FunctionJobPhaseFailed
|
||||||
@@ -259,6 +265,31 @@ func fnEnvVars(fn *slessv1alpha1.Function) []corev1.EnvVar {
|
|||||||
|
|
||||||
func int32Ptr(i int32) *int32 { return &i }
|
func int32Ptr(i int32) *int32 { return &i }
|
||||||
|
|
||||||
|
// getJobPodOutput находит под созданный Job-ом и возвращает его stdout (trimmed).
|
||||||
|
// runner.py/runner.js печатают json.dumps(result) в stdout — это и есть return value функции.
|
||||||
|
// Если под не найден или логи недоступны — возвращает "completed successfully" как fallback.
|
||||||
|
func getJobPodOutput(ctx context.Context, kube kubernetes.Interface, namespace, jobName string) string {
|
||||||
|
pods, err := kube.CoreV1().Pods(namespace).List(ctx, metav1.ListOptions{
|
||||||
|
LabelSelector: "job-name=" + jobName,
|
||||||
|
})
|
||||||
|
if err != nil || len(pods.Items) == 0 {
|
||||||
|
return "completed successfully"
|
||||||
|
}
|
||||||
|
req := kube.CoreV1().Pods(namespace).GetLogs(pods.Items[0].Name, &corev1.PodLogOptions{})
|
||||||
|
stream, err := req.Stream(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return "completed successfully"
|
||||||
|
}
|
||||||
|
defer stream.Close()
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
_, _ = io.Copy(buf, stream)
|
||||||
|
out := strings.TrimSpace(buf.String())
|
||||||
|
if out == "" {
|
||||||
|
return "completed successfully"
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// SetupWithManager регистрирует контроллер.
|
// SetupWithManager регистрирует контроллер.
|
||||||
// Owns(&batchv1.Job{}) намеренно убрано: Job создаётся в другом namespace
|
// Owns(&batchv1.Job{}) намеренно убрано: Job создаётся в другом namespace
|
||||||
// (sless-fn-*), где OwnerReference кросс-неймспейсно не работают.
|
// (sless-fn-*), где OwnerReference кросс-неймспейсно не работают.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Изменено: 2026-03-07
|
# Изменено: 2026-03-09 (добавлен доступ к pods/log для feature B)
|
||||||
# RBAC для sless оператора.
|
# RBAC для sless оператора.
|
||||||
# ServiceAccount + ClusterRole + ClusterRoleBinding.
|
# ServiceAccount + ClusterRole + ClusterRoleBinding.
|
||||||
# ClusterRole нужен (не namespaced Role) потому что оператор создаёт
|
# ClusterRole нужен (не namespaced Role) потому что оператор создаёт
|
||||||
@@ -49,6 +49,10 @@ rules:
|
|||||||
- apiGroups: [""]
|
- apiGroups: [""]
|
||||||
resources: ["events"]
|
resources: ["events"]
|
||||||
verbs: ["create", "patch"]
|
verbs: ["create", "patch"]
|
||||||
|
# Pods + logs — чтение stdout завершённых Job-подов (feature B: status.Message = return value функции)
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["pods", "pods/log"]
|
||||||
|
verbs: ["get", "list", "watch"]
|
||||||
# Lease для leader election
|
# Lease для leader election
|
||||||
- apiGroups: ["coordination.k8s.io"]
|
- apiGroups: ["coordination.k8s.io"]
|
||||||
resources: ["leases"]
|
resources: ["leases"]
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
// Создано: 2026-03-09
|
||||||
|
// time_display.js — HTTP-функция (постоянный Deployment + Trigger).
|
||||||
|
// Читает env JOB_TIME, которую terraform передаёт из sless_job.run_getter.message.
|
||||||
|
// Демонстрирует цепочку: Job вычисляет данные → Function использует их через env.
|
||||||
|
|
||||||
|
exports.showTime = function(event) {
|
||||||
|
// JOB_TIME устанавливается terraform из статуса джоба (JSON строка)
|
||||||
|
const jobTimeRaw = process.env.JOB_TIME || '{}';
|
||||||
|
let jobTime;
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(jobTimeRaw);
|
||||||
|
jobTime = parsed.time || jobTimeRaw;
|
||||||
|
} catch (e) {
|
||||||
|
jobTime = jobTimeRaw;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
message: `Сервис запустился в: ${jobTime}`,
|
||||||
|
path: event._path || '/',
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// Создано: 2026-03-09
|
||||||
|
// time_getter.js — функция запускается как Job (одноразово).
|
||||||
|
// Возвращает JSON со временем запуска. Оператор v0.1.16 захватывает stdout
|
||||||
|
// и записывает его в sless_job.run_getter.message — оттуда terraform передаёт
|
||||||
|
// значение в sless_function.display через env_var JOB_TIME.
|
||||||
|
|
||||||
|
exports.getTime = function(event) {
|
||||||
|
// Возвращаем время в ISO 8601 UTC — без зависимостей, только stdlib
|
||||||
|
return { time: new Date().toISOString() };
|
||||||
|
};
|
||||||
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,22 @@
|
|||||||
|
# Создано: 2026-03-09
|
||||||
|
# main.tf — точка входа для примера simple-node.
|
||||||
|
# Демонстрирует цепочку: sless_job (one-shot) → sless_function (http).
|
||||||
|
# Аналог simple-python, но на Node.js 20.
|
||||||
|
|
||||||
|
terraform {
|
||||||
|
required_providers {
|
||||||
|
sless = {
|
||||||
|
source = "terra.k8c.ru/naeel/sless"
|
||||||
|
version = "~> 0.1.8"
|
||||||
|
}
|
||||||
|
archive = {
|
||||||
|
source = "hashicorp/archive"
|
||||||
|
version = "~> 2.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
provider "sless" {
|
||||||
|
endpoint = "https://sless-api.kube5s.ru"
|
||||||
|
token = "dev-token-change-me"
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
# Создано: 2026-03-09
|
||||||
|
# outputs.tf — полезные значения после terraform apply.
|
||||||
|
|
||||||
|
output "display_url" {
|
||||||
|
description = "URL HTTP-триггера функции time_display"
|
||||||
|
value = sless_trigger.display_http.url
|
||||||
|
}
|
||||||
|
|
||||||
|
output "job_result" {
|
||||||
|
description = "Stdout джоба (return value функции getTime)"
|
||||||
|
value = sless_job.run_getter.message
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
# Создано: 2026-03-09
|
||||||
|
# time-display.tf — постоянная HTTP-функция, получающая данные от джоба.
|
||||||
|
|
||||||
|
# Упаковываем код функции в zip
|
||||||
|
data "archive_file" "time_display_zip" {
|
||||||
|
type = "zip"
|
||||||
|
source_dir = "${path.module}/code/time_display"
|
||||||
|
output_path = "${path.module}/dist/time_display.zip"
|
||||||
|
}
|
||||||
|
|
||||||
|
# HTTP-функция: постоянный Deployment, читает JOB_TIME из env
|
||||||
|
resource "sless_function" "time_display" {
|
||||||
|
namespace = "default"
|
||||||
|
name = "simple-node-time-display"
|
||||||
|
runtime = "nodejs20"
|
||||||
|
entrypoint = "time_display.showTime"
|
||||||
|
memory_mb = 64
|
||||||
|
|
||||||
|
# Значение вычислено джобом при apply и зафиксировано в state
|
||||||
|
env_vars = {
|
||||||
|
JOB_TIME = sless_job.run_getter.message
|
||||||
|
}
|
||||||
|
|
||||||
|
code_path = data.archive_file.time_display_zip.output_path
|
||||||
|
code_hash = filesha256("${path.module}/code/time_display/time_display.js")
|
||||||
|
|
||||||
|
depends_on = [sless_job.run_getter]
|
||||||
|
}
|
||||||
|
|
||||||
|
# HTTP-триггер — публикует функцию по URL
|
||||||
|
resource "sless_trigger" "display_http" {
|
||||||
|
namespace = "default"
|
||||||
|
name = "simple-node-display-http"
|
||||||
|
type = "http"
|
||||||
|
function = sless_function.time_display.name
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
# Создано: 2026-03-09
|
||||||
|
# time-getter.tf — одноразовая функция + джоб запускающий её при apply.
|
||||||
|
# sless_job.run_getter.message после apply содержит stdout runner-а:
|
||||||
|
# {"time":"2026-03-09T12:34:56.789Z"}
|
||||||
|
# Это значение terraform записывает в env JOB_TIME функции time_display.
|
||||||
|
|
||||||
|
# Упаковываем код функции в zip
|
||||||
|
data "archive_file" "time_getter_zip" {
|
||||||
|
type = "zip"
|
||||||
|
source_dir = "${path.module}/code/time_getter"
|
||||||
|
output_path = "${path.module}/dist/time_getter.zip"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Функция-вычислитель: запускается только джобом, не имеет HTTP-триггера
|
||||||
|
resource "sless_function" "time_getter" {
|
||||||
|
namespace = "default"
|
||||||
|
name = "simple-node-time-getter"
|
||||||
|
runtime = "nodejs20"
|
||||||
|
entrypoint = "time_getter.getTime"
|
||||||
|
memory_mb = 64
|
||||||
|
|
||||||
|
code_path = data.archive_file.time_getter_zip.output_path
|
||||||
|
code_hash = filesha256("${path.module}/code/time_getter/time_getter.js")
|
||||||
|
}
|
||||||
|
|
||||||
|
# Джоб: запускает time_getter один раз при terraform apply.
|
||||||
|
resource "sless_job" "run_getter" {
|
||||||
|
namespace = "default"
|
||||||
|
name = "simple-node-getter-run"
|
||||||
|
function = sless_function.time_getter.name
|
||||||
|
run_id = 1
|
||||||
|
wait_timeout_sec = 120
|
||||||
|
event_json = "{}"
|
||||||
|
|
||||||
|
depends_on = [sless_function.time_getter]
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
# Создано: 2026-03-09
|
||||||
|
# time_display.py — HTTP-функция (постоянный Deployment + Trigger).
|
||||||
|
# Читает env JOB_TIME, которую terraform передаёт из sless_job.run_getter.message.
|
||||||
|
# Демонстрирует цепочку: Job вычисляет данные → Function использует их через env.
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
def show_time(event):
|
||||||
|
# JOB_TIME устанавливается terraform из статуса джоба (JSON строка)
|
||||||
|
job_time_raw = os.environ.get("JOB_TIME", "{}")
|
||||||
|
try:
|
||||||
|
job_time = json.loads(job_time_raw).get("time", job_time_raw)
|
||||||
|
except (json.JSONDecodeError, AttributeError):
|
||||||
|
job_time = job_time_raw
|
||||||
|
return {
|
||||||
|
"message": f"Сервис запустился в: {job_time}",
|
||||||
|
"path": event.get("_path", "/"),
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# Создано: 2026-03-09
|
||||||
|
# time_getter.py — функция запускается как Job (одноразово).
|
||||||
|
# Возвращает JSON со временем запуска. Оператор v0.1.16 захватывает stdout
|
||||||
|
# и записывает его в sless_job.run_getter.message — оттуда terraform передаёт
|
||||||
|
# значение в sless_function.display через env_var JOB_TIME.
|
||||||
|
|
||||||
|
import json
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
|
|
||||||
|
def get_time(event):
|
||||||
|
# Возвращаем время в ISO 8601 UTC — без зависимостей, только stdlib
|
||||||
|
return {"time": datetime.now(timezone.utc).isoformat()}
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# Для локального тестирования без оператора
|
||||||
|
print(json.dumps(get_time({})))
|
||||||
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,23 @@
|
|||||||
|
# Создано: 2026-03-09
|
||||||
|
# main.tf — точка входа для примера simple-python.
|
||||||
|
# Демонстрирует цепочку: sless_job (one-shot) → sless_function (http).
|
||||||
|
# Джоб запускается при terraform apply, его stdout (JSON) попадает в
|
||||||
|
# sless_job.run_getter.message и передаётся функции через env_vars.
|
||||||
|
|
||||||
|
terraform {
|
||||||
|
required_providers {
|
||||||
|
sless = {
|
||||||
|
source = "terra.k8c.ru/naeel/sless"
|
||||||
|
version = "~> 0.1.8"
|
||||||
|
}
|
||||||
|
archive = {
|
||||||
|
source = "hashicorp/archive"
|
||||||
|
version = "~> 2.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
provider "sless" {
|
||||||
|
endpoint = "https://sless-api.kube5s.ru"
|
||||||
|
token = "dev-token-change-me"
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# Создано: 2026-03-09
|
||||||
|
# outputs.tf — полезные значения после terraform apply.
|
||||||
|
|
||||||
|
# URL HTTP-триггера для тестирования функции display
|
||||||
|
output "display_url" {
|
||||||
|
description = "URL HTTP-триггера функции time_display"
|
||||||
|
value = sless_trigger.display_http.url
|
||||||
|
}
|
||||||
|
|
||||||
|
# Результат джоба — JSON строка {"time": "..."} из stdout функции get_time()
|
||||||
|
output "job_result" {
|
||||||
|
description = "Stdout джоба (return value функции get_time)"
|
||||||
|
value = sless_job.run_getter.message
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
# Создано: 2026-03-09
|
||||||
|
# time-display.tf — постоянная HTTP-функция, получающая данные от джоба.
|
||||||
|
# JOB_TIME берётся из sless_job.run_getter.message (stdout джоба) —
|
||||||
|
# это JSON строка {"time": "..."}, terraform передаёт её в env целиком.
|
||||||
|
# Функция парсит её через os.environ, а не через event — демонстрирует
|
||||||
|
# паттерн "данные вычислены один раз при деплое, используются на каждый запрос".
|
||||||
|
|
||||||
|
# Упаковываем код функции в zip
|
||||||
|
data "archive_file" "time_display_zip" {
|
||||||
|
type = "zip"
|
||||||
|
source_dir = "${path.module}/code/time_display"
|
||||||
|
output_path = "${path.module}/dist/time_display.zip"
|
||||||
|
}
|
||||||
|
|
||||||
|
# HTTP-функция: постоянный Deployment, читает JOB_TIME из env
|
||||||
|
resource "sless_function" "time_display" {
|
||||||
|
namespace = "default"
|
||||||
|
name = "simple-py-time-display"
|
||||||
|
runtime = "python3.11"
|
||||||
|
entrypoint = "time_display.show_time"
|
||||||
|
memory_mb = 64
|
||||||
|
|
||||||
|
# Значение вычислено джобом при apply и зафиксировано в state
|
||||||
|
env_vars = {
|
||||||
|
JOB_TIME = sless_job.run_getter.message
|
||||||
|
}
|
||||||
|
|
||||||
|
code_path = data.archive_file.time_display_zip.output_path
|
||||||
|
code_hash = filesha256("${path.module}/code/time_display/time_display.py")
|
||||||
|
|
||||||
|
depends_on = [sless_job.run_getter]
|
||||||
|
}
|
||||||
|
|
||||||
|
# HTTP-триггер — публикует функцию по URL
|
||||||
|
resource "sless_trigger" "display_http" {
|
||||||
|
namespace = "default"
|
||||||
|
name = "simple-py-display-http"
|
||||||
|
type = "http"
|
||||||
|
function = sless_function.time_display.name
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
# Создано: 2026-03-09
|
||||||
|
# time-getter.tf — одноразовая функция + джоб запускающий её при apply.
|
||||||
|
# sless_job.run_getter.message после apply содержит stdout runner-а:
|
||||||
|
# {"time": "2026-03-09T12:34:56.789012+00:00"}
|
||||||
|
# Это значение terraform записывает в env JOB_TIME функции time_display.
|
||||||
|
|
||||||
|
# Упаковываем код функции в zip
|
||||||
|
data "archive_file" "time_getter_zip" {
|
||||||
|
type = "zip"
|
||||||
|
source_dir = "${path.module}/code/time_getter"
|
||||||
|
output_path = "${path.module}/dist/time_getter.zip"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Функция-вычислитель: запускается только джобом, не имеет HTTP-триггера
|
||||||
|
resource "sless_function" "time_getter" {
|
||||||
|
namespace = "default"
|
||||||
|
name = "simple-py-time-getter"
|
||||||
|
runtime = "python3.11"
|
||||||
|
entrypoint = "time_getter.get_time"
|
||||||
|
memory_mb = 64
|
||||||
|
|
||||||
|
code_path = data.archive_file.time_getter_zip.output_path
|
||||||
|
code_hash = filesha256("${path.module}/code/time_getter/time_getter.py")
|
||||||
|
}
|
||||||
|
|
||||||
|
# Джоб: запускает time_getter один раз при terraform apply.
|
||||||
|
# run_id > 0 — разрешение на запуск (run_id=0 пропускается оператором).
|
||||||
|
# После завершения message = stdout пода = json возвращённый get_time().
|
||||||
|
resource "sless_job" "run_getter" {
|
||||||
|
namespace = "default"
|
||||||
|
name = "simple-py-getter-run"
|
||||||
|
function = sless_function.time_getter.name
|
||||||
|
run_id = 1
|
||||||
|
wait_timeout_sec = 120
|
||||||
|
event_json = "{}"
|
||||||
|
|
||||||
|
depends_on = [sless_function.time_getter]
|
||||||
|
}
|
||||||
@@ -19,6 +19,7 @@ import (
|
|||||||
|
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||||
|
"k8s.io/client-go/kubernetes"
|
||||||
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
|
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
|
||||||
ctrl "sigs.k8s.io/controller-runtime"
|
ctrl "sigs.k8s.io/controller-runtime"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/healthz"
|
"sigs.k8s.io/controller-runtime/pkg/healthz"
|
||||||
@@ -151,6 +152,7 @@ func main() {
|
|||||||
Client: mgr.GetClient(),
|
Client: mgr.GetClient(),
|
||||||
Scheme: mgr.GetScheme(),
|
Scheme: mgr.GetScheme(),
|
||||||
RegistrySecret: cfg.RegistrySecret,
|
RegistrySecret: cfg.RegistrySecret,
|
||||||
|
KubeClient: kubernetes.NewForConfigOrDie(mgr.GetConfig()),
|
||||||
}).SetupWithManager(mgr); err != nil {
|
}).SetupWithManager(mgr); err != nil {
|
||||||
log.Error("unable to create controller", "controller", "FunctionJob", "err", err)
|
log.Error("unable to create controller", "controller", "FunctionJob", "err", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
|||||||
Reference in New Issue
Block a user