Skip to content

Commit

Permalink
Updates
Browse files Browse the repository at this point in the history
  • Loading branch information
samlamont committed Oct 18, 2024
1 parent 28da9e5 commit 579c523
Show file tree
Hide file tree
Showing 11 changed files with 67 additions and 1,242 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/docker_publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ jobs:
with:
images: ${{ env.AWS_REGISTRY }}/${{ github.event.repository.name }}

# Build and push Docker image with Buildx (don't push on PR)
# Build and push Docker image
# https://github.com/docker/build-push-action
- name: Build and push Docker image
id: build-and-push-aws
Expand All @@ -132,9 +132,9 @@ jobs:
push: true
tags: ${{ steps.meta-aws.outputs.tags }}
labels: ${{ steps.meta-aws.outputs.labels }}
build-args: |
AWS_ACCESS_KEY_ID=${{ secrets.AWS_READ_ONLY_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_READ_ONLY_SECRET_ACCESS_KEY_ID }}
# build-args: |
# AWS_ACCESS_KEY_ID=${{ secrets.AWS_READ_ONLY_ACCESS_KEY_ID }}
# AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_READ_ONLY_SECRET_ACCESS_KEY_ID }}

# - name: Build and push
# uses: docker/build-push-action@v6
Expand Down
48 changes: 17 additions & 31 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
# https://github.com/2i2c-org/infrastructure/issues/1444#issuecomment-1187405324

FROM pangeo/pangeo-notebook:2024.10.01
# FROM 935462133478.dkr.ecr.us-east-2.amazonaws.com/teehr:v0.4-beta

USER root
ENV DEBIAN_FRONTEND=noninteractive
ENV PATH ${NB_PYTHON_PREFIX}/bin:$PATH

ARG AWS_ACCESS_KEY_ID
ARG AWS_SECRET_ACCESS_KEY
# # For local testing
# ARG AWS_ACCESS_KEY_ID
# ARG AWS_SECRET_ACCESS_KEY

# Needed for apt-key to work
RUN apt-get update -qq --yes > /dev/null && \
Expand Down Expand Up @@ -46,7 +48,7 @@ RUN wget -q "https://sourceforge.net/projects/turbovnc/files/${TURBOVNC_VERSION}
&& ln -s /opt/TurboVNC/bin/* /usr/local/bin/ \
&& rm -rf /var/lib/apt/lists/*

RUN mamba install -n ${CONDA_ENV} -y websockify voila
RUN mamba install -n ${CONDA_ENV} -y websockify ipywidgets-bokeh

# Install jupyter-remote-desktop-proxy with compatible npm version
RUN export PATH=${NB_PYTHON_PREFIX}/bin:${PATH} \
Expand All @@ -60,38 +62,22 @@ RUN pip install 'teehr @ git+https://github.com/RTIInternational/[email protected]
# Install git-lfs
RUN apt-get update && apt-get install git-lfs -y

# Install jupyter-server-proxy?

# # Download FEWS binaries from s3?
# RUN aws s3 cp s3://ciroh-rti-hefs-data/fews-NA-202102-115469-bin.zip /opt/fews/fews-NA-202102-115469-bin.zip
# RUN unzip /opt/fews/fews-NA-202102-115469-bin.zip -d /opt/fews/

# Copy in FEWS binaries from local directory
COPY fews/fews-NA-202102-115469-bin.zip /opt/fews/fews-NA-202102-115469-bin.zip
RUN unzip /opt/fews/fews-NA-202102-115469-bin.zip -d /opt/fews/ \
&& chown -R jovyan:jovyan /opt/fews

RUN mkdir /opt/data \
&& chown -R jovyan:jovyan /opt/data

# Copy in the python notebook and scripts

# IPywidgets
# COPY scripts/dashboard.ipynb scripts/dashboard_funcs.py scripts/start_dashboard.sh /opt/hefs_fews_dashboard/
# COPY images/index_getting_started.svg /opt/hefs_fews_dashboard/index_getting_started.svg
# COPY images/CIROHLogo_200x200.png /opt/hefs_fews_dashboard/CIROHLogo_200x200.png
# Panel
COPY playground/panel_dashboard.py playground/dashboard_funcs.py playground/start_dashboard.sh /opt/hefs_fews_dashboard/
COPY playground/geo/rfc_boundaries.geojson /opt/hefs_fews_dashboard/rfc_boundaries.geojson
COPY images/index_getting_started.svg /opt/hefs_fews_dashboard/index_getting_started.svg
# COPY images/index_getting_started.svg /opt/hefs_fews_dashboard/index_getting_started.svg
COPY images/dashboard_icon2.png /opt/hefs_fews_dashboard/dashboard_icon2.png
COPY images/CIROHLogo_200x200.png /opt/hefs_fews_dashboard/CIROHLogo_200x200.png
RUN chown -R jovyan:jovyan /opt/hefs_fews_dashboard && chmod +x /opt/hefs_fews_dashboard/start_dashboard.sh
COPY playground/panel_requirements.txt /opt/hefs_fews_dashboard/
RUN pip install -r /opt/hefs_fews_dashboard/panel_requirements.txt

# Create Desktop dir and copy in the dashboard desktop file
COPY scripts/dashboard.desktop /opt/hefs_fews_dashboard/dashboard.desktop
RUN chmod +x /opt/hefs_fews_dashboard/dashboard.desktop

RUN chown -R jovyan:jovyan /opt/hefs_fews_dashboard && chmod +x /opt/hefs_fews_dashboard/start_dashboard.sh \
&& chmod +x /opt/hefs_fews_dashboard/dashboard.desktop

# Install Firefox
RUN wget -P Downloads https://ftp.mozilla.org/pub/firefox/releases/131.0b9/linux-x86_64/en-US/firefox-131.0b9.tar.bz2 \
Expand All @@ -107,18 +93,18 @@ RUN wget -P Downloads https://ftp.mozilla.org/pub/firefox/releases/131.0b9/linux
# $$ echo 'Package: *Pin: origin packages.mozilla.orgPin-Priority: 1000' | tee /etc/apt/preferences.d/mozilla \
# && apt-get update && apt-get install firefox -y

# COPY playground/jupyter-panel-proxy.yml /opt/hefs_fews_dashboard/jupyter-panel-proxy.yml
# COPY playground/jupyter-panel-proxy.yml /etc/jupyter/jupyter-panel-proxy.yml
# RUN jupyter server extension enable panel.io.jupyter_server_extension

# ENV BOKEH_ALLOW_WS_ORIGIN "*"

# Run the web service on container startup.
# CMD panel serve /opt/hefs_fews_dashboard/panel_dashboard.py --allow-websocket-origin="*" --port 8888 --autoreload --address 0.0.0.0 --static-dirs
# For local testing
# RUN chown -R jovyan:jovyan .aws

USER ${NB_USER}

RUN aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID \
&& aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY \
&& aws configure set default.region us-east-2
# # For local testing
# RUN aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID \
# && aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY \
# && aws configure set default.region us-east-2

WORKDIR /home/jovyan
Binary file added images/dashboard_icon1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/dashboard_icon2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 17 additions & 1 deletion playground/dashboard_funcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from typing import Union, List
from concurrent import futures
import subprocess
import logging

import boto3

Expand All @@ -14,6 +15,20 @@
s3_client = boto3.client('s3')


def set_up_logger(file_path: Union[str, Path]) -> logging.Logger:
"""Set up a logger for the dashboard."""
logger = logging.getLogger("HEFS-Dashboard")
logger.setLevel(logging.INFO)
handler = logging.FileHandler(file_path)
handler.setLevel(logging.INFO)
formatter = logging.Formatter(
'%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s'
)
handler.setFormatter(formatter)
logger.addHandler(handler)
return logger


def extract_archive(
archive: Union[str, Path],
extract_path: Union[str, Path]
Expand Down Expand Up @@ -61,12 +76,13 @@ def write_shell_file(
def write_fews_desktop_shortcut(
output_filepath: Union[str, Path],
shell_script_filepath: Union[str, Path],
rfc_name: str
) -> None:
"""Write a desktop shortcut file to the remote desktop."""
os.umask(0)
with open(Path(output_filepath), "w", opener=_opener) as f:
f.write("[Desktop Entry]\n")
f.write(f"Name=FEWS.{Path(output_filepath).name}\n")
f.write(f"Name=FEWS.{rfc_name}\n")
f.write("Type=Application\n")
f.write(f"Exec={shell_script_filepath}\n")
f.write("Terminal=false\n")
Expand Down
5 changes: 5 additions & 0 deletions playground/jupyter-panel-proxy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# jupyter-panel-proxy.yml
apps:
- /opt/hefs_fews_dashboard/panel_dashboard.py
command: panel serve /opt/hefs_fews_dashboard/panel_dashboard.py --port 8888 --allow-websocket-origin="*"
absolute-url: True
212 changes: 0 additions & 212 deletions playground/panel_dashboard.ipynb

This file was deleted.

52 changes: 22 additions & 30 deletions playground/panel_dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,21 @@

import panel as pn
from ipyleaflet import Map, GeoJSON
# import param

from dashboard_funcs import (
create_start_standalone_command,
write_shell_file,
s3_download_file,
write_fews_desktop_shortcut,
s3_download_directory_cli
s3_download_directory_cli,
set_up_logger
)

pn.extension("ipywidgets", sizing_mode="stretch_width")

ACCENT_BASE_COLOR = "#5d6d7e"

RFC_BOUNDARIES = "/home/sam/git/hefs-fews-hub/playground/geo/rfc_boundaries.geojson"
# RFC_BOUNDARIES = "/opt/hefs_fews_dashboard/rfc_boundaries.geojson"
RFC_BOUNDARIES = "/opt/hefs_fews_dashboard/rfc_boundaries.geojson"
FEWS_INSTALL_DIR = Path("/opt", "fews")
MAP_CENTER_X = 38.80
MAP_CENTER_Y = -99.14
Expand Down Expand Up @@ -54,16 +53,6 @@ def turn_on_indeterminate():
return


# def download_configs_button_click(event):
# rfc_id = rfc_selector.value
# s3_download_directory_cli(
# f"{rfc_id}/Config",
# download_dir_text.value
# )
# indeterminate.name = "Download Complete"
# return


def on_geojson_click(event, feature, **kwargs):
rfc_selector.value = feature['properties']["BASIN_ID"]
return
Expand All @@ -87,88 +76,95 @@ def download_historical_data(event) -> None:
"does not exist. Please create it first!"
)

print(f"Downloading historical data to {fews_download_dir.as_posix()}...")
logger.info(f"Downloading historical data to {fews_download_dir.as_posix()}...")
s3_download_directory_cli(
prefix=f"{rfc_selector.value}/historicalData",
local=Path(
fews_download_dir,
f"{rfc_selector.value}/cardfiles"
).as_posix()
)
print("Data download complete.")
logger.info("Data download complete.")


def install_fews_standalone(event) -> None:
"""Download standalone configuration from S3 to the working directory."""
turn_on_indeterminate()
fews_download_dir = Path(download_dir_text.value)
if not fews_download_dir.exists():
print(f"The directory: {fews_download_dir}, does not exist. Please create it first!")
logger.info(f"The directory: {fews_download_dir}, does not exist. Please create it first!")
raise ValueError(f"The directory: {fews_download_dir}, does not exist. Please create it first!")

# 1. Download sa from S3
print(f"Downloading RFC configuration to {fews_download_dir.as_posix()}...This will take a few minutes...")
logger.info(f"Downloading {rfc_selector.value} configuration to {fews_download_dir.as_posix()}...This will take a few minutes...")
s3_download_directory_cli(
prefix=f"{rfc_selector.value}/Config",
local=Path(fews_download_dir, f"{rfc_selector.value}/Config").as_posix(),
)
# 2. Create the bash command to run the standalone configuration
logger.info("Creating bash command to start FEWS...")
sa_dir_path = Path(fews_download_dir, rfc_selector.value)
bash_command_str = create_start_standalone_command(
fews_root_dir=FEWS_INSTALL_DIR.as_posix(),
configuration_dir=sa_dir_path.as_posix()
)
# 3. Write the command to start FEWS to a shell script
logger.info("Writing shell script to start FEWS...")
shell_script_filepath = Path(sa_dir_path, "start_fews_standalone.sh")
write_shell_file(shell_script_filepath, bash_command_str)

# 4. Copy in patch file for the downloaded standalone config.
print("Downloading patch file and global properties...")
logger.info("Downloading patch file and global properties...")
s3_download_file(
remote_filepath="fews-install/fews-NA-202102-125264-patch.jar",
local_filepath=Path(sa_dir_path, "fews-NA-202102-125264-patch.jar")
)
logger.info("Downloading sa_global.properties...Temporarily to Config dir.")
s3_download_file(
remote_filepath=f"{rfc_selector.value}/sa_global.properties",
local_filepath=Path(sa_dir_path, "sa_global.properties")
local_filepath=Path(sa_dir_path, "Config", "sa_global.properties")
)
# 5. Create FEWS desktop shortcut that calls the shell script
desktop_shortcut_filepath = Path(
Path.home(),
"Desktop",
f"{sa_dir_path.name}.desktop"
)
print(f"Creating FEWS desktop shortcut...{desktop_shortcut_filepath}")
logger.info(f"Creating FEWS desktop shortcut...{desktop_shortcut_filepath}")
write_fews_desktop_shortcut(
desktop_shortcut_filepath,
shell_script_filepath
shell_script_filepath,
rfc_selector.value
)
turn_off_indeterminate()
print("Installation complete.")
logger.info("Installation complete.")
return


# MAP (ipyleaflet)
with open(RFC_BOUNDARIES) as f:
geojson_data = json.load(f)

geojson_layer = GeoJSON(
data=geojson_data,
hover_style={
'color': 'red', 'dashArray': '0', 'fillOpacity': 0.6
},
)


lmap = get_marker_and_map()

geojson_layer.on_click(on_geojson_click)

# WIDGETS
rfc_selector = pn.widgets.Select(name="", options=RFC_IDS, value=RFC_IDS[5])

download_dir_text = pn.widgets.TextInput(
name='Directory to download the data:',
value='/home/jovyan'
)

logger_filepath = Path(download_dir_text.value, "dashboard.log")
logger = set_up_logger(logger_filepath)

download_configs_button = pn.widgets.Button(
name='Download Configs',
button_type='primary'
Expand All @@ -181,8 +177,6 @@ def install_fews_standalone(event) -> None:
)
download_data_button.on_click(download_historical_data)

rfc_selector = pn.widgets.Select(name="", options=RFC_IDS, value=RFC_IDS[5])

indeterminate = pn.indicators.Progress(
name='Indeterminate Progress',
active=False,
Expand All @@ -191,7 +185,6 @@ def install_fews_standalone(event) -> None:
)

# LAYOUT

download_row = pn.Row(
rfc_selector,
download_configs_button,
Expand All @@ -205,7 +198,6 @@ def install_fews_standalone(event) -> None:
pn.Row(indeterminate)
)


template = pn.template.FastListTemplate(
site="HEFS-FEWS",
title="Exploration System Dashboard",
Expand Down
Loading

0 comments on commit 579c523

Please sign in to comment.