nandi/atop-analyzepublic Fork 0
main
Commits
Clone
git clone https://git.rickub.com/nandi/atop-analyze.git
git clone ssh://git@rickub.com/nandi/atop-analyze.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

modal_grafana.py · 89 lines · 3.6 KBPython Blame HistoryRaw
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
"""Browser-facing Grafana for the private scale-to-zero ClickHouse endpoint.

Create a Modal Secret named ``atop-grafana`` before deploying. It needs:
``CLICKHOUSE_HOST`` (hostname only), ``MODAL_KEY``, ``MODAL_SECRET``, and
the Pocket ID Generic OAuth settings, including ``GF_SERVER_ROOT_URL``. A
separate ``atop-grafana-clickhouse-auth`` Secret must contain the nonempty
``CLICKHOUSE_GRAFANA_PASSWORD`` for the read-only ``grafana_reader`` user.
Deploy with ``modal deploy modal_grafana.py``.
"""

import subprocess
import time

import modal

APP_NAME = "atop-grafana"
DATA_VOLUME_NAME = "atop-grafana-data"
IDLE_SECONDS = 300
app = modal.App(APP_NAME)
data_volume = modal.Volume.from_name(DATA_VOLUME_NAME, create_if_missing=True)
grafana_secret = modal.Secret.from_name(
    "atop-grafana",
    required_keys=[
        "CLICKHOUSE_HOST", "MODAL_KEY", "MODAL_SECRET", "GF_SERVER_ROOT_URL",
        "GF_AUTH_GENERIC_OAUTH_CLIENT_ID", "GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET",
        "GF_AUTH_GENERIC_OAUTH_AUTH_URL", "GF_AUTH_GENERIC_OAUTH_TOKEN_URL",
        "GF_AUTH_GENERIC_OAUTH_API_URL", "GF_AUTH_GENERIC_OAUTH_JWK_SET_URL",
    ],
)
clickhouse_auth_secret = modal.Secret.from_name(
    "atop-grafana-clickhouse-auth",
    required_keys=["CLICKHOUSE_GRAFANA_PASSWORD"],
)
image = (
    modal.Image.debian_slim(python_version="3.12")
    .apt_install("adduser", "ca-certificates", "curl", "libfontconfig1", "musl")
    .run_commands(
        "curl --fail --location --silent --show-error "
        "https://dl.grafana.com/oss/release/grafana_11.6.0_amd64.deb "
        "--output /tmp/grafana.deb "
        "&& echo 'c5159ce58c1eb7b4a47474951f0334055dd1a4b3325ffc432ef1761da6474b2a  /tmp/grafana.deb' "
        "| sha256sum --check "
        "&& apt-get update "
        "&& apt-get install --yes --no-install-recommends /tmp/grafana.deb "
        "&& /usr/share/grafana/bin/grafana cli --homepath=/usr/share/grafana "
        "--pluginsDir=/opt/grafana/plugins "
        "plugins install grafana-clickhouse-datasource"
    )
    .add_local_dir("grafana/provisioning", "/etc/grafana/provisioning")
)


@app.function(
    image=image,
    secrets=[grafana_secret, clickhouse_auth_secret],
    volumes={"/var/lib/grafana": data_volume},
    min_containers=0,
    max_containers=1,
    scaledown_window=IDLE_SECONDS,
    timeout=15 * 60,
    env={
        "GF_SERVER_HTTP_ADDR": "0.0.0.0",
        "GF_PATHS_DATA": "/var/lib/grafana",
        "GF_PATHS_LOGS": "/var/log/grafana",
        "GF_PATHS_PLUGINS": "/opt/grafana/plugins",
        "GF_DATABASE_WAL": "false",
        "GF_PATHS_PROVISIONING": "/etc/grafana/provisioning",
        "GF_AUTH_DISABLE_LOGIN_FORM": "true",
        "GF_AUTH_GENERIC_OAUTH_ENABLED": "true",
        "GF_AUTH_GENERIC_OAUTH_NAME": "Pocket ID",
        "GF_AUTH_GENERIC_OAUTH_SCOPES": "openid profile email offline_access",
        "GF_AUTH_GENERIC_OAUTH_ALLOW_SIGN_UP": "true",
        "GF_AUTH_GENERIC_OAUTH_AUTO_LOGIN": "true",
        "GF_AUTH_GENERIC_OAUTH_USE_PKCE": "true",
        "GF_AUTH_GENERIC_OAUTH_USE_REFRESH_TOKEN": "true",
        "GF_AUTH_GENERIC_OAUTH_VALIDATE_ID_TOKEN": "true",
    },
)
@modal.concurrent(max_inputs=100)
@modal.web_server(3000, startup_timeout=120)
def grafana() -> None:
    """Run a public Grafana login page; its data-source credentials stay server-side."""
    grafana_process = subprocess.Popen([
        "/usr/share/grafana/bin/grafana", "server",
        "--homepath=/usr/share/grafana", "--config=/etc/grafana/grafana.ini",
    ])
    time.sleep(1)
    if grafana_process.poll() is not None:
        raise RuntimeError(f"Grafana exited during startup ({grafana_process.returncode})")