diff --git a/install/garmin-grafana-install.sh b/install/garmin-grafana-install.sh index c1688a2e8..b5d7ebeff 100644 --- a/install/garmin-grafana-install.sh +++ b/install/garmin-grafana-install.sh @@ -2,10 +2,9 @@ # Copyright (c) 2021-2026 community-scripts ORG # Author: aliaksei135 -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE # Source: https://github.com/arpanghosh8453/garmin-grafana -# Import Functions und Setup source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" color verb_ip6 @@ -14,104 +13,79 @@ setting_up_container network_check update_os -# Installing Dependencies msg_info "Installing Dependencies" $STD apt-get install -y \ - apt-transport-https \ - software-properties-common \ - lsb-base \ - lsb-release \ python3 \ python3-requests \ python3-dotenv -setup_uv msg_ok "Installed Dependencies" -msg_info "Setting up InfluxDB Repository" -curl -fsSL "https://repos.influxdata.com/influxdata-archive.key" | gpg --dearmor >/etc/apt/trusted.gpg.d/influxdata-archive.gpg -echo "deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive.gpg] https://repos.influxdata.com/debian stable main" >/etc/apt/sources.list.d/influxdata.list -msg_ok "Set up InfluxDB Repository" +setup_uv + +setup_deb822_repo "influxdb" \ + "https://repos.influxdata.com/influxdata-archive.key" \ + "https://repos.influxdata.com/debian" \ + "stable" \ + "main" -# garmin-grafana recommends influxdb v1 -# this install chronograf, which is the UI for influxdb. this might be overkill? msg_info "Installing InfluxDB" -$STD apt-get update $STD apt-get install -y influxdb -curl -fsSL "https://dl.influxdata.com/chronograf/releases/chronograf_1.10.9_amd64.deb" -o "$(basename "https://dl.influxdata.com/chronograf/releases/chronograf_1.10.9_amd64.deb")" -$STD dpkg -i chronograf_1.10.9_amd64.deb +curl -fsSL "https://dl.influxdata.com/chronograf/releases/chronograf_1.10.9_amd64.deb" -o /tmp/chronograf.deb +$STD dpkg -i /tmp/chronograf.deb +rm -f /tmp/chronograf.deb msg_ok "Installed InfluxDB" -msg_info "Setting up InfluxDB" -$STD sed -i 's/# index-version = "inmem"/index-version = "tsi1"/' /etc/influxdb/influxdb.conf - +msg_info "Configuring InfluxDB" +sed -i 's/# index-version = "inmem"/index-version = "tsi1"/' /etc/influxdb/influxdb.conf +$STD systemctl enable --now influxdb INFLUXDB_USER="garmin_grafana_user" INFLUXDB_PASSWORD=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13) INFLUXDB_NAME="GarminStats" $STD influx -execute "CREATE DATABASE ${INFLUXDB_NAME}" $STD influx -execute "CREATE USER ${INFLUXDB_USER} WITH PASSWORD '${INFLUXDB_PASSWORD}'" $STD influx -execute "GRANT ALL ON ${INFLUXDB_NAME} TO ${INFLUXDB_USER}" -# Start the service -$STD systemctl enable --now influxdb -msg_ok "Set up InfluxDB" +msg_ok "Configured InfluxDB" -msg_info "Setting up Grafana Repository" -curl -fsSL "https://apt.grafana.com/gpg.key" -o "/usr/share/keyrings/grafana.key" -sh -c 'echo "deb [signed-by=/usr/share/keyrings/grafana.key] https://apt.grafana.com stable main" > /etc/apt/sources.list.d/grafana.list' -msg_ok "Set up Grafana Repository" +setup_deb822_repo "grafana" \ + "https://apt.grafana.com/gpg.key" \ + "https://apt.grafana.com" \ + "stable" \ + "main" msg_info "Installing Grafana" -$STD apt-get update $STD apt-get install -y grafana -systemctl start grafana-server -systemctl daemon-reload -systemctl enable --now -q grafana-server.service -# This avoids the "database is locked" error when running the grafana-cli +$STD systemctl enable --now grafana-server sleep 20 msg_ok "Installed Grafana" -msg_info "Setting up Grafana" -GRAFANA_USER="admin" +msg_info "Configuring Grafana" GRAFANA_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13) $STD grafana-cli admin reset-admin-password "${GRAFANA_PASS}" $STD grafana-cli plugins install marcusolsson-hourly-heatmap-panel $STD systemctl restart grafana-server -# Output credentials to file { echo "Grafana Credentials" - echo "Grafana User: ${GRAFANA_USER}" + echo "Grafana User: admin" echo "Grafana Password: ${GRAFANA_PASS}" } >>~/garmin-grafana.creds -msg_ok "Set up Grafana" +msg_ok "Configured Grafana" -# Setup App -msg_info "Installing garmin-grafana" -RELEASE=$(curl -fsSL https://api.github.com/repos/arpanghosh8453/garmin-grafana/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') -curl -fsSL -o "${RELEASE}.zip" "https://github.com/arpanghosh8453/garmin-grafana/archive/refs/tags/${RELEASE}.zip" -unzip -q "${RELEASE}.zip" -# Remove the v prefix to RELEASE if it exists -if [[ "${RELEASE}" == v* ]]; then - RELEASE="${RELEASE:1}" -fi -mv "garmin-grafana-${RELEASE}/" "/opt/garmin-grafana" +fetch_and_deploy_gh_release "garmin-grafana" "arpanghosh8453/garmin-grafana" + +msg_info "Configuring garmin-grafana" mkdir -p /opt/garmin-grafana/.garminconnect $STD uv sync --locked --project /opt/garmin-grafana/ -# Setup grafana provisioning configs -# shellcheck disable=SC2016 + sed -i 's/\${DS_GARMIN_STATS}/garmin_influxdb/g' /opt/garmin-grafana/Grafana_Dashboard/Garmin-Grafana-Dashboard.json sed -i 's/influxdb:8086/localhost:8086/' /opt/garmin-grafana/Grafana_Datasource/influxdb.yaml sed -i "s/influxdb_user/${INFLUXDB_USER}/" /opt/garmin-grafana/Grafana_Datasource/influxdb.yaml sed -i "s/influxdb_secret_password/${INFLUXDB_PASSWORD}/" /opt/garmin-grafana/Grafana_Datasource/influxdb.yaml sed -i "s/GarminStats/${INFLUXDB_NAME}/" /opt/garmin-grafana/Grafana_Datasource/influxdb.yaml -# Copy across grafana data cp -r /opt/garmin-grafana/Grafana_Datasource/* /etc/grafana/provisioning/datasources cp -r /opt/garmin-grafana/Grafana_Dashboard/* /etc/grafana/provisioning/dashboards -echo "${RELEASE}" >"/opt/garmin-grafana_version.txt" -msg_ok "Installed garmin-grafana" -msg_info "Setting up garmin-grafana" -# Check if using Chinese garmin servers read -rp "Are you using Garmin in mainland China? (y/N): " prompt -if [[ "${prompt,,}" =~ ^(y|yes|Y)$ ]]; then +if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then GARMIN_CN="True" else GARMIN_CN="False" @@ -128,60 +102,41 @@ GARMIN_IS_CN=${GARMIN_CN} TOKEN_DIR=/opt/garmin-grafana/.garminconnect EOF -# garmin-grafana usually prompts the user for email and password (and MFA) on first run, -# then stores a refreshable token. We try to avoid storing user credentials in the env vars if [ -z "$(ls -A /opt/garmin-grafana/.garminconnect)" ]; then read -r -p "Please enter your Garmin Connect Email: " GARMIN_EMAIL - read -r -p "Please enter your Garmin Connect Password (this is used to generate a token and NOT stored): " GARMIN_PASSWORD - read -r -p "Please enter your MFA Code (if applicable, leave blank if not): " GARMIN_MFA - # Run the script once to prompt for credential - msg_info "Creating Garmin credentials, this will timeout in 60 seconds" + read -r -p "Please enter your Garmin Connect Password (used to generate token, NOT stored): " GARMIN_PASSWORD + read -r -p "Please enter your MFA Code (leave blank if not applicable): " GARMIN_MFA + msg_info "Creating Garmin credentials (timeout 60s)" timeout 60s uv run --env-file /opt/garmin-grafana/.env --project /opt/garmin-grafana/ /opt/garmin-grafana/src/garmin_grafana/garmin_fetch.py <~/bulk-import.sh +cat <<'EOF' >/usr/local/bin/garmin-bulk-import #!/usr/bin/env bash -if [[ -z \$1 ]]; then - echo "Usage: \$0 " - echo "Example: \$0 2023-01-01 2023-01-31" - echo "Date format: YYYY-MM-DD" - echo "This will import data from the start_date to the end_date (inclusive)" +if [[ -z $1 ]]; then + echo "Usage: $0 [end_date]" + echo "Example: $0 2023-01-01 2023-01-31" exit 1 fi - -START_DATE="\$1" -if [[ -z \$2 ]]; then - END_DATE="\$(date +%Y-%m-%d)" - echo "No end date provided, using today as end date: \${END_DATE}" -else - END_DATE="\$2" -fi - -# Stop the service if running +START_DATE="$1" +END_DATE="${2:-$(date +%Y-%m-%d)}" systemctl stop garmin-grafana - -MANUAL_START_DATE="\${START_DATE}" MANUAL_END_DATE="\${END_DATE}" uv run --env-file /opt/garmin-grafana/.env --project /opt/garmin-grafana/ /opt/garmin-grafana/src/garmin_grafana/garmin_fetch.py - -# Restart the service +MANUAL_START_DATE="${START_DATE}" MANUAL_END_DATE="${END_DATE}" uv run --env-file /opt/garmin-grafana/.env --project /opt/garmin-grafana/ /opt/garmin-grafana/src/garmin_grafana/garmin_fetch.py systemctl start garmin-grafana EOF -chmod +x ~/bulk-import.sh -msg_ok "Set up garmin-grafana" +chmod +x /usr/local/bin/garmin-bulk-import +msg_ok "Configured garmin-grafana" msg_info "Creating Service" cat </etc/systemd/system/garmin-grafana.service @@ -190,9 +145,12 @@ Description=garmin-grafana Service After=network.target [Service] -ExecStart=uv run --project /opt/garmin-grafana/ /opt/garmin-grafana/src/garmin_grafana/garmin_fetch.py -Restart=always +Type=simple +WorkingDirectory=/opt/garmin-grafana EnvironmentFile=/opt/garmin-grafana/.env +ExecStart=/root/.local/bin/uv run --project /opt/garmin-grafana/ /opt/garmin-grafana/src/garmin_grafana/garmin_fetch.py +Restart=on-failure +RestartSec=5 [Install] WantedBy=multi-user.target @@ -202,10 +160,4 @@ msg_ok "Created Service" motd_ssh customize - -# Cleanup -msg_info "Cleaning up" -rm -f "${RELEASE}".zip -$STD apt-get -y autoremove -$STD apt-get -y autoclean -msg_ok "Cleaned" +cleanup_lxc