2
0
mirror of https://github.com/frappe/bench.git synced 2024-11-13 16:56:33 +00:00

[cleanup] bench path

This commit is contained in:
Anand Doshi 2016-06-16 11:18:51 +05:30
parent 47662c4d90
commit 8ff5519959
14 changed files with 280 additions and 264 deletions

View File

@ -3,3 +3,11 @@ from jinja2 import Environment, PackageLoader
__version__ = "4.0.0-beta" __version__ = "4.0.0-beta"
env = Environment(loader=PackageLoader('bench.config'), trim_blocks=True) env = Environment(loader=PackageLoader('bench.config'), trim_blocks=True)
FRAPPE_VERSION = None
def set_frappe_version(bench_path='.'):
from .app import get_current_frappe_version
global FRAPPE_VERSION
if not FRAPPE_VERSION:
FRAPPE_VERSION = get_current_frappe_version(bench_path=bench_path)

View File

@ -9,6 +9,7 @@ import semantic_version
import json import json
import re import re
import subprocess import subprocess
import bench
logging.basicConfig(level="DEBUG") logging.basicConfig(level="DEBUG")
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -22,30 +23,30 @@ class MajorVersionUpgradeException(Exception):
self.upstream_version = upstream_version self.upstream_version = upstream_version
self.local_version = local_version self.local_version = local_version
def get_apps(bench='.'): def get_apps(bench_path='.'):
try: try:
with open(os.path.join(bench, 'sites', 'apps.txt')) as f: with open(os.path.join(bench_path, 'sites', 'apps.txt')) as f:
return f.read().strip().split('\n') return f.read().strip().split('\n')
except IOError: except IOError:
return [] return []
def add_to_appstxt(app, bench='.'): def add_to_appstxt(app, bench_path='.'):
apps = get_apps(bench=bench) apps = get_apps(bench_path=bench_path)
if app not in apps: if app not in apps:
apps.append(app) apps.append(app)
return write_appstxt(apps, bench=bench) return write_appstxt(apps, bench_path=bench_path)
def remove_from_appstxt(app, bench='.'): def remove_from_appstxt(app, bench_path='.'):
apps = get_apps(bench=bench) apps = get_apps(bench_path=bench_path)
if app in apps: if app in apps:
apps.remove(app) apps.remove(app)
return write_appstxt(apps, bench=bench) return write_appstxt(apps, bench_path=bench_path)
def write_appstxt(apps, bench='.'): def write_appstxt(apps, bench_path='.'):
with open(os.path.join(bench, 'sites', 'apps.txt'), 'w') as f: with open(os.path.join(bench_path, 'sites', 'apps.txt'), 'w') as f:
return f.write('\n'.join(apps)) return f.write('\n'.join(apps))
def get_app(git_url, branch=None, bench='.', build_asset_files=True, verbose=False): def get_app(git_url, branch=None, bench_path='.', build_asset_files=True, verbose=False):
#Gets repo name from URL #Gets repo name from URL
repo_name = git_url.rsplit('/', 1)[1].rsplit('.', 1)[0] repo_name = git_url.rsplit('/', 1)[1].rsplit('.', 1)[0]
logger.info('getting app {}'.format(repo_name)) logger.info('getting app {}'.format(repo_name))
@ -56,52 +57,55 @@ def get_app(git_url, branch=None, bench='.', build_asset_files=True, verbose=Fal
git_url=git_url, git_url=git_url,
shallow_clone=shallow_clone, shallow_clone=shallow_clone,
branch=branch), branch=branch),
cwd=os.path.join(bench, 'apps')) cwd=os.path.join(bench_path, 'apps'))
#Retrieves app name from setup.py #Retrieves app name from setup.py
app_path = os.path.join(bench, 'apps', repo_name, 'setup.py') app_path = os.path.join(bench_path, 'apps', repo_name, 'setup.py')
with open(app_path, 'rb') as f: with open(app_path, 'rb') as f:
app_name = re.search(r'name\s*=\s*[\'"](.*)[\'"]', f.read().decode('utf-8')).group(1) app_name = re.search(r'name\s*=\s*[\'"](.*)[\'"]', f.read().decode('utf-8')).group(1)
if repo_name != app_name: if repo_name != app_name:
apps_path = os.path.join(os.path.abspath(bench), 'apps') apps_path = os.path.join(os.path.abspath(bench_path), 'apps')
os.rename(os.path.join(apps_path, repo_name), os.path.join(apps_path, app_name)) os.rename(os.path.join(apps_path, repo_name), os.path.join(apps_path, app_name))
print 'installing', app_name print 'installing', app_name
install_app(app=app_name, bench=bench, verbose=verbose) install_app(app=app_name, bench_path=bench_path, verbose=verbose)
if build_asset_files:
build_assets(bench=bench)
conf = get_config(bench=bench)
if conf.get('restart_supervisor_on_update'):
restart_supervisor_processes(bench=bench)
def new_app(app, bench='.'): if build_asset_files:
build_assets(bench_path=bench_path)
conf = get_config(bench_path=bench_path)
if conf.get('restart_supervisor_on_update'):
restart_supervisor_processes(bench_path=bench_path)
def new_app(app, bench_path='.'):
# For backwards compatibility # For backwards compatibility
app = app.lower().replace(" ", "_").replace("-", "_") app = app.lower().replace(" ", "_").replace("-", "_")
logger.info('creating new app {}'.format(app)) logger.info('creating new app {}'.format(app))
apps = os.path.abspath(os.path.join(bench, 'apps')) apps = os.path.abspath(os.path.join(bench_path, 'apps'))
if FRAPPE_VERSION == 4: bench.set_frappe_version(bench_path=bench_path)
exec_cmd("{frappe} --make_app {apps} {app}".format(frappe=get_frappe(bench=bench),
if bench.FRAPPE_VERSION == 4:
exec_cmd("{frappe} --make_app {apps} {app}".format(frappe=get_frappe(bench_path=bench_path),
apps=apps, app=app)) apps=apps, app=app))
else: else:
run_frappe_cmd('make-app', apps, app, bench=bench) run_frappe_cmd('make-app', apps, app, bench_path=bench_path)
install_app(app, bench=bench) install_app(app, bench_path=bench_path)
def install_app(app, bench='.', verbose=False): def install_app(app, bench_path='.', verbose=False):
logger.info('installing {}'.format(app)) logger.info('installing {}'.format(app))
# find_links = '--find-links={}'.format(conf.get('wheel_cache_dir')) if conf.get('wheel_cache_dir') else '' # find_links = '--find-links={}'.format(conf.get('wheel_cache_dir')) if conf.get('wheel_cache_dir') else ''
find_links = '' find_links = ''
exec_cmd("{pip} install {quiet} {find_links} -e {app}".format( exec_cmd("{pip} install {quiet} {find_links} -e {app}".format(
pip=os.path.join(bench, 'env', 'bin', 'pip'), pip=os.path.join(bench_path, 'env', 'bin', 'pip'),
quiet="-q" if not verbose else "", quiet="-q" if not verbose else "",
app=os.path.join(bench, 'apps', app), app=os.path.join(bench_path, 'apps', app),
find_links=find_links)) find_links=find_links))
add_to_appstxt(app, bench=bench) add_to_appstxt(app, bench_path=bench_path)
def pull_all_apps(bench='.'): def pull_all_apps(bench_path='.'):
rebase = '--rebase' if get_config(bench).get('rebase_on_pull') else '' rebase = '--rebase' if get_config(bench_path).get('rebase_on_pull') else ''
for app in get_apps(bench=bench): for app in get_apps(bench_path=bench_path):
app_dir = get_repo_dir(app, bench=bench) app_dir = get_repo_dir(app, bench_path=bench_path)
if os.path.exists(os.path.join(app_dir, '.git')): if os.path.exists(os.path.join(app_dir, '.git')):
contents = subprocess.check_output(['git', 'remote', '-v'], cwd=app_dir, contents = subprocess.check_output(['git', 'remote', '-v'], cwd=app_dir,
stderr=subprocess.STDOUT) stderr=subprocess.STDOUT)
@ -114,22 +118,22 @@ def pull_all_apps(bench='.'):
logger.info('pulling {0}'.format(app)) logger.info('pulling {0}'.format(app))
exec_cmd("git pull {rebase} {remote} {branch}".format(rebase=rebase, exec_cmd("git pull {rebase} {remote} {branch}".format(rebase=rebase,
remote=remote, branch=get_current_branch(app, bench=bench)), cwd=app_dir) remote=remote, branch=get_current_branch(app, bench_path=bench_path)), cwd=app_dir)
exec_cmd('find . -name "*.pyc" -delete', cwd=app_dir) exec_cmd('find . -name "*.pyc" -delete', cwd=app_dir)
def is_version_upgrade(app='frappe', bench='.', branch=None): def is_version_upgrade(app='frappe', bench_path='.', branch=None):
try: try:
fetch_upstream(app, bench=bench) fetch_upstream(app, bench_path=bench_path)
except CommandFailedError: except CommandFailedError:
raise InvalidRemoteException("No remote named upstream for {0}".format(app)) raise InvalidRemoteException("No remote named upstream for {0}".format(app))
upstream_version = get_upstream_version(app=app, branch=branch, bench=bench) upstream_version = get_upstream_version(app=app, branch=branch, bench_path=bench_path)
if not upstream_version: if not upstream_version:
raise InvalidBranchException("Specified branch of app {0} is not in upstream".format(app)) raise InvalidBranchException("Specified branch of app {0} is not in upstream".format(app))
local_version = get_major_version(get_current_version(app, bench=bench)) local_version = get_major_version(get_current_version(app, bench_path=bench_path))
upstream_version = get_major_version(upstream_version) upstream_version = get_major_version(upstream_version)
if upstream_version - local_version > 0: if upstream_version - local_version > 0:
@ -137,14 +141,14 @@ def is_version_upgrade(app='frappe', bench='.', branch=None):
return (False, local_version, upstream_version) return (False, local_version, upstream_version)
def get_current_frappe_version(bench='.'): def get_current_frappe_version(bench_path='.'):
try: try:
return get_major_version(get_current_version('frappe', bench=bench)) return get_major_version(get_current_version('frappe', bench_path=bench_path))
except IOError: except IOError:
return 0 return 0
def get_current_branch(app, bench='.'): def get_current_branch(app, bench_path='.'):
repo_dir = get_repo_dir(app, bench=bench) repo_dir = get_repo_dir(app, bench_path=bench_path)
return get_cmd_output("basename $(git symbolic-ref -q HEAD)", cwd=repo_dir) return get_cmd_output("basename $(git symbolic-ref -q HEAD)", cwd=repo_dir)
def use_rq(bench_path): def use_rq(bench_path):
@ -152,12 +156,12 @@ def use_rq(bench_path):
celery_app = os.path.join(bench_path, 'apps', 'frappe', 'frappe', 'celery_app.py') celery_app = os.path.join(bench_path, 'apps', 'frappe', 'frappe', 'celery_app.py')
return not os.path.exists(celery_app) return not os.path.exists(celery_app)
def fetch_upstream(app, bench='.'): def fetch_upstream(app, bench_path='.'):
repo_dir = get_repo_dir(app, bench=bench) repo_dir = get_repo_dir(app, bench_path=bench_path)
return subprocess.call(["git", "fetch", "upstream"], cwd=repo_dir) return subprocess.call(["git", "fetch", "upstream"], cwd=repo_dir)
def get_current_version(app, bench='.'): def get_current_version(app, bench_path='.'):
repo_dir = get_repo_dir(app, bench=bench) repo_dir = get_repo_dir(app, bench_path=bench_path)
try: try:
with open(os.path.join(repo_dir, os.path.basename(repo_dir), '__init__.py')) as f: with open(os.path.join(repo_dir, os.path.basename(repo_dir), '__init__.py')) as f:
return get_version_from_string(f.read()) return get_version_from_string(f.read())
@ -167,10 +171,10 @@ def get_current_version(app, bench='.'):
with open(os.path.join(repo_dir, 'setup.py')) as f: with open(os.path.join(repo_dir, 'setup.py')) as f:
return get_version_from_string(f.read(), field='version') return get_version_from_string(f.read(), field='version')
def get_upstream_version(app, branch=None, bench='.'): def get_upstream_version(app, branch=None, bench_path='.'):
repo_dir = get_repo_dir(app, bench=bench) repo_dir = get_repo_dir(app, bench_path=bench_path)
if not branch: if not branch:
branch = get_current_branch(app, bench=bench) branch = get_current_branch(app, bench_path=bench_path)
try: try:
contents = subprocess.check_output(['git', 'show', 'upstream/{branch}:{app}/__init__.py'.format(branch=branch, app=app)], cwd=repo_dir, stderr=subprocess.STDOUT) contents = subprocess.check_output(['git', 'show', 'upstream/{branch}:{app}/__init__.py'.format(branch=branch, app=app)], cwd=repo_dir, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError, e: except subprocess.CalledProcessError, e:
@ -180,17 +184,17 @@ def get_upstream_version(app, branch=None, bench='.'):
raise raise
return get_version_from_string(contents) return get_version_from_string(contents)
def get_upstream_url(app, bench='.'): def get_upstream_url(app, bench_path='.'):
repo_dir = get_repo_dir(app, bench=bench) repo_dir = get_repo_dir(app, bench_path=bench_path)
return subprocess.check_output(['git', 'config', '--get', 'remote.upstream.url'], cwd=repo_dir).strip() return subprocess.check_output(['git', 'config', '--get', 'remote.upstream.url'], cwd=repo_dir).strip()
def get_repo_dir(app, bench='.'): def get_repo_dir(app, bench_path='.'):
return os.path.join(bench, 'apps', app) return os.path.join(bench_path, 'apps', app)
def switch_branch(branch, apps=None, bench='.', upgrade=False, check_upgrade=True): def switch_branch(branch, apps=None, bench_path='.', upgrade=False, check_upgrade=True):
from .utils import update_requirements, backup_all_sites, patch_sites, build_assets, pre_upgrade, post_upgrade from .utils import update_requirements, backup_all_sites, patch_sites, build_assets, pre_upgrade, post_upgrade
import utils import utils
apps_dir = os.path.join(bench, 'apps') apps_dir = os.path.join(bench_path, 'apps')
version_upgrade = (False,) version_upgrade = (False,)
switched_apps = [] switched_apps = []
@ -205,7 +209,7 @@ def switch_branch(branch, apps=None, bench='.', upgrade=False, check_upgrade=Tru
if os.path.exists(app_dir): if os.path.exists(app_dir):
try: try:
if check_upgrade: if check_upgrade:
version_upgrade = is_version_upgrade(app=app, bench=bench, branch=branch) version_upgrade = is_version_upgrade(app=app, bench_path=bench_path, branch=branch)
if version_upgrade[0] and not upgrade: if version_upgrade[0] and not upgrade:
raise MajorVersionUpgradeException("Switching to {0} will cause upgrade from {1} to {2}. Pass --upgrade to confirm".format(branch, version_upgrade[1], version_upgrade[2]), version_upgrade[1], version_upgrade[2]) raise MajorVersionUpgradeException("Switching to {0} will cause upgrade from {1} to {2}. Pass --upgrade to confirm".format(branch, version_upgrade[1], version_upgrade[2]), version_upgrade[1], version_upgrade[2])
print "Switching for "+app print "Switching for "+app
@ -235,20 +239,20 @@ def switch_branch(branch, apps=None, bench='.', upgrade=False, check_upgrade=Tru
build_assets() build_assets()
post_upgrade(version_upgrade[1], version_upgrade[2]) post_upgrade(version_upgrade[1], version_upgrade[2])
def switch_to_branch(branch=None, apps=None, bench='.', upgrade=False): def switch_to_branch(branch=None, apps=None, bench_path='.', upgrade=False):
switch_branch(branch, apps=apps, bench=bench, upgrade=upgrade) switch_branch(branch, apps=apps, bench_path=bench_path, upgrade=upgrade)
def switch_to_master(apps=None, bench='.', upgrade=False): def switch_to_master(apps=None, bench_path='.', upgrade=False):
switch_branch('master', apps=apps, bench=bench, upgrade=upgrade) switch_branch('master', apps=apps, bench_path=bench_path, upgrade=upgrade)
def switch_to_develop(apps=None, bench='.', upgrade=False): def switch_to_develop(apps=None, bench_path='.', upgrade=False):
switch_branch('develop', apps=apps, bench=bench, upgrade=upgrade) switch_branch('develop', apps=apps, bench_path=bench_path, upgrade=upgrade)
def switch_to_v4(apps=None, bench='.', upgrade=False): def switch_to_v4(apps=None, bench_path='.', upgrade=False):
switch_branch('v4.x.x', apps=apps, bench=bench, upgrade=upgrade) switch_branch('v4.x.x', apps=apps, bench_path=bench_path, upgrade=upgrade)
def switch_to_v5(apps=None, bench='.', upgrade=False): def switch_to_v5(apps=None, bench_path='.', upgrade=False):
switch_branch('v5.x.x', apps=apps, bench=bench, upgrade=upgrade) switch_branch('v5.x.x', apps=apps, bench_path=bench_path, upgrade=upgrade)
def get_version_from_string(contents, field='__version__'): def get_version_from_string(contents, field='__version__'):
match = re.search(r"^(\s*%s\s*=\s*['\\\"])(.+?)(['\"])(?sm)" % field, match = re.search(r"^(\s*%s\s*=\s*['\\\"])(.+?)(['\"])(?sm)" % field,
@ -258,10 +262,10 @@ def get_version_from_string(contents, field='__version__'):
def get_major_version(version): def get_major_version(version):
return semantic_version.Version(version).major return semantic_version.Version(version).major
def install_apps_from_path(path, bench='.'): def install_apps_from_path(path, bench_path='.'):
apps = get_apps_json(path) apps = get_apps_json(path)
for app in apps: for app in apps:
get_app(app['url'], branch=app.get('branch'), bench=bench, build_asset_files=False) get_app(app['url'], branch=app.get('branch'), bench_path=bench_path, build_asset_files=False)
def get_apps_json(path): def get_apps_json(path):
if path.startswith('http'): if path.startswith('http'):
@ -270,5 +274,3 @@ def get_apps_json(path):
else: else:
with open(path) as f: with open(path) as f:
return json.load(f) return json.load(f)
FRAPPE_VERSION = get_current_frappe_version()

View File

@ -73,24 +73,24 @@ def change_uid():
print 'You should not run this command as root' print 'You should not run this command as root'
sys.exit(1) sys.exit(1)
def old_frappe_cli(bench='.'): def old_frappe_cli(bench_path='.'):
f = get_frappe(bench=bench) f = get_frappe(bench_path=bench_path)
os.chdir(os.path.join(bench, 'sites')) os.chdir(os.path.join(bench_path, 'sites'))
os.execv(f, [f] + sys.argv[2:]) os.execv(f, [f] + sys.argv[2:])
def app_cmd(bench='.'): def app_cmd(bench_path='.'):
f = get_env_cmd('python', bench=bench) f = get_env_cmd('python', bench_path=bench_path)
os.chdir(os.path.join(bench, 'sites')) os.chdir(os.path.join(bench_path, 'sites'))
os.execv(f, [f] + ['-m', 'frappe.utils.bench_helper'] + sys.argv[1:]) os.execv(f, [f] + ['-m', 'frappe.utils.bench_helper'] + sys.argv[1:])
def frappe_cmd(bench='.'): def frappe_cmd(bench_path='.'):
f = get_env_cmd('python', bench=bench) f = get_env_cmd('python', bench_path=bench_path)
os.chdir(os.path.join(bench, 'sites')) os.chdir(os.path.join(bench_path, 'sites'))
os.execv(f, [f] + ['-m', 'frappe.utils.bench_helper', 'frappe'] + sys.argv[1:]) os.execv(f, [f] + ['-m', 'frappe.utils.bench_helper', 'frappe'] + sys.argv[1:])
def get_frappe_commands(bench='.'): def get_frappe_commands(bench_path='.'):
python = get_env_cmd('python', bench=bench) python = get_env_cmd('python', bench_path=bench_path)
sites_path = os.path.join(bench, 'sites') sites_path = os.path.join(bench_path, 'sites')
if not os.path.exists(sites_path): if not os.path.exists(sites_path):
return [] return []
try: try:
@ -98,9 +98,9 @@ def get_frappe_commands(bench='.'):
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
return [] return []
def get_frappe_help(bench='.'): def get_frappe_help(bench_path='.'):
python = get_env_cmd('python', bench=bench) python = get_env_cmd('python', bench_path=bench_path)
sites_path = os.path.join(bench, 'sites') sites_path = os.path.join(bench_path, 'sites')
if not os.path.exists(sites_path): if not os.path.exists(sites_path):
return [] return []
try: try:

View File

@ -1,16 +1,14 @@
import click import click
global FRAPPE_VERSION
@click.group() @click.group()
def bench_command(bench='.'): def bench_command(bench_path='.'):
"Bench manager for Frappe" "Bench manager for Frappe"
import bench
from bench.app import get_current_frappe_version from bench.app import get_current_frappe_version
from bench.utils import setup_logging from bench.utils import setup_logging
# TODO add bench path context bench.set_frappe_version(bench_path=bench_path)
global FRAPPE_VERSION setup_logging(bench_path=bench_path)
FRAPPE_VERSION = get_current_frappe_version()
setup_logging(bench=bench)
from bench.commands.make import init, get_app, new_app, new_site from bench.commands.make import init, get_app, new_app, new_site

View File

@ -23,12 +23,12 @@ def setup_nginx(force=None):
@click.command('supervisor') @click.command('supervisor')
@click.option('--user')
@click.option('--force', help='Force regeneration of supervisor config', is_flag=True, default=False) @click.option('--force', help='Force regeneration of supervisor config', is_flag=True, default=False)
def setup_supervisor(force=None): def setup_supervisor(user=None, force=None):
"generate config for supervisor" "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=".", force=force) generate_supervisor_config(bench_path=".", user=user, force=force)
@click.command('redis') @click.command('redis')
def setup_redis(): def setup_redis():

View File

@ -61,39 +61,39 @@ def update(pull=False, patch=False, build=False, bench=False, auto=False, restar
def _update(pull=False, patch=False, build=False, update_bench=False, auto=False, restart_supervisor=False, requirements=False, no_backup=False, upgrade=False, bench_path='.', force=False): def _update(pull=False, patch=False, build=False, update_bench=False, auto=False, restart_supervisor=False, requirements=False, no_backup=False, upgrade=False, bench_path='.', force=False):
conf = get_config(bench=bench_path) conf = get_config(bench_path=bench_path)
version_upgrade = is_version_upgrade(bench=bench_path) version_upgrade = is_version_upgrade(bench_path=bench_path)
if version_upgrade[0] and not upgrade: if version_upgrade[0] and not upgrade:
raise Exception("Major Version Upgrade") raise Exception("Major Version Upgrade")
if upgrade and (version_upgrade[0] or (not version_upgrade[0] and force)): if upgrade and (version_upgrade[0] or (not version_upgrade[0] and force)):
validate_upgrade(version_upgrade[1], version_upgrade[2], bench=bench_path) validate_upgrade(version_upgrade[1], version_upgrade[2], bench_path=bench_path)
before_update(bench=bench_path, requirements=requirements) before_update(bench_path=bench_path, requirements=requirements)
if pull: if pull:
pull_all_apps(bench=bench_path) pull_all_apps(bench_path=bench_path)
if requirements: if requirements:
update_requirements(bench=bench_path) update_requirements(bench_path=bench_path)
if upgrade and (version_upgrade[0] or (not version_upgrade[0] and force)): if upgrade and (version_upgrade[0] or (not version_upgrade[0] and force)):
pre_upgrade(version_upgrade[1], version_upgrade[2], bench=bench_path) pre_upgrade(version_upgrade[1], version_upgrade[2], bench_path=bench_path)
import bench.utils, bench.app import bench.utils, bench.app
reload(bench.utils) reload(bench.utils)
reload(bench.app) reload(bench.app)
if patch: if patch:
if not no_backup: if not no_backup:
backup_all_sites(bench=bench_path) backup_all_sites(bench_path=bench_path)
patch_sites(bench=bench_path) patch_sites(bench_path=bench_path)
if build: if build:
build_assets(bench=bench_path) build_assets(bench_path=bench_path)
if upgrade and (version_upgrade[0] or (not version_upgrade[0] and force)): if upgrade and (version_upgrade[0] or (not version_upgrade[0] and force)):
post_upgrade(version_upgrade[1], version_upgrade[2], bench=bench_path) post_upgrade(version_upgrade[1], version_upgrade[2], bench_path=bench_path)
if restart_supervisor or conf.get('restart_supervisor_on_update'): if restart_supervisor or conf.get('restart_supervisor_on_update'):
restart_supervisor_processes(bench=bench_path) restart_supervisor_processes(bench_path=bench_path)
print "_"*80 print "_"*80
print "Bench: Open source installer + admin for Frappe and ERPNext (https://erpnext.com)" print "Bench: Open source installer + admin for Frappe and ERPNext (https://erpnext.com)"

View File

@ -83,7 +83,7 @@ def renew_lets_encrypt():
renew_certs() renew_certs()
@click.command() @click.command()
def shell(bench='.'): def shell(bench_path='.'):
if not os.environ.get('SHELL'): if not os.environ.get('SHELL'):
print "Cannot get shell" print "Cannot get shell"
sys.exit(1) sys.exit(1)
@ -102,17 +102,17 @@ def shell(bench='.'):
def backup_site(site): def backup_site(site):
"backup site" "backup site"
from bench.utils import get_sites, backup_site from bench.utils import get_sites, backup_site
if not site in get_sites(bench='.'): if not site in get_sites(bench_path='.'):
print 'site not found' print 'site not found'
sys.exit(1) sys.exit(1)
backup_site(site, bench='.') backup_site(site, bench_path='.')
@click.command('backup-all-sites') @click.command('backup-all-sites')
def backup_all_sites(): def backup_all_sites():
"backup all sites" "backup all sites"
from bench.utils import backup_all_sites from bench.utils import backup_all_sites
backup_all_sites(bench='.') backup_all_sites(bench_path='.')
@click.command('release') @click.command('release')

View File

@ -20,8 +20,8 @@ def make_config(bench_path):
put_config(bench_config, bench_path) put_config(bench_config, bench_path)
def get_config(bench): def get_config(bench_path):
return get_common_site_config(bench) return get_common_site_config(bench_path)
def get_common_site_config(bench_path): def get_common_site_config(bench_path):
config_path = get_config_path(bench_path) config_path = get_config_path(bench_path)
@ -30,18 +30,18 @@ def get_common_site_config(bench_path):
with open(config_path, 'r') as f: with open(config_path, 'r') as f:
return json.load(f) return json.load(f)
def put_config(config, bench='.'): def put_config(config, bench_path='.'):
config_path = get_config_path(bench) config_path = get_config_path(bench_path)
with open(config_path, 'w') as f: with open(config_path, 'w') as f:
return json.dump(config, f, indent=1, sort_keys=True) return json.dump(config, f, indent=1, sort_keys=True)
def update_config(new_config, bench='.'): def update_config(new_config, bench_path='.'):
config = get_config(bench=bench) config = get_config(bench_path=bench_path)
config.update(new_config) config.update(new_config)
put_config(config, bench=bench) put_config(config, bench_path=bench_path)
def get_config_path(bench): def get_config_path(bench_path):
return os.path.join(bench, 'sites', 'common_site_config.json') return os.path.join(bench_path, 'sites', 'common_site_config.json')
def get_gunicorn_workers(): def get_gunicorn_workers():
'''This function will return the maximum workers that can be started depending upon '''This function will return the maximum workers that can be started depending upon
@ -78,9 +78,9 @@ def make_ports(bench_path):
# collect all existing ports # collect all existing ports
existing_ports = {} existing_ports = {}
for folder in os.listdir(benches_path): for folder in os.listdir(benches_path):
bench = os.path.join(benches_path, folder) bench_path = os.path.join(benches_path, folder)
if os.path.isdir(bench): if os.path.isdir(bench_path):
bench_config = get_config(bench) bench_config = get_config(bench_path)
for key in default_ports.keys(): for key in default_ports.keys():
value = bench_config.get(key) value = bench_config.get(key)

View File

@ -61,7 +61,7 @@ def prepare_sites(config, bench_path):
return sites return sites
def get_sites_with_config(bench_path): def get_sites_with_config(bench_path):
sites = get_sites(bench=bench_path) sites = get_sites(bench_path=bench_path)
ret = [] ret = []
for site in sites: for site in sites:
site_config = get_site_config(site, bench_path=bench_path) site_config = get_site_config(site, bench_path=bench_path)

View File

@ -4,7 +4,7 @@ from bench.app import use_rq
from bench.config.common_site_config import get_config from bench.config.common_site_config import get_config
def setup_procfile(bench_path, force=False): def setup_procfile(bench_path, force=False):
config = get_config(bench=bench_path) config = get_config(bench_path=bench_path)
procfile_path = os.path.join(bench_path, 'Procfile') procfile_path = os.path.join(bench_path, 'Procfile')
if not force and os.path.exists(procfile_path): if not force and os.path.exists(procfile_path):
click.confirm('A Procfile already exists and this will overwrite it. Do you want to continue?', click.confirm('A Procfile already exists and this will overwrite it. Do you want to continue?',

View File

@ -3,13 +3,13 @@ from bench.config.supervisor import generate_supervisor_config
from bench.config.nginx import make_nginx_conf from bench.config.nginx import make_nginx_conf
import os import os
def setup_production(user, bench='.'): def setup_production(user, bench_path='.'):
generate_supervisor_config(bench_path=bench, user=user) generate_supervisor_config(bench_path=bench_path, user=user)
make_nginx_conf(bench_path=bench) make_nginx_conf(bench_path=bench_path)
fix_prod_setup_perms(bench, frappe_user=user) fix_prod_setup_perms(bench_path, frappe_user=user)
remove_default_nginx_configs() remove_default_nginx_configs()
bench_name = get_bench_name(bench) bench_name = get_bench_name(bench_path)
nginx_conf = '/etc/nginx/conf.d/{bench_name}.conf'.format(bench_name=bench_name) nginx_conf = '/etc/nginx/conf.d/{bench_name}.conf'.format(bench_name=bench_name)
supervisor_conf_extn = "ini" if is_centos7() else "conf" supervisor_conf_extn = "ini" if is_centos7() else "conf"
@ -18,10 +18,10 @@ def setup_production(user, bench='.'):
# Check if symlink exists, If not then create it. # Check if symlink exists, If not then create it.
if not os.path.islink(supervisor_conf): if not os.path.islink(supervisor_conf):
os.symlink(os.path.abspath(os.path.join(bench, 'config', 'supervisor.conf')), supervisor_conf) os.symlink(os.path.abspath(os.path.join(bench_path, 'config', 'supervisor.conf')), supervisor_conf)
if not os.path.islink(nginx_conf): if not os.path.islink(nginx_conf):
os.symlink(os.path.abspath(os.path.join(bench, 'config', 'nginx.conf')), nginx_conf) os.symlink(os.path.abspath(os.path.join(bench_path, 'config', 'nginx.conf')), nginx_conf)
exec_cmd('supervisorctl reload') exec_cmd('supervisorctl reload')
if os.environ.get('NO_SERVICE_RESTART'): if os.environ.get('NO_SERVICE_RESTART'):

View File

@ -10,7 +10,7 @@ def generate_supervisor_config(bench_path, user=None, force=False):
if not user: if not user:
user = getpass.getuser() user = getpass.getuser()
config = get_config(bench=bench_path) config = get_config(bench_path=bench_path)
bench_dir = os.path.abspath(bench_path) bench_dir = os.path.abspath(bench_path)
@ -41,5 +41,5 @@ def generate_supervisor_config(bench_path, user=None, force=False):
with open(conf_path, 'w') as f: with open(conf_path, 'w') as f:
f.write(config) f.write(config)
update_config({'restart_supervisor_on_update': True}, bench=bench_path) update_config({'restart_supervisor_on_update': True}, bench_path=bench_path)

View File

@ -103,12 +103,12 @@ class TestBenchInit(unittest.TestCase):
bench_path = os.path.join(self.benches_path, "test-bench") bench_path = os.path.join(self.benches_path, "test-bench")
# get app # get app
bench.app.get_app("https://github.com/frappe/erpnext", "develop", bench=bench_path) bench.app.get_app("https://github.com/frappe/erpnext", "develop", bench_path=bench_path)
self.assertTrue(os.path.exists(os.path.join(bench_path, "apps", "erpnext"))) self.assertTrue(os.path.exists(os.path.join(bench_path, "apps", "erpnext")))
# install app # install app
bench.app.install_app("erpnext", bench=bench_path) bench.app.install_app("erpnext", bench_path=bench_path)
# install it to site # install it to site
subprocess.check_output(["bench", "--site", site_name, "install-app", "erpnext"], cwd=bench_path) subprocess.check_output(["bench", "--site", site_name, "install-app", "erpnext"], cwd=bench_path)

View File

@ -10,6 +10,7 @@ import select
import multiprocessing import multiprocessing
from distutils.spawn import find_executable from distutils.spawn import find_executable
import pwd, grp import pwd, grp
import bench
from bench import env from bench import env
class PatchError(Exception): class PatchError(Exception):
@ -24,15 +25,15 @@ logger = logging.getLogger(__name__)
folders_in_bench = ('apps', 'sites', 'config', 'logs', 'config/pids') folders_in_bench = ('apps', 'sites', 'config', 'logs', 'config/pids')
def get_frappe(bench='.'): def get_frappe(bench_path='.'):
frappe = get_env_cmd('frappe', bench=bench) frappe = get_env_cmd('frappe', bench_path=bench_path)
if not os.path.exists(frappe): if not os.path.exists(frappe):
print 'frappe app is not installed. Run the following command to install frappe' print 'frappe app is not installed. Run the following command to install frappe'
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='.'): def get_env_cmd(cmd, bench_path='.'):
return os.path.abspath(os.path.join(bench, '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, 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, no_auto_update=False, frappe_path=None, frappe_branch=None, wheel_cache_dir=None,
@ -41,7 +42,6 @@ def init(path, apps_path=None, no_procfile=False, no_backups=False,
from .config.common_site_config import make_config from .config.common_site_config import make_config
from .config import redis from .config import redis
from .config.procfile import setup_procfile from .config.procfile import setup_procfile
global FRAPPE_VERSION
if os.path.exists(path): if os.path.exists(path):
print 'Directory {} already exists!'.format(path) print 'Directory {} already exists!'.format(path)
@ -54,30 +54,31 @@ def init(path, apps_path=None, no_procfile=False, no_backups=False,
setup_logging() setup_logging()
setup_env(bench=path) setup_env(bench_path=path)
make_config(path) make_config(path)
if not frappe_path: if not frappe_path:
frappe_path = 'https://github.com/frappe/frappe.git' frappe_path = 'https://github.com/frappe/frappe.git'
get_app(frappe_path, branch=frappe_branch, bench=path, build_asset_files=False, verbose=verbose)
get_app(frappe_path, branch=frappe_branch, bench_path=path, build_asset_files=False, verbose=verbose)
if apps_path: if apps_path:
install_apps_from_path(apps_path, bench=path) install_apps_from_path(apps_path, bench_path=path)
FRAPPE_VERSION = get_current_frappe_version(bench=path) bench.set_frappe_version(bench_path=path)
if FRAPPE_VERSION > 5: if bench.FRAPPE_VERSION > 5:
setup_socketio(bench=path) setup_socketio(bench_path=path)
build_assets(bench=path) build_assets(bench_path=path)
redis.generate_config(path) redis.generate_config(path)
if not no_procfile: if not no_procfile:
setup_procfile(path) setup_procfile(path)
if not no_backups: if not no_backups:
setup_backups(bench=path) setup_backups(bench_path=path)
if not no_auto_update: if not no_auto_update:
setup_auto_update(bench=path) setup_auto_update(bench_path=path)
def exec_cmd(cmd, cwd='.'): def exec_cmd(cmd, cwd='.'):
@ -98,74 +99,80 @@ def exec_cmd(cmd, cwd='.'):
if return_code > 0: if return_code > 0:
raise CommandFailedError(cmd) raise CommandFailedError(cmd)
def setup_env(bench='.'): def setup_env(bench_path='.'):
exec_cmd('virtualenv -q {} -p {}'.format('env', sys.executable), cwd=bench) exec_cmd('virtualenv -q {} -p {}'.format('env', sys.executable), cwd=bench_path)
exec_cmd('./env/bin/pip -q install --upgrade pip', cwd=bench) exec_cmd('./env/bin/pip -q install --upgrade pip', cwd=bench_path)
exec_cmd('./env/bin/pip -q install wheel', cwd=bench) exec_cmd('./env/bin/pip -q install wheel', cwd=bench_path)
# exec_cmd('./env/bin/pip -q install https://github.com/frappe/MySQLdb1/archive/MySQLdb-1.2.5-patched.tar.gz', cwd=bench) # exec_cmd('./env/bin/pip -q install https://github.com/frappe/MySQLdb1/archive/MySQLdb-1.2.5-patched.tar.gz', cwd=bench_path)
exec_cmd('./env/bin/pip -q install -e git+https://github.com/frappe/python-pdfkit.git#egg=pdfkit', cwd=bench) exec_cmd('./env/bin/pip -q install -e git+https://github.com/frappe/python-pdfkit.git#egg=pdfkit', cwd=bench_path)
def setup_socketio(bench='.'): def setup_socketio(bench_path='.'):
exec_cmd("npm install socket.io redis express superagent cookie", cwd=bench) exec_cmd("npm install socket.io redis express superagent cookie", cwd=bench_path)
def new_site(site, mariadb_root_password=None, admin_password=None, bench='.'): def new_site(site, mariadb_root_password=None, admin_password=None, bench_path='.'):
import hashlib import hashlib
logger.info('creating new site {}'.format(site)) logger.info('creating new site {}'.format(site))
mariadb_root_password_fragment = '--root_password {}'.format(mariadb_root_password) if mariadb_root_password else '' mariadb_root_password_fragment = '--root_password {}'.format(mariadb_root_password) if mariadb_root_password else ''
admin_password_fragment = '--admin_password {}'.format(admin_password) if admin_password else '' admin_password_fragment = '--admin_password {}'.format(admin_password) if admin_password else ''
exec_cmd("{frappe} {site} --install {db_name} {mariadb_root_password_fragment} {admin_password_fragment}".format( exec_cmd("{frappe} {site} --install {db_name} {mariadb_root_password_fragment} {admin_password_fragment}".format(
frappe=get_frappe(bench=bench), frappe=get_frappe(bench_path=bench_path),
site=site, site=site,
db_name = hashlib.sha1(site).hexdigest()[:10], db_name = hashlib.sha1(site).hexdigest()[:10],
mariadb_root_password_fragment=mariadb_root_password_fragment, mariadb_root_password_fragment=mariadb_root_password_fragment,
admin_password_fragment=admin_password_fragment admin_password_fragment=admin_password_fragment
), cwd=os.path.join(bench, 'sites')) ), cwd=os.path.join(bench_path, 'sites'))
if len(get_sites(bench=bench)) == 1: if len(get_sites(bench_path=bench_path)) == 1:
exec_cmd("{frappe} --use {site}".format(frappe=get_frappe(bench=bench), site=site), cwd=os.path.join(bench, 'sites')) exec_cmd("{frappe} --use {site}".format(frappe=get_frappe(bench_path=bench_path), site=site), cwd=os.path.join(bench_path, 'sites'))
def patch_sites(bench_path='.'):
bench.set_frappe_version(bench_path=bench_path)
def patch_sites(bench='.'):
try: try:
if FRAPPE_VERSION == 4: if bench.FRAPPE_VERSION == 4:
exec_cmd("{frappe} --latest all".format(frappe=get_frappe(bench=bench)), cwd=os.path.join(bench, 'sites')) exec_cmd("{frappe} --latest all".format(frappe=get_frappe(bench_path=bench_path)), cwd=os.path.join(bench_path, 'sites'))
else: else:
run_frappe_cmd('--site', 'all', 'migrate', bench=bench) run_frappe_cmd('--site', 'all', 'migrate', bench_path=bench_path)
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
raise PatchError raise PatchError
def build_assets(bench='.'): def build_assets(bench_path='.'):
if FRAPPE_VERSION == 4: bench.set_frappe_version(bench_path=bench_path)
exec_cmd("{frappe} --build".format(frappe=get_frappe(bench=bench)), cwd=os.path.join(bench, 'sites'))
else:
run_frappe_cmd('build', bench=bench)
def get_sites(bench='.'): if bench.FRAPPE_VERSION == 4:
sites_dir = os.path.join(bench, "sites") exec_cmd("{frappe} --build".format(frappe=get_frappe(bench_path=bench_path)), cwd=os.path.join(bench_path, 'sites'))
else:
run_frappe_cmd('build', bench_path=bench_path)
def get_sites(bench_path='.'):
sites_dir = os.path.join(bench_path, "sites")
sites = [site for site in os.listdir(sites_dir) sites = [site for site in os.listdir(sites_dir)
if os.path.isdir(os.path.join(sites_dir, site)) and site not in ('assets',)] if os.path.isdir(os.path.join(sites_dir, site)) and site not in ('assets',)]
return sites return sites
def get_sites_dir(bench='.'): def get_sites_dir(bench_path='.'):
return os.path.abspath(os.path.join(bench, 'sites')) return os.path.abspath(os.path.join(bench_path, 'sites'))
def get_bench_dir(bench='.'): def get_bench_dir(bench_path='.'):
return os.path.abspath(bench) return os.path.abspath(bench_path)
def setup_auto_update(bench='.'): def setup_auto_update(bench_path='.'):
logger.info('setting up auto update') 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=bench), 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=bench), 'env', 'bin', 'bench'), bench=os.path.join(get_bench_dir(bench_path=bench_path), 'env', 'bin', 'bench'),
logfile=os.path.join(get_bench_dir(bench=bench), 'logs', 'auto_update_log.log'))) logfile=os.path.join(get_bench_dir(bench_path=bench_path), 'logs', 'auto_update_log.log')))
def setup_backups(bench='.'): def setup_backups(bench_path='.'):
logger.info('setting up backups') logger.info('setting up backups')
bench_dir = get_bench_dir(bench=bench) bench_dir = get_bench_dir(bench_path=bench_path)
if FRAPPE_VERSION == 4: bench.set_frappe_version(bench_path=bench_path)
backup_command = "cd {sites_dir} && {frappe} --backup all".format(frappe=get_frappe(bench=bench),)
if bench.FRAPPE_VERSION == 4:
backup_command = "cd {sites_dir} && {frappe} --backup all".format(frappe=get_frappe(bench_path=bench_path),)
else: else:
backup_command = "cd {bench_dir} && {bench} --site all backup".format(bench_dir=bench_dir, bench=sys.argv[0]) backup_command = "cd {bench_dir} && {bench} --site all backup".format(bench_dir=bench_dir, bench=sys.argv[0])
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=bench), '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()
@ -223,10 +230,10 @@ def setup_sudoers(user):
os.chmod(sudoers_file, 0440) os.chmod(sudoers_file, 0440)
def setup_logging(bench='.'): def setup_logging(bench_path='.'):
if os.path.exists(os.path.join(bench, 'logs')): if os.path.exists(os.path.join(bench_path, 'logs')):
logger = logging.getLogger('bench') logger = logging.getLogger('bench')
log_file = os.path.join(bench, 'logs', 'bench.log') log_file = os.path.join(bench_path, 'logs', 'bench.log')
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s') formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
hdlr = logging.FileHandler(log_file) hdlr = logging.FileHandler(log_file)
hdlr.setFormatter(formatter) hdlr.setFormatter(formatter)
@ -290,17 +297,17 @@ def get_cmd_output(cmd, cwd='.'):
print e.output print e.output
raise raise
def restart_supervisor_processes(bench='.'): def restart_supervisor_processes(bench_path='.'):
from .config.common_site_config import get_config from .config.common_site_config import get_config
conf = get_config(bench=bench) conf = get_config(bench_path=bench_path)
bench_name = get_bench_name(bench) bench_name = get_bench_name(bench_path)
cmd = conf.get('supervisor_restart_cmd') cmd = conf.get('supervisor_restart_cmd')
if cmd: if cmd:
exec_cmd(cmd, cwd=bench) exec_cmd(cmd, cwd=bench_path)
else: else:
supervisor_status = subprocess.check_output(['sudo', 'supervisorctl', 'status'], cwd=bench) supervisor_status = subprocess.check_output(['sudo', 'supervisorctl', 'status'], cwd=bench_path)
if '{bench_name}-workers:'.format(bench_name=bench_name) in supervisor_status: if '{bench_name}-workers:'.format(bench_name=bench_name) in supervisor_status:
group = '{bench_name}-workers: {bench_name}-web:'.format(bench_name=bench_name) group = '{bench_name}-workers: {bench_name}-web:'.format(bench_name=bench_name)
@ -313,84 +320,86 @@ def restart_supervisor_processes(bench='.'):
else: else:
group = 'frappe:' group = 'frappe:'
exec_cmd('sudo supervisorctl restart {group}'.format(group=group), cwd=bench) exec_cmd('sudo supervisorctl restart {group}'.format(group=group), cwd=bench_path)
def get_site_config(site, bench='.'): def get_site_config(site, bench_path='.'):
config_path = os.path.join(bench, 'sites', site, 'site_config.json') config_path = os.path.join(bench_path, 'sites', site, 'site_config.json')
if not os.path.exists(config_path): if not os.path.exists(config_path):
return {} return {}
with open(config_path) as f: with open(config_path) as f:
return json.load(f) return json.load(f)
def put_site_config(site, config, bench='.'): def put_site_config(site, config, bench_path='.'):
config_path = os.path.join(bench, 'sites', site, 'site_config.json') config_path = os.path.join(bench_path, 'sites', site, 'site_config.json')
with open(config_path, 'w') as f: with open(config_path, 'w') as f:
return json.dump(config, f, indent=1) return json.dump(config, f, indent=1)
def update_site_config(site, new_config, bench='.'): def update_site_config(site, new_config, bench_path='.'):
config = get_site_config(site, bench=bench) config = get_site_config(site, bench_path=bench_path)
config.update(new_config) config.update(new_config)
put_site_config(site, config, bench=bench) put_site_config(site, config, bench_path=bench_path)
def set_nginx_port(site, port, bench='.', gen_config=True): def set_nginx_port(site, port, bench_path='.', gen_config=True):
set_site_config_nginx_property(site, {"nginx_port": port}, bench=bench, gen_config=gen_config) set_site_config_nginx_property(site, {"nginx_port": port}, bench_path=bench_path, gen_config=gen_config)
def set_ssl_certificate(site, ssl_certificate, bench='.', gen_config=True): def set_ssl_certificate(site, ssl_certificate, bench_path='.', gen_config=True):
set_site_config_nginx_property(site, {"ssl_certificate": ssl_certificate}, bench=bench, gen_config=gen_config) set_site_config_nginx_property(site, {"ssl_certificate": ssl_certificate}, bench_path=bench_path, gen_config=gen_config)
def set_ssl_certificate_key(site, ssl_certificate_key, bench='.', gen_config=True): def set_ssl_certificate_key(site, ssl_certificate_key, bench_path='.', gen_config=True):
set_site_config_nginx_property(site, {"ssl_certificate_key": ssl_certificate_key}, bench=bench, gen_config=gen_config) set_site_config_nginx_property(site, {"ssl_certificate_key": ssl_certificate_key}, bench_path=bench_path, gen_config=gen_config)
def set_site_config_nginx_property(site, config, bench='.', gen_config=True): def set_site_config_nginx_property(site, config, bench_path='.', gen_config=True):
from .config.nginx import make_nginx_conf from .config.nginx import make_nginx_conf
if site not in get_sites(bench=bench): if site not in get_sites(bench_path=bench_path):
raise Exception("No such site") raise Exception("No such site")
update_site_config(site, config, bench=bench) update_site_config(site, config, bench_path=bench_path)
if gen_config: if gen_config:
make_nginx_conf(bench_path=bench) make_nginx_conf(bench_path=bench_path)
def set_url_root(site, url_root, bench='.'): def set_url_root(site, url_root, bench_path='.'):
update_site_config(site, {"host_name": url_root}, bench=bench) update_site_config(site, {"host_name": url_root}, bench_path=bench_path)
def set_default_site(site, bench='.'): def set_default_site(site, bench_path='.'):
if not site in get_sites(bench=bench): if not site 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=bench), site=site), exec_cmd("{frappe} --use {site}".format(frappe=get_frappe(bench_path=bench_path), site=site),
cwd=os.path.join(bench, 'sites')) cwd=os.path.join(bench_path, 'sites'))
def update_requirements(bench='.'): def update_requirements(bench_path='.'):
pip = os.path.join(bench, 'env', 'bin', 'pip') pip = os.path.join(bench_path, 'env', 'bin', 'pip')
# upgrade pip to latest # upgrade pip to latest
exec_cmd("{pip} install --upgrade pip".format(pip=pip)) exec_cmd("{pip} install --upgrade pip".format(pip=pip))
apps_dir = os.path.join(bench, 'apps') apps_dir = os.path.join(bench_path, 'apps')
for app in os.listdir(apps_dir): for app in os.listdir(apps_dir):
req_file = os.path.join(apps_dir, app, 'requirements.txt') req_file = os.path.join(apps_dir, app, 'requirements.txt')
if os.path.exists(req_file): if os.path.exists(req_file):
exec_cmd("{pip} install -q -r {req_file}".format(pip=pip, req_file=req_file)) exec_cmd("{pip} install -q -r {req_file}".format(pip=pip, req_file=req_file))
def backup_site(site, bench='.'): def backup_site(site, bench_path='.'):
if FRAPPE_VERSION == 4: bench.set_frappe_version(bench_path=bench_path)
exec_cmd("{frappe} --backup {site}".format(frappe=get_frappe(bench=bench), site=site),
cwd=os.path.join(bench, 'sites'))
else:
run_frappe_cmd('--site', site, 'backup', bench=bench)
def backup_all_sites(bench='.'): if bench.FRAPPE_VERSION == 4:
for site in get_sites(bench=bench): exec_cmd("{frappe} --backup {site}".format(frappe=get_frappe(bench_path=bench_path), site=site),
backup_site(site, bench=bench) cwd=os.path.join(bench_path, 'sites'))
else:
run_frappe_cmd('--site', site, 'backup', bench_path=bench_path)
def backup_all_sites(bench_path='.'):
for site in get_sites(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='.'): def set_mariadb_host(host, bench_path='.'):
update_common_site_config({'db_host': host}, bench=bench) update_common_site_config({'db_host': host}, bench_path=bench_path)
def update_common_site_config(ddict, bench='.'): def update_common_site_config(ddict, bench_path='.'):
update_json_file(os.path.join(bench, '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):
@ -424,7 +433,7 @@ def drop_privileges(uid_name='nobody', gid_name='nogroup'):
# Ensure a very conservative umask # Ensure a very conservative umask
os.umask(022) os.umask(022)
def fix_prod_setup_perms(bench='.', 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
files = [ files = [
"logs/web.error.log", "logs/web.error.log",
@ -438,7 +447,7 @@ def fix_prod_setup_perms(bench='.', frappe_user=None):
] ]
if not frappe_user: if not frappe_user:
frappe_user = get_config(bench).get('frappe_user') frappe_user = get_config(bench_path).get('frappe_user')
if not frappe_user: if not frappe_user:
print "frappe user not set" print "frappe user not set"
@ -462,16 +471,16 @@ def fix_file_perms():
if not _file.startswith('activate'): if not _file.startswith('activate'):
os.chmod(os.path.join(bin_dir, _file), 0755) os.chmod(os.path.join(bin_dir, _file), 0755)
def get_current_frappe_version(bench='.'): 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=bench) 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
bench = kwargs.get('bench', '.') bench_path = kwargs.get('bench_path', '.')
f = get_env_cmd('python', bench=bench) f = get_env_cmd('python', bench_path=bench_path)
sites_dir = os.path.join(bench, 'sites') sites_dir = os.path.join(bench_path, 'sites')
async = False if from_command_line else True async = False if from_command_line else True
if async: if async:
@ -491,48 +500,49 @@ def run_frappe_cmd(*args, **kwargs):
raise CommandFailedError(args) raise CommandFailedError(args)
def get_frappe_cmd_output(*args, **kwargs): def get_frappe_cmd_output(*args, **kwargs):
bench = kwargs.get('bench', '.') bench_path = kwargs.get('bench_path', '.')
f = get_env_cmd('python', bench=bench) f = get_env_cmd('python', bench_path=bench_path)
sites_dir = os.path.join(bench, '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='.'): 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='.'): def pre_upgrade(from_ver, to_ver, bench_path='.'):
pip = os.path.join(bench, 'env', 'bin', 'pip') pip = os.path.join(bench_path, 'env', 'bin', 'pip')
if from_ver <= 4 and to_ver >= 5: if from_ver <= 4 and to_ver >= 5:
from .migrate_to_v5 import remove_shopping_cart from .migrate_to_v5 import remove_shopping_cart
apps = ('frappe', 'erpnext') apps = ('frappe', 'erpnext')
remove_shopping_cart(bench=bench) remove_shopping_cart(bench_path=bench_path)
for app in apps: for app in apps:
cwd = os.path.abspath(os.path.join(bench, 'apps', app)) cwd = os.path.abspath(os.path.join(bench_path, 'apps', app))
if os.path.exists(cwd): if os.path.exists(cwd):
exec_cmd("git clean -dxf", cwd=cwd) exec_cmd("git clean -dxf", cwd=cwd)
exec_cmd("{pip} install --upgrade -e {app}".format(pip=pip, app=cwd)) exec_cmd("{pip} install --upgrade -e {app}".format(pip=pip, app=cwd))
def post_upgrade(from_ver, to_ver, bench='.'): 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
from .config import redis from .config import redis
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=bench) conf = get_config(bench_path=bench_path)
print "-"*80 print "-"*80
print "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) redis.generate_config(bench_path=bench_path)
generate_supervisor_config(bench_path=bench) generate_supervisor_config(bench_path=bench_path)
make_nginx_conf(bench_path=bench) make_nginx_conf(bench_path=bench_path)
if from_ver == 4 and to_ver == 5: if from_ver == 4 and to_ver == 5:
setup_backups(bench=bench) setup_backups(bench_path=bench_path)
if from_ver <= 5 and to_ver == 6: if from_ver <= 5 and to_ver == 6:
setup_socketio(bench=bench) setup_socketio(bench_path=bench_path)
print "As you have setup your bench for production, you will have to reload configuration for nginx and supervisor" print "As you have setup your bench for production, you will have to reload configuration for nginx and supervisor"
print "To complete the migration, please run the following commands" print "To complete the migration, please run the following commands"
@ -618,17 +628,15 @@ def get_output(*cmd):
s.stdout.close() s.stdout.close()
return out return out
FRAPPE_VERSION = get_current_frappe_version() def before_update(bench_path, requirements):
validate_pillow_dependencies(bench_path, requirements)
def before_update(bench, requirements): def validate_pillow_dependencies(bench_path, requirements):
validate_pillow_dependencies(bench, requirements)
def validate_pillow_dependencies(bench, requirements):
if not requirements: if not requirements:
return return
try: try:
pip = os.path.join(bench, 'env', 'bin', 'pip') pip = os.path.join(bench_path, 'env', 'bin', 'pip')
exec_cmd("{pip} install Pillow".format(pip=pip)) exec_cmd("{pip} install Pillow".format(pip=pip))
except CommandFailedError: except CommandFailedError: