DEV Community

tj_27
tj_27

Posted on

Installing Node Exporter Bash Script

Hello, everyone!
I enjoy writing script since I learned it.
But please don't mock me, as I don't know yet the rules. I mean I'm not sure if this is the common and professional way of writing scripts.
I am not actually an IT (my college course is really far from this field, lol).
Anyways, hope this can help.

#!/bin/bash
# Installing Node Exporter

# Output yellow text
echo_yellow() {
    echo - "\e[93m$1\e[0m"
}

# Specify the name of the systemd service
SERVICE_NAME="node_exporter"

# Check if the service file exists
if [ -e "/usr/lib/systemd/system/$SERVICE_NAME.service" ]; then
    # Check if the service is active
    if sudo systemctl is-active --quiet "$SERVICE_NAME"; then
        echo_yellow "There is an active $SERVICE_NAME."
        # Check the version of the active node_exporter
        NODE_EXPORTER_PATH="/usr/local/$SERVICE_NAME/$SERVICE_NAME"
        VERSION_INFO="$($NODE_EXPORTER_PATH --version | awk '/node_exporter/ {print $3}')"
        echo_yellow "Active Node ExporterVersion: $VERSION_INFO"
        echo
        echo "Do you want to remove it and replace with a new one? [ 1 / 2 ]"
        echo
        echo_yellow "1: Remove the active node_exporter and replace it with a new one."
        echo
        echo "2: Don't do anything and exit."
        echo
        read -rp "> " ACTION
        # Check the action to do
        if [ -z "$ACTION" ]; then
            echo
            echo_yellow "Removing all node_exporter files..."
            echo
            # Remove node_exporter related files
            sudo systemctl stop $SERVICE_NAME
            sudo systemctl disable $SERVICE_NAME
            sudo rm /usr/lib/systemd/system/$SERVICE_NAME.service
            sudo rm -rf /usr/local/node_exporter*
            echo
            echo "Related files removed."
            echo
            echo "Installation will continue..."
            echo
        elif [ "$ACTION" -eq 2 ]; then
            echo
            echo "No action done."
            echo
            exit
        else
            echo
            echo "Invalid input. Please enter 1 or 2."
            echo
            exit 1
        fi
    else
        echo "There's a $SERVICE_NAME service that is not active. Removing related files..."
        sudo systemctl stop $SERVICE_NAME
        sudo systemctl disable $SERVICE_NAME
        sudo rm /usr/lib/systemd/system/$SERVICE_NAME.service
        sudo rm -rf /usr/local/node_exporter*
        echo
        echo "Related files removed."
        echo
        echo "Installation will continue..."
        echo
    fi
else
    echo "No $SERVICE_NAME service file found."
    echo
    fi

# Curling Google to check if connected to a network
echo "Looking for a network..."
echo
if curl -sSf https://www.google.com > /dev/null; then
    echo "Network connected."
    echo
else
    echo "The server is not connected to the network. Please connect and try again.";
    echo
    exit 1
fi

echo_yellow -n "Insert the version you would lilke to be installed, default is [ 1.2.2 ] :"
read VERSION
VERSION=${VERSION:-1.2.2}
echo
# Download the file
wget https://github.com/prometheus/node_exporter/releases/download/v$VERSION/node_exporter-$VERSION.linux-amd64.tar.gz -P /opt
# Extract the downloaded tarball in user directory with a new name
tar -xzvf /opt/node_exporter-$VERSION.linux-amd64.tar.gz -C /usr/local && mv /usr/local/node_exporter-$VERSION.linux-amd64 /usr/local_node_exporter

# Create a systemd service file for Node Exporter
cat >/usr/lib/systemd/system/node_exporter.service<<EOF
[Unit]
Description= Node Exporter
Documentation= https://prometheus.io/
Wants=network.target
After=network.target

[Service]
User=node_exporter
Group=node_exporter
Type=simple
ExecStart=/usr/local/node_exporter/node_exporter
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

# Create the node_exporter user
sudo useradd -M -r -s /bin/false node_exporter

# Set proper permissions
sudo chown -R node_exporter. /usr/local/node_exporter/node_exporter
sudo chmod 755 /usr/local/node_exporter/node_exporter

# Reload systemd and start Node Exporter
sudo systemctl daemon-reload
sudo systemctl start node_exporter.service
sudo systemctl enable node_exporter.service
sudo systemctl status node_exporter.service

# Cleanup downloaded file
rm -f /opt/node_exporter-$VERSION.linux-amd64.tar.gz*
echo 
if sudo systemctl is-active --quiet "$SERVICE_NAME"; then
    echo_yellow "Node Exporter installed successfully!"
    echo
else
    echo "Node Exporter installation failed."
    echo
fi
Enter fullscreen mode Exit fullscreen mode

Top comments (3)

Collapse
 
moopet profile image
Ben Sinclair • Edited

This looks mostly fine - it does what you want; it automates installing the service for you which is exactly what a script is good for.

That said, here're a couple of tips:

  • You probably meant "quiet" here rather than "quite", since that's not a flag:
if sudo systemctl is-active --quite "$SERVICE_NAME"; then
Enter fullscreen mode Exit fullscreen mode
  • the last line reads, done but you haven't started a while loop - did you have an earlier draft where the user input was repeated if the user gave an invalid value?
  • rather than outputing ANSI escape codes directly, you might find it easier and more portable to use the tput command
  • printf is more portable than echo and you can use newlines in it expliclity:
printf "Network connected.\n\n"
Enter fullscreen mode Exit fullscreen mode

General notes:

  • the convention of using all caps for variable names in shell scripts is supposed to be for things that are available outside the local environment (things you import or export), though a lot of people do just use all caps all the time
  • you should probably check some of your commands have succeeded before proceeding
  • some of your sudo commands scare me a little:
sudo rm -rf /usr/local/$SERVICE_NAME*
Enter fullscreen mode Exit fullscreen mode

The way this is formatted, if for some reason SERVICE_NAME is unset - say you changed it and made a typo - then you'll wipe out the entirety of /usr/local

  • having several nested if blocks gets unmanageable quite quickly in shell scripts, so it's probably best to factor more things out to their own functions or to exit early if the condition isn't met.

Final note:

Did you know you can syntax-highlight the code here if you put the language after the three backticks (in this case either "bash" or "sh")!

Collapse
 
tj_27 profile image
tj_27

waaah, I didn't expect someone would notice. Thanks a lot. I'll study more

Collapse
 
tj_27 profile image
tj_27 • Edited

REVISED NODE EXPORTER INSTALLTION BASH SCRIPT

#!/bin/bash
# Installing Node Exporter

# tput commands
CLEAR="tput clear"
DOWN="tput cud1"
BOLD="tput bold"
NORMAL="tput sgr0"
BLACK="tput setaf 0"
RED="tput setaf 1"
GREEN="tput setaf 2"
YELLOW="tput setaf 3"
BLUE="tput setaf 4"

$CLEAR
$DOWN
# Installation confirmation
printf "You have selected to install node_exporter.\n\n"
read -p "Do you want to continue? [ yes / no ] : " USER_INPUT
USER_INPUT=${USER_INPUT:-yes}
$DOWN

# Convert user's choice to lowercase for case-sensitive comparison
USER_INPUT_LOWER=$(echo "$USER_INPUT" | tr '[:upper:]' '[:lower:]')

# Check the user's input
if [ "$USER_INPUT_LOWER" == "yes" ]; then
    $YELLOW
    printf "Node exporter installation confirmed.\n\n"
    $NORMAL
else
    printf "Node exporter installation cancelled.\n\n"
    exit
fi

# Specify the name of the systemd service
SERVICE_NAME="node_exporter"

# Check if the service file exists
if [ -e "/usr/lib/systemd/system/$SERVICE_NAME.service" ]; then
    # Check if the service is active
    if sudo systemctl is-active --quiet "$SERVICE_NAME"; then
        $BOLD
        printf "There is an active $SERVICE_NAME. \n\n"
        $NORMAL
        # Check the version of the active node_exporter
        NODE_EXPORTER_PATH="/usr/local/$SERVICE_NAME/$SERVICE_NAME"
        VERSION_INFO="$($NODE_EXPORTER_PATH --version | awk '/node_exporter/ {print $3}')"
        $GREEN
        printf "Active Node ExporterVersion: $VERSION_INFO \n\n"
        $NORMAL
        printf "Do you want to remove it and replace with a new one? [ 1 / 2 ]\n\n"
        printf " 1: Remove the active node_exporter and replace it with a new one. \n\n"
        printf " 2: Don't do anything and exit.\n\n"
        read -rp "> " ACTION
        # Check the action to do
        if [ -z "$ACTION" ]; then
            printf "Removing all node_exporter files... \n\n"
            # Remove node_exporter related files
            sudo systemctl stop $SERVICE_NAME
            sudo systemctl disable $SERVICE_NAME
            sudo rm /usr/lib/systemd/system/$SERVICE_NAME.service
            sudo rm -rf /usr/local/node_exporter*
            printf "Related files removed.\n\n"
            printf "Installation will continue...\n\n"
        elif [ "$ACTION" -eq 1 ]; then
            printf "Removing all node_exporter files... \n\n"
            # Remove node_exporter related files
            sudo systemctl stop $SERVICE_NAME
            sudo systemctl disable $SERVICE_NAME
            sudo rm /usr/lib/systemd/system/$SERVICE_NAME.service
            sudo rm -rf /usr/local/node_exporter*
            printf "Related files removed.\n\n"
            printf "Installation will continue...\n\n"
        elif [ "$ACTION" -eq 2 ]; then
            $DOWN
            printf "No action done.\n\n"
            exit
        else
            printf "Invalid input. Please enter 1 or 2.\n\n"
            exit 1
        fi
    else
        printf "There's a $SERVICE_NAME service that is not active. Removing related files...\n\n"
        sudo systemctl stop $SERVICE_NAME
        sudo systemctl disable $SERVICE_NAME
        sudo rm /usr/lib/systemd/system/$SERVICE_NAME.service
        sudo rm -rf /usr/local/node_exporter*
        printf "Related files removed.\n\n"
        printf "Installation will continue...\n\n"
    fi
else
    printf "No $SERVICE_NAME service file found.\n\n"
    fi

# Curling Google to check if connected to a network
printf "Looking for a network...\n\n"
if curl google.com > /dev/null; then
    $DOWN
    printf "Network connected.\n\n"
else
    $DOWN
    printf "The server is not connected to the network. Please connect and try again.\n\n";
    exit 1
fi

echo -n "Insert the version you would lilke to be installed, default is [ 1.2.2 ] : "
$BOLD
$BLUE
read VERSION
$NORMAL
VERSION=${VERSION:-1.2.2}
$DOWN
$NORMAL
# Download the file
wget https://github.com/prometheus/node_exporter/releases/download/v$VERSION/node_exporter-$VERSION.linux-amd64.tar.gz -P /opt
# Extract the downloaded tarball in user directory with a new name
tar -xzvf /opt/node_exporter-$VERSION.linux-amd64.tar.gz -C /usr/local && mv /usr/local/node_exporter-$VERSION.linux-amd64 /usr/local/node_exporter

# Create a systemd service file for Node Exporter
cat >/usr/lib/systemd/system/node_exporter.service<<EOF
[Unit]
Description= Node Exporter
Documentation= https://prometheus.io/
Wants=network.target
After=network.target

[Service]
User=node_exporter
Group=node_exporter
Type=simple
ExecStart=/usr/local/node_exporter/node_exporter
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

# Create the node_exporter user
sudo useradd -M -r -s /bin/false node_exporter

# Set proper permissions
sudo chown -R node_exporter. /usr/local/node_exporter/node_exporter
sudo chmod 755 /usr/local/node_exporter/node_exporter

# Reload systemd and start Node Exporter
sudo systemctl daemon-reload
sudo systemctl start node_exporter.service
sudo systemctl enable node_exporter.service
sudo systemctl status node_exporter.service

# Cleanup downloaded file
rm -f /opt/node_exporter-$VERSION.linux-amd64.tar.gz*
$DOWN
if sudo systemctl is-active --quiet "$SERVICE_NAME"; then
    $DOWN
    $BOLD
    $YELLOW
    printf "======================================\n"
    $GREEN
    printf "Node Exporter installed successfully!\n"
    $NORMAL
    $BOLD
    printf "Version: $VERSION\n"
    $YELLOW
    printf "======================================\n"
    $NORMAL
    $DOWN
else
    $DOWN
    $RED
    printf "Node Exporter installation failed.\n\n"
    $NORMAL
    $DOWN
fi
Enter fullscreen mode Exit fullscreen mode

β€œLive as if you were to die tomorrow. Learn as if you were to live forever.” β€” Mahatma Gandhi