From cb33f0c521a1bd39536db7b5d8ac976c06dfe800 Mon Sep 17 00:00:00 2001 From: Marc Aymerich Date: Fri, 2 Oct 2015 17:17:56 +0000 Subject: [PATCH] Fixes on deployment --- .../project_template/project_name/settings.py | 1 + requirements.txt | 2 +- scripts/containers/deploy.sh | 258 +++++++++++++----- 3 files changed, 197 insertions(+), 64 deletions(-) diff --git a/orchestra/conf/project_template/project_name/settings.py b/orchestra/conf/project_template/project_name/settings.py index 7c6e0a36..b8669175 100644 --- a/orchestra/conf/project_template/project_name/settings.py +++ b/orchestra/conf/project_template/project_name/settings.py @@ -80,6 +80,7 @@ INSTALLED_APPS = [ # Last to load 'orchestra.contrib.resources', 'orchestra.contrib.settings', +# 'django_nose', ] diff --git a/requirements.txt b/requirements.txt index a05b140b..e159518a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ django==1.8.2 django-celery-email==1.0.4 django-fluent-dashboard==0.5 -https://github.com/glic3rinu/django-admin-tools/archive/master.zip +django-admin-tools==0.6.0 django-extensions==1.5.2 django-transaction-signals==1.0.0 django-celery==3.1.16 diff --git a/scripts/containers/deploy.sh b/scripts/containers/deploy.sh index af852089..8e8f35ef 100644 --- a/scripts/containers/deploy.sh +++ b/scripts/containers/deploy.sh @@ -12,20 +12,16 @@ normal=$(tput -T ${TERM:-xterm} sgr0) function test_orchestra () { user=$1 - + ip_addr=$2 # Test if serving requests - ip_addr=$(ip addr show eth0 | grep 'inet ' | sed -r "s/.*inet ([^\s]*).*/\1/" | cut -d'/' -f1) - if [[ $ip_addr == '' ]]; then - ip_addr=127.0.0.1 - fi echo echo ${bold} echo "> Checking if Orchestra is serving on https://${ip_addr}/admin/ ..." if [[ $noinput == '--noinput' ]]; then - echo -e " - username: $user" - echo -e " - password: orchestra${normal}" + echo " - username: $user" + echo " - password: orchestra${normal}" fi - + echo if [[ $(curl -s -L -k -c /tmp/cookies.txt -b /tmp/cookies.txt https://$ip_addr/admin/ | grep 'Panel Hosting Management') ]]; then token=$(grep csrftoken /tmp/cookies.txt | awk {'print $7'}) if [[ $(curl -s -L -k -c /tmp/cookies.txt -b /tmp/cookies.txt \ @@ -43,45 +39,181 @@ function test_orchestra () { } -function main () { - noinput='' - user=$USER - if [[ $# -eq 2 ]]; then - if [[ $1 != '--noinput' ]]; then - echo -e "\nErr. What argument is $1?\n" >&2 - exit 2 - elif ! id $2; then - echo -e "\nErr. User $2 does not exist\n" >&2 - exit 3 +function install_orchestra () { + dev=$1 + home=$2 + repo=$3 + + if [[ $dev -eq 1 ]]; then + # Install from source + python_path=$(python3 -c "import sys; print([path for path in sys.path if path.startswith('/usr/local/lib/python')][0]);") + if [[ -d $python_path/orchestra ]]; then + run sudo rm -fr $python_path/orchestra fi - [ $(whoami) != 'root' ] && { - echo -e "\nErr. --noinput should run as root\n" >&2 - exit 1 - } - noinput='--noinput' - run () { echo " ${bold}\$ ${@}${normal}"; ${@}; } - surun () { echo " ${bold}\$ su $user -c \"${@}\"${normal}"; su $user -c "${@}"; } - user=$2 - elif [[ $# -eq 1 ]]; then - if [[ $1 != '--noinput' ]]; then - echo -e "\nErr. What argument is $1?\n" >&2 - else - echo -e "\nErr. --noinput should provide a username\n" >&2 + orch_version=$(python3 -c "from orchestra import get_version; print(get_version());" 2> /dev/null || false) || true + if [[ ! $orch_version ]]; then + # First Orchestra installation + run sudo apt-get -y install git python3-pip + surun "git clone $repo $home/django-orchestra" || { + # Finishing partial installation + surun "export GIT_DIR=$home/django-orchestra/.git; git pull" + } + echo $home/django-orchestra/ | sudo tee "$python_path/orchestra.pth" fi - exit 1 + if [[ -L /usr/local/bin/orchestra-admin || -f /usr/local/bin/orchestra-admin ]]; then + run sudo rm -f /usr/local/bin/{orchestra-admin,orchestra-beat} + fi + run sudo ln -s $home/django-orchestra/orchestra/bin/orchestra-admin /usr/local/bin/ + run sudo ln -s $home/django-orchestra/orchestra/bin/orchestra-beat /usr/local/bin/ + run sudo orchestra-admin install_requirements --testing else - [ $(whoami) == 'root' ] && { - echo -e "\nErr. This script should run as a regular user\n" >&2 - exit 1 - } + # Install from pip + run sudo pip3 install django-orchestra==dev \ + --allow-external django-orchestra \ + --allow-unverified django-orchestra + run sudo orchestra-admin install_requirements + fi +} + + +function setup_database () { + dev=$1 + noinput=$2 + # Setup Database + if [[ $dev -eq 1 ]]; then + # Speeding up tests, don't do this in production! + . /usr/share/postgresql-common/init.d-functions + pg_version=$(psql --version | head -n1 | sed -r "s/^.*\s([0-9]+\.[0-9]+).*/\1/") + sudo sed -i \ + -e "s/^#fsync =\s*.*/fsync = off/" \ + -e "s/^#full_page_writes =\s*.*/full_page_writes = off/" \ + /etc/postgresql/${pg_version}/main/postgresql.conf + fi + run sudo service postgresql start + if [[ $noinput == '--noinput' ]]; then + db_password=$(ps aux | sha256sum | base64 | head -c 10) + run sudo python3 -W ignore manage.py setuppostgres --noinput --db_password $db_password + else + run sudo python3 -W ignore manage.py setuppostgres + fi + if [[ $dev -eq 1 ]]; then + # Create database permissions are needed for running tests + sudo su postgres -c 'psql -c "ALTER USER orchestra CREATEDB;"' + fi + surun "python3 -W ignore manage.py migrate $noinput" +} + + +function create_orchestra_superuser () { + user=$1 + email=$2 + password=$3 + cat <<- EOF | surun "python3 -W ignore manage.py shell" + from orchestra.contrib.accounts.models import Account + if not Account.objects.filter(username="$user").exists(): + print('Creating orchestra superuser') + Account.objects.create_superuser("$user", "$email", "$password") + + EOF +} + + +print_help () { + cat <<- EOF + + ${bold}NAME${normal} + ${bold}deploy.sh${normal} - Deploy a django-orchestra project + + ${bold}SYNOPSIS${normal} + ${bold}deploy.sh${normal} [--noinput=USERNAME] [--dev] [--repo=GITREPO] [--projectname=NAME] + + ${bold}OPTIONS${normal} + ${bold}-n, --noinput=USERNAME${normal} + Execute the script without any user input, an existing system USERNAME is required. + requires the script to be executed as root user + + ${bold}-d, --dev${normal} + Perform a deployment suitable for development: + 1. debug mode + 2. dependencies for running tests + 3. access to source code + + ${bold}-r, --repo=GITREPO${normal} + Chose which repo use for development deployment + this option requires --dev option to be selected + https://github.com/glic3rinu/django-orchestra.git is used by default + + ${bold}-p, --projectname=NAME${normal} + Specify a project name, this will be asked on interactive mode + and name 'panel' will be used otherwise. + + ${bold}-h, --help${normal} + Display this message + + ${bold}EXAMPLES${normal} + deploy.sh + + deploy.sh --dev + + deploy.sh --dev --noinput orchestra + + EOF +} + + +function main () { + # Input validation + opts=$(getopt -o n:dr:h -l noinput:,dev,repo:,help -- "$@") || exit 1 + set -- $opts + + dev=0 + noinput='' + user=${USER:-root} + repo='https://github.com/glic3rinu/django-orchestra.git' + brepo=false + project_name="panel" + bproject_name=false + + while [ $# -gt 0 ]; do + case $1 in + -n|--noinput) user="${2:1:${#2}-2}"; noinput='--noinput'; shift ;; + -r|--repo) repo="${2:1:${#2}-2}"; brepo=true; shift ;; + -d|--dev) dev=1; ;; + -p|--project_name) project_name="${2:1:${#2}-2}"; bproject_name=true; shift ;; + -h|--help) print_help; exit 0 ;; + (--) shift; break;; + (-*) echo "$0: Err. - unrecognized option $1" 1>&2; exit 1;; + (*) break;; + esac + shift + done + unset OPTIND + unset opt + + if [[ $noinput == '' ]]; then + if [[ $(whoami) == 'root' ]]; then + echo -e "\nErr. Interactive script should run as a regular user\n" >&2 + exit 2 + fi run () { echo " ${bold}\$ ${@}${normal}"; ${@}; } surun () { echo " ${bold}\$ ${@}${normal}"; ${@}; } - # Test sudo privileges - sudo true + else + if [[ $(whoami) != 'root' ]]; then + echo -e "\nErr. --noinput should run as root\n" >&2 + exit 3 + elif ! id $user &> /dev/null; then + echo -e "\nErr. User $2 does not exist\n" >&2 + exit 4 + fi + run () { echo " ${bold}\$ ${@}${normal}"; ${@}; } + surun () { echo " ${bold}\$ su $user -c \"${@}\"${normal}"; su $user -c "${@}"; } + fi + if [[ $dev -eq 0 && $brepo == true ]]; then + echo -e "\nErr. --repo only makes sense with --dev\n" >&2 + exit 5 fi - project_name="panel" - if [[ $noinput == '' ]]; then + if [[ $noinput == '' && $bproject_name == false ]]; then while true; do read -p "Enter a project name [panel]: " project_name if [[ "$project_name" == "" ]]; then @@ -113,32 +245,16 @@ function main () { done fi - run sudo pip3 install django-orchestra==dev \ - --allow-external django-orchestra \ - --allow-unverified django-orchestra - run sudo orchestra-admin install_requirements - cd $(eval echo ~$user) - + home=$(eval echo ~$user) + cd $home + + install_orchestra $dev $home $repo surun "orchestra-admin startproject $project_name" cd $project_name + setup_database $dev "$noinput" - run sudo service postgresql start if [[ $noinput == '--noinput' ]]; then - db_password=$(ps aux | sha256sum | base64 | head -c 10) - run sudo python3 -W ignore manage.py setuppostgres --noinput --db_password $db_password - else - run sudo python3 -W ignore manage.py setuppostgres - fi - surun "python3 -W ignore manage.py migrate $noinput" - if [[ $noinput == '--noinput' ]]; then - # Create orchestra superuser - cat <<- EOF | surun "python3 -W ignore manage.py shell" -from orchestra.contrib.accounts.models import Account -if not Account.objects.filter(username="$user").exists(): - print('Creating orchestra superuser') - Account.objects.create_superuser("$user", "$user@localhost", "orchestra") - -EOF + create_orchestra_superuser $user $user@localhost orchestra fi if [[ "$task" == "celery" ]]; then @@ -158,7 +274,23 @@ EOF run sudo python3 -W ignore manage.py startservices surun "python3 -W ignore manage.py check --deploy" - test_orchestra $user + + ip_addr=$(ip addr show eth0 | grep 'inet ' | sed -r "s/.*inet ([^\s]*).*/\1/" | cut -d'/' -f1) + if [[ $ip_addr == '' ]]; then + ip_addr='127.0.0.1' + fi + + # Configure settings file into debug mode + if [[ $dev -eq 1 ]]; then + sed -i \ + -e "s/^\s*#\s*'debug_toolbar',/ 'debug_toolbar',/" \ + -e "s/^\s*#\s*'django_nose',/ 'django_nose',/" $project_name/settings.py + if [[ ! $(grep '^INTERNAL_IPS\s*=' $project_name/settings.py) ]]; then + echo "INTERNAL_IPS = ('$ip_addr',)" >> $project_name/settings.py + fi + fi + + test_orchestra $user $ip_addr } # Wrap it all on a function to avoid partial executions when running through wget/curl