2020-03-18 12:32:40 +01:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
if [ -v $OSHIPKA_PATH ]; then
|
|
|
|
echo "You need to specify OSHIPKA_PATH env variable"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
echo "oshipka is at: $OSHIPKA_PATH"
|
|
|
|
|
|
|
|
#!/usr/bin/env bash
|
|
|
|
HELP="
|
2020-06-04 16:40:52 +02:00
|
|
|
Usage $0 [ bootstrap | model | db_migrate | db_upgrade | db_populate | db_recreate | db_purge_recreate | init | worker | web | venv | install | link | cert ]
|
2020-03-18 12:32:40 +01:00
|
|
|
|
|
|
|
bootstrap [PROJECT_PATH] Create a new project in PROJECT_PATH
|
2020-05-02 22:28:37 +02:00
|
|
|
init Install dev env
|
2020-06-27 20:32:12 +02:00
|
|
|
download_sensitive Download sensitive
|
2020-05-02 22:28:37 +02:00
|
|
|
|
2020-06-04 16:40:52 +02:00
|
|
|
model Create or update a model from files in webapp/view_models/*.yaml
|
|
|
|
db_migrate DB migration
|
|
|
|
db_upgrade DB upgrade to last migration
|
|
|
|
db_populate Populate db with data from data_static/ and populate.py
|
|
|
|
db_recreate Delete the database, recreate to latest migration and populate
|
|
|
|
db_purge_recreate Same as db_recreate but also purge the migrations
|
|
|
|
|
2020-06-29 11:00:34 +02:00
|
|
|
translate Translations subcommand
|
|
|
|
|
2020-03-19 14:13:58 +01:00
|
|
|
worker Start worker
|
|
|
|
web Start webapp
|
2020-05-02 22:28:37 +02:00
|
|
|
|
2020-03-26 09:17:17 +01:00
|
|
|
venv Init venv
|
|
|
|
install Install requirements
|
2020-04-15 21:13:28 +02:00
|
|
|
link Link dev oshipka
|
|
|
|
|
2020-04-15 21:33:31 +02:00
|
|
|
prod Run in prod
|
2020-06-21 11:17:34 +02:00
|
|
|
prod_install Install in prod
|
2020-04-15 21:13:28 +02:00
|
|
|
cert [DOMAIN] Install certificate
|
2020-03-18 12:32:40 +01:00
|
|
|
"
|
|
|
|
|
2020-06-29 11:00:34 +02:00
|
|
|
HELP_TRANSLATION="
|
|
|
|
USAGE ./manage.sh translate [extract|gen {lang}|compile|update]
|
|
|
|
|
|
|
|
extract Extract strings in files as defined in translations/babel.cfg
|
|
|
|
gen {lang} Init translations for {lang}
|
|
|
|
compile Compile all translations
|
|
|
|
update Use after a new extract - it may mark strings as fuzzy.
|
|
|
|
"
|
|
|
|
|
|
|
|
command_translate() {
|
2020-07-08 14:38:55 +02:00
|
|
|
shift
|
2020-06-29 11:00:34 +02:00
|
|
|
TRANSLATE_COMMAND=$1
|
|
|
|
shift
|
2020-07-08 14:38:55 +02:00
|
|
|
source venv/bin/activate
|
2020-06-29 11:00:34 +02:00
|
|
|
case "$TRANSLATE_COMMAND" in
|
|
|
|
extract) pybabel extract -F translations/babel.cfg -o translations/messages.pot .
|
|
|
|
;;
|
|
|
|
gen) pybabel init -i translations/messages.pot -d translations -l "$@"
|
|
|
|
;;
|
|
|
|
compile) pybabel compile -d translations
|
|
|
|
;;
|
|
|
|
update) pybabel update -i translations/messages.pot -d translations
|
|
|
|
;;
|
|
|
|
*) >&2 echo -e "${HELP_TRANSLATION}"
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
return $?
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-03-19 14:13:58 +01:00
|
|
|
worker () {
|
2020-03-25 16:23:24 +01:00
|
|
|
source venv/bin/activate
|
2020-03-20 12:44:42 +01:00
|
|
|
python worker.py
|
2020-03-19 14:13:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
web () {
|
2020-03-25 16:23:24 +01:00
|
|
|
source venv/bin/activate
|
2020-03-19 14:13:58 +01:00
|
|
|
python run.py
|
|
|
|
}
|
|
|
|
|
2020-03-25 16:23:24 +01:00
|
|
|
init_venv() {
|
|
|
|
virtualenv -p python3 venv
|
|
|
|
}
|
|
|
|
|
|
|
|
install_reqs() {
|
|
|
|
source venv/bin/activate
|
2020-06-21 21:18:50 +02:00
|
|
|
pip3 install --upgrade pip --trusted-host pypi.org --trusted-host files.pythonhosted.org
|
2020-03-25 16:23:24 +01:00
|
|
|
pip install -r requirements.txt
|
|
|
|
}
|
|
|
|
|
2020-04-15 21:13:28 +02:00
|
|
|
link_dev_oshipka() {
|
|
|
|
source venv/bin/activate
|
|
|
|
pip install -e ${OSHIPKA_PATH}
|
2020-05-02 13:40:29 +02:00
|
|
|
pip install -e ${TWW_PATH}
|
2020-04-15 21:13:28 +02:00
|
|
|
}
|
|
|
|
|
2020-06-27 20:32:12 +02:00
|
|
|
download_sensitive() {
|
|
|
|
if [ ! -f sensitive.py ]; then
|
|
|
|
echo "File sensitive.py NOT FOUND"
|
2020-08-11 14:35:25 +02:00
|
|
|
if [ -f sensitive_dev.py ]; then
|
|
|
|
echo "Copying sensitive_dev for dev env"
|
|
|
|
cp sensitive_dev.py sensitive.py
|
|
|
|
else
|
|
|
|
exit 1;
|
|
|
|
fi
|
2020-06-27 20:32:12 +02:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2020-05-02 22:28:37 +02:00
|
|
|
init() {
|
|
|
|
init_venv
|
|
|
|
install_reqs
|
|
|
|
link_dev_oshipka
|
2020-06-27 20:32:12 +02:00
|
|
|
mkdir -p data
|
|
|
|
db_upgrade
|
|
|
|
download_sensitive
|
|
|
|
db_populate
|
2020-05-02 22:28:37 +02:00
|
|
|
}
|
|
|
|
|
2020-04-15 21:13:28 +02:00
|
|
|
install_cert() {
|
|
|
|
PROJECT_DOMAIN=$1
|
|
|
|
sudo apt install certbot
|
2020-06-21 21:36:31 +02:00
|
|
|
sudo certbot certonly --authenticator standalone --installer nginx --pre-hook "service nginx stop" --post-hook "service nginx start" --redirect --agree-tos --no-eff-email --email danieltcv@gmail.com -d ${PROJECT_DOMAIN} --no-bootstrap
|
2020-04-15 21:13:28 +02:00
|
|
|
}
|
|
|
|
|
2020-03-18 12:32:40 +01:00
|
|
|
bootstrap() {
|
|
|
|
shift
|
|
|
|
PROJECT_PATH=$1
|
|
|
|
if [[ -z "$PROJECT_PATH" ]]; then
|
|
|
|
read -p "Enter project path: " PROJECT_PATH
|
|
|
|
fi
|
|
|
|
if [[ -z "$PROJECT_PATH" ]]; then
|
|
|
|
echo "ERROR: Specify project path"
|
|
|
|
exit 1
|
|
|
|
else
|
|
|
|
echo "INFO: Project path: $PROJECT_PATH"
|
|
|
|
PROJECT_PATH=`realpath $PROJECT_PATH`
|
|
|
|
echo "INFO: Absolute project path: $PROJECT_PATH"
|
|
|
|
if [[ "$PROJECT_PATH" == $OSHIPKA_PATH* ]]; then
|
|
|
|
echo "ERROR: Project path can't be inside this directory. Exiting..."
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
if [ -d $PROJECT_PATH ]; then
|
|
|
|
echo "ERROR: Project path exists. Please remove or specify another. Exiting..."
|
|
|
|
exit 1
|
|
|
|
else
|
|
|
|
echo "INFO: Project path doesn't exist, creating..."
|
|
|
|
mkdir -p $PROJECT_PATH
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
PROJECT_NAME=$(basename $PROJECT_PATH)
|
|
|
|
echo "INFO: Bootstrapping project $PROJECT_NAME..."
|
|
|
|
mkdir -p ${PROJECT_PATH}
|
|
|
|
cp -r ${OSHIPKA_PATH}/bootstrap/* ${PROJECT_PATH}/
|
2020-03-25 16:23:24 +01:00
|
|
|
cp ${OSHIPKA_PATH}/bootstrap/.gitignore ${PROJECT_PATH}/.gitignore
|
2020-06-04 22:11:57 +02:00
|
|
|
mkdir ${PROJECT_PATH}/data
|
|
|
|
mkdir ${PROJECT_PATH}/webapp/view_models
|
2020-03-26 09:17:17 +01:00
|
|
|
cd ${PROJECT_PATH}
|
2020-03-25 16:23:24 +01:00
|
|
|
init_venv
|
2020-04-15 21:13:28 +02:00
|
|
|
link_dev_oshipka
|
2020-06-04 15:24:18 +02:00
|
|
|
source venv/bin/activate
|
2021-05-14 23:37:30 +02:00
|
|
|
model
|
2020-06-04 15:24:18 +02:00
|
|
|
python manager.py db init
|
2020-06-04 16:40:52 +02:00
|
|
|
python manager.py db migrate -m "001"
|
|
|
|
_post_migrate
|
2020-06-04 15:24:18 +02:00
|
|
|
python manager.py db upgrade
|
2020-07-08 14:38:55 +02:00
|
|
|
git init .
|
|
|
|
git add .
|
|
|
|
git commit -m "Initial commit"
|
2020-03-18 12:32:40 +01:00
|
|
|
}
|
|
|
|
|
2020-04-15 21:33:31 +02:00
|
|
|
run_in_prod() {
|
|
|
|
shift
|
|
|
|
PORT=$1
|
2020-04-15 21:56:06 +02:00
|
|
|
source venv/bin/activate
|
2020-04-15 21:33:31 +02:00
|
|
|
gunicorn -w 4 -b 0.0.0.0:${PORT} run:app
|
|
|
|
}
|
|
|
|
|
2020-06-21 11:17:34 +02:00
|
|
|
prod_install() {
|
|
|
|
shift
|
2020-06-27 20:32:12 +02:00
|
|
|
if [ ! -f ${OSHIPKA_PATH}/provision/auto_dns/sensitive.py ]; then
|
|
|
|
echo "File ${OSHIPKA_PATH}/provision/auto_dns/sensitive.py NOT FOUND"
|
|
|
|
exit 1;
|
|
|
|
fi
|
|
|
|
sudo apt install -y nginx dnsutils
|
2020-06-21 11:17:34 +02:00
|
|
|
source venv/bin/activate
|
|
|
|
PROJECT_NAME=$(basename `pwd`)
|
2020-06-21 17:45:33 +02:00
|
|
|
echo "1/6 Generating service and config files..."
|
|
|
|
python "${OSHIPKA_PATH}/provision/prod_mgmt.py"
|
2020-06-21 11:17:34 +02:00
|
|
|
if [ -f "/etc/systemd/system/${PROJECT_NAME}.service" ]; then
|
|
|
|
echo "Service gunicorn for ${PROJECT_NAME} service exists."
|
|
|
|
systemctl status ${PROJECT_NAME}
|
|
|
|
else
|
|
|
|
echo "Installing '$PROJECT_NAME' gunicorn service"
|
|
|
|
sudo cp "${OSHIPKA_PATH}/provision/tmp/${PROJECT_NAME}.service" /etc/systemd/system/
|
|
|
|
sudo systemctl enable "${PROJECT_NAME}"
|
|
|
|
sudo systemctl start "${PROJECT_NAME}"
|
|
|
|
fi
|
|
|
|
|
2020-06-21 17:45:33 +02:00
|
|
|
echo "2/6 Installing '$PROJECT_NAME' worker service"
|
2020-06-21 11:17:34 +02:00
|
|
|
if [ -f "/etc/systemd/system/${PROJECT_NAME}_worker.service" ]; then
|
|
|
|
echo "Service worker for ${PROJECT_NAME} service exists."
|
|
|
|
systemctl status "${PROJECT_NAME}_worker"
|
|
|
|
else
|
|
|
|
sudo cp "${OSHIPKA_PATH}/provision/tmp/${PROJECT_NAME}_worker.service" /etc/systemd/system/
|
|
|
|
sudo systemctl enable "${PROJECT_NAME}_worker"
|
|
|
|
sudo systemctl start "${PROJECT_NAME}_worker"
|
|
|
|
fi
|
|
|
|
|
|
|
|
NGINX_CONFIG_FILE=$(basename `find $OSHIPKA_PATH/provision/tmp -name *.conf`)
|
|
|
|
DOMAIN=$(basename -s .conf $NGINX_CONFIG_FILE)
|
2020-06-21 17:45:33 +02:00
|
|
|
echo "3/6 Installing '$DOMAIN' domain..."
|
|
|
|
python "${OSHIPKA_PATH}/provision/auto_dns/set_domain_ipv4.py" "$DOMAIN"
|
|
|
|
|
|
|
|
sudo systemctl start nginx
|
2020-07-01 10:32:06 +02:00
|
|
|
echo "Enabling firewall rule -> 80/tcp..."
|
|
|
|
sudo ufw allow proto tcp to any port 80
|
2020-06-21 17:45:33 +02:00
|
|
|
echo "4/6 Installing '$PROJECT_NAME' insecure nginx config..."
|
2020-06-21 21:18:50 +02:00
|
|
|
if [ -f "/etc/nginx/sites-available/${DOMAIN}.insecure" ]; then
|
2020-06-21 17:45:33 +02:00
|
|
|
echo "Insecure Nginx config for ${PROJECT_NAME} available."
|
2020-06-21 21:18:50 +02:00
|
|
|
if [ -f "/etc/nginx/sites-enabled/${DOMAIN}_insecure" ]; then
|
2020-06-21 17:45:33 +02:00
|
|
|
echo "Nginx config for ${PROJECT_NAME} enabled."
|
|
|
|
else
|
|
|
|
echo "Nginx config for ${PROJECT_NAME} NOT enabled."
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
echo "Installing insecure nginx config for ${PROJECT_NAME} -> enabling + available."
|
2020-06-21 21:18:50 +02:00
|
|
|
sudo cp "${OSHIPKA_PATH}/provision/tmp/${DOMAIN}.insecure" /etc/nginx/sites-available/
|
|
|
|
sudo ln -s "/etc/nginx/sites-available/${DOMAIN}.insecure" "/etc/nginx/sites-enabled/${DOMAIN}.insecure"
|
2020-06-21 17:45:33 +02:00
|
|
|
sudo systemctl reload nginx
|
|
|
|
fi
|
2020-06-21 11:17:34 +02:00
|
|
|
|
2020-06-21 17:45:33 +02:00
|
|
|
echo "5/6 Installing '$PROJECT_NAME' certificate..."
|
2020-06-21 11:17:34 +02:00
|
|
|
install_cert $DOMAIN
|
|
|
|
|
2020-06-21 17:45:33 +02:00
|
|
|
echo "6/6 Installing '$PROJECT_NAME' secure nginx config..."
|
|
|
|
echo "Enabling firewall rule for 192.168.1.1 -> 443/tcp..."
|
2020-07-01 10:32:06 +02:00
|
|
|
sudo ufw allow proto tcp to any port 443
|
2020-06-21 17:45:33 +02:00
|
|
|
echo "Removing '$PROJECT_NAME' insecure nginx config..."
|
2020-06-21 21:36:31 +02:00
|
|
|
sudo rm "/etc/nginx/sites-available/${DOMAIN}.insecure" "/etc/nginx/sites-enabled/${DOMAIN}.insecure"
|
2020-06-27 20:55:31 +02:00
|
|
|
|
|
|
|
# PROBLEM: BIO_new_file("/etc/nginx/dhparam.pem") failed
|
|
|
|
# SOLUTION: sudo openssl dhparam -out /etc/nginx/dhparam.pem 2048
|
|
|
|
if [ ! -f "/etc/nginx/dhparam.pem" ]; then
|
|
|
|
sudo openssl dhparam -out /etc/nginx/dhparam.pem 2048
|
|
|
|
fi
|
|
|
|
|
2020-06-21 11:17:34 +02:00
|
|
|
if [ -f "/etc/nginx/sites-available/${NGINX_CONFIG_FILE}" ]; then
|
|
|
|
echo "Nginx config for ${PROJECT_NAME} available."
|
|
|
|
if [ -f "/etc/nginx/sites-enabled/${NGINX_CONFIG_FILE}" ]; then
|
|
|
|
echo "Nginx config for ${PROJECT_NAME} enabled."
|
|
|
|
else
|
|
|
|
echo "Nginx config for ${PROJECT_NAME} NOT enabled."
|
|
|
|
fi
|
2020-06-21 17:45:33 +02:00
|
|
|
else
|
2020-06-21 11:17:34 +02:00
|
|
|
echo "Installing nginx config for ${PROJECT_NAME} -> enabling + available."
|
2020-06-21 17:45:33 +02:00
|
|
|
sudo cp "${OSHIPKA_PATH}/provision/tmp/${NGINX_CONFIG_FILE}" /etc/nginx/sites-available/
|
2020-06-21 11:17:34 +02:00
|
|
|
sudo ln -s "/etc/nginx/sites-available/${NGINX_CONFIG_FILE}" "/etc/nginx/sites-enabled/${NGINX_CONFIG_FILE}"
|
2020-06-21 17:45:33 +02:00
|
|
|
sudo systemctl reload nginx
|
2020-06-21 11:17:34 +02:00
|
|
|
fi
|
2020-06-21 21:36:31 +02:00
|
|
|
|
|
|
|
# PROBLEM : Certificates missing
|
|
|
|
# SOLUTION: rm /etc/ssl/certs/ca-certificates.crt
|
|
|
|
# sudo update-ca-certificates in virtual environment.
|
2020-06-21 11:17:34 +02:00
|
|
|
}
|
|
|
|
|
2020-06-03 16:00:51 +02:00
|
|
|
model() {
|
|
|
|
shift
|
|
|
|
source venv/bin/activate
|
2020-06-03 18:11:37 +02:00
|
|
|
python "${OSHIPKA_PATH}/vm_gen/vm_gen.py" "`pwd`"
|
2020-06-03 16:00:51 +02:00
|
|
|
}
|
|
|
|
|
2020-06-04 15:24:18 +02:00
|
|
|
db_migrate() {
|
|
|
|
shift
|
|
|
|
source venv/bin/activate
|
2020-06-22 17:20:13 +02:00
|
|
|
next_id=$(printf "%03d" $(($(ls -la migrations/versions/*.py | wc -l)+1)))
|
|
|
|
python manager.py db migrate -m "${next_id}"
|
2020-06-04 15:24:18 +02:00
|
|
|
_post_migrate
|
|
|
|
}
|
|
|
|
|
|
|
|
db_upgrade() {
|
|
|
|
shift
|
|
|
|
source venv/bin/activate
|
2020-07-13 10:38:29 +02:00
|
|
|
mkdir -p data
|
2020-06-04 15:24:18 +02:00
|
|
|
python manager.py db upgrade
|
|
|
|
}
|
|
|
|
|
2020-06-04 16:40:52 +02:00
|
|
|
db_purge_recreate() {
|
|
|
|
shift
|
|
|
|
source venv/bin/activate
|
2021-05-08 14:14:54 +02:00
|
|
|
rm -rf data/db.sqlite data/search_index migrations/ data/media
|
2020-06-04 16:40:52 +02:00
|
|
|
python manager.py db init
|
|
|
|
db_migrate
|
|
|
|
db_upgrade
|
|
|
|
db_populate
|
|
|
|
}
|
|
|
|
|
|
|
|
db_populate() {
|
|
|
|
shift
|
|
|
|
source venv/bin/activate
|
|
|
|
python init_populate.py
|
|
|
|
}
|
|
|
|
|
|
|
|
db_recreate() {
|
|
|
|
shift
|
|
|
|
source venv/bin/activate
|
|
|
|
rm -rf data/db.sqlite data/search_index
|
|
|
|
db_upgrade
|
|
|
|
db_populate
|
|
|
|
}
|
|
|
|
|
2020-06-04 15:24:18 +02:00
|
|
|
_post_migrate() {
|
|
|
|
for i in migrations/versions/*.py; do
|
|
|
|
sed -i "s/sqlalchemy_utils.types.choice.ChoiceType(length=255), /sa.String(), / " "$i";
|
2020-06-04 16:40:52 +02:00
|
|
|
sed -i "s/oshipka.persistance.LiberalBoolean(), /sa.Boolean(), / " "$i";
|
2020-06-04 15:24:18 +02:00
|
|
|
done
|
|
|
|
}
|
|
|
|
|
2020-03-18 12:32:40 +01:00
|
|
|
command_main() {
|
|
|
|
INITIAL_COMMAND=$1
|
|
|
|
case "$INITIAL_COMMAND" in
|
|
|
|
bootstrap) bootstrap "$@"
|
2020-03-19 14:13:58 +01:00
|
|
|
;;
|
2020-06-03 16:00:51 +02:00
|
|
|
model) model "$@"
|
|
|
|
;;
|
2020-06-04 15:24:18 +02:00
|
|
|
db_migrate) db_migrate "$@"
|
|
|
|
;;
|
|
|
|
db_upgrade) db_upgrade "$@"
|
|
|
|
;;
|
2020-06-04 16:40:52 +02:00
|
|
|
db_populate) db_populate "$@"
|
|
|
|
;;
|
|
|
|
db_recreate) db_recreate "$@"
|
|
|
|
;;
|
|
|
|
db_purge_recreate) db_purge_recreate "$@"
|
|
|
|
;;
|
2020-06-29 11:00:34 +02:00
|
|
|
translate) command_translate "$@"
|
|
|
|
;;
|
2020-05-02 22:28:37 +02:00
|
|
|
init) init "$@"
|
|
|
|
;;
|
2020-06-27 20:32:12 +02:00
|
|
|
download_sensitive) download_sensitive "$@"
|
|
|
|
;;
|
2020-03-19 14:13:58 +01:00
|
|
|
worker) worker "$@"
|
|
|
|
;;
|
2020-03-26 09:17:17 +01:00
|
|
|
web) web "$@"
|
|
|
|
;;
|
|
|
|
venv) init_venv "$@"
|
|
|
|
;;
|
|
|
|
install) install_reqs "$@"
|
|
|
|
;;
|
2020-04-15 21:13:28 +02:00
|
|
|
link) link_dev_oshipka "$@"
|
|
|
|
;;
|
2020-04-15 21:33:31 +02:00
|
|
|
prod) run_in_prod "$@"
|
|
|
|
;;
|
2020-06-21 11:17:34 +02:00
|
|
|
prod_install) prod_install "$@"
|
|
|
|
;;
|
2020-06-21 17:45:33 +02:00
|
|
|
cert) shift && install_cert "$@"
|
2020-03-18 12:32:40 +01:00
|
|
|
;;
|
|
|
|
*) >&2 echo -e "${HELP}"
|
|
|
|
return 1
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
return $?
|
|
|
|
}
|
|
|
|
|
2020-03-26 09:17:17 +01:00
|
|
|
command_main "$@"
|