2014-07-10 17:21:34 +00:00
import click
2016-03-22 07:44:31 +00:00
import os , sys , logging , json , pwd , subprocess
2020-04-02 09:49:13 +00:00
from bench . utils import is_root , PatchError , drop_privileges , get_env_cmd , get_cmd_output , get_frappe , log , is_dist_editable , find_parent_bench , check_latest_version
2016-03-22 07:44:31 +00:00
from bench . app import get_apps
from bench . config . common_site_config import get_config
from bench . commands import bench_command
2014-07-11 09:33:07 +00:00
2020-02-01 13:28:37 +00:00
2014-07-11 09:33:07 +00:00
logger = logging . getLogger ( ' bench ' )
2015-08-15 17:30:33 +00:00
from_command_line = False
2020-03-15 14:01:27 +00:00
change_uid_msg = " You should not run this command as root "
2014-07-11 07:40:33 +00:00
def cli ( ) :
2015-08-15 17:30:33 +00:00
global from_command_line
from_command_line = True
2020-02-01 13:28:37 +00:00
change_working_directory ( )
2014-11-07 14:42:42 +00:00
check_uid ( )
change_dir ( )
change_uid ( )
2016-03-22 07:44:31 +00:00
2020-03-16 07:23:47 +00:00
if is_dist_editable ( " bench " ) :
2020-03-30 19:02:30 +00:00
log ( " bench is installed in editable mode! \n \n This is not the recommended mode of installation for production. Instead, install the package from PyPI with: `pip install frappe-bench` \n " , level = 3 )
2020-03-16 07:23:47 +00:00
2014-07-15 06:17:36 +00:00
if len ( sys . argv ) > 2 and sys . argv [ 1 ] == " frappe " :
2015-03-02 11:42:41 +00:00
return old_frappe_cli ( )
2016-03-22 07:44:31 +00:00
2019-04-13 04:41:25 +00:00
elif len ( sys . argv ) > 1 and sys . argv [ 1 ] in get_frappe_commands ( ) :
2015-03-02 11:42:41 +00:00
return frappe_cmd ( )
2016-03-22 07:44:31 +00:00
2015-03-05 11:04:28 +00:00
elif len ( sys . argv ) > 1 and sys . argv [ 1 ] in ( " --site " , " --verbose " , " --force " , " --profile " ) :
2015-03-02 11:42:41 +00:00
return frappe_cmd ( )
2016-03-22 07:44:31 +00:00
2015-03-02 11:42:41 +00:00
elif len ( sys . argv ) > 1 and sys . argv [ 1 ] == " --help " :
2017-04-17 11:58:18 +00:00
print ( click . Context ( bench_command ) . get_help ( ) )
print ( get_frappe_help ( ) )
2015-08-14 10:11:53 +00:00
return
2016-03-22 07:44:31 +00:00
2015-03-02 11:42:41 +00:00
elif len ( sys . argv ) > 1 and sys . argv [ 1 ] in get_apps ( ) :
2015-01-13 11:48:03 +00:00
return app_cmd ( )
2016-03-22 07:44:31 +00:00
2015-03-02 11:42:41 +00:00
else :
2015-05-11 15:21:17 +00:00
try :
2016-03-22 07:44:31 +00:00
# NOTE: this is the main bench command
2020-04-02 09:49:13 +00:00
check_latest_version ( )
2016-03-22 07:44:31 +00:00
bench_command ( )
2015-05-11 15:21:17 +00:00
except PatchError :
sys . exit ( 1 )
2014-07-11 07:40:33 +00:00
2016-03-22 07:44:31 +00:00
def check_uid ( ) :
if cmd_requires_root ( ) and not is_root ( ) :
2020-01-10 09:15:13 +00:00
log ( ' superuser privileges required for this command ' , level = 3 )
2016-03-22 07:44:31 +00:00
sys . exit ( 1 )
2014-11-10 09:26:09 +00:00
def cmd_requires_root ( ) :
2020-03-16 12:01:08 +00:00
if len ( sys . argv ) > 2 and sys . argv [ 2 ] in ( ' production ' , ' sudoers ' , ' supervisor ' , ' lets-encrypt ' , ' fonts ' ,
2018-06-29 08:16:40 +00:00
' print ' , ' firewall ' , ' ssh-port ' , ' role ' , ' fail2ban ' , ' wildcard-ssl ' ) :
2017-08-30 10:08:17 +00:00
return True
2017-09-18 13:14:00 +00:00
if len ( sys . argv ) > = 2 and sys . argv [ 1 ] in ( ' patch ' , ' renew-lets-encrypt ' , ' disable-production ' ,
' install ' ) :
2017-08-30 10:08:17 +00:00
return True
2014-11-10 09:26:09 +00:00
2016-03-22 07:44:31 +00:00
def change_dir ( ) :
if os . path . exists ( ' config.json ' ) or " init " in sys . argv :
return
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 ( )
if os . path . exists ( dir_path ) :
os . chdir ( dir_path )
2014-11-07 14:42:42 +00:00
def change_uid ( ) :
2014-11-10 09:26:09 +00:00
if is_root ( ) and not cmd_requires_root ( ) :
2016-02-25 12:11:08 +00:00
frappe_user = get_config ( " . " ) . get ( ' frappe_user ' )
2014-11-07 14:42:42 +00:00
if frappe_user :
2014-11-10 15:51:45 +00:00
drop_privileges ( uid_name = frappe_user , gid_name = frappe_user )
2014-11-10 10:33:23 +00:00
os . environ [ ' HOME ' ] = pwd . getpwnam ( frappe_user ) . pw_dir
2014-11-07 14:42:42 +00:00
else :
2020-03-15 14:01:27 +00:00
log ( change_uid_msg , level = 3 )
2014-11-07 14:42:42 +00:00
sys . exit ( 1 )
2016-06-16 05:48:51 +00:00
def old_frappe_cli ( bench_path = ' . ' ) :
f = get_frappe ( bench_path = bench_path )
os . chdir ( os . path . join ( bench_path , ' sites ' ) )
2014-07-11 07:40:33 +00:00
os . execv ( f , [ f ] + sys . argv [ 2 : ] )
2014-07-10 17:21:34 +00:00
2016-06-16 05:48:51 +00:00
def app_cmd ( bench_path = ' . ' ) :
f = get_env_cmd ( ' python ' , bench_path = bench_path )
os . chdir ( os . path . join ( bench_path , ' sites ' ) )
2015-01-13 11:48:03 +00:00
os . execv ( f , [ f ] + [ ' -m ' , ' frappe.utils.bench_helper ' ] + sys . argv [ 1 : ] )
2016-06-16 05:48:51 +00:00
def frappe_cmd ( bench_path = ' . ' ) :
f = get_env_cmd ( ' python ' , bench_path = bench_path )
os . chdir ( os . path . join ( bench_path , ' sites ' ) )
2015-03-02 11:42:41 +00:00
os . execv ( f , [ f ] + [ ' -m ' , ' frappe.utils.bench_helper ' , ' frappe ' ] + sys . argv [ 1 : ] )
2016-06-16 05:48:51 +00:00
def get_frappe_commands ( bench_path = ' . ' ) :
python = get_env_cmd ( ' python ' , bench_path = bench_path )
sites_path = os . path . join ( bench_path , ' sites ' )
2015-03-04 06:02:12 +00:00
if not os . path . exists ( sites_path ) :
2020-01-10 09:19:16 +00:00
log ( " Command not being executed in bench directory " , level = 3 )
2015-03-04 06:02:12 +00:00
return [ ]
2015-03-02 11:42:41 +00:00
try :
2018-01-29 12:24:03 +00:00
output = get_cmd_output ( " {python} -m frappe.utils.bench_helper get-frappe-commands " . format ( python = python ) , cwd = sites_path )
return json . loads ( output )
2019-01-19 07:42:21 +00:00
except subprocess . CalledProcessError as e :
2019-01-21 10:41:10 +00:00
if hasattr ( e , " stderr " ) :
2019-01-19 07:42:21 +00:00
print ( e . stderr . decode ( ' utf-8 ' ) )
2015-03-02 11:42:41 +00:00
return [ ]
2016-06-16 05:48:51 +00:00
def get_frappe_help ( bench_path = ' . ' ) :
python = get_env_cmd ( ' python ' , bench_path = bench_path )
sites_path = os . path . join ( bench_path , ' sites ' )
2015-03-02 11:42:41 +00:00
try :
out = get_cmd_output ( " {python} -m frappe.utils.bench_helper get-frappe-help " . format ( python = python ) , cwd = sites_path )
2020-02-12 22:45:30 +00:00
return " \n \n Framework commands: \n " + out . split ( ' Commands: ' ) [ 1 ]
except :
2015-03-02 11:42:41 +00:00
return " "
2020-02-01 13:28:37 +00:00
def change_working_directory ( ) :
""" Allows bench commands to be run from anywhere inside a bench directory """
2020-02-01 18:49:58 +00:00
cur_dir = os . path . abspath ( " . " )
bench_path = find_parent_bench ( cur_dir )
if bench_path :
os . chdir ( bench_path )