Merge branch 'nightly' into k8s-shuffle-app-ports
This commit is contained in:
@@ -22,7 +22,7 @@ require (
|
|||||||
github.com/gorilla/mux v1.8.1
|
github.com/gorilla/mux v1.8.1
|
||||||
github.com/h2non/filetype v1.1.3
|
github.com/h2non/filetype v1.1.3
|
||||||
github.com/satori/go.uuid v1.2.0
|
github.com/satori/go.uuid v1.2.0
|
||||||
github.com/shuffle/shuffle-shared v0.8.39
|
github.com/shuffle/shuffle-shared v0.8.50
|
||||||
golang.org/x/crypto v0.36.0
|
golang.org/x/crypto v0.36.0
|
||||||
google.golang.org/api v0.228.0
|
google.golang.org/api v0.228.0
|
||||||
google.golang.org/grpc v1.71.1
|
google.golang.org/grpc v1.71.1
|
||||||
|
|||||||
@@ -341,8 +341,8 @@ github.com/sendgrid/sendgrid-go v3.14.0+incompatible h1:KDSasSTktAqMJCYClHVE94Fc
|
|||||||
github.com/sendgrid/sendgrid-go v3.14.0+incompatible/go.mod h1:QRQt+LX/NmgVEvmdRw0VT/QgUn499+iza2FnDca9fg8=
|
github.com/sendgrid/sendgrid-go v3.14.0+incompatible/go.mod h1:QRQt+LX/NmgVEvmdRw0VT/QgUn499+iza2FnDca9fg8=
|
||||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
|
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
|
||||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
|
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
|
||||||
github.com/shuffle/shuffle-shared v0.8.39 h1:ylRj+2xGIOPQfpawf45udnQzKLtTP9JFEFyREc2GJXM=
|
github.com/shuffle/shuffle-shared v0.8.50 h1:Sy6o7Nrcd3QG+m28775STKS3uOfaXDzDcctTuaYfdYQ=
|
||||||
github.com/shuffle/shuffle-shared v0.8.39/go.mod h1:z+ISGBgNINmZvWNrtGTc51yVG+pMkpBFu9ZLVlTyuag=
|
github.com/shuffle/shuffle-shared v0.8.50/go.mod h1:z+ISGBgNINmZvWNrtGTc51yVG+pMkpBFu9ZLVlTyuag=
|
||||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||||
|
|||||||
@@ -5138,7 +5138,7 @@ func initHandlers() {
|
|||||||
r.HandleFunc("/api/v1/apps/{key}/execute", executeSingleAction).Methods("POST", "OPTIONS")
|
r.HandleFunc("/api/v1/apps/{key}/execute", executeSingleAction).Methods("POST", "OPTIONS")
|
||||||
r.HandleFunc("/api/v1/apps/{key}/run", executeSingleAction).Methods("POST", "OPTIONS")
|
r.HandleFunc("/api/v1/apps/{key}/run", executeSingleAction).Methods("POST", "OPTIONS")
|
||||||
r.HandleFunc("/api/v1/apps/categories", shuffle.GetActiveCategories).Methods("GET", "OPTIONS")
|
r.HandleFunc("/api/v1/apps/categories", shuffle.GetActiveCategories).Methods("GET", "OPTIONS")
|
||||||
r.HandleFunc("/api/v1/apps/categories/run", shuffle.RunCategoryAction).Methods("POST", "OPTIONS")
|
//r.HandleFunc("/api/v1/apps/categories/run", shuffle.RunCategoryAction).Methods("POST", "OPTIONS")
|
||||||
r.HandleFunc("/api/v1/apps/upload", handleAppZipUpload).Methods("POST", "OPTIONS")
|
r.HandleFunc("/api/v1/apps/upload", handleAppZipUpload).Methods("POST", "OPTIONS")
|
||||||
r.HandleFunc("/api/v1/apps/{appId}/activate", activateWorkflowAppDocker).Methods("GET", "OPTIONS")
|
r.HandleFunc("/api/v1/apps/{appId}/activate", activateWorkflowAppDocker).Methods("GET", "OPTIONS")
|
||||||
r.HandleFunc("/api/v1/apps/{appId}/deactivate", activateWorkflowAppDocker).Methods("GET", "OPTIONS")
|
r.HandleFunc("/api/v1/apps/{appId}/deactivate", activateWorkflowAppDocker).Methods("GET", "OPTIONS")
|
||||||
|
|||||||
@@ -3039,7 +3039,13 @@ func executeSingleAction(resp http.ResponseWriter, request *http.Request) {
|
|||||||
shouldRerun = true
|
shouldRerun = true
|
||||||
}
|
}
|
||||||
|
|
||||||
workflowExecution, err := shuffle.PrepareSingleAction(ctx, user, fileId, body, runValidationAction)
|
decisionId := ""
|
||||||
|
decision, decisionOk := query["decision_id"]
|
||||||
|
if decisionOk && len(decision) > 0 {
|
||||||
|
decisionId = decision[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
workflowExecution, err := shuffle.PrepareSingleAction(ctx, user, fileId, body, runValidationAction, decisionId)
|
||||||
|
|
||||||
debugUrl := fmt.Sprintf("/workflows/%s?execution_id=%s", workflowExecution.Workflow.ID, workflowExecution.ExecutionId)
|
debugUrl := fmt.Sprintf("/workflows/%s?execution_id=%s", workflowExecution.Workflow.ID, workflowExecution.ExecutionId)
|
||||||
resp.Header().Add("X-Debug-Url", debugUrl)
|
resp.Header().Add("X-Debug-Url", debugUrl)
|
||||||
@@ -3101,7 +3107,12 @@ func executeSingleAction(resp http.ResponseWriter, request *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
returnBody := shuffle.HandleRetValidation(ctx, workflowExecution, 1)
|
actionId := ""
|
||||||
|
if len(workflowExecution.Workflow.Actions) == 1 {
|
||||||
|
actionId = workflowExecution.Workflow.Actions[0].ID
|
||||||
|
}
|
||||||
|
|
||||||
|
returnBody := shuffle.HandleRetValidation(ctx, workflowExecution, 1, actionId)
|
||||||
returnBytes, err := json.Marshal(returnBody)
|
returnBytes, err := json.Marshal(returnBody)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("[ERROR] Failed to marshal retStruct in single execution: %s", err)
|
log.Printf("[ERROR] Failed to marshal retStruct in single execution: %s", err)
|
||||||
|
|||||||
@@ -791,6 +791,40 @@ const App = (message, props) => {
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
<Route
|
||||||
|
exact
|
||||||
|
path="/chat"
|
||||||
|
element={
|
||||||
|
<ChatBot
|
||||||
|
serverside={serverside}
|
||||||
|
cookies={cookies}
|
||||||
|
removeCookie={removeCookie}
|
||||||
|
isLoaded={isLoaded}
|
||||||
|
isLoggedIn={isLoggedIn}
|
||||||
|
globalUrl={globalUrl}
|
||||||
|
cookies={cookies}
|
||||||
|
userdata={userdata}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
exact
|
||||||
|
path="/conversation"
|
||||||
|
element={
|
||||||
|
<ChatBot
|
||||||
|
serverside={serverside}
|
||||||
|
cookies={cookies}
|
||||||
|
removeCookie={removeCookie}
|
||||||
|
isLoaded={isLoaded}
|
||||||
|
isLoggedIn={isLoggedIn}
|
||||||
|
globalUrl={globalUrl}
|
||||||
|
cookies={cookies}
|
||||||
|
userdata={userdata}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
<Route
|
<Route
|
||||||
exact
|
exact
|
||||||
path="/dashboards/:key"
|
path="/dashboards/:key"
|
||||||
@@ -821,6 +855,22 @@ const App = (message, props) => {
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<Route
|
||||||
|
exact
|
||||||
|
path="/agents"
|
||||||
|
element={
|
||||||
|
<AgentUI
|
||||||
|
serverside={serverside}
|
||||||
|
isLoaded={isLoaded}
|
||||||
|
isLoggedIn={isLoggedIn}
|
||||||
|
globalUrl={globalUrl}
|
||||||
|
userdata={userdata}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
<Route
|
<Route
|
||||||
exact
|
exact
|
||||||
path="/"
|
path="/"
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ The password should be provided with the `SHUFFLE_OPENSEARCH_PASSWORD` env varia
|
|||||||
| `backend.affinity` | Affinity for backend pods assignment | `{}` |
|
| `backend.affinity` | Affinity for backend pods assignment | `{}` |
|
||||||
| `backend.nodeSelector` | Node labels for backend pods assignment | `{}` |
|
| `backend.nodeSelector` | Node labels for backend pods assignment | `{}` |
|
||||||
| `backend.tolerations` | Tolerations for backend pods assignment | `[]` |
|
| `backend.tolerations` | Tolerations for backend pods assignment | `[]` |
|
||||||
| `backend.updateStrategy.type` | backend deployment strategy type | `RollingUpdate` |
|
| `backend.updateStrategy.type` | backend deployment strategy type | `Recreate` |
|
||||||
| `backend.priorityClassName` | backend pods' priorityClassName | `""` |
|
| `backend.priorityClassName` | backend pods' priorityClassName | `""` |
|
||||||
| `backend.topologySpreadConstraints` | Topology Spread Constraints for backend pod assignment spread across your cluster among failure-domains | `[]` |
|
| `backend.topologySpreadConstraints` | Topology Spread Constraints for backend pod assignment spread across your cluster among failure-domains | `[]` |
|
||||||
| `backend.schedulerName` | Name of the k8s scheduler (other than default) for backend pods | `""` |
|
| `backend.schedulerName` | Name of the k8s scheduler (other than default) for backend pods | `""` |
|
||||||
@@ -244,6 +244,7 @@ The password should be provided with the `SHUFFLE_OPENSEARCH_PASSWORD` env varia
|
|||||||
| `backend.autoscaling.hpa.maxReplicas` | Maximum number of replicas | `""` |
|
| `backend.autoscaling.hpa.maxReplicas` | Maximum number of replicas | `""` |
|
||||||
| `backend.autoscaling.hpa.targetCPU` | Target CPU utilization percentage | `""` |
|
| `backend.autoscaling.hpa.targetCPU` | Target CPU utilization percentage | `""` |
|
||||||
| `backend.autoscaling.hpa.targetMemory` | Target Memory utilization percentage | `""` |
|
| `backend.autoscaling.hpa.targetMemory` | Target Memory utilization percentage | `""` |
|
||||||
|
| `backend.service.labels` | Extra labels for backend service | `{}` |
|
||||||
| `backend.serviceAccount.create` | Specifies whether a ServiceAccount should be created | `true` |
|
| `backend.serviceAccount.create` | Specifies whether a ServiceAccount should be created | `true` |
|
||||||
| `backend.serviceAccount.name` | The name of the ServiceAccount to use. | `""` |
|
| `backend.serviceAccount.name` | The name of the ServiceAccount to use. | `""` |
|
||||||
| `backend.serviceAccount.annotations` | Additional Service Account annotations (evaluated as a template) | `{}` |
|
| `backend.serviceAccount.annotations` | Additional Service Account annotations (evaluated as a template) | `{}` |
|
||||||
@@ -359,6 +360,7 @@ The password should be provided with the `SHUFFLE_OPENSEARCH_PASSWORD` env varia
|
|||||||
| `frontend.autoscaling.hpa.maxReplicas` | Maximum number of replicas | `""` |
|
| `frontend.autoscaling.hpa.maxReplicas` | Maximum number of replicas | `""` |
|
||||||
| `frontend.autoscaling.hpa.targetCPU` | Target CPU utilization percentage | `""` |
|
| `frontend.autoscaling.hpa.targetCPU` | Target CPU utilization percentage | `""` |
|
||||||
| `frontend.autoscaling.hpa.targetMemory` | Target Memory utilization percentage | `""` |
|
| `frontend.autoscaling.hpa.targetMemory` | Target Memory utilization percentage | `""` |
|
||||||
|
| `frontend.service.labels` | Extra labels for frontend service | `{}` |
|
||||||
| `frontend.serviceAccount.create` | Specifies whether a ServiceAccount should be created | `true` |
|
| `frontend.serviceAccount.create` | Specifies whether a ServiceAccount should be created | `true` |
|
||||||
| `frontend.serviceAccount.name` | The name of the ServiceAccount to use. | `""` |
|
| `frontend.serviceAccount.name` | The name of the ServiceAccount to use. | `""` |
|
||||||
| `frontend.serviceAccount.annotations` | Additional Service Account annotations (evaluated as a template) | `{}` |
|
| `frontend.serviceAccount.annotations` | Additional Service Account annotations (evaluated as a template) | `{}` |
|
||||||
@@ -477,23 +479,38 @@ The password should be provided with the `SHUFFLE_OPENSEARCH_PASSWORD` env varia
|
|||||||
|
|
||||||
### worker Parameters
|
### worker Parameters
|
||||||
|
|
||||||
| Name | Description | Value |
|
| Name | Description | Value |
|
||||||
| ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ |
|
| ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ |
|
||||||
| `worker.image.registry` | worker image registry | `ghcr.io` |
|
| `worker.image.registry` | worker image registry | `ghcr.io` |
|
||||||
| `worker.image.repository` | worker image repository | `shuffle/shuffle-worker` |
|
| `worker.image.repository` | worker image repository | `shuffle/shuffle-worker` |
|
||||||
| `worker.image.tag` | worker image tag (immutable tags are recommended, defaults to appVersion) | `""` |
|
| `worker.image.tag` | worker image tag (immutable tags are recommended, defaults to appVersion) | `""` |
|
||||||
| `worker.image.digest` | worker image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag image tag (immutable tags are recommended) | `""` |
|
| `worker.image.digest` | worker image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag image tag (immutable tags are recommended) | `""` |
|
||||||
| `worker.serviceAccount.create` | Specifies whether a ServiceAccount should be created | `true` |
|
| `worker.podSecurityContext.enabled` | Enable worker pods' Security Context | `true` |
|
||||||
| `worker.serviceAccount.name` | The name of the ServiceAccount to use. | `""` |
|
| `worker.podSecurityContext.fsGroupChangePolicy` | Set filesystem group change policy for worker pods | `Always` |
|
||||||
| `worker.serviceAccount.annotations` | Additional Service Account annotations (evaluated as a template) | `{}` |
|
| `worker.podSecurityContext.sysctls` | Set kernel settings using the sysctl interface for worker pods | `[]` |
|
||||||
| `worker.serviceAccount.automountServiceAccountToken` | Automount service account token for the worker service account | `true` |
|
| `worker.podSecurityContext.supplementalGroups` | Set filesystem extra groups for worker pods | `[]` |
|
||||||
| `worker.serviceAccount.imagePullSecrets` | Add image pull secrets to the worker service account | `[]` |
|
| `worker.podSecurityContext.fsGroup` | Set fsGroup in worker pods' Security Context | `1001` |
|
||||||
| `worker.rbac.create` | Specifies whether RBAC resources should be created | `true` |
|
| `worker.containerSecurityContext.enabled` | Enabled worker container' Security Context | `true` |
|
||||||
| `worker.networkPolicy.enabled` | Specifies whether a NetworkPolicy should be created | `true` |
|
| `worker.containerSecurityContext.seLinuxOptions` | Set SELinux options in worker container | `{}` |
|
||||||
| `worker.networkPolicy.allowExternal` | Don't require server label for connections | `true` |
|
| `worker.containerSecurityContext.runAsUser` | Set runAsUser in worker container' Security Context | `1001` |
|
||||||
| `worker.networkPolicy.allowExternalEgress` | Allow the pod to access any range of port and all destinations. | `true` |
|
| `worker.containerSecurityContext.runAsGroup` | Set runAsGroup in worker container' Security Context | `1001` |
|
||||||
| `worker.networkPolicy.extraIngress` | Add extra ingress rules to the NetworkPolicy | `[]` |
|
| `worker.containerSecurityContext.runAsNonRoot` | Set runAsNonRoot in worker container' Security Context | `true` |
|
||||||
| `worker.networkPolicy.extraEgress` | Add extra ingress rules to the NetworkPolicy (ignored if allowExternalEgress=true) | `[]` |
|
| `worker.containerSecurityContext.readOnlyRootFilesystem` | Set readOnlyRootFilesystem in worker container' Security Context | `true` |
|
||||||
|
| `worker.containerSecurityContext.privileged` | Set privileged in worker container' Security Context | `false` |
|
||||||
|
| `worker.containerSecurityContext.allowPrivilegeEscalation` | Set allowPrivilegeEscalation in worker container' Security Context | `false` |
|
||||||
|
| `worker.containerSecurityContext.capabilities.drop` | List of capabilities to be dropped in worker container | `["ALL"]` |
|
||||||
|
| `worker.containerSecurityContext.seccompProfile.type` | Set seccomp profile in worker container | `RuntimeDefault` |
|
||||||
|
| `worker.serviceAccount.create` | Specifies whether a ServiceAccount should be created | `true` |
|
||||||
|
| `worker.serviceAccount.name` | The name of the ServiceAccount to use. | `""` |
|
||||||
|
| `worker.serviceAccount.annotations` | Additional Service Account annotations (evaluated as a template) | `{}` |
|
||||||
|
| `worker.serviceAccount.automountServiceAccountToken` | Automount service account token for the worker service account | `true` |
|
||||||
|
| `worker.serviceAccount.imagePullSecrets` | Add image pull secrets to the worker service account | `[]` |
|
||||||
|
| `worker.rbac.create` | Specifies whether RBAC resources should be created | `true` |
|
||||||
|
| `worker.networkPolicy.enabled` | Specifies whether a NetworkPolicy should be created | `true` |
|
||||||
|
| `worker.networkPolicy.allowExternal` | Don't require server label for connections | `true` |
|
||||||
|
| `worker.networkPolicy.allowExternalEgress` | Allow the pod to access any range of port and all destinations. | `true` |
|
||||||
|
| `worker.networkPolicy.extraIngress` | Add extra ingress rules to the NetworkPolicy | `[]` |
|
||||||
|
| `worker.networkPolicy.extraEgress` | Add extra ingress rules to the NetworkPolicy (ignored if allowExternalEgress=true) | `[]` |
|
||||||
|
|
||||||
### app Parameters
|
### app Parameters
|
||||||
|
|
||||||
@@ -511,6 +528,32 @@ The password should be provided with the `SHUFFLE_OPENSEARCH_PASSWORD` env varia
|
|||||||
| `app.networkPolicy.extraIngress` | Add extra ingress rules to the NetworkPolicy | `[]` |
|
| `app.networkPolicy.extraIngress` | Add extra ingress rules to the NetworkPolicy | `[]` |
|
||||||
| `app.networkPolicy.extraEgress` | Add extra ingress rules to the NetworkPolicy (ignored if allowExternalEgress=true) | `[]` |
|
| `app.networkPolicy.extraEgress` | Add extra ingress rules to the NetworkPolicy (ignored if allowExternalEgress=true) | `[]` |
|
||||||
| `app.exposedContainerPort` | The port that shuffle app containers will listen on for new requests. | `80` |
|
| `app.exposedContainerPort` | The port that shuffle app containers will listen on for new requests. | `80` |
|
||||||
|
| `app.podSecurityContext.enabled` | Enable app pods' Security Context | `true` |
|
||||||
|
| `app.podSecurityContext.fsGroupChangePolicy` | Set filesystem group change policy for app pods | `Always` |
|
||||||
|
| `app.podSecurityContext.sysctls` | Set kernel settings using the sysctl interface for app pods | `[]` |
|
||||||
|
| `app.podSecurityContext.supplementalGroups` | Set filesystem extra groups for app pods | `[]` |
|
||||||
|
| `app.podSecurityContext.fsGroup` | Set fsGroup in app pods' Security Context | `1001` |
|
||||||
|
| `app.containerSecurityContext.enabled` | Enabled app container' Security Context | `true` |
|
||||||
|
| `app.containerSecurityContext.seLinuxOptions` | Set SELinux options in app container | `{}` |
|
||||||
|
| `app.containerSecurityContext.runAsUser` | Set runAsUser in app container' Security Context | `1001` |
|
||||||
|
| `app.containerSecurityContext.runAsGroup` | Set runAsGroup in app container' Security Context | `1001` |
|
||||||
|
| `app.containerSecurityContext.runAsNonRoot` | Set runAsNonRoot in app container' Security Context | `true` |
|
||||||
|
| `app.containerSecurityContext.readOnlyRootFilesystem` | Set readOnlyRootFilesystem in app container' Security Context | `true` |
|
||||||
|
| `app.containerSecurityContext.privileged` | Set privileged in app container' Security Context | `false` |
|
||||||
|
| `app.containerSecurityContext.allowPrivilegeEscalation` | Set allowPrivilegeEscalation in app container' Security Context | `false` |
|
||||||
|
| `app.containerSecurityContext.capabilities.drop` | List of capabilities to be dropped in app container | `["ALL"]` |
|
||||||
|
| `app.containerSecurityContext.seccompProfile.type` | Set seccomp profile in app container | `RuntimeDefault` |
|
||||||
|
| `app.serviceAccount.create` | Specifies whether a ServiceAccount should be created | `true` |
|
||||||
|
| `app.serviceAccount.name` | The name of the ServiceAccount to use. | `""` |
|
||||||
|
| `app.serviceAccount.annotations` | Additional Service Account annotations (evaluated as a template) | `{}` |
|
||||||
|
| `app.serviceAccount.automountServiceAccountToken` | Automount service account token for the app service account | `true` |
|
||||||
|
| `app.serviceAccount.imagePullSecrets` | Add image pull secrets to the app service account | `[]` |
|
||||||
|
| `app.rbac.create` | Specifies whether RBAC resources should be created | `true` |
|
||||||
|
| `app.networkPolicy.enabled` | Specifies whether a NetworkPolicy should be created | `true` |
|
||||||
|
| `app.networkPolicy.allowExternal` | Don't require server label for connections | `true` |
|
||||||
|
| `app.networkPolicy.allowExternalEgress` | Allow the pod to access any range of port and all destinations. | `true` |
|
||||||
|
| `app.networkPolicy.extraIngress` | Add extra ingress rules to the NetworkPolicy | `[]` |
|
||||||
|
| `app.networkPolicy.extraEgress` | Add extra ingress rules to the NetworkPolicy (ignored if allowExternalEgress=true) | `[]` |
|
||||||
|
|
||||||
### Traffic Exposure Parameters
|
### Traffic Exposure Parameters
|
||||||
|
|
||||||
|
|||||||
@@ -8,18 +8,20 @@ metadata:
|
|||||||
annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
|
annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
data:
|
data:
|
||||||
BACKEND_PORT: "5001"
|
BACKEND_PORT: "{{ .Values.backend.containerPorts.http }}"
|
||||||
{{- if .Values.shuffle.baseUrl }}
|
{{- if .Values.shuffle.baseUrl }}
|
||||||
BASE_URL: "{{ .Values.shuffle.baseUrl }}"
|
BASE_URL: "{{ .Values.shuffle.baseUrl }}"
|
||||||
SSO_REDIRECT_URL: "{{ .Values.shuffle.baseUrl }}"
|
SSO_REDIRECT_URL: "{{ .Values.shuffle.baseUrl }}"
|
||||||
{{- else }}
|
{{- else }}
|
||||||
BASE_URL: "http://{{ include "shuffle.backend.name" . }}:5001"
|
BASE_URL: "http://{{ include "shuffle.backend.name" . }}.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.backend.containerPorts.http }}"
|
||||||
{{- end }}
|
{{- end }}
|
||||||
ORG_ID: "{{ .Values.shuffle.org }}"
|
ORG_ID: "{{ .Values.shuffle.org }}"
|
||||||
SHUFFLE_APP_DOWNLOAD_LOCATION: "{{ .Values.backend.apps.downloadLocation }}"
|
SHUFFLE_APP_DOWNLOAD_LOCATION: "{{ .Values.backend.apps.downloadLocation }}"
|
||||||
SHUFFLE_DOWNLOAD_AUTH_BRANCH: "{{ .Values.backend.apps.downloadBranch }}"
|
SHUFFLE_DOWNLOAD_AUTH_BRANCH: "{{ .Values.backend.apps.downloadBranch }}"
|
||||||
SHUFFLE_APP_FORCE_UPDATE: "{{ .Values.backend.apps.forceUpdate }}"
|
SHUFFLE_APP_FORCE_UPDATE: "{{ .Values.backend.apps.forceUpdate }}"
|
||||||
SHUFFLE_CHAT_DISABLED: "true"
|
SHUFFLE_CHAT_DISABLED: "true"
|
||||||
|
# Sets backend_url parameter for workflow execution to the cluster-internal shuffle-backend address
|
||||||
|
SHUFFLE_CLOUDRUN_URL: "http://{{ include "shuffle.backend.name" . }}.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.backend.containerPorts.http }}"
|
||||||
SHUFFLE_OPENSEARCH_URL: {{ include "common.tplvalues.render" (dict "value" .Values.backend.openSearch.url "context" $) }}
|
SHUFFLE_OPENSEARCH_URL: {{ include "common.tplvalues.render" (dict "value" .Values.backend.openSearch.url "context" $) }}
|
||||||
SHUFFLE_OPENSEARCH_USERNAME: "{{ .Values.backend.openSearch.username }}"
|
SHUFFLE_OPENSEARCH_USERNAME: "{{ .Values.backend.openSearch.username }}"
|
||||||
SHUFFLE_OPENSEARCH_CERTIFICATE_FILE: "{{ .Values.backend.openSearch.certificateFile }}"
|
SHUFFLE_OPENSEARCH_CERTIFICATE_FILE: "{{ .Values.backend.openSearch.certificateFile }}"
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ kind: Service
|
|||||||
metadata:
|
metadata:
|
||||||
name: {{ template "shuffle.backend.name" . }}
|
name: {{ template "shuffle.backend.name" . }}
|
||||||
namespace: {{ include "common.names.namespace" . | quote }}
|
namespace: {{ include "common.names.namespace" . | quote }}
|
||||||
labels: {{- include "shuffle.backend.labels" (dict "customLabels" .Values.commonLabels "context" $) | nindent 4 }}
|
{{- $serviceLabels := include "common.tplvalues.merge" (dict "values" (list .Values.backend.service.labels .Values.commonLabels) "context" .) }}
|
||||||
|
labels: {{- include "shuffle.backend.labels" (dict "customLabels" $serviceLabels "context" $) | nindent 4 }}
|
||||||
{{- if .Values.commonAnnotations }}
|
{{- if .Values.commonAnnotations }}
|
||||||
annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }}
|
annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
@@ -14,5 +15,6 @@ spec:
|
|||||||
port: {{ .Values.backend.containerPorts.http }}
|
port: {{ .Values.backend.containerPorts.http }}
|
||||||
targetPort: http
|
targetPort: http
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
|
appProtocol: http
|
||||||
{{- $podLabels := include "common.tplvalues.merge" (dict "values" (list .Values.backend.podLabels .Values.commonLabels) "context" .) }}
|
{{- $podLabels := include "common.tplvalues.merge" (dict "values" (list .Values.backend.podLabels .Values.commonLabels) "context" .) }}
|
||||||
selector: {{- include "shuffle.backend.matchLabels" (dict "customLabels" $podLabels "context" $) | nindent 4 }}
|
selector: {{- include "shuffle.backend.matchLabels" (dict "customLabels" $podLabels "context" $) | nindent 4 }}
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ kind: Service
|
|||||||
metadata:
|
metadata:
|
||||||
name: {{ template "shuffle.frontend.name" . }}
|
name: {{ template "shuffle.frontend.name" . }}
|
||||||
namespace: {{ include "common.names.namespace" . | quote }}
|
namespace: {{ include "common.names.namespace" . | quote }}
|
||||||
labels: {{- include "shuffle.frontend.labels" (dict "customLabels" .Values.commonLabels "context" $) | nindent 4 }}
|
{{- $serviceLabels := include "common.tplvalues.merge" (dict "values" (list .Values.frontend.service.labels .Values.commonLabels) "context" .) }}
|
||||||
|
labels: {{- include "shuffle.frontend.labels" (dict "customLabels" $serviceLabels "context" $) | nindent 4 }}
|
||||||
{{- if .Values.commonAnnotations }}
|
{{- if .Values.commonAnnotations }}
|
||||||
annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }}
|
annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
@@ -14,11 +15,13 @@ spec:
|
|||||||
port: {{ .Values.frontend.containerPorts.http }}
|
port: {{ .Values.frontend.containerPorts.http }}
|
||||||
targetPort: http
|
targetPort: http
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
|
appProtocol: http
|
||||||
{{- if .Values.frontend.containerPorts.https }}
|
{{- if .Values.frontend.containerPorts.https }}
|
||||||
- name: https
|
- name: https
|
||||||
port: {{ .Values.frontend.containerPorts.https }}
|
port: {{ .Values.frontend.containerPorts.https }}
|
||||||
targetPort: https
|
targetPort: https
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
|
appProtocol: https
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- $podLabels := include "common.tplvalues.merge" (dict "values" (list .Values.frontend.podLabels .Values.commonLabels) "context" .) }}
|
{{- $podLabels := include "common.tplvalues.merge" (dict "values" (list .Values.frontend.podLabels .Values.commonLabels) "context" .) }}
|
||||||
selector: {{- include "shuffle.frontend.matchLabels" (dict "customLabels" $podLabels "context" $) | nindent 4 }}
|
selector: {{- include "shuffle.frontend.matchLabels" (dict "customLabels" $podLabels "context" $) | nindent 4 }}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ data:
|
|||||||
ENVIRONMENT_NAME: "{{ .Values.shuffle.org }}"
|
ENVIRONMENT_NAME: "{{ .Values.shuffle.org }}"
|
||||||
ORG_ID: "{{ .Values.shuffle.org }}"
|
ORG_ID: "{{ .Values.shuffle.org }}"
|
||||||
TZ: "{{ .Values.shuffle.timezone }}"
|
TZ: "{{ .Values.shuffle.timezone }}"
|
||||||
BASE_URL: "http://{{ include "shuffle.backend.name" . }}.{{ .Release.Namespace }}.svc.cluster.local:5001"
|
BASE_URL: "http://{{ include "shuffle.backend.name" . }}.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.backend.containerPorts.http }}"
|
||||||
KUBERNETES_NAMESPACE: "{{ .Release.Namespace }}"
|
KUBERNETES_NAMESPACE: "{{ .Release.Namespace }}"
|
||||||
KUBERNETES_SERVICE_ACCOUNT: {{ include "shuffle.orborus.serviceAccount.name" . }}
|
KUBERNETES_SERVICE_ACCOUNT: {{ include "shuffle.orborus.serviceAccount.name" . }}
|
||||||
SHUFFLE_WORKER_IMAGE: "{{ include "shuffle.worker.image" . }}"
|
SHUFFLE_WORKER_IMAGE: "{{ include "shuffle.worker.image" . }}"
|
||||||
|
|||||||
@@ -90,8 +90,24 @@ spec:
|
|||||||
value: {{ include "shuffle.worker.serviceAccount.name" . }}
|
value: {{ include "shuffle.worker.serviceAccount.name" . }}
|
||||||
- name: SHUFFLE_APP_EXPOSED_PORT
|
- name: SHUFFLE_APP_EXPOSED_PORT
|
||||||
value: {{ .Values.app.exposedContainerPort | quote }}
|
value: {{ .Values.app.exposedContainerPort | quote }}
|
||||||
|
{{- if .Values.worker.podSecurityContext.enabled }}
|
||||||
|
- name: SHUFFLE_WORKER_POD_SECURITY_CONTEXT
|
||||||
|
value: {{ omit .Values.worker.podSecurityContext "enabled" | mustToJson | quote }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.worker.containerSecurityContext.enabled }}
|
||||||
|
- name: SHUFFLE_WORKER_CONTAINER_SECURITY_CONTEXT
|
||||||
|
value: {{ include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.worker.containerSecurityContext "context" $) | fromYaml | mustToJson | quote }}
|
||||||
|
{{- end }}
|
||||||
- name: SHUFFLE_APP_SERVICE_ACCOUNT_NAME
|
- name: SHUFFLE_APP_SERVICE_ACCOUNT_NAME
|
||||||
value: {{ include "shuffle.app.serviceAccount.name" . }}
|
value: {{ include "shuffle.app.serviceAccount.name" . }}
|
||||||
|
{{- if .Values.app.podSecurityContext.enabled }}
|
||||||
|
- name: SHUFFLE_APP_POD_SECURITY_CONTEXT
|
||||||
|
value: {{ omit .Values.app.podSecurityContext "enabled" | mustToJson | quote }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.app.containerSecurityContext.enabled }}
|
||||||
|
- name: SHUFFLE_APP_CONTAINER_SECURITY_CONTEXT
|
||||||
|
value: {{ include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.app.containerSecurityContext "context" $) | fromYaml | mustToJson | quote }}
|
||||||
|
{{- end }}
|
||||||
{{- if .Values.orborus.extraEnvVars }}
|
{{- if .Values.orborus.extraEnvVars }}
|
||||||
{{- include "common.tplvalues.render" (dict "value" .Values.orborus.extraEnvVars "context" $) | nindent 12 }}
|
{{- include "common.tplvalues.render" (dict "value" .Values.orborus.extraEnvVars "context" $) | nindent 12 }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|||||||
+10
@@ -29,6 +29,16 @@ spec:
|
|||||||
- namespaceSelector:
|
- namespaceSelector:
|
||||||
matchLabels:
|
matchLabels:
|
||||||
kubernetes.io/metadata.name: kube-system
|
kubernetes.io/metadata.name: kube-system
|
||||||
|
# Allow access to backend
|
||||||
|
- ports:
|
||||||
|
- port: {{ .Values.backend.containerPorts.http }}
|
||||||
|
protocol: TCP
|
||||||
|
to:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: {{ .Release.Namespace }}
|
||||||
|
podSelector:
|
||||||
|
matchLabels: {{ include "shuffle.backend.matchLabels" . | nindent 14 }}
|
||||||
# Allow access to workers
|
# Allow access to workers
|
||||||
- ports:
|
- ports:
|
||||||
- port: 33333
|
- port: 33333
|
||||||
|
|||||||
@@ -517,7 +517,7 @@
|
|||||||
"type": {
|
"type": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "backend deployment strategy type",
|
"description": "backend deployment strategy type",
|
||||||
"default": "RollingUpdate"
|
"default": "Recreate"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -683,6 +683,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"service": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"labels": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Extra labels for backend service",
|
||||||
|
"default": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"serviceAccount": {
|
"serviceAccount": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -1362,6 +1372,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"service": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"labels": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Extra labels for frontend service",
|
||||||
|
"default": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"serviceAccount": {
|
"serviceAccount": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -2074,6 +2094,103 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"podSecurityContext": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"enabled": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Enable worker pods' Security Context",
|
||||||
|
"default": true
|
||||||
|
},
|
||||||
|
"fsGroupChangePolicy": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Set filesystem group change policy for worker pods",
|
||||||
|
"default": "Always"
|
||||||
|
},
|
||||||
|
"sysctls": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Set kernel settings using the sysctl interface for worker pods",
|
||||||
|
"default": [],
|
||||||
|
"items": {}
|
||||||
|
},
|
||||||
|
"supplementalGroups": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Set filesystem extra groups for worker pods",
|
||||||
|
"default": [],
|
||||||
|
"items": {}
|
||||||
|
},
|
||||||
|
"fsGroup": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "Set fsGroup in worker pods' Security Context",
|
||||||
|
"default": 1001
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"containerSecurityContext": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"enabled": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Enabled worker container' Security Context",
|
||||||
|
"default": true
|
||||||
|
},
|
||||||
|
"runAsUser": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "Set runAsUser in worker container' Security Context",
|
||||||
|
"default": 1001
|
||||||
|
},
|
||||||
|
"runAsGroup": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "Set runAsGroup in worker container' Security Context",
|
||||||
|
"default": 1001
|
||||||
|
},
|
||||||
|
"runAsNonRoot": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Set runAsNonRoot in worker container' Security Context",
|
||||||
|
"default": true
|
||||||
|
},
|
||||||
|
"readOnlyRootFilesystem": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Set readOnlyRootFilesystem in worker container' Security Context",
|
||||||
|
"default": true
|
||||||
|
},
|
||||||
|
"privileged": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Set privileged in worker container' Security Context",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
|
"allowPrivilegeEscalation": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Set allowPrivilegeEscalation in worker container' Security Context",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
|
"capabilities": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"drop": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "List of capabilities to be dropped in worker container",
|
||||||
|
"default": [
|
||||||
|
"ALL"
|
||||||
|
],
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"seccompProfile": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Set seccomp profile in worker container",
|
||||||
|
"default": "RuntimeDefault"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"serviceAccount": {
|
"serviceAccount": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -2152,6 +2269,103 @@
|
|||||||
"app": {
|
"app": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"podSecurityContext": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"enabled": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Enable app pods' Security Context",
|
||||||
|
"default": true
|
||||||
|
},
|
||||||
|
"fsGroupChangePolicy": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Set filesystem group change policy for app pods",
|
||||||
|
"default": "Always"
|
||||||
|
},
|
||||||
|
"sysctls": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Set kernel settings using the sysctl interface for app pods",
|
||||||
|
"default": [],
|
||||||
|
"items": {}
|
||||||
|
},
|
||||||
|
"supplementalGroups": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Set filesystem extra groups for app pods",
|
||||||
|
"default": [],
|
||||||
|
"items": {}
|
||||||
|
},
|
||||||
|
"fsGroup": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "Set fsGroup in app pods' Security Context",
|
||||||
|
"default": 1001
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"containerSecurityContext": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"enabled": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Enabled app container' Security Context",
|
||||||
|
"default": true
|
||||||
|
},
|
||||||
|
"runAsUser": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "Set runAsUser in app container' Security Context",
|
||||||
|
"default": 1001
|
||||||
|
},
|
||||||
|
"runAsGroup": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "Set runAsGroup in app container' Security Context",
|
||||||
|
"default": 1001
|
||||||
|
},
|
||||||
|
"runAsNonRoot": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Set runAsNonRoot in app container' Security Context",
|
||||||
|
"default": true
|
||||||
|
},
|
||||||
|
"readOnlyRootFilesystem": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Set readOnlyRootFilesystem in app container' Security Context",
|
||||||
|
"default": true
|
||||||
|
},
|
||||||
|
"privileged": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Set privileged in app container' Security Context",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
|
"allowPrivilegeEscalation": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Set allowPrivilegeEscalation in app container' Security Context",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
|
"capabilities": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"drop": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "List of capabilities to be dropped in app container",
|
||||||
|
"default": [
|
||||||
|
"ALL"
|
||||||
|
],
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"seccompProfile": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Set seccomp profile in app container",
|
||||||
|
"default": "RuntimeDefault"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"serviceAccount": {
|
"serviceAccount": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|||||||
@@ -310,14 +310,14 @@ backend:
|
|||||||
## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/
|
## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/
|
||||||
##
|
##
|
||||||
tolerations: []
|
tolerations: []
|
||||||
## ONLY FOR DEPLOYMENTS:
|
|
||||||
## @param backend.updateStrategy.type backend deployment strategy type
|
## @param backend.updateStrategy.type backend deployment strategy type
|
||||||
## ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy
|
## ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy
|
||||||
##
|
##
|
||||||
updateStrategy:
|
updateStrategy:
|
||||||
## Can be set to RollingUpdate or Recreate
|
## Can be set to RollingUpdate or Recreate
|
||||||
|
## Backend uses ReadWriteOnce volumes by default, which is incompatible with RollingUpdate
|
||||||
##
|
##
|
||||||
type: RollingUpdate
|
type: Recreate
|
||||||
## @param backend.priorityClassName backend pods' priorityClassName
|
## @param backend.priorityClassName backend pods' priorityClassName
|
||||||
##
|
##
|
||||||
priorityClassName: ""
|
priorityClassName: ""
|
||||||
@@ -421,6 +421,14 @@ backend:
|
|||||||
targetCPU: ""
|
targetCPU: ""
|
||||||
targetMemory: ""
|
targetMemory: ""
|
||||||
|
|
||||||
|
## Service configuration
|
||||||
|
##
|
||||||
|
service:
|
||||||
|
## @param backend.service.labels Extra labels for backend service
|
||||||
|
## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
|
||||||
|
##
|
||||||
|
labels: {}
|
||||||
|
|
||||||
## ServiceAccount configuration
|
## ServiceAccount configuration
|
||||||
##
|
##
|
||||||
serviceAccount:
|
serviceAccount:
|
||||||
@@ -870,6 +878,14 @@ frontend:
|
|||||||
targetCPU: ""
|
targetCPU: ""
|
||||||
targetMemory: ""
|
targetMemory: ""
|
||||||
|
|
||||||
|
## Service configuration
|
||||||
|
##
|
||||||
|
service:
|
||||||
|
## @param frontend.service.labels Extra labels for frontend service
|
||||||
|
## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
|
||||||
|
##
|
||||||
|
labels: {}
|
||||||
|
|
||||||
## ServiceAccount configuration
|
## ServiceAccount configuration
|
||||||
##
|
##
|
||||||
serviceAccount:
|
serviceAccount:
|
||||||
@@ -1328,6 +1344,48 @@ worker:
|
|||||||
tag: ""
|
tag: ""
|
||||||
digest: ""
|
digest: ""
|
||||||
|
|
||||||
|
## Configure Pods Security Context
|
||||||
|
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod
|
||||||
|
## @param worker.podSecurityContext.enabled Enable worker pods' Security Context
|
||||||
|
## @param worker.podSecurityContext.fsGroupChangePolicy Set filesystem group change policy for worker pods
|
||||||
|
## @param worker.podSecurityContext.sysctls Set kernel settings using the sysctl interface for worker pods
|
||||||
|
## @param worker.podSecurityContext.supplementalGroups Set filesystem extra groups for worker pods
|
||||||
|
## @param worker.podSecurityContext.fsGroup Set fsGroup in worker pods' Security Context
|
||||||
|
##
|
||||||
|
podSecurityContext:
|
||||||
|
enabled: true
|
||||||
|
fsGroupChangePolicy: Always
|
||||||
|
sysctls: []
|
||||||
|
supplementalGroups: []
|
||||||
|
fsGroup: 1001
|
||||||
|
|
||||||
|
## Configure Container Security Context
|
||||||
|
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container
|
||||||
|
## @param worker.containerSecurityContext.enabled Enabled worker container' Security Context
|
||||||
|
## @param worker.containerSecurityContext.seLinuxOptions [object,nullable] Set SELinux options in worker container
|
||||||
|
## @param worker.containerSecurityContext.runAsUser Set runAsUser in worker container' Security Context
|
||||||
|
## @param worker.containerSecurityContext.runAsGroup Set runAsGroup in worker container' Security Context
|
||||||
|
## @param worker.containerSecurityContext.runAsNonRoot Set runAsNonRoot in worker container' Security Context
|
||||||
|
## @param worker.containerSecurityContext.readOnlyRootFilesystem Set readOnlyRootFilesystem in worker container' Security Context
|
||||||
|
## @param worker.containerSecurityContext.privileged Set privileged in worker container' Security Context
|
||||||
|
## @param worker.containerSecurityContext.allowPrivilegeEscalation Set allowPrivilegeEscalation in worker container' Security Context
|
||||||
|
## @param worker.containerSecurityContext.capabilities.drop List of capabilities to be dropped in worker container
|
||||||
|
## @param worker.containerSecurityContext.seccompProfile.type Set seccomp profile in worker container
|
||||||
|
##
|
||||||
|
containerSecurityContext:
|
||||||
|
enabled: true
|
||||||
|
seLinuxOptions: {}
|
||||||
|
runAsUser: 1001
|
||||||
|
runAsGroup: 1001
|
||||||
|
runAsNonRoot: true
|
||||||
|
readOnlyRootFilesystem: true
|
||||||
|
privileged: false
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop: ["ALL"]
|
||||||
|
seccompProfile:
|
||||||
|
type: "RuntimeDefault"
|
||||||
|
|
||||||
## ServiceAccount configuration
|
## ServiceAccount configuration
|
||||||
##
|
##
|
||||||
serviceAccount:
|
serviceAccount:
|
||||||
@@ -1390,6 +1448,48 @@ worker:
|
|||||||
## @section app Parameters
|
## @section app Parameters
|
||||||
##
|
##
|
||||||
app:
|
app:
|
||||||
|
## Configure Pods Security Context
|
||||||
|
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod
|
||||||
|
## @param app.podSecurityContext.enabled Enable app pods' Security Context
|
||||||
|
## @param app.podSecurityContext.fsGroupChangePolicy Set filesystem group change policy for app pods
|
||||||
|
## @param app.podSecurityContext.sysctls Set kernel settings using the sysctl interface for app pods
|
||||||
|
## @param app.podSecurityContext.supplementalGroups Set filesystem extra groups for app pods
|
||||||
|
## @param app.podSecurityContext.fsGroup Set fsGroup in app pods' Security Context
|
||||||
|
##
|
||||||
|
podSecurityContext:
|
||||||
|
enabled: true
|
||||||
|
fsGroupChangePolicy: Always
|
||||||
|
sysctls: []
|
||||||
|
supplementalGroups: []
|
||||||
|
fsGroup: 1001
|
||||||
|
|
||||||
|
## Configure Container Security Context
|
||||||
|
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container
|
||||||
|
## @param app.containerSecurityContext.enabled Enabled app container' Security Context
|
||||||
|
## @param app.containerSecurityContext.seLinuxOptions [object,nullable] Set SELinux options in app container
|
||||||
|
## @param app.containerSecurityContext.runAsUser Set runAsUser in app container' Security Context
|
||||||
|
## @param app.containerSecurityContext.runAsGroup Set runAsGroup in app container' Security Context
|
||||||
|
## @param app.containerSecurityContext.runAsNonRoot Set runAsNonRoot in app container' Security Context
|
||||||
|
## @param app.containerSecurityContext.readOnlyRootFilesystem Set readOnlyRootFilesystem in app container' Security Context
|
||||||
|
## @param app.containerSecurityContext.privileged Set privileged in app container' Security Context
|
||||||
|
## @param app.containerSecurityContext.allowPrivilegeEscalation Set allowPrivilegeEscalation in app container' Security Context
|
||||||
|
## @param app.containerSecurityContext.capabilities.drop List of capabilities to be dropped in app container
|
||||||
|
## @param app.containerSecurityContext.seccompProfile.type Set seccomp profile in app container
|
||||||
|
##
|
||||||
|
containerSecurityContext:
|
||||||
|
enabled: true
|
||||||
|
seLinuxOptions: {}
|
||||||
|
runAsUser: 1001
|
||||||
|
runAsGroup: 1001
|
||||||
|
runAsNonRoot: true
|
||||||
|
readOnlyRootFilesystem: true
|
||||||
|
privileged: false
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop: ["ALL"]
|
||||||
|
seccompProfile:
|
||||||
|
type: "RuntimeDefault"
|
||||||
|
|
||||||
## ServiceAccount configuration
|
## ServiceAccount configuration
|
||||||
##
|
##
|
||||||
serviceAccount:
|
serviceAccount:
|
||||||
|
|||||||
@@ -76,7 +76,11 @@ var maxCPUPercent = 90
|
|||||||
var isKubernetes = os.Getenv("IS_KUBERNETES")
|
var isKubernetes = os.Getenv("IS_KUBERNETES")
|
||||||
var kubernetesNamespace = os.Getenv("KUBERNETES_NAMESPACE")
|
var kubernetesNamespace = os.Getenv("KUBERNETES_NAMESPACE")
|
||||||
var workerServiceAccountName = os.Getenv("SHUFFLE_WORKER_SERVICE_ACCOUNT_NAME")
|
var workerServiceAccountName = os.Getenv("SHUFFLE_WORKER_SERVICE_ACCOUNT_NAME")
|
||||||
|
var workerPodSecurityContext = os.Getenv("SHUFFLE_WORKER_POD_SECURITY_CONTEXT")
|
||||||
|
var workerContainerSecurityContext = os.Getenv("SHUFFLE_WORKER_CONTAINER_SECURITY_CONTEXT")
|
||||||
var appServiceAccountName = os.Getenv("SHUFFLE_APP_SERVICE_ACCOUNT_NAME")
|
var appServiceAccountName = os.Getenv("SHUFFLE_APP_SERVICE_ACCOUNT_NAME")
|
||||||
|
var appPodSecurityContext = os.Getenv("SHUFFLE_APP_POD_SECURITY_CONTEXT")
|
||||||
|
var appContainerSecurityContext = os.Getenv("SHUFFLE_APP_CONTAINER_SECURITY_CONTEXT")
|
||||||
|
|
||||||
// var baseimagename = "docker.pkg.github.com/shuffle/shuffle"
|
// var baseimagename = "docker.pkg.github.com/shuffle/shuffle"
|
||||||
// var baseimagename = "ghcr.io/frikky"
|
// var baseimagename = "ghcr.io/frikky"
|
||||||
@@ -1004,6 +1008,14 @@ func deployK8sWorker(image string, identifier string, env []string) error {
|
|||||||
env = append(env, fmt.Sprintf("SHUFFLE_APP_SERVICE_ACCOUNT_NAME=%s", appServiceAccountName))
|
env = append(env, fmt.Sprintf("SHUFFLE_APP_SERVICE_ACCOUNT_NAME=%s", appServiceAccountName))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(appPodSecurityContext) > 0 {
|
||||||
|
env = append(env, fmt.Sprintf("SHUFFLE_APP_POD_SECURITY_CONTEXT=%s", appPodSecurityContext))
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(appContainerSecurityContext) > 0 {
|
||||||
|
env = append(env, fmt.Sprintf("SHUFFLE_APP_CONTAINER_SECURITY_CONTEXT=%s", appContainerSecurityContext))
|
||||||
|
}
|
||||||
|
|
||||||
clientset, _, err := shuffle.GetKubernetesClient()
|
clientset, _, err := shuffle.GetKubernetesClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("[ERROR] Error getting kubernetes client:", err)
|
log.Printf("[ERROR] Error getting kubernetes client:", err)
|
||||||
@@ -1085,10 +1097,33 @@ func deployK8sWorker(image string, identifier string, env []string) error {
|
|||||||
"app.kubernetes.io/instance": identifier,
|
"app.kubernetes.io/instance": identifier,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse security contexts from env
|
||||||
|
var podSecurityContext *corev1.PodSecurityContext
|
||||||
|
var containerSecurityContext *corev1.SecurityContext
|
||||||
|
|
||||||
|
if len(workerPodSecurityContext) > 0 {
|
||||||
|
podSecurityContext = &corev1.PodSecurityContext{}
|
||||||
|
err = json.Unmarshal([]byte(workerPodSecurityContext), podSecurityContext)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[ERROR] Failed to unmarshal worker pod security context: %v", err)
|
||||||
|
return fmt.Errorf("failed to unmarshal worker pod security context: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(workerContainerSecurityContext) > 0 {
|
||||||
|
containerSecurityContext = &corev1.SecurityContext{}
|
||||||
|
err = json.Unmarshal([]byte(workerContainerSecurityContext), containerSecurityContext)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[ERROR] Failed to unmarshal worker container security context: %v", err)
|
||||||
|
return fmt.Errorf("failed to unmarshal worker container security context: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
containerAttachment := corev1.Container{
|
containerAttachment := corev1.Container{
|
||||||
Name: identifier,
|
Name: identifier,
|
||||||
Image: kubernetesImage,
|
Image: kubernetesImage,
|
||||||
Env: buildEnvVars(envMap),
|
Env: buildEnvVars(envMap),
|
||||||
|
SecurityContext: containerSecurityContext,
|
||||||
|
|
||||||
//ImagePullPolicy: "Never",
|
//ImagePullPolicy: "Never",
|
||||||
ImagePullPolicy: corev1.PullIfNotPresent,
|
ImagePullPolicy: corev1.PullIfNotPresent,
|
||||||
@@ -1205,6 +1240,7 @@ func deployK8sWorker(image string, identifier string, env []string) error {
|
|||||||
},
|
},
|
||||||
DNSPolicy: corev1.DNSClusterFirst,
|
DNSPolicy: corev1.DNSClusterFirst,
|
||||||
ServiceAccountName: workerServiceAccountName,
|
ServiceAccountName: workerServiceAccountName,
|
||||||
|
SecurityContext: podSecurityContext,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -57,9 +57,13 @@ var logsDisabled = os.Getenv("SHUFFLE_LOGS_DISABLED")
|
|||||||
var cleanupEnv = strings.ToLower(os.Getenv("CLEANUP"))
|
var cleanupEnv = strings.ToLower(os.Getenv("CLEANUP"))
|
||||||
var swarmNetworkName = os.Getenv("SHUFFLE_SWARM_NETWORK_NAME")
|
var swarmNetworkName = os.Getenv("SHUFFLE_SWARM_NETWORK_NAME")
|
||||||
var dockerApiVersion = strings.ToLower(os.Getenv("DOCKER_API_VERSION"))
|
var dockerApiVersion = strings.ToLower(os.Getenv("DOCKER_API_VERSION"))
|
||||||
var appServiceAccountName = os.Getenv("SHUFFLE_APP_SERVICE_ACCOUNT_NAME")
|
|
||||||
|
|
||||||
|
// Kubernetes settings
|
||||||
|
var appServiceAccountName = os.Getenv("SHUFFLE_APP_SERVICE_ACCOUNT_NAME")
|
||||||
|
var appPodSecurityContext = os.Getenv("SHUFFLE_APP_POD_SECURITY_CONTEXT")
|
||||||
|
var appContainerSecurityContext = os.Getenv("SHUFFLE_APP_CONTAINER_SECURITY_CONTEXT")
|
||||||
var kubernetesNamespace = os.Getenv("KUBERNETES_NAMESPACE")
|
var kubernetesNamespace = os.Getenv("KUBERNETES_NAMESPACE")
|
||||||
|
|
||||||
var executionCount int64
|
var executionCount int64
|
||||||
|
|
||||||
var baseimagename = os.Getenv("SHUFFLE_BASE_IMAGE_NAME")
|
var baseimagename = os.Getenv("SHUFFLE_BASE_IMAGE_NAME")
|
||||||
@@ -74,6 +78,7 @@ var appsInitialized = false
|
|||||||
|
|
||||||
var hostname string
|
var hostname string
|
||||||
var maxReplicas = uint64(12)
|
var maxReplicas = uint64(12)
|
||||||
|
var debug bool
|
||||||
|
|
||||||
/*
|
/*
|
||||||
var environments []string
|
var environments []string
|
||||||
@@ -506,6 +511,28 @@ func deployk8sApp(image string, identifier string, env []string) error {
|
|||||||
"app.kubernetes.io/instance": name,
|
"app.kubernetes.io/instance": name,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse security contexts from env
|
||||||
|
var podSecurityContext *corev1.PodSecurityContext
|
||||||
|
var containerSecurityContext *corev1.SecurityContext
|
||||||
|
|
||||||
|
if len(appPodSecurityContext) > 0 {
|
||||||
|
podSecurityContext = &corev1.PodSecurityContext{}
|
||||||
|
err = json.Unmarshal([]byte(appPodSecurityContext), podSecurityContext)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[ERROR] Failed to unmarshal app pod security context: %v", err)
|
||||||
|
return fmt.Errorf("failed to unmarshal app pod security context: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(appContainerSecurityContext) > 0 {
|
||||||
|
containerSecurityContext = &corev1.SecurityContext{}
|
||||||
|
err = json.Unmarshal([]byte(appContainerSecurityContext), containerSecurityContext)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[ERROR] Failed to unmarshal app container security context: %v", err)
|
||||||
|
return fmt.Errorf("failed to unmarshal app container security context: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// pod := &corev1.Pod{
|
// pod := &corev1.Pod{
|
||||||
// ObjectMeta: metav1.ObjectMeta{
|
// ObjectMeta: metav1.ObjectMeta{
|
||||||
// Name: podName,
|
// Name: podName,
|
||||||
@@ -608,10 +635,12 @@ func deployk8sApp(image string, identifier string, env []string) error {
|
|||||||
ContainerPort: int32(deployport),
|
ContainerPort: int32(deployport),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
SecurityContext: containerSecurityContext,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
DNSPolicy: corev1.DNSClusterFirst,
|
DNSPolicy: corev1.DNSClusterFirst,
|
||||||
ServiceAccountName: appServiceAccountName,
|
ServiceAccountName: appServiceAccountName,
|
||||||
|
SecurityContext: podSecurityContext,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -2555,11 +2584,16 @@ func runWorkflowExecutionTransaction(ctx context.Context, attempts int64, workfl
|
|||||||
}
|
}
|
||||||
|
|
||||||
if setExecution || workflowExecution.Status == "FINISHED" || workflowExecution.Status == "ABORTED" || workflowExecution.Status == "FAILURE" {
|
if setExecution || workflowExecution.Status == "FINISHED" || workflowExecution.Status == "ABORTED" || workflowExecution.Status == "FAILURE" {
|
||||||
log.Printf("[DEBUG][%s] Running setexec with status %s and %d/%d results", workflowExecution.ExecutionId, workflowExecution.Status, len(workflowExecution.Results), len(workflowExecution.Workflow.Actions))
|
if debug {
|
||||||
|
log.Printf("[DEBUG][%s] Running setexec with status %s and %d/%d results", workflowExecution.ExecutionId, workflowExecution.Status, len(workflowExecution.Results), len(workflowExecution.Workflow.Actions))
|
||||||
|
}
|
||||||
|
|
||||||
//result(s)", workflowExecution.ExecutionId, workflowExecution.Status, len(workflowExecution.Results))
|
//result(s)", workflowExecution.ExecutionId, workflowExecution.Status, len(workflowExecution.Results))
|
||||||
err = setWorkflowExecution(ctx, *workflowExecution, dbSave)
|
err = setWorkflowExecution(ctx, *workflowExecution, dbSave)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.WriteHeader(401)
|
log.Printf("[ERROR][%s] Failed setting execution: %s", workflowExecution.ExecutionId, err)
|
||||||
|
|
||||||
|
resp.WriteHeader(400)
|
||||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed setting workflowexecution actionresult: %s"}`, err)))
|
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed setting workflowexecution actionresult: %s"}`, err)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -2568,7 +2602,10 @@ func runWorkflowExecutionTransaction(ctx context.Context, attempts int64, workfl
|
|||||||
if os.Getenv("SHUFFLE_SWARM_CONFIG") == "run" || os.Getenv("SHUFFLE_SWARM_CONFIG") == "swarm" {
|
if os.Getenv("SHUFFLE_SWARM_CONFIG") == "run" || os.Getenv("SHUFFLE_SWARM_CONFIG") == "swarm" {
|
||||||
finished := shuffle.ValidateFinished(ctx, -1, *workflowExecution)
|
finished := shuffle.ValidateFinished(ctx, -1, *workflowExecution)
|
||||||
if !finished {
|
if !finished {
|
||||||
log.Printf("[DEBUG][%s] Handling next node since it's not finished!", workflowExecution.ExecutionId)
|
if debug {
|
||||||
|
log.Printf("[DEBUG][%s] Handling next node since it's not finished!", workflowExecution.ExecutionId)
|
||||||
|
}
|
||||||
|
|
||||||
handleExecutionResult(*workflowExecution)
|
handleExecutionResult(*workflowExecution)
|
||||||
} else {
|
} else {
|
||||||
shutdownData, err := json.Marshal(workflowExecution)
|
shutdownData, err := json.Marshal(workflowExecution)
|
||||||
@@ -3526,7 +3563,9 @@ func sendAppRequest(ctx context.Context, incomingUrl, appName string, port int,
|
|||||||
log.Printf("[ERROR] Failed reading app request body body: %s", err)
|
log.Printf("[ERROR] Failed reading app request body body: %s", err)
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
log.Printf("[DEBUG][%s] NEWRESP (from app): %s", workflowExecution.ExecutionId, string(body))
|
if debug {
|
||||||
|
log.Printf("[DEBUG][%s] NEWRESP (from app): %s", workflowExecution.ExecutionId, string(body))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -3918,6 +3957,10 @@ func checkStandaloneRun() {
|
|||||||
func main() {
|
func main() {
|
||||||
checkStandaloneRun()
|
checkStandaloneRun()
|
||||||
|
|
||||||
|
if os.Getenv("DEBUG") == "true" {
|
||||||
|
debug = true
|
||||||
|
}
|
||||||
|
|
||||||
/*** STARTREMOVE ***/
|
/*** STARTREMOVE ***/
|
||||||
if os.Getenv("SHUFFLE_SWARM_CONFIG") == "run" || os.Getenv("SHUFFLE_SWARM_CONFIG") == "swarm" {
|
if os.Getenv("SHUFFLE_SWARM_CONFIG") == "run" || os.Getenv("SHUFFLE_SWARM_CONFIG") == "swarm" {
|
||||||
logsDisabled = "true"
|
logsDisabled = "true"
|
||||||
|
|||||||
Reference in New Issue
Block a user