Initial commit
This commit is contained in:
commit
5a1bf22e0b
15 changed files with 1604 additions and 0 deletions
46
factory/lib/00_init.sh
Normal file
46
factory/lib/00_init.sh
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# This is a library file.
|
||||
# It should be 'source'd only, if it is not we bail out here.
|
||||
if [[ "$0" = "$BASH_SOURCE" ]]; then
|
||||
echo "This file should not be executed directly, it should be 'source'd only. "
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
# Check that we are running on a linux system, to prevent accidentally running on Windows or Mac.
|
||||
# Ideally we would want to explicitly limit to Debian / Ubuntu but at this point that's not needed.
|
||||
OS="$(uname -s)"
|
||||
case "${OS}" in
|
||||
Linux*) :;;
|
||||
*) echo "This script must be run under Linux. "; exit 1;;
|
||||
esac
|
||||
|
||||
# To prevent accidentally messing up permissions, we need to always run as root.
|
||||
# Check that the uid is 0, and otherwise bail out.
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "This script should be run as root, use 'sudo' if in doubt. "
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
# We enable shell aliases, to allow us to setup utility functions much more easily.
|
||||
# To be safe that we don't have any other ones in the environment, we first unalias everything.
|
||||
unalias -a
|
||||
shopt -s expand_aliases
|
||||
|
||||
# Setup some basic input/output functions
|
||||
function log_info() {
|
||||
echo -e "\033[1m$1\033[0m"
|
||||
}
|
||||
|
||||
function log_ok() {
|
||||
echo -e "\033[0;32m$1\033[0m"
|
||||
}
|
||||
|
||||
function log_warn() {
|
||||
echo -e "\033[1;33m$1\033[0m"
|
||||
}
|
||||
|
||||
function log_error() {
|
||||
echo -e "\033[0;31m$1\033[0m"
|
||||
}
|
||||
128
factory/lib/10_config.sh
Normal file
128
factory/lib/10_config.sh
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# This is a library file.
|
||||
# It should be 'source'd only, if it is not we bail out here.
|
||||
if [[ "$0" = "$BASH_SOURCE" ]]; then
|
||||
echo "This file should not be executed directly, it should be 'source'd only. "
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
# The Path to the configuration file.
|
||||
CONFIG_FILE="$SCRIPT_DIR/.env"
|
||||
|
||||
# Check that the configuration file exists.
|
||||
# If it does not, throw an error
|
||||
log_info " => Reading configuration file"
|
||||
if ! [ -f "$CONFIG_FILE" ]; then
|
||||
log_error ""
|
||||
log_error "Missing configuration, provide a '.env' file"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 'source' in the configuration file.
|
||||
# Ideally we would want to make sure to prevent code-executation within the .env file
|
||||
# But for the moment let's not.
|
||||
source "$CONFIG_FILE"
|
||||
|
||||
# Next, validate all the configuration settings.
|
||||
|
||||
# is_valid_slug checks if it's argument is a valid 'slug'.
|
||||
# A slug is any non-empty string of alphanumeric characters or '-'s.
|
||||
# The first character of a slug may not be a dash.
|
||||
function is_valid_slug() {
|
||||
if [[ "$1" =~ ^[a-zA-Z0-9][-a-zA-Z0-9]*$ ]]; then
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
fi;
|
||||
}
|
||||
|
||||
# is_valid_abspath checks if it's argument is an absolute path.
|
||||
function is_valid_abspath() {
|
||||
if [[ "$1" =~ ^\/(.+)\/([^/]+)$ ]]; then
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
fi;
|
||||
}
|
||||
|
||||
# 'is_valid_domain' checks if a number is a valid domain.
|
||||
# A domain consists of at least one slug, seperated by '.'s.
|
||||
# Each token is a slug.
|
||||
function is_valid_domain() {
|
||||
if [[ "$1" =~ ^([a-zA-Z0-9][-a-zA-Z0-9]*\.)*[a-zA-Z0-9][-a-zA-Z0-9]*$ ]]; then
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
fi;
|
||||
}
|
||||
|
||||
# 'is_valid_number' checks if a value is a valid number.
|
||||
function is_valid_number() {
|
||||
if [[ "$1" =~ ^[1-9][0-9]*$ ]]; then
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
fi;
|
||||
}
|
||||
|
||||
# The 'DRUPAL_ROOT' variable must be an absolute path.
|
||||
if ! is_valid_abspath "$DRUPAL_ROOT"; then
|
||||
log_error "Variable 'DRUPAL_ROOT' is missing or not a valid path. ";
|
||||
log_info "Please verify that it is set correctly in '.env'. ";
|
||||
log_info "Please ensure that it does not end in '/'. ";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
# The 'SYSTEM_USER_PREFIX' variable must be a valid slug.
|
||||
if ! is_valid_slug "$SYSTEM_USER_PREFIX"; then
|
||||
log_error "Variable 'SYSTEM_USER_PREFIX' is missing or not a valid slug. ";
|
||||
log_info "Please verify that it is set correctly in '.env'. ";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
# The 'MYSQL_USER_PREFIX' variable must be a valid slug.
|
||||
if ! is_valid_slug "$MYSQL_USER_PREFIX"; then
|
||||
log_error "Variable 'MYSQL_USER_PREFIX' is missing or not a valid slug. ";
|
||||
log_info "Please verify that it is set correctly in '.env'. ";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
# The 'MYSQL_DATABASE_PREFIX' variable must be a valid slug.
|
||||
if ! is_valid_slug "$MYSQL_DATABASE_PREFIX"; then
|
||||
log_error "Variable 'MYSQL_DATABASE_PREFIX' is missing or not a valid slug. ";
|
||||
log_info "Please verify that it is set correctly in '.env'. ";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
# The 'GRAPHDB_USER_PREFIX' variable must be a valid slug.
|
||||
if ! is_valid_slug "$GRAPHDB_USER_PREFIX"; then
|
||||
log_error "Variable 'DATABASE_PREFIX' is missing or not a valid slug. ";
|
||||
log_info "Please verify that it is set correctly in '.env'. ";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
# The 'GRAPHDB_REPO_PREFIX' variable must be a valid slug.
|
||||
if ! is_valid_slug "$GRAPHDB_REPO_PREFIX"; then
|
||||
log_error "Variable 'GRAPHDB_REPO_PREFIX' is missing or not a valid slug. ";
|
||||
log_info "Please verify that it is set correctly in '.env'. ";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
|
||||
# The 'DOMAIN' variable must be a valid domain.
|
||||
if ! is_valid_domain "$DEFAULT_DOMAIN"; then
|
||||
log_error "Variable 'DEFAULT_DOMAIN' is missing or not a valid domain. ";
|
||||
log_info "Please verify that it is set correctly in '.env'. ";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
# The 'PASSWORD_LENGTH' variable must be a valid number.
|
||||
if ! is_valid_number "$PASSWORD_LENGTH"; then
|
||||
log_error "Variable 'PASSWORD_LENGTH' is missing or not a valid number. ";
|
||||
log_info "Please verify that it is set correctly in '.env'. ";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
log_ok "Read and validated configuration file. "
|
||||
78
factory/lib/20_slug.sh
Normal file
78
factory/lib/20_slug.sh
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# This is a library file.
|
||||
# It should be 'source'd only, if it is not we bail out here.
|
||||
if [[ "$0" = "$BASH_SOURCE" ]]; then
|
||||
echo "This file should not be executed directly, it should be 'source'd only. "
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
# This file reads a single slug command line option.
|
||||
# This is validated when 'require_slug_argument' is called.
|
||||
|
||||
function require_slug_argument() {
|
||||
# The 'SLUG' argument must be a valid slug.
|
||||
if ! is_valid_slug "$SLUG"; then
|
||||
log_error "Argument 'SLUG' is missing or not a valid slug. ";
|
||||
log_info "Please provide it via the command line. ";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
log_info " => Deriving configuration for '$SLUG'. "
|
||||
echo "Domain Name: $INSTANCE_DOMAIN"
|
||||
echo "Base Directory: $BASE_DIR"
|
||||
echo "System User: $SYSTEM_USER"
|
||||
echo "MySQL User: $MYSQL_USER"
|
||||
echo "MySQL Database: $MYSQL_DATABASE"
|
||||
echo "GraphDB User: $GRAPHDB_USER"
|
||||
echo "GraphDB Repository: $GRAPHDB_REPO"
|
||||
}
|
||||
|
||||
# Read the slug argument.
|
||||
# We also read it in for scripts where it is not required, and will only use it if that is the case.
|
||||
SLUG="$1"
|
||||
|
||||
# Compute the domain name for this instance.
|
||||
# Also lowercase the domain name for consistency.
|
||||
INSTANCE_DOMAIN="$SLUG.$DEFAULT_DOMAIN"
|
||||
INSTANCE_DOMAIN="$(echo "$INSTANCE_DOMAIN" | tr '[:upper:]' '[:lower:]')"
|
||||
|
||||
# Next we need a username base.
|
||||
# This will be used as a username across the system (linux), MySQL and GraphDB.
|
||||
# For this we can only allow [0-9a-zA-Z-], hence we have to escape.
|
||||
# In most cases, the only characters that require escaping are '.'s.
|
||||
# Hence we replace '.' with '-'s.
|
||||
# We replace the other two characters that require escaping (_ and -)s with --u and --s respectively.
|
||||
# Because no two dots can ever follow each other in the INSTANCE_DOMAIN, this is guaranteed collision free.
|
||||
# We also have to do the '-' replacement first, to prevent escaped other characters from being escaped twice.
|
||||
USERNAME_BASE="$SLUG"
|
||||
USERNAME_BASE="${USERNAME_BASE//-/--d}"
|
||||
USERNAME_BASE="${USERNAME_BASE//_/--u}"
|
||||
USERNAME_BASE="${USERNAME_BASE//./-}"
|
||||
|
||||
# Generate the user and database names for the various systems
|
||||
SYSTEM_USER="${SYSTEM_USER_PREFIX}${USERNAME_BASE}"
|
||||
MYSQL_USER="${MYSQL_USER_PREFIX}${USERNAME_BASE}"
|
||||
MYSQL_DATABASE="${MYSQL_DATABASE_PREFIX}${USERNAME_BASE}"
|
||||
GRAPHDB_USER="${GRAPHDB_USER_PREFIX}${USERNAME_BASE}"
|
||||
GRAPHDB_REPO="${GRAPHDB_REPO_PREFIX}${USERNAME_BASE}"
|
||||
|
||||
# Compute the base directory for the files that will live on disk.
|
||||
BASE_DIR="$DRUPAL_ROOT/$INSTANCE_DOMAIN"
|
||||
COMPOSER_DIR="$BASE_DIR/project"
|
||||
WEB_DIR="$COMPOSER_DIR/web"
|
||||
|
||||
# Setup aliases for drush and composer.
|
||||
alias composer="sudo -u $SYSTEM_USER /usr/local/bin/composer"
|
||||
alias drush="sudo -u $SYSTEM_USER $COMPOSER_DIR/vendor/bin/drush"
|
||||
|
||||
# Because of a bug in Drupal we constantly have to reset the permissions of the site directory.
|
||||
# See https://www.drupal.org/project/drupal/issues/3091285.
|
||||
function drupal_sites_permission_workaround() {
|
||||
chmod -R u+w "$WEB_DIR/sites/"
|
||||
}
|
||||
|
||||
# Apache configuration paths
|
||||
APACHE_CONFIG_SITE_AVAILABLE="/etc/apache2/sites-available/${INSTANCE_DOMAIN}.conf"
|
||||
APACHE_CONFIG_SITE_ENABLED="/etc/apache2/sites-enabled/${INSTANCE_DOMAIN}.conf"
|
||||
16
factory/lib/30_utils.sh
Normal file
16
factory/lib/30_utils.sh
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# This is a library file.
|
||||
# It should be 'source'd only, if it is not we bail out here.
|
||||
if [[ "$0" = "$BASH_SOURCE" ]]; then
|
||||
echo "This file should not be executed directly, it should be 'source'd only. "
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
# Set a few variables to point to the debian frontend
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# This file just sets a few utility functions to be used by the code.
|
||||
# randompw generates a random password as per the configuration file.
|
||||
alias randompw="cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $PASSWORD_LENGTH | head -n 1"
|
||||
20
factory/lib/lib.sh
Normal file
20
factory/lib/lib.sh
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# This file will load all the library functions needed by the various scripts.
|
||||
# It should be 'source'd only, if it is not we bail out here.
|
||||
if [[ "$0" = "$BASH_SOURCE" ]]; then
|
||||
echo "This file should not be executed directly, it should be 'source'd only. "
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
# Set variables for the script_dir and the lib_dir
|
||||
SCRIPT_DIR="$(pwd)"
|
||||
LIB_DIR="$SCRIPT_DIR/lib"
|
||||
|
||||
# Next, we load a bunch of utility functions stored in lib/lib_<number>_<system>.sh
|
||||
# These contain functionality used in the various scripts.
|
||||
source "$LIB_DIR/00_init.sh";
|
||||
source "$LIB_DIR/10_config.sh";
|
||||
source "$LIB_DIR/20_slug.sh";
|
||||
source "$LIB_DIR/30_utils.sh";
|
||||
Loading…
Add table
Add a link
Reference in a new issue