From ec1cf6d1a811e1e456c8a0681a9022d2758bc05f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20=20LAURENT?= <francois.laurent@pasteur.fr>
Date: Thu, 17 Apr 2025 18:46:55 +0200
Subject: [PATCH] Set of commits to be tagged v0.2.1
---
.gitlab-ci.yml | 63 ++++-----
Project.toml | 2 +-
README.md | 12 +-
back/Containerfile.larvatagger | 58 ++++++++
back/larvatagger-build.sh | 28 ++++
back/larvatagger-entrypoint.sh | 15 ++
back/larvatagger-no-build.sh | 30 ++++
front/Containerfile | 2 +-
front/Containerfile.local | 2 +-
front/Manifest.toml | 16 ++-
front/build-run-local.sh | 2 +-
front/build.sh | 2 +-
front/entrypoint.sh | 11 ++
nyxui/Chart.yaml | 4 +-
nyxui/templates/configmap-front.yaml | 9 ++
nyxui/templates/deployment-front.yaml | 15 +-
nyxui/templates/deployment-larvatagger.yaml | 69 ++++++++++
nyxui/templates/ingress.yaml | 4 +-
.../{service.yaml => service-front.yaml} | 3 +-
nyxui/templates/service-larvatagger.yaml | 16 +++
nyxui/values.yaml | 49 ++++---
src/GenieExtras.jl | 130 +++++++++++++++++-
src/apps/catalog/app.jl | 4 +-
src/apps/larvatagger/app.jl | 60 ++++----
src/apps/muscles/Backbone.jl | 79 ++++-------
src/apps/muscles/app.jl | 9 +-
values-yaml.gotmpl | 61 ++++----
27 files changed, 571 insertions(+), 184 deletions(-)
create mode 100644 back/Containerfile.larvatagger
create mode 100755 back/larvatagger-build.sh
create mode 100755 back/larvatagger-entrypoint.sh
create mode 100755 back/larvatagger-no-build.sh
create mode 100644 nyxui/templates/configmap-front.yaml
create mode 100644 nyxui/templates/deployment-larvatagger.yaml
rename nyxui/templates/{service.yaml => service-front.yaml} (79%)
create mode 100644 nyxui/templates/service-larvatagger.yaml
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 79f586e..fd8d8e9 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -14,17 +14,22 @@ stages:
STORAGE_DRIVER: vfs
BUILDAH_FORMAT: docker
BUILDAH_ISOLATION: chroot
- FQ_IMAGE_NAME: "$CI_REGISTRY_IMAGE/front:$CI_COMMIT_SHORT_SHA"
+ IMAGE_NAME: front
+ IMAGE_TAG: "$CI_COMMIT_SHORT_SHA"
+ REGISTRY_IMAGE: "$CI_REGISTRY_IMAGE/$IMAGE_NAME"
+ FQ_IMAGE_NAME: "$REGISTRY_IMAGE:$IMAGE_TAG"
BUILD_CONTEXT: "."
CONTAINERFILE: "front/Containerfile"
before_script:
- export REGISTRY_AUTH_FILE="$HOME/auth.json"
- echo "$CI_REGISTRY_PASSWORD" | buildah login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"
script:
- - buildah build -t "$FQ_IMAGE_NAME" -f "$CONTAINERFILE" "$BUILD_CONTEXT"
+ - buildah build -t "$FQ_IMAGE_NAME" -f "$CONTAINERFILE" $BUILD_CONTEXT
- buildah push "$FQ_IMAGE_NAME"
+ - buildah tag "$FQ_IMAGE_NAME" "$REGISTRY_IMAGE:latest"
+ - buildah push "$REGISTRY_IMAGE:latest"
-build on gitlab.pasteur.fr:
+build front:
extends: .build-with-buildah
variables:
PUBLIC_URL: "nyx.pasteur.cloud"
@@ -32,7 +37,7 @@ build on gitlab.pasteur.fr:
- if: ($CI_COMMIT_BRANCH == "main" &&
$CI_PROJECT_ID == $GITLAB_PASTEUR_PROJECT_ID) # gitlab.pasteur.fr only
-build dev on gitlab.pasteur.fr:
+build dev front:
extends: .build-with-buildah
variables:
PUBLIC_URL: "nyx.dev.pasteur.cloud"
@@ -40,25 +45,6 @@ build dev on gitlab.pasteur.fr:
- if: ($CI_COMMIT_BRANCH == "dev" &&
$CI_PROJECT_ID == $GITLAB_PASTEUR_PROJECT_ID) # gitlab.pasteur.fr only
-.deploy-with-manifests:
- stage: deploy
- image: docker.io/enix/ci-toolbox:1.21
- variables:
- APP_NAME: nyxui
- FQ_IMAGE_NAME: "$CI_REGISTRY_IMAGE/front:$CI_COMMIT_SHORT_SHA"
- script:
- - kubectl create secret
- docker-registry registry-gitlab
- --docker-server=registry-gitlab.pasteur.fr
- --docker-username="$DOCKER_USER"
- --docker-password="$DOCKER_TOKEN"
- --docker-email=kubernetes@pasteur.fr
- -n "$KUBE_NAMESPACE"
- --dry-run=client -o yaml | kubectl apply -f -
- - envsubst < k8s/front-deployment.yaml | kubectl apply -n "$KUBE_NAMESPACE" -f -
- - envsubst < k8s/front-service.yaml | kubectl apply -n "$KUBE_NAMESPACE" -f -
- - envsubst < k8s/ingress.yaml | kubectl apply -n "$KUBE_NAMESPACE" -f -
-
.deploy-with-helm:
stage: deploy
image: docker.io/enix/ci-toolbox:1.21
@@ -81,16 +67,17 @@ build dev on gitlab.pasteur.fr:
deploy to pasteur.cloud:
extends: .deploy-with-helm
variables:
- SERVICE_TARGET_PORT: "8080"
IMAGE_SECRETS: "registry-gitlab"
KUBE_NAMESPACE: "nyx-prod"
PUBLIC_URL: "nyx.pasteur.cloud"
INGRESS_CLASS: "external"
INGRESS_URL: "nyx.pasteur.cloud"
- SERVICE_PORT: "80"
LIMITS_CPU: "2"
- LIMITS_MEMORY: "4Gi"
- LIMITS_STORAGE: "1Gi"
+ LIMITS_MEMORY: "5Gi"
+ LIMITS_STORAGE: "4Gi"
+ LT_LIMITS_CPU: "2"
+ LT_LIMITS_MEMORY: "5Gi"
+ LT_LIMITS_STORAGE: "2Gi"
environment:
name: k8sprod-02/nyx-prod
url: https://nyx.pasteur.cloud
@@ -102,16 +89,17 @@ deploy to pasteur.cloud:
deploy to dev.pasteur.cloud:
extends: .deploy-with-helm
variables:
- SERVICE_TARGET_PORT: "8080"
IMAGE_SECRETS: "registry-gitlab"
KUBE_NAMESPACE: "nyx-dev"
PUBLIC_URL: "nyx.dev.pasteur.cloud"
INGRESS_CLASS: "internal"
INGRESS_URL: "nyx.dev.pasteur.cloud"
- SERVICE_PORT: "80"
LIMITS_CPU: "2"
- LIMITS_MEMORY: "4Gi"
- LIMITS_STORAGE: "1Gi"
+ LIMITS_MEMORY: "5Gi"
+ LIMITS_STORAGE: "4Gi"
+ LT_LIMITS_CPU: "2"
+ LT_LIMITS_MEMORY: "5Gi"
+ LT_LIMITS_STORAGE: "2Gi"
environment:
name: k8sdev-01/nyx-dev
url: https://nyx.dev.pasteur.cloud
@@ -120,3 +108,16 @@ deploy to dev.pasteur.cloud:
$CI_PROJECT_ID == $GITLAB_PASTEUR_PROJECT_ID) # gitlab.pasteur.fr only
when: manual
+build larvatagger backend:
+ extends: .build-with-buildah
+ variables:
+ IMAGE_NAME: "larvatagger"
+ IMAGE_TAG: "0.20.1-bigfat"
+ BUILD_CONTEXT: --build-arg LARVATAGGER_IMAGE_TAG=0.20.1-bigfat back
+ CONTAINERFILE: "back/Containerfile.larvatagger"
+ rules:
+ - if: ($CI_COMMIT_BRANCH == "dev" &&
+ $CI_PROJECT_ID == $GITLAB_PASTEUR_PROJECT_ID) # gitlab.pasteur.fr only
+ when: manual # on IMAGE_TAG update only; alias latest is used and
+ allow_failure: true # should be confirmed to work when moving to branch main
+
diff --git a/Project.toml b/Project.toml
index c0988dd..d4e91c2 100644
--- a/Project.toml
+++ b/Project.toml
@@ -1,7 +1,7 @@
name = "NyxUI"
uuid = "2c32e805-e4ca-4d0f-96f6-9d2d6204339d"
authors = ["François Laurent <francois.laurent@pasteur.fr>"]
-version = "0.2.0"
+version = "0.2.1"
[deps]
Bonito = "824d6782-a2ef-11e9-3a09-e5662e0c26f8"
diff --git a/README.md b/README.md
index 4b6613d..f97582d 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ Web interface meant to be served at [nyx.pasteur.cloud](https://nyx.pasteur.clou
It features an app catalog, with the following apps:
* an editor for muscular activity programs,
-* [LarvaTagger.jl](https://gitlab.pasteur.fr/nyx/larvatagger.jl) without any automating tagging backends.
+* [LarvaTagger.jl](https://gitlab.pasteur.fr/nyx/larvatagger.jl) with two automating tagging backends.
## Local installation
@@ -24,10 +24,11 @@ cp front/Manifest.toml .
juliaup add lts
juliaup default lts
julia --project=. -e 'using Pkg; Pkg.instantiate()'
+. back/larvatagger-no-build.sh
julia --project=. routes.jl
```
-You may be asked whether to authorize ports 9284 and 9285; please give the app permission.
+You may be asked whether to authorize ports 9284, 9285 and 9286; please give the app permission.
From there, in a web browser, open http://localhost:9284/ to access the app.
@@ -35,4 +36,9 @@ Note that the generated files can be found somewhere in directory *storage/expor
The download buttons in the LarvaTagger app will not work in the web browser.
To make them work, the reverse proxy setup in the container image called *front* is required.
-If you have [Podman](https://podman.io/), as an alternative to the above installation procedure, you can simply run `front/build.sh --now` and, once the container is up and running, connect to http://localhost:8080/.
+If you have [Podman](https://podman.io/), as an alternative to the above installation procedure, you can simply run the backend and frontend as follows:
+```
+. back/larvatagger-no-build.sh
+front/build.sh --now
+```
+Once the frontend container is up and running, connect to http://localhost:8080/.
diff --git a/back/Containerfile.larvatagger b/back/Containerfile.larvatagger
new file mode 100644
index 0000000..963f042
--- /dev/null
+++ b/back/Containerfile.larvatagger
@@ -0,0 +1,58 @@
+ARG LARVATAGGER_IMAGE_TAG=0.20.1-bigfat
+FROM docker.io/flaur/larvatagger:${LARVATAGGER_IMAGE_TAG} as src
+
+
+FROM debian:bullseye as base
+
+# Python and Curl for Poetry
+RUN apt-get update \
+ && apt-get install --no-install-recommends -y python3-dev python3-pip curl \
+ && rm -rf /var/lib/apt/lists/*
+
+# Unprivileged environment
+ARG UID=1001
+
+RUN useradd julia -u ${UID} --user-group --create-home
+
+COPY --chown=julia --from=src /app /app/
+
+USER ${UID}
+
+# Poetry
+ENV POETRY_VERSION=1.8.4
+
+ENV POETRY_HOME=/app/poetry
+ENV POETRY_VIRTUALENVS_IN_PROJECT=1
+ENV PIP_DISABLE_PIP_VERSION_CHECK=1
+ENV PIP_NO_CACHE_DIR=1
+
+RUN curl -sSL https://install.python-poetry.org | python3 -
+
+# Julia
+ARG JULIA_VERSION=1.10.9
+
+ENV JULIA_PROJECT=/app
+ENV JULIA_DEPOT_PATH=/app/julia
+ENV JULIAUP_DEPOT_PATH=/app/juliaup
+
+RUN export HOME="${JULIA_PROJECT}" \
+ && curl -fsSL https://install.julialang.org \
+ | sh -s -- --yes --default-channel "${JULIA_VERSION}" \
+ && ${JULIA_PROJECT}/.juliaup/bin/juliaup config versionsdbupdateinterval 0
+
+ENV PATH "${PATH}:${JULIA_PROJECT}/.juliaup/bin:${POETRY_HOME}/bin"
+
+# LarvaTagger.jl/MaggotUBA-adapter/PasteurJanelia-adapter
+RUN cd "${JULIA_PROJECT}" \
+ && julia -e 'using Pkg; Pkg.instantiate()' \
+ && cd MaggotUBA \
+ && poetry install --only main \
+ && cd ../PasteurJanelia \
+ && poetry install --only main
+
+# final stage
+
+COPY --chown=julia larvatagger-entrypoint.sh /app/
+
+ENTRYPOINT ["/app/larvatagger-entrypoint.sh"]
+CMD []
diff --git a/back/larvatagger-build.sh b/back/larvatagger-build.sh
new file mode 100755
index 0000000..dcbdefd
--- /dev/null
+++ b/back/larvatagger-build.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+CONTAINERFILE=back/Containerfile.larvatagger
+
+if ! [ -f "$CONTAINERFILE" -a -f routes.jl ]; then
+ echo "Run $0 from the project root directory"
+ exit 1
+fi
+
+IMAGE=larvatagger-backend
+
+podman rmi -f $IMAGE || true
+
+podman build --tag $IMAGE -f "$CONTAINERFILE" back
+
+if [ "$1" = "--now" ]; then
+ podman run -d -p 9286:9286 $IMAGE
+
+ CONTAINER=`podman ps | grep $IMAGE | cut -d' ' -f1`
+
+ if [ -n "$CONTAINER" ]; then
+ echo "podman logs -f $CONTAINER"
+ sleep 1
+ podman logs -f $CONTAINER
+ fi
+fi
+
+export LARVATAGGER_BACKEND=http://localhost:9286
diff --git a/back/larvatagger-entrypoint.sh b/back/larvatagger-entrypoint.sh
new file mode 100755
index 0000000..aa31482
--- /dev/null
+++ b/back/larvatagger-entrypoint.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+if [ -z "$LARVATAGGER_PORT" ]; then
+ LARVATAGGER_PORT=9286
+else
+ echo "Using environment variable: LARVATAGGER_PORT= $LARVATAGGER_PORT"
+fi
+
+if [ -z "$LARVATAGGER_TOKEN_EXPIRY" ]; then
+ LARVATAGGER_TOKEN_EXPIRY=14400
+else
+ echo "Using environment variable: LARVATAGGER_TOKEN_EXPIRY= $LARVATAGGER_TOKEN_EXPIRY"
+fi
+
+julia -e "using LarvaTagger.REST.Server; run_backend(\"/app\", $LARVATAGGER_TOKEN_EXPIRY; host=\"0.0.0.0\", port=$LARVATAGGER_PORT)"
diff --git a/back/larvatagger-no-build.sh b/back/larvatagger-no-build.sh
new file mode 100755
index 0000000..7101dd7
--- /dev/null
+++ b/back/larvatagger-no-build.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+# for tests with lightweight deployment
+
+if [ -z "$LARVATAGGER_PORT" ]; then
+ LARVATAGGER_PORT=9286
+else
+ echo "Using environment variable: LARVATAGGER_PORT= $LARVATAGGER_PORT"
+fi
+if [ -z "$LARVATAGGER_IMAGE" ]; then
+ LARVATAGGER_IMAGE=docker.io/flaur/larvatagger:0.20-bigfat
+else
+ echo "Using environment variable: LARVATAGGER_IMAGE= $LARVATAGGER_IMAGE"
+fi
+if [ -z "$LARVATAGGER_TOKEN_EXPIRY" ]; then
+ LARVATAGGER_TOKEN_EXPIRY=3600
+else
+ echo "Using environment variable: LARVATAGGER_TOKEN_EXPIRY= $LARVATAGGER_TOKEN_EXPIRY"
+fi
+
+podman run -d -p $LARVATAGGER_PORT:9285 --entrypoint=julia $LARVATAGGER_IMAGE --project=/app \
+ -e "using LarvaTagger.REST.Server; run_backend(\"/app\", $LARVATAGGER_TOKEN_EXPIRY; host=\"0.0.0.0\")"
+
+CONTAINER=`podman ps | grep $LARVATAGGER_IMAGE | cut -d' ' -f1`
+if ! [ -z "$CONTAINER" ]; then
+ echo "To monitor the LarvaTagger backend:"
+ echo "podman logs -f $CONTAINER"
+fi
+
+export LARVATAGGER_BACKEND=http://localhost:$LARVATAGGER_PORT
diff --git a/front/Containerfile b/front/Containerfile
index ca3adb2..c788eb3 100644
--- a/front/Containerfile
+++ b/front/Containerfile
@@ -16,7 +16,7 @@ ENV JULIA_PROJECT /app
ENV JULIA_DEPOT_PATH /app/julia
ENV JULIAUP_DEPOT_PATH /app/juliaup
-ARG JULIA_VERSION=1.10.8
+ARG JULIA_VERSION=1.10.9
# UID/GID should match with same arguments defined in:
# https://github.com/nginxinc/docker-nginx-unprivileged/blob/main/mainline/debian/Dockerfile
diff --git a/front/Containerfile.local b/front/Containerfile.local
index 1449a18..d25b8dc 100644
--- a/front/Containerfile.local
+++ b/front/Containerfile.local
@@ -6,7 +6,7 @@ COPY ./NyxUI.jl/front/proxy.conf /etc/nginx/conf.d/default.conf
ENV JULIAUP_DEPOT_PATH /juliaup
ENV JULIA_DEPOT_PATH /julia
-ARG JULIA_VERSION=1.10.8
+ARG JULIA_VERSION=1.10.9
RUN curl -fsSL https://install.julialang.org \
| sh -s -- --yes --default-channel $JULIA_VERSION
diff --git a/front/Manifest.toml b/front/Manifest.toml
index 7b87bea..c55bc77 100644
--- a/front/Manifest.toml
+++ b/front/Manifest.toml
@@ -1,6 +1,6 @@
# This file is machine-generated - editing it directly is not advised
-julia_version = "1.10.8"
+julia_version = "1.10.9"
manifest_format = "2.0"
project_hash = "f30a6bd140cd9f9b66d3656725e83b8d83e18ee6"
@@ -833,12 +833,12 @@ uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
version = "1.4.0"
[[deps.LarvaTagger]]
-deps = ["Bonito", "Colors", "Dates", "DocOpt", "Format", "LinearAlgebra", "Logging", "Makie", "Meshes", "NearestNeighbors", "NyxWidgets", "Observables", "ObservationPolicies", "OrderedCollections", "PlanarLarvae", "Random", "StaticArrays", "Statistics", "TidyObservables", "WGLMakie"]
-git-tree-sha1 = "c9c185beb0bf417ed98afe9b8b9da557a0b886b7"
+deps = ["Bonito", "Colors", "Dates", "DocOpt", "Format", "HTTP", "JSON3", "LinearAlgebra", "Logging", "Makie", "Meshes", "NearestNeighbors", "NyxWidgets", "Observables", "ObservationPolicies", "OrderedCollections", "Oxygen", "PlanarLarvae", "Random", "StaticArrays", "Statistics", "TidyObservables", "WGLMakie"]
+git-tree-sha1 = "0b405b69b603ef4df736142907a32ab81df20215"
repo-rev = "main"
repo-url = "https://gitlab.pasteur.fr/nyx/larvatagger.jl"
uuid = "8b3b36f1-dfed-446e-8561-ea19fe966a4d"
-version = "0.19.1"
+version = "0.20.1"
[[deps.LazyArtifacts]]
deps = ["Artifacts", "Pkg"]
@@ -1182,7 +1182,7 @@ version = "3.2.4+0"
[[deps.OpenLibm_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "05823500-19ac-5b8b-9628-191a04bc5112"
-version = "0.8.1+2"
+version = "0.8.1+4"
[[deps.OpenMPI_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML", "Zlib_jll"]
@@ -1219,6 +1219,12 @@ git-tree-sha1 = "12f1439c4f986bb868acda6ea33ebc78e19b95ad"
uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
version = "1.7.0"
+[[deps.Oxygen]]
+deps = ["DataStructures", "Dates", "HTTP", "JSON3", "MIMEs", "Reexport", "RelocatableFolders", "Requires", "Sockets", "Statistics", "StructTypes"]
+git-tree-sha1 = "2ad010b0de6172faf1d09ed5e0837eb0b7355bd8"
+uuid = "df9a0d86-3283-4920-82dc-4555fc0d1d8b"
+version = "1.5.16"
+
[[deps.PCRE2_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15"
diff --git a/front/build-run-local.sh b/front/build-run-local.sh
index 79c9f43..3aeaf2c 100755
--- a/front/build-run-local.sh
+++ b/front/build-run-local.sh
@@ -18,7 +18,7 @@ podman build --tag $IMAGE -f "$CONTAINERFILE" .. # --no-cache
#mkdir -p public
podman run -d -p 8081:80 -p 9484:9284 -p 9485:9285 \
- $IMAGE
+ -e LARVATAGGER_BACKEND $IMAGE
CONTAINER=`podman ps | grep $IMAGE | cut -d' ' -f1`
diff --git a/front/build.sh b/front/build.sh
index 02619d9..1b9693e 100755
--- a/front/build.sh
+++ b/front/build.sh
@@ -14,7 +14,7 @@ podman rmi -f $IMAGE || true
podman build --tag $IMAGE -f "$CONTAINERFILE" .
if [ "$1" = "--now" ]; then
- podman run -d -p 8080:8080 $IMAGE
+ podman run -d -p 8080:8080 -e LARVATAGGER_BACKEND $IMAGE
CONTAINER=`podman ps | grep $IMAGE | cut -d' ' -f1`
diff --git a/front/entrypoint.sh b/front/entrypoint.sh
index ae9288c..0358243 100644
--- a/front/entrypoint.sh
+++ b/front/entrypoint.sh
@@ -2,6 +2,17 @@
set -m
+cd /app
+
+if [ -f "front/.env" ]; then
+ echo "Found dotenv file:"
+ echo "------------------"
+ cat front/.env
+ echo "------------------"
+ export `cat front/.env | xargs`
+fi
+LARVATAGGER_BACKEND=`echo $LARVATAGGER_BACKEND | sed "s/localhost/host.containers.internal/"`
+
/docker-entrypoint.sh nginx -g "daemon off;" &>/dev/null &
NGINX_PID=$!
diff --git a/nyxui/Chart.yaml b/nyxui/Chart.yaml
index 567ea86..0126bd7 100644
--- a/nyxui/Chart.yaml
+++ b/nyxui/Chart.yaml
@@ -15,10 +15,10 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
-version: 0.2.0
+version: 0.2.1
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
-appVersion: "0.2.0"
+appVersion: "0.2.1"
diff --git a/nyxui/templates/configmap-front.yaml b/nyxui/templates/configmap-front.yaml
new file mode 100644
index 0000000..5505c88
--- /dev/null
+++ b/nyxui/templates/configmap-front.yaml
@@ -0,0 +1,9 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ include "nyxui.name" . }}-front-config
+ labels:
+ {{- include "nyxui.labels" . | nindent 4 }}
+data:
+ .env: |
+ LARVATAGGER_BACKEND=http://{{ include "nyxui.name" . }}-larvatagger:{{ .Values.service.port }}
diff --git a/nyxui/templates/deployment-front.yaml b/nyxui/templates/deployment-front.yaml
index e4319b6..d54718c 100644
--- a/nyxui/templates/deployment-front.yaml
+++ b/nyxui/templates/deployment-front.yaml
@@ -1,7 +1,7 @@
apiVersion: apps/v1
kind: Deployment
metadata:
- name: {{ include "nyxui.name" . }}
+ name: {{ include "nyxui.name" . }}-front
labels:
{{- include "nyxui.labels" . | nindent 4 }}
spec:
@@ -19,6 +19,7 @@ spec:
{{- end }}
labels:
{{- include "nyxui.labels" . | nindent 8 }}
+ app.kubernetes.io/component: front
{{- with .Values.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
@@ -45,13 +46,19 @@ spec:
readinessProbe:
{{- toYaml .Values.readinessProbe | nindent 12 }}
resources:
- {{- toYaml .Values.resources | nindent 12 }}
- {{- with .Values.volumeMounts }}
+ {{- toYaml .Values.front.resources | nindent 12 }}
volumeMounts:
+ - name: front-config
+ mountPath: /app/front/.env
+ subPath: .env
+ {{- with .Values.volumeMounts }}
{{- toYaml . | nindent 12 }}
{{- end }}
- {{- with .Values.volumes }}
volumes:
+ - name: front-config
+ configMap:
+ name: nyxui-front-config
+ {{- with .Values.volumes }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.nodeSelector }}
diff --git a/nyxui/templates/deployment-larvatagger.yaml b/nyxui/templates/deployment-larvatagger.yaml
new file mode 100644
index 0000000..e47504b
--- /dev/null
+++ b/nyxui/templates/deployment-larvatagger.yaml
@@ -0,0 +1,69 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "nyxui.name" . }}-larvatagger
+ labels:
+ {{- include "nyxui.labels" . | nindent 4 }}
+spec:
+ {{- if not .Values.autoscaling.enabled }}
+ replicas: {{ .Values.replicaCount }}
+ {{- end }}
+ selector:
+ matchLabels:
+ {{- include "nyxui.selectorLabels" . | nindent 6 }}
+ template:
+ metadata:
+ {{- with .Values.podAnnotations }}
+ annotations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ labels:
+ {{- include "nyxui.labels" . | nindent 8 }}
+ app.kubernetes.io/component: larvatagger
+ {{- with .Values.podLabels }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ spec:
+ {{- with .Values.imagePullSecrets }}
+ imagePullSecrets:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ serviceAccountName: {{ include "nyxui.serviceAccountName" . }}
+ securityContext:
+ {{- toYaml .Values.podSecurityContext | nindent 8 }}
+ containers:
+ - name: {{ .Chart.Name }}
+ securityContext:
+ {{- toYaml .Values.securityContext | nindent 12 }}
+ image: "{{ .Values.larvatagger.image.repository }}/{{ .Values.larvatagger.image.name }}:{{ .Values.larvatagger.image.tag }}"
+ imagePullPolicy: {{ .Values.larvatagger.image.pullPolicy }}
+ ports:
+ - name: http
+ containerPort: {{ .Values.larvatagger.service.targetPort }}
+ protocol: TCP
+ livenessProbe:
+ {{- toYaml .Values.livenessProbe | nindent 12 }}
+ readinessProbe:
+ {{- toYaml .Values.readinessProbe | nindent 12 }}
+ resources:
+ {{- toYaml .Values.larvatagger.resources | nindent 12 }}
+ {{- with .Values.volumeMounts }}
+ volumeMounts:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ {{- with .Values.volumes }}
+ volumes:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
diff --git a/nyxui/templates/ingress.yaml b/nyxui/templates/ingress.yaml
index 79522d8..03b430c 100644
--- a/nyxui/templates/ingress.yaml
+++ b/nyxui/templates/ingress.yaml
@@ -49,11 +49,11 @@ spec:
backend:
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
service:
- name: {{ $fullName }}
+ name: {{ .serviceName }}
port:
number: {{ $svcPort }}
{{- else }}
- serviceName: {{ $fullName }}
+ serviceName: {{ .serviceName }}
servicePort: {{ $svcPort }}
{{- end }}
{{- end }}
diff --git a/nyxui/templates/service.yaml b/nyxui/templates/service-front.yaml
similarity index 79%
rename from nyxui/templates/service.yaml
rename to nyxui/templates/service-front.yaml
index 6086251..5bdec4b 100644
--- a/nyxui/templates/service.yaml
+++ b/nyxui/templates/service-front.yaml
@@ -1,7 +1,7 @@
apiVersion: v1
kind: Service
metadata:
- name: {{ include "nyxui.name" . }}
+ name: {{ include "nyxui.name" . }}-front
labels:
{{- include "nyxui.labels" . | nindent 4 }}
spec:
@@ -13,3 +13,4 @@ spec:
name: http
selector:
{{- include "nyxui.selectorLabels" . | nindent 4 }}
+ app.kubernetes.io/component: front
diff --git a/nyxui/templates/service-larvatagger.yaml b/nyxui/templates/service-larvatagger.yaml
new file mode 100644
index 0000000..32ac7f4
--- /dev/null
+++ b/nyxui/templates/service-larvatagger.yaml
@@ -0,0 +1,16 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "nyxui.name" . }}-larvatagger
+ labels:
+ {{- include "nyxui.labels" . | nindent 4 }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ selector:
+ {{- include "nyxui.selectorLabels" . | nindent 4 }}
+ app.kubernetes.io/component: larvatagger
diff --git a/nyxui/values.yaml b/nyxui/values.yaml
index c7bde4b..4eacdc4 100644
--- a/nyxui/values.yaml
+++ b/nyxui/values.yaml
@@ -12,6 +12,33 @@ front:
pullPolicy: Always
service:
targetPort: 8080
+ resources:
+ limits:
+ cpu: "2"
+ memory: 4Gi
+ ephemeral-storage: 1Gi
+ requests:
+ cpu: "2"
+ memory: 4Gi
+ ephemeral-storage: 1Gi
+
+larvatagger:
+ image:
+ repository: registry-gitlab.pasteur.fr/nyx/nyxui.jl
+ name: larvatagger
+ tag: latest
+ pullPolicy: Always
+ service:
+ targetPort: 9286
+ resources:
+ limits:
+ cpu: "2"
+ memory: 4Gi
+ ephemeral-storage: 4Gi
+ requests:
+ cpu: "2"
+ memory: 4Gi
+ ephemeral-storage: 4Gi
imagePullSecrets:
- name: registry-gitlab
@@ -60,21 +87,12 @@ ingress:
paths:
- path: /
pathType: Prefix
+ serviceName: nyxui-front
tls: []
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
-resources:
- limits:
- cpu: "2"
- memory: 4Gi
- ephemeral-storage: 1Gi
- requests:
- cpu: "2"
- memory: 4Gi
- ephemeral-storage: 1Gi
-
autoscaling:
enabled: false
minReplicas: 1
@@ -82,18 +100,11 @@ autoscaling:
targetCPUUtilizationPercentage: 80
# targetMemoryUtilizationPercentage: 80
-# Additional volumes on the output Deployment definition.
+# Additional shared volumes on the output Deployment definitions.
volumes: []
-# - name: foo
-# secret:
-# secretName: mysecret
-# optional: false
-# Additional volumeMounts on the output Deployment definition.
+# Additional shared volumeMounts on the output Deployment definitions.
volumeMounts: []
-# - name: foo
-# mountPath: "/etc/foo"
-# readOnly: true
nodeSelector: {}
diff --git a/src/GenieExtras.jl b/src/GenieExtras.jl
index 40cf48a..ebe416c 100644
--- a/src/GenieExtras.jl
+++ b/src/GenieExtras.jl
@@ -1,8 +1,11 @@
module GenieExtras
import Genie.Renderer.Html
+import GenieSession: GenieSession, Session
+using NyxWidgets.Base: Cache
-export publish_css, appinfo, add_footer
+export publish_css, appinfo, add_footer, Session, SessionRegistry, getsessionid, getsession,
+ clearexpired
const project_root = dirname(Base.current_project())
@@ -49,4 +52,129 @@ add_footer(ui::AbstractString, footer=footer) = "$ui$(footer())"
add_footer(ui::Function, footer=footer) = () -> add_footer(ui(), footer)
+struct SessionRegistry
+ register
+ idlength
+ purgesession
+ purgesession_args
+end
+
+function SessionRegistry(f, args=(:session_id,); idlength=32)
+ SessionRegistry(Cache{String, Dict{Symbol, Any}}(), idlength, f, args)
+end
+
+Base.lock(f::Function, registry::SessionRegistry) = lock(f, registry.register)
+
+function check_session_id_length(registry, session_id)
+ if !isnothing(registry.idlength) && length(session_id) < registry.idlength
+ throw("wrong session_id length")
+ end
+end
+
+function Base.haskey(registry::SessionRegistry, session_id::AbstractString)
+ lock(registry) do
+ for session_long_id in keys(registry.register.cache)
+ if startswith(session_long_id, session_id)
+ return true
+ end
+ end
+ return false
+ end
+end
+
+function Base.getindex(registry::SessionRegistry, session_id::AbstractString)
+ check_session_id_length(registry, session_id)
+ lock(registry) do
+ for (session_long_id, records) in pairs(registry.register.cache)
+ if startswith(session_long_id, session_id)
+ records[:lastseen] = time()
+ return records
+ end
+ end
+ throw(KeyError(session_id))
+ end
+end
+
+Base.getindex(registry::SessionRegistry, session_id::AbstractString, record::Symbol
+ ) = registry[session_id][record]
+
+function getsessionid(session_long_id::String, idlength::Union{Nothing, <:Integer})
+ session_id = session_long_id
+ if !isnothing(idlength)
+ session_id = string(session_id[1:idlength])
+ end
+ return session_id
+end
+
+function getsessionid(registry::SessionRegistry)
+ session = GenieSession.session()
+ session_long_id = session.id
+ session_id = getsessionid(session_long_id, registry.idlength)
+ # create the entry in the register if missing
+ records = lock(registry) do
+ register = registry.register.cache
+ if session_id != session_long_id && session_id in keys(register)
+ # if the session has been registered with its short id (and `getsession`),
+ # update the short id with the long one
+ register[session_long_id] = pop!(register, session_id)
+ else
+ # registry.register is a NyxWidgets.Cache and `getindex` behaves like `get!`
+ registry.register[session_long_id]
+ end
+ end
+ # register minimum information
+ records[:session] = session
+ records[:lastseen] = time()
+ # run maintenance routine
+ clearexpired(registry)
+ return session_id
+end
+
+function getsession(registry::SessionRegistry, session_id::AbstractString)
+ if haskey(registry, session_id) # check for long id
+ registry[session_id]
+ else # call get! on short id (if session_id is short); not ideal
+ registry.register[session_id]
+ end
+end
+
+function clearexpired(registry, expiry::Real=604800)
+ lock(registry) do
+ register = registry.register.cache
+ for (session_long_id, records) in pairs(register)
+ if !haskey(records, :lastseen)
+ @warn "Missing key: lastseen"
+ continue
+ end
+ expiry <= time() - records[:lastseen] || continue
+ # prepare to clear the session; collect the arguments to purgesession
+ session_id = getsessionid(session_long_id, registry.idlength)
+ available_args = Dict(:session_id=>session_id,
+ :session_long_id=>session_long_id,
+ records...)
+ @info "Purging session" session_id
+ pop!(register, session_long_id)
+ if haskey(records, :session)
+ session = records[:session]
+ # see learn.genieframework.com/framework/genie.jl/recipes/session
+ empty!(session.data)
+ else
+ @warn "Missing key: session"
+ end
+ #
+ function get′(arg)
+ get(available_args, arg) do
+ @warn "Missing argument for purgesession" arg
+ nothing
+ end
+ end
+ try
+ registry.purgesession(get′.(registry.purgesession_args)...)
+ catch
+ @error "\`purgesession\` callback failed"
+ end
+ end
+ end
+end
+
end
diff --git a/src/apps/catalog/app.jl b/src/apps/catalog/app.jl
index cc5c45f..4ae5596 100644
--- a/src/apps/catalog/app.jl
+++ b/src/apps/catalog/app.jl
@@ -36,9 +36,7 @@ function app_catalog_view()
]))),
item(item(class=app, Html.a(href=Router.link_to(:get_larvatagger), [
Html.h1("LarvaTagger", style=header2),
- imageview(src="/images/LarvaTagger.png", style=img,
- Html.div(class=caption, "Partially available"),
- ),
+ imageview(src="/images/LarvaTagger.png", style=img),
]))),
]),
])
diff --git a/src/apps/larvatagger/app.jl b/src/apps/larvatagger/app.jl
index dbdea62..7b30816 100644
--- a/src/apps/larvatagger/app.jl
+++ b/src/apps/larvatagger/app.jl
@@ -3,7 +3,7 @@ module LarvaTagger
using NyxUI, NyxUI.Storage, NyxUI.GenieExtras
using NyxWidgets.Base: Cache
import LarvaTagger as LT
-using GenieSession, Stipple
+using Stipple
import Stipple: @app, @init, @private, @in, @onchange, @onbutton, @click
import StippleUI: tooltip
@@ -16,21 +16,33 @@ mutable struct Model
sizefactor
app # TODO: check whether explicitly closing apps helps
appdata
+ kwargs
end
-const bonito_models = Cache{String, Model}()
+function purgesession(model, session_id)
+ if isnothing(model)
+ @warn "Session data prematurely lost"
+ elseif !isnothing(model.app)
+ close(model.app)
+ end
+ purge_appdata(session_id, "larvatagger")
+ BonitoServer.addsession(bonito_app, session_id; restart=true)
+end
+
+const session_registry = SessionRegistry(purgesession, (:model, :session_id))
const bonito_app = NamedApp("larvatagger",
function (session)
bucket = getbucket(session, "larvatagger", :read)
mkpath(bucket)
- model = lock(bonito_models) do
- if haskey(bonito_models, session)
- bonito_models.cache[session]
- else
- inputfile = Ref{Union{Nothing, String}}(nothing)
- bonito_models.cache[session] = Model(1.0, nothing, inputfile)
+ model = get!(getsession(session_registry, session), :model) do
+ kwargs = Dict{Symbol, Any}()
+ if !isempty(get(ENV, "LARVATAGGER_BACKEND", ""))
+ kwargs[:backend_directory] = backend = ENV["LARVATAGGER_BACKEND"]
+ @info "Using environment variable" LARVATAGGER_BACKEND=backend
end
+ inputfile = Ref{Union{Nothing, String}}(nothing)
+ Model(1.0, nothing, inputfile, kwargs)
end
exportdir = joinpath("public", session, "larvatagger")
function prepare_download(srcfile)
@@ -54,18 +66,15 @@ const bonito_app = NamedApp("larvatagger",
prepare_download=prepare_download,
enable_new_directories=true,
enable_delete=true,
- viewfactor=model.sizefactor)
+ viewfactor=model.sizefactor,
+ model.kwargs...)
return app
end
)
-function purgesession(session)
- model = lock(bonito_models) do
- pop!(bonito_models.cache, session)
- end
- isnothing(model.app) || close(model.app)
- purge_appdata(session, "larvatagger")
- BonitoServer.addsession(bonito_app, session; restart=true)
+function purgesession(session_id)
+ model = pop!(session_registry[session_id], :model, nothing)
+ purgesession(model, session_id)
end
@@ -75,10 +84,10 @@ end
@in reset_bonito_session = false
@onchange isready begin
- genie_session = GenieSession.session()
- bonito_session_id = genie_session.id[1:32]
- if haskey(bonito_models, bonito_session_id)
- sizefactor = sizefactors_str[bonito_models[bonito_session_id].sizefactor]
+ bonito_session_id = getsessionid(session_registry)
+ if haskey(session_registry[bonito_session_id], :model)
+ model = session_registry[bonito_session_id, :model]
+ sizefactor = sizefactors_str[model.sizefactor]
else
BonitoServer.addsession(bonito_app, bonito_session_id)
end
@@ -96,9 +105,10 @@ end
@onchange sizefactor begin
new_sizefactor = sizefactors[sizefactor]
- if new_sizefactor != bonito_models[bonito_session_id].sizefactor
+ model = session_registry[bonito_session_id, :model]
+ if new_sizefactor != model.sizefactor
@info "New size factor; refreshing the iframe"
- bonito_models[bonito_session_id].sizefactor = new_sizefactor
+ model.sizefactor = new_sizefactor
BonitoServer.addsession(bonito_app, bonito_session_id; restart=true) # restart
width = appwidth[sizefactor]
height = appheight[sizefactor]
@@ -112,7 +122,11 @@ end
end
@onbutton reset_bonito_session begin
- purgesession(bonito_session_id)
+ try
+ purgesession(bonito_session_id)
+ catch
+ @error "Error while resetting session"
+ end
# reset UI to defaults
bonito_session_id[!] = ""
sizefactor[!] = "1.0"
diff --git a/src/apps/muscles/Backbone.jl b/src/apps/muscles/Backbone.jl
index 5547f55..320d214 100644
--- a/src/apps/muscles/Backbone.jl
+++ b/src/apps/muscles/Backbone.jl
@@ -3,6 +3,7 @@ module Backbone
using NyxWidgets.Base: Cache
using NyxUI.MuscleActivities
using NyxUI.Storage
+using NyxUI.GenieExtras
using Bonito
include("MuscleWidgets.jl")
@@ -11,58 +12,37 @@ using .MuscleWidgets
export hasmodel, getmodel, setmodel, newsequence, getsequence, withsequences,
exportsequence, loadsequence, deletesequence, purgesession
-# mutable struct Backbone{W}
-# widget::Union{Nothing, W}
-# channel::Observable{Bonito.JSCode}
-# end
-#
-# Backbone{W}() where {W} = Backbone{W}(nothing)
-#
-# Backbone{W}(widget::W) where {W} = Backbone{W}(widget, Observable(js""))
-#
-# Backbone(widget::W) where {W} = Backbone{W}(widget)
-#
-# function Bonito.jsrender(session::Session, widget::Backbone)
-# isnothing(widget.widget) && error("backbone widget not initialized")
-# on(session, widget.channel) do jscode
-# evaljs(session, jscode)
-# end
-# Bonito.jsrender(session, widget.widget)
-# end
-
## models
-const __backbone_cache__ = Cache{String, MuscleWidget}()
-const __valid_sessions__ = Dict{String, Bool}()
+function purgesession end
+
+const session_registry = SessionRegistry(purgesession, (:session_id, ))
function app(persistent=""; title="Nyx muscle activity")
App(; title=title) do session
- # # embedded apps are always renderded twice; save time # EDIT: except on Ctrl+R
- # valid = get(__valid_sessions__, persistent, false)
- # __valid_sessions__[persistent] = !valid
- # valid || return
@info "New session" session.id
cache_id = isempty(persistent) ? session.id : persistent
- model = __backbone_cache__[cache_id]
+ model = session_registry[cache_id, :model]
Bonito.jsrender(session, model)
end
end
## muscle model
-getmodel(session_id) = __backbone_cache__[session_id]#.widget
+getmodel(session_id) = session_registry[session_id, :model]
-# for debugging
-getmodel() = first(values(__backbone_cache__))#.widget
-
-hasmodel(session_id) = haskey(__backbone_cache__, session_id)
+hasmodel(session_id) = haskey(session_registry[session_id], :model)
function setmodel(session_id, sequence)
- __backbone_cache__[session_id] = MuscleWidget(sequence)
+ records = getsession(session_registry, session_id)
+ records[:model] = model = MuscleWidget(sequence)
+ # init :sequences
+ get!(records, :sequences) do
+ Cache{Int, MuscleActivity}()
+ end
+ return model
end
-# getchannel(session_id) = __backbone_cache__[session_id].channel
-
## sequence model
function newsequencename(stem, existing)
@@ -97,14 +77,13 @@ function newsequence(session_id, sequence_name, sequence_names, start_time, time
return sequence
end
-const __sequences__ = Cache{String, Cache{Int, MuscleActivity}}()
-
function getsequence(session_id, sequence_name)
model = getmodel(session_id)
sequence = nothing
if model.sequence[].program_name != sequence_name
- lock(__sequences__[session_id]) do
- for outer sequence in values(__sequences__[session_id])
+ sequences = session_registry[session_id, :sequences]
+ lock(sequences) do
+ for outer sequence in values(sequences)
sequence.program_name == sequence_name && break
end
end
@@ -116,16 +95,16 @@ end
getsequence(session_id) = getmodel(session_id).sequence[]
function addsequence(session_id, sequence)
- lock(__sequences__[session_id]) do
- sequences = __sequences__[session_id]
+ sequences = session_registry[session_id, :sequences]
+ lock(sequences) do
i = isempty(sequences) ? 0 : maximum(keys(sequences))
sequences[i+1] = sequence
end
end
function withsequences(f, session_id)
- lock(__sequences__[session_id]) do
- sequences = __sequences__[session_id]
+ sequences = session_registry[session_id, :sequences]
+ lock(sequences) do
return f(sequences)
end
end
@@ -153,7 +132,7 @@ end
function deletesequence(session_id)
model = getmodel(session_id)
current = model.sequence[].program_name
- sequences = __sequences__[session_id]
+ sequences = session_registry[session_id, :sequences]
lock(sequences) do
for (ix, seq) in pairs(sequences)
if seq.program_name == current
@@ -167,19 +146,7 @@ function deletesequence(session_id)
end
function purgesession(session_id; appname="muscles")
- model = lock(__backbone_cache__) do
- if session_id in keys(__backbone_cache__.cache)
- #pop!(__valid_sessions__, session_id) # not sure what to do with it
- pop!(__backbone_cache__.cache, session_id)
- end
- end
- lock(__sequences__) do
- if session_id in keys(__sequences__.cache)
- pop!(__sequences__.cache, session_id)
- end
- end
- purge_appdata(session_id, appname)
- return model
+ purge_appdata(session_id, appname)
end
end
diff --git a/src/apps/muscles/app.jl b/src/apps/muscles/app.jl
index 6140bd2..044e4cc 100644
--- a/src/apps/muscles/app.jl
+++ b/src/apps/muscles/app.jl
@@ -2,7 +2,7 @@ module MuscleApp
using NyxUI, NyxUI.Storage, NyxUI.GenieExtras
using Observables
-using Genie, GenieSession, Stipple, StippleUI
+using Genie, Stipple, StippleUI
import Stipple: @app, @init, @private, @in, @out, @onchange, @onbutton, @notify
include("Backbone.jl")
@@ -20,6 +20,8 @@ const maxlength = getconfig("muscle-activity", "maxlength")
const bonito_app = NamedApp(:inherit, Backbone.app)
+Backbone.purgesession(session_id) = purgesession(session_id; appname=bonito_app.name)
+
@app begin
@private bonito_session_id = ""
@@ -95,7 +97,7 @@ const bonito_app = NamedApp(:inherit, Backbone.app)
end
@onbutton reset_bonito_session begin
- model = purgesession(bonito_session_id; appname=bonito_app.name)
+ purgesession(bonito_session_id)
# reset UI to defaults
#bonito_session_id[!] = ""
sequence[!] = MuscleActivity("")
@@ -445,8 +447,7 @@ function init_model(muscle_model=nothing)
muscle_model = @init
#@show muscle_model
end
- genie_session = GenieSession.session()
- session_id = genie_session.id[1:32]
+ session_id = getsessionid(Backbone.session_registry)
if hasmodel(session_id)
withsequences(session_id) do sequences
ids = sort!(collect(keys(sequences)))
diff --git a/values-yaml.gotmpl b/values-yaml.gotmpl
index d2b4df2..712200b 100644
--- a/values-yaml.gotmpl
+++ b/values-yaml.gotmpl
@@ -7,11 +7,38 @@ replicaCount: 1
front:
image:
repository: {{ requiredEnv "CI_REGISTRY_IMAGE" }}
- name: {{ requiredEnv "IMAGE_NAME" }}
+ name: {{ env "IMAGE_NAME" | default "front" }}
tag: {{ requiredEnv "CI_COMMIT_SHORT_SHA" }}
- pullPolicy: {{ requiredEnv "IMAGE_POLICY" }}
+ pullPolicy: {{ env "IMAGE_POLICY" | default "Always" }}
service:
- targetPort: {{ requiredEnv "SERVICE_TARGET_PORT" }}
+ targetPort: {{ env "SERVICE_TARGET_PORT" | default "8080" }}
+ resources:
+ limits:
+ cpu: {{ env "LIMITS_CPU" | default "2" }}
+ memory: {{ env "LIMITS_MEMORY" | default "4Gi" }}
+ ephemeral-storage: {{ env "LIMITS_STORAGE" | default "1Gi" }}
+ requests:
+ cpu: {{ env "LIMITS_CPU" | default "2" }}
+ memory: {{ env "LIMITS_MEMORY" | default "4Gi" }}
+ ephemeral-storage: {{ env "LIMITS_STORAGE" | default "1Gi" }}
+
+larvatagger:
+ image:
+ repository: {{ requiredEnv "CI_REGISTRY_IMAGE" }}
+ name: {{ env "LT_IMAGE_NAME" | default "larvatagger" }}
+ tag: {{ env "LT_IMAGE_TAG" | default "latest" }}
+ pullPolicy: {{ env "LT_IMAGE_POLICY" | default "Always" }}
+ service:
+ targetPort: {{ env "LARVATAGGER_PORT" | default "9286" }}
+ resources:
+ limits:
+ cpu: {{ env "LT_LIMITS_CPU" | default "2" }}
+ memory: {{ env "LT_LIMITS_MEMORY" | default "4Gi" }}
+ ephemeral-storage: {{ env "LT_LIMITS_STORAGE" | default "4Gi" }}
+ requests:
+ cpu: {{ env "LT_LIMITS_CPU" | default "2" }}
+ memory: {{ env "LT_LIMITS_MEMORY" | default "4Gi" }}
+ ephemeral-storage: {{ env "LT_LIMITS_STORAGE" | default "4Gi" }}
imagePullSecrets:
- name: {{ requiredEnv "IMAGE_SECRETS" }}
@@ -45,14 +72,14 @@ securityContext: {}
service:
type: ClusterIP
- port: {{ requiredEnv "SERVICE_PORT" }}
+ port: {{ env "SERVICE_PORT" | default "80" }}
ingress:
enabled: true
name: nyxui
- className: {{ requiredEnv "INGRESS_CLASS" }}
+ className: {{ env "INGRESS_CLASS" | default "internal" }}
annotations:
- meta.helm.sh/release-name: {{ requiredEnv "INGRESS_CLASS" }}
+ meta.helm.sh/release-name: nyxui
meta.helm.sh/release-namespace: {{ requiredEnv "KUBE_NAMESPACE" }}
nginx.ingress.kubernetes.io/proxy-body-size: "0"
hosts:
@@ -60,21 +87,12 @@ ingress:
paths:
- path: /
pathType: Prefix
+ serviceName: nyxui-front
tls: []
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
-resources:
- limits:
- cpu: {{ requiredEnv "LIMITS_CPU" }}
- memory: {{ requiredEnv "LIMITS_MEMORY" }}
- ephemeral-storage: {{ requiredEnv "LIMITS_STORAGE" }}
- requests:
- cpu: {{ requiredEnv "LIMITS_CPU" }}
- memory: {{ requiredEnv "LIMITS_MEMORY" }}
- ephemeral-storage: {{ requiredEnv "LIMITS_STORAGE" }}
-
autoscaling:
enabled: false
minReplicas: 1
@@ -82,18 +100,11 @@ autoscaling:
targetCPUUtilizationPercentage: 80
# targetMemoryUtilizationPercentage: 80
-# Additional volumes on the output Deployment definition.
+# Additional shared volumes on the output Deployment definitions.
volumes: []
-# - name: foo
-# secret:
-# secretName: mysecret
-# optional: false
-# Additional volumeMounts on the output Deployment definition.
+# Additional shared volumeMounts on the output Deployment definitions.
volumeMounts: []
-# - name: foo
-# mountPath: "/etc/foo"
-# readOnly: true
nodeSelector: {}
--
GitLab