#!/usr/bin/env bash # This is my Linux server configuration utility (sconfig.sh) # Read more about it here: https://git.socialnerds.org/david/sconfig # ***** CONFIG ***** # general information NAME="sconfig" TITLE="Server Configuration" DESCRIPTION="The Linux server configuration utility" VERSION="0.2" AUTHOR="david@socialnerds.org" WEBSITE="https://git.socialnerds.org/david/sconfig" REPO="$WEBSITE.git" LICENSE="https://git.socialnerds.org/david/sconfig/raw/branch/main/LICENSE" # default settings CONFIGFILE="/etc/sconfig/sconfig.conf" DEBUG=0 LOGFILE="" declare -A CONFIG CONFIG=([debug_enabled]=$DEBUG [logfile]="$LOGFILE" [btrfs_enabled]= [btrfs_subvols]="/" [btrfs_versions]=30 [miab_enabled]= [miab_host]="box.example.com" [miab_user]="admin@example.com" [miab_password]="verysecret!=+%password" [healthchecks_enabled]= [healthchecks_baseurl]="" [healthchecks_id]="") declare -A PACKAGES PACKAGES=([ubuntu]="curl less vim" [arch]="curl less vim" [debian]="curl less vim") # external library files and command prerequsites # both unused for now #LIBRARIES=("library.sh" "ui.sh") #DEPENDENCIES=("curl" "more" "sort") # ***** FUNCTION DEFINITIONS ***** # execute upon Ctrl-C detection function bashtrap { library_log warn "Ctrl-C detected, exiting" exit 2 } # return 1/false if not executed as root function amiroot { if [ "$(whoami)" != "root" ]; then return 1 fi } # check if stdout is a TTY and return 1 if it is not # for detecting if executed by cron (or user) function amitty { if [ ! -t 1 ]; then return 1 fi } # general text output method # usage: output function library_log { if [ "$1" != "debug" -o $DEBUG -eq 1 ]; then echo "[$1] ${@:2}" if [ "$LOGFILE" -a -w "$LOGFILE" ]; then echo "[$(date +%Y%m%d%H%M%S)][$1] ${@:2}" >> "$LOGFILE" fi fi } # very simple configfile parser # it fills a global variable with key=value pairs from a configfile # usage: config_read function config_read { if [ "$1" -a -r "$1" ]; then local FILE="$1" while read -r LINE || [ -n "$LINE" ]; do local FILTER='^[0-9a-zA-Z]+[_-]?[0-9a-zA-Z]+=.*$' if [[ "$LINE" =~ $FILTER ]]; then CONFIG[${LINE%%=*}]=${LINE#*=} fi done < $FILE else return 1 fi } # very simple configfile writer # it (over)writes a configfile with key=value pairs from a global variable # usage: config_write function config_write { if [ "$1" ]; then local FILE="$1" for KEY in ${!CONFIG[@]}; do echo "$KEY=${CONFIG[$KEY]}" done | sort > $FILE else return 1 fi } # get the linux distribution id from /etc/os-release # only systems with this file present are supported function library_get_distro { local RELEASE_FILE="/etc/os-release" if [ -r $RELEASE_FILE ]; then while read -r LINE || [ -n "$LINE" ]; do local FILTER='^ID=' if [[ "$LINE" =~ $FILTER ]]; then echo "${LINE#*=}"; break fi done < $RELEASE_FILE fi } # retrieve path to this script #function get_scriptpath { # local DIRNAME="$(dirname $0)" # if [ -L $0 ]; then # local DIRLINK="$(dirname $(readlink $0))" # if [ $DIRLINK == "." ]; then # local SCRIPTPATH="$DIRNAME" # else # local SCRIPTPATH="$DIRNAME/$DIRLINK" # fi # else # local SCRIPTPATH="$DIRNAME" # fi # if [[ $SCRIPTPATH =~ ^/.* ]]; then # echo "$SCRIPTPATH" # else # #TODO: redirect stdout and stderr for cd to /dev/null # cd $SCRIPTPATH; echo "$PWD" # fi #} #function main { # for MODULE in ${MODULES[@]}; do # library_log debug "Module found ($MODULE)" # done # library_log info "This is an informational message"; sleep 2 #} # print the usage message function usage { echo; echo "Usage: $(basename $0) " echo ""; echo "OPTIONS:" echo " -h Show help message" echo " -i Show script information (Version, etc.)" echo " -c Use custom configuration file" echo " -l Use custom log file" echo " -d|-v Enable verbose output"; echo } # print general information function info { echo; echo "$NAME - $DESCRIPTION"; echo echo "Version: $VERSION" echo "Author: $AUTHOR" echo "Website: $WEBSITE" echo "License: $LICENSE"; echo } # ***** START ***** # bashtrap initialization trap bashtrap INT # require root if ! amiroot; then library_log error "You need to run this script with elevated privileges" exit 1 fi # option handler while getopts "c:l:dvih" ARG; do case $ARG in c) CONFIGFILE="$OPTARG" library_log debug "Custom config file set by command line option [-$ARG $OPTARG]" ;; l) LOGFILE="$OPTARG" library_log debug "Custom log file set by command line option [-$ARG $OPTARG]" ;; d|v) if [ ! $DEBUG -eq 1 ]; then DEBUG=1 library_log debug "Debug mode enabled by command line option [-$ARG]" fi ;; i) info; exit 0 ;; h) usage; exit 0 ;; *) usage; exit 1 ;; esac done # loading config values (from $CONFIGFILE) if ! config_read "$CONFIGFILE"; then library_log warning "Could not read config file, skipping [$CONFIGFILE]" fi # setting runtime variables #SCRIPTPATH="$(get_scriptpath)" #MODULES=($(ls $SCRIPTPATH/modules/*.sh)) if [ ! $DEBUG -eq 1 ]; then DEBUG=${CONFIG[debug_enabled]} fi if [ -z $LOGFILE ]; then LOGFILE=${CONFIG[logfile]} fi # create logfile if missing if [ "$LOGFILE" -a ! -w "$LOGFILE" ]; then if [ ! -d $(dirname "$LOGFILE") ]; then mkdir -p $(dirname "$LOGFILE") fi touch "$LOGFILE" fi # create configfile if missing if [ ! -w $CONFIGFILE ]; then if [ ! -d $(dirname $CONFIGFILE) ]; then mkdir -p $(dirname $CONFIGFILE) fi # write config values (to $CONFIGFILE) library_log info "Creating new config file [$CONFIGFILE]" if ! config_write "$CONFIGFILE"; then library_log warning "Could not write to config file [$CONFIGFILE]" fi fi # fix file permissions library_log debug "Fixing file permissions" chown $(id -u):$(id -g) "$CONFIGFILE" chmod 600 "$CONFIGFILE" if [ "$LOGFILE" ]; then chown $(id -u):$(id -g) "$LOGFILE" chmod 644 "$LOGFILE" fi # loading libraries #for LIBRARY in ${LIBRARIES[@]}; do # if [ -r $SCRIPTPATH/$LIBRARY ]; then # source $SCRIPTPATH/$LIBRARY # if [ $DEBUG -eq 1 ]; then # echo "[debug] Library loaded [$LIBRARY]" # fi # else # echo "[error] Library not found [$LIBRARY]" # exit 1 # fi #done # checking for the availibility of ${DEPENDENCIES[@]} #TODO: loop through all before reporting the missing depenencies #for DEPENDENCY in ${DEPENDENCIES[@]}; do # if ! $(command -v $DEPENDENCY &> /dev/null); then # library_log error "Dependency not found [$DEPENDENCY]" # #exit 1 # fi #done # update package repositories and install required packages case "$(library_get_distro)" in debian|ubuntu|raspbian) library_log info "Updating package repositories" apt-get update > /dev/null if [ $? -eq 0 ]; then library_log debug "Success!" else library_log error "An error occured while updating package repositories" exit 1 fi ;; arch) library_log info "Updating package repositories" pacman -Sy > /dev/null if [ $? -eq 0 ]; then library_log debug "Success!" else library_log error "An error occured while updating package repositories" exit 1 fi ;; *) library_log error "Could not determine your operating system" exit 1 ;; esac # main program, execute only if called directly if [ $(basename $0) == "$NAME" -o $(basename $0) == "$NAME.sh" ]; then # output useful debugging information library_log debug "***** START *****" # main fi # ***** END ***** library_log debug "***** END *****" exit 0