Fixes in Tensorboard web app (kubeflow/kubeflow#5693)

* twa(front): Use correct base-href when building

Signed-off-by: Kimonas Sotirchos <kimwnasptd@arrikto.com>

* web-apps(backend): Fix regex for parsing prefix

Signed-off-by: Kimonas Sotirchos <kimwnasptd@arrikto.com>

* twa: Add git tag while building the image

Signed-off-by: Kimonas Sotirchos <kimwnasptd@arrikto.com>

* twa: Fix dockerfile for buster-slim image

Signed-off-by: Kimonas Sotirchos <kimwnasptd@arrikto.com>

* twa: Use common date-time component to show date

Signed-off-by: Kimonas Sotirchos <kimwnasptd@arrikto.com>

* twa(back): Fetch the name directly from the CR

Signed-off-by: Kimonas Sotirchos <kimwnasptd@arrikto.com>

* review: Remove unused npm script

Signed-off-by: Kimonas Sotirchos <kimwnasptd@arrikto.com>

* twa: Don't override the app's config

Signed-off-by: Kimonas Sotirchos <kimwnasptd@arrikto.com>

* twa: Use correct AWS image in Makefile

Signed-off-by: Kimonas Sotirchos <kimwnasptd@arrikto.com>

* review: Use bash in Dockerfile entrypoint

Signed-off-by: Kimonas Sotirchos <kimwnasptd@arrikto.com>
This commit is contained in:
Kimonas Sotirchos 2021-03-18 21:26:16 +02:00 committed by GitHub
parent a63eff43ed
commit ebbd123359
8 changed files with 18 additions and 32 deletions

View File

@ -24,7 +24,7 @@ def get_prefixed_index_html():
with open(os.path.join(static_dir, "index.html"), "r") as f: with open(os.path.join(static_dir, "index.html"), "r") as f:
index_html = f.read() index_html = f.read()
index_prefixed = re.sub( index_prefixed = re.sub(
r"\<base href=\".*\"\>", '<base href="%s">' % prefix, index_html, r"\<base href=\".*\".*\>", '<base href="%s">' % prefix, index_html,
) )
return index_prefixed return index_prefixed

View File

@ -48,4 +48,4 @@ COPY ./tensorboards/backend/Makefile .
COPY --from=frontend /src/dist/ /src/app/static/ COPY --from=frontend /src/dist/ /src/app/static/
ENTRYPOINT make run ENTRYPOINT ["/bin/bash","-c","gunicorn -w 3 --bind 0.0.0.0:5000 --access-logfile - entrypoint:app"]

View File

@ -1,5 +1,5 @@
IMG ?= konstantinosand/twa IMG ?= public.ecr.aws/j1r0q0g6/notebooks/tensorboards-web-app
TAG ?= v1 TAG ?= $(shell git log -n 1 --pretty=format:"%h" ./)
DOCKERFILE=tensorboards/Dockerfile DOCKERFILE=tensorboards/Dockerfile
docker-build: docker-build:

View File

@ -19,10 +19,11 @@ def get_tensorboards(namespace):
return api.success_response("tensorboards", content) return api.success_response("tensorboards", content)
@bp.route("/api/namespaces/<namespace>/pvcs") @bp.route("/api/namespaces/<namespace>/pvcs")
def get_pvcs(namespace): def get_pvcs(namespace):
# Return the list of PVCs and the corresponding Viewer's state # Return the list of PVCs and the corresponding Viewer's state
pvcs = api.list_pvcs(namespace) pvcs = api.list_pvcs(namespace)
content = [utils.getPVCName(pvc) for pvc in pvcs.items] content = [pvc.metadata.name for pvc in pvcs.items]
return api.success_response("pvcs", content) return api.success_response("pvcs", content)

View File

@ -1,12 +1,11 @@
from kubeflow.kubeflow.crud_backend import helpers, status from kubeflow.kubeflow.crud_backend import status
def parse_tensorboard(tensorboard): def parse_tensorboard(tensorboard):
""" """
Process the Tensorboard object and format it as the UI expects it. Process the Tensorboard object and format it as the UI expects it.
""" """
if tensorboard.get("status", {}).get("readyReplicas", 0) == 1:
if tensorboard.get("status", {}).get("readyReplicas", 0) == 1:
phase = status.STATUS_PHASE.READY phase = status.STATUS_PHASE.READY
message = "The Tensorboard server is ready to connect" message = "The Tensorboard server is ready to connect"
else: else:
@ -17,19 +16,12 @@ def parse_tensorboard(tensorboard):
"name": tensorboard["metadata"]["name"], "name": tensorboard["metadata"]["name"],
"namespace": tensorboard["metadata"]["namespace"], "namespace": tensorboard["metadata"]["namespace"],
"logspath": tensorboard["spec"]["logspath"], "logspath": tensorboard["spec"]["logspath"],
"age": helpers.get_age(tensorboard), "age": tensorboard["metadata"]["creationTimestamp"],
"status": status.create_status(phase, message, "") "status": status.create_status(phase, message, "")
} }
return parsed_tensorboard return parsed_tensorboard
def getPVCName(pvc):
"""
Return name of given PVC.
"""
return pvc.metadata.name
def get_tensorboard_dict(namespace, body): def get_tensorboard_dict(namespace, body):
""" """

View File

@ -13,12 +13,6 @@ BACKEND_MODE = os.environ.get("BACKEND_MODE",
cfg = config.get_config(BACKEND_MODE) cfg = config.get_config(BACKEND_MODE)
cfg.PREFIX = PREFIX cfg.PREFIX = PREFIX
# Load the Dev config based on BACKEND_MODE env var
if BACKEND_MODE == "dev":
cfg = config.DevConfig
else:
cfg = config.Config
app = app.create_app(APP_NAME, cfg) app = app.create_app(APP_NAME, cfg)
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -3,8 +3,7 @@
"version": "0.0.0", "version": "0.0.0",
"scripts": { "scripts": {
"ng": "ng", "ng": "ng",
"start": "npm run copyLibAssets && ng serve --base-href /tensorboard/ --deploy-url /tensorboard/", "build": "npm run copyLibAssets && ng build --prod --base-href /tensorboards/ --deploy-url static/",
"build": "npm run copyLibAssets && ng build --prod --base-href /tensorboard/ --deploy-url /tensorboard/static/",
"build:watch": "npm run copyLibAssets && ng build --watch --deploy-url static/ --outputPath ../backend/app/static/ --outputHashing all", "build:watch": "npm run copyLibAssets && ng build --watch --deploy-url static/ --outputPath ../backend/app/static/ --outputHashing all",
"copyLibAssets": "cp ./node_modules/kubeflow/assets/* ./src/assets/", "copyLibAssets": "cp ./node_modules/kubeflow/assets/* ./src/assets/",
"test": "ng test", "test": "ng test",

View File

@ -7,6 +7,7 @@ import {
TableColumn, TableColumn,
TRUNCATE_TEXT_SIZE, TRUNCATE_TEXT_SIZE,
TableConfig, TableConfig,
DateTimeValue,
} from 'kubeflow'; } from 'kubeflow';
const tableConfig: TableConfig = { const tableConfig: TableConfig = {
@ -27,6 +28,13 @@ const tableConfig: TableConfig = {
truncate: TRUNCATE_TEXT_SIZE.SMALL, truncate: TRUNCATE_TEXT_SIZE.SMALL,
}), }),
}, },
{
matHeaderCellDef: 'Age',
matColumnDef: 'age',
value: new DateTimeValue({
field: 'age',
}),
},
{ {
matHeaderCellDef: 'Logspath', matHeaderCellDef: 'Logspath',
matColumnDef: 'logspath', matColumnDef: 'logspath',
@ -36,14 +44,6 @@ const tableConfig: TableConfig = {
truncate: TRUNCATE_TEXT_SIZE.SMALL, truncate: TRUNCATE_TEXT_SIZE.SMALL,
}), }),
}, },
{
matHeaderCellDef: 'Age',
matColumnDef: 'age',
value: new PropertyValue({
field: 'age.uptime',
tooltipField: 'age.timestamp',
}),
},
], ],
}; };