Newer
Older
#!/bin/bash
#
# .---. . .
# | | |
# |--- .--. .-. .-. .-.| .-. .--.--. |.-. .-. .--. .-.
# | | (.-' (.-' ( | ( )| | | | )( )| | (.-'
# ' ' --' --' -' - -' ' ' -' -' -' ' - --'
#
# Freedom in the Cloud
#
# Functions for selecting which apps to install or remove
#
# License
# =======
#
# Copyright (C) 2015-2016 Bob Mottram <bob@freedombone.net>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Array containing names of available apps
APPS_AVAILABLE=()
# Array containing 1 or 0 indicating installed apps
APPS_INSTALLED=()
# Apps selected with checklist
APPS_CHOSEN=()
# A list of the names of installed apps
APPS_INSTALLED_NAMES=()
# file containing a list of removed apps
REMOVED_APPS_FILE=/root/removed
INSTALLED_APPS_LIST=/usr/share/${PROJECT_NAME}/installed.txt
Bob Mottram
committed
# keep a list of which users have been added to which apps
# so that when a new app is added existing users can be added
APP_USERS_FILE=$HOME/app_users.txt
if [ ! $COMPLETION_FILE ]; then
COMPLETION_FILE=$HOME/${PROJECT_NAME}-completed.txt
fi
# Loads variables defined at the beginning of an app script
function app_load_variables {
app_name=$1
config_var_name=${app_name}_variables
if [ ! ${!config_var_name} ]; then
configvarname=$config_var_name[@]
configvarname=( ${!configvarname} )
do
read_config_param $v
done
}
# Saves variables for a given app script
function app_save_variables {
app_name=$1
config_var_name=${app_name}_variables
if [ ! ${!config_var_name} ]; then
configvarname=$config_var_name[@]
configvarname=( ${!configvarname} )
variants_line=$(cat ${filename} | grep 'VARIANTS=')
if [[ "$variants_line" == *"'"* ]]; then
variants_list=$(echo "$variants_line" | awk -F '=' '{print $2}' | awk -F "'" '{print $2}')
else
variants_list=$(echo "$variants_line" | awk -F '=' '{print $2}' | awk -F '"' '{print $2}')
fi
echo "$variants_list"
}
local e
for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done
return 1
# returns a list of available system variants
# based upon the variants string in each app script
function available_system_variants {
system_variants_list=$(app_variants $filename)
variants_array=($system_variants_list)
for variant_str in "${variants_array[@]}"
item_in_array "${variant_str}" "${new_available_variants_list[@]}"
available_variants_list=($(sort <<<"${new_available_variants_list[*]}"))
function is_valid_variant {
sys_type="$1"
available_variants_list=()
available_system_variants
for variant_str in "${available_variants_list[@]}"
do
if [[ "$sys_type" == "$variant_str" ]]; then
return "1"
fi
done
return "0"
}
function show_available_variants {
available_variants_list=()
available_system_variants
for variant_str in "${available_variants_list[@]}"
do
echo " $variant_str"
done
}
# mark a given app as having been removed so that it doesn't get reinstalled on updates
function remove_app {
app_name=$1
if [ ! -f $REMOVED_APPS_FILE ]; then
touch $REMOVED_APPS_FILE
fi
if ! grep -Fxq "_${app_name}_" $REMOVED_APPS_FILE; then
echo "_${app_name}_" >> $REMOVED_APPS_FILE
if grep -Fxq "install_${app_name}" $COMPLETION_FILE; then
sed -i "/install_${app_name}/d" $COMPLETION_FILE
fi
if grep -Fxq "install_${app_name}" $INSTALLED_APPS_LIST; then
sed -i "/install_${app_name}/d" $INSTALLED_APPS_LIST
fi
function app_is_removed {
app_name="$1"
if [ ! -f $REMOVED_APPS_FILE ]; then
echo "0"
return
fi
echo "0"
else
echo "1"
fi
}
# Allows an app to be reinstalled even if it was previously marked as being removed
function reinstall_app {
app_name=$1
if [ ! -f $REMOVED_APPS_FILE ]; then
return
fi
if [[ $(app_is_removed $app_name) == "1" ]]; then
# Why does this secondary file exist, apart from COMPLETION_FILE ?
# It's so that it is visible to unprivileged users from the user control panel
if [ -f $INSTALLED_APPS_LIST ]; then
if ! grep -Fxq "install_${app_name}" $INSTALLED_APPS_LIST; then
echo "0"
else
echo "1"
fi
return
fi
if [ ! -f $COMPLETION_FILE ]; then
echo "0"
return
fi
if ! grep -Fxq "install_${app_name}" $COMPLETION_FILE; then
echo "0"
else
echo "1"
fi
function install_completed {
if [ ! ${1} ]; then
exit 673935
fi
if ! grep -Fxq "install_${1}" $COMPLETION_FILE; then
echo "install_${1}" >> $COMPLETION_FILE
fi
# populates an array of "0" or "1" for whether apps are installed
for a in "${APPS_AVAILABLE[@]}"
do
APPS_INSTALLED+=("$(app_is_installed $a)")
done
APPS_INSTALLED_NAMES=()
for a in "${APPS_AVAILABLE[@]}"
do
if [[ $(app_is_installed $a) == "1" ]]; then
APPS_INSTALLED_NAMES+=("$a")
fi
done
FILES=/usr/share/${PROJECT_NAME}/apps/${PROJECT_NAME}-app-*
APPS_AVAILABLE=()
APPS_CHOSEN=()
# for all the app scripts
for filename in $FILES
do
app_name=$(echo "${filename}" | awk -F '-app-' '{print $2}')
item_in_array "${app_name}" "${APPS_AVAILABLE[@]}"
if [[ $? != 0 ]]; then
APPS_AVAILABLE+=("${app_name}")
APPS_CHOSEN+=("0")
fi
done
function_check get_apps_installed
get_apps_installed
get_apps_installed_names
# detects what apps are available and can be installed
# If the variants list within an app script is an empty string then
# it is considered to be too experimental to be installable
function detect_installable_apps {
FILES=/usr/share/${PROJECT_NAME}/apps/${PROJECT_NAME}-app-*
APPS_AVAILABLE=()
APPS_CHOSEN=()
APPS_INSTALLED=()
APPS_INSTALLED_NAMES=()
# for all the app scripts
for filename in $FILES
do
app_name=$(echo "${filename}" | awk -F '-app-' '{print $2}')
item_in_array "${app_name}" "${APPS_AVAILABLE[@]}"
if [[ $? != 0 ]]; then
if [ ${#variants_list} -gt 0 ]; then
APPS_AVAILABLE+=("${app_name}")
APPS_CHOSEN+=("0")
APPS_INSTALLED+=("$(app_is_installed $app_name)")
if [[ $(app_is_installed $app_name) == "1" ]]; then
APPS_INSTALLED_NAMES+=("$app_name")
fi
fi
fi
done
}
function detect_installed_apps {
FILES=/usr/share/${PROJECT_NAME}/apps/${PROJECT_NAME}-app-*
APPS_AVAILABLE=()
APPS_INSTALLED=()
APPS_INSTALLED_NAMES=()
function_check app_variants
function_check app_is_installed
function_check item_in_array
# for all the app scripts
for filename in $FILES
do
app_name=$(echo "${filename}" | awk -F '-app-' '{print $2}')
item_in_array "${app_name}" "${APPS_AVAILABLE[@]}"
if [[ $? != 0 ]]; then
variants_list=$(app_variants $filename)
if [ ${#variants_list} -gt 0 ]; then
APPS_AVAILABLE+=("${app_name}")
APPS_INSTALLED_NAMES+=("$app_name")
fi
fi
fi
done
}
# creates the APPS_AVAILABLE and APPS_CHOSEN arrays based on
# the given variant name
function choose_apps_for_variant {
function_check item_in_array
function_check app_variants
function_check app_is_removed
if [ ${#variant_name} -eq 0 ]; then
echo $"No variant name for choosing apps"
exit 237567
fi
FILES=/usr/share/${PROJECT_NAME}/apps/${PROJECT_NAME}-app-*
APPS_CHOSEN=()
# for all the app scripts
for filename in $FILES
do
app_name=$(echo "${filename}" | awk -F '-app-' '{print $2}')
item_in_array "${app_name}" "${APPS_AVAILABLE[@]}"
"${variants_list}" == "$variant_name "* || \
"${variants_list}" == *" $variant_name "* || \
"${variants_list}" == *" $variant_name" ]]; then
else
APPS_CHOSEN+=("0")
fi
else
APPS_CHOSEN+=("0")
fi
fi
done
function_check get_apps_installed
get_apps_installed
app_index=0
for a in "${APPS_AVAILABLE[@]}"
do
if [[ ${APPS_CHOSEN[$app_index]} == "1" ]]; then
echo $"${a}"
fi
app_index=$[app_index+1]
done
app_index=0
for a in "${APPS_AVAILABLE[@]}"
do
if [[ ${APPS_INSTALLED[$app_index]} == "1" ]]; then
if [[ ${APPS_CHOSEN[$app_index]} == "0" ]]; then
Bob Mottram
committed
echo $"Removing users for application: ${a}"
function_check remove_users_for_app
remove_users_for_app ${a}
remove_app ${a}
echo $"${a} was removed"
fi
fi
app_index=$[app_index+1]
done
function install_apps_interactive {
echo $"Interactive installer"
app_index=0
for a in "${APPS_AVAILABLE[@]}"
do
if [[ ${APPS_INSTALLED[$app_index]} == "0" ]]; then
if [[ ${APPS_CHOSEN[$app_index]} == "1" ]]; then
# interactively obtain settings for this app
if [[ $(function_exists install_interactive_${a}) == "1" ]]; then
install_interactive_${a}
fi
fi
fi
app_index=$[app_index+1]
done
echo $"Interactive settings complete"
}
Bob Mottram
committed
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
function user_added_to_app {
user_name="$1"
app_name="$2"
if [[ $(is_valid_user "$user_name") == "1" ]]; then
if [[ $(function_exists add_user_${app_name}) == "1" ]]; then
if grep -Fxq "${app_name}_${user_name}" $APP_USERS_FILE; then
echo "1"
return
fi
fi
fi
echo "0"
}
function add_users_after_install {
app_name="$1"
read_config_param MY_USERNAME
# ensure a minimum password length
if [ ! $MINIMUM_PASSWORD_LENGTH ]; then
MINIMUM_PASSWORD_LENGTH=20
fi
if [ ${#MINIMUM_PASSWORD_LENGTH} -lt 20 ]; then
MINIMUM_PASSWORD_LENGTH=20
fi
ADMIN_USERNAME=$(get_completion_param "Admin user")
if [ ! $ADMIN_USERNAME ]; then
ADMIN_USERNAME=$MY_USERNAME
fi
for d in /home/*/ ; do
USERNAME=$(echo "$d" | awk -F '/' '{print $3}')
if [[ $(is_valid_user "$USERNAME") == "1" ]]; then
if [[ "$USERNAME" != "$ADMIN_USERNAME" ]]; then
if [[ $(user_added_to_app "${USERNAME}" "${app_name}") == "0" ]]; then
valstr=$"Login for user ${USERNAME}="
app_password="$(create_password ${MINIMUM_PASSWORD_LENGTH})"
add_user_${app_name} "${USERNAME}" "${app_password}"
echo "${app_name}_${USERNAME}" >> $APP_USERS_FILE
Bob Mottram
committed
fi
fi
fi
done
}
function remove_users_for_app {
app_name="$1"
read_config_param MY_USERNAME
for d in /home/*/ ; do
USERNAME=$(echo "$d" | awk -F '/' '{print $3}')
if [[ $(is_valid_user "$USERNAME") == "1" ]]; then
if [[ "$USERNAME" != "$MY_USERNAME" ]]; then
if [[ $(user_added_to_app "${USERNAME}" "${app_name}") == "1" ]]; then
if [[ $(function_exists remove_user_${app_name}) == "1" ]]; then
remove_user_${app_name} "${USERNAME}"
fi
sed -i "/${app_name}_${USERNAME}/d" $APP_USERS_FILE
Bob Mottram
committed
fi
fi
fi
done
}
APP_INSTALLED_SUCCESS=1
# interactive install configuration for each app
if [ ${is_interactive} ]; then
install_apps_interactive
app_index=0
for a in "${APPS_AVAILABLE[@]}"
do
if [[ ${APPS_CHOSEN[$app_index]} == "1" ]]; then
if [ ${is_interactive} ]; then
reinstall_app ${a}
if [[ $(app_is_installed ${a}) == "1" ]]; then
echo $"Upgrading application from interactive: ${a}"
upgrade_${a}
echo $"${a} was upgraded from interactive"
else
echo $"Installing application from interactive: ${a}"
Bob Mottram
committed
function_check add_users_after_install
add_users_after_install ${a}
${PROJECT_NAME}-mirrors --app ${a}
function_check lockdown_permissions
lockdown_permissions
install_completed ${a}
echo $"${a} was installed from interactive"
else
echo "Failed to install: ${a}" >> /var/log/${PROJECT_NAME}.log
APP_INSTALLED_SUCCESS=
echo $"${a} was not installed from interactive"
fi
if [[ $(app_is_removed ${a}) == "0" ]]; then
if [[ $(app_is_installed ${a}) == "1" ]]; then
echo $"Upgrading application: ${a}"
upgrade_${a}
echo $"${a} was upgraded"
else
echo $"Installing application: ${a}"
Bob Mottram
committed
function_check add_users_after_install
add_users_after_install ${a}
function_check lockdown_permissions
lockdown_permissions
${PROJECT_NAME}-mirrors --app ${a}
install_completed ${a}
echo $"${a} was installed"
else
echo "Failed to install: ${a}" >> /var/log/${PROJECT_NAME}.log
APP_INSTALLED_SUCCESS=
echo $"${a} was not installed"
fi
else
echo $"${a} has been removed and so will not be reinstalled"
fi
fi