2
0
mirror of https://github.com/frappe/bench.git synced 2024-09-23 04:29:02 +00:00

Merge branch 'v0.9wip'

This commit is contained in:
Pratik Vyas 2014-11-11 10:54:17 +05:30
commit 1400a5ee69
7 changed files with 531 additions and 167 deletions

View File

@ -19,10 +19,12 @@ Open your Terminal and enter:
``` ```
wget https://raw.githubusercontent.com/frappe/bench/master/install_scripts/setup_frappe.sh wget https://raw.githubusercontent.com/frappe/bench/master/install_scripts/setup_frappe.sh
sudo bash setup_frappe.sh sudo bash setup_frappe.sh --setup-production
``` ```
This script should install the pre-requisites and add a bench command. This script should install the pre-requisites, install bench and setup an ERPNext site.
If you want to develop ERPNext or any Frappe App, you can omit the "--setup-production" part from the command.
Manual Install Manual Install
@ -181,8 +183,10 @@ Production Deployment
===================== =====================
You can setup the bench for production use by configuring two programs, You can setup the bench for production use by configuring two programs
Supervisor and nginx. , Supervisor and nginx. These steps are automated if you pass
`--setup-production` to the easy install script or run `sudo bench
setup production`
Supervisor Supervisor
---------- ----------

View File

@ -8,26 +8,60 @@ from .utils import setup_sudoers as _setup_sudoers
from .utils import start as _start from .utils import start as _start
from .utils import setup_procfile as _setup_procfile from .utils import setup_procfile as _setup_procfile
from .utils import set_nginx_port as _set_nginx_port from .utils import set_nginx_port as _set_nginx_port
from .utils import set_nginx_port as _set_nginx_port
from .utils import set_default_site as _set_default_site from .utils import set_default_site as _set_default_site
from .utils import (build_assets, patch_sites, exec_cmd, update_bench, get_frappe, setup_logging, from .utils import (build_assets, patch_sites, exec_cmd, update_bench, get_frappe, setup_logging,
get_config, update_config, restart_supervisor_processes, put_config, default_config, update_requirements, get_config, update_config, restart_supervisor_processes, put_config, default_config, update_requirements,
backup_all_sites, backup_site, get_sites, prime_wheel_cache) backup_all_sites, backup_site, get_sites, prime_wheel_cache, is_root, set_mariadb_host, drop_privileges)
from .app import get_app as _get_app from .app import get_app as _get_app
from .app import new_app as _new_app from .app import new_app as _new_app
from .app import pull_all_apps from .app import pull_all_apps
from .config import generate_nginx_config, generate_supervisor_config from .config import generate_nginx_config, generate_supervisor_config
from .production_setup import setup_production as _setup_production
import os import os
import sys import sys
import logging import logging
import copy import copy
import pwd
logger = logging.getLogger('bench') logger = logging.getLogger('bench')
def cli(): def cli():
check_uid()
change_dir()
change_uid()
if len(sys.argv) > 2 and sys.argv[1] == "frappe": if len(sys.argv) > 2 and sys.argv[1] == "frappe":
return frappe() return frappe()
return bench() return bench()
def cmd_requires_root():
if len(sys.argv) > 2 and sys.argv[2] in ('production', 'sudoers'):
return True
if len(sys.argv) > 2 and sys.argv[1] in ('patch',):
return True
def check_uid():
if cmd_requires_root() and not is_root():
print 'superuser privileges required for this command'
sys.exit(1)
def change_uid():
if is_root() and not cmd_requires_root():
frappe_user = get_config().get('frappe_user')
if frappe_user:
drop_privileges(uid_name=frappe_user, gid_name=frappe_user)
os.environ['HOME'] = pwd.getpwnam(frappe_user).pw_dir
else:
print 'You should not run this command as root'
sys.exit(1)
def change_dir():
dir_path_file = '/etc/frappe_bench_dir'
if os.path.exists(dir_path_file):
with open(dir_path_file) as f:
dir_path = f.read().strip()
os.chdir(dir_path)
def frappe(bench='.'): def frappe(bench='.'):
f = get_frappe(bench=bench) f = get_frappe(bench=bench)
os.chdir(os.path.join(bench, 'sites')) os.chdir(os.path.join(bench, 'sites'))
@ -83,10 +117,12 @@ def new_app(app_name):
_new_app(app_name) _new_app(app_name)
@click.command('new-site') @click.command('new-site')
@click.option('--mariadb-root-password', help="MariaDB root password")
@click.option('--admin-password', help="admin password to set for site")
@click.argument('site') @click.argument('site')
def new_site(site): def new_site(site, mariadb_root_password=None, admin_password=None):
"Create a new site in the bench" "Create a new site in the bench"
_new_site(site) _new_site(site, mariadb_root_password=mariadb_root_password, admin_password=admin_password)
#TODO: Not DRY #TODO: Not DRY
@click.command('update') @click.command('update')
@ -168,6 +204,12 @@ def set_nginx_port(site, port):
"Set nginx port for site" "Set nginx port for site"
_set_nginx_port(site, port) _set_nginx_port(site, port)
@click.command('set-mariadb-host')
@click.argument('host')
def _set_mariadb_host(host):
"Set MariaDB host for bench"
set_mariadb_host(host)
@click.command('set-default-site') @click.command('set-default-site')
@click.argument('site') @click.argument('site')
def set_default_site(site): def set_default_site(site):
@ -223,7 +265,11 @@ def setup_nginx():
def setup_supervisor(): def setup_supervisor():
"generate config for supervisor" "generate config for supervisor"
generate_supervisor_config() generate_supervisor_config()
update_config({'restart_supervisor_on_update': True})
@click.command('production')
def setup_production():
"setup bench for production"
_setup_production()
@click.command('auto-update') @click.command('auto-update')
def setup_auto_update(): def setup_auto_update():
@ -263,6 +309,7 @@ setup.add_command(setup_backups)
setup.add_command(setup_env) setup.add_command(setup_env)
setup.add_command(setup_procfile) setup.add_command(setup_procfile)
setup.add_command(setup_config) setup.add_command(setup_config)
setup.add_command(setup_production)
## Config ## Config
## Not DRY ## Not DRY
@ -351,6 +398,7 @@ bench.add_command(restart)
bench.add_command(config) bench.add_command(config)
bench.add_command(start) bench.add_command(start)
bench.add_command(set_nginx_port) bench.add_command(set_nginx_port)
bench.add_command(_set_mariadb_host)
bench.add_command(set_default_site) bench.add_command(set_default_site)
bench.add_command(migrate_3to4) bench.add_command(migrate_3to4)
bench.add_command(shell) bench.add_command(shell)

View File

@ -2,7 +2,7 @@ import os
import getpass import getpass
import json import json
from jinja2 import Environment, PackageLoader from jinja2 import Environment, PackageLoader
from .utils import get_sites, get_config from .utils import get_sites, get_config, update_config
env = Environment(loader=PackageLoader('bench', 'templates'), trim_blocks=True) env = Environment(loader=PackageLoader('bench', 'templates'), trim_blocks=True)
@ -22,6 +22,7 @@ def generate_supervisor_config(bench='.'):
}) })
with open("config/supervisor.conf", 'w') as f: with open("config/supervisor.conf", 'w') as f:
f.write(config) f.write(config)
update_config({'restart_supervisor_on_update': True})
def get_site_config(site, bench='.'): def get_site_config(site, bench='.'):
with open(os.path.join(bench, 'sites', site, 'site_config.json')) as f: with open(os.path.join(bench, 'sites', site, 'site_config.json')) as f:

51
bench/production_setup.py Normal file
View File

@ -0,0 +1,51 @@
from .utils import get_program, exec_cmd, get_cmd_output
from .config import generate_nginx_config, generate_supervisor_config
from jinja2 import Environment, PackageLoader
import os
import shutil
def restart_service(service):
program = get_program(['systemctl', 'service'])
if not program:
raise Exception, 'No service manager found'
elif os.path.basename(program) == 'systemctl':
exec_cmd("{prog} restart {service}".format(prog=program, service=service))
elif os.path.basename(program) == 'service':
exec_cmd("{prog} {service} restart ".format(prog=program, service=service))
def get_supervisor_confdir():
possiblities = ('/etc/supervisor/conf.d', '/etc/supervisor.d/', '/etc/supervisord/conf.d', '/etc/supervisord.d')
for possiblity in possiblities:
if os.path.exists(possiblity):
return possiblity
def remove_default_nginx_configs():
default_nginx_configs = ['/etc/nginx/conf.d/default.conf', '/etc/nginx/sites-enabled/default']
for conf_file in default_nginx_configs:
if os.path.exists(conf_file):
os.unlink(conf_file)
def is_centos7():
return os.path.exists('/etc/redhat-release') and get_cmd_output("cat /etc/redhat-release | sed 's/Linux\ //g' | cut -d' ' -f3 | cut -d. -f1").strip() == '7'
def copy_default_nginx_config():
shutil.copy(os.path.join(os.path.dirname(__file__), 'templates', 'nginx_default.conf'), '/etc/nginx/nginx.conf')
def setup_production(bench='.'):
generate_supervisor_config(bench=bench)
generate_nginx_config(bench=bench)
remove_default_nginx_configs()
if is_centos7():
supervisor_conf_filename = 'frappe.ini'
copy_default_nginx_config()
else:
supervisor_conf_filename = 'frappe.conf'
os.symlink(os.path.abspath(os.path.join(bench, 'config', 'supervisor.conf')), os.path.join(get_supervisor_confdir(), supervisor_conf_filename))
os.symlink(os.path.abspath(os.path.join(bench, 'config', 'nginx.conf')), '/etc/nginx/conf.d/frappe.conf')
exec_cmd('supervisorctl reload')
restart_service('nginx')

View File

@ -0,0 +1,44 @@
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log;
#error_log /var/log/nginx/error.log notice;
#error_log /var/log/nginx/error.log info;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
index index.html index.htm;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
}

View File

@ -5,6 +5,7 @@ import getpass
import logging import logging
import json import json
from distutils.spawn import find_executable from distutils.spawn import find_executable
import pwd, grp
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -14,6 +15,7 @@ default_config = {
'serve_default_site': True, 'serve_default_site': True,
'rebase_on_pull': False, 'rebase_on_pull': False,
'update_bench_on_update': True, 'update_bench_on_update': True,
'frappe_user': getpass.getuser(),
'shallow_clone': True 'shallow_clone': True
} }
@ -71,9 +73,16 @@ def setup_procfile(bench='.'):
worker: sh -c 'cd sites && exec ../env/bin/python -m frappe.celery_app worker' worker: sh -c 'cd sites && exec ../env/bin/python -m frappe.celery_app worker'
workerbeat: sh -c 'cd sites && exec ../env/bin/python -m frappe.celery_app beat -s scheduler.schedule'""") workerbeat: sh -c 'cd sites && exec ../env/bin/python -m frappe.celery_app beat -s scheduler.schedule'""")
def new_site(site, bench='.'): def new_site(site, mariadb_root_password=None, admin_password=None, bench='.'):
logger.info('creating new site {}'.format(site)) logger.info('creating new site {}'.format(site))
exec_cmd("{frappe} --install {site} {site}".format(frappe=get_frappe(bench=bench), site=site), cwd=os.path.join(bench, 'sites')) mariadb_root_password_fragment = '--root_password {}'.format(mariadb_root_password) if mariadb_root_password else ''
admin_password_fragment = '--admin_password {}'.format(admin_password) if admin_password else ''
exec_cmd("{frappe} --install {site} {site} {mariadb_root_password_fragment} {admin_password_fragment}".format(
frappe=get_frappe(bench=bench),
site=site,
mariadb_root_password_fragment=mariadb_root_password_fragment,
admin_password_fragment=admin_password_fragment
), cwd=os.path.join(bench, 'sites'))
if len(get_sites(bench=bench)) == 1: if len(get_sites(bench=bench)) == 1:
exec_cmd("{frappe} --use {site}".format(frappe=get_frappe(bench=bench), site=site), cwd=os.path.join(bench, 'sites')) exec_cmd("{frappe} --use {site}".format(frappe=get_frappe(bench=bench), site=site), cwd=os.path.join(bench, 'sites'))
@ -129,10 +138,12 @@ def update_bench():
exec_cmd("git pull", cwd=cwd) exec_cmd("git pull", cwd=cwd)
def setup_sudoers(user): def setup_sudoers(user):
with open('/etc/sudoers.d/frappe', 'w') as f: sudoers_file = '/etc/sudoers.d/frappe'
with open(sudoers_file, 'w') as f:
f.write("{user} ALL=(ALL) NOPASSWD: {supervisorctl} restart frappe\:\n".format( f.write("{user} ALL=(ALL) NOPASSWD: {supervisorctl} restart frappe\:\n".format(
user=user, user=user,
supervisorctl=subprocess.check_output('which supervisorctl', shell=True).strip())) supervisorctl=subprocess.check_output('which supervisorctl', shell=True).strip()))
os.chmod(sudoers_file, 0440)
def setup_logging(bench='.'): def setup_logging(bench='.'):
if os.path.exists(os.path.join(bench, 'logs')): if os.path.exists(os.path.join(bench, 'logs')):
@ -160,8 +171,7 @@ def update_config(new_config, bench='.'):
config.update(new_config) config.update(new_config)
put_config(config, bench=bench) put_config(config, bench=bench)
def get_process_manager(): def get_program(programs):
programs = ['foreman', 'forego', 'honcho']
program = None program = None
for p in programs: for p in programs:
program = find_executable(p) program = find_executable(p)
@ -169,6 +179,9 @@ def get_process_manager():
break break
return program return program
def get_process_manager():
return get_program(['foreman', 'forego', 'honcho'])
def start(): def start():
program = get_process_manager() program = get_process_manager()
if not program: if not program:
@ -262,3 +275,41 @@ def prime_wheel_cache(bench='.'):
wheelhouse=wheel_cache_dir, wheelhouse=wheel_cache_dir,
requirements=requirements) requirements=requirements)
exec_cmd(cmd) exec_cmd(cmd)
def is_root():
if os.getuid() == 0:
return True
return False
def set_mariadb_host(host, bench='.'):
update_common_site_config({'db_host': host}, bench=bench)
def update_common_site_config(ddict, bench='.'):
update_json_file(os.path.join(bench, 'sites', 'common_site_config.json'), ddict)
def update_json_file(filename, ddict):
with open(filename, 'r') as f:
content = json.load(f)
content.update(ddict)
with open(filename, 'w') as f:
content = json.dump(content, f, indent=1)
def drop_privileges(uid_name='nobody', gid_name='nogroup'):
# from http://stackoverflow.com/a/2699996
if os.getuid() != 0:
# We're not root so, like, whatever dude
return
# Get the uid/gid from the name
running_uid = pwd.getpwnam(uid_name).pw_uid
running_gid = grp.getgrnam(gid_name).gr_gid
# Remove group privileges
os.setgroups([])
# Try setting the new uid/gid
os.setgid(running_gid)
os.setuid(running_uid)
# Ensure a very conservative umask
old_umask = os.umask(077)

View File

@ -1,7 +1,59 @@
#!/bin/bash
set -e set -e
## Utils
print_msg() {
echo "Frappe password: $FRAPPE_USER_PASS"
echo "MariaDB root password: $MSQ_PASS"
echo "Administrator password: $ADMIN_PASS"
}
get_passwd() {
echo `cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1`
}
set_opts () {
OPTS=`getopt -o v --long verbose,mysql-root-password:,frappe-user:,setup-production,help -n 'parse-options' -- "$@"`
if [ $? != 0 ] ; then echo "Failed parsing options." >&2 ; exit 1 ; fi
eval set -- "$OPTS"
VERBOSE=false
HELP=false
FRAPPE_USER=false
FRAPPE_USER_PASS=`get_passwd`
MSQ_PASS=`get_passwd`
ADMIN_PASS=`get_passwd`
SETUP_PROD=false
while true; do
case "$1" in
-v | --verbose ) VERBOSE=true; shift ;;
-h | --help ) HELP=true; shift ;;
--mysql-root-password ) MSQ_PASS="$2"; shift; shift ;;
--frappe-user ) FRAPPE_USER="$2"; shift; shift ;;
--setup-production ) SETUP_PROD=true; shift;;
-- ) shift; break ;;
* ) break ;;
esac
done
}
get_distro() { get_distro() {
ARCH=$(uname -m | sed 's/x86_/amd/;s/i[3-6]86/x86/') ARCH=$(uname -m | sed 's/x86_/amd/;s/i[3-6]86/x86/')
if [ $ARCH == "amd64" ]; then
T_ARCH="x86_64"
WK_ARCH="amd64"
else
T_ARCH="i386"
WK_ARCH="i386"
fi
if [ -f /etc/redhat-release ]; then if [ -f /etc/redhat-release ]; then
OS="centos" OS="centos"
OS_VER=`cat /etc/redhat-release | sed 's/Linux\ //g' | cut -d" " -f3 | cut -d. -f1` OS_VER=`cat /etc/redhat-release | sed 's/Linux\ //g' | cut -d" " -f3 | cut -d. -f1`
@ -20,10 +72,23 @@ get_distro() {
export OS=$OS export OS=$OS
export OS_VER=$OS_VER export OS_VER=$OS_VER
export ARCH=$ARCH export ARCH=$ARCH
echo DEBUG $OS $OS_VER $ARCH export T_ARCH=$T_ARCH
export WK_ARCH=$WK_ARCH
echo DEBUG $OS $OS_VER $ARCH $WK_ARCH
} }
add_centos_mariadb_repo() { run_cmd() {
if $VERBOSE; then
"$@"
else
# $@
"$@" > /tmp/cmdoutput.txt 2>&1 || (cat /tmp/cmdoutput.txt && exit 1)
fi
}
## add repos
add_centos6_mariadb_repo() {
echo " echo "
[mariadb] [mariadb]
name = MariaDB name = MariaDB
@ -32,12 +97,13 @@ gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1 gpgcheck=1
" > /etc/yum.repos.d/mariadb.repo " > /etc/yum.repos.d/mariadb.repo
} }
add_ubuntu_mariadb_repo() { add_ubuntu_mariadb_repo() {
sudo apt-get update run_cmd sudo apt-get update
sudo apt-get install -y python-software-properties run_cmd sudo apt-get install -y python-software-properties
sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db run_cmd sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db
sudo add-apt-repository "deb http://ams2.mirrors.digitalocean.com/mariadb/repo/5.5/ubuntu $OS_VER main" run_cmd sudo add-apt-repository "deb http://ams2.mirrors.digitalocean.com/mariadb/repo/5.5/ubuntu $OS_VER main"
} }
add_debian_mariadb_repo() { add_debian_mariadb_repo() {
@ -51,140 +117,18 @@ add_debian_mariadb_repo() {
exit 1 exit 1
fi fi
sudo apt-get update run_cmd sudo apt-get update
sudo apt-get install -y python-software-properties run_cmd sudo apt-get install -y python-software-properties
sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 0xcbcb082a1bb943db run_cmd sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 0xcbcb082a1bb943db
sudo add-apt-repository "deb http://ams2.mirrors.digitalocean.com/mariadb/repo/5.5/debian $CODENAME main" run_cmd sudo add-apt-repository "deb http://ams2.mirrors.digitalocean.com/mariadb/repo/5.5/debian $CODENAME main"
} }
add_maria_db_repo() {
if [ "$OS" == "centos" ]; then
echo DEBUG adding centos mariadb repo
add_centos_mariadb_repo
elif [ "$OS" == "debian" ]; then
echo DEBUG adding debian mariadb repo
add_debian_mariadb_repo
elif [ "$OS" == "Ubuntu" ]; then
echo DEBUG adding debian mariadb repo
add_ubuntu_mariadb_repo
else
echo Unsupported Distribution
exit 1
fi
}
install_packages() {
if [ $OS == "centos" ] && [ $OS_VER == "6" ]; then
sudo yum install wget -y
add_ius_repo
sudo yum groupinstall -y "Development tools"
sudo yum install -y git MariaDB-server MariaDB-client MariaDB-compat python-setuptools nginx zlib-devel bzip2-devel openssl-devel memcached postfix python27-devel python27 libxml2 libxml2-devel libxslt libxslt-devel redis MariaDB-devel libXrender libXext python27-setuptools
wget http://downloads.sourceforge.net/project/wkhtmltopdf/0.12.1/wkhtmltox-0.12.1_linux-centos6-amd64.rpm
sudo rpm -Uvh wkhtmltox-0.12.1_linux-centos6-amd64.rpm
easy_install-2.7 -U pip
elif [ $OS == "centos" ] && [ $OS_VER == "7" ]; then
sudo yum install wget -y
add_epel_centos7
sudo yum groupinstall -y "Development tools"
sudo yum install -y git mariadb-server mariadb-server mariadb-devel python-setuptools nginx zlib-devel bzip2-devel openssl-devel memcached postfix python-devel libxml2 libxml2-devel libxslt libxslt-devel redis libXrender libXext supervisor
wget http://downloads.sourceforge.net/project/wkhtmltopdf/0.12.1/wkhtmltox-0.12.1_linux-centos6-amd64.rpm
sudo rpm -Uvh wkhtmltox-0.12.1_linux-centos6-amd64.rpm
easy_install-2.7 -U pip
elif [ $OS == "debian" ]; then
sudo apt-get update
sudo apt-get install python-dev python-setuptools build-essential python-mysqldb git memcached ntp vim screen htop mariadb-server mariadb-common libmariadbclient-dev libxslt1.1 libxslt1-dev redis-server libssl-dev libcrypto++-dev postfix nginx supervisor python-pip fontconfig libxrender1 -y
elif [ $OS == "Ubuntu" ]; then
sudo apt-get update
sudo apt-get install python-dev python-setuptools build-essential python-mysqldb git memcached ntp vim screen htop mariadb-server mariadb-common libmariadbclient-dev libxslt1.1 libxslt1-dev redis-server libssl-dev libcrypto++-dev postfix nginx supervisor python-pip fontconfig libxrender1 -y
else
echo Unsupported Distribution
exit 1
fi
}
add_user() {
# Check if script is running as root and is not running as sudo. We want to skip
# this step if the user is already running this script with sudo as a non root
# user
if [ $SUDO_UID -eq 0 ] && [ $EUID -eq 0 ]; then
useradd -m -d /home/frappe -s $SHELL frappe
chmod o+x /home/frappe
chmod o+r /home/frappe
export FRAPPE_USER="frappe"
else
export FRAPPE_USER="$SUDO_USER"
fi
}
configure_mariadb_centos() {
# Required only for CentOS, Ubuntu and Debian will show dpkg configure screen to set the password
if [ $OS == "centos" ]; then
echo Enter mysql root password to set:
read -t 1 -n 10000 discard || true
read -p "Enter mysql root password to set:" -s MSQ_PASS
mysqladmin -u root password $MSQ_PASS
fi
}
install_supervisor_centos() {
# Required only for CentOS, Ubuntu and Debian have them in repositories
easy_install supervisor
curl https://raw.githubusercontent.com/pdvyas/supervisor-initscripts/master/redhat-init-jkoppe > /etc/init.d/supervisord
curl https://raw.githubusercontent.com/pdvyas/supervisor-initscripts/master/redhat-sysconfig-jkoppe > /etc/sysconfig/supervisord
curl https://raw.githubusercontent.com/pdvyas/supervisor-initscripts/master/supervisord.conf > /etc/supervisord.conf
mkdir /etc/supervisor.d
chmod +x /etc/init.d/supervisord
bash -c "service supervisord start || true"
}
start_services_centos() {
service mysql start
service redis start
service postfix start
service nginx start
service memcached start
}
start_services_centos7() {
systemctl start nginx
systemctl start mariadb
systemctl start redis
systemctl start supervisord
}
configure_services_centos() {
chkconfig --add supervisord
chkconfig redis on
chkconfig mysql on
chkconfig nginx on
chkconfig supervisord on
}
configure_services_centos7() {
systemctl enable nginx
systemctl enable mariadb
systemctl enable redis
systemctl enable supervisord
}
add_ius_repo() { add_ius_repo() {
if [ $ARCH == "amd64" ]; then
T_ARCH="x86_64"
else
T_ARCH="i386"
fi
if [ $OS_VER -eq "6" ]; then if [ $OS_VER -eq "6" ]; then
wget http://dl.iuscommunity.org/pub/ius/stable/CentOS/$OS_VER/$T_ARCH/epel-release-6-5.noarch.rpm wget http://dl.iuscommunity.org/pub/ius/stable/CentOS/$OS_VER/$T_ARCH/epel-release-6-5.noarch.rpm
wget http://dl.iuscommunity.org/pub/ius/stable/CentOS/$OS_VER/$T_ARCH/ius-release-1.0-13.ius.centos6.noarch.rpm wget http://dl.iuscommunity.org/pub/ius/stable/CentOS/$OS_VER/$T_ARCH/ius-release-1.0-13.ius.centos6.noarch.rpm
rpm -Uvh epel-release-6-5.noarch.rpm rpm --quiet -q epel-release || rpm -Uvh epel-release-6-5.noarch.rpm
rpm -Uvh ius-release-1.0-13.ius.centos6.noarch.rpm rpm --quiet -q ius-release || rpm -Uvh ius-release-1.0-13.ius.centos6.noarch.rpm
fi fi
} }
@ -192,8 +136,165 @@ add_epel_centos7() {
yum install -y epel-release yum install -y epel-release
} }
add_maria_db_repo() {
if [ "$OS" == "centos" ]; then
echo Adding centos mariadb repo
add_centos6_mariadb_repo
elif [ "$OS" == "debian" ]; then
echo Adding debian mariadb repo
add_debian_mariadb_repo
elif [ "$OS" == "Ubuntu" ]; then
echo Adding debian mariadb repo
add_ubuntu_mariadb_repo
else
echo Unsupported Distribution
exit 1
fi
}
## install
install_packages() {
if [ $OS == "centos" ]; then
run_cmd sudo yum install wget -y
run_cmd sudo yum groupinstall -y "Development tools"
if [ $OS_VER == "6" ]; then
run_cmd add_ius_repo
run_cmd sudo yum install -y git MariaDB-server MariaDB-client MariaDB-compat python-setuptools nginx zlib-devel bzip2-devel openssl-devel memcached postfix python27-devel python27 libxml2 libxml2-devel libxslt libxslt-devel redis MariaDB-devel libXrender libXext python27-setuptools
elif [ $OS_VER == "7" ]; then
run_cmd add_epel_centos7
run_cmd sudo yum install -y git mariadb-server mariadb-devel python-setuptools nginx zlib-devel bzip2-devel openssl-devel memcached postfix python-devel libxml2 libxml2-devel libxslt libxslt-devel redis libXrender libXext supervisor
fi
echo "Installing wkhtmltopdf"
install_wkhtmltopdf_centos
run_cmd easy_install-2.7 -U pip
elif [ $OS == "debian" ] || [ $OS == "Ubuntu" ]; then
export DEBIAN_FRONTEND=noninteractive
setup_debconf
run_cmd sudo apt-get update
run_cmd sudo apt-get install python-dev python-setuptools build-essential python-mysqldb git memcached ntp vim screen htop mariadb-server mariadb-common libmariadbclient-dev libxslt1.1 libxslt1-dev redis-server libssl-dev libcrypto++-dev postfix nginx supervisor python-pip fontconfig libxrender1 -y
echo "Installing wkhtmltopdf"
install_wkhtmltopdf_deb
else
echo Unsupported Distribution
exit 1
fi
}
install_wkhtmltopdf_centos () {
if [[ $OS == "centos" && $OS_VER == "7" && $T_ARCH="i386" ]]; then
echo "Cannot install wkhtmltodpdf. Skipping..."
return 0
fi
RPM="wkhtmltox-0.12.1_linux-$OS$OS_VER-$WK_ARCH.rpm"
run_cmd wget http://downloads.sourceforge.net/project/wkhtmltopdf/0.12.1/$RPM
rpm --quiet -q wkhtmltox || run_cmd rpm -Uvh $RPM
}
install_wkhtmltopdf_deb () {
if [[ $OS_VER == "utopic" ]]; then
echo "Cannot install wkhtmltodpdf. Skipping..."
return 0
fi
if [[ $OS == "debian" && $OS_VER == "7" ]]; then
WK_VER="wheezy"
else
WK_VER=$OS_VER
fi
run_cmd wget http://downloads.sourceforge.net/project/wkhtmltopdf/0.12.1/wkhtmltox-0.12.1_linux-$WK_VER-$WK_ARCH.deb
run_cmd dpkg -i wkhtmltox-0.12.1_linux-$WK_VER-$WK_ARCH.deb
}
install_supervisor_centos6() {
run_cmd easy_install supervisor
curl -Ss https://raw.githubusercontent.com/pdvyas/supervisor-initscripts/master/redhat-init-jkoppe > /etc/init.d/supervisord
curl -Ss https://raw.githubusercontent.com/pdvyas/supervisor-initscripts/master/redhat-sysconfig-jkoppe > /etc/sysconfig/supervisord
curl -Ss https://raw.githubusercontent.com/pdvyas/supervisor-initscripts/master/supervisord.conf > /etc/supervisord.conf
run_cmd mkdir /etc/supervisor.d
run_cmd chmod +x /etc/init.d/supervisord
bash -c "service supervisord start || true"
}
### config
get_mariadb_password() {
get_password "MariaDB root" MSQ_PASS
}
get_site_admin_password() {
get_password "Admin password" ADMIN_PASS
}
get_password() {
if [ -z "$2" ]; then
read -t 1 -n 10000 discard || true
echo
read -p "Enter $1 password to set:" -s TMP_PASS1
echo
read -p "Re enter $1 password to set:" -s TMP_PASS2
echo
if [ $TMP_PASS1 == $TMP_PASS2 ]; then
export $2=$TMp_PASS1
else
echo Passwords do not match
get_password $1 $2
fi
fi
}
configure_mariadb_centos() {
# Required only for CentOS, Ubuntu and Debian will show dpkg configure screen to set the password
if [ $OS == "centos" ]; then
mysqladmin -u root password $MSQ_PASS
fi
}
start_services_centos6() {
run_cmd service nginx start
run_cmd service mysql start
run_cmd service redis start
}
configure_services_centos6() {
run_cmd chkconfig --add supervisord
run_cmd chkconfig redis on
run_cmd chkconfig mysql on
run_cmd chkconfig nginx on
run_cmd chkconfig supervisord on
}
configure_services_centos7() {
run_cmd systemctl enable nginx
run_cmd systemctl enable mariadb
run_cmd systemctl enable redis
run_cmd systemctl enable supervisord
run_cmd systemctl enable memcached
}
start_services_centos7() {
run_cmd systemctl start nginx
run_cmd systemctl start mariadb
run_cmd systemctl start redis
run_cmd systemctl start supervisord
run_cmd systemctl start memcached
}
setup_debconf() {
debconf-set-selections <<< "postfix postfix/mailname string `hostname`"
debconf-set-selections <<< "postfix postfix/main_mailer_type string 'Internet Site'"
debconf-set-selections <<< "mariadb-server-5.5 mysql-server/root_password password $MSQ_PASS"
debconf-set-selections <<< "mariadb-server-5.5 mysql-server/root_password_again password $MSQ_PASS"
}
install_bench() { install_bench() {
sudo su $FRAPPE_USER -c "cd /home/$FRAPPE_USER && git clone https://github.com/frappe/bench bench-repo" run_cmd sudo su $FRAPPE_USER -c "cd /home/$FRAPPE_USER && git clone https://github.com/frappe/bench bench-repo"
if hash pip-2.7; then if hash pip-2.7; then
PIP="pip-2.7" PIP="pip-2.7"
elif hash pip2.7; then elif hash pip2.7; then
@ -206,24 +307,88 @@ install_bench() {
echo PIP not installed echo PIP not installed
exit 1 exit 1
fi fi
sudo $PIP install -e /home/$FRAPPE_USER/bench-repo run_cmd sudo $PIP install -e /home/$FRAPPE_USER/bench-repo
# temp MariaDB fix # temp MariaDB fix
sudo bench patch mariadb-config sudo bench patch mariadb-config
} }
get_distro setup_bench() {
add_maria_db_repo echo Installing frappe-bench
install_packages FRAPPE_BRANCH="develop"
add_user ERPNEXT_APPS_JSON="https://raw.githubusercontent.com/frappe/bench/master/install_scripts/erpnext-apps.json"
if [ $OS == "centos" ] && [ $OS_VER == "6"]; then if $SETUP_PROD; then
install_supervisor_centos FRAPPE_BRANCH="master"
configure_services_centos ERPNEXT_APPS_JSON="https://raw.githubusercontent.com/frappe/bench/master/install_scripts/erpnext-apps-master.json"
start_services_centos fi
configure_mariadb_centos
fi run_cmd sudo su $FRAPPE_USER -c "cd /home/$FRAPPE_USER && bench init frappe-bench --frappe-branch $FRAPPE_BRANCH --apps_path $ERPNEXT_APPS_JSON"
if [ $OS == "centos" ] && [ $OS_VER == "7"]; then echo Setting up first site
configure_services_centos7 echo /home/$FRAPPE_USER/frappe-bench > /etc/frappe_bench_dir
start_services_centos7 run_cmd sudo su $FRAPPE_USER -c "cd /home/$FRAPPE_USER/frappe-bench && bench new-site site1.local --mariadb-root-password $MSQ_PASS --admin-password $ADMIN_PASS"
configure_mariadb_centos run_cmd sudo su $FRAPPE_USER -c "cd /home/$FRAPPE_USER/frappe-bench && bench frappe --install_app erpnext"
fi run_cmd sudo su $FRAPPE_USER -c "cd /home/$FRAPPE_USER/frappe-bench && bench frappe --install_app shopping_cart"
install_bench run_cmd bash -c "cd /home/$FRAPPE_USER/frappe-bench && bench setup sudoers $FRAPPE_USER"
if $SETUP_PROD; then
run_cmd bash -c "cd /home/$FRAPPE_USER/frappe-bench && bench setup production"
fi
}
add_user() {
# Check if script is running as root and is not running as sudo. We want to skip
# this step if the user is already running this script with sudo as a non root
# user
if [ "$FRAPPE_USER" == "false" ]; then
if [[ $SUDO_UID -eq 0 ]] && [[ $EUID -eq 0 ]]; then
export FRAPPE_USER="frappe"
else
export FRAPPE_USER="$SUDO_USER"
fi
fi
USER_EXISTS=`bash -c "id $FRAPPE_USER > /dev/null 2>&1 && echo true || (echo false && exit 0)"`
if [ $USER_EXISTS == "false" ]; then
useradd -m -d /home/$FRAPPE_USER -s $SHELL $FRAPPE_USER
echo $FRAPPE_USER:$FRAPPE_USER_PASS | chpasswd
chmod o+x /home/$FRAPPE_USER
chmod o+r /home/$FRAPPE_USER
fi
}
main() {
set_opts $@
get_distro
add_maria_db_repo
echo Installing packages for $OS\. This might take time...
install_packages
if [ $OS == "centos" ]; then
if [ $OS_VER == "6" ]; then
echo "Installing supervisor"
install_supervisor_centos6
echo "Configuring CentOS services"
configure_services_centos6
echo "Starting services"
start_services_centos6
elif [ $OS_VER == "7" ]; then
echo "Configuring CentOS services"
configure_services_centos7
echo "Starting services"
start_services_centos7
fi
configure_mariadb_centos
fi
echo "Adding frappe user"
add_user
install_bench
setup_bench
echo
echo "Frappe/ERPNext is installed successfully."
print_msg > ~/frappe_passwords.txt
print_msg
echo
echo "The passwords are also stored at ~/frappe_passwords.txt"
echo "You can remove this file after making a note of the passwords."
}
main $@