#!/bin/bash ############################################################################## # DO NOT MODIFY THIS FILE. Instead, modify 'helpers/custom'. ############################################################################## COOKBOOK_NAME="$(basename "$0")" if [ -z "$SHOESTRAP_BASE" ]; then DIR="$( cd "$( dirname "$0" )" && pwd )" else DIR="$SHOESTRAP_BASE" fi # # Run a given recipe. # # Arguments can be passed to the 'recipe' function. They will be accessible by # the recipe as $2, $3, $4, etc. # recipe () { CURRENT_RECIPE_NAME=$1 DEFAULT_ASSETS_PATH="$DIR/assets/default/$CURRENT_RECIPE_NAME" COOKBOOK_ASSETS_PATH="$DIR/assets/$COOKBOOK_NAME/$CURRENT_RECIPE_NAME" local default_recipe="$DIR/recipes/default/$CURRENT_RECIPE_NAME" local cookbook_recipe="$DIR/recipes/$COOKBOOK_NAME/$CURRENT_RECIPE_NAME" if [ -f "$cookbook_recipe" ]; then log "Running recipe '$cookbook_recipe'..." 1 separator # shellcheck source=/dev/null . "$cookbook_recipe" elif [ -f "$default_recipe" ]; then log "Running recipe '$default_recipe'..." 1 separator # shellcheck source=/dev/null . "$default_recipe" else error "Could not find recipe for '$CURRENT_RECIPE_NAME'. Fail!" fi cd "$DIR" || error "Failed to find recipe" } # # Prints the 'finished' banner. # finished () { spacer 1 separator "=" echo " FINISHED: '$COOKBOOK_NAME'" separator "=" spacer 1 } # # Writes a log line to the screen # # If specified, the first parameter is the number of empty lines to print # before the log message. # # If specified, the second parameter is the number of empty lines to print # before the log message. # log () { if [[ $2 -gt 0 ]]; then spacer "$2" fi echo " * $1" if [[ $3 -gt 0 ]]; then spacer "$3" fi } # # Writes an error log line to the screen and exit with an error code. # error () { spacer 2 echo " -> $1" spacer 2 exit 1 } # # Write one or many empty lines to the screen. # spacer () { if [ -n "$1" ]; then local spaces=$1 else local spaces=1 fi for (( i=0; i /dev/null 2>&1; } # # Copy a file from the assets folder to the specified location. # copy () { local cookbook_assets_source="$COOKBOOK_ASSETS_PATH/$1" local default_assets_source="$DEFAULT_ASSETS_PATH/$1" local target="$2" if [ -f "$cookbook_assets_source" ]; then log "Copying $cookbook_assets_source to $target..." cp "$cookbook_assets_source" "$target" elif [ -f "$default_assets_source" ]; then log "Copying $default_assets_source to $target..." cp "$default_assets_source" "$target" else error "Could not find '$1' to copy. Fail!" fi } # # Link a file from the assets folder to the specified location. # link () { local src="$1" local cookbook_assets_source="$COOKBOOK_ASSETS_PATH/$1" local default_assets_source="$DEFAULT_ASSETS_PATH/$1" local target="$2" if [ -f "$src" ]; then src="$src" elif [ -d "$src" ]; then src="$src" elif [ -f "$cookbook_assets_source" ]; then src="$cookbook_assets_source" elif [ -f "$default_assets_source" ]; then src="$default_assets_source" elif [ -d "$cookbook_assets_source" ]; then src="$cookbook_assets_source" elif [ -d "$default_assets_source" ]; then src="$default_assets_source" else error "Could not find '$1' to link Fail!" fi ln -s "$src" "$target" } # # Attempt to link a file if it doesn't already exist # try_link () { local src="$1" local cookbook_assets_source="$COOKBOOK_ASSETS_PATH/$1" local default_assets_source="$DEFAULT_ASSETS_PATH/$1" local target="$2" if [ -f "$src" ]; then src="$src" elif [ -d "$src" ]; then src="$src" elif [ -f "$cookbook_assets_source" ]; then src="$cookbook_assets_source" elif [ -f "$default_assets_source" ]; then src="$default_assets_source" elif [ -d "$cookbook_assets_source" ]; then src="$cookbook_assets_source" elif [ -d "$default_assets_source" ]; then src="$default_assets_source" else error "Could not find '$1' to link Fail!" fi if [ -L "$2" ] && [ "$(readlink "$2")" == "$src" ] ; then log "Link already exists: $2" else log "Creating link: $2 -> $src" link "$1" "$2" fi } # # Add a user to the system. # add_user () { local user=$1 local pass=$2 local args=$3 if id "$user" > /dev/null 2>&1 ; then log "User $user already exists. Skipped creation." else log "Adding user $user..." [ "$pass" == "" ] && pass=generate_password if [[ "$args" != *nohome* ]]; then /usr/sbin/useradd --password "$(openssl passwd -crypt "$pass")" --create-home "$user" --shell /bin/bash else /usr/sbin/useradd --password "$(openssl passwd -crypt "$pass")" "$user" --shell /bin/bash fi fi } # # Generate a random password. # generate_password() { local l=$1 [ "$l" == "" ] && l=8 tr -dc A-Za-z0-9_ < /dev/urandom | head -c ${l} | xargs } # # Run a command as another user # run_as () { local user=$1 local cmd=$2 log "Running command as '$user'..." log "$cmd" # sudo -u $user -H -s /bin/bash -c "$cmd" # sudo -u $user -s /bin/bash -i "$cmd" su -c "$cmd" -s /bin/bash "$user" } # # Add line to a file if line is not already present # add_line () { local line="$1" local file="$2" grep "$line" "$file" > /dev/null 2>&1 # shellcheck disable=2181 if [ $? -ne 0 ]; then log "Adding '$line' to '$file'..." echo "$line" >> "$file" else log "'$line' already in '$file'. Skipping." fi } # # Write a warning if user is not root. # warn_if_not_root () { [ "$(id -u)" = "0" ] || { echo "WARNING: You are NOT running this script as 'root'. You might want to consider that..."; } } # # Stops the execution of the script if user is not root. # fail_if_not_root () { [ "$(id -u)" = "0" ] || { echo "You must run this as 'root'. Exiting."; exit 1; } } # # Checks if a certain element has already been installed. # is_installed () { local args=$* local name=${args//[ \/:@]/-} if [[ -f ~/.shoestrap/installed/$name ]]; then log "'$name' is already installed." return 0 else log "'$name' is not installed." return 1 fi } # # Sets an element as installed. # set_installed () { local args=$* local name=${args//[ \/:@]/-} mkdir -p "$HOME/.shoestrap/installed" touch "$HOME/.shoestrap/installed/$name" } # # Promts a user for a Yn confirmation # prompt_yn () { read -p "$1 [y/n] " -n 1 -r echo # move to a new line if [[ $REPLY =~ ^[Yy]$ ]]; then return 0 fi return 1 }