2019-12-18 09:03:21 +00:00
#!/usr/bin/env python3
2020-02-20 14:16:40 +00:00
from __future__ import print_function
import os
import sys
import subprocess
import getpass
import json
import multiprocessing
import shutil
import platform
import warnings
import datetime
2016-03-15 06:54:17 +00:00
2019-12-27 07:44:33 +00:00
tmp_bench_repo = os . path . join ( ' / ' , ' tmp ' , ' .bench ' )
tmp_log_folder = os . path . join ( ' / ' , ' tmp ' , ' logs ' )
2020-01-09 06:36:59 +00:00
execution_timestamp = datetime . datetime . utcnow ( )
execution_day = " { : % Y- % m- %d } " . format ( execution_timestamp )
execution_time = " { : % H: % M} " . format ( execution_timestamp )
log_file_name = " easy-install__ {0} __ {1} .log " . format ( execution_day , execution_time . replace ( ' : ' , ' - ' ) )
2020-01-07 10:04:34 +00:00
log_path = os . path . join ( tmp_log_folder , log_file_name )
2019-12-18 09:03:21 +00:00
log_stream = sys . stdout
2020-08-14 14:59:46 +00:00
distro_required = not ( ( sys . version_info . major < 3 ) or ( sys . version_info . major == 3 and sys . version_info . minor < 5 ) )
2019-12-18 09:03:21 +00:00
2019-12-19 09:08:46 +00:00
def log ( message , level = 0 ) :
2019-12-18 09:03:21 +00:00
levels = {
0 : ' \033 [94m ' , # normal
1 : ' \033 [92m ' , # success
2 : ' \033 [91m ' , # fail
3 : ' \033 [93m ' # warn/suggest
}
start = levels . get ( level ) or ' '
end = ' \033 [0m '
2019-12-19 09:08:46 +00:00
print ( start + message + end )
2019-12-18 09:03:21 +00:00
2019-12-27 07:44:33 +00:00
def setup_log_stream ( args ) :
global log_stream
sys . stderr = sys . stdout
if not args . verbose :
if not os . path . exists ( tmp_log_folder ) :
os . makedirs ( tmp_log_folder )
log_stream = open ( log_path , ' w ' )
log ( " Logs are saved under {0} " . format ( log_path ) , level = 3 )
2020-01-09 06:36:59 +00:00
print ( " Install script run at {0} on {1} \n \n " . format ( execution_time , execution_day ) , file = log_stream )
2019-12-27 07:44:33 +00:00
2019-12-19 08:31:24 +00:00
def check_environment ( ) :
needed_environ_vars = [ ' LANG ' , ' LC_ALL ' ]
message = ' '
for var in needed_environ_vars :
if var not in os . environ :
2019-12-27 07:44:33 +00:00
message + = " \n export {0} =C.UTF-8 " . format ( var )
2019-12-19 08:31:24 +00:00
if message :
2019-12-19 09:08:46 +00:00
log ( " Bench ' s CLI needs these to be defined! " , level = 3 )
2019-12-27 07:44:33 +00:00
log ( " Run the following commands in shell: {0} " . format ( message ) , level = 2 )
2019-12-19 08:31:24 +00:00
sys . exit ( )
2019-12-27 07:44:33 +00:00
def check_system_package_managers ( ) :
if ' Darwin ' in os . uname ( ) :
if not shutil . which ( ' brew ' ) :
raise Exception ( '''
Please install brew package manager before proceeding with bench setup . Please run following
to install brew package manager on your machine ,
/ usr / bin / ruby - e " $(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install) "
''' )
if ' Linux ' in os . uname ( ) :
if not any ( [ shutil . which ( x ) for x in [ ' apt-get ' , ' yum ' ] ] ) :
raise Exception ( ' Cannot find any compatible package manager! ' )
2020-08-14 08:11:40 +00:00
def check_distribution_compatibility ( ) :
dist_name , dist_version = get_distribution_info ( )
2019-12-27 07:44:33 +00:00
supported_dists = {
' macos ' : [ 10.9 , 10.10 , 10.11 , 10.12 ] ,
2020-08-14 05:20:36 +00:00
' ubuntu ' : [ 14 , 15 , 16 , 18 , 19 , 20 ] ,
2020-08-05 11:01:27 +00:00
' debian ' : [ 8 , 9 , 10 ] ,
2019-12-27 07:44:33 +00:00
' centos ' : [ 7 ]
}
log ( " Checking System Compatibility... " )
if dist_name in supported_dists :
if float ( dist_version ) in supported_dists [ dist_name ] :
log ( " {0} {1} is compatible! " . format ( dist_name , dist_version ) , level = 1 )
else :
2020-01-07 10:04:34 +00:00
log ( " {0} {1} is detected " . format ( dist_name , dist_version ) , level = 1 )
2019-12-27 07:44:33 +00:00
log ( " Install on {0} {1} instead " . format ( dist_name , supported_dists [ dist_name ] [ - 1 ] ) , level = 3 )
else :
log ( " Sorry, the installer doesn ' t support {0} . Aborting installation! " . format ( dist_name ) , level = 2 )
2020-08-14 14:59:46 +00:00
2020-08-14 05:20:36 +00:00
def import_with_install ( package ) :
# copied from https://discuss.erpnext.com/u/nikunj_patel
# https://discuss.erpnext.com/t/easy-install-setup-guide-for-erpnext-installation-on-ubuntu-20-04-lts-with-some-modification-of-course/62375/5
# need to move to top said v13 for fully python3 era
import importlib
try :
importlib . import_module ( package )
except ImportError :
# caveat : pip3 must be installed
import pip
pip . main ( [ ' install ' , package ] )
finally :
globals ( ) [ package ] = importlib . import_module ( package )
2020-08-14 08:11:40 +00:00
def get_distribution_info ( ) :
2019-12-27 07:44:33 +00:00
# return distribution name and major version
if platform . system ( ) == " Linux " :
2020-08-14 14:59:46 +00:00
if distro_required :
2020-08-14 05:20:36 +00:00
current_dist = distro . linux_distribution ( full_distribution_name = True )
else :
current_dist = platform . dist ( )
2020-08-14 14:59:46 +00:00
2019-12-27 07:44:33 +00:00
return current_dist [ 0 ] . lower ( ) , current_dist [ 1 ] . rsplit ( ' . ' ) [ 0 ]
elif platform . system ( ) == " Darwin " :
current_dist = platform . mac_ver ( )
return " macos " , current_dist [ 0 ] . rsplit ( ' . ' , 1 ) [ 0 ]
2019-12-18 09:03:21 +00:00
def run_os_command ( command_map ) :
''' command_map is a dictionary of { ' executable ' : command}. For ex. { ' apt-get ' : ' sudo apt-get install -y python2.7 ' } '''
success = True
for executable , commands in command_map . items ( ) :
2019-12-20 09:15:56 +00:00
if shutil . which ( executable ) :
2019-12-18 09:03:21 +00:00
if isinstance ( commands , str ) :
commands = [ commands ]
for command in commands :
returncode = subprocess . check_call ( command , shell = True , stdout = log_stream , stderr = sys . stderr )
success = success and ( returncode == 0 )
return success
2019-12-27 07:44:33 +00:00
def install_prerequisites ( ) :
# pre-requisites for bench repo cloning
run_os_command ( {
' apt-get ' : [
' sudo apt-get update ' ,
' sudo apt-get install -y git build-essential python3-setuptools python3-dev libffi-dev '
] ,
' yum ' : [
' sudo yum groupinstall -y " Development tools " ' ,
' sudo yum install -y epel-release redhat-lsb-core git python-setuptools python-devel openssl-devel libffi-devel '
]
} )
2020-11-24 10:16:51 +00:00
2020-10-03 17:13:23 +00:00
# until psycopg2-binary is available for aarch64 (Arm 64-bit), we'll need libpq and libssl dev packages to build psycopg2 from source
if platform . machine ( ) == ' aarch64 ' :
log ( " Installing libpq and libssl dev packages to build psycopg2 for aarch64... " )
run_os_command ( {
' apt-get ' : [ ' sudo apt-get install -y libpq-dev libssl-dev ' ] ,
' yum ' : [ ' sudo yum install -y libpq-devel openssl-devel ' ]
} )
2019-12-27 07:44:33 +00:00
install_package ( ' curl ' )
install_package ( ' wget ' )
install_package ( ' git ' )
2020-01-02 08:51:29 +00:00
install_package ( ' pip3 ' , ' python3-pip ' )
2019-12-27 07:44:33 +00:00
2016-03-17 09:50:21 +00:00
success = run_os_command ( {
2020-10-03 16:58:18 +00:00
' python3 ' : " sudo -H python3 -m pip install --upgrade setuptools wheel cryptography ansible~=2.8.15 pip "
2016-03-17 09:50:21 +00:00
} )
2016-03-15 06:54:17 +00:00
2020-01-02 08:51:29 +00:00
if not ( success or shutil . which ( ' ansible ' ) ) :
2016-03-22 07:44:31 +00:00
could_not_install ( ' Ansible ' )
2019-12-27 07:44:33 +00:00
def could_not_install ( package ) :
raise Exception ( ' Could not install {0} . Please install it manually. ' . format ( package ) )
def is_sudo_user ( ) :
return os . geteuid ( ) == 0
2020-01-02 08:51:29 +00:00
def install_package ( package , package_name = None ) :
2019-12-27 07:44:33 +00:00
if shutil . which ( package ) :
log ( " {0} already installed! " . format ( package ) , level = 1 )
else :
log ( " Installing {0} ... " . format ( package ) )
2020-01-02 08:51:29 +00:00
package_name = package_name or package
2019-12-27 07:44:33 +00:00
success = run_os_command ( {
2020-01-02 08:51:29 +00:00
' apt-get ' : [ ' sudo apt-get install -y {0} ' . format ( package_name ) ] ,
' yum ' : [ ' sudo yum install -y {0} ' . format ( package_name ) ] ,
' brew ' : [ ' brew install {0} ' . format ( package_name ) ]
2019-12-27 07:44:33 +00:00
} )
if success :
log ( " {0} installed! " . format ( package ) , level = 1 )
return success
could_not_install ( package )
def install_bench ( args ) :
2016-03-15 06:54:17 +00:00
# clone bench repo
2016-06-28 06:41:06 +00:00
if not args . run_travis :
clone_bench_repo ( args )
2016-05-25 10:47:48 +00:00
2016-06-28 09:36:12 +00:00
if not args . user :
if args . production :
args . user = ' frappe '
2016-06-30 11:10:07 +00:00
2017-04-17 11:58:18 +00:00
elif ' SUDO_USER ' in os . environ :
2016-06-30 11:10:07 +00:00
args . user = os . environ [ ' SUDO_USER ' ]
2016-06-28 09:36:12 +00:00
else :
args . user = getpass . getuser ( )
2016-03-15 06:54:17 +00:00
2016-06-28 09:36:12 +00:00
if args . user == ' root ' :
2016-06-30 11:10:07 +00:00
raise Exception ( ' Please run this script as a non-root user with sudo privileges, but without using sudo or pass --user=USER ' )
2016-05-27 06:55:12 +00:00
2018-03-26 11:25:31 +00:00
# Python executable
2020-08-14 08:11:40 +00:00
dist_name , dist_version = get_distribution_info ( )
2019-06-21 03:10:13 +00:00
if dist_name == ' centos ' :
args . python = ' python3.6 '
else :
args . python = ' python3 '
2018-03-26 11:25:31 +00:00
2016-05-27 06:55:12 +00:00
# create user if not exists
2016-05-30 11:12:55 +00:00
extra_vars = vars ( args )
2016-06-28 09:36:12 +00:00
extra_vars . update ( frappe_user = args . user )
2021-02-16 15:45:07 +00:00
extra_vars . update ( user_directory = get_user_home_directory ( args . user ) )
2016-05-30 11:12:55 +00:00
2016-08-01 06:39:54 +00:00
if os . path . exists ( tmp_bench_repo ) :
repo_path = tmp_bench_repo
else :
repo_path = os . path . join ( os . path . expanduser ( ' ~ ' ) , ' bench ' )
extra_vars . update ( repo_path = repo_path )
2018-02-05 09:37:14 +00:00
run_playbook ( ' create_user.yml ' , extra_vars = extra_vars )
2016-05-27 06:55:12 +00:00
2017-08-03 11:03:57 +00:00
extra_vars . update ( get_passwords ( args ) )
2016-06-28 09:36:12 +00:00
if args . production :
extra_vars . update ( max_worker_connections = multiprocessing . cpu_count ( ) * 1024 )
2019-07-23 06:34:47 +00:00
frappe_branch = ' version-12 '
erpnext_branch = ' version-12 '
2019-07-22 10:31:36 +00:00
if args . version :
if args . version < = 10 :
frappe_branch = " {0} .x.x " . format ( args . version )
erpnext_branch = " {0} .x.x " . format ( args . version )
else :
frappe_branch = " version- {0} " . format ( args . version )
erpnext_branch = " version- {0} " . format ( args . version )
2020-10-03 09:12:39 +00:00
# Allow override of frappe_branch and erpnext_branch, regardless of args.version (which always has a default set)
if args . frappe_branch :
frappe_branch = args . frappe_branch
if args . erpnext_branch :
erpnext_branch = args . erpnext_branch
2019-07-23 06:34:47 +00:00
extra_vars . update ( frappe_branch = frappe_branch )
extra_vars . update ( erpnext_branch = erpnext_branch )
2019-05-07 04:17:35 +00:00
2017-08-28 13:40:38 +00:00
bench_name = ' frappe-bench ' if not args . bench_name else args . bench_name
extra_vars . update ( bench_name = bench_name )
2016-06-28 09:36:12 +00:00
2018-02-05 09:37:14 +00:00
# Will install ERPNext production setup by default
2020-10-30 10:35:19 +00:00
if args . without_erpnext :
log ( " Initializing bench {bench_name} : \n \t Frappe Branch: {frappe_branch} \n \t ERPNext will not be installed due to --without-erpnext " . format ( bench_name = bench_name , frappe_branch = frappe_branch ) )
else :
log ( " Initializing bench {bench_name} : \n \t Frappe Branch: {frappe_branch} \n \t ERPNext Branch: {erpnext_branch} " . format ( bench_name = bench_name , frappe_branch = frappe_branch , erpnext_branch = erpnext_branch ) )
2018-02-05 09:37:14 +00:00
run_playbook ( ' site.yml ' , sudo = True , extra_vars = extra_vars )
2016-05-25 10:47:48 +00:00
2016-06-28 06:41:06 +00:00
if os . path . exists ( tmp_bench_repo ) :
shutil . rmtree ( tmp_bench_repo )
2016-03-15 06:54:17 +00:00
2016-08-02 06:28:28 +00:00
2016-05-25 10:47:48 +00:00
def clone_bench_repo ( args ) :
2016-03-22 07:44:31 +00:00
''' Clones the bench repository in the user folder '''
2020-09-03 07:37:13 +00:00
branch = args . bench_branch or ' develop '
2019-12-18 09:03:21 +00:00
repo_url = args . repo_url or ' https://github.com/frappe/bench '
2016-05-25 10:47:48 +00:00
if os . path . exists ( tmp_bench_repo ) :
2020-10-30 10:35:19 +00:00
log ( ' Not cloning already existing Bench repository at {tmp_bench_repo} ' . format ( tmp_bench_repo = tmp_bench_repo ) )
2016-03-15 06:54:17 +00:00
return 0
2016-08-01 06:39:54 +00:00
elif args . without_bench_setup :
clone_path = os . path . join ( os . path . expanduser ( ' ~ ' ) , ' bench ' )
2020-10-30 10:35:19 +00:00
log ( ' --without-bench-setup specified, clone path is: {clone_path} ' . format ( clone_path = clone_path ) )
2016-08-01 06:39:54 +00:00
else :
clone_path = tmp_bench_repo
2020-10-30 10:35:19 +00:00
# Not logging repo_url to avoid accidental credential leak in case credential is embedded in URL
log ( ' Cloning bench repository branch {branch} into {clone_path} ' . format ( branch = branch , clone_path = clone_path ) )
2016-08-01 06:39:54 +00:00
2016-03-15 06:54:17 +00:00
success = run_os_command (
2019-12-18 09:03:21 +00:00
{ ' git ' : ' git clone --quiet {repo_url} {bench_repo} --depth 1 --branch {branch} ' . format (
2016-08-01 06:39:54 +00:00
repo_url = repo_url , bench_repo = clone_path , branch = branch ) }
2016-03-15 06:54:17 +00:00
)
return success
2016-03-22 07:44:31 +00:00
2020-01-07 10:04:34 +00:00
def passwords_didnt_match ( context = ' ' ) :
log ( " {} passwords did not match! " . format ( context ) , level = 3 )
2017-08-03 11:03:57 +00:00
def get_passwords ( args ) :
"""
Returns a dict of passwords for further use
and creates passwords . txt in the bench user ' s home directory
"""
2020-01-07 10:04:34 +00:00
log ( " Input MySQL and Frappe Administrator passwords: " )
2017-08-03 11:03:57 +00:00
ignore_prompt = args . run_travis or args . without_bench_setup
mysql_root_password , admin_password = ' ' , ' '
passwords_file_path = os . path . join ( os . path . expanduser ( ' ~ ' + args . user ) , ' passwords.txt ' )
2016-08-01 05:44:01 +00:00
if not ignore_prompt :
2017-08-03 11:03:57 +00:00
# set passwords from existing passwords.txt
if os . path . isfile ( passwords_file_path ) :
with open ( passwords_file_path , ' r ' ) as f :
passwords = json . load ( f )
mysql_root_password , admin_password = passwords [ ' mysql_root_password ' ] , passwords [ ' admin_password ' ]
# set passwords from cli args
if args . mysql_root_password :
mysql_root_password = args . mysql_root_password
if args . admin_password :
admin_password = args . admin_password
# prompt for passwords
2016-05-04 07:53:33 +00:00
pass_set = True
while pass_set :
# mysql root password
if not mysql_root_password :
mysql_root_password = getpass . unix_getpass ( prompt = ' Please enter mysql root password: ' )
conf_mysql_passwd = getpass . unix_getpass ( prompt = ' Re-enter mysql root password: ' )
2018-04-09 10:11:01 +00:00
if mysql_root_password != conf_mysql_passwd or mysql_root_password == ' ' :
2020-01-07 10:04:34 +00:00
passwords_didnt_match ( " MySQL " )
2016-05-04 07:53:33 +00:00
mysql_root_password = ' '
continue
2020-10-04 07:07:41 +00:00
# admin password, only needed if we're also creating a site
if not admin_password and not args . without_site :
2016-10-13 07:38:12 +00:00
admin_password = getpass . unix_getpass ( prompt = ' Please enter the default Administrator user password: ' )
2016-05-04 07:53:33 +00:00
conf_admin_passswd = getpass . unix_getpass ( prompt = ' Re-enter Administrator password: ' )
2018-04-09 10:11:01 +00:00
if admin_password != conf_admin_passswd or admin_password == ' ' :
2020-01-07 10:04:34 +00:00
passwords_didnt_match ( " Administrator " )
2016-05-04 07:53:33 +00:00
admin_password = ' '
continue
2020-10-30 10:35:19 +00:00
elif args . without_site :
log ( " Not creating a new site due to --without-site " )
2016-05-04 07:53:33 +00:00
pass_set = False
else :
mysql_root_password = admin_password = ' travis '
2016-09-22 09:23:36 +00:00
passwords = {
2016-05-04 07:53:33 +00:00
' mysql_root_password ' : mysql_root_password ,
' admin_password ' : admin_password
}
2016-09-22 09:23:36 +00:00
if not ignore_prompt :
with open ( passwords_file_path , ' w ' ) as f :
json . dump ( passwords , f , indent = 1 )
2019-12-19 09:08:46 +00:00
log ( ' Passwords saved at ~/passwords.txt ' )
2016-10-13 07:38:12 +00:00
2016-09-22 09:23:36 +00:00
return passwords
2017-08-03 11:03:57 +00:00
2016-06-28 09:36:12 +00:00
def get_extra_vars_json ( extra_args ) :
2016-05-30 11:12:55 +00:00
# We need to pass production as extra_vars to the playbook to execute conditionals in the
# playbook. Extra variables can passed as json or key=value pair. Here, we will use JSON.
2019-12-27 07:44:33 +00:00
json_path = os . path . join ( ' / ' , ' tmp ' , ' extra_vars.json ' )
2017-04-17 11:58:18 +00:00
extra_vars = dict ( list ( extra_args . items ( ) ) )
2019-12-27 07:44:33 +00:00
2016-05-30 11:12:55 +00:00
with open ( json_path , mode = ' w ' ) as j :
json . dump ( extra_vars , j , indent = 1 , sort_keys = True )
return ( ' @ ' + json_path )
2016-05-27 06:55:12 +00:00
2021-02-16 15:45:07 +00:00
def get_user_home_directory ( user ) :
# Return home directory /home/USERNAME or anything else defined as home directory in
# passwd for user.
return os . path . expanduser ( ' ~ ' + user )
2019-12-27 07:44:33 +00:00
2016-05-27 06:55:12 +00:00
def run_playbook ( playbook_name , sudo = False , extra_vars = None ) :
2019-07-23 14:20:07 +00:00
args = [ ' ansible-playbook ' , ' -c ' , ' local ' , playbook_name , ' -vvvv ' ]
2016-05-27 06:55:12 +00:00
if extra_vars :
2016-05-30 11:12:55 +00:00
args . extend ( [ ' -e ' , get_extra_vars_json ( extra_vars ) ] )
2016-05-27 06:55:12 +00:00
2016-03-15 06:54:17 +00:00
if sudo :
2016-05-30 11:12:55 +00:00
user = extra_vars . get ( ' user ' ) or getpass . getuser ( )
2016-05-25 10:47:48 +00:00
args . extend ( [ ' --become ' , ' --become-user= {0} ' . format ( user ) ] )
2016-05-04 07:53:33 +00:00
2016-08-01 06:39:54 +00:00
if os . path . exists ( tmp_bench_repo ) :
cwd = tmp_bench_repo
else :
cwd = os . path . join ( os . path . expanduser ( ' ~ ' ) , ' bench ' )
2020-05-07 09:30:34 +00:00
playbooks_locations = [ os . path . join ( cwd , ' bench ' , ' playbooks ' ) , os . path . join ( cwd , ' playbooks ' ) ]
playbooks_folder = [ x for x in playbooks_locations if os . path . exists ( x ) ] [ 0 ]
success = subprocess . check_call ( args , cwd = playbooks_folder , stdout = log_stream , stderr = sys . stderr )
2016-03-15 06:54:17 +00:00
return success
2019-12-18 09:03:21 +00:00
2020-08-14 14:59:46 +00:00
def setup_script_requirements ( ) :
if distro_required :
install_package ( ' pip3 ' , ' python3-pip ' )
import_with_install ( ' distro ' )
2016-03-15 06:54:17 +00:00
def parse_commandline_args ( ) :
import argparse
parser = argparse . ArgumentParser ( description = ' Frappe Installer ' )
2016-05-25 10:47:48 +00:00
# Arguments develop and production are mutually exclusive both can't be specified together.
2016-05-04 07:53:33 +00:00
# Hence, we need to create a group for discouraging use of both options at the same time.
args_group = parser . add_mutually_exclusive_group ( )
2019-12-18 09:03:21 +00:00
args_group . add_argument ( ' --develop ' , dest = ' develop ' , action = ' store_true ' , default = False , help = ' Install developer setup ' )
args_group . add_argument ( ' --production ' , dest = ' production ' , action = ' store_true ' , default = False , help = ' Setup Production environment for bench ' )
2020-10-30 10:35:19 +00:00
parser . add_argument ( ' --site ' , dest = ' site ' , action = ' store ' , default = ' site1.local ' , help = ' Specify name for your first ERPNext site ' )
parser . add_argument ( ' --without-site ' , dest = ' without_site ' , action = ' store_true ' , default = False , help = ' Do not create a new site ' )
2019-12-18 09:03:21 +00:00
parser . add_argument ( ' --verbose ' , dest = ' verbose ' , action = ' store_true ' , default = False , help = ' Run the script in verbose mode ' )
2016-05-25 10:47:48 +00:00
parser . add_argument ( ' --user ' , dest = ' user ' , help = ' Install frappe-bench for this user ' )
parser . add_argument ( ' --bench-branch ' , dest = ' bench_branch ' , help = ' Clone a particular branch of bench repository ' )
2016-05-30 11:12:55 +00:00
parser . add_argument ( ' --repo-url ' , dest = ' repo_url ' , help = ' Clone bench from the given url ' )
2019-12-18 09:03:21 +00:00
parser . add_argument ( ' --frappe-repo-url ' , dest = ' frappe_repo_url ' , action = ' store ' , default = ' https://github.com/frappe/frappe ' , help = ' Clone frappe from the given url ' )
parser . add_argument ( ' --frappe-branch ' , dest = ' frappe_branch ' , action = ' store ' , help = ' Clone a particular branch of frappe ' )
parser . add_argument ( ' --erpnext-repo-url ' , dest = ' erpnext_repo_url ' , action = ' store ' , default = ' https://github.com/frappe/erpnext ' , help = ' Clone erpnext from the given url ' )
parser . add_argument ( ' --erpnext-branch ' , dest = ' erpnext_branch ' , action = ' store ' , help = ' Clone a particular branch of erpnext ' )
parser . add_argument ( ' --without-erpnext ' , dest = ' without_erpnext ' , action = ' store_true ' , default = False , help = ' Prevent fetching ERPNext ' )
2019-07-22 10:31:36 +00:00
# direct provision to install versions
2019-12-18 09:03:21 +00:00
parser . add_argument ( ' --version ' , dest = ' version ' , action = ' store ' , default = ' 12 ' , type = int , help = ' Clone particular version of frappe and erpnext ' )
2016-05-04 07:53:33 +00:00
# To enable testing of script using Travis, this should skip the prompt
2019-12-18 09:03:21 +00:00
parser . add_argument ( ' --run-travis ' , dest = ' run_travis ' , action = ' store_true ' , default = False , help = argparse . SUPPRESS )
parser . add_argument ( ' --without-bench-setup ' , dest = ' without_bench_setup ' , action = ' store_true ' , default = False , help = argparse . SUPPRESS )
2017-05-15 15:43:37 +00:00
# whether to overwrite an existing bench
2019-12-18 09:03:21 +00:00
parser . add_argument ( ' --overwrite ' , dest = ' overwrite ' , action = ' store_true ' , default = False , help = ' Whether to overwrite an existing bench ' )
2017-08-03 11:03:57 +00:00
# set passwords
parser . add_argument ( ' --mysql-root-password ' , dest = ' mysql_root_password ' , help = ' Set mysql root password ' )
2020-08-05 11:01:27 +00:00
parser . add_argument ( ' --mariadb-version ' , dest = ' mariadb_version ' , default = ' 10.4 ' , help = ' Specify mariadb version ' )
2017-08-03 11:03:57 +00:00
parser . add_argument ( ' --admin-password ' , dest = ' admin_password ' , help = ' Set admin password ' )
2017-08-28 13:40:38 +00:00
parser . add_argument ( ' --bench-name ' , dest = ' bench_name ' , help = ' Create bench with specified name. Default name is frappe-bench ' )
2018-03-26 11:25:31 +00:00
# Python interpreter to be used
2019-12-18 09:03:21 +00:00
parser . add_argument ( ' --python ' , dest = ' python ' , default = ' python3 ' , help = argparse . SUPPRESS )
2018-12-11 17:56:15 +00:00
# LXC Support
2019-12-18 09:03:21 +00:00
parser . add_argument ( ' --container ' , dest = ' container ' , default = False , action = ' store_true ' , help = ' Use if you \' re creating inside LXC ' )
2020-08-14 05:20:36 +00:00
2016-03-15 06:54:17 +00:00
args = parser . parse_args ( )
return args
2020-08-14 14:59:46 +00:00
2016-03-22 07:44:31 +00:00
if __name__ == ' __main__ ' :
2020-02-20 14:32:35 +00:00
if sys . version [ 0 ] == ' 2 ' :
if not os . environ . get ( ' CI ' ) :
if not raw_input ( " It is recommended to run this script with Python 3 \n Do you still wish to continue? [Y/n]: " ) . lower ( ) == " y " :
sys . exit ( )
2020-01-02 08:51:29 +00:00
2020-02-27 15:49:20 +00:00
try :
from distutils . spawn import find_executable
except ImportError :
try :
subprocess . check_call ( ' pip install --upgrade setuptools ' )
except subprocess . CalledProcessError :
print ( " Install distutils or use Python3 to run the script " )
sys . exit ( 1 )
shutil . which = find_executable
2019-12-19 08:31:24 +00:00
if not is_sudo_user ( ) :
2019-12-19 09:08:46 +00:00
log ( " Please run this script as a non-root user with sudo privileges " , level = 3 )
2019-12-19 08:31:24 +00:00
sys . exit ( )
2016-03-15 06:54:17 +00:00
args = parse_commandline_args ( )
2019-12-27 07:44:33 +00:00
2019-12-18 09:03:21 +00:00
with warnings . catch_warnings ( ) :
warnings . simplefilter ( " ignore " )
2019-12-27 07:44:33 +00:00
setup_log_stream ( args )
2020-09-03 07:16:28 +00:00
install_prerequisites ( )
2020-08-14 14:59:46 +00:00
setup_script_requirements ( )
2020-08-14 08:11:40 +00:00
check_distribution_compatibility ( )
2019-12-27 07:44:33 +00:00
check_system_package_managers ( )
2019-12-19 08:31:24 +00:00
check_environment ( )
2019-12-18 09:03:21 +00:00
install_bench ( args )
2019-12-19 08:31:24 +00:00
2019-12-19 09:08:46 +00:00
log ( " Bench + Frappe + ERPNext has been successfully installed! " )