initial
This commit is contained in:
97
rootfs/opt/bitnami/scripts/grafana-env.sh
Normal file
97
rootfs/opt/bitnami/scripts/grafana-env.sh
Normal file
@@ -0,0 +1,97 @@
|
||||
#!/bin/bash
|
||||
# Copyright Broadcom, Inc. All Rights Reserved.
|
||||
# SPDX-License-Identifier: APACHE-2.0
|
||||
#
|
||||
# Environment configuration for grafana
|
||||
|
||||
# The values for all environment variables will be set in the below order of precedence
|
||||
# 1. Custom environment variables defined below after Bitnami defaults
|
||||
# 2. Constants defined in this file (environment variables with no default), i.e. BITNAMI_ROOT_DIR
|
||||
# 3. Environment variables overridden via external files using *_FILE variables (see below)
|
||||
# 4. Environment variables set externally (i.e. current Bash context/Dockerfile/userdata)
|
||||
|
||||
# Load logging library
|
||||
# shellcheck disable=SC1090,SC1091
|
||||
. /opt/bitnami/scripts/liblog.sh
|
||||
|
||||
export BITNAMI_ROOT_DIR="/opt/bitnami"
|
||||
export BITNAMI_VOLUME_DIR="/bitnami"
|
||||
|
||||
# Logging configuration
|
||||
export MODULE="${MODULE:-grafana}"
|
||||
export BITNAMI_DEBUG="${BITNAMI_DEBUG:-false}"
|
||||
|
||||
# By setting an environment variable matching *_FILE to a file path, the prefixed environment
|
||||
# variable will be overridden with the value specified in that file
|
||||
grafana_env_vars=(
|
||||
GRAFANA_TMP_DIR
|
||||
GRAFANA_PID_FILE
|
||||
GRAFANA_DEFAULT_CONF_DIR
|
||||
GRAFANA_DEFAULT_PLUGINS_DIR
|
||||
GF_PATHS_HOME
|
||||
GF_PATHS_CONFIG
|
||||
GF_PATHS_DATA
|
||||
GF_PATHS_LOGS
|
||||
GF_PATHS_PLUGINS
|
||||
GF_PATHS_PROVISIONING
|
||||
GF_INSTALL_PLUGINS
|
||||
GF_INSTALL_PLUGINS_SKIP_TLS
|
||||
GF_FEATURE_TOGGLES
|
||||
GF_SECURITY_ADMIN_PASSWORD
|
||||
GRAFANA_MIGRATION_LOCK
|
||||
GRAFANA_SLEEP_TIME
|
||||
GRAFANA_RETRY_ATTEMPTS
|
||||
GRAFANA_PLUGINS
|
||||
)
|
||||
for env_var in "${grafana_env_vars[@]}"; do
|
||||
file_env_var="${env_var}_FILE"
|
||||
if [[ -n "${!file_env_var:-}" ]]; then
|
||||
if [[ -r "${!file_env_var:-}" ]]; then
|
||||
export "${env_var}=$(< "${!file_env_var}")"
|
||||
unset "${file_env_var}"
|
||||
else
|
||||
warn "Skipping export of '${env_var}'. '${!file_env_var:-}' is not readable."
|
||||
fi
|
||||
fi
|
||||
done
|
||||
unset grafana_env_vars
|
||||
|
||||
# Grafana paths
|
||||
export GRAFANA_BASE_DIR="${BITNAMI_ROOT_DIR}/grafana"
|
||||
export GRAFANA_BIN_DIR="${GRAFANA_BASE_DIR}/bin"
|
||||
export GRAFANA_TMP_DIR="${GRAFANA_TMP_DIR:-${GRAFANA_BASE_DIR}/tmp}"
|
||||
export GRAFANA_CONF_DIR="${GRAFANA_BASE_DIR}/conf"
|
||||
export GRAFANA_PID_FILE="${GRAFANA_PID_FILE:-${GRAFANA_TMP_DIR}/grafana.pid}"
|
||||
export PATH="${GRAFANA_BIN_DIR}:${BITNAMI_ROOT_DIR}/common/bin:${PATH}"
|
||||
export GRAFANA_DEFAULT_CONF_DIR="${GRAFANA_DEFAULT_CONF_DIR:-${GRAFANA_BASE_DIR}/conf.default}"
|
||||
export GRAFANA_DEFAULT_PLUGINS_DIR="${GRAFANA_DEFAULT_PLUGINS_DIR:-${GRAFANA_BASE_DIR}/default-plugins}"
|
||||
|
||||
# System users (when running with a privileged user)
|
||||
export GRAFANA_DAEMON_USER="grafana"
|
||||
export GRAFANA_DAEMON_GROUP="grafana"
|
||||
|
||||
# Grafana configuration
|
||||
export GF_PATHS_HOME="${GF_PATHS_HOME:-$GRAFANA_BASE_DIR}"
|
||||
export GF_PATHS_CONFIG="${GF_PATHS_CONFIG:-${GRAFANA_BASE_DIR}/conf/grafana.ini}"
|
||||
export GF_PATHS_DATA="${GF_PATHS_DATA:-${GRAFANA_BASE_DIR}/data}"
|
||||
export GF_PATHS_LOGS="${GF_PATHS_LOGS:-${GRAFANA_BASE_DIR}/logs}"
|
||||
export GF_PATHS_PLUGINS="${GF_PATHS_PLUGINS:-${GF_PATHS_DATA}/plugins}"
|
||||
export GF_PATHS_PROVISIONING="${GF_PATHS_PROVISIONING:-${GRAFANA_BASE_DIR}/conf/provisioning}"
|
||||
GF_INSTALL_PLUGINS="${GF_INSTALL_PLUGINS:-"${GRAFANA_PLUGINS:-}"}"
|
||||
export GF_INSTALL_PLUGINS="${GF_INSTALL_PLUGINS:-}"
|
||||
export GF_INSTALL_PLUGINS_SKIP_TLS="${GF_INSTALL_PLUGINS_SKIP_TLS:-yes}"
|
||||
export GF_FEATURE_TOGGLES="${GF_FEATURE_TOGGLES:-}"
|
||||
export GF_VOLUME_DIR="${BITNAMI_VOLUME_DIR}/grafana"
|
||||
export GF_SECURITY_ADMIN_PASSWORD="${GF_SECURITY_ADMIN_PASSWORD:-}"
|
||||
export GRAFANA_MIGRATION_LOCK="${GRAFANA_MIGRATION_LOCK:-false}"
|
||||
export GRAFANA_SLEEP_TIME="${GRAFANA_SLEEP_TIME:-10}"
|
||||
export GRAFANA_RETRY_ATTEMPTS="${GRAFANA_RETRY_ATTEMPTS:-12}"
|
||||
|
||||
# Grafana Operator configuration
|
||||
export GF_OP_PATHS_CONFIG="/etc/grafana/grafana.ini"
|
||||
export GF_OP_PATHS_DATA="/var/lib/grafana"
|
||||
export GF_OP_PATHS_LOGS="/var/log/grafana"
|
||||
export GF_OP_PATHS_PROVISIONING="/etc/grafana/provisioning"
|
||||
export GF_OP_PLUGINS_INIT_DIR="/opt/plugins"
|
||||
|
||||
# Custom environment variables may be defined below
|
||||
55
rootfs/opt/bitnami/scripts/grafana/entrypoint.sh
Executable file
55
rootfs/opt/bitnami/scripts/grafana/entrypoint.sh
Executable file
@@ -0,0 +1,55 @@
|
||||
#!/bin/bash
|
||||
# Copyright Broadcom, Inc. All Rights Reserved.
|
||||
# SPDX-License-Identifier: APACHE-2.0
|
||||
|
||||
# shellcheck disable=SC1091
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
# set -o xtrace # Uncomment this line for debugging purposes
|
||||
|
||||
# Load Grafana environment
|
||||
. /opt/bitnami/scripts/grafana-env.sh
|
||||
|
||||
# Load libraries
|
||||
. /opt/bitnami/scripts/libbitnami.sh
|
||||
. /opt/bitnami/scripts/liblog.sh
|
||||
|
||||
function is_exec() {
|
||||
# This checks if the first provided argument is executable or if only args was used
|
||||
exec_in_path=$(builtin type -P "$1" 2> /dev/null)
|
||||
if [[ -f "$1" && -x $(realpath "$1" 2> /dev/null) || -x $(realpath "$exec_in_path" 2> /dev/null) ]]; then
|
||||
true;
|
||||
else
|
||||
false;
|
||||
fi;
|
||||
}
|
||||
|
||||
print_welcome_page
|
||||
|
||||
# We add the copy from default config in the entrypoint to not break users
|
||||
# bypassing the setup.sh logic. If the file already exists do not overwrite (in
|
||||
# case someone mounts a configuration file in /opt/bitnami/postgresql/conf)
|
||||
debug "Copying files from $GRAFANA_DEFAULT_CONF_DIR to $GRAFANA_CONF_DIR"
|
||||
cp -nr "$GRAFANA_DEFAULT_CONF_DIR"/. "$GRAFANA_CONF_DIR"
|
||||
|
||||
if [[ "$1" = "/opt/bitnami/scripts/grafana/run.sh" ]] || ! is_exec "$1"; then
|
||||
# This catches the error-code from libgrafana.sh for the immediate exit when the grafana-operator is used. And ensure that the exit code is kept silently.
|
||||
/opt/bitnami/scripts/grafana/setup.sh || GRAFANA_OPERATOR_IMMEDIATE_EXIT=$?
|
||||
if [[ "${GRAFANA_OPERATOR_IMMEDIATE_EXIT:-0}" -eq 255 ]]; then
|
||||
exit 0
|
||||
elif [[ "${GRAFANA_OPERATOR_IMMEDIATE_EXIT:-0}" -ne 0 ]]; then
|
||||
exit "$GRAFANA_OPERATOR_IMMEDIATE_EXIT"
|
||||
fi
|
||||
/post-init.sh
|
||||
info "** Grafana setup finished! **"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
if is_exec "$1"; then
|
||||
exec "$@"
|
||||
else
|
||||
exec "/opt/bitnami/scripts/grafana/run.sh" "$@"
|
||||
fi
|
||||
70
rootfs/opt/bitnami/scripts/grafana/postunpack.sh
Executable file
70
rootfs/opt/bitnami/scripts/grafana/postunpack.sh
Executable file
@@ -0,0 +1,70 @@
|
||||
#!/bin/bash
|
||||
# Copyright Broadcom, Inc. All Rights Reserved.
|
||||
# SPDX-License-Identifier: APACHE-2.0
|
||||
|
||||
# shellcheck disable=SC1091
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
# set -o xtrace # Uncomment this line for debugging purposes
|
||||
|
||||
# Load Grafana environment
|
||||
. /opt/bitnami/scripts/grafana-env.sh
|
||||
|
||||
# Load libraries
|
||||
. /opt/bitnami/scripts/libfs.sh
|
||||
. /opt/bitnami/scripts/liblog.sh
|
||||
. /opt/bitnami/scripts/libos.sh
|
||||
. /opt/bitnami/scripts/libgrafana.sh
|
||||
|
||||
info "Creating configuration file"
|
||||
cp "${GRAFANA_BASE_DIR}/conf/sample.ini" "$(grafana_env_var_value PATHS_CONFIG)"
|
||||
|
||||
info "Creating system user"
|
||||
ensure_user_exists "$GRAFANA_DAEMON_USER" --group "$GRAFANA_DAEMON_GROUP" --system
|
||||
|
||||
info "Configuring file permissions"
|
||||
for dir in "$(grafana_env_var_value PATHS_DATA)" "$(grafana_env_var_value PATHS_LOGS)" "$(grafana_env_var_value PATHS_PLUGINS)" "$(grafana_env_var_value PATHS_PROVISIONING)" "$(grafana_env_var_value VOLUME_DIR)" "${GRAFANA_DEFAULT_CONF_DIR}"; do
|
||||
ensure_dir_exists "$dir"
|
||||
# Use grafana:root ownership for compatibility when running as a non-root user
|
||||
configure_permissions_ownership "$dir" -d "775" -f "664" -u "$GRAFANA_DAEMON_USER" -g "root"
|
||||
done
|
||||
|
||||
# Use grafana:root ownership for compatibility when running as a non-root user
|
||||
configure_permissions_ownership "$(grafana_env_var_value PATHS_CONFIG)" -f "664" -u "$GRAFANA_DAEMON_USER" -g "root"
|
||||
|
||||
# Ensure permissions to parent directories of configs
|
||||
# Used when replacing configs with symlinks for grafana-operator compatibility
|
||||
for dir in "$(grafana_env_var_value PATHS_CONFIG)" "$(grafana_env_var_value PATHS_DATA)" "$(grafana_env_var_value PATHS_LOGS)" "$(grafana_env_var_value PATHS_PROVISIONING)"; do
|
||||
chmod 775 "$(dirname "$dir")"
|
||||
done
|
||||
|
||||
# Install well-known plugins
|
||||
grafana_plugin_list=(
|
||||
"grafana-clock-panel"
|
||||
"briangann-gauge-panel"
|
||||
"jdbranham-diagram-panel"
|
||||
"vonage-status-panel"
|
||||
"larona-epict-panel"
|
||||
"pierosavi-imageit-panel"
|
||||
"grafana-polystat-panel"
|
||||
"scadavis-synoptic-panel"
|
||||
)
|
||||
|
||||
cd ${GRAFANA_BASE_DIR} || exit 1
|
||||
for plugin in "${grafana_plugin_list[@]}"; do
|
||||
info "Installing ${plugin} plugin"
|
||||
grafana cli --pluginsDir "$(grafana_env_var_value PATHS_PLUGINS)" plugins install "$plugin"
|
||||
done
|
||||
|
||||
# The Grafana Helm chart mounts the data directory at "/opt/bitnami/grafana/data"
|
||||
# Therefore, all the plugins installed when building the image will be lost
|
||||
# As a workaround, we can move them to a "default-plugins" directory and recover them
|
||||
# during the 1st boot of the container
|
||||
ensure_dir_exists "$GRAFANA_DEFAULT_PLUGINS_DIR"
|
||||
mv "$(grafana_env_var_value PATHS_PLUGINS)"/* "$GRAFANA_DEFAULT_PLUGINS_DIR"
|
||||
|
||||
# Copy all initially generated configuration files to the default directory
|
||||
# (this is to avoid breaking when entrypoint is being overridden)
|
||||
cp -r "$GRAFANA_CONF_DIR"/* "$GRAFANA_DEFAULT_CONF_DIR"
|
||||
42
rootfs/opt/bitnami/scripts/grafana/run.sh
Executable file
42
rootfs/opt/bitnami/scripts/grafana/run.sh
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
# Copyright Broadcom, Inc. All Rights Reserved.
|
||||
# SPDX-License-Identifier: APACHE-2.0
|
||||
|
||||
# shellcheck disable=SC1091
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
# set -o xtrace # Uncomment this line for debugging purposes
|
||||
|
||||
# Load Grafana environment
|
||||
. /opt/bitnami/scripts/grafana-env.sh
|
||||
|
||||
# Load libraries
|
||||
. /opt/bitnami/scripts/libos.sh
|
||||
. /opt/bitnami/scripts/liblog.sh
|
||||
|
||||
declare cmd="grafana"
|
||||
declare -a args=(
|
||||
# Based on https://github.com/grafana/grafana/blob/v8.2.5/packaging/docker/run.sh
|
||||
"server"
|
||||
"--homepath=${GF_PATHS_HOME}"
|
||||
"--config=${GF_PATHS_CONFIG}"
|
||||
"--pidfile=${GRAFANA_PID_FILE}"
|
||||
"--packaging=docker"
|
||||
"$@"
|
||||
"cfg:default.log.mode=console"
|
||||
"cfg:default.paths.data=${GF_PATHS_DATA}"
|
||||
"cfg:default.paths.logs=${GF_PATHS_LOGS}"
|
||||
"cfg:default.paths.plugins=${GF_PATHS_PLUGINS}"
|
||||
"cfg:default.paths.provisioning=${GF_PATHS_PROVISIONING}"
|
||||
)
|
||||
|
||||
cd "$GRAFANA_BASE_DIR"
|
||||
|
||||
info "** Starting Grafana **"
|
||||
if am_i_root; then
|
||||
exec_as_user "$GRAFANA_DAEMON_USER" "$cmd" "${args[@]}"
|
||||
else
|
||||
exec "$cmd" "${args[@]}"
|
||||
fi
|
||||
32
rootfs/opt/bitnami/scripts/grafana/setup.sh
Executable file
32
rootfs/opt/bitnami/scripts/grafana/setup.sh
Executable file
@@ -0,0 +1,32 @@
|
||||
#!/bin/bash
|
||||
# Copyright Broadcom, Inc. All Rights Reserved.
|
||||
# SPDX-License-Identifier: APACHE-2.0
|
||||
|
||||
# shellcheck disable=SC1091
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
# set -o xtrace # Uncomment this line for debugging purposes
|
||||
|
||||
# Load Grafana environment
|
||||
. /opt/bitnami/scripts/grafana-env.sh
|
||||
|
||||
# Load MySQL Client environment for 'mysql_remote_execute' (after 'grafana-env.sh' so that MODULE is not set to a wrong value)
|
||||
if [[ -f /opt/bitnami/scripts/mysql-client-env.sh ]]; then
|
||||
. /opt/bitnami/scripts/mysql-client-env.sh
|
||||
elif [[ -f /opt/bitnami/scripts/mysql-env.sh ]]; then
|
||||
. /opt/bitnami/scripts/mysql-env.sh
|
||||
elif [[ -f /opt/bitnami/scripts/mariadb-env.sh ]]; then
|
||||
. /opt/bitnami/scripts/mariadb-env.sh
|
||||
fi
|
||||
|
||||
# Load libraries
|
||||
. /opt/bitnami/scripts/liblog.sh
|
||||
. /opt/bitnami/scripts/libgrafana.sh
|
||||
|
||||
# Ensure Grafana environment variables are valid
|
||||
grafana_validate
|
||||
|
||||
# Ensure Grafana is initialized
|
||||
grafana_initialize
|
||||
404
rootfs/opt/bitnami/scripts/libgrafana.sh
Normal file
404
rootfs/opt/bitnami/scripts/libgrafana.sh
Normal file
@@ -0,0 +1,404 @@
|
||||
#!/bin/bash
|
||||
# Copyright Broadcom, Inc. All Rights Reserved.
|
||||
# SPDX-License-Identifier: APACHE-2.0
|
||||
#
|
||||
# Bitnami Grafana library
|
||||
|
||||
# shellcheck disable=SC1091
|
||||
|
||||
# Load generic libraries
|
||||
. /opt/bitnami/scripts/liblog.sh
|
||||
. /opt/bitnami/scripts/libos.sh
|
||||
. /opt/bitnami/scripts/libvalidations.sh
|
||||
. /opt/bitnami/scripts/libversion.sh
|
||||
|
||||
# Load database library
|
||||
if [[ -f /opt/bitnami/scripts/libmysqlclient.sh ]]; then
|
||||
. /opt/bitnami/scripts/libmysqlclient.sh
|
||||
elif [[ -f /opt/bitnami/scripts/libmysql.sh ]]; then
|
||||
. /opt/bitnami/scripts/libmysql.sh
|
||||
elif [[ -f /opt/bitnami/scripts/libmariadb.sh ]]; then
|
||||
. /opt/bitnami/scripts/libmariadb.sh
|
||||
fi
|
||||
|
||||
########################
|
||||
# Print the value of a Grafana environment variable
|
||||
# Globals:
|
||||
# GF_*
|
||||
# GRAFANA_CFG_*
|
||||
# Arguments:
|
||||
# None
|
||||
# Returns:
|
||||
# The value in the environment variable
|
||||
#########################
|
||||
grafana_env_var_value() {
|
||||
local -r name="${1:?missing name}"
|
||||
local gf_env_var="GF_${name}"
|
||||
local grafana_cfg_env_var="GRAFANA_CFG_${name}"
|
||||
if [[ -n "${!gf_env_var:-}" ]]; then
|
||||
echo "${!gf_env_var:-}"
|
||||
elif [[ -n "${!grafana_cfg_env_var}" ]]; then
|
||||
echo "${!grafana_cfg_env_var:-}"
|
||||
else
|
||||
error "${gf_env_var} or ${grafana_cfg_env_var} must be set"
|
||||
fi
|
||||
}
|
||||
|
||||
########################
|
||||
# Validate settings in GRAFANA_* env vars
|
||||
# Globals:
|
||||
# GRAFANA_*
|
||||
# Arguments:
|
||||
# None
|
||||
# Returns:
|
||||
# 0 if the validation succeeded, 1 otherwise
|
||||
#########################
|
||||
grafana_validate() {
|
||||
debug "Validating settings in GRAFANA_* environment variables..."
|
||||
local error_code=0
|
||||
|
||||
# Auxiliary functions
|
||||
print_validation_error() {
|
||||
error "$1"
|
||||
error_code=1
|
||||
}
|
||||
check_path_exists() {
|
||||
if [[ ! -e "$1" ]]; then
|
||||
print_validation_error "The directory ${1} does not exist"
|
||||
fi
|
||||
}
|
||||
|
||||
# Validate user inputs
|
||||
[[ -e "$GF_OP_PATHS_CONFIG" ]] || check_path_exists "$(grafana_env_var_value PATHS_CONFIG)"
|
||||
[[ -e "$GF_OP_PATHS_DATA" ]] || check_path_exists "$(grafana_env_var_value PATHS_DATA)"
|
||||
[[ -e "$GF_OP_PATHS_LOGS" ]] || check_path_exists "$(grafana_env_var_value PATHS_LOGS)"
|
||||
[[ -e "$GF_OP_PATHS_PROVISIONING" ]] || check_path_exists "$(grafana_env_var_value PATHS_PROVISIONING)"
|
||||
|
||||
return "$error_code"
|
||||
}
|
||||
|
||||
########################
|
||||
# Ensure Grafana is initialized
|
||||
# Globals:
|
||||
# GRAFANA_*
|
||||
# Arguments:
|
||||
# None
|
||||
# Returns:
|
||||
# None
|
||||
#########################
|
||||
grafana_initialize() {
|
||||
# Ensure compatibility with Grafana Operator
|
||||
local grafana_var grafana_operator_var
|
||||
for path_suffix in "config" "data" "logs" "provisioning"; do
|
||||
grafana_var="GF_PATHS_${path_suffix^^}"
|
||||
grafana_operator_var="GF_OP_PATHS_${path_suffix^^}"
|
||||
if [[ -e "${!grafana_operator_var}" && "${!grafana_operator_var}" != "${!grafana_var}" ]]; then
|
||||
info "Ensuring ${!grafana_operator_var} points to ${!grafana_var}"
|
||||
rm -rf "${!grafana_var}"
|
||||
ln -sfn "${!grafana_operator_var}" "${!grafana_var}"
|
||||
fi
|
||||
done
|
||||
|
||||
if am_i_root; then
|
||||
for dir in "$GF_PATHS_DATA" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS"; do
|
||||
is_mounted_dir_empty "$dir" && configure_permissions_ownership "$dir" -d "775" -f "664" -u "$GRAFANA_DAEMON_USER"
|
||||
done
|
||||
fi
|
||||
|
||||
# Install plugins in a Grafana operator-compatible environment, useful to for starting the image as an init container
|
||||
# Based on https://github.com/grafana-operator/grafana-operator/blob/master/controllers/grafana/pluginsHelper.go
|
||||
if [[ -d "$GF_OP_PLUGINS_INIT_DIR" ]]; then
|
||||
info "Detected mounted plugins directory at '${GF_OP_PLUGINS_INIT_DIR}'. The container will exit after installing plugins as grafana-operator."
|
||||
if [[ -n "$GF_INSTALL_PLUGINS" ]]; then
|
||||
GF_PATHS_PLUGINS="$GF_OP_PLUGINS_INIT_DIR" grafana_install_plugins
|
||||
else
|
||||
warn "There are no plugins to install"
|
||||
fi
|
||||
return 255
|
||||
fi
|
||||
|
||||
# Recover plugins installed when building the image
|
||||
if [[ ! -e "$(grafana_env_var_value PATHS_PLUGINS)" ]] || [[ -z "$(ls -A "$(grafana_env_var_value PATHS_PLUGINS)")" ]]; then
|
||||
mkdir -p "$(grafana_env_var_value PATHS_PLUGINS)"
|
||||
if [[ -e "$GRAFANA_DEFAULT_PLUGINS_DIR" ]] && [[ -n "$(ls -A "$GRAFANA_DEFAULT_PLUGINS_DIR")" ]]; then
|
||||
cp -r "$GRAFANA_DEFAULT_PLUGINS_DIR"/* "$(grafana_env_var_value PATHS_PLUGINS)"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Configure configuration file based on environment variables
|
||||
grafana_configure_from_environment_variables
|
||||
|
||||
# Install plugins
|
||||
grafana_install_plugins
|
||||
|
||||
# Configure Grafana feature toggles
|
||||
! is_empty_value "$GF_FEATURE_TOGGLES" && grafana_conf_set "feature_toggles" "enable" "$GF_FEATURE_TOGGLES"
|
||||
|
||||
# If using an external database, avoid nodes collition during migration
|
||||
if is_boolean_yes "$GRAFANA_MIGRATION_LOCK"; then
|
||||
grafana_migrate_db
|
||||
fi
|
||||
|
||||
# Avoid exit code of previous commands to affect the result of this function
|
||||
true
|
||||
}
|
||||
|
||||
########################
|
||||
# Runs Grafana migration using a database lock to avoid collision with other Grafana nodes
|
||||
# If database is locked, wait until unlocked and continue. Otherwise, run Grafana to perform migration.
|
||||
# Globals:
|
||||
# GRAFANA_CFG_*
|
||||
# Arguments:
|
||||
# None
|
||||
# Returns:
|
||||
# None
|
||||
#########################
|
||||
grafana_migrate_db() {
|
||||
local -r db_host="${GRAFANA_CFG_DATABASE_HOST:-mysql}"
|
||||
local -r db_port="${GRAFANA_CFG_DATABASE_PORT:-3306}"
|
||||
local -r db_name="${GRAFANA_CFG_DATABASE_NAME:-}"
|
||||
local -r db_user="${GRAFANA_CFG_DATABASE_USER:-}"
|
||||
local -r db_pass="${GRAFANA_CFG_DATABASE_PASSWORD:-}"
|
||||
|
||||
local -r grafana_host="${GRAFANA_CFG_SERVER_HTTP_ADDR:-localhost}"
|
||||
local -r grafana_port="${GRAFANA_CFG_SERVER_HTTP_PORT:-3000}"
|
||||
local -r grafana_protocol="${GRAFANA_CFG_SERVER_PROTOCOL:-http}"
|
||||
|
||||
local -r sleep_time="${GRAFANA_SLEEP_TIME:-5}"
|
||||
local -r retries="${GRAFANA_RETRY_ATTEMPTS:-12}"
|
||||
|
||||
lock_db() {
|
||||
debug_execute mysql_remote_execute_print_output "$db_host" "$db_port" "$db_name" "$db_user" "$db_pass" <<EOF
|
||||
create table db_lock(
|
||||
id INT PRIMARY KEY
|
||||
);
|
||||
EOF
|
||||
}
|
||||
release_db() {
|
||||
debug_execute mysql_remote_execute_print_output "$db_host" "$db_port" "$db_name" "$db_user" "$db_pass" <<EOF
|
||||
drop table if exists db_lock;
|
||||
EOF
|
||||
}
|
||||
is_db_unlocked() {
|
||||
local result
|
||||
|
||||
result=$(mysql_remote_execute_print_output "$db_host" "$db_port" "$db_name" "$db_user" "$db_pass" <<EOF
|
||||
show tables like 'db_lock';
|
||||
EOF
|
||||
)
|
||||
if grep -q "db_lock" <<<"$result"; then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
if lock_db; then
|
||||
info "Starting Grafana database migration"
|
||||
grafana_start_bg
|
||||
# Grafana will start listening HTTP connections once the database initialization has succeeded
|
||||
if ! retry_while "debug_execute curl --silent ${grafana_protocol}://${grafana_host}:${grafana_port}" "$retries" "$sleep_time"; then
|
||||
error "Grafana failed to start in the background. Releasing database lock before exit."
|
||||
# Release the lock
|
||||
release_db
|
||||
return 1
|
||||
fi
|
||||
grafana_stop
|
||||
# Release the lock
|
||||
release_db
|
||||
info "Grafana database migration completed. Lock released."
|
||||
else
|
||||
info "Grafana database migration in progress detected. Waiting for lock to be released before initializing Grafana"
|
||||
if ! retry_while "is_db_unlocked" "$retries" "$sleep_time"; then
|
||||
error "Failed waiting for database lock to be released. If there is no migration in progress, manually drop table 'db_lock' from the grafana database"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
########################
|
||||
# Start Grafana in background
|
||||
# Arguments:
|
||||
# None
|
||||
# Returns:
|
||||
# None
|
||||
#########################
|
||||
grafana_start_bg() {
|
||||
local cmd="grafana"
|
||||
local -a args=(
|
||||
# Based on https://github.com/grafana/grafana/blob/v8.2.5/packaging/docker/run.sh
|
||||
"server"
|
||||
"--homepath=${GF_PATHS_HOME}"
|
||||
"--config=${GF_PATHS_CONFIG}"
|
||||
"--packaging=docker"
|
||||
"--pidfile=${GRAFANA_PID_FILE}"
|
||||
"cfg:default.log.mode=console"
|
||||
"cfg:default.paths.data=${GF_PATHS_DATA}"
|
||||
"cfg:default.paths.logs=${GF_PATHS_LOGS}"
|
||||
"cfg:default.paths.plugins=${GF_PATHS_PLUGINS}"
|
||||
"cfg:default.paths.provisioning=${GF_PATHS_PROVISIONING}"
|
||||
)
|
||||
|
||||
cd "$GRAFANA_BASE_DIR" || return
|
||||
|
||||
info "Starting Grafana in background"
|
||||
if am_i_root; then
|
||||
debug_execute run_as_user "$GRAFANA_DAEMON_USER" "$cmd" "${args[@]}" &
|
||||
else
|
||||
debug_execute "$cmd" "${args[@]}" &
|
||||
fi
|
||||
}
|
||||
|
||||
########################
|
||||
# Update Grafana config file with settings provided via environment variables
|
||||
# Globals:
|
||||
# GRAFANA_CFG_*
|
||||
# GF_PATHS_CONFIG
|
||||
# Arguments:
|
||||
# None
|
||||
# Returns:
|
||||
# None
|
||||
#########################
|
||||
grafana_configure_from_environment_variables() {
|
||||
local section_key_pair section key value
|
||||
# Map environment variables to config properties
|
||||
for var in "${!GRAFANA_CFG_@}"; do
|
||||
# shellcheck disable=SC2001
|
||||
section_key_pair="$(sed 's/^GRAFANA_CFG_//g' <<< "$var" | tr '[:upper:]' '[:lower:]')"
|
||||
section="${section_key_pair/_*}"
|
||||
key="${section_key_pair#*_}"
|
||||
value="${!var}"
|
||||
grafana_conf_set "$section" "$key" "$value"
|
||||
done
|
||||
}
|
||||
|
||||
########################
|
||||
# Update a single configuration in Grafana's config file
|
||||
# Globals:
|
||||
# GF_PATHS_CONFIG
|
||||
# Arguments:
|
||||
# $1 - section
|
||||
# $2 - key
|
||||
# $3 - value
|
||||
# Returns:
|
||||
# None
|
||||
#########################
|
||||
grafana_conf_set() {
|
||||
local -r section="${1:?missing key}"
|
||||
local -r key="${2:?missing key}"
|
||||
local -r value="${3:-}"
|
||||
debug "Setting configuration ${section}.${key} with value '${value}' to configuration file"
|
||||
ini-file set --section "$section" --key "$key" --value "$value" "$(grafana_env_var_value PATHS_CONFIG)"
|
||||
}
|
||||
|
||||
########################
|
||||
# Install plugins
|
||||
# Globals:
|
||||
# GRAFANA_*
|
||||
# Arguments:
|
||||
# None
|
||||
# Returns:
|
||||
# None
|
||||
#########################
|
||||
grafana_install_plugins() {
|
||||
[[ -z "$GF_INSTALL_PLUGINS" ]] && return
|
||||
|
||||
local -a plugin_list
|
||||
IFS="," read -r -a plugin_list <<< "$(tr ';' ',' <<< "${GF_INSTALL_PLUGINS}")"
|
||||
if [[ "${#plugin_list[@]}" -le 0 ]]; then
|
||||
warn "There are no plugins to install"
|
||||
return
|
||||
fi
|
||||
|
||||
local plugin_id plugin_version
|
||||
local -a grafana_plugin_install_args
|
||||
local -a plugin_url_array
|
||||
local -a plugin_id_version_array
|
||||
for plugin in "${plugin_list[@]}"; do
|
||||
plugin_id="$plugin"
|
||||
plugin_version=""
|
||||
grafana_plugin_install_args=("--pluginsDir" "$(grafana_env_var_value PATHS_PLUGINS)")
|
||||
is_boolean_yes "$GF_INSTALL_PLUGINS_SKIP_TLS" && grafana_plugin_install_args+=("--insecure")
|
||||
if grep -q '=' <<< "$plugin"; then
|
||||
read -r -a plugin_url_array <<< "$(tr '=' ' ' <<< "${plugin}")"
|
||||
info "Installing plugin ${plugin_url_array[0]} from URL ${plugin_url_array[1]}"
|
||||
plugin_id="${plugin_url_array[0]}"
|
||||
grafana_plugin_install_args+=("--pluginUrl" "${plugin_url_array[1]}")
|
||||
elif grep ':' <<< "$plugin"; then
|
||||
read -r -a plugin_id_version_array <<< "$(tr ':' ' ' <<< "${plugin}")"
|
||||
plugin_id="${plugin_id_version_array[0]}"
|
||||
plugin_version="${plugin_id_version_array[1]}"
|
||||
info "Installing plugin ${plugin_id} @ ${plugin_version}"
|
||||
elif grep ' ' <<< "$plugin"; then
|
||||
read -r -a plugin_id_version_array <<< "$plugin"
|
||||
plugin_id="${plugin_id_version_array[0]}"
|
||||
plugin_version="${plugin_id_version_array[1]}"
|
||||
info "Installing plugin ${plugin_id} @ ${plugin_version}"
|
||||
else
|
||||
info "Installing plugin ${plugin_id}"
|
||||
fi
|
||||
grafana_plugin_install_args+=("plugins" "install" "${plugin_id}")
|
||||
if [[ -n "$plugin_version" ]]; then
|
||||
grafana_plugin_install_args+=("$plugin_version")
|
||||
fi
|
||||
grafana cli "${grafana_plugin_install_args[@]}"
|
||||
done
|
||||
}
|
||||
|
||||
########################
|
||||
# Check if Grafana is running
|
||||
# Arguments:
|
||||
# None
|
||||
# Returns:
|
||||
# Boolean
|
||||
#########################
|
||||
is_grafana_running() {
|
||||
local pid
|
||||
pid="$(get_pid_from_file "$GRAFANA_PID_FILE")"
|
||||
if [[ -n "$pid" ]]; then
|
||||
is_service_running "$pid"
|
||||
else
|
||||
false
|
||||
fi
|
||||
}
|
||||
|
||||
########################
|
||||
# Check if Grafana is not running
|
||||
# Arguments:
|
||||
# None
|
||||
# Returns:
|
||||
# Boolean
|
||||
#########################
|
||||
is_grafana_not_running() {
|
||||
! is_grafana_running
|
||||
}
|
||||
|
||||
########################
|
||||
# Stop Grafana
|
||||
# Arguments:
|
||||
# None
|
||||
# Returns:
|
||||
# None
|
||||
#########################
|
||||
grafana_stop() {
|
||||
is_grafana_not_running && return
|
||||
|
||||
info "Stopping Grafana"
|
||||
stop_service_using_pid "$GRAFANA_PID_FILE"
|
||||
}
|
||||
|
||||
########################
|
||||
# Returns grafana major version
|
||||
# Globals:
|
||||
# GRAFANA_BIN_DIR
|
||||
# Arguments:
|
||||
# None
|
||||
# Returns:
|
||||
# None
|
||||
#########################
|
||||
get_grafana_major_version() {
|
||||
grafana_version="$("${GRAFANA_BIN_DIR}/grafana" -v)"
|
||||
grafana_version="${grafana_version#"grafana version "}"
|
||||
major_version="$(get_sematic_version "$grafana_version" 1)"
|
||||
echo "${major_version:-0}"
|
||||
}
|
||||
38
rootfs/post-init.d/shell.sh
Executable file
38
rootfs/post-init.d/shell.sh
Executable file
@@ -0,0 +1,38 @@
|
||||
#!/bin/bash
|
||||
# Copyright Broadcom, Inc. All Rights Reserved.
|
||||
# SPDX-License-Identifier: APACHE-2.0
|
||||
#
|
||||
# Executes custom Bash init scripts
|
||||
|
||||
# shellcheck disable=SC1090,SC1091
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
# set -o xtrace # Uncomment this line for debugging purposes
|
||||
|
||||
# Load libraries with logging functions
|
||||
if [[ -f /opt/bitnami/base/functions ]]; then
|
||||
. /opt/bitnami/base/functions
|
||||
else
|
||||
. /opt/bitnami/scripts/liblog.sh
|
||||
fi
|
||||
|
||||
# Loop through all input files passed via stdin
|
||||
read -r -a custom_init_scripts <<< "$@"
|
||||
failure=0
|
||||
if [[ "${#custom_init_scripts[@]}" -gt 0 ]]; then
|
||||
for custom_init_script in "${custom_init_scripts[@]}"; do
|
||||
[[ "$custom_init_script" != *".sh" ]] && continue
|
||||
if [[ -x "$custom_init_script" ]]; then
|
||||
info "Executing ${custom_init_script}"
|
||||
"$custom_init_script" || failure="1"
|
||||
else
|
||||
info "Sourcing ${custom_init_script} as it is not executable by the current user, any error may cause initialization to fail"
|
||||
. "$custom_init_script"
|
||||
fi
|
||||
[[ "$failure" -ne 0 ]] && error "Failed to execute ${custom_init_script}"
|
||||
done
|
||||
fi
|
||||
|
||||
exit "$failure"
|
||||
25
rootfs/post-init.sh
Executable file
25
rootfs/post-init.sh
Executable file
@@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
# Copyright Broadcom, Inc. All Rights Reserved.
|
||||
# SPDX-License-Identifier: APACHE-2.0
|
||||
|
||||
# shellcheck disable=SC1091
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
# set -o xtrace # Uncomment this line for debugging purposes
|
||||
|
||||
# Only execute init scripts once
|
||||
if [[ ! -f "/bitnami/grafana/.user_scripts_initialized" && -d "/docker-entrypoint-init.d" ]]; then
|
||||
read -r -a init_scripts <<< "$(find "/docker-entrypoint-init.d" -type f -print0 | sort -z | xargs -0)"
|
||||
if [[ "${#init_scripts[@]}" -gt 0 ]] && [[ ! -f "/bitnami/grafana/.user_scripts_initialized" ]]; then
|
||||
mkdir -p "/bitnami/grafana"
|
||||
for init_script in "${init_scripts[@]}"; do
|
||||
for init_script_type_handler in /post-init.d/*.sh; do
|
||||
"$init_script_type_handler" "$init_script"
|
||||
done
|
||||
done
|
||||
fi
|
||||
|
||||
touch "/bitnami/grafana/.user_scripts_initialized"
|
||||
fi
|
||||
Reference in New Issue
Block a user