mirror of
https://github.com/frappe/bench.git
synced 2025-01-09 08:30:39 +00:00
Merge pull request #925 from gavindsouza/bench-cmd-help
refactor: bench commands help
This commit is contained in:
commit
6ecfa006e2
23
bench/cli.py
23
bench/cli.py
@ -1,6 +1,6 @@
|
|||||||
import click
|
import click
|
||||||
import os, sys, logging, json, pwd, subprocess
|
import os, sys, logging, json, pwd, subprocess
|
||||||
from bench.utils import is_root, PatchError, drop_privileges, get_env_cmd, get_cmd_output, get_frappe, log, is_bench_directory
|
from bench.utils import is_root, PatchError, drop_privileges, get_env_cmd, get_cmd_output, get_frappe, log, find_parent_bench
|
||||||
from bench.app import get_apps
|
from bench.app import get_apps
|
||||||
from bench.config.common_site_config import get_config
|
from bench.config.common_site_config import get_config
|
||||||
from bench.commands import bench_command
|
from bench.commands import bench_command
|
||||||
@ -29,7 +29,6 @@ def cli():
|
|||||||
|
|
||||||
elif len(sys.argv) > 1 and sys.argv[1]=="--help":
|
elif len(sys.argv) > 1 and sys.argv[1]=="--help":
|
||||||
print(click.Context(bench_command).get_help())
|
print(click.Context(bench_command).get_help())
|
||||||
print()
|
|
||||||
print(get_frappe_help())
|
print(get_frappe_help())
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -99,7 +98,6 @@ def get_frappe_commands(bench_path='.'):
|
|||||||
return []
|
return []
|
||||||
try:
|
try:
|
||||||
output = get_cmd_output("{python} -m frappe.utils.bench_helper get-frappe-commands".format(python=python), cwd=sites_path)
|
output = get_cmd_output("{python} -m frappe.utils.bench_helper get-frappe-commands".format(python=python), cwd=sites_path)
|
||||||
# output = output.decode('utf-8')
|
|
||||||
return json.loads(output)
|
return json.loads(output)
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
if hasattr(e, "stderr"):
|
if hasattr(e, "stderr"):
|
||||||
@ -109,27 +107,12 @@ def get_frappe_commands(bench_path='.'):
|
|||||||
def get_frappe_help(bench_path='.'):
|
def get_frappe_help(bench_path='.'):
|
||||||
python = get_env_cmd('python', bench_path=bench_path)
|
python = get_env_cmd('python', bench_path=bench_path)
|
||||||
sites_path = os.path.join(bench_path, 'sites')
|
sites_path = os.path.join(bench_path, 'sites')
|
||||||
if not os.path.exists(sites_path):
|
|
||||||
return []
|
|
||||||
try:
|
try:
|
||||||
out = get_cmd_output("{python} -m frappe.utils.bench_helper get-frappe-help".format(python=python), cwd=sites_path)
|
out = get_cmd_output("{python} -m frappe.utils.bench_helper get-frappe-help".format(python=python), cwd=sites_path)
|
||||||
return "Framework commands:\n" + out.split('Commands:')[1]
|
return "\n\nFramework commands:\n" + out.split('Commands:')[1]
|
||||||
except subprocess.CalledProcessError:
|
except:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
def find_parent_bench(path):
|
|
||||||
"""Checks if parent directories are benches"""
|
|
||||||
if is_bench_directory(directory=path):
|
|
||||||
return path
|
|
||||||
|
|
||||||
home_path = os.path.expanduser("~")
|
|
||||||
root_path = os.path.abspath(os.sep)
|
|
||||||
|
|
||||||
if path not in {home_path, root_path}:
|
|
||||||
# NOTE: the os.path.split assumes that given path is absolute
|
|
||||||
parent_dir = os.path.split(path)[0]
|
|
||||||
return find_parent_bench(parent_dir)
|
|
||||||
|
|
||||||
def change_working_directory():
|
def change_working_directory():
|
||||||
"""Allows bench commands to be run from anywhere inside a bench directory"""
|
"""Allows bench commands to be run from anywhere inside a bench directory"""
|
||||||
cur_dir = os.path.abspath(".")
|
cur_dir = os.path.abspath(".")
|
||||||
|
@ -40,7 +40,7 @@ bench_command.add_command(switch_to_develop)
|
|||||||
|
|
||||||
|
|
||||||
from bench.commands.utils import (start, restart, set_nginx_port, set_ssl_certificate, set_ssl_certificate_key, set_url_root,
|
from bench.commands.utils import (start, restart, set_nginx_port, set_ssl_certificate, set_ssl_certificate_key, set_url_root,
|
||||||
set_mariadb_host, set_default_site, download_translations, shell, backup_site, backup_all_sites, release, renew_lets_encrypt,
|
set_mariadb_host, set_default_site, download_translations, backup_site, backup_all_sites, release, renew_lets_encrypt,
|
||||||
disable_production, bench_src, prepare_beta_release, set_redis_cache_host, set_redis_queue_host, set_redis_socketio_host, find_benches, migrate_env)
|
disable_production, bench_src, prepare_beta_release, set_redis_cache_host, set_redis_queue_host, set_redis_socketio_host, find_benches, migrate_env)
|
||||||
bench_command.add_command(start)
|
bench_command.add_command(start)
|
||||||
bench_command.add_command(restart)
|
bench_command.add_command(restart)
|
||||||
@ -54,7 +54,6 @@ bench_command.add_command(set_redis_queue_host)
|
|||||||
bench_command.add_command(set_redis_socketio_host)
|
bench_command.add_command(set_redis_socketio_host)
|
||||||
bench_command.add_command(set_default_site)
|
bench_command.add_command(set_default_site)
|
||||||
bench_command.add_command(download_translations)
|
bench_command.add_command(download_translations)
|
||||||
bench_command.add_command(shell)
|
|
||||||
bench_command.add_command(backup_site)
|
bench_command.add_command(backup_site)
|
||||||
bench_command.add_command(backup_all_sites)
|
bench_command.add_command(backup_all_sites)
|
||||||
bench_command.add_command(release)
|
bench_command.add_command(release)
|
||||||
|
@ -1,112 +1,80 @@
|
|||||||
import click, json
|
# imports - standard imports
|
||||||
from bench.config.common_site_config import update_config
|
import ast
|
||||||
|
|
||||||
## Config
|
# imports - module imports
|
||||||
## Not DRY
|
from bench.config.common_site_config import update_config, get_config, put_config
|
||||||
@click.group()
|
|
||||||
|
# imports - third party imports
|
||||||
|
import click
|
||||||
|
|
||||||
|
|
||||||
|
@click.group(help='Change bench configuration')
|
||||||
def config():
|
def config():
|
||||||
"change bench configuration"
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@click.command('auto_update')
|
|
||||||
@click.argument('state', type=click.Choice(['on', 'off']))
|
|
||||||
def config_auto_update(state):
|
|
||||||
"Enable/Disable auto update for bench"
|
|
||||||
state = True if state == 'on' else False
|
|
||||||
update_config({'auto_update': state})
|
|
||||||
|
|
||||||
|
@click.command('restart_supervisor_on_update', help='Enable/Disable auto restart of supervisor processes')
|
||||||
@click.command('restart_supervisor_on_update')
|
|
||||||
@click.argument('state', type=click.Choice(['on', 'off']))
|
@click.argument('state', type=click.Choice(['on', 'off']))
|
||||||
def config_restart_supervisor_on_update(state):
|
def config_restart_supervisor_on_update(state):
|
||||||
"Enable/Disable auto restart of supervisor processes"
|
update_config({'restart_supervisor_on_update': state == 'on'})
|
||||||
state = True if state == 'on' else False
|
|
||||||
update_config({'restart_supervisor_on_update': state})
|
|
||||||
|
|
||||||
@click.command('restart_systemd_on_update')
|
|
||||||
|
@click.command('restart_systemd_on_update', help='Enable/Disable auto restart of systemd units')
|
||||||
@click.argument('state', type=click.Choice(['on', 'off']))
|
@click.argument('state', type=click.Choice(['on', 'off']))
|
||||||
def config_restart_systemd_on_update(state):
|
def config_restart_systemd_on_update(state):
|
||||||
"Enable/Disable auto restart of systemd units"
|
update_config({'restart_systemd_on_update': state == 'on'})
|
||||||
state = True if state == 'on' else False
|
|
||||||
update_config({'restart_systemd_on_update': state})
|
|
||||||
|
|
||||||
@click.command('update_bench_on_update')
|
|
||||||
|
@click.command('update_bench_on_update', help='Enable/Disable bench updates on running bench update')
|
||||||
@click.argument('state', type=click.Choice(['on', 'off']))
|
@click.argument('state', type=click.Choice(['on', 'off']))
|
||||||
def config_update_bench_on_update(state):
|
def config_update_bench_on_update(state):
|
||||||
"Enable/Disable bench updates on running bench update"
|
update_config({'update_bench_on_update': state == 'on'})
|
||||||
state = True if state == 'on' else False
|
|
||||||
update_config({'update_bench_on_update': state})
|
|
||||||
|
|
||||||
|
|
||||||
@click.command('dns_multitenant')
|
@click.command('dns_multitenant', help='Enable/Disable bench multitenancy on running bench update')
|
||||||
@click.argument('state', type=click.Choice(['on', 'off']))
|
@click.argument('state', type=click.Choice(['on', 'off']))
|
||||||
def config_dns_multitenant(state):
|
def config_dns_multitenant(state):
|
||||||
"Enable/Disable bench updates on running bench update"
|
update_config({'dns_multitenant': state == 'on'})
|
||||||
state = True if state == 'on' else False
|
|
||||||
update_config({'dns_multitenant': state})
|
|
||||||
|
|
||||||
|
|
||||||
@click.command('serve_default_site')
|
@click.command('serve_default_site', help='Configure nginx to serve the default site on port 80')
|
||||||
@click.argument('state', type=click.Choice(['on', 'off']))
|
@click.argument('state', type=click.Choice(['on', 'off']))
|
||||||
def config_serve_default_site(state):
|
def config_serve_default_site(state):
|
||||||
"Configure nginx to serve the default site on port 80"
|
update_config({'serve_default_site': state == 'on'})
|
||||||
state = True if state == 'on' else False
|
|
||||||
update_config({'serve_default_site': state})
|
|
||||||
|
|
||||||
|
|
||||||
@click.command('rebase_on_pull')
|
@click.command('rebase_on_pull', help='Rebase repositories on pulling')
|
||||||
@click.argument('state', type=click.Choice(['on', 'off']))
|
@click.argument('state', type=click.Choice(['on', 'off']))
|
||||||
def config_rebase_on_pull(state):
|
def config_rebase_on_pull(state):
|
||||||
"Rebase repositories on pulling"
|
update_config({'rebase_on_pull': state == 'on'})
|
||||||
state = True if state == 'on' else False
|
|
||||||
update_config({'rebase_on_pull': state})
|
|
||||||
|
|
||||||
|
|
||||||
@click.command('http_timeout')
|
@click.command('http_timeout', help='Set HTTP timeout')
|
||||||
@click.argument('seconds', type=int)
|
@click.argument('seconds', type=int)
|
||||||
def config_http_timeout(seconds):
|
def config_http_timeout(seconds):
|
||||||
"set http timeout"
|
|
||||||
update_config({'http_timeout': seconds})
|
update_config({'http_timeout': seconds})
|
||||||
|
|
||||||
|
|
||||||
@click.command('set-common-config')
|
@click.command('set-common-config', help='Set value in common config')
|
||||||
@click.option('configs', '-c', '--config', multiple=True, type=(str, str))
|
@click.option('configs', '-c', '--config', multiple=True, type=(str, str))
|
||||||
def set_common_config(configs):
|
def set_common_config(configs):
|
||||||
import ast
|
|
||||||
from bench.config.common_site_config import update_config
|
|
||||||
|
|
||||||
common_site_config = {}
|
common_site_config = {}
|
||||||
for key, value in configs:
|
for key, value in configs:
|
||||||
if value in ("False", "True"):
|
if value in ('true', 'false'):
|
||||||
|
value = value.title()
|
||||||
|
try:
|
||||||
value = ast.literal_eval(value)
|
value = ast.literal_eval(value)
|
||||||
|
except ValueError:
|
||||||
elif "." in value:
|
pass
|
||||||
try:
|
|
||||||
value = float(value)
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
elif "{" in value or "[" in value:
|
|
||||||
try:
|
|
||||||
value = json.loads(value)
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
value = int(value)
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
common_site_config[key] = value
|
common_site_config[key] = value
|
||||||
|
|
||||||
update_config(common_site_config, bench_path='.')
|
update_config(common_site_config, bench_path='.')
|
||||||
|
|
||||||
|
|
||||||
@click.command('remove-common-config')
|
@click.command('remove-common-config', help='Remove specific keys from current bench\'s common config')
|
||||||
@click.argument('keys', nargs=-1)
|
@click.argument('keys', nargs=-1)
|
||||||
def remove_common_config(keys):
|
def remove_common_config(keys):
|
||||||
from bench.config.common_site_config import get_config, put_config
|
|
||||||
common_site_config = get_config('.')
|
common_site_config = get_config('.')
|
||||||
for key in keys:
|
for key in keys:
|
||||||
if key in common_site_config:
|
if key in common_site_config:
|
||||||
@ -115,7 +83,6 @@ def remove_common_config(keys):
|
|||||||
put_config(common_site_config)
|
put_config(common_site_config)
|
||||||
|
|
||||||
|
|
||||||
config.add_command(config_auto_update)
|
|
||||||
config.add_command(config_update_bench_on_update)
|
config.add_command(config_update_bench_on_update)
|
||||||
config.add_command(config_restart_supervisor_on_update)
|
config.add_command(config_restart_supervisor_on_update)
|
||||||
config.add_command(config_restart_systemd_on_update)
|
config.add_command(config_restart_systemd_on_update)
|
||||||
|
@ -1,28 +1,30 @@
|
|||||||
import click
|
# imports - standard imports
|
||||||
import os, subprocess, re
|
import os
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
# imports - module imports
|
||||||
from bench.app import get_repo_dir, get_apps, get_remote
|
from bench.app import get_repo_dir, get_apps, get_remote
|
||||||
from bench.utils import set_git_remote_url
|
from bench.utils import set_git_remote_url
|
||||||
|
|
||||||
|
# imports - third party imports
|
||||||
|
import click
|
||||||
|
|
||||||
@click.command('remote-set-url')
|
|
||||||
|
@click.command('remote-set-url', help="Set app remote url")
|
||||||
@click.argument('git-url')
|
@click.argument('git-url')
|
||||||
def remote_set_url(git_url):
|
def remote_set_url(git_url):
|
||||||
"Set app remote url"
|
|
||||||
set_git_remote_url(git_url)
|
set_git_remote_url(git_url)
|
||||||
|
|
||||||
|
|
||||||
@click.command('remote-reset-url')
|
@click.command('remote-reset-url', help="Reset app remote url to frappe official")
|
||||||
@click.argument('app')
|
@click.argument('app')
|
||||||
def remote_reset_url(app):
|
def remote_reset_url(app):
|
||||||
"Reset app remote url to frappe official"
|
|
||||||
git_url = "https://github.com/frappe/{}.git".format(app)
|
git_url = "https://github.com/frappe/{}.git".format(app)
|
||||||
set_git_remote_url(git_url)
|
set_git_remote_url(git_url)
|
||||||
|
|
||||||
|
|
||||||
@click.command('remote-urls')
|
@click.command('remote-urls', help="Show apps remote url")
|
||||||
def remote_urls():
|
def remote_urls():
|
||||||
"Show apps remote url"
|
|
||||||
for app in get_apps():
|
for app in get_apps():
|
||||||
repo_dir = get_repo_dir(app)
|
repo_dir = get_repo_dir(app)
|
||||||
|
|
||||||
|
@ -1,21 +1,29 @@
|
|||||||
import os, sys, json, click
|
# imports - module imports
|
||||||
from bench.utils import run_playbook, setup_sudoers, is_root
|
from bench.utils import run_playbook, setup_sudoers
|
||||||
|
|
||||||
extra_vars = {"production": True}
|
# imports - third party imports
|
||||||
|
import click
|
||||||
|
|
||||||
@click.group()
|
|
||||||
|
extra_vars = {
|
||||||
|
"production": True
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@click.group(help="Install system dependencies for setting up Frappe environment")
|
||||||
def install():
|
def install():
|
||||||
"Install system dependancies"
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@click.command('prerequisites')
|
|
||||||
|
@click.command('prerequisites', help="Installs pre-requisite libraries, essential tools like b2zip, htop, screen, vim, x11-fonts, python libs, cups and Redis")
|
||||||
def install_prerequisites():
|
def install_prerequisites():
|
||||||
run_playbook('site.yml', tag='common, redis')
|
run_playbook('site.yml', tag='common, redis')
|
||||||
|
|
||||||
@click.command('mariadb')
|
|
||||||
@click.option('--mysql_root_password')
|
@click.command('mariadb', help="Install and setup MariaDB of specified version and root password")
|
||||||
|
@click.option('--mysql_root_password', '--mysql-root-password', default="")
|
||||||
@click.option('--version', default="10.3")
|
@click.option('--version', default="10.3")
|
||||||
def install_maridb(mysql_root_password='', version=''):
|
def install_maridb(mysql_root_password, version):
|
||||||
if mysql_root_password:
|
if mysql_root_password:
|
||||||
extra_vars.update({
|
extra_vars.update({
|
||||||
"mysql_root_password": mysql_root_password,
|
"mysql_root_password": mysql_root_password,
|
||||||
@ -27,41 +35,49 @@ def install_maridb(mysql_root_password='', version=''):
|
|||||||
|
|
||||||
run_playbook('site.yml', extra_vars=extra_vars, tag='mariadb')
|
run_playbook('site.yml', extra_vars=extra_vars, tag='mariadb')
|
||||||
|
|
||||||
@click.command('wkhtmltopdf')
|
|
||||||
|
@click.command('wkhtmltopdf', help="Installs wkhtmltopdf v0.12.3 for linux")
|
||||||
def install_wkhtmltopdf():
|
def install_wkhtmltopdf():
|
||||||
run_playbook('site.yml', extra_vars=extra_vars, tag='wkhtmltopdf')
|
run_playbook('site.yml', extra_vars=extra_vars, tag='wkhtmltopdf')
|
||||||
|
|
||||||
@click.command('nodejs')
|
|
||||||
|
@click.command('nodejs', help="Installs Node.js v8")
|
||||||
def install_nodejs():
|
def install_nodejs():
|
||||||
run_playbook('site.yml', extra_vars=extra_vars, tag='nodejs')
|
run_playbook('site.yml', extra_vars=extra_vars, tag='nodejs')
|
||||||
|
|
||||||
@click.command('psutil')
|
|
||||||
|
@click.command('psutil', help="Installs psutil via pip")
|
||||||
def install_psutil():
|
def install_psutil():
|
||||||
run_playbook('site.yml', extra_vars=extra_vars, tag='psutil')
|
run_playbook('site.yml', extra_vars=extra_vars, tag='psutil')
|
||||||
|
|
||||||
@click.command('supervisor')
|
|
||||||
|
@click.command('supervisor', help="Installs supervisor. If user is specified, sudoers is setup for that user")
|
||||||
@click.option('--user')
|
@click.option('--user')
|
||||||
def install_supervisor(user=None):
|
def install_supervisor(user=None):
|
||||||
run_playbook('site.yml', extra_vars=extra_vars, tag='supervisor')
|
run_playbook('site.yml', extra_vars=extra_vars, tag='supervisor')
|
||||||
if user:
|
if user:
|
||||||
setup_sudoers(user)
|
setup_sudoers(user)
|
||||||
|
|
||||||
@click.command('nginx')
|
|
||||||
|
@click.command('nginx', help="Installs NGINX. If user is specified, sudoers is setup for that user")
|
||||||
@click.option('--user')
|
@click.option('--user')
|
||||||
def install_nginx(user=None):
|
def install_nginx(user=None):
|
||||||
run_playbook('site.yml', extra_vars=extra_vars, tag='nginx')
|
run_playbook('site.yml', extra_vars=extra_vars, tag='nginx')
|
||||||
if user:
|
if user:
|
||||||
setup_sudoers(user)
|
setup_sudoers(user)
|
||||||
|
|
||||||
@click.command('virtualbox')
|
|
||||||
|
@click.command('virtualbox', help="Installs supervisor")
|
||||||
def install_virtualbox():
|
def install_virtualbox():
|
||||||
run_playbook('vm_build.yml', tag='virtualbox')
|
run_playbook('vm_build.yml', tag='virtualbox')
|
||||||
|
|
||||||
@click.command('packer')
|
|
||||||
|
@click.command('packer', help="Installs Oracle virtualbox and packer 1.2.1")
|
||||||
def install_packer():
|
def install_packer():
|
||||||
run_playbook('vm_build.yml', tag='packer')
|
run_playbook('vm_build.yml', tag='packer')
|
||||||
|
|
||||||
@click.command('fail2ban')
|
|
||||||
|
@click.command("fail2ban", help="Install fail2ban, an intrusion prevention software framework that protects computer servers from brute-force attacks")
|
||||||
@click.option('--maxretry', default=6, help="Number of matches (i.e. value of the counter) which triggers ban action on the IP.")
|
@click.option('--maxretry', default=6, help="Number of matches (i.e. value of the counter) which triggers ban action on the IP.")
|
||||||
@click.option('--bantime', default=600, help="The counter is set to zero if no match is found within 'findtime' seconds.")
|
@click.option('--bantime', default=600, help="The counter is set to zero if no match is found within 'findtime' seconds.")
|
||||||
@click.option('--findtime', default=600, help='Duration (in seconds) for IP to be banned for. Negative number for "permanent" ban.')
|
@click.option('--findtime', default=600, help='Duration (in seconds) for IP to be banned for. Negative number for "permanent" ban.')
|
||||||
@ -69,6 +85,7 @@ def install_failtoban(**kwargs):
|
|||||||
extra_vars.update(kwargs)
|
extra_vars.update(kwargs)
|
||||||
run_playbook('site.yml', extra_vars=extra_vars, tag='fail2ban')
|
run_playbook('site.yml', extra_vars=extra_vars, tag='fail2ban')
|
||||||
|
|
||||||
|
|
||||||
install.add_command(install_prerequisites)
|
install.add_command(install_prerequisites)
|
||||||
install.add_command(install_maridb)
|
install.add_command(install_maridb)
|
||||||
install.add_command(install_wkhtmltopdf)
|
install.add_command(install_wkhtmltopdf)
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
|
# imports - third party imports
|
||||||
import click
|
import click
|
||||||
|
|
||||||
@click.command()
|
|
||||||
|
@click.command('init', help='Initialize a new bench instance in the specified path')
|
||||||
@click.argument('path')
|
@click.argument('path')
|
||||||
@click.option('--python', type = str, default = 'python3', help = 'Path to Python Executable.')
|
@click.option('--python', type = str, default = 'python3', help = 'Path to Python Executable.')
|
||||||
@click.option('--ignore-exist', is_flag = True, default = False, help = "Ignore if Bench instance exists.")
|
@click.option('--ignore-exist', is_flag = True, default = False, help = "Ignore if Bench instance exists.")
|
||||||
@ -11,14 +13,10 @@ import click
|
|||||||
@click.option('--clone-without-update', is_flag=True, help="copy repos from path without update")
|
@click.option('--clone-without-update', is_flag=True, help="copy repos from path without update")
|
||||||
@click.option('--no-procfile', is_flag=True, help="Pull changes in all the apps in bench")
|
@click.option('--no-procfile', is_flag=True, help="Pull changes in all the apps in bench")
|
||||||
@click.option('--no-backups',is_flag=True, help="Run migrations for all sites in the bench")
|
@click.option('--no-backups',is_flag=True, help="Run migrations for all sites in the bench")
|
||||||
@click.option('--no-auto-update',is_flag=True, help="Build JS and CSS artifacts for the bench")
|
|
||||||
@click.option('--skip-redis-config-generation', is_flag=True, help="Skip redis config generation if already specifying the common-site-config file")
|
@click.option('--skip-redis-config-generation', is_flag=True, help="Skip redis config generation if already specifying the common-site-config file")
|
||||||
@click.option('--skip-assets',is_flag=True, default=False, help="Do not build assets")
|
@click.option('--skip-assets',is_flag=True, default=False, help="Do not build assets")
|
||||||
@click.option('--verbose',is_flag=True, help="Verbose output during install")
|
@click.option('--verbose',is_flag=True, help="Verbose output during install")
|
||||||
def init(path, apps_path, frappe_path, frappe_branch, no_procfile, no_backups, no_auto_update, clone_from, verbose, skip_redis_config_generation, clone_without_update, ignore_exist=False, skip_assets=False, python='python3'):
|
def init(path, apps_path, frappe_path, frappe_branch, no_procfile, no_backups, clone_from, verbose, skip_redis_config_generation, clone_without_update, ignore_exist=False, skip_assets=False, python='python3'):
|
||||||
'''
|
|
||||||
Create a New Bench Instance.
|
|
||||||
'''
|
|
||||||
from bench.utils import init, log
|
from bench.utils import init, log
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -27,7 +25,6 @@ def init(path, apps_path, frappe_path, frappe_branch, no_procfile, no_backups, n
|
|||||||
apps_path=apps_path,
|
apps_path=apps_path,
|
||||||
no_procfile=no_procfile,
|
no_procfile=no_procfile,
|
||||||
no_backups=no_backups,
|
no_backups=no_backups,
|
||||||
no_auto_update=no_auto_update,
|
|
||||||
frappe_path=frappe_path,
|
frappe_path=frappe_path,
|
||||||
frappe_branch=frappe_branch,
|
frappe_branch=frappe_branch,
|
||||||
verbose=verbose,
|
verbose=verbose,
|
||||||
@ -52,7 +49,7 @@ def init(path, apps_path, frappe_path, frappe_branch, no_procfile, no_backups, n
|
|||||||
shutil.rmtree(path)
|
shutil.rmtree(path)
|
||||||
|
|
||||||
|
|
||||||
@click.command('get-app')
|
@click.command('get-app', help='Clone an app from the internet or filesystem and set it up in your bench')
|
||||||
@click.argument('name', nargs=-1) # Dummy argument for backward compatibility
|
@click.argument('name', nargs=-1) # Dummy argument for backward compatibility
|
||||||
@click.argument('git-url')
|
@click.argument('git-url')
|
||||||
@click.option('--branch', default=None, help="branch to checkout")
|
@click.option('--branch', default=None, help="branch to checkout")
|
||||||
@ -64,31 +61,28 @@ def get_app(git_url, branch, name=None, overwrite=False, skip_assets=False):
|
|||||||
get_app(git_url, branch=branch, skip_assets=skip_assets, overwrite=overwrite)
|
get_app(git_url, branch=branch, skip_assets=skip_assets, overwrite=overwrite)
|
||||||
|
|
||||||
|
|
||||||
@click.command('new-app')
|
@click.command('new-app', help='Create a new Frappe application under apps folder')
|
||||||
@click.argument('app-name')
|
@click.argument('app-name')
|
||||||
def new_app(app_name):
|
def new_app(app_name):
|
||||||
"start a new app"
|
|
||||||
from bench.app import new_app
|
from bench.app import new_app
|
||||||
new_app(app_name)
|
new_app(app_name)
|
||||||
|
|
||||||
|
|
||||||
@click.command('remove-app')
|
@click.command('remove-app', help='Completely remove app from bench and re-build assets if not installed on any site')
|
||||||
@click.argument('app-name')
|
@click.argument('app-name')
|
||||||
def remove_app(app_name):
|
def remove_app(app_name):
|
||||||
"completely remove app from bench"
|
|
||||||
from bench.app import remove_app
|
from bench.app import remove_app
|
||||||
remove_app(app_name)
|
remove_app(app_name)
|
||||||
|
|
||||||
|
|
||||||
@click.command('exclude-app')
|
@click.command('exclude-app', help='Exclude app from updating')
|
||||||
@click.argument('app_name')
|
@click.argument('app_name')
|
||||||
def exclude_app_for_update(app_name):
|
def exclude_app_for_update(app_name):
|
||||||
"Exclude app from updating"
|
|
||||||
from bench.app import add_to_excluded_apps_txt
|
from bench.app import add_to_excluded_apps_txt
|
||||||
add_to_excluded_apps_txt(app_name)
|
add_to_excluded_apps_txt(app_name)
|
||||||
|
|
||||||
|
|
||||||
@click.command('include-app')
|
@click.command('include-app', help='Include app for updating')
|
||||||
@click.argument('app_name')
|
@click.argument('app_name')
|
||||||
def include_app_for_update(app_name):
|
def include_app_for_update(app_name):
|
||||||
"Include app from updating"
|
"Include app from updating"
|
||||||
|
@ -1,233 +1,216 @@
|
|||||||
from bench.utils import exec_cmd
|
# imports - standard imports
|
||||||
from six import PY3
|
|
||||||
import click, sys, json
|
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
@click.group()
|
# imports - module imports
|
||||||
|
from bench.utils import exec_cmd
|
||||||
|
|
||||||
|
# imports - third party imports
|
||||||
|
from six import PY3
|
||||||
|
import click
|
||||||
|
|
||||||
|
|
||||||
|
@click.group(help="Setup command group for enabling setting up a Frappe environment")
|
||||||
def setup():
|
def setup():
|
||||||
"Setup bench"
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@click.command('sudoers')
|
|
||||||
@click.argument('user')
|
@click.command("sudoers", help="Add commands to sudoers list for execution without password")
|
||||||
|
@click.argument("user")
|
||||||
def setup_sudoers(user):
|
def setup_sudoers(user):
|
||||||
"Add commands to sudoers list for execution without password"
|
|
||||||
from bench.utils import setup_sudoers
|
from bench.utils import setup_sudoers
|
||||||
setup_sudoers(user)
|
setup_sudoers(user)
|
||||||
|
|
||||||
@click.command('nginx')
|
|
||||||
@click.option('--yes', help='Yes to regeneration of nginx config file', default=False, is_flag=True)
|
@click.command("nginx", help="Generate configuration files for NGINX")
|
||||||
|
@click.option("--yes", help="Yes to regeneration of nginx config file", default=False, is_flag=True)
|
||||||
def setup_nginx(yes=False):
|
def setup_nginx(yes=False):
|
||||||
"generate config for nginx"
|
|
||||||
from bench.config.nginx import make_nginx_conf
|
from bench.config.nginx import make_nginx_conf
|
||||||
make_nginx_conf(bench_path=".", yes=yes)
|
make_nginx_conf(bench_path=".", yes=yes)
|
||||||
|
|
||||||
@click.command('reload-nginx')
|
|
||||||
|
@click.command("reload-nginx", help="Checks NGINX config file and reloads service")
|
||||||
def reload_nginx():
|
def reload_nginx():
|
||||||
from bench.config.production_setup import reload_nginx
|
from bench.config.production_setup import reload_nginx
|
||||||
reload_nginx()
|
reload_nginx()
|
||||||
|
|
||||||
@click.command('supervisor')
|
|
||||||
@click.option('--user')
|
@click.command("supervisor", help="Generate configuration for supervisor")
|
||||||
@click.option('--yes', help='Yes to regeneration of supervisor config', is_flag=True, default=False)
|
@click.option("--user", help="optional user argument")
|
||||||
|
@click.option("--yes", help="Yes to regeneration of supervisor config", is_flag=True, default=False)
|
||||||
def setup_supervisor(user=None, yes=False):
|
def setup_supervisor(user=None, yes=False):
|
||||||
"generate config for supervisor with an optional user argument"
|
|
||||||
from bench.config.supervisor import generate_supervisor_config
|
from bench.config.supervisor import generate_supervisor_config
|
||||||
generate_supervisor_config(bench_path=".", user=user, yes=yes)
|
generate_supervisor_config(bench_path=".", user=user, yes=yes)
|
||||||
|
|
||||||
@click.command('redis')
|
|
||||||
|
@click.command("redis", help="Generates configuration for Redis")
|
||||||
def setup_redis():
|
def setup_redis():
|
||||||
"generate config for redis cache"
|
|
||||||
from bench.config.redis import generate_config
|
from bench.config.redis import generate_config
|
||||||
generate_config('.')
|
generate_config(".")
|
||||||
|
|
||||||
|
|
||||||
@click.command('fonts')
|
@click.command("fonts", help="Add Frappe fonts to system")
|
||||||
def setup_fonts():
|
def setup_fonts():
|
||||||
"Add frappe fonts to system"
|
|
||||||
from bench.utils import setup_fonts
|
from bench.utils import setup_fonts
|
||||||
setup_fonts()
|
setup_fonts()
|
||||||
|
|
||||||
@click.command('production')
|
|
||||||
@click.argument('user')
|
@click.command("production", help="Setup Frappe production environment for specific user")
|
||||||
@click.option('--yes', help='Yes to regeneration config', is_flag=True, default=False)
|
@click.argument("user")
|
||||||
|
@click.option("--yes", help="Yes to regeneration config", is_flag=True, default=False)
|
||||||
def setup_production(user, yes=False):
|
def setup_production(user, yes=False):
|
||||||
"setup bench for production"
|
|
||||||
from bench.config.production_setup import setup_production
|
from bench.config.production_setup import setup_production
|
||||||
from bench.utils import run_playbook
|
|
||||||
# Install prereqs for production
|
# Install prereqs for production
|
||||||
from distutils.spawn import find_executable
|
from distutils.spawn import find_executable
|
||||||
if not find_executable('ansible'):
|
if not find_executable("ansible"):
|
||||||
exec_cmd("sudo {0} install ansible".format("pip3" if PY3 else "pip2"))
|
exec_cmd("sudo -H {0} -m pip install ansible".format(sys.executable))
|
||||||
if not find_executable('fail2ban-client'):
|
if not find_executable("fail2ban-client"):
|
||||||
exec_cmd("bench setup role fail2ban")
|
exec_cmd("bench setup role fail2ban")
|
||||||
if not find_executable('nginx'):
|
if not find_executable("nginx"):
|
||||||
exec_cmd("bench setup role nginx")
|
exec_cmd("bench setup role nginx")
|
||||||
if not find_executable('supervisord'):
|
if not find_executable("supervisord"):
|
||||||
exec_cmd("bench setup role supervisor")
|
exec_cmd("bench setup role supervisor")
|
||||||
setup_production(user=user, yes=yes)
|
setup_production(user=user, yes=yes)
|
||||||
|
|
||||||
|
|
||||||
@click.command('auto-update')
|
@click.command("backups", help="Add cronjob for bench backups")
|
||||||
def setup_auto_update():
|
|
||||||
"Add cronjob for bench auto update"
|
|
||||||
from bench.utils import setup_auto_update
|
|
||||||
setup_auto_update()
|
|
||||||
|
|
||||||
|
|
||||||
@click.command('backups')
|
|
||||||
def setup_backups():
|
def setup_backups():
|
||||||
"Add cronjob for bench backups"
|
|
||||||
from bench.utils import setup_backups
|
from bench.utils import setup_backups
|
||||||
setup_backups()
|
setup_backups()
|
||||||
|
|
||||||
@click.command('env')
|
|
||||||
@click.option('--python', type = str, default = 'python3', help = 'Path to Python Executable.')
|
@click.command("env", help="Setup virtualenv for bench")
|
||||||
def setup_env(python='python3'):
|
@click.option("--python", type = str, default = "python3", help = "Path to Python Executable.")
|
||||||
"Setup virtualenv for bench"
|
def setup_env(python="python3"):
|
||||||
from bench.utils import setup_env
|
from bench.utils import setup_env
|
||||||
setup_env(python=python)
|
setup_env(python=python)
|
||||||
|
|
||||||
@click.command('firewall')
|
|
||||||
@click.option('--ssh_port')
|
@click.command("firewall", help="Setup firewall for system")
|
||||||
@click.option('--force')
|
@click.option("--ssh_port")
|
||||||
|
@click.option("--force")
|
||||||
def setup_firewall(ssh_port=None, force=False):
|
def setup_firewall(ssh_port=None, force=False):
|
||||||
"Setup firewall"
|
|
||||||
from bench.utils import run_playbook
|
from bench.utils import run_playbook
|
||||||
|
|
||||||
if not force:
|
if not force:
|
||||||
click.confirm('Setting up the firewall will block all ports except 80, 443 and 22\n'
|
click.confirm("Setting up the firewall will block all ports except 80, 443 and {0}\nDo you want to continue?".format(ssh_port), abort=True)
|
||||||
'Do you want to continue?',
|
|
||||||
abort=True)
|
|
||||||
|
|
||||||
if not ssh_port:
|
if not ssh_port:
|
||||||
ssh_port = 22
|
ssh_port = 22
|
||||||
|
|
||||||
run_playbook('roles/bench/tasks/setup_firewall.yml', {"ssh_port": ssh_port})
|
run_playbook("roles/bench/tasks/setup_firewall.yml", {"ssh_port": ssh_port})
|
||||||
|
|
||||||
@click.command('ssh-port')
|
|
||||||
@click.argument('port')
|
@click.command("ssh-port", help="Set SSH Port for system")
|
||||||
@click.option('--force')
|
@click.argument("port")
|
||||||
|
@click.option("--force")
|
||||||
def set_ssh_port(port, force=False):
|
def set_ssh_port(port, force=False):
|
||||||
"Set SSH Port"
|
|
||||||
from bench.utils import run_playbook
|
from bench.utils import run_playbook
|
||||||
|
|
||||||
if not force:
|
if not force:
|
||||||
click.confirm('This will change your SSH Port to {}\n'
|
click.confirm("This will change your SSH Port to {}\nDo you want to continue?".format(port), abort=True)
|
||||||
'Do you want to continue?'.format(port),
|
|
||||||
abort=True)
|
|
||||||
|
|
||||||
run_playbook('roles/bench/tasks/change_ssh_port.yml', {"ssh_port": port})
|
run_playbook("roles/bench/tasks/change_ssh_port.yml", {"ssh_port": port})
|
||||||
|
|
||||||
@click.command('lets-encrypt')
|
|
||||||
@click.argument('site')
|
@click.command("lets-encrypt", help="Setup lets-encrypt SSL for site")
|
||||||
@click.option('--custom-domain')
|
@click.argument("site")
|
||||||
|
@click.option("--custom-domain")
|
||||||
@click.option('-n', '--non-interactive', default=False, is_flag=True, help="Run command non-interactively. This flag restarts nginx and runs certbot non interactively. Shouldn't be used on 1'st attempt")
|
@click.option('-n', '--non-interactive', default=False, is_flag=True, help="Run command non-interactively. This flag restarts nginx and runs certbot non interactively. Shouldn't be used on 1'st attempt")
|
||||||
def setup_letsencrypt(site, custom_domain, non_interactive):
|
def setup_letsencrypt(site, custom_domain, non_interactive):
|
||||||
"Setup lets-encrypt for site"
|
|
||||||
from bench.config.lets_encrypt import setup_letsencrypt
|
from bench.config.lets_encrypt import setup_letsencrypt
|
||||||
setup_letsencrypt(site, custom_domain, bench_path='.', interactive=not non_interactive)
|
setup_letsencrypt(site, custom_domain, bench_path=".", interactive=not non_interactive)
|
||||||
|
|
||||||
|
|
||||||
@click.command('wildcard-ssl')
|
@click.command("wildcard-ssl", help="Setup wildcard SSL certificate for multi-tenant bench")
|
||||||
@click.argument('domain')
|
@click.argument("domain")
|
||||||
@click.option('--email')
|
@click.option("--email")
|
||||||
@click.option('--exclude-base-domain', default=False, is_flag=True, help="SSL Certificate not applicable for base domain")
|
@click.option("--exclude-base-domain", default=False, is_flag=True, help="SSL Certificate not applicable for base domain")
|
||||||
def setup_wildcard_ssl(domain, email, exclude_base_domain):
|
def setup_wildcard_ssl(domain, email, exclude_base_domain):
|
||||||
''' Setup wildcard ssl certificate '''
|
|
||||||
from bench.config.lets_encrypt import setup_wildcard_ssl
|
from bench.config.lets_encrypt import setup_wildcard_ssl
|
||||||
setup_wildcard_ssl(domain, email, bench_path='.', exclude_base_domain=exclude_base_domain)
|
setup_wildcard_ssl(domain, email, bench_path=".", exclude_base_domain=exclude_base_domain)
|
||||||
|
|
||||||
|
|
||||||
@click.command('procfile')
|
@click.command("procfile", help="Generate Procfile for bench start")
|
||||||
def setup_procfile():
|
def setup_procfile():
|
||||||
"Setup Procfile for bench start"
|
|
||||||
from bench.config.procfile import setup_procfile
|
from bench.config.procfile import setup_procfile
|
||||||
setup_procfile('.')
|
setup_procfile(".")
|
||||||
|
|
||||||
|
|
||||||
@click.command('socketio')
|
@click.command("socketio", help="Setup node dependencies for socketio server")
|
||||||
def setup_socketio():
|
def setup_socketio():
|
||||||
"Setup node deps for socketio server"
|
|
||||||
from bench.utils import setup_socketio
|
from bench.utils import setup_socketio
|
||||||
setup_socketio()
|
setup_socketio()
|
||||||
|
|
||||||
@click.command('requirements', help="Update Python and Node packages")
|
|
||||||
@click.option('--node', help="Update only Node packages", default=False, is_flag=True)
|
@click.command("requirements", help="Setup Python and Node dependencies")
|
||||||
@click.option('--python', help="Update only Python packages", default=False, is_flag=True)
|
@click.option("--node", help="Update only Node packages", default=False, is_flag=True)
|
||||||
|
@click.option("--python", help="Update only Python packages", default=False, is_flag=True)
|
||||||
def setup_requirements(node=False, python=False):
|
def setup_requirements(node=False, python=False):
|
||||||
"Setup python and node requirements"
|
|
||||||
|
|
||||||
if not node:
|
if not node:
|
||||||
setup_python_requirements()
|
from bench.utils import update_requirements as setup_python_packages
|
||||||
|
setup_python_packages()
|
||||||
|
|
||||||
if not python:
|
if not python:
|
||||||
setup_node_requirements()
|
from bench.utils import update_node_packages as setup_node_packages
|
||||||
|
setup_node_packages()
|
||||||
def setup_python_requirements():
|
|
||||||
from bench.utils import update_requirements
|
|
||||||
update_requirements()
|
|
||||||
|
|
||||||
def setup_node_requirements():
|
|
||||||
from bench.utils import update_node_packages
|
|
||||||
update_node_packages()
|
|
||||||
|
|
||||||
|
|
||||||
@click.command('manager')
|
@click.command("manager", help="Setup bench-manager.local site with the bench_manager app installed on it")
|
||||||
@click.option('--yes', help='Yes to regeneration of nginx config file', default=False, is_flag=True)
|
@click.option("--yes", help="Yes to regeneration of nginx config file", default=False, is_flag=True)
|
||||||
@click.option('--port', help='Port on which you want to run bench manager', default=23624)
|
@click.option("--port", help="Port on which you want to run bench manager", default=23624)
|
||||||
@click.option('--domain', help='Domain on which you want to run bench manager')
|
@click.option("--domain", help="Domain on which you want to run bench manager")
|
||||||
def setup_manager(yes=False, port=23624, domain=None):
|
def setup_manager(yes=False, port=23624, domain=None):
|
||||||
"Setup bench-manager.local site with the bench_manager app installed on it"
|
|
||||||
from six.moves import input
|
from six.moves import input
|
||||||
|
from bench.utils import get_sites
|
||||||
|
from bench.config.common_site_config import get_config
|
||||||
|
from bench.config.nginx import make_bench_manager_nginx_conf
|
||||||
|
|
||||||
create_new_site = True
|
create_new_site = True
|
||||||
if 'bench-manager.local' in os.listdir('sites'):
|
|
||||||
ans = input('Site already exists. Overwrite existing site? [Y/n]: ').lower()
|
if "bench-manager.local" in os.listdir("sites"):
|
||||||
while ans not in ('y', 'n', ''):
|
ans = input("Site already exists. Overwrite existing site? [Y/n]: ").lower()
|
||||||
ans = input(
|
while ans not in ("y", "n", ""):
|
||||||
'Please enter "y" or "n". Site already exists. Overwrite existing site? [Y/n]: ').lower()
|
ans = input("Please enter 'y' or 'n'. Site already exists. Overwrite existing site? [Y/n]: ").lower()
|
||||||
if ans == 'n':
|
if ans == "n":
|
||||||
create_new_site = False
|
create_new_site = False
|
||||||
|
|
||||||
if create_new_site:
|
if create_new_site:
|
||||||
exec_cmd("bench new-site --force bench-manager.local")
|
exec_cmd("bench new-site --force bench-manager.local")
|
||||||
|
|
||||||
if 'bench_manager' in os.listdir('apps'):
|
if "bench_manager" in os.listdir("apps"):
|
||||||
print('App already exists. Skipping app download.')
|
print("App already exists. Skipping app download.")
|
||||||
else:
|
else:
|
||||||
exec_cmd("bench get-app bench_manager")
|
exec_cmd("bench get-app bench_manager")
|
||||||
|
|
||||||
exec_cmd("bench --site bench-manager.local install-app bench_manager")
|
exec_cmd("bench --site bench-manager.local install-app bench_manager")
|
||||||
|
|
||||||
from bench.config.common_site_config import get_config
|
bench_path = "."
|
||||||
bench_path = '.'
|
|
||||||
conf = get_config(bench_path)
|
conf = get_config(bench_path)
|
||||||
if conf.get('restart_supervisor_on_update') or conf.get('restart_systemd_on_update'):
|
|
||||||
|
if conf.get("restart_supervisor_on_update") or conf.get("restart_systemd_on_update"):
|
||||||
# implicates a production setup or so I presume
|
# implicates a production setup or so I presume
|
||||||
if not domain:
|
if not domain:
|
||||||
print("Please specify the site name on which you want to host bench-manager using the 'domain' flag")
|
print("Please specify the site name on which you want to host bench-manager using the 'domain' flag")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
from bench.utils import get_sites, get_bench_name
|
|
||||||
bench_name = get_bench_name(bench_path)
|
|
||||||
|
|
||||||
if domain not in get_sites(bench_path):
|
if domain not in get_sites(bench_path):
|
||||||
raise Exception("No such site")
|
raise Exception("No such site")
|
||||||
|
|
||||||
from bench.config.nginx import make_bench_manager_nginx_conf
|
|
||||||
make_bench_manager_nginx_conf(bench_path, yes=yes, port=port, domain=domain)
|
make_bench_manager_nginx_conf(bench_path, yes=yes, port=port, domain=domain)
|
||||||
|
|
||||||
|
|
||||||
@click.command('config')
|
@click.command("config", help="Generate or over-write sites/common_site_config.json")
|
||||||
def setup_config():
|
def setup_config():
|
||||||
"overwrite or make config.json"
|
|
||||||
from bench.config.common_site_config import make_config
|
from bench.config.common_site_config import make_config
|
||||||
make_config('.')
|
make_config(".")
|
||||||
|
|
||||||
|
|
||||||
@click.command('add-domain')
|
@click.command("add-domain", help="Add a custom domain to a particular site")
|
||||||
@click.argument('domain')
|
@click.argument("domain")
|
||||||
@click.option('--site', prompt=True)
|
@click.option("--site", prompt=True)
|
||||||
@click.option('--ssl-certificate', help="Absolute path to SSL Certificate")
|
@click.option("--ssl-certificate", help="Absolute path to SSL Certificate")
|
||||||
@click.option('--ssl-certificate-key', help="Absolute path to SSL Certificate Key")
|
@click.option("--ssl-certificate-key", help="Absolute path to SSL Certificate Key")
|
||||||
def add_domain(domain, site=None, ssl_certificate=None, ssl_certificate_key=None):
|
def add_domain(domain, site=None, ssl_certificate=None, ssl_certificate_key=None):
|
||||||
"""Add custom domain to site"""
|
"""Add custom domain to site"""
|
||||||
from bench.config.site_config import add_domain
|
from bench.config.site_config import add_domain
|
||||||
@ -236,24 +219,25 @@ def add_domain(domain, site=None, ssl_certificate=None, ssl_certificate_key=None
|
|||||||
print("Please specify site")
|
print("Please specify site")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
add_domain(site, domain, ssl_certificate, ssl_certificate_key, bench_path='.')
|
add_domain(site, domain, ssl_certificate, ssl_certificate_key, bench_path=".")
|
||||||
|
|
||||||
@click.command('remove-domain')
|
|
||||||
@click.argument('domain')
|
@click.command("remove-domain", help="Remove custom domain from a site")
|
||||||
@click.option('--site', prompt=True)
|
@click.argument("domain")
|
||||||
|
@click.option("--site", prompt=True)
|
||||||
def remove_domain(domain, site=None):
|
def remove_domain(domain, site=None):
|
||||||
"""Remove custom domain from a site"""
|
|
||||||
from bench.config.site_config import remove_domain
|
from bench.config.site_config import remove_domain
|
||||||
|
|
||||||
if not site:
|
if not site:
|
||||||
print("Please specify site")
|
print("Please specify site")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
remove_domain(site, domain, bench_path='.')
|
remove_domain(site, domain, bench_path=".")
|
||||||
|
|
||||||
@click.command('sync-domains')
|
|
||||||
@click.option('--domain', multiple=True)
|
@click.command("sync-domains", help="Check if there is a change in domains. If yes, updates the domains list.")
|
||||||
@click.option('--site', prompt=True)
|
@click.option("--domain", multiple=True)
|
||||||
|
@click.option("--site", prompt=True)
|
||||||
def sync_domains(domain=None, site=None):
|
def sync_domains(domain=None, site=None):
|
||||||
from bench.config.site_config import sync_domains
|
from bench.config.site_config import sync_domains
|
||||||
|
|
||||||
@ -262,53 +246,55 @@ def sync_domains(domain=None, site=None):
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
domains = list(map(str,domain))
|
domains = list(map(str, domain))
|
||||||
except Exception:
|
except Exception:
|
||||||
print("Domains should be a json list of strings or dictionaries")
|
print("Domains should be a json list of strings or dictionaries")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
changed = sync_domains(site, domains, bench_path='.')
|
changed = sync_domains(site, domains, bench_path=".")
|
||||||
|
|
||||||
# if changed, success, else failure
|
# if changed, success, else failure
|
||||||
sys.exit(0 if changed else 1)
|
sys.exit(0 if changed else 1)
|
||||||
|
|
||||||
@click.command('role')
|
|
||||||
@click.argument('role')
|
@click.command("role", help="Install dependencies via ansible roles")
|
||||||
@click.option('--admin_emails', default='')
|
@click.argument("role")
|
||||||
@click.option('--mysql_root_password')
|
@click.option("--admin_emails", default="")
|
||||||
@click.option('--container', is_flag=True, default=False)
|
@click.option("--mysql_root_password")
|
||||||
|
@click.option("--container", is_flag=True, default=False)
|
||||||
def setup_roles(role, **kwargs):
|
def setup_roles(role, **kwargs):
|
||||||
"Install dependancies via roles"
|
|
||||||
from bench.utils import run_playbook
|
from bench.utils import run_playbook
|
||||||
|
|
||||||
extra_vars = {"production": True}
|
extra_vars = {"production": True}
|
||||||
extra_vars.update(kwargs)
|
extra_vars.update(kwargs)
|
||||||
|
|
||||||
if role:
|
if role:
|
||||||
run_playbook('site.yml', extra_vars=extra_vars, tag=role)
|
run_playbook("site.yml", extra_vars=extra_vars, tag=role)
|
||||||
else:
|
else:
|
||||||
run_playbook('site.yml', extra_vars=extra_vars)
|
run_playbook("site.yml", extra_vars=extra_vars)
|
||||||
|
|
||||||
@click.command('fail2ban')
|
|
||||||
@click.option('--maxretry', default=6, help="Number of matches (i.e. value of the counter) which triggers ban action on the IP. Default is 6 seconds" )
|
@click.command("fail2ban", help="Setup fail2ban, an intrusion prevention software framework that protects computer servers from brute-force attacks")
|
||||||
@click.option('--bantime', default=600, help="The counter is set to zero if no match is found within 'findtime' seconds. Default is 600 seconds")
|
@click.option("--maxretry", default=6, help="Number of matches (i.e. value of the counter) which triggers ban action on the IP. Default is 6 seconds" )
|
||||||
@click.option('--findtime', default=600, help='Duration (in seconds) for IP to be banned for. Negative number for "permanent" ban. Default is 600 seconds')
|
@click.option("--bantime", default=600, help="The counter is set to zero if no match is found within 'findtime' seconds. Default is 600 seconds")
|
||||||
|
@click.option("--findtime", default=600, help="Duration (in seconds) for IP to be banned for. Negative number for 'permanent' ban. Default is 600 seconds")
|
||||||
def setup_nginx_proxy_jail(**kwargs):
|
def setup_nginx_proxy_jail(**kwargs):
|
||||||
from bench.utils import run_playbook
|
from bench.utils import run_playbook
|
||||||
run_playbook('roles/fail2ban/tasks/configure_nginx_jail.yml', extra_vars=kwargs)
|
run_playbook("roles/fail2ban/tasks/configure_nginx_jail.yml", extra_vars=kwargs)
|
||||||
|
|
||||||
@click.command('systemd')
|
|
||||||
@click.option('--user')
|
@click.command("systemd", help="Generate configuration for systemd")
|
||||||
@click.option('--yes', help='Yes to regeneration of systemd config files', is_flag=True, default=False)
|
@click.option("--user", help="Optional user argument")
|
||||||
@click.option('--stop', help='Stop bench services', is_flag=True, default=False)
|
@click.option("--yes", help="Yes to regeneration of systemd config files", is_flag=True, default=False)
|
||||||
@click.option('--create-symlinks', help='Create Symlinks', is_flag=True, default=False)
|
@click.option("--stop", help="Stop bench services", is_flag=True, default=False)
|
||||||
@click.option('--delete-symlinks', help='Delete Symlinks', is_flag=True, default=False)
|
@click.option("--create-symlinks", help="Create Symlinks", is_flag=True, default=False)
|
||||||
|
@click.option("--delete-symlinks", help="Delete Symlinks", is_flag=True, default=False)
|
||||||
def setup_systemd(user=None, yes=False, stop=False, create_symlinks=False, delete_symlinks=False):
|
def setup_systemd(user=None, yes=False, stop=False, create_symlinks=False, delete_symlinks=False):
|
||||||
"generate configs for systemd with an optional user argument"
|
|
||||||
from bench.config.systemd import generate_systemd_config
|
from bench.config.systemd import generate_systemd_config
|
||||||
generate_systemd_config(bench_path=".", user=user, yes=yes,
|
generate_systemd_config(bench_path=".", user=user, yes=yes,
|
||||||
stop=stop, create_symlinks=create_symlinks, delete_symlinks=delete_symlinks)
|
stop=stop, create_symlinks=create_symlinks, delete_symlinks=delete_symlinks)
|
||||||
|
|
||||||
|
|
||||||
setup.add_command(setup_sudoers)
|
setup.add_command(setup_sudoers)
|
||||||
setup.add_command(setup_nginx)
|
setup.add_command(setup_nginx)
|
||||||
setup.add_command(reload_nginx)
|
setup.add_command(reload_nginx)
|
||||||
@ -317,7 +303,6 @@ setup.add_command(setup_redis)
|
|||||||
setup.add_command(setup_letsencrypt)
|
setup.add_command(setup_letsencrypt)
|
||||||
setup.add_command(setup_wildcard_ssl)
|
setup.add_command(setup_wildcard_ssl)
|
||||||
setup.add_command(setup_production)
|
setup.add_command(setup_production)
|
||||||
setup.add_command(setup_auto_update)
|
|
||||||
setup.add_command(setup_backups)
|
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)
|
||||||
|
@ -1,124 +1,32 @@
|
|||||||
import click
|
# imports - standard imports
|
||||||
import sys
|
|
||||||
import os
|
import os
|
||||||
from bench.config.common_site_config import get_config, update_config
|
|
||||||
from bench.app import pull_all_apps, is_version_upgrade, validate_branch
|
# imports - third party imports
|
||||||
from bench.utils import (update_bench, validate_upgrade, pre_upgrade, post_upgrade, before_update,
|
import click
|
||||||
update_requirements, update_node_packages, backup_all_sites, patch_sites, build_assets,
|
|
||||||
restart_supervisor_processes, restart_systemd_processes, is_bench_directory)
|
|
||||||
from bench import patches
|
|
||||||
from six.moves import reload_module
|
from six.moves import reload_module
|
||||||
|
|
||||||
|
# imports - module imports
|
||||||
|
from bench.app import pull_all_apps
|
||||||
|
from bench.utils import post_upgrade, patch_sites, build_assets
|
||||||
|
|
||||||
@click.command('update')
|
|
||||||
@click.option('--pull', is_flag=True, help="Pull changes in all the apps in bench")
|
@click.command('update', help="Updates bench tool and if executed in a bench directory, without any flags will backup, pull, setup requirements, build, run patches and restart bench. Using specific flags will only do certain tasks instead of all")
|
||||||
|
@click.option('--pull', is_flag=True, help="Pull updates for all the apps in bench")
|
||||||
@click.option('--patch', is_flag=True, help="Run migrations for all sites in the bench")
|
@click.option('--patch', is_flag=True, help="Run migrations for all sites in the bench")
|
||||||
@click.option('--build', is_flag=True, help="Build JS and CSS artifacts for the bench")
|
@click.option('--build', is_flag=True, help="Build JS and CSS assets for the bench")
|
||||||
@click.option('--bench', is_flag=True, help="Update bench")
|
@click.option('--bench', is_flag=True, help="Update bench CLI tool")
|
||||||
@click.option('--requirements', is_flag=True, help="Update requirements")
|
@click.option('--requirements', is_flag=True, help="Update requirements. If run alone, equivalent to `bench setup requirements`")
|
||||||
@click.option('--restart-supervisor', is_flag=True, help="restart supervisor processes after update")
|
@click.option('--restart-supervisor', is_flag=True, help="Restart supervisor processes after update")
|
||||||
@click.option('--restart-systemd', is_flag=True, help="restart systemd units after update")
|
@click.option('--restart-systemd', is_flag=True, help="Restart systemd units after update")
|
||||||
@click.option('--auto', is_flag=True)
|
@click.option('--no-backup', is_flag=True, help="If this flag is set, sites won't be backed up prior to updates. Note: This is not recommended in production.")
|
||||||
@click.option('--no-backup', is_flag=True)
|
@click.option('--force', is_flag=True, help="Forces major version upgrades")
|
||||||
@click.option('--force', is_flag=True)
|
|
||||||
@click.option('--reset', is_flag=True, help="Hard resets git branch's to their new states overriding any changes and overriding rebase on pull")
|
@click.option('--reset', is_flag=True, help="Hard resets git branch's to their new states overriding any changes and overriding rebase on pull")
|
||||||
def update(pull=False, patch=False, build=False, bench=False, auto=False, restart_supervisor=False, restart_systemd=False, requirements=False, no_backup=False, force=False, reset=False):
|
def update(pull, patch, build, bench, requirements, restart_supervisor, restart_systemd, no_backup, force, reset):
|
||||||
"Update bench"
|
from bench.utils import update
|
||||||
|
update(pull=pull, patch=patch, build=build, bench=bench, requirements=requirements, restart_supervisor=restart_supervisor, restart_systemd=restart_systemd, backup= not no_backup, force=force, reset=reset)
|
||||||
|
|
||||||
if not is_bench_directory():
|
|
||||||
"""Update only bench if bench update called from outside a bench"""
|
|
||||||
update_bench(bench_repo=True, requirements=True)
|
|
||||||
sys.exit()
|
|
||||||
|
|
||||||
if not (pull or patch or build or bench or requirements):
|
@click.command('retry-upgrade', help="Retry a failed upgrade")
|
||||||
pull, patch, build, bench, requirements = True, True, True, True, True
|
|
||||||
|
|
||||||
if auto:
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
patches.run(bench_path='.')
|
|
||||||
conf = get_config(".")
|
|
||||||
|
|
||||||
if bench and conf.get('update_bench_on_update'):
|
|
||||||
update_bench(bench_repo=True, requirements=False)
|
|
||||||
restart_update({
|
|
||||||
'pull': pull,
|
|
||||||
'patch': patch,
|
|
||||||
'build': build,
|
|
||||||
'requirements': requirements,
|
|
||||||
'no-backup': no_backup,
|
|
||||||
'restart-supervisor': restart_supervisor,
|
|
||||||
'reset': reset
|
|
||||||
})
|
|
||||||
|
|
||||||
if conf.get('release_bench'):
|
|
||||||
print('Release bench, cannot update')
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
validate_branch()
|
|
||||||
|
|
||||||
version_upgrade = is_version_upgrade()
|
|
||||||
if version_upgrade[0]:
|
|
||||||
print()
|
|
||||||
print()
|
|
||||||
print("This update will cause a major version change in Frappe/ERPNext from {0} to {1}.".format(*version_upgrade[1:]))
|
|
||||||
print("This would take significant time to migrate and might break custom apps.")
|
|
||||||
click.confirm('Do you want to continue?', abort=True)
|
|
||||||
|
|
||||||
_update(pull, patch, build, bench, auto, restart_supervisor, restart_systemd, requirements, no_backup, force=force, reset=reset)
|
|
||||||
|
|
||||||
def _update(pull=False, patch=False, build=False, update_bench=False, auto=False, restart_supervisor=False,
|
|
||||||
restart_systemd=False, requirements=False, no_backup=False, bench_path='.', force=False, reset=False):
|
|
||||||
conf = get_config(bench_path=bench_path)
|
|
||||||
version_upgrade = is_version_upgrade(bench_path=bench_path)
|
|
||||||
|
|
||||||
if version_upgrade[0] or (not version_upgrade[0] and force):
|
|
||||||
validate_upgrade(version_upgrade[1], version_upgrade[2], bench_path=bench_path)
|
|
||||||
|
|
||||||
before_update(bench_path=bench_path, requirements=requirements)
|
|
||||||
|
|
||||||
conf.update({ "maintenance_mode": 1, "pause_scheduler": 1 })
|
|
||||||
update_config(conf, bench_path=bench_path)
|
|
||||||
|
|
||||||
if not no_backup:
|
|
||||||
print('Backing up sites...')
|
|
||||||
backup_all_sites(bench_path=bench_path)
|
|
||||||
|
|
||||||
if pull:
|
|
||||||
pull_all_apps(bench_path=bench_path, reset=reset)
|
|
||||||
|
|
||||||
if requirements:
|
|
||||||
update_requirements(bench_path=bench_path)
|
|
||||||
update_node_packages(bench_path=bench_path)
|
|
||||||
|
|
||||||
if version_upgrade[0] or (not version_upgrade[0] and force):
|
|
||||||
pre_upgrade(version_upgrade[1], version_upgrade[2], bench_path=bench_path)
|
|
||||||
import bench.utils, bench.app
|
|
||||||
print('Reloading bench...')
|
|
||||||
reload_module(bench.utils)
|
|
||||||
reload_module(bench.app)
|
|
||||||
|
|
||||||
if patch:
|
|
||||||
print('Patching sites...')
|
|
||||||
patch_sites(bench_path=bench_path)
|
|
||||||
if build:
|
|
||||||
build_assets(bench_path=bench_path)
|
|
||||||
if version_upgrade[0] or (not version_upgrade[0] and force):
|
|
||||||
post_upgrade(version_upgrade[1], version_upgrade[2], bench_path=bench_path)
|
|
||||||
if restart_supervisor or conf.get('restart_supervisor_on_update'):
|
|
||||||
restart_supervisor_processes(bench_path=bench_path)
|
|
||||||
if restart_systemd or conf.get('restart_systemd_on_update'):
|
|
||||||
restart_systemd_processes(bench_path=bench_path)
|
|
||||||
|
|
||||||
conf.update({ "maintenance_mode": 0, "pause_scheduler": 0 })
|
|
||||||
update_config(conf, bench_path=bench_path)
|
|
||||||
|
|
||||||
print("_"*80)
|
|
||||||
print("Bench: Deployment tool for Frappe and ERPNext (https://erpnext.org).")
|
|
||||||
print("Open source depends on your contributions, so please contribute bug reports, patches, fixes or cash and be a part of the community")
|
|
||||||
print()
|
|
||||||
|
|
||||||
@click.command('retry-upgrade')
|
|
||||||
@click.option('--version', default=5)
|
@click.option('--version', default=5)
|
||||||
def retry_upgrade(version):
|
def retry_upgrade(version):
|
||||||
pull_all_apps()
|
pull_all_apps()
|
||||||
@ -126,35 +34,27 @@ def retry_upgrade(version):
|
|||||||
build_assets()
|
build_assets()
|
||||||
post_upgrade(version-1, version)
|
post_upgrade(version-1, version)
|
||||||
|
|
||||||
def restart_update(kwargs):
|
|
||||||
args = ['--'+k for k, v in list(kwargs.items()) if v]
|
|
||||||
os.execv(sys.argv[0], sys.argv[:2] + args)
|
|
||||||
|
|
||||||
@click.command('switch-to-branch')
|
@click.command('switch-to-branch', help="Switch all apps to specified branch, or specify apps separated by space")
|
||||||
@click.argument('branch')
|
@click.argument('branch')
|
||||||
@click.argument('apps', nargs=-1)
|
@click.argument('apps', nargs=-1)
|
||||||
@click.option('--upgrade',is_flag=True)
|
@click.option('--upgrade',is_flag=True)
|
||||||
def switch_to_branch(branch, apps, upgrade=False):
|
def switch_to_branch(branch, apps, upgrade=False):
|
||||||
"Switch all apps to specified branch, or specify apps separated by space"
|
|
||||||
from bench.app import switch_to_branch
|
from bench.app import switch_to_branch
|
||||||
switch_to_branch(branch=branch, apps=list(apps), upgrade=upgrade)
|
switch_to_branch(branch=branch, apps=list(apps), upgrade=upgrade)
|
||||||
print('Switched to ' + branch)
|
print('Switched to ' + branch)
|
||||||
print('Please run `bench update --patch` to be safe from any differences in database schema')
|
print('Please run `bench update --patch` to be safe from any differences in database schema')
|
||||||
|
|
||||||
@click.command('switch-to-master')
|
|
||||||
|
@click.command('switch-to-master', help="[DEPRECATED]: Switch frappe and erpnext to master branch")
|
||||||
def switch_to_master():
|
def switch_to_master():
|
||||||
"Switch frappe and erpnext to master branch"
|
from bench.utils import log
|
||||||
from bench.app import switch_to_master
|
log("`switch-to-master` has been deprecated as master branches were renamed to version-11")
|
||||||
switch_to_master(apps=['frappe', 'erpnext'])
|
|
||||||
print()
|
|
||||||
print('Switched to master')
|
|
||||||
print('Please run `bench update --patch` to be safe from any differences in database schema')
|
|
||||||
|
|
||||||
@click.command('switch-to-develop')
|
@click.command('switch-to-develop')
|
||||||
def switch_to_develop(upgrade=False):
|
def switch_to_develop(upgrade=False):
|
||||||
"Switch frappe and erpnext to develop branch"
|
"Switch frappe and erpnext to develop branch"
|
||||||
from bench.app import switch_to_develop
|
from bench.app import switch_to_develop
|
||||||
switch_to_develop(apps=['frappe', 'erpnext'])
|
switch_to_develop(apps=['frappe', 'erpnext'])
|
||||||
print()
|
print('Switched to develop\nPlease run `bench update --patch` to be safe from any differences in database schema')
|
||||||
print('Switched to develop')
|
|
||||||
print('Please run `bench update --patch` to be safe from any differences in database schema')
|
|
||||||
|
@ -1,23 +1,25 @@
|
|||||||
|
# imports - standard imports
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# imports - third party imports
|
||||||
import click
|
import click
|
||||||
import sys, os, copy
|
|
||||||
|
|
||||||
|
|
||||||
@click.command('start')
|
@click.command('start', help="Start Frappe development processes")
|
||||||
@click.option('--no-dev', is_flag=True, default=False)
|
@click.option('--no-dev', is_flag=True, default=False)
|
||||||
@click.option('--concurrency', '-c', type=str)
|
@click.option('--concurrency', '-c', type=str)
|
||||||
@click.option('--procfile', '-p', type=str)
|
@click.option('--procfile', '-p', type=str)
|
||||||
def start(no_dev, concurrency, procfile):
|
def start(no_dev, concurrency, procfile):
|
||||||
"Start Frappe development processes"
|
|
||||||
from bench.utils import start
|
from bench.utils import start
|
||||||
start(no_dev=no_dev, concurrency=concurrency, procfile=procfile)
|
start(no_dev=no_dev, concurrency=concurrency, procfile=procfile)
|
||||||
|
|
||||||
|
|
||||||
@click.command('restart')
|
@click.command('restart', help="Restart supervisor processes or systemd units")
|
||||||
@click.option('--web', is_flag=True, default=False)
|
@click.option('--web', is_flag=True, default=False)
|
||||||
@click.option('--supervisor', is_flag=True, default=False)
|
@click.option('--supervisor', is_flag=True, default=False)
|
||||||
@click.option('--systemd', is_flag=True, default=False)
|
@click.option('--systemd', is_flag=True, default=False)
|
||||||
def restart(web, supervisor, systemd):
|
def restart(web, supervisor, systemd):
|
||||||
"Restart supervisor processes or systemd units"
|
|
||||||
from bench.utils import restart_supervisor_processes, restart_systemd_processes
|
from bench.utils import restart_supervisor_processes, restart_systemd_processes
|
||||||
from bench.config.common_site_config import get_config
|
from bench.config.common_site_config import get_config
|
||||||
if get_config('.').get('restart_supervisor_on_update') or supervisor:
|
if get_config('.').get('restart_supervisor_on_update') or supervisor:
|
||||||
@ -25,134 +27,112 @@ def restart(web, supervisor, systemd):
|
|||||||
if get_config('.').get('restart_systemd_on_update') or systemd:
|
if get_config('.').get('restart_systemd_on_update') or systemd:
|
||||||
restart_systemd_processes(bench_path='.', web_workers=web)
|
restart_systemd_processes(bench_path='.', web_workers=web)
|
||||||
|
|
||||||
@click.command('set-nginx-port')
|
|
||||||
|
@click.command('set-nginx-port', help="Set NGINX port for site")
|
||||||
@click.argument('site')
|
@click.argument('site')
|
||||||
@click.argument('port', type=int)
|
@click.argument('port', type=int)
|
||||||
def set_nginx_port(site, port):
|
def set_nginx_port(site, port):
|
||||||
"Set nginx port for site"
|
|
||||||
from bench.config.site_config import set_nginx_port
|
from bench.config.site_config import set_nginx_port
|
||||||
set_nginx_port(site, port)
|
set_nginx_port(site, port)
|
||||||
|
|
||||||
|
|
||||||
@click.command('set-ssl-certificate')
|
@click.command('set-ssl-certificate', help="Set SSL certificate path for site")
|
||||||
@click.argument('site')
|
@click.argument('site')
|
||||||
@click.argument('ssl-certificate-path')
|
@click.argument('ssl-certificate-path')
|
||||||
def set_ssl_certificate(site, ssl_certificate_path):
|
def set_ssl_certificate(site, ssl_certificate_path):
|
||||||
"Set ssl certificate path for site"
|
|
||||||
from bench.config.site_config import set_ssl_certificate
|
from bench.config.site_config import set_ssl_certificate
|
||||||
set_ssl_certificate(site, ssl_certificate_path)
|
set_ssl_certificate(site, ssl_certificate_path)
|
||||||
|
|
||||||
|
|
||||||
@click.command('set-ssl-key')
|
@click.command('set-ssl-key', help="Set SSL certificate private key path for site")
|
||||||
@click.argument('site')
|
@click.argument('site')
|
||||||
@click.argument('ssl-certificate-key-path')
|
@click.argument('ssl-certificate-key-path')
|
||||||
def set_ssl_certificate_key(site, ssl_certificate_key_path):
|
def set_ssl_certificate_key(site, ssl_certificate_key_path):
|
||||||
"Set ssl certificate private key path for site"
|
|
||||||
from bench.config.site_config import set_ssl_certificate_key
|
from bench.config.site_config import set_ssl_certificate_key
|
||||||
set_ssl_certificate_key(site, ssl_certificate_key_path)
|
set_ssl_certificate_key(site, ssl_certificate_key_path)
|
||||||
|
|
||||||
|
|
||||||
@click.command('set-url-root')
|
@click.command('set-url-root', help="Set URL root for site")
|
||||||
@click.argument('site')
|
@click.argument('site')
|
||||||
@click.argument('url-root')
|
@click.argument('url-root')
|
||||||
def set_url_root(site, url_root):
|
def set_url_root(site, url_root):
|
||||||
"Set url root for site"
|
|
||||||
from bench.config.site_config import set_url_root
|
from bench.config.site_config import set_url_root
|
||||||
set_url_root(site, url_root)
|
set_url_root(site, url_root)
|
||||||
|
|
||||||
|
|
||||||
@click.command('set-mariadb-host')
|
@click.command('set-mariadb-host', help="Set MariaDB host for bench")
|
||||||
@click.argument('host')
|
@click.argument('host')
|
||||||
def set_mariadb_host(host):
|
def set_mariadb_host(host):
|
||||||
"Set MariaDB host for bench"
|
|
||||||
from bench.utils import set_mariadb_host
|
from bench.utils import set_mariadb_host
|
||||||
set_mariadb_host(host)
|
set_mariadb_host(host)
|
||||||
|
|
||||||
@click.command('set-redis-cache-host')
|
|
||||||
|
@click.command('set-redis-cache-host', help="Set Redis cache host for bench")
|
||||||
@click.argument('host')
|
@click.argument('host')
|
||||||
def set_redis_cache_host(host):
|
def set_redis_cache_host(host):
|
||||||
"""
|
"""
|
||||||
Set Redis cache host for bench
|
Usage: bench set-redis-cache-host localhost:6379/1
|
||||||
Eg: bench set-redis-cache-host localhost:6379/1
|
|
||||||
"""
|
"""
|
||||||
from bench.utils import set_redis_cache_host
|
from bench.utils import set_redis_cache_host
|
||||||
set_redis_cache_host(host)
|
set_redis_cache_host(host)
|
||||||
|
|
||||||
@click.command('set-redis-queue-host')
|
|
||||||
|
@click.command('set-redis-queue-host', help="Set Redis queue host for bench")
|
||||||
@click.argument('host')
|
@click.argument('host')
|
||||||
def set_redis_queue_host(host):
|
def set_redis_queue_host(host):
|
||||||
"""
|
"""
|
||||||
Set Redis queue host for bench
|
Usage: bench set-redis-queue-host localhost:6379/2
|
||||||
Eg: bench set-redis-queue-host localhost:6379/2
|
|
||||||
"""
|
"""
|
||||||
from bench.utils import set_redis_queue_host
|
from bench.utils import set_redis_queue_host
|
||||||
set_redis_queue_host(host)
|
set_redis_queue_host(host)
|
||||||
|
|
||||||
@click.command('set-redis-socketio-host')
|
|
||||||
|
@click.command('set-redis-socketio-host', help="Set Redis socketio host for bench")
|
||||||
@click.argument('host')
|
@click.argument('host')
|
||||||
def set_redis_socketio_host(host):
|
def set_redis_socketio_host(host):
|
||||||
"""
|
"""
|
||||||
Set Redis socketio host for bench
|
Usage: bench set-redis-socketio-host localhost:6379/3
|
||||||
Eg: bench set-redis-socketio-host localhost:6379/3
|
|
||||||
"""
|
"""
|
||||||
from bench.utils import set_redis_socketio_host
|
from bench.utils import set_redis_socketio_host
|
||||||
set_redis_socketio_host(host)
|
set_redis_socketio_host(host)
|
||||||
|
|
||||||
|
|
||||||
@click.command('set-default-site')
|
@click.command('set-default-site', help="Set default site for bench")
|
||||||
@click.argument('site')
|
@click.argument('site')
|
||||||
def set_default_site(site):
|
def set_default_site(site):
|
||||||
"Set default site for bench"
|
|
||||||
from bench.utils import set_default_site
|
from bench.utils import set_default_site
|
||||||
set_default_site(site)
|
set_default_site(site)
|
||||||
|
|
||||||
|
|
||||||
@click.command('download-translations')
|
@click.command('download-translations', help="Download latest translations")
|
||||||
def download_translations():
|
def download_translations():
|
||||||
"Download latest translations"
|
|
||||||
from bench.utils import download_translations_p
|
from bench.utils import download_translations_p
|
||||||
download_translations_p()
|
download_translations_p()
|
||||||
|
|
||||||
@click.command('renew-lets-encrypt')
|
|
||||||
|
@click.command('renew-lets-encrypt', help="Renew Let's Encrypt certificate")
|
||||||
def renew_lets_encrypt():
|
def renew_lets_encrypt():
|
||||||
"Renew Let's Encrypt certificate"
|
|
||||||
from bench.config.lets_encrypt import renew_certs
|
from bench.config.lets_encrypt import renew_certs
|
||||||
renew_certs()
|
renew_certs()
|
||||||
|
|
||||||
@click.command()
|
|
||||||
def shell(bench_path='.'):
|
|
||||||
if not os.environ.get('SHELL'):
|
|
||||||
print("Cannot get shell")
|
|
||||||
sys.exit(1)
|
|
||||||
if not os.path.exists('sites'):
|
|
||||||
print("sites dir doesn't exist")
|
|
||||||
sys.exit(1)
|
|
||||||
env = copy.copy(os.environ)
|
|
||||||
env['PS1'] = '(' + os.path.basename(os.path.dirname(os.path.abspath(__file__))) + ')' + env.get('PS1', '')
|
|
||||||
env['PATH'] = os.path.dirname(os.path.abspath(os.path.join('env','bin')) + ':' + env['PATH'])
|
|
||||||
os.chdir('sites')
|
|
||||||
os.execve(env['SHELL'], [env['SHELL']], env)
|
|
||||||
|
|
||||||
|
@click.command('backup', help="Backup single site")
|
||||||
@click.command('backup')
|
|
||||||
@click.argument('site')
|
@click.argument('site')
|
||||||
def backup_site(site):
|
def backup_site(site):
|
||||||
"backup site"
|
|
||||||
from bench.utils import get_sites, backup_site
|
from bench.utils import get_sites, backup_site
|
||||||
if site not in get_sites(bench_path='.'):
|
if site not in get_sites(bench_path='.'):
|
||||||
print('site not found')
|
print('Site `{0}` not found'.format(site))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
backup_site(site, bench_path='.')
|
backup_site(site, bench_path='.')
|
||||||
|
|
||||||
|
|
||||||
@click.command('backup-all-sites')
|
@click.command('backup-all-sites', help="Backup all sites in current bench")
|
||||||
def backup_all_sites():
|
def backup_all_sites():
|
||||||
"backup all sites"
|
|
||||||
from bench.utils import backup_all_sites
|
from bench.utils import backup_all_sites
|
||||||
backup_all_sites(bench_path='.')
|
backup_all_sites(bench_path='.')
|
||||||
|
|
||||||
|
|
||||||
@click.command('release')
|
@click.command('release', help="Release a Frappe app (internal to the Frappe team)")
|
||||||
@click.argument('app')
|
@click.argument('app')
|
||||||
@click.argument('bump-type', type=click.Choice(['major', 'minor', 'patch', 'stable', 'prerelease']))
|
@click.argument('bump-type', type=click.Choice(['major', 'minor', 'patch', 'stable', 'prerelease']))
|
||||||
@click.option('--from-branch', default='develop')
|
@click.option('--from-branch', default='develop')
|
||||||
@ -162,48 +142,41 @@ def backup_all_sites():
|
|||||||
@click.option('--repo-name')
|
@click.option('--repo-name')
|
||||||
@click.option('--dont-frontport', is_flag=True, default=False, help='Front port fixes to new branches, example merging hotfix(v10) into staging-fixes(v11)')
|
@click.option('--dont-frontport', is_flag=True, default=False, help='Front port fixes to new branches, example merging hotfix(v10) into staging-fixes(v11)')
|
||||||
def release(app, bump_type, from_branch, to_branch, owner, repo_name, remote, dont_frontport):
|
def release(app, bump_type, from_branch, to_branch, owner, repo_name, remote, dont_frontport):
|
||||||
"Release app (internal to the Frappe team)"
|
|
||||||
from bench.release import release
|
from bench.release import release
|
||||||
frontport = not dont_frontport
|
frontport = not dont_frontport
|
||||||
release(bench_path='.', app=app, bump_type=bump_type, from_branch=from_branch, to_branch=to_branch,
|
release(bench_path='.', app=app, bump_type=bump_type, from_branch=from_branch, to_branch=to_branch, remote=remote, owner=owner, repo_name=repo_name, frontport=frontport)
|
||||||
remote=remote, owner=owner, repo_name=repo_name, frontport=frontport)
|
|
||||||
|
|
||||||
|
|
||||||
@click.command('prepare-beta-release')
|
@click.command('prepare-beta-release', help="Prepare major beta release from develop branch")
|
||||||
@click.argument('app')
|
@click.argument('app')
|
||||||
@click.option('--owner', default='frappe')
|
@click.option('--owner', default='frappe')
|
||||||
def prepare_beta_release(app, owner):
|
def prepare_beta_release(app, owner):
|
||||||
"""Prepare major beta release from develop branch"""
|
|
||||||
from bench.prepare_beta_release import prepare_beta_release
|
from bench.prepare_beta_release import prepare_beta_release
|
||||||
prepare_beta_release(bench_path='.', app=app, owner=owner)
|
prepare_beta_release(bench_path='.', app=app, owner=owner)
|
||||||
|
|
||||||
|
|
||||||
@click.command('disable-production')
|
@click.command('disable-production', help="Disables production environment for the bench.")
|
||||||
def disable_production():
|
def disable_production():
|
||||||
"""Disables production environment for the bench."""
|
|
||||||
from bench.config.production_setup import disable_production
|
from bench.config.production_setup import disable_production
|
||||||
disable_production(bench_path='.')
|
disable_production(bench_path='.')
|
||||||
|
|
||||||
|
|
||||||
@click.command('src')
|
@click.command('src', help="Prints bench source folder path, which can be used as: cd `bench src`")
|
||||||
def bench_src():
|
def bench_src():
|
||||||
"""Prints bench source folder path, which can be used as: cd `bench src` """
|
|
||||||
import bench
|
import bench
|
||||||
print(os.path.dirname(bench.__path__[0]))
|
print(os.path.dirname(bench.__path__[0]))
|
||||||
|
|
||||||
|
|
||||||
@click.command('find')
|
@click.command('find', help="Finds benches recursively from location")
|
||||||
@click.argument('location', default='')
|
@click.argument('location', default='')
|
||||||
def find_benches(location):
|
def find_benches(location):
|
||||||
"""Finds benches recursively from location"""
|
|
||||||
from bench.utils import find_benches
|
from bench.utils import find_benches
|
||||||
find_benches(directory=location)
|
find_benches(directory=location)
|
||||||
|
|
||||||
|
|
||||||
@click.command('migrate-env')
|
@click.command('migrate-env', help="Migrate Virtual Environment to desired Python Version")
|
||||||
@click.argument('python', type=str)
|
@click.argument('python', type=str)
|
||||||
@click.option('--no-backup', 'backup', is_flag=True, default=True)
|
@click.option('--no-backup', 'backup', is_flag=True, default=True)
|
||||||
def migrate_env(python, backup=True):
|
def migrate_env(python, backup=True):
|
||||||
"""Migrate Virtual Environment to desired Python Version"""
|
|
||||||
from bench.utils import migrate_env
|
from bench.utils import migrate_env
|
||||||
migrate_env(python=python, backup=backup)
|
migrate_env(python=python, backup=backup)
|
||||||
|
@ -19,9 +19,7 @@ def prepare_staging(bench_path, app, remote='upstream'):
|
|||||||
print('No commits to release')
|
print('No commits to release')
|
||||||
return
|
return
|
||||||
|
|
||||||
print()
|
|
||||||
print(message)
|
print(message)
|
||||||
print()
|
|
||||||
|
|
||||||
click.confirm('Do you want to continue?', abort=True)
|
click.confirm('Do you want to continue?', abort=True)
|
||||||
|
|
||||||
|
@ -83,9 +83,7 @@ def bump(bench_path, app, bump_type, from_branch, to_branch, remote, owner, repo
|
|||||||
print('No commits to release')
|
print('No commits to release')
|
||||||
return
|
return
|
||||||
|
|
||||||
print()
|
|
||||||
print(message)
|
print(message)
|
||||||
print()
|
|
||||||
|
|
||||||
click.confirm('Do you want to continue?', abort=True)
|
click.confirm('Do you want to continue?', abort=True)
|
||||||
|
|
||||||
|
217
bench/utils.py
217
bench/utils.py
@ -1,14 +1,31 @@
|
|||||||
import errno, glob, grp, itertools, json, logging, multiprocessing, os, platform, pwd, re, select, shutil, site, subprocess, sys
|
# imports - standard imports
|
||||||
|
import errno
|
||||||
|
import glob
|
||||||
|
import grp
|
||||||
|
import itertools
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
|
import multiprocessing
|
||||||
|
import os
|
||||||
|
import platform
|
||||||
|
import pwd
|
||||||
|
import re
|
||||||
|
import select
|
||||||
|
import shutil
|
||||||
|
import site
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from distutils.spawn import find_executable
|
from distutils.spawn import find_executable
|
||||||
|
|
||||||
|
# imports - third party imports
|
||||||
|
import click
|
||||||
import requests
|
import requests
|
||||||
import semantic_version
|
|
||||||
from six import iteritems
|
from six import iteritems
|
||||||
from six.moves.urllib.parse import urlparse
|
from six.moves.urllib.parse import urlparse
|
||||||
|
|
||||||
|
# imports - module imports
|
||||||
import bench
|
import bench
|
||||||
from bench import env
|
|
||||||
|
|
||||||
|
|
||||||
class PatchError(Exception):
|
class PatchError(Exception):
|
||||||
@ -61,6 +78,7 @@ def safe_decode(string, encoding = 'utf-8'):
|
|||||||
pass
|
pass
|
||||||
return string
|
return string
|
||||||
|
|
||||||
|
|
||||||
def get_frappe(bench_path='.'):
|
def get_frappe(bench_path='.'):
|
||||||
frappe = get_env_cmd('frappe', bench_path=bench_path)
|
frappe = get_env_cmd('frappe', bench_path=bench_path)
|
||||||
if not os.path.exists(frappe):
|
if not os.path.exists(frappe):
|
||||||
@ -68,12 +86,16 @@ def get_frappe(bench_path='.'):
|
|||||||
print('bench get-app https://github.com/frappe/frappe.git')
|
print('bench get-app https://github.com/frappe/frappe.git')
|
||||||
return frappe
|
return frappe
|
||||||
|
|
||||||
|
|
||||||
def get_env_cmd(cmd, bench_path='.'):
|
def get_env_cmd(cmd, bench_path='.'):
|
||||||
return os.path.abspath(os.path.join(bench_path, 'env', 'bin', cmd))
|
return os.path.abspath(os.path.join(bench_path, 'env', 'bin', cmd))
|
||||||
|
|
||||||
def init(path, apps_path=None, no_procfile=False, no_backups=False, no_auto_update=False,
|
|
||||||
frappe_path=None, frappe_branch=None, wheel_cache_dir=None, verbose=False, clone_from=None,
|
def init(path, apps_path=None, no_procfile=False, no_backups=False,
|
||||||
skip_redis_config_generation=False, clone_without_update=False, ignore_exist = False, skip_assets=False, python='python3'):
|
frappe_path=None, frappe_branch=None, verbose=False, clone_from=None,
|
||||||
|
skip_redis_config_generation=False, clone_without_update=False, ignore_exist=False, skip_assets=False,
|
||||||
|
python='python3'):
|
||||||
|
"""Initialize a new bench directory"""
|
||||||
from bench.app import get_app, install_apps_from_path
|
from bench.app import get_app, install_apps_from_path
|
||||||
from bench.config import redis
|
from bench.config import redis
|
||||||
from bench.config.common_site_config import make_config
|
from bench.config.common_site_config import make_config
|
||||||
@ -128,14 +150,107 @@ def init(path, apps_path=None, no_procfile=False, no_backups=False, no_auto_upda
|
|||||||
setup_procfile(path)
|
setup_procfile(path)
|
||||||
if not no_backups:
|
if not no_backups:
|
||||||
setup_backups(bench_path=path)
|
setup_backups(bench_path=path)
|
||||||
if not no_auto_update:
|
|
||||||
setup_auto_update(bench_path=path)
|
|
||||||
copy_patches_txt(path)
|
copy_patches_txt(path)
|
||||||
|
|
||||||
|
|
||||||
|
def restart_update(kwargs):
|
||||||
|
args = ['--'+k for k, v in list(kwargs.items()) if v]
|
||||||
|
os.execv(sys.argv[0], sys.argv[:2] + args)
|
||||||
|
|
||||||
|
|
||||||
|
def update(pull=False, patch=False, build=False, bench=False, restart_supervisor=False,
|
||||||
|
restart_systemd=False, requirements=False, backup=True, force=False, reset=False):
|
||||||
|
"""command: bench update"""
|
||||||
|
|
||||||
|
if not is_bench_directory():
|
||||||
|
"""Update only bench CLI if bench update called from outside a bench"""
|
||||||
|
update_bench(bench_repo=True, requirements=True)
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
from bench import patches
|
||||||
|
from bench.app import is_version_upgrade, pull_all_apps, validate_branch
|
||||||
|
from bench.config.common_site_config import get_config, update_config
|
||||||
|
|
||||||
|
bench_path = os.path.abspath(".")
|
||||||
|
patches.run(bench_path=bench_path)
|
||||||
|
conf = get_config(bench_path)
|
||||||
|
|
||||||
|
if conf.get('release_bench'):
|
||||||
|
print('Release bench detected, cannot update!')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if not (pull or patch or build or bench or requirements):
|
||||||
|
pull, patch, build, bench, requirements = True, True, True, True, True
|
||||||
|
|
||||||
|
if bench and conf.get('update_bench_on_update'):
|
||||||
|
update_bench(bench_repo=True, requirements=False)
|
||||||
|
restart_update({
|
||||||
|
'pull': pull,
|
||||||
|
'patch': patch,
|
||||||
|
'build': build,
|
||||||
|
'requirements': requirements,
|
||||||
|
'backup': backup,
|
||||||
|
'restart-supervisor': restart_supervisor,
|
||||||
|
'reset': reset
|
||||||
|
})
|
||||||
|
|
||||||
|
validate_branch()
|
||||||
|
version_upgrade = is_version_upgrade()
|
||||||
|
|
||||||
|
if version_upgrade[0]:
|
||||||
|
if force:
|
||||||
|
print("Force flag has been used for a major version change in Frappe and it's apps. \nThis will take significant time to migrate and might break custom apps.")
|
||||||
|
else:
|
||||||
|
print("This update will cause a major version change in Frappe/ERPNext from {0} to {1}. \nThis would take significant time to migrate and might break custom apps.".format(*version_upgrade[1:]))
|
||||||
|
click.confirm('Do you want to continue?', abort=True)
|
||||||
|
|
||||||
|
if version_upgrade[0] or (not version_upgrade[0] and force):
|
||||||
|
validate_upgrade(version_upgrade[1], version_upgrade[2], bench_path=bench_path)
|
||||||
|
|
||||||
|
before_update(bench_path=bench_path, requirements=requirements)
|
||||||
|
|
||||||
|
conf.update({ "maintenance_mode": 1, "pause_scheduler": 1 })
|
||||||
|
update_config(conf, bench_path=bench_path)
|
||||||
|
|
||||||
|
if backup:
|
||||||
|
print('Backing up sites...')
|
||||||
|
backup_all_sites(bench_path=bench_path)
|
||||||
|
|
||||||
|
if pull:
|
||||||
|
pull_all_apps(bench_path=bench_path, reset=reset)
|
||||||
|
|
||||||
|
if requirements:
|
||||||
|
update_requirements(bench_path=bench_path)
|
||||||
|
update_node_packages(bench_path=bench_path)
|
||||||
|
|
||||||
|
if patch:
|
||||||
|
print('Patching sites...')
|
||||||
|
patch_sites(bench_path=bench_path)
|
||||||
|
|
||||||
|
if build:
|
||||||
|
build_assets(bench_path=bench_path)
|
||||||
|
|
||||||
|
if version_upgrade[0] or (not version_upgrade[0] and force):
|
||||||
|
post_upgrade(version_upgrade[1], version_upgrade[2], bench_path=bench_path)
|
||||||
|
|
||||||
|
if restart_supervisor or conf.get('restart_supervisor_on_update'):
|
||||||
|
restart_supervisor_processes(bench_path=bench_path)
|
||||||
|
|
||||||
|
if restart_systemd or conf.get('restart_systemd_on_update'):
|
||||||
|
restart_systemd_processes(bench_path=bench_path)
|
||||||
|
|
||||||
|
conf.update({ "maintenance_mode": 0, "pause_scheduler": 0 })
|
||||||
|
update_config(conf, bench_path=bench_path)
|
||||||
|
|
||||||
|
print("_" * 80 + "\nBench: Deployment tool for Frappe and Frappe Applications (https://frappe.io/bench).\nOpen source depends on your contributions, so please contribute bug reports, patches, fixes or cash and be a part of the community")
|
||||||
|
|
||||||
|
|
||||||
def copy_patches_txt(bench_path):
|
def copy_patches_txt(bench_path):
|
||||||
shutil.copy(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'patches', 'patches.txt'),
|
shutil.copy(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'patches', 'patches.txt'),
|
||||||
os.path.join(bench_path, 'patches.txt'))
|
os.path.join(bench_path, 'patches.txt'))
|
||||||
|
|
||||||
|
|
||||||
def clone_apps_from(bench_path, clone_from, update_app=True):
|
def clone_apps_from(bench_path, clone_from, update_app=True):
|
||||||
from .app import install_app
|
from .app import install_app
|
||||||
print('Copying apps from {0}...'.format(clone_from))
|
print('Copying apps from {0}...'.format(clone_from))
|
||||||
@ -172,14 +287,15 @@ def clone_apps_from(bench_path, clone_from, update_app=True):
|
|||||||
for app in apps:
|
for app in apps:
|
||||||
setup_app(app)
|
setup_app(app)
|
||||||
|
|
||||||
|
|
||||||
def exec_cmd(cmd, cwd='.'):
|
def exec_cmd(cmd, cwd='.'):
|
||||||
import shlex
|
import shlex
|
||||||
print("{0}$ {1}{2}".format(color.silver, cmd, color.nc))
|
print("{0}$ {1}{2}".format(color.silver, cmd, color.nc))
|
||||||
cmd = shlex.split(cmd)
|
cmd = shlex.split(cmd)
|
||||||
subprocess.call(cmd, cwd=cwd, universal_newlines=True)
|
subprocess.call(cmd, cwd=cwd, universal_newlines=True)
|
||||||
|
|
||||||
|
|
||||||
def which(executable, raise_err = False):
|
def which(executable, raise_err = False):
|
||||||
from distutils.spawn import find_executable
|
|
||||||
exec_ = find_executable(executable)
|
exec_ = find_executable(executable)
|
||||||
|
|
||||||
if not exec_ and raise_err:
|
if not exec_ and raise_err:
|
||||||
@ -189,6 +305,7 @@ def which(executable, raise_err = False):
|
|||||||
|
|
||||||
return exec_
|
return exec_
|
||||||
|
|
||||||
|
|
||||||
def setup_env(bench_path='.', python = 'python3'):
|
def setup_env(bench_path='.', python = 'python3'):
|
||||||
python = which(python, raise_err = True)
|
python = which(python, raise_err = True)
|
||||||
pip = os.path.join('env', 'bin', 'pip')
|
pip = os.path.join('env', 'bin', 'pip')
|
||||||
@ -197,10 +314,12 @@ def setup_env(bench_path='.', python = 'python3'):
|
|||||||
exec_cmd('{} -q install -U pip wheel six'.format(pip), cwd=bench_path)
|
exec_cmd('{} -q install -U pip wheel six'.format(pip), cwd=bench_path)
|
||||||
exec_cmd('{} -q install -e git+https://github.com/frappe/python-pdfkit.git#egg=pdfkit'.format(pip), cwd=bench_path)
|
exec_cmd('{} -q install -e git+https://github.com/frappe/python-pdfkit.git#egg=pdfkit'.format(pip), cwd=bench_path)
|
||||||
|
|
||||||
|
|
||||||
def setup_socketio(bench_path='.'):
|
def setup_socketio(bench_path='.'):
|
||||||
exec_cmd("npm install socket.io redis express superagent cookie babel-core less chokidar \
|
exec_cmd("npm install socket.io redis express superagent cookie babel-core less chokidar \
|
||||||
babel-cli babel-preset-es2015 babel-preset-es2016 babel-preset-es2017 babel-preset-babili", cwd=bench_path)
|
babel-cli babel-preset-es2015 babel-preset-es2016 babel-preset-es2017 babel-preset-babili", cwd=bench_path)
|
||||||
|
|
||||||
|
|
||||||
def patch_sites(bench_path='.'):
|
def patch_sites(bench_path='.'):
|
||||||
bench.set_frappe_version(bench_path=bench_path)
|
bench.set_frappe_version(bench_path=bench_path)
|
||||||
|
|
||||||
@ -212,6 +331,7 @@ def patch_sites(bench_path='.'):
|
|||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
raise PatchError
|
raise PatchError
|
||||||
|
|
||||||
|
|
||||||
def build_assets(bench_path='.', app=None):
|
def build_assets(bench_path='.', app=None):
|
||||||
bench.set_frappe_version(bench_path=bench_path)
|
bench.set_frappe_version(bench_path=bench_path)
|
||||||
|
|
||||||
@ -223,19 +343,16 @@ def build_assets(bench_path='.', app=None):
|
|||||||
command += ' --app {}'.format(app)
|
command += ' --app {}'.format(app)
|
||||||
exec_cmd(command, cwd=bench_path)
|
exec_cmd(command, cwd=bench_path)
|
||||||
|
|
||||||
|
|
||||||
def get_sites(bench_path='.'):
|
def get_sites(bench_path='.'):
|
||||||
sites_path = os.path.join(bench_path, 'sites')
|
sites_path = os.path.join(bench_path, 'sites')
|
||||||
sites = (site for site in os.listdir(sites_path) if os.path.exists(os.path.join(sites_path, site, 'site_config.json')))
|
sites = (site for site in os.listdir(sites_path) if os.path.exists(os.path.join(sites_path, site, 'site_config.json')))
|
||||||
return sites
|
return sites
|
||||||
|
|
||||||
|
|
||||||
def get_bench_dir(bench_path='.'):
|
def get_bench_dir(bench_path='.'):
|
||||||
return os.path.abspath(bench_path)
|
return os.path.abspath(bench_path)
|
||||||
|
|
||||||
def setup_auto_update(bench_path='.'):
|
|
||||||
logger.info('setting up auto update')
|
|
||||||
add_to_crontab('0 10 * * * cd {bench_dir} && {bench} update --auto >> {logfile} 2>&1'.format(bench_dir=get_bench_dir(bench_path=bench_path),
|
|
||||||
bench=os.path.join(get_bench_dir(bench_path=bench_path), 'env', 'bin', 'bench'),
|
|
||||||
logfile=os.path.join(get_bench_dir(bench_path=bench_path), 'logs', 'auto_update_log.log')))
|
|
||||||
|
|
||||||
def setup_backups(bench_path='.'):
|
def setup_backups(bench_path='.'):
|
||||||
logger.info('setting up backups')
|
logger.info('setting up backups')
|
||||||
@ -250,6 +367,7 @@ def setup_backups(bench_path='.'):
|
|||||||
add_to_crontab('0 */6 * * * {backup_command} >> {logfile} 2>&1'.format(backup_command=backup_command,
|
add_to_crontab('0 */6 * * * {backup_command} >> {logfile} 2>&1'.format(backup_command=backup_command,
|
||||||
logfile=os.path.join(get_bench_dir(bench_path=bench_path), 'logs', 'backup.log')))
|
logfile=os.path.join(get_bench_dir(bench_path=bench_path), 'logs', 'backup.log')))
|
||||||
|
|
||||||
|
|
||||||
def add_to_crontab(line):
|
def add_to_crontab(line):
|
||||||
current_crontab = read_crontab()
|
current_crontab = read_crontab()
|
||||||
line = str.encode(line)
|
line = str.encode(line)
|
||||||
@ -262,12 +380,14 @@ def add_to_crontab(line):
|
|||||||
s.stdin.write(line + b'\n')
|
s.stdin.write(line + b'\n')
|
||||||
s.stdin.close()
|
s.stdin.close()
|
||||||
|
|
||||||
|
|
||||||
def read_crontab():
|
def read_crontab():
|
||||||
s = subprocess.Popen(["crontab", "-l"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
s = subprocess.Popen(["crontab", "-l"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
||||||
out = s.stdout.read()
|
out = s.stdout.read()
|
||||||
s.stdout.close()
|
s.stdout.close()
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
def update_bench(bench_repo=True, requirements=True):
|
def update_bench(bench_repo=True, requirements=True):
|
||||||
logger.info("Updating bench")
|
logger.info("Updating bench")
|
||||||
|
|
||||||
@ -286,7 +406,10 @@ def update_bench(bench_repo=True, requirements=True):
|
|||||||
|
|
||||||
logger.info("Bench Updated!")
|
logger.info("Bench Updated!")
|
||||||
|
|
||||||
|
|
||||||
def setup_sudoers(user):
|
def setup_sudoers(user):
|
||||||
|
from bench import env
|
||||||
|
|
||||||
if not os.path.exists('/etc/sudoers.d'):
|
if not os.path.exists('/etc/sudoers.d'):
|
||||||
os.makedirs('/etc/sudoers.d')
|
os.makedirs('/etc/sudoers.d')
|
||||||
|
|
||||||
@ -318,6 +441,7 @@ def setup_sudoers(user):
|
|||||||
|
|
||||||
os.chmod(sudoers_file, 0o440)
|
os.chmod(sudoers_file, 0o440)
|
||||||
|
|
||||||
|
|
||||||
def setup_logging(bench_path='.'):
|
def setup_logging(bench_path='.'):
|
||||||
if os.path.exists(os.path.join(bench_path, 'logs')):
|
if os.path.exists(os.path.join(bench_path, 'logs')):
|
||||||
logger = logging.getLogger('bench')
|
logger = logging.getLogger('bench')
|
||||||
@ -328,6 +452,7 @@ def setup_logging(bench_path='.'):
|
|||||||
logger.addHandler(hdlr)
|
logger.addHandler(hdlr)
|
||||||
logger.setLevel(logging.DEBUG)
|
logger.setLevel(logging.DEBUG)
|
||||||
|
|
||||||
|
|
||||||
def get_program(programs):
|
def get_program(programs):
|
||||||
program = None
|
program = None
|
||||||
for p in programs:
|
for p in programs:
|
||||||
@ -336,9 +461,11 @@ def get_program(programs):
|
|||||||
break
|
break
|
||||||
return program
|
return program
|
||||||
|
|
||||||
|
|
||||||
def get_process_manager():
|
def get_process_manager():
|
||||||
return get_program(['foreman', 'forego', 'honcho'])
|
return get_program(['foreman', 'forego', 'honcho'])
|
||||||
|
|
||||||
|
|
||||||
def start(no_dev=False, concurrency=None, procfile=None):
|
def start(no_dev=False, concurrency=None, procfile=None):
|
||||||
program = get_process_manager()
|
program = get_process_manager()
|
||||||
if not program:
|
if not program:
|
||||||
@ -356,6 +483,7 @@ def start(no_dev=False, concurrency=None, procfile=None):
|
|||||||
|
|
||||||
os.execv(program, command)
|
os.execv(program, command)
|
||||||
|
|
||||||
|
|
||||||
def check_cmd(cmd, cwd='.'):
|
def check_cmd(cmd, cwd='.'):
|
||||||
try:
|
try:
|
||||||
subprocess.check_call(cmd, cwd=cwd, shell=True)
|
subprocess.check_call(cmd, cwd=cwd, shell=True)
|
||||||
@ -363,6 +491,7 @@ def check_cmd(cmd, cwd='.'):
|
|||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def get_git_version():
|
def get_git_version():
|
||||||
'''returns git version from `git --version`
|
'''returns git version from `git --version`
|
||||||
extracts version number from string `get version 1.9.1` etc'''
|
extracts version number from string `get version 1.9.1` etc'''
|
||||||
@ -372,6 +501,7 @@ def get_git_version():
|
|||||||
version = '.'.join(version.split('.')[0:2])
|
version = '.'.join(version.split('.')[0:2])
|
||||||
return float(version)
|
return float(version)
|
||||||
|
|
||||||
|
|
||||||
def check_git_for_shallow_clone():
|
def check_git_for_shallow_clone():
|
||||||
from .config.common_site_config import get_config
|
from .config.common_site_config import get_config
|
||||||
config = get_config('.')
|
config = get_config('.')
|
||||||
@ -387,6 +517,7 @@ def check_git_for_shallow_clone():
|
|||||||
if git_version > 1.9:
|
if git_version > 1.9:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def get_cmd_output(cmd, cwd='.'):
|
def get_cmd_output(cmd, cwd='.'):
|
||||||
try:
|
try:
|
||||||
output = subprocess.check_output(cmd, cwd=cwd, shell=True, stderr=subprocess.PIPE).strip()
|
output = subprocess.check_output(cmd, cwd=cwd, shell=True, stderr=subprocess.PIPE).strip()
|
||||||
@ -397,6 +528,7 @@ def get_cmd_output(cmd, cwd='.'):
|
|||||||
print(e.output)
|
print(e.output)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
def safe_encode(what, encoding = 'utf-8'):
|
def safe_encode(what, encoding = 'utf-8'):
|
||||||
try:
|
try:
|
||||||
what = what.encode(encoding)
|
what = what.encode(encoding)
|
||||||
@ -405,6 +537,7 @@ def safe_encode(what, encoding = 'utf-8'):
|
|||||||
|
|
||||||
return what
|
return what
|
||||||
|
|
||||||
|
|
||||||
def restart_supervisor_processes(bench_path='.', web_workers=False):
|
def restart_supervisor_processes(bench_path='.', web_workers=False):
|
||||||
from .config.common_site_config import get_config
|
from .config.common_site_config import get_config
|
||||||
conf = get_config(bench_path=bench_path)
|
conf = get_config(bench_path=bench_path)
|
||||||
@ -434,26 +567,31 @@ def restart_supervisor_processes(bench_path='.', web_workers=False):
|
|||||||
|
|
||||||
exec_cmd('sudo supervisorctl restart {group}'.format(group=group), cwd=bench_path)
|
exec_cmd('sudo supervisorctl restart {group}'.format(group=group), cwd=bench_path)
|
||||||
|
|
||||||
|
|
||||||
def restart_systemd_processes(bench_path='.', web_workers=False):
|
def restart_systemd_processes(bench_path='.', web_workers=False):
|
||||||
from .config.common_site_config import get_config
|
from .config.common_site_config import get_config
|
||||||
bench_name = get_bench_name(bench_path)
|
bench_name = get_bench_name(bench_path)
|
||||||
exec_cmd('sudo systemctl stop -- $(systemctl show -p Requires {bench_name}.target | cut -d= -f2)'.format(bench_name=bench_name))
|
exec_cmd('sudo systemctl stop -- $(systemctl show -p Requires {bench_name}.target | cut -d= -f2)'.format(bench_name=bench_name))
|
||||||
exec_cmd('sudo systemctl start -- $(systemctl show -p Requires {bench_name}.target | cut -d= -f2)'.format(bench_name=bench_name))
|
exec_cmd('sudo systemctl start -- $(systemctl show -p Requires {bench_name}.target | cut -d= -f2)'.format(bench_name=bench_name))
|
||||||
|
|
||||||
|
|
||||||
def set_default_site(site, bench_path='.'):
|
def set_default_site(site, bench_path='.'):
|
||||||
if site not in get_sites(bench_path=bench_path):
|
if site not in get_sites(bench_path=bench_path):
|
||||||
raise Exception("Site not in bench")
|
raise Exception("Site not in bench")
|
||||||
exec_cmd("{frappe} --use {site}".format(frappe=get_frappe(bench_path=bench_path), site=site),
|
exec_cmd("{frappe} --use {site}".format(frappe=get_frappe(bench_path=bench_path), site=site),
|
||||||
cwd=os.path.join(bench_path, 'sites'))
|
cwd=os.path.join(bench_path, 'sites'))
|
||||||
|
|
||||||
|
|
||||||
def update_bench_requirements():
|
def update_bench_requirements():
|
||||||
bench_req_file = os.path.join(os.path.dirname(bench.__path__[0]), 'requirements.txt')
|
bench_req_file = os.path.join(os.path.dirname(bench.__path__[0]), 'requirements.txt')
|
||||||
install_requirements(bench_req_file, user=True)
|
install_requirements(bench_req_file, user=True)
|
||||||
|
|
||||||
|
|
||||||
def update_env_pip(bench_path):
|
def update_env_pip(bench_path):
|
||||||
env_pip = os.path.join(bench_path, 'env', 'bin', 'pip')
|
env_pip = os.path.join(bench_path, 'env', 'bin', 'pip')
|
||||||
exec_cmd("{pip} install -q -U pip".format(pip=env_pip))
|
exec_cmd("{pip} install -q -U pip".format(pip=env_pip))
|
||||||
|
|
||||||
|
|
||||||
def update_requirements(bench_path='.'):
|
def update_requirements(bench_path='.'):
|
||||||
from bench.app import get_apps, install_app
|
from bench.app import get_apps, install_app
|
||||||
print('Updating Python libraries...')
|
print('Updating Python libraries...')
|
||||||
@ -467,13 +605,13 @@ def update_requirements(bench_path='.'):
|
|||||||
for app in get_apps():
|
for app in get_apps():
|
||||||
install_app(app, bench_path=bench_path)
|
install_app(app, bench_path=bench_path)
|
||||||
|
|
||||||
|
|
||||||
def update_node_packages(bench_path='.'):
|
def update_node_packages(bench_path='.'):
|
||||||
print('Updating node packages...')
|
print('Updating node packages...')
|
||||||
from bench.app import get_develop_version
|
from bench.app import get_develop_version
|
||||||
from distutils.version import LooseVersion
|
from distutils.version import LooseVersion
|
||||||
v = LooseVersion(get_develop_version('frappe', bench_path = bench_path))
|
v = LooseVersion(get_develop_version('frappe', bench_path = bench_path))
|
||||||
|
|
||||||
|
|
||||||
# After rollup was merged, frappe_version = 10.1
|
# After rollup was merged, frappe_version = 10.1
|
||||||
# if develop_verion is 11 and up, only then install yarn
|
# if develop_verion is 11 and up, only then install yarn
|
||||||
if v < LooseVersion('11.x.x-develop'):
|
if v < LooseVersion('11.x.x-develop'):
|
||||||
@ -481,6 +619,7 @@ def update_node_packages(bench_path='.'):
|
|||||||
else:
|
else:
|
||||||
update_yarn_packages(bench_path)
|
update_yarn_packages(bench_path)
|
||||||
|
|
||||||
|
|
||||||
def update_yarn_packages(bench_path='.'):
|
def update_yarn_packages(bench_path='.'):
|
||||||
apps_dir = os.path.join(bench_path, 'apps')
|
apps_dir = os.path.join(bench_path, 'apps')
|
||||||
|
|
||||||
@ -541,6 +680,7 @@ def install_requirements(req_file, user=False):
|
|||||||
|
|
||||||
exec_cmd("{python} -m pip install {user_flag} -q -U -r {req_file}".format(python=python, user_flag=user_flag, req_file=req_file))
|
exec_cmd("{python} -m pip install {user_flag} -q -U -r {req_file}".format(python=python, user_flag=user_flag, req_file=req_file))
|
||||||
|
|
||||||
|
|
||||||
def backup_site(site, bench_path='.'):
|
def backup_site(site, bench_path='.'):
|
||||||
bench.set_frappe_version(bench_path=bench_path)
|
bench.set_frappe_version(bench_path=bench_path)
|
||||||
|
|
||||||
@ -550,30 +690,38 @@ def backup_site(site, bench_path='.'):
|
|||||||
else:
|
else:
|
||||||
run_frappe_cmd('--site', site, 'backup', bench_path=bench_path)
|
run_frappe_cmd('--site', site, 'backup', bench_path=bench_path)
|
||||||
|
|
||||||
|
|
||||||
def backup_all_sites(bench_path='.'):
|
def backup_all_sites(bench_path='.'):
|
||||||
for site in get_sites(bench_path=bench_path):
|
for site in get_sites(bench_path=bench_path):
|
||||||
backup_site(site, bench_path=bench_path)
|
backup_site(site, bench_path=bench_path)
|
||||||
|
|
||||||
|
|
||||||
def is_root():
|
def is_root():
|
||||||
if os.getuid() == 0:
|
if os.getuid() == 0:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def set_mariadb_host(host, bench_path='.'):
|
def set_mariadb_host(host, bench_path='.'):
|
||||||
update_common_site_config({'db_host': host}, bench_path=bench_path)
|
update_common_site_config({'db_host': host}, bench_path=bench_path)
|
||||||
|
|
||||||
|
|
||||||
def set_redis_cache_host(host, bench_path='.'):
|
def set_redis_cache_host(host, bench_path='.'):
|
||||||
update_common_site_config({'redis_cache': "redis://{}".format(host)}, bench_path=bench_path)
|
update_common_site_config({'redis_cache': "redis://{}".format(host)}, bench_path=bench_path)
|
||||||
|
|
||||||
|
|
||||||
def set_redis_queue_host(host, bench_path='.'):
|
def set_redis_queue_host(host, bench_path='.'):
|
||||||
update_common_site_config({'redis_queue': "redis://{}".format(host)}, bench_path=bench_path)
|
update_common_site_config({'redis_queue': "redis://{}".format(host)}, bench_path=bench_path)
|
||||||
|
|
||||||
|
|
||||||
def set_redis_socketio_host(host, bench_path='.'):
|
def set_redis_socketio_host(host, bench_path='.'):
|
||||||
update_common_site_config({'redis_socketio': "redis://{}".format(host)}, bench_path=bench_path)
|
update_common_site_config({'redis_socketio': "redis://{}".format(host)}, bench_path=bench_path)
|
||||||
|
|
||||||
|
|
||||||
def update_common_site_config(ddict, bench_path='.'):
|
def update_common_site_config(ddict, bench_path='.'):
|
||||||
update_json_file(os.path.join(bench_path, 'sites', 'common_site_config.json'), ddict)
|
update_json_file(os.path.join(bench_path, 'sites', 'common_site_config.json'), ddict)
|
||||||
|
|
||||||
|
|
||||||
def update_json_file(filename, ddict):
|
def update_json_file(filename, ddict):
|
||||||
if os.path.exists(filename):
|
if os.path.exists(filename):
|
||||||
with open(filename, 'r') as f:
|
with open(filename, 'r') as f:
|
||||||
@ -586,6 +734,7 @@ def update_json_file(filename, ddict):
|
|||||||
with open(filename, 'w') as f:
|
with open(filename, 'w') as f:
|
||||||
json.dump(content, f, indent=1, sort_keys=True)
|
json.dump(content, f, indent=1, sort_keys=True)
|
||||||
|
|
||||||
|
|
||||||
def drop_privileges(uid_name='nobody', gid_name='nogroup'):
|
def drop_privileges(uid_name='nobody', gid_name='nogroup'):
|
||||||
# from http://stackoverflow.com/a/2699996
|
# from http://stackoverflow.com/a/2699996
|
||||||
if os.getuid() != 0:
|
if os.getuid() != 0:
|
||||||
@ -606,6 +755,7 @@ def drop_privileges(uid_name='nobody', gid_name='nogroup'):
|
|||||||
# Ensure a very conservative umask
|
# Ensure a very conservative umask
|
||||||
os.umask(0o22)
|
os.umask(0o22)
|
||||||
|
|
||||||
|
|
||||||
def fix_prod_setup_perms(bench_path='.', frappe_user=None):
|
def fix_prod_setup_perms(bench_path='.', frappe_user=None):
|
||||||
from .config.common_site_config import get_config
|
from .config.common_site_config import get_config
|
||||||
|
|
||||||
@ -623,6 +773,7 @@ def fix_prod_setup_perms(bench_path='.', frappe_user=None):
|
|||||||
gid = grp.getgrnam(frappe_user).gr_gid
|
gid = grp.getgrnam(frappe_user).gr_gid
|
||||||
os.chown(path, uid, gid)
|
os.chown(path, uid, gid)
|
||||||
|
|
||||||
|
|
||||||
def fix_file_perms():
|
def fix_file_perms():
|
||||||
for dir_path, dirs, files in os.walk('.'):
|
for dir_path, dirs, files in os.walk('.'):
|
||||||
for _dir in dirs:
|
for _dir in dirs:
|
||||||
@ -635,10 +786,12 @@ def fix_file_perms():
|
|||||||
if not _file.startswith('activate'):
|
if not _file.startswith('activate'):
|
||||||
os.chmod(os.path.join(bin_dir, _file), 0o755)
|
os.chmod(os.path.join(bin_dir, _file), 0o755)
|
||||||
|
|
||||||
|
|
||||||
def get_current_frappe_version(bench_path='.'):
|
def get_current_frappe_version(bench_path='.'):
|
||||||
from .app import get_current_frappe_version as fv
|
from .app import get_current_frappe_version as fv
|
||||||
return fv(bench_path=bench_path)
|
return fv(bench_path=bench_path)
|
||||||
|
|
||||||
|
|
||||||
def run_frappe_cmd(*args, **kwargs):
|
def run_frappe_cmd(*args, **kwargs):
|
||||||
from .cli import from_command_line
|
from .cli import from_command_line
|
||||||
|
|
||||||
@ -662,7 +815,7 @@ def run_frappe_cmd(*args, **kwargs):
|
|||||||
|
|
||||||
if return_code > 0:
|
if return_code > 0:
|
||||||
sys.exit(return_code)
|
sys.exit(return_code)
|
||||||
#raise CommandFailedError(args)
|
|
||||||
|
|
||||||
def get_frappe_cmd_output(*args, **kwargs):
|
def get_frappe_cmd_output(*args, **kwargs):
|
||||||
bench_path = kwargs.get('bench_path', '.')
|
bench_path = kwargs.get('bench_path', '.')
|
||||||
@ -670,24 +823,12 @@ def get_frappe_cmd_output(*args, **kwargs):
|
|||||||
sites_dir = os.path.join(bench_path, 'sites')
|
sites_dir = os.path.join(bench_path, 'sites')
|
||||||
return subprocess.check_output((f, '-m', 'frappe.utils.bench_helper', 'frappe') + args, cwd=sites_dir)
|
return subprocess.check_output((f, '-m', 'frappe.utils.bench_helper', 'frappe') + args, cwd=sites_dir)
|
||||||
|
|
||||||
|
|
||||||
def validate_upgrade(from_ver, to_ver, bench_path='.'):
|
def validate_upgrade(from_ver, to_ver, bench_path='.'):
|
||||||
if to_ver >= 6:
|
if to_ver >= 6:
|
||||||
if not find_executable('npm') and not (find_executable('node') or find_executable('nodejs')):
|
if not find_executable('npm') and not (find_executable('node') or find_executable('nodejs')):
|
||||||
raise Exception("Please install nodejs and npm")
|
raise Exception("Please install nodejs and npm")
|
||||||
|
|
||||||
def pre_upgrade(from_ver, to_ver, bench_path='.'):
|
|
||||||
pip = os.path.join(bench_path, 'env', 'bin', 'pip')
|
|
||||||
|
|
||||||
if from_ver <= 4 and to_ver >= 5:
|
|
||||||
from .migrate_to_v5 import remove_shopping_cart
|
|
||||||
apps = ('frappe', 'erpnext')
|
|
||||||
remove_shopping_cart(bench_path=bench_path)
|
|
||||||
|
|
||||||
for app in apps:
|
|
||||||
cwd = os.path.abspath(os.path.join(bench_path, 'apps', app))
|
|
||||||
if os.path.exists(cwd):
|
|
||||||
exec_cmd("git clean -dxf", cwd=cwd)
|
|
||||||
exec_cmd("{pip} install --upgrade -e {app}".format(pip=pip, app=cwd))
|
|
||||||
|
|
||||||
def post_upgrade(from_ver, to_ver, bench_path='.'):
|
def post_upgrade(from_ver, to_ver, bench_path='.'):
|
||||||
from .config.common_site_config import get_config
|
from .config.common_site_config import get_config
|
||||||
@ -695,8 +836,7 @@ def post_upgrade(from_ver, to_ver, bench_path='.'):
|
|||||||
from .config.supervisor import generate_supervisor_config
|
from .config.supervisor import generate_supervisor_config
|
||||||
from .config.nginx import make_nginx_conf
|
from .config.nginx import make_nginx_conf
|
||||||
conf = get_config(bench_path=bench_path)
|
conf = get_config(bench_path=bench_path)
|
||||||
print("-"*80)
|
print("-" * 80 + "Your bench was upgraded to version {0}".format(to_ver))
|
||||||
print("Your bench was upgraded to version {0}".format(to_ver))
|
|
||||||
|
|
||||||
if conf.get('restart_supervisor_on_update'):
|
if conf.get('restart_supervisor_on_update'):
|
||||||
redis.generate_config(bench_path=bench_path)
|
redis.generate_config(bench_path=bench_path)
|
||||||
@ -972,6 +1112,7 @@ def in_virtual_env():
|
|||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def migrate_env(python, backup=False):
|
def migrate_env(python, backup=False):
|
||||||
from bench.config.common_site_config import get_config
|
from bench.config.common_site_config import get_config
|
||||||
from bench.app import get_apps
|
from bench.app import get_apps
|
||||||
@ -1028,3 +1169,17 @@ def migrate_env(python, backup=False):
|
|||||||
except:
|
except:
|
||||||
log.debug('Migration Error')
|
log.debug('Migration Error')
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
def find_parent_bench(path):
|
||||||
|
"""Checks if parent directories are benches"""
|
||||||
|
if is_bench_directory(directory=path):
|
||||||
|
return path
|
||||||
|
|
||||||
|
home_path = os.path.expanduser("~")
|
||||||
|
root_path = os.path.abspath(os.sep)
|
||||||
|
|
||||||
|
if path not in {home_path, root_path}:
|
||||||
|
# NOTE: the os.path.split assumes that given path is absolute
|
||||||
|
parent_dir = os.path.split(path)[0]
|
||||||
|
return find_parent_bench(parent_dir)
|
||||||
|
Loading…
Reference in New Issue
Block a user