From 186ba280f1ed5d77e101d5a2fca83951521c901e Mon Sep 17 00:00:00 2001 From: "Chinmay D. Pai" Date: Tue, 23 Jun 2020 14:24:14 +0530 Subject: [PATCH 01/51] fix: add declarative config support for bench bench will attempt to read name and version from setup.cfg before trying to access setup.py for details Signed-off-by: Chinmay D. Pai --- bench/app.py | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/bench/app.py b/bench/app.py index 2c0759852..fbe6b7c17 100755 --- a/bench/app.py +++ b/bench/app.py @@ -16,6 +16,7 @@ import requests import semantic_version from six.moves import reload_module +from setuptools.config import read_configuration # imports - module imports import bench @@ -140,14 +141,23 @@ def get_app(git_url, branch=None, bench_path='.', skip_assets=False, verbose=Fal def get_app_name(bench_path, repo_name): - # retrieves app name from setup.py - app_path = os.path.join(bench_path, 'apps', repo_name, 'setup.py') - with open(app_path, 'rb') as f: - app_name = re.search(r'name\s*=\s*[\'"](.*)[\'"]', f.read().decode('utf-8')).group(1) - if repo_name != app_name: - 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)) - return app_name + app_name = None + apps_path = os.path.join(os.path.abspath(bench_path), 'apps') + config_path = os.path.join(apps_path, repo_name, 'setup.cfg') + if os.path.exists(config_path): + config = read_configuration(config_path) + app_name = config.get('metadata', {}).get('name') + + if not app_name: + # retrieve app name from setup.py as fallback + app_path = os.path.join(apps_path, repo_name, 'setup.py') + with open(app_path, 'rb') as f: + app_name = re.search(r'name\s*=\s*[\'"](.*)[\'"]', f.read().decode('utf-8')).group(1) + + if app_name and repo_name != app_name: + os.rename(os.path.join(apps_path, repo_name), os.path.join(apps_path, app_name)) + + return app_name def new_app(app, bench_path='.'): @@ -325,15 +335,23 @@ def fetch_upstream(app, bench_path='.'): return subprocess.call(["git", "fetch", "upstream"], cwd=repo_dir) def get_current_version(app, bench_path='.'): + current_version = None repo_dir = get_repo_dir(app, bench_path=bench_path) try: - with open(os.path.join(repo_dir, os.path.basename(repo_dir), '__init__.py')) as f: - return get_version_from_string(f.read()) + config_path = os.path.join(repo_dir, "setup.cfg") + if os.path.exists(config_path): + config = read_configuration(config_path) + current_version = config.get("metadata", {}).get("version") + if not current_version: + with open(os.path.join(repo_dir, os.path.basename(repo_dir), '__init__.py')) as f: + current_version = get_version_from_string(f.read()) except AttributeError: # backward compatibility with open(os.path.join(repo_dir, 'setup.py')) as f: - return get_version_from_string(f.read(), field='version') + current_version = get_version_from_string(f.read(), field='version') + + return current_version def get_develop_version(app, bench_path='.'): repo_dir = get_repo_dir(app, bench_path=bench_path) From aa1a1b9a718da1dcfb164f5035fe79a2af813677 Mon Sep 17 00:00:00 2001 From: gavin Date: Thu, 10 Sep 2020 11:44:45 +0530 Subject: [PATCH 02/51] fix: Return repo_name if app_name doesn't exist --- bench/app.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bench/app.py b/bench/app.py index fbe6b7c17..3420f8fad 100755 --- a/bench/app.py +++ b/bench/app.py @@ -156,8 +156,9 @@ def get_app_name(bench_path, repo_name): if app_name and repo_name != app_name: os.rename(os.path.join(apps_path, repo_name), os.path.join(apps_path, app_name)) + return app_name - return app_name + return repo_name def new_app(app, bench_path='.'): From 3ddbff4eaa04008e74c001c5ae9e7f7aeaf722c5 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Thu, 10 Sep 2020 11:49:03 +0530 Subject: [PATCH 03/51] chore: Assign variables to simplify block --- bench/app.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/bench/app.py b/bench/app.py index 3420f8fad..e55498e0b 100755 --- a/bench/app.py +++ b/bench/app.py @@ -338,18 +338,21 @@ def fetch_upstream(app, bench_path='.'): def get_current_version(app, bench_path='.'): current_version = None repo_dir = get_repo_dir(app, bench_path=bench_path) + config_path = os.path.join(repo_dir, "setup.cfg") + init_path = os.path.join(repo_dir, os.path.basename(repo_dir), '__init__.py') + setup_path = os.path.join(repo_dir, 'setup.py') + try: - config_path = os.path.join(repo_dir, "setup.cfg") if os.path.exists(config_path): config = read_configuration(config_path) current_version = config.get("metadata", {}).get("version") if not current_version: - with open(os.path.join(repo_dir, os.path.basename(repo_dir), '__init__.py')) as f: + with open(init_path) as f: current_version = get_version_from_string(f.read()) except AttributeError: # backward compatibility - with open(os.path.join(repo_dir, 'setup.py')) as f: + with open(setup_path) as f: current_version = get_version_from_string(f.read(), field='version') return current_version From 7f9bed4c8e18114a54432e426e958281da7428ec Mon Sep 17 00:00:00 2001 From: Raffael Meyer <14891507+barredterra@users.noreply.github.com> Date: Mon, 25 Jan 2021 19:36:56 +0100 Subject: [PATCH 04/51] fix: nginx proxy buffer --- bench/config/templates/nginx.conf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bench/config/templates/nginx.conf b/bench/config/templates/nginx.conf index 06fc0b2ba..82f16d466 100644 --- a/bench/config/templates/nginx.conf +++ b/bench/config/templates/nginx.conf @@ -29,6 +29,10 @@ server { {% if allow_rate_limiting %} limit_conn per_host_{{ bench_name_hash }} 8; {% endif %} + + proxy_buffer_size 128k; + proxy_buffers 4 256k; + proxy_busy_buffers_size 256k; {% if ssl_certificate and ssl_certificate_key %} ssl on; From 4211f5d750b5f6130e5479ea263154d3cd87bb84 Mon Sep 17 00:00:00 2001 From: Mohammad Hasnain Mohsin Rajan Date: Thu, 4 Feb 2021 16:09:42 +0530 Subject: [PATCH 05/51] fix: change TEST_PYPI to PYPI --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 18103defe..fbb96207b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,6 +23,6 @@ jobs: - name: Create Release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - TEST_PYPI_PASSWORD: ${{ secrets.PYPI_PASSWORD }} - TEST_PYPI_USERNAME: ${{ secrets.PYPI_USERNAME }} + PYPI_PASSWORD: ${{ secrets.PYPI_PASSWORD }} + PYPI_USERNAME: ${{ secrets.PYPI_USERNAME }} run: npx semantic-release From 7e171967b3773446e231dfe56221e107eda0c157 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Tue, 9 Feb 2021 11:06:04 +0530 Subject: [PATCH 06/51] docs: Update help message for --frappe-branch --- bench/commands/make.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bench/commands/make.py b/bench/commands/make.py index 554b06039..c20b25b30 100755 --- a/bench/commands/make.py +++ b/bench/commands/make.py @@ -8,7 +8,7 @@ @click.option('--ignore-exist', is_flag = True, default = False, help = "Ignore if Bench instance exists.") @click.option('--apps_path', default=None, help="path to json files with apps to install after init") @click.option('--frappe-path', default=None, help="path to frappe repo") -@click.option('--frappe-branch', default=None, help="path to frappe repo") +@click.option('--frappe-branch', default=None, help="Clone a particular branch of frappe") @click.option('--clone-from', default=None, help="copy repos from path") @click.option('--clone-without-update', is_flag=True, help="copy repos from path without update") @click.option('--no-procfile', is_flag=True, help="Do not create a Procfile") From 17ef5da5ce3a7061a01c890ae8ca90dcbb6c7957 Mon Sep 17 00:00:00 2001 From: DANY ROBERT Date: Tue, 16 Feb 2021 20:17:49 +0530 Subject: [PATCH 07/51] fix: Upgrade pip first (#1120) * fix: Upgrade pip first `pip` needs to be upgraded before `cryptography` to avoid version compatibility error. * fix: Add setuptools-rust in upgrade. * fix: Install setuptools-rust * fix: Add setuptools-rust in requirments.txt * fix: Revert unwanted addition to README * fix: Install setuptools-rust beforehand. * fix: Upgrade pip beforehand. * fix: Upgrade pip separately beforehand. * fix: Upgrade setuptools-rust with pip. * chore: Remove unused dependency Co-authored-by: gavin --- install.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/install.py b/install.py index 716478243..1abd26553 100644 --- a/install.py +++ b/install.py @@ -170,8 +170,11 @@ def install_prerequisites(): install_package('git') install_package('pip3', 'python3-pip') + run_os_command({ + 'python3': "sudo -H python3 -m pip install --upgrade pip setuptools-rust" + }) success = run_os_command({ - 'python3': "sudo -H python3 -m pip install --upgrade setuptools wheel cryptography ansible~=2.8.15 pip" + 'python3': "sudo -H python3 -m pip install --upgrade setuptools wheel cryptography ansible~=2.8.15" }) if not (success or shutil.which('ansible')): From 5c5d2b57dfaf0e43b56b7140717649e356e2cad6 Mon Sep 17 00:00:00 2001 From: Nicolas Streng Date: Tue, 16 Feb 2021 16:45:07 +0100 Subject: [PATCH 08/51] fix: create bench folder in user directory --- bench/playbooks/create_user.yml | 2 +- bench/playbooks/roles/bench/tasks/main.yml | 4 ++-- bench/playbooks/roles/bench/tasks/setup_inputrc.yml | 4 ++-- bench/playbooks/site.yml | 4 ++-- install.py | 8 +++++++- 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/bench/playbooks/create_user.yml b/bench/playbooks/create_user.yml index 2991afb30..10695833b 100644 --- a/bench/playbooks/create_user.yml +++ b/bench/playbooks/create_user.yml @@ -11,7 +11,7 @@ - name: Set home folder perms file: - path: '/home/{{ frappe_user }}' + path: '{{ user_directory }}' mode: 'o+rx' owner: '{{ frappe_user }}' group: '{{ frappe_user }}' diff --git a/bench/playbooks/roles/bench/tasks/main.yml b/bench/playbooks/roles/bench/tasks/main.yml index e01d18b73..164a216e0 100644 --- a/bench/playbooks/roles/bench/tasks/main.yml +++ b/bench/playbooks/roles/bench/tasks/main.yml @@ -33,7 +33,7 @@ - name: Fix permissions become_user: root - command: chown {{ frappe_user }} -R /home/{{ frappe_user }} + command: chown {{ frappe_user }} -R {{ user_directory }} - name: python3 bench init for develop command: bench init {{ bench_path }} --frappe-path {{ frappe_repo_url }} --frappe-branch {{ frappe_branch }} --python {{ python }} @@ -77,6 +77,6 @@ # Setup Bench for production environment - include_tasks: setup_bench_production.yml vars: - bench_path: "/home/{{ frappe_user }}/{{ bench_name }}" + bench_path: "{{ user_directory }}/{{ bench_name }}" when: not run_travis and production ... diff --git a/bench/playbooks/roles/bench/tasks/setup_inputrc.yml b/bench/playbooks/roles/bench/tasks/setup_inputrc.yml index 9c88b9336..14b47a344 100644 --- a/bench/playbooks/roles/bench/tasks/setup_inputrc.yml +++ b/bench/playbooks/roles/bench/tasks/setup_inputrc.yml @@ -1,11 +1,11 @@ --- - name: insert/update inputrc for history blockinfile: - dest: "/home/{{ frappe_user }}/.inputrc" + dest: "{{ user_directory }}/.inputrc" create: yes block: | ## arrow up "\e[A":history-search-backward ## arrow down "\e[B":history-search-forward -... \ No newline at end of file +... diff --git a/bench/playbooks/site.yml b/bench/playbooks/site.yml index 328cfcba1..7a3e106c5 100644 --- a/bench/playbooks/site.yml +++ b/bench/playbooks/site.yml @@ -40,8 +40,8 @@ - name: setup bench and dev environment hosts: localhost vars: - bench_repo_path: "/home/{{ frappe_user }}/.bench" - bench_path: "/home/{{ frappe_user }}/{{ bench_name }}" + bench_repo_path: "{{ user_directory }}/.bench" + bench_path: "{{ user_directory }}/{{ bench_name }}" roles: # setup frappe-bench - { role: bench, tags: "bench", when: not run_travis and not without_bench_setup } diff --git a/install.py b/install.py index 716478243..0b1540936 100644 --- a/install.py +++ b/install.py @@ -231,10 +231,11 @@ def install_bench(args): # create user if not exists extra_vars = vars(args) extra_vars.update(frappe_user=args.user) + + extra_vars.update(user_directory=get_user_home_directory(args.user)) if os.path.exists(tmp_bench_repo): repo_path = tmp_bench_repo - else: repo_path = os.path.join(os.path.expanduser('~'), 'bench') @@ -383,6 +384,11 @@ def get_extra_vars_json(extra_args): return ('@' + json_path) +def get_user_home_directory(user): + # Return home directory /home/USERNAME or anything else defined as home directory in + # passwd for user. + return os.path.expanduser('~'+user) + def run_playbook(playbook_name, sudo=False, extra_vars=None): args = ['ansible-playbook', '-c', 'local', playbook_name , '-vvvv'] From 294b399942e3b143fdb235efe9176460f12ad9d7 Mon Sep 17 00:00:00 2001 From: Nicolas Streng Date: Wed, 17 Feb 2021 08:18:37 +0100 Subject: [PATCH 09/51] fix: Update documentation for user directory --- docs/easy_install.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/easy_install.md b/docs/easy_install.md index 3c59f3084..91ee55666 100644 --- a/docs/easy_install.md +++ b/docs/easy_install.md @@ -34,6 +34,8 @@ If you are on a fresh server and logged in as root, at first create a dedicated *(it is very common to use "frappe" as frappe-username, but this comes with the security flaw of ["frappe" ranking very high](https://www.reddit.com/r/dataisbeautiful/comments/b3sirt/i_deployed_over_a_dozen_cyber_honeypots_all_over/?st=JTJ0SC0Q&sh=76e05240) in as a username challenged in hacking attempts. So, for production sites it is highly recommended to use a custom username harder to guess)* +*(you can specify the flag --home to specify a directory for your [frappe-user]. Bench will follow the home directory specified by the user's home directory e.g. /data/[frappe-user]/frappe-bench)* + Switch to `[frappe-user]` (using `su [frappe-user]`) and start the setup wget https://raw.githubusercontent.com/frappe/bench/develop/install.py @@ -71,7 +73,7 @@ use --python flag to specify virtual environments python version, by default scr ## How do I start ERPNext -1. For development: Go to your bench folder (`frappe-bench` by default) and start the bench with `bench start` +1. For development: Go to your bench folder (`~[frappe-user]/frappe-bench` by default) and start the bench with `bench start` 2. For production: Your process will be setup and managed by `nginx` and `supervisor`. Checkout [Setup Production](https://frappe.io/docs/user/en/bench/guides/setup-production.html) for more information. --- From fec89212143d122c647292195fd4b1f8024a55bd Mon Sep 17 00:00:00 2001 From: DANY ROBERT Date: Thu, 18 Feb 2021 11:31:38 +0530 Subject: [PATCH 10/51] fix: fail2ban help message --- bench/commands/setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bench/commands/setup.py b/bench/commands/setup.py index 08e2d4f22..328fc74dc 100755 --- a/bench/commands/setup.py +++ b/bench/commands/setup.py @@ -253,8 +253,8 @@ def setup_roles(role, **kwargs): @click.command("fail2ban", help="Setup 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. Default is 6 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") +@click.option("--bantime", default=600, help="Duration (in seconds) for IP to be banned for. Negative number for 'permanent' ban. Default is 600 seconds") +@click.option("--findtime", default=600, help="The counter is set to zero if match found within 'findtime' seconds doesn't exceed 'maxretry'. Default is 600 seconds") def setup_nginx_proxy_jail(**kwargs): run_playbook("roles/fail2ban/tasks/configure_nginx_jail.yml", extra_vars=kwargs) From cc9258492784ed0fc7fa31f283b97f2e4e260836 Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Sat, 20 Feb 2021 13:14:56 +0530 Subject: [PATCH 11/51] perf: Remove requests from the import tree --- bench/app.py | 5 ++++- bench/release.py | 9 ++++++--- bench/utils.py | 7 ++++++- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/bench/app.py b/bench/app.py index 2c0759852..e70d51ed9 100755 --- a/bench/app.py +++ b/bench/app.py @@ -13,7 +13,6 @@ # imports - third party imports import click import git -import requests import semantic_version from six.moves import reload_module @@ -91,6 +90,8 @@ def remove_from_excluded_apps_txt(app, bench_path='.'): return write_excluded_apps_txt(apps, bench_path=bench_path) def get_app(git_url, branch=None, bench_path='.', skip_assets=False, verbose=False, restart_bench=True, overwrite=False): + import requests + if not os.path.exists(git_url): if not is_git_url(git_url): orgs = ['frappe', 'erpnext'] @@ -433,6 +434,8 @@ def install_apps_from_path(path, bench_path='.'): get_app(app['url'], branch=app.get('branch'), bench_path=bench_path, skip_assets=True) def get_apps_json(path): + import requests + if path.startswith('http'): r = requests.get(path) return r.json() diff --git a/bench/release.py b/bench/release.py index f026b3797..81efdc021 100755 --- a/bench/release.py +++ b/bench/release.py @@ -4,11 +4,8 @@ import sys import semantic_version import git -import requests import getpass import re -from requests.auth import HTTPBasicAuth -import requests.exceptions from time import sleep from .config.common_site_config import get_config import click @@ -47,6 +44,9 @@ def release(bench_path, app, bump_type, from_branch, to_branch, repo_name=repo_name, remote=remote, frontport=frontport) def validate(bench_path, config): + import requests + from requests.auth import HTTPBasicAuth + global github_username, github_password github_username = config.get('github_username') @@ -306,6 +306,9 @@ def push_release(repo_path, from_branch, to_branch, remote='upstream'): def create_github_release(repo_path, tag_name, message, remote='upstream', owner='frappe', repo_name=None, gh_username=None, gh_password=None, prerelease=False): + import requests + import requests.exceptions + from requests.auth import HTTPBasicAuth print('creating release on github') diff --git a/bench/utils.py b/bench/utils.py index bb1b55e49..7a08c3461 100755 --- a/bench/utils.py +++ b/bench/utils.py @@ -24,7 +24,6 @@ # imports - third party imports import click from crontab import CronTab -import requests from semantic_version import Version from six import iteritems from six.moves.urllib.parse import urlparse @@ -93,6 +92,8 @@ def safe_decode(string, encoding = 'utf-8'): def check_latest_version(): + import requests + try: pypi_request = requests.get("https://pypi.org/pypi/frappe-bench/json") except Exception: @@ -815,6 +816,8 @@ def post_upgrade(from_ver, to_ver, bench_path='.'): def update_translations_p(args): + import requests + try: update_translations(*args) except requests.exceptions.HTTPError: @@ -846,6 +849,8 @@ def get_langs(): def update_translations(app, lang): + import requests + translations_dir = os.path.join('apps', app, app, 'translations') csv_file = os.path.join(translations_dir, lang + '.csv') url = "https://translate.erpnext.com/files/{}-{}.csv".format(app, lang) From df773d4f9f60f6d8b566f29ee44bc3769b895e8d Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Sat, 20 Feb 2021 13:22:56 +0530 Subject: [PATCH 12/51] perf: Remove git from the import tree --- bench/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bench/app.py b/bench/app.py index e70d51ed9..84070c280 100755 --- a/bench/app.py +++ b/bench/app.py @@ -12,7 +12,6 @@ # imports - third party imports import click -import git import semantic_version from six.moves import reload_module @@ -359,6 +358,7 @@ def get_repo_dir(app, bench_path='.'): return os.path.join(bench_path, 'apps', app) def switch_branch(branch, apps=None, bench_path='.', upgrade=False, check_upgrade=True): + import git from bench.utils import update_requirements, update_node_packages, backup_all_sites, patch_sites, build_assets, post_upgrade apps_dir = os.path.join(bench_path, 'apps') version_upgrade = (False,) From ad90d9485f389b168b96f1de161a0bd281a936cf Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Sat, 20 Feb 2021 13:52:39 +0530 Subject: [PATCH 13/51] perf: Remove Jinja and PackageLoader from the import tree --- bench/config/__init__.py | 5 +++-- bench/config/lets_encrypt.py | 2 +- bench/config/nginx.py | 4 ++-- bench/config/procfile.py | 2 +- bench/config/redis.py | 2 +- bench/config/supervisor.py | 2 +- bench/config/systemd.py | 26 +++++++++++++------------- bench/utils.py | 2 +- 8 files changed, 23 insertions(+), 22 deletions(-) diff --git a/bench/config/__init__.py b/bench/config/__init__.py index 301b515bb..5a1b0c60d 100644 --- a/bench/config/__init__.py +++ b/bench/config/__init__.py @@ -1,6 +1,7 @@ """Module for setting up system and respective bench configurations""" # imports - third party imports -from jinja2 import Environment, PackageLoader -env = Environment(loader=PackageLoader('bench.config')) +def env(): + from jinja2 import Environment, PackageLoader + return Environment(loader=PackageLoader('bench.config')) diff --git a/bench/config/lets_encrypt.py b/bench/config/lets_encrypt.py index 32ca3380d..9f2851990 100755 --- a/bench/config/lets_encrypt.py +++ b/bench/config/lets_encrypt.py @@ -48,7 +48,7 @@ def setup_letsencrypt(site, custom_domain, bench_path, interactive): def create_config(site, custom_domain): - config = bench.config.env.get_template('letsencrypt.cfg').render(domain=custom_domain or site) + config = bench.config.env().get_template('letsencrypt.cfg').render(domain=custom_domain or site) config_path = '/etc/letsencrypt/configs/{site}.cfg'.format(site=custom_domain or site) create_dir_if_missing(config_path) diff --git a/bench/config/nginx.py b/bench/config/nginx.py index fbb736802..4ed4233d0 100644 --- a/bench/config/nginx.py +++ b/bench/config/nginx.py @@ -20,7 +20,7 @@ def make_nginx_conf(bench_path, yes=False): if not click.confirm('nginx.conf already exists and this will overwrite it. Do you want to continue?'): return - template = bench.config.env.get_template('nginx.conf') + template = bench.config.env().get_template('nginx.conf') bench_path = os.path.abspath(bench_path) sites_path = os.path.join(bench_path, "sites") @@ -59,7 +59,7 @@ def make_bench_manager_nginx_conf(bench_path, yes=False, port=23624, domain=None from bench.config.site_config import get_site_config from bench.config.common_site_config import get_config - template = bench.config.env.get_template('bench_manager_nginx.conf') + template = bench.config.env().get_template('bench_manager_nginx.conf') bench_path = os.path.abspath(bench_path) sites_path = os.path.join(bench_path, "sites") diff --git a/bench/config/procfile.py b/bench/config/procfile.py index 1b3f20edc..e57e579d6 100755 --- a/bench/config/procfile.py +++ b/bench/config/procfile.py @@ -18,7 +18,7 @@ def setup_procfile(bench_path, yes=False, skip_redis=False): click.confirm('A Procfile already exists and this will overwrite it. Do you want to continue?', abort=True) - procfile = bench.config.env.get_template('Procfile').render( + procfile = bench.config.env().get_template('Procfile').render( node=find_executable("node") or find_executable("nodejs"), use_rq=use_rq(bench_path), webserver_port=config.get('webserver_port'), diff --git a/bench/config/redis.py b/bench/config/redis.py index 42005b07e..9d8f3ee45 100644 --- a/bench/config/redis.py +++ b/bench/config/redis.py @@ -52,7 +52,7 @@ def generate_config(bench_path): os.makedirs(pid_path) def write_redis_config(template_name, context, bench_path): - template = bench.config.env.get_template(template_name) + template = bench.config.env().get_template(template_name) if "pid_path" not in context: context["pid_path"] = os.path.abspath(os.path.join(bench_path, "config", "pids")) diff --git a/bench/config/supervisor.py b/bench/config/supervisor.py index 8788757fb..8a3d07fab 100644 --- a/bench/config/supervisor.py +++ b/bench/config/supervisor.py @@ -22,7 +22,7 @@ def generate_supervisor_config(bench_path, user=None, yes=False): if not user: user = getpass.getuser() - template = bench.config.env.get_template('supervisor.conf') + template = bench.config.env().get_template('supervisor.conf') config = get_config(bench_path=bench_path) bench_dir = os.path.abspath(bench_path) diff --git a/bench/config/systemd.py b/bench/config/systemd.py index 4a4148255..574f857e6 100644 --- a/bench/config/systemd.py +++ b/bench/config/systemd.py @@ -85,7 +85,7 @@ def setup_systemd_directory(bench_path): def setup_main_config(bench_info, bench_path): # Main config - bench_template = bench.config.env.get_template('systemd/frappe-bench.target') + bench_template = bench.config.env().get_template('systemd/frappe-bench.target') bench_config = bench_template.render(**bench_info) bench_config_path = os.path.join(bench_path, 'config', 'systemd' , bench_info.get("bench_name") + '.target') @@ -94,11 +94,11 @@ def setup_main_config(bench_info, bench_path): def setup_workers_config(bench_info, bench_path): # Worker Group - bench_workers_target_template = bench.config.env.get_template('systemd/frappe-bench-workers.target') - bench_default_worker_template = bench.config.env.get_template('systemd/frappe-bench-frappe-default-worker.service') - bench_short_worker_template = bench.config.env.get_template('systemd/frappe-bench-frappe-short-worker.service') - bench_long_worker_template = bench.config.env.get_template('systemd/frappe-bench-frappe-long-worker.service') - bench_schedule_worker_template = bench.config.env.get_template('systemd/frappe-bench-frappe-schedule.service') + bench_workers_target_template = bench.config.env().get_template('systemd/frappe-bench-workers.target') + bench_default_worker_template = bench.config.env().get_template('systemd/frappe-bench-frappe-default-worker.service') + bench_short_worker_template = bench.config.env().get_template('systemd/frappe-bench-frappe-short-worker.service') + bench_long_worker_template = bench.config.env().get_template('systemd/frappe-bench-frappe-long-worker.service') + bench_schedule_worker_template = bench.config.env().get_template('systemd/frappe-bench-frappe-schedule.service') bench_workers_target_config = bench_workers_target_template.render(**bench_info) bench_default_worker_config = bench_default_worker_template.render(**bench_info) @@ -129,9 +129,9 @@ def setup_workers_config(bench_info, bench_path): def setup_web_config(bench_info, bench_path): # Web Group - bench_web_target_template = bench.config.env.get_template('systemd/frappe-bench-web.target') - bench_web_service_template = bench.config.env.get_template('systemd/frappe-bench-frappe-web.service') - bench_node_socketio_template = bench.config.env.get_template('systemd/frappe-bench-node-socketio.service') + bench_web_target_template = bench.config.env().get_template('systemd/frappe-bench-web.target') + bench_web_service_template = bench.config.env().get_template('systemd/frappe-bench-frappe-web.service') + bench_node_socketio_template = bench.config.env().get_template('systemd/frappe-bench-node-socketio.service') bench_web_target_config = bench_web_target_template.render(**bench_info) bench_web_service_config = bench_web_service_template.render(**bench_info) @@ -152,10 +152,10 @@ def setup_web_config(bench_info, bench_path): def setup_redis_config(bench_info, bench_path): # Redis Group - bench_redis_target_template = bench.config.env.get_template('systemd/frappe-bench-redis.target') - bench_redis_cache_template = bench.config.env.get_template('systemd/frappe-bench-redis-cache.service') - bench_redis_queue_template = bench.config.env.get_template('systemd/frappe-bench-redis-queue.service') - bench_redis_socketio_template = bench.config.env.get_template('systemd/frappe-bench-redis-socketio.service') + bench_redis_target_template = bench.config.env().get_template('systemd/frappe-bench-redis.target') + bench_redis_cache_template = bench.config.env().get_template('systemd/frappe-bench-redis-cache.service') + bench_redis_queue_template = bench.config.env().get_template('systemd/frappe-bench-redis-queue.service') + bench_redis_socketio_template = bench.config.env().get_template('systemd/frappe-bench-redis-socketio.service') bench_redis_target_config = bench_redis_target_template.render(**bench_info) bench_redis_cache_config = bench_redis_cache_template.render(**bench_info) diff --git a/bench/utils.py b/bench/utils.py index 7a08c3461..4e7a24dbc 100755 --- a/bench/utils.py +++ b/bench/utils.py @@ -423,7 +423,7 @@ def setup_sudoers(user): if set_permissions: os.chmod('/etc/sudoers', 0o440) - template = bench.config.env.get_template('frappe_sudoers') + template = bench.config.env().get_template('frappe_sudoers') frappe_sudoers = template.render(**{ 'user': user, 'service': find_executable('service'), From ad37665e8b9520a22d0a624104a547afa83a40b8 Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Sun, 21 Feb 2021 10:01:44 +0530 Subject: [PATCH 14/51] perf: Remove multiprocessing from the import tree --- bench/utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bench/utils.py b/bench/utils.py index 4e7a24dbc..f6ec6b54b 100755 --- a/bench/utils.py +++ b/bench/utils.py @@ -9,7 +9,6 @@ import itertools import json import logging -import multiprocessing import os import pwd import re @@ -825,6 +824,8 @@ def update_translations_p(args): def download_translations_p(): + import multiprocessing + pool = multiprocessing.Pool(multiprocessing.cpu_count()) langs = get_langs() From 2a4377ac6f22f53dc687f222e2e6c7bb2f7879e6 Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Sun, 21 Feb 2021 10:02:02 +0530 Subject: [PATCH 15/51] perf: Remove crontab from the import tree --- bench/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bench/utils.py b/bench/utils.py index f6ec6b54b..1428d19d8 100755 --- a/bench/utils.py +++ b/bench/utils.py @@ -22,7 +22,6 @@ # imports - third party imports import click -from crontab import CronTab from semantic_version import Version from six import iteritems from six.moves.urllib.parse import urlparse @@ -386,6 +385,7 @@ def get_sites(bench_path='.'): def setup_backups(bench_path='.'): + from crontab import CronTab from bench.config.common_site_config import get_config logger.log('setting up backups') From 104efd349bcc9cf1ed599279778976322272a065 Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Sun, 21 Feb 2021 10:02:20 +0530 Subject: [PATCH 16/51] perf: Remove ast from the import tree --- bench/commands/config.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bench/commands/config.py b/bench/commands/config.py index 4d4bec598..196e78771 100644 --- a/bench/commands/config.py +++ b/bench/commands/config.py @@ -1,5 +1,4 @@ # imports - standard imports -import ast # imports - module imports from bench.config.common_site_config import update_config, get_config, put_config @@ -52,6 +51,8 @@ def config_http_timeout(seconds): @click.command('set-common-config', help='Set value in common config') @click.option('configs', '-c', '--config', multiple=True, type=(str, str)) def set_common_config(configs): + import ast + common_site_config = {} for key, value in configs: if value in ('true', 'false'): From 8527b106c39c445b9fb8eee3d14fa8beaf9828cf Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Sun, 21 Feb 2021 10:02:41 +0530 Subject: [PATCH 17/51] perf: Remove multiprocessing from the import tree --- bench/config/common_site_config.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bench/config/common_site_config.py b/bench/config/common_site_config.py index d71d9efd9..26f1040b6 100644 --- a/bench/config/common_site_config.py +++ b/bench/config/common_site_config.py @@ -1,7 +1,6 @@ # imports - standard imports import getpass import json -import multiprocessing import os # imports - third party imports @@ -54,6 +53,8 @@ def get_config_path(bench_path): def get_gunicorn_workers(): '''This function will return the maximum workers that can be started depending upon number of cpu's present on the machine''' + import multiprocessing + return { "gunicorn_workers": multiprocessing.cpu_count() * 2 + 1 } From 6c0e1a359ebd19bd3833c3e9d7c5d1ef8948419d Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Sun, 21 Feb 2021 10:03:03 +0530 Subject: [PATCH 18/51] perf: Remove siz.moves.configparser from the import tree --- bench/config/supervisor.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bench/config/supervisor.py b/bench/config/supervisor.py index 8a3d07fab..b2f26d675 100644 --- a/bench/config/supervisor.py +++ b/bench/config/supervisor.py @@ -11,7 +11,6 @@ # imports - third party imports import click -from six.moves import configparser logger = logging.getLogger(bench.PROJECT_NAME) @@ -68,6 +67,8 @@ def get_supervisord_conf(): def update_supervisord_config(user=None, yes=False): """From bench v5.x, we're moving to supervisor running as user""" + from six.moves import configparser + from bench.config.production_setup import service if not user: From e12717d63ac410f14f292dab62b398b37b5e48a3 Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Sun, 21 Feb 2021 10:03:36 +0530 Subject: [PATCH 19/51] perf: Remove crontab from the import tree --- bench/config/lets_encrypt.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bench/config/lets_encrypt.py b/bench/config/lets_encrypt.py index 9f2851990..c771226dc 100755 --- a/bench/config/lets_encrypt.py +++ b/bench/config/lets_encrypt.py @@ -3,7 +3,6 @@ # imports - third party imports import click -from crontab import CronTab from six.moves.urllib.request import urlretrieve # imports - module imports @@ -86,6 +85,8 @@ def run_certbot_and_setup_ssl(site, custom_domain, bench_path, interactive=True) def setup_crontab(): + from crontab import CronTab + job_command = '/opt/certbot-auto renew -a nginx --post-hook "systemctl reload nginx"' job_comment = 'Renew lets-encrypt every month' print("Setting Up cron job to {0}".format(job_comment)) From 5525548ced5a3c9666e30f22682f7d7cef362240 Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Sun, 21 Feb 2021 10:04:03 +0530 Subject: [PATCH 20/51] perf: Remove six.moves.urllib from the import tree --- bench/config/lets_encrypt.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bench/config/lets_encrypt.py b/bench/config/lets_encrypt.py index c771226dc..752d361cc 100755 --- a/bench/config/lets_encrypt.py +++ b/bench/config/lets_encrypt.py @@ -3,7 +3,6 @@ # imports - third party imports import click -from six.moves.urllib.request import urlretrieve # imports - module imports import bench @@ -107,6 +106,8 @@ def create_dir_if_missing(path): def get_certbot(): + from six.moves.urllib.request import urlretrieve + certbot_path = get_certbot_path() create_dir_if_missing(certbot_path) From 36e48c7dd7625edb4dded617992576faa01c96e6 Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Sun, 21 Feb 2021 10:05:40 +0530 Subject: [PATCH 21/51] perf: Remove bench.config.nginx from the import tree --- bench/commands/setup.py | 3 ++- bench/config/site_config.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/bench/commands/setup.py b/bench/commands/setup.py index 08e2d4f22..87b0d5b73 100755 --- a/bench/commands/setup.py +++ b/bench/commands/setup.py @@ -7,7 +7,6 @@ # imports - module imports import bench.config.lets_encrypt -import bench.config.nginx import bench.config.procfile import bench.config.production_setup import bench.config.redis @@ -31,6 +30,8 @@ def setup_sudoers(user): @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): + import bench.config.nginx + bench.config.nginx.make_nginx_conf(bench_path=".", yes=yes) diff --git a/bench/config/site_config.py b/bench/config/site_config.py index 696185c8a..9ea67a862 100644 --- a/bench/config/site_config.py +++ b/bench/config/site_config.py @@ -4,7 +4,6 @@ from collections import defaultdict # imports - module imports -from bench.config.nginx import make_nginx_conf from bench.utils import get_sites @@ -35,6 +34,8 @@ def set_ssl_certificate_key(site, ssl_certificate_key, bench_path='.', gen_confi 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_path='.', gen_config=True): + from bench.config.nginx import make_nginx_conf + if site not in get_sites(bench_path=bench_path): raise Exception("No such site") update_site_config(site, config, bench_path=bench_path) From cab2d44df5c1854d5f5dbce6e627a35565b4d8ef Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Sun, 21 Feb 2021 10:06:11 +0530 Subject: [PATCH 22/51] perf: Remove bench.config.letsencrypt from the import tree --- bench/commands/setup.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/bench/commands/setup.py b/bench/commands/setup.py index 87b0d5b73..21dfdafa1 100755 --- a/bench/commands/setup.py +++ b/bench/commands/setup.py @@ -6,9 +6,7 @@ import click # imports - module imports -import bench.config.lets_encrypt import bench.config.procfile -import bench.config.production_setup import bench.config.redis import bench.config.site_config import bench.config.supervisor @@ -37,6 +35,8 @@ def setup_nginx(yes=False): @click.command("reload-nginx", help="Checks NGINX config file and reloads service") def reload_nginx(): + import bench.config.production_setup + bench.config.production_setup.reload_nginx() @@ -62,6 +62,8 @@ def setup_fonts(): @click.argument("user") @click.option("--yes", help="Yes to regeneration config", is_flag=True, default=False) def setup_production(user, yes=False): + import bench.config.production_setup + bench.config.production_setup.setup_production(user=user, yes=yes) @@ -104,6 +106,8 @@ def set_ssh_port(port, force=False): @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") def setup_letsencrypt(site, custom_domain, non_interactive): + import bench.config.lets_encrypt + bench.config.lets_encrypt.setup_letsencrypt(site, custom_domain, bench_path=".", interactive=not non_interactive) @@ -112,6 +116,8 @@ def setup_letsencrypt(site, custom_domain, non_interactive): @click.option("--email") @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): + import bench.config.lets_encrypt + bench.config.lets_encrypt.setup_wildcard_ssl(domain, email, bench_path=".", exclude_base_domain=exclude_base_domain) From c5d2fb9255979a46fc4e29b9d04f44e8acf2f722 Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Sun, 21 Feb 2021 10:06:44 +0530 Subject: [PATCH 23/51] perf: Remove bench.config.common_site_config from the import tree --- bench/app.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/bench/app.py b/bench/app.py index 84070c280..a3a63ec8f 100755 --- a/bench/app.py +++ b/bench/app.py @@ -17,7 +17,6 @@ # imports - module imports import bench -from bench.config.common_site_config import get_config from bench.utils import color, CommandFailedError, build_assets, check_git_for_shallow_clone, exec_cmd, get_cmd_output, get_frappe, restart_supervisor_processes, restart_systemd_processes, run_frappe_cmd @@ -166,6 +165,8 @@ def new_app(app, bench_path='.'): def install_app(app, bench_path=".", verbose=False, no_cache=False, restart_bench=True, skip_assets=False): + from bench.config.common_site_config import get_config + print('\n{0}Installing {1}{2}'.format(color.yellow, app, color.nc)) logger.log("installing {}".format(app)) @@ -194,6 +195,8 @@ def install_app(app, bench_path=".", verbose=False, no_cache=False, restart_benc def remove_app(app, bench_path='.'): + from bench.config.common_site_config import get_config + if app not in get_apps(bench_path): print("No app named {0}".format(app)) sys.exit(1) @@ -221,6 +224,8 @@ def remove_app(app, bench_path='.'): def pull_apps(apps=None, bench_path='.', reset=False): '''Check all apps if there no local changes, pull''' + from bench.config.common_site_config import get_config + rebase = '--rebase' if get_config(bench_path).get('rebase_on_pull') else '' apps = apps or get_apps(bench_path=bench_path) From 6706b230da1bfb42dbd671c5524ee1ed62c6908c Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Sun, 21 Feb 2021 11:10:43 +0530 Subject: [PATCH 24/51] perf: Remove six.moves.urllib from the import tree --- bench/config/common_site_config.py | 3 ++- bench/config/redis.py | 3 ++- bench/utils.py | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/bench/config/common_site_config.py b/bench/config/common_site_config.py index 26f1040b6..08f62c8f5 100644 --- a/bench/config/common_site_config.py +++ b/bench/config/common_site_config.py @@ -4,7 +4,6 @@ import os # imports - third party imports -from six.moves.urllib.parse import urlparse default_config = { @@ -74,6 +73,8 @@ def update_config_for_frappe(config, bench_path): # TODO Optionally we need to add the host or domain name in case dns_multitenant is false def make_ports(bench_path): + from six.moves.urllib.parse import urlparse + benches_path = os.path.dirname(os.path.abspath(bench_path)) default_ports = { diff --git a/bench/config/redis.py b/bench/config/redis.py index 9d8f3ee45..8c707dcda 100644 --- a/bench/config/redis.py +++ b/bench/config/redis.py @@ -5,7 +5,6 @@ # imports - third party imports import semantic_version -from six.moves.urllib.parse import urlparse # imports - module imports import bench @@ -13,6 +12,8 @@ def generate_config(bench_path): + from six.moves.urllib.parse import urlparse + config = get_config(bench_path) ports = {} diff --git a/bench/utils.py b/bench/utils.py index 1428d19d8..6a2614cfd 100755 --- a/bench/utils.py +++ b/bench/utils.py @@ -24,7 +24,6 @@ import click from semantic_version import Version from six import iteritems -from six.moves.urllib.parse import urlparse # imports - module imports import bench @@ -973,6 +972,7 @@ def find_benches(directory=None): def migrate_env(python, backup=False): + from six.moves.urllib.parse import urlparse from bench.config.common_site_config import get_config from bench.app import get_apps From 07ecaa1f776d15c98d50087e3757dc4910203e7d Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Sun, 21 Feb 2021 11:12:00 +0530 Subject: [PATCH 25/51] perf: Remove shutil from the import tree --- bench/app.py | 3 ++- bench/utils.py | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/bench/app.py b/bench/app.py index a3a63ec8f..689a59214 100755 --- a/bench/app.py +++ b/bench/app.py @@ -6,7 +6,6 @@ import logging import os import re -import shutil import subprocess import sys @@ -89,6 +88,7 @@ def remove_from_excluded_apps_txt(app, bench_path='.'): def get_app(git_url, branch=None, bench_path='.', skip_assets=False, verbose=False, restart_bench=True, overwrite=False): import requests + import shutil if not os.path.exists(git_url): if not is_git_url(git_url): @@ -195,6 +195,7 @@ def install_app(app, bench_path=".", verbose=False, no_cache=False, restart_benc def remove_app(app, bench_path='.'): + import shutil from bench.config.common_site_config import get_config if app not in get_apps(bench_path): diff --git a/bench/utils.py b/bench/utils.py index 6a2614cfd..a9f9a60cf 100755 --- a/bench/utils.py +++ b/bench/utils.py @@ -13,7 +13,6 @@ import pwd import re import select -import shutil import site import subprocess import sys @@ -261,6 +260,8 @@ def update(pull=False, apps=None, patch=False, build=False, requirements=False, def copy_patches_txt(bench_path): + import shutil + shutil.copy(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'patches', 'patches.txt'), os.path.join(bench_path, 'patches.txt')) @@ -900,6 +901,8 @@ def get_bench_name(bench_path): def setup_fonts(): + import shutil + fonts_path = os.path.join('/tmp', 'fonts') if os.path.exists('/etc/fonts_backup'): @@ -972,6 +975,7 @@ def find_benches(directory=None): def migrate_env(python, backup=False): + import shutil from six.moves.urllib.parse import urlparse from bench.config.common_site_config import get_config from bench.app import get_apps From 2df0bf726d9c1fb5fb4188c4c745d918d1cf1774 Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Sun, 21 Feb 2021 11:12:40 +0530 Subject: [PATCH 26/51] perf: Remove semantic_version from the import tree --- bench/app.py | 3 ++- bench/config/redis.py | 5 ++--- bench/utils.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bench/app.py b/bench/app.py index 689a59214..0cf8f6198 100755 --- a/bench/app.py +++ b/bench/app.py @@ -11,7 +11,6 @@ # imports - third party imports import click -import semantic_version from six.moves import reload_module # imports - module imports @@ -432,6 +431,8 @@ def get_version_from_string(contents, field='__version__'): return match.group(2) def get_major_version(version): + import semantic_version + return semantic_version.Version(version).major def install_apps_from_path(path, bench_path='.'): diff --git a/bench/config/redis.py b/bench/config/redis.py index 8c707dcda..7af1bbf79 100644 --- a/bench/config/redis.py +++ b/bench/config/redis.py @@ -3,9 +3,6 @@ import re import subprocess -# imports - third party imports -import semantic_version - # imports - module imports import bench from bench.config.common_site_config import get_config @@ -62,6 +59,8 @@ def write_redis_config(template_name, context, bench_path): f.write(template.render(**context)) def get_redis_version(): + import semantic_version + version_string = subprocess.check_output('redis-server --version', shell=True) version_string = version_string.decode('utf-8').strip() # extract version number from string diff --git a/bench/utils.py b/bench/utils.py index a9f9a60cf..66297ffce 100755 --- a/bench/utils.py +++ b/bench/utils.py @@ -21,7 +21,6 @@ # imports - third party imports import click -from semantic_version import Version from six import iteritems # imports - module imports @@ -89,6 +88,7 @@ def safe_decode(string, encoding = 'utf-8'): def check_latest_version(): import requests + from semantic_version import Version try: pypi_request = requests.get("https://pypi.org/pypi/frappe-bench/json") From 5d903466604c354ede536ffeadbffba0306c7666 Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Sun, 21 Feb 2021 11:12:57 +0530 Subject: [PATCH 27/51] perf: Remove six.moves.reload_module from the import tree --- bench/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bench/app.py b/bench/app.py index 0cf8f6198..0367ea9b1 100755 --- a/bench/app.py +++ b/bench/app.py @@ -11,7 +11,6 @@ # imports - third party imports import click -from six.moves import reload_module # imports - module imports import bench @@ -364,6 +363,7 @@ def get_repo_dir(app, bench_path='.'): def switch_branch(branch, apps=None, bench_path='.', upgrade=False, check_upgrade=True): import git + from six.moves import reload_module from bench.utils import update_requirements, update_node_packages, backup_all_sites, patch_sites, build_assets, post_upgrade apps_dir = os.path.join(bench_path, 'apps') version_upgrade = (False,) From b70aa21a7394c6f323162ee754ca4ed7e76320cd Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Sun, 21 Feb 2021 11:24:32 +0530 Subject: [PATCH 28/51] chore: Remove unused import comment blocks --- bench/commands/config.py | 2 -- bench/config/__init__.py | 1 - bench/config/common_site_config.py | 1 - 3 files changed, 4 deletions(-) diff --git a/bench/commands/config.py b/bench/commands/config.py index 196e78771..b36919415 100644 --- a/bench/commands/config.py +++ b/bench/commands/config.py @@ -1,5 +1,3 @@ -# imports - standard imports - # imports - module imports from bench.config.common_site_config import update_config, get_config, put_config diff --git a/bench/config/__init__.py b/bench/config/__init__.py index 5a1b0c60d..f79be5322 100644 --- a/bench/config/__init__.py +++ b/bench/config/__init__.py @@ -1,6 +1,5 @@ """Module for setting up system and respective bench configurations""" -# imports - third party imports def env(): from jinja2 import Environment, PackageLoader diff --git a/bench/config/common_site_config.py b/bench/config/common_site_config.py index 08f62c8f5..41d9cc9cb 100644 --- a/bench/config/common_site_config.py +++ b/bench/config/common_site_config.py @@ -3,7 +3,6 @@ import json import os -# imports - third party imports default_config = { From 5cf1363481f0cde81d0c4163f4c5de0aff934360 Mon Sep 17 00:00:00 2001 From: Revant Nandgaonkar Date: Fri, 26 Feb 2021 07:55:04 +0530 Subject: [PATCH 29/51] feat: skip redis config during supervisor setup --- bench/commands/setup.py | 5 +++-- bench/config/supervisor.py | 5 +++-- bench/config/templates/supervisor.conf | 6 ++++++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/bench/commands/setup.py b/bench/commands/setup.py index 08e2d4f22..860c83755 100755 --- a/bench/commands/setup.py +++ b/bench/commands/setup.py @@ -42,9 +42,10 @@ def reload_nginx(): @click.command("supervisor", help="Generate configuration for supervisor") @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): +@click.option("--skip-redis", help="Skip redis configuration", is_flag=True, default=False) +def setup_supervisor(user=None, yes=False, skip_redis=False): bench.config.supervisor.update_supervisord_config(user=user, yes=yes) - bench.config.supervisor.generate_supervisor_config(bench_path=".", user=user, yes=yes) + bench.config.supervisor.generate_supervisor_config(bench_path=".", user=user, yes=yes, skip_redis=skip_redis) @click.command("redis", help="Generates configuration for Redis") diff --git a/bench/config/supervisor.py b/bench/config/supervisor.py index 8788757fb..08740e701 100644 --- a/bench/config/supervisor.py +++ b/bench/config/supervisor.py @@ -17,7 +17,7 @@ logger = logging.getLogger(bench.PROJECT_NAME) -def generate_supervisor_config(bench_path, user=None, yes=False): +def generate_supervisor_config(bench_path, user=None, yes=False, skip_redis=False): """Generate supervisor config for respective bench path""" if not user: user = getpass.getuser() @@ -42,7 +42,8 @@ def generate_supervisor_config(bench_path, user=None, yes=False): "gunicorn_workers": config.get('gunicorn_workers', get_gunicorn_workers()["gunicorn_workers"]), "bench_name": get_bench_name(bench_path), "background_workers": config.get('background_workers') or 1, - "bench_cmd": find_executable('bench') + "bench_cmd": find_executable('bench'), + "skip_redis": skip_redis, }) conf_path = os.path.join(bench_path, 'config', 'supervisor.conf') diff --git a/bench/config/templates/supervisor.conf b/bench/config/templates/supervisor.conf index a9d06331e..92aa83335 100644 --- a/bench/config/templates/supervisor.conf +++ b/bench/config/templates/supervisor.conf @@ -114,6 +114,7 @@ killasgroup=true {% endif %} +{% if not skip_redis %} [program:{{ bench_name }}-redis-cache] command={{ redis_server }} {{ redis_cache_config }} priority=1 @@ -133,8 +134,10 @@ stdout_logfile={{ bench_dir }}/logs/redis-queue.log stderr_logfile={{ bench_dir }}/logs/redis-queue.error.log user={{ user }} directory={{ sites_dir }} +{% endif %} {% if frappe_version > 5 %} +{% if not skip_redis %} [program:{{ bench_name }}-redis-socketio] command={{ redis_server }} {{ redis_socketio_config }} priority=1 @@ -144,6 +147,7 @@ stdout_logfile={{ bench_dir }}/logs/redis-socketio.log stderr_logfile={{ bench_dir }}/logs/redis-socketio.error.log user={{ user }} directory={{ sites_dir }} +{% endif %} {% if node %} [program:{{ bench_name }}-node-socketio] @@ -174,5 +178,7 @@ programs={{ bench_name }}-frappe-workerbeat,{{ bench_name }}-frappe-worker,{{ be {% endif %} +{% if not skip_redis %} [group:{{ bench_name }}-redis] programs={{ bench_name }}-redis-cache,{{ bench_name }}-redis-queue {%- if frappe_version > 5 -%} ,{{ bench_name }}-redis-socketio {%- endif %} +{% endif %} From 66240e1f8d038f419e586499579fc437f309419b Mon Sep 17 00:00:00 2001 From: Richard Case Date: Thu, 4 Mar 2021 23:18:42 +0000 Subject: [PATCH 30/51] feat: Keep repos shallow if --reset is specified and shallow_clone is set --- bench/app.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/bench/app.py b/bench/app.py index 0367ea9b1..763446826 100755 --- a/bench/app.py +++ b/bench/app.py @@ -268,9 +268,15 @@ def pull_apps(apps=None, bench_path='.', reset=False): continue logger.log('pulling {0}'.format(app)) if reset: - exec_cmd("git fetch --all", cwd=app_dir) - exec_cmd("git reset --hard {remote}/{branch}".format( - remote=remote, branch=get_current_branch(app,bench_path=bench_path)), cwd=app_dir) + reset_cmd = "git reset --hard {remote}/{branch}".format( + remote=remote, branch=get_current_branch(app,bench_path=bench_path)) + if get_config(bench_path).get('shallow_clone'): + exec_cmd("git fetch --depth 1 --no-tags", cwd=app_dir) + exec_cmd(reset_cmd, cwd=app_dir) + exec_cmd("git clean -dfx", cwd=app_dir) + else: + exec_cmd("git fetch --all", cwd=app_dir) + exec_cmd(reset_cmd, cwd=app_dir) else: exec_cmd("git pull {rebase} {remote} {branch}".format(rebase=rebase, remote=remote, branch=get_current_branch(app, bench_path=bench_path)), cwd=app_dir) From 82173c1d42eaaed563f6f3ac17cda2e96b35b195 Mon Sep 17 00:00:00 2001 From: Richard Case Date: Wed, 10 Mar 2021 18:45:47 +0000 Subject: [PATCH 31/51] fix: only fetch what is necessary, simplify & improve grepability --- bench/app.py | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/bench/app.py b/bench/app.py index 763446826..d8f559074 100755 --- a/bench/app.py +++ b/bench/app.py @@ -228,7 +228,7 @@ def pull_apps(apps=None, bench_path='.', reset=False): rebase = '--rebase' if get_config(bench_path).get('rebase_on_pull') else '' apps = apps or get_apps(bench_path=bench_path) - # chech for local changes + # check for local changes if not reset: for app in apps: excluded_apps = get_excluded_apps() @@ -271,9 +271,10 @@ def pull_apps(apps=None, bench_path='.', reset=False): reset_cmd = "git reset --hard {remote}/{branch}".format( remote=remote, branch=get_current_branch(app,bench_path=bench_path)) if get_config(bench_path).get('shallow_clone'): - exec_cmd("git fetch --depth 1 --no-tags", cwd=app_dir) + exec_cmd("git fetch --depth=1 --no-tags", cwd=app_dir) exec_cmd(reset_cmd, cwd=app_dir) - exec_cmd("git clean -dfx", cwd=app_dir) + exec_cmd("git reflog expire --all", cwd=app_dir) + exec_cmd("git gc --prune=all", cwd=app_dir) else: exec_cmd("git fetch --all", cwd=app_dir) exec_cmd(reset_cmd, cwd=app_dir) @@ -284,20 +285,15 @@ def pull_apps(apps=None, bench_path='.', reset=False): def is_version_upgrade(app='frappe', bench_path='.', branch=None): - try: - fetch_upstream(app, bench_path=bench_path) - except CommandFailedError: - raise InvalidRemoteException("No remote named upstream for {0}".format(app)) - upstream_version = get_upstream_version(app=app, branch=branch, bench_path=bench_path) 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 remote'.format(app)) local_version = get_major_version(get_current_version(app, bench_path=bench_path)) upstream_version = get_major_version(upstream_version) - if upstream_version - local_version > 0: + if upstream_version > local_version: return (True, local_version, upstream_version) return (False, local_version, upstream_version) @@ -330,10 +326,6 @@ def use_rq(bench_path): celery_app = os.path.join(bench_path, 'apps', 'frappe', 'frappe', 'celery_app.py') return not os.path.exists(celery_app) -def fetch_upstream(app, bench_path='.'): - repo_dir = get_repo_dir(app, bench_path=bench_path) - return subprocess.call(["git", "fetch", "upstream"], cwd=repo_dir) - def get_current_version(app, bench_path='.'): repo_dir = get_repo_dir(app, bench_path=bench_path) try: @@ -352,10 +344,16 @@ def get_develop_version(app, bench_path='.'): def get_upstream_version(app, branch=None, bench_path='.'): repo_dir = get_repo_dir(app, bench_path=bench_path) + try: + subprocess.call('git fetch --depth=1 --no-tags upstream', shell=True, cwd=repo_dir) + except CommandFailedError: + raise InvalidRemoteException('Failed to fetch from remote named upstream for {0}'.format(app)) + if not branch: branch = get_current_branch(app, bench_path=bench_path) 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), + shell=True, cwd=repo_dir, stderr=subprocess.STDOUT) contents = contents.decode('utf-8') except subprocess.CalledProcessError as e: if b"Invalid object" in e.output: From 895c40327806d93d33507731cefed2d013ba117e Mon Sep 17 00:00:00 2001 From: Richard Case Date: Wed, 10 Mar 2021 19:47:48 +0000 Subject: [PATCH 32/51] fix: only fetch current branch --- bench/app.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/bench/app.py b/bench/app.py index d8f559074..a2ddfbfaf 100755 --- a/bench/app.py +++ b/bench/app.py @@ -237,7 +237,7 @@ def pull_apps(apps=None, bench_path='.', reset=False): continue app_dir = get_repo_dir(app, bench_path=bench_path) if os.path.exists(os.path.join(app_dir, '.git')): - out = subprocess.check_output(["git", "status"], cwd=app_dir) + out = subprocess.check_output('git status', shell=True, cwd=app_dir) out = out.decode('utf-8') if not re.search(r'nothing to commit, working (directory|tree) clean', out): print(''' @@ -266,12 +266,13 @@ def pull_apps(apps=None, bench_path='.', reset=False): add_to_excluded_apps_txt(app, bench_path=bench_path) print("Skipping pull for app {}, since remote doesn't exist, and adding it to excluded apps".format(app)) continue + branch = get_current_branch(app, bench_path=bench_path) logger.log('pulling {0}'.format(app)) if reset: - reset_cmd = "git reset --hard {remote}/{branch}".format( - remote=remote, branch=get_current_branch(app,bench_path=bench_path)) + reset_cmd = "git reset --hard {remote}/{branch}".format(remote=remote, branch=branch) if get_config(bench_path).get('shallow_clone'): - exec_cmd("git fetch --depth=1 --no-tags", cwd=app_dir) + exec_cmd("git fetch --depth=1 --no-tags {remote} {branch}".format(remote=remote, branch=branch), + cwd=app_dir) exec_cmd(reset_cmd, cwd=app_dir) exec_cmd("git reflog expire --all", cwd=app_dir) exec_cmd("git gc --prune=all", cwd=app_dir) @@ -280,7 +281,7 @@ def pull_apps(apps=None, bench_path='.', reset=False): exec_cmd(reset_cmd, cwd=app_dir) else: exec_cmd("git pull {rebase} {remote} {branch}".format(rebase=rebase, - remote=remote, branch=get_current_branch(app, bench_path=bench_path)), cwd=app_dir) + remote=remote, branch=branch), cwd=app_dir) exec_cmd('find . -name "*.pyc" -delete', cwd=app_dir) From 0ff8dddef960f63e35103285961f08f835da422e Mon Sep 17 00:00:00 2001 From: Richard Case Date: Wed, 10 Mar 2021 19:58:55 +0000 Subject: [PATCH 33/51] fix: only get the specific branch for version check --- bench/app.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/bench/app.py b/bench/app.py index a2ddfbfaf..390ca0365 100755 --- a/bench/app.py +++ b/bench/app.py @@ -345,13 +345,14 @@ def get_develop_version(app, bench_path='.'): def get_upstream_version(app, branch=None, bench_path='.'): repo_dir = get_repo_dir(app, bench_path=bench_path) + if not branch: + branch = get_current_branch(app, bench_path=bench_path) + try: - subprocess.call('git fetch --depth=1 --no-tags upstream', shell=True, cwd=repo_dir) + subprocess.call('git fetch --depth=1 --no-tags upstream {branch}'.format(branch=branch), shell=True, cwd=repo_dir) except CommandFailedError: raise InvalidRemoteException('Failed to fetch from remote named upstream for {0}'.format(app)) - if not branch: - branch = get_current_branch(app, bench_path=bench_path) try: contents = subprocess.check_output('git show upstream/{branch}:{app}/__init__.py'.format(branch=branch, app=app), shell=True, cwd=repo_dir, stderr=subprocess.STDOUT) From a1db48b57ef7263e1bf2775f8738469f9074533f Mon Sep 17 00:00:00 2001 From: casesolved-co-uk Date: Mon, 15 Mar 2021 20:52:34 +0000 Subject: [PATCH 34/51] fix: serious bug capable of deleting apps path --- bench/app.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bench/app.py b/bench/app.py index 390ca0365..607867605 100755 --- a/bench/app.py +++ b/bench/app.py @@ -109,7 +109,8 @@ def get_app(git_url, branch=None, bench_path='.', skip_assets=False, verbose=Fal shallow_clone = '--depth 1' if check_git_for_shallow_clone() else '' branch = '--branch {branch}'.format(branch=branch) if branch else '' else: - repo_name = git_url.split(os.sep)[-1] + git_url = os.path.abspath(git_url) + _, repo_name = os.path.split(git_url) shallow_clone = '' branch = '--branch {branch}'.format(branch=branch) if branch else '' From 4c627e4531ace6324bee3e810b9329f278833f3d Mon Sep 17 00:00:00 2001 From: Mohammad Hasnain Mohsin Rajan Date: Thu, 18 Mar 2021 13:57:21 +0530 Subject: [PATCH 35/51] chore: update version (#1138) * chore: update version * chore: use dev version on develop branch * chore: move develop branch check before imports --- bench/__init__.py | 2 +- bench/utils.py | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/bench/__init__.py b/bench/__init__.py index eec75ea43..19d73b97f 100644 --- a/bench/__init__.py +++ b/bench/__init__.py @@ -1,4 +1,4 @@ -VERSION = "5.2.1" +VERSION = "5.0.0-dev" PROJECT_NAME = "frappe-bench" FRAPPE_VERSION = None diff --git a/bench/utils.py b/bench/utils.py index 66297ffce..2c22005bd 100755 --- a/bench/utils.py +++ b/bench/utils.py @@ -87,6 +87,9 @@ def safe_decode(string, encoding = 'utf-8'): def check_latest_version(): + if bench.VERSION.endswith("dev"): + return + import requests from semantic_version import Version From 9b297284a676f11299ffa6bca25c3c4e2584774b Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 22 Mar 2021 16:23:26 +0530 Subject: [PATCH 36/51] build(deps): [security] bump jinja2 from 2.10.3 to 2.11.3 (#1142) Bumps [jinja2](https://github.com/pallets/jinja) from 2.10.3 to 2.11.3. **This update includes a security fix.** - [Release notes](https://github.com/pallets/jinja/releases) - [Changelog](https://github.com/pallets/jinja/blob/master/CHANGES.rst) - [Commits](https://github.com/pallets/jinja/compare/2.10.3...2.11.3) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index ea1bdd089..92df93314 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ Click==7.0 GitPython==2.1.15 honcho==1.0.1 -Jinja2==2.10.3 +Jinja2==2.11.3 python-crontab==2.4.0 requests==2.22.0 semantic-version==2.8.2 From b3a0757e38be2acf4e6bc8c8427717096d5e8bb0 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Fri, 2 Apr 2021 19:48:04 +0530 Subject: [PATCH 37/51] fix: use correct path for compiling py files --- bench/utils.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bench/utils.py b/bench/utils.py index 2c22005bd..365b1ed02 100755 --- a/bench/utils.py +++ b/bench/utils.py @@ -247,8 +247,9 @@ def update(pull=False, apps=None, patch=False, build=False, requirements=False, post_upgrade(version_upgrade[1], version_upgrade[2], bench_path=bench_path) if pull and compile: - print("Compiling Python files...") - compileall.compile_dir('../apps', quiet=1, rx=re.compile('.*node_modules.*')) + print('Compiling Python files...') + apps_dir = os.path.join(bench_path, 'apps') + compileall.compile_dir(apps_dir, quiet=1, rx=re.compile('.*node_modules.*')) if restart_supervisor or conf.get('restart_supervisor_on_update'): restart_supervisor_processes(bench_path=bench_path) From 777b204490cd4bc96eea9fe9ef0cefccd17b4ba4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20HOUZET?= Date: Wed, 7 Apr 2021 09:43:33 +0200 Subject: [PATCH 38/51] docs: Change link on Menu to Basic Usage Fix link on menu to Basic Usage --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index abbbb7f4b..f11b78793 100755 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Bench is a command-line utility that helps you to install, update, and manage mu - [Production Setup](#docker-installation-for-production) - [Easy Install Script](#easy-install-script) - [Manual Installation](#manual-installation) - - [Usage](#usage) + - [Usage](#basic-usage) - [Custom Bench commands](#custom-bench-commands) - [Bench Manager](#bench-manager) - [Guides](#guides) From ec2ce0f3b80d0e838b8ccaf1180313e5c47b8339 Mon Sep 17 00:00:00 2001 From: Sagar Vora Date: Tue, 13 Apr 2021 13:06:08 +0530 Subject: [PATCH 39/51] chore: remove support for older versions of frappe --- bench/app.py | 8 +---- bench/config/supervisor.py | 3 +- bench/config/systemd.py | 3 +- bench/config/templates/supervisor.conf | 5 +-- bench/utils.py | 48 +++++--------------------- 5 files changed, 13 insertions(+), 54 deletions(-) diff --git a/bench/app.py b/bench/app.py index 0367ea9b1..18d768dae 100755 --- a/bench/app.py +++ b/bench/app.py @@ -152,13 +152,7 @@ def new_app(app, bench_path='.'): app = app.lower().replace(" ", "_").replace("-", "_") logger.log('creating new app {}'.format(app)) apps = os.path.abspath(os.path.join(bench_path, 'apps')) - bench.set_frappe_version(bench_path=bench_path) - - if bench.FRAPPE_VERSION == 4: - exec_cmd("{frappe} --make_app {apps} {app}".format(frappe=get_frappe(bench_path=bench_path), - apps=apps, app=app)) - else: - run_frappe_cmd('make-app', apps, app, bench_path=bench_path) + run_frappe_cmd('make-app', apps, app, bench_path=bench_path) install_app(app, bench_path=bench_path) diff --git a/bench/config/supervisor.py b/bench/config/supervisor.py index dd9cfa6ee..76ffd877f 100644 --- a/bench/config/supervisor.py +++ b/bench/config/supervisor.py @@ -5,7 +5,7 @@ # imports - module imports import bench -from bench.app import get_current_frappe_version, use_rq +from bench.app import use_rq from bench.utils import get_bench_name, find_executable from bench.config.common_site_config import get_config, update_config, get_gunicorn_workers @@ -29,7 +29,6 @@ def generate_supervisor_config(bench_path, user=None, yes=False, skip_redis=Fals "bench_dir": bench_dir, "sites_dir": os.path.join(bench_dir, 'sites'), "user": user, - "frappe_version": get_current_frappe_version(bench_path), "use_rq": use_rq(bench_path), "http_timeout": config.get("http_timeout", 120), "redis_server": find_executable('redis-server'), diff --git a/bench/config/systemd.py b/bench/config/systemd.py index 574f857e6..c0a0053c2 100644 --- a/bench/config/systemd.py +++ b/bench/config/systemd.py @@ -7,7 +7,7 @@ # imports - module imports import bench -from bench.app import get_current_frappe_version, use_rq +from bench.app import use_rq from bench.config.common_site_config import get_config, get_gunicorn_workers, update_config from bench.utils import exec_cmd, find_executable, get_bench_name @@ -51,7 +51,6 @@ def generate_systemd_config(bench_path, user=None, yes=False, "bench_dir": bench_dir, "sites_dir": os.path.join(bench_dir, 'sites'), "user": user, - "frappe_version": get_current_frappe_version(bench_path), "use_rq": use_rq(bench_path), "http_timeout": config.get("http_timeout", 120), "redis_server": find_executable('redis-server'), diff --git a/bench/config/templates/supervisor.conf b/bench/config/templates/supervisor.conf index 92aa83335..d24b1cb61 100644 --- a/bench/config/templates/supervisor.conf +++ b/bench/config/templates/supervisor.conf @@ -136,7 +136,6 @@ user={{ user }} directory={{ sites_dir }} {% endif %} -{% if frappe_version > 5 %} {% if not skip_redis %} [program:{{ bench_name }}-redis-socketio] command={{ redis_server }} {{ redis_socketio_config }} @@ -161,8 +160,6 @@ user={{ user }} directory={{ bench_dir }} {% endif %} -{% endif %} - [group:{{ bench_name }}-web] programs={{ bench_name }}-frappe-web {%- if node -%} ,{{ bench_name }}-node-socketio {%- endif%} @@ -180,5 +177,5 @@ programs={{ bench_name }}-frappe-workerbeat,{{ bench_name }}-frappe-worker,{{ be {% if not skip_redis %} [group:{{ bench_name }}-redis] -programs={{ bench_name }}-redis-cache,{{ bench_name }}-redis-queue {%- if frappe_version > 5 -%} ,{{ bench_name }}-redis-socketio {%- endif %} +programs={{ bench_name }}-redis-cache,{{ bench_name }}-redis-queue,{{ bench_name }}-redis-socketio {% endif %} diff --git a/bench/utils.py b/bench/utils.py index 2c22005bd..54350ba9f 100755 --- a/bench/utils.py +++ b/bench/utils.py @@ -163,11 +163,8 @@ def init(path, apps_path=None, no_procfile=False, no_backups=False, if apps_path: install_apps_from_path(apps_path, bench_path=path) - - bench.set_frappe_version(bench_path=path) - if bench.FRAPPE_VERSION > 5: - if not skip_assets: - update_node_packages(bench_path=path) + if not skip_assets: + update_node_packages(bench_path=path) set_all_patches_executed(bench_path=path) if not skip_assets: @@ -358,27 +355,17 @@ def setup_socketio(bench_path='.'): def patch_sites(bench_path='.'): - bench.set_frappe_version(bench_path=bench_path) - try: - if bench.FRAPPE_VERSION == 4: - exec_cmd("{frappe} --latest all".format(frappe=get_frappe(bench_path=bench_path)), cwd=os.path.join(bench_path, 'sites')) - else: - run_frappe_cmd('--site', 'all', 'migrate', bench_path=bench_path) + run_frappe_cmd('--site', 'all', 'migrate', bench_path=bench_path) except subprocess.CalledProcessError: raise PatchError def build_assets(bench_path='.', app=None): - bench.set_frappe_version(bench_path=bench_path) - - if bench.FRAPPE_VERSION == 4: - exec_cmd("{frappe} --build".format(frappe=get_frappe(bench_path=bench_path)), cwd=os.path.join(bench_path, 'sites')) - else: - command = 'bench build' - if app: - command += ' --app {}'.format(app) - exec_cmd(command, cwd=bench_path) + command = 'bench build' + if app: + command += ' --app {}'.format(app) + exec_cmd(command, cwd=bench_path) def get_sites(bench_path='.'): @@ -395,14 +382,8 @@ def setup_backups(bench_path='.'): bench_dir = os.path.abspath(bench_path) user = get_config(bench_path=bench_dir).get('frappe_user') logfile = os.path.join(bench_dir, 'logs', 'backup.log') - bench.set_frappe_version(bench_path=bench_path) system_crontab = CronTab(user=user) - - if bench.FRAPPE_VERSION == 4: - backup_command = "cd {sites_dir} && {frappe} --backup all".format(frappe=get_frappe(bench_path=bench_path),) - else: - backup_command = "cd {bench_dir} && {bench} --verbose --site all backup".format(bench_dir=bench_dir, bench=sys.argv[0]) - + backup_command = "cd {bench_dir} && {bench} --verbose --site all backup".format(bench_dir=bench_dir, bench=sys.argv[0]) job_command = "{backup_command} >> {logfile} 2>&1".format(backup_command=backup_command, logfile=logfile) if job_command not in str(system_crontab): @@ -662,13 +643,7 @@ def update_npm_packages(bench_path='.'): def backup_site(site, bench_path='.'): - bench.set_frappe_version(bench_path=bench_path) - - if bench.FRAPPE_VERSION == 4: - exec_cmd("{frappe} --backup {site}".format(frappe=get_frappe(bench_path=bench_path), site=site), - cwd=os.path.join(bench_path, 'sites')) - 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='.'): @@ -754,11 +729,6 @@ def fix_prod_setup_perms(bench_path='.', frappe_user=None): os.chown(path, uid, gid) -def get_current_frappe_version(bench_path='.'): - from .app import get_current_frappe_version as fv - return fv(bench_path=bench_path) - - def run_frappe_cmd(*args, **kwargs): from .cli import from_command_line From 778fe6cb0bdf442bceac0ac5b98b7ab7fdcae6da Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Fri, 23 Apr 2021 10:47:36 +0530 Subject: [PATCH 40/51] fix: Don't break update if no sites exist on patching sites stage --- bench/utils.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/bench/utils.py b/bench/utils.py index 417eb12fb..43525bb54 100755 --- a/bench/utils.py +++ b/bench/utils.py @@ -356,10 +356,11 @@ def setup_socketio(bench_path='.'): def patch_sites(bench_path='.'): - try: - run_frappe_cmd('--site', 'all', 'migrate', bench_path=bench_path) - except subprocess.CalledProcessError: - raise PatchError + for site in get_sites(bench_path=bench_path): + try: + migrate_site(site, bench_path=bench_path) + except subprocess.CalledProcessError: + raise PatchError def build_assets(bench_path='.', app=None): @@ -643,6 +644,10 @@ def update_npm_packages(bench_path='.'): exec_cmd('npm install', cwd=bench_path) +def migrate_site(site, bench_path='.'): + run_frappe_cmd('--site', site, 'migrate', bench_path=bench_path) + + def backup_site(site, bench_path='.'): run_frappe_cmd('--site', site, 'backup', bench_path=bench_path) From da85e0ccdd83e40956c30a1bd00e3a1543faa682 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Fri, 23 Apr 2021 10:58:21 +0530 Subject: [PATCH 41/51] refactor: Optimize and simplify imports * make relative imports absolute * minor: Simplify logic --- bench/config/procfile.py | 4 +- bench/config/production_setup.py | 18 ++++----- bench/config/supervisor.py | 8 ++-- bench/config/systemd.py | 8 ++-- bench/utils.py | 67 +++++++++++++++++--------------- 5 files changed, 54 insertions(+), 51 deletions(-) diff --git a/bench/config/procfile.py b/bench/config/procfile.py index e57e579d6..50a455609 100755 --- a/bench/config/procfile.py +++ b/bench/config/procfile.py @@ -8,7 +8,7 @@ import bench from bench.app import use_rq from bench.config.common_site_config import get_config -from bench.utils import find_executable +from bench.utils import which def setup_procfile(bench_path, yes=False, skip_redis=False): @@ -19,7 +19,7 @@ def setup_procfile(bench_path, yes=False, skip_redis=False): abort=True) procfile = bench.config.env().get_template('Procfile').render( - node=find_executable("node") or find_executable("nodejs"), + node=which("node") or which("nodejs"), use_rq=use_rq(bench_path), webserver_port=config.get('webserver_port'), CI=os.environ.get('CI'), diff --git a/bench/config/production_setup.py b/bench/config/production_setup.py index 6809b7331..13640e6f4 100755 --- a/bench/config/production_setup.py +++ b/bench/config/production_setup.py @@ -9,7 +9,7 @@ from bench.config.nginx import make_nginx_conf from bench.config.supervisor import generate_supervisor_config, update_supervisord_config from bench.config.systemd import generate_systemd_config -from bench.utils import CommandFailedError, exec_cmd, find_executable, fix_prod_setup_perms, get_bench_name, get_cmd_output, log +from bench.utils import CommandFailedError, exec_cmd, which, fix_prod_setup_perms, get_bench_name, get_cmd_output, log logger = logging.getLogger(bench.PROJECT_NAME) @@ -17,13 +17,13 @@ def setup_production_prerequisites(): """Installs ansible, fail2banc, NGINX and supervisor""" - if not find_executable("ansible"): + if not which("ansible"): exec_cmd("sudo {0} -m pip install ansible".format(sys.executable)) - if not find_executable("fail2ban-client"): + if not which("fail2ban-client"): exec_cmd("bench setup role fail2ban") - if not find_executable("nginx"): + if not which("nginx"): exec_cmd("bench setup role nginx") - if not find_executable("supervisord"): + if not which("supervisord"): exec_cmd("bench setup role supervisor") @@ -95,11 +95,11 @@ def disable_production(bench_path='.'): def service(service_name, service_option): - if os.path.basename(find_executable('systemctl') or '') == 'systemctl' and is_running_systemd(): + if os.path.basename(which('systemctl') or '') == 'systemctl' and is_running_systemd(): systemctl_cmd = "sudo {service_manager} {service_option} {service_name}" exec_cmd(systemctl_cmd.format(service_manager='systemctl', service_option=service_option, service_name=service_name)) - elif os.path.basename(find_executable('service') or '') == 'service': + elif os.path.basename(which('service') or '') == 'service': service_cmd = "sudo {service_manager} {service_name} {service_option}" exec_cmd(service_cmd.format(service_manager='service', service_name=service_name, service_option=service_option)) @@ -145,7 +145,7 @@ def is_running_systemd(): def reload_supervisor(): - supervisorctl = find_executable('supervisorctl') + supervisorctl = which('supervisorctl') try: # first try reread/update @@ -178,7 +178,7 @@ def reload_supervisor(): def reload_nginx(): try: - exec_cmd('sudo {0} -t'.format(find_executable('nginx'))) + exec_cmd('sudo {0} -t'.format(which('nginx'))) except: raise diff --git a/bench/config/supervisor.py b/bench/config/supervisor.py index 76ffd877f..0cea009e0 100644 --- a/bench/config/supervisor.py +++ b/bench/config/supervisor.py @@ -6,7 +6,7 @@ # imports - module imports import bench from bench.app import use_rq -from bench.utils import get_bench_name, find_executable +from bench.utils import get_bench_name, which from bench.config.common_site_config import get_config, update_config, get_gunicorn_workers # imports - third party imports @@ -31,8 +31,8 @@ def generate_supervisor_config(bench_path, user=None, yes=False, skip_redis=Fals "user": user, "use_rq": use_rq(bench_path), "http_timeout": config.get("http_timeout", 120), - "redis_server": find_executable('redis-server'), - "node": find_executable('node') or find_executable('nodejs'), + "redis_server": which('redis-server'), + "node": which('node') or which('nodejs'), "redis_cache_config": os.path.join(bench_dir, 'config', 'redis_cache.conf'), "redis_socketio_config": os.path.join(bench_dir, 'config', 'redis_socketio.conf'), "redis_queue_config": os.path.join(bench_dir, 'config', 'redis_queue.conf'), @@ -40,7 +40,7 @@ def generate_supervisor_config(bench_path, user=None, yes=False, skip_redis=Fals "gunicorn_workers": config.get('gunicorn_workers', get_gunicorn_workers()["gunicorn_workers"]), "bench_name": get_bench_name(bench_path), "background_workers": config.get('background_workers') or 1, - "bench_cmd": find_executable('bench'), + "bench_cmd": which('bench'), "skip_redis": skip_redis, }) diff --git a/bench/config/systemd.py b/bench/config/systemd.py index c0a0053c2..1501d4550 100644 --- a/bench/config/systemd.py +++ b/bench/config/systemd.py @@ -9,7 +9,7 @@ import bench from bench.app import use_rq from bench.config.common_site_config import get_config, get_gunicorn_workers, update_config -from bench.utils import exec_cmd, find_executable, get_bench_name +from bench.utils import exec_cmd, which, get_bench_name def generate_systemd_config(bench_path, user=None, yes=False, @@ -53,8 +53,8 @@ def generate_systemd_config(bench_path, user=None, yes=False, "user": user, "use_rq": use_rq(bench_path), "http_timeout": config.get("http_timeout", 120), - "redis_server": find_executable('redis-server'), - "node": find_executable('node') or find_executable('nodejs'), + "redis_server": which('redis-server'), + "node": which('node') or which('nodejs'), "redis_cache_config": os.path.join(bench_dir, 'config', 'redis_cache.conf'), "redis_socketio_config": os.path.join(bench_dir, 'config', 'redis_socketio.conf'), "redis_queue_config": os.path.join(bench_dir, 'config', 'redis_queue.conf'), @@ -62,7 +62,7 @@ def generate_systemd_config(bench_path, user=None, yes=False, "gunicorn_workers": config.get('gunicorn_workers', get_gunicorn_workers()["gunicorn_workers"]), "bench_name": get_bench_name(bench_path), "worker_target_wants": " ".join(background_workers), - "bench_cmd": find_executable('bench') + "bench_cmd": which('bench') } if not yes: diff --git a/bench/utils.py b/bench/utils.py index 43525bb54..ede9b1691 100755 --- a/bench/utils.py +++ b/bench/utils.py @@ -2,26 +2,17 @@ # -*- coding: utf-8 -*- # imports - standard imports -import compileall -import errno -import glob import grp import itertools import json import logging import os import pwd -import re -import select -import site import subprocess import sys -from datetime import datetime -from distutils.spawn import find_executable # imports - third party imports import click -from six import iteritems # imports - module imports import bench @@ -143,6 +134,8 @@ def init(path, apps_path=None, no_procfile=False, no_backups=False, try: os.makedirs(os.path.join(path, dirname)) except OSError as e: + import errno + if e.errno == errno.EEXIST: pass @@ -184,6 +177,7 @@ def init(path, apps_path=None, no_procfile=False, no_backups=False, def update(pull=False, apps=None, patch=False, build=False, requirements=False, backup=True, compile=True, force=False, reset=False, restart_supervisor=False, restart_systemd=False): """command: bench update""" + import re from bench import patches from bench.app import is_version_upgrade, pull_apps, validate_branch from bench.config.common_site_config import get_config, update_config @@ -244,9 +238,11 @@ def update(pull=False, apps=None, patch=False, build=False, requirements=False, post_upgrade(version_upgrade[1], version_upgrade[2], bench_path=bench_path) if pull and compile: + from compileall import compile_dir + print('Compiling Python files...') apps_dir = os.path.join(bench_path, 'apps') - compileall.compile_dir(apps_dir, quiet=1, rx=re.compile('.*node_modules.*')) + compile_dir(apps_dir, quiet=1, rx=re.compile('.*node_modules.*')) if restart_supervisor or conf.get('restart_supervisor_on_update'): restart_supervisor_processes(bench_path=bench_path) @@ -268,7 +264,7 @@ def copy_patches_txt(bench_path): def clone_apps_from(bench_path, clone_from, update_app=True): - from .app import install_app + from bench.app import install_app print('Copying apps from {0}...'.format(clone_from)) subprocess.check_output(['cp', '-R', os.path.join(clone_from, 'apps'), bench_path]) @@ -316,7 +312,9 @@ def exec_cmd(cmd, cwd='.'): logger.warning("{0} executed with exit code {1}".format(cmd_log, return_code)) -def which(executable, raise_err = False): +def which(executable, raise_err=False): + from distutils.spawn import find_executable + exec_ = find_executable(executable) if not exec_ and raise_err: @@ -411,9 +409,9 @@ def setup_sudoers(user): template = bench.config.env().get_template('frappe_sudoers') frappe_sudoers = template.render(**{ 'user': user, - 'service': find_executable('service'), - 'systemctl': find_executable('systemctl'), - 'nginx': find_executable('nginx'), + 'service': which('service'), + 'systemctl': which('systemctl'), + 'nginx': which('nginx'), }) frappe_sudoers = safe_decode(frappe_sudoers) @@ -449,7 +447,7 @@ def logv(self, message, *args, **kws): def get_process_manager(): for proc_man in ['honcho', 'foreman', 'forego']: - proc_man_path = find_executable(proc_man) + proc_man_path = which(proc_man) if proc_man_path: return proc_man_path @@ -486,7 +484,7 @@ def get_git_version(): def check_git_for_shallow_clone(): - from .config.common_site_config import get_config + from bench.config.common_site_config import get_config config = get_config('.') if config: @@ -514,7 +512,7 @@ def get_cmd_output(cmd, cwd='.', _raise=True): def restart_supervisor_processes(bench_path='.', web_workers=False): - from .config.common_site_config import get_config + from bench.config.common_site_config import get_config conf = get_config(bench_path=bench_path) bench_name = get_bench_name(bench_path) @@ -600,7 +598,7 @@ def update_node_packages(bench_path='.'): def update_yarn_packages(bench_path='.'): apps_dir = os.path.join(bench_path, 'apps') - if not find_executable('yarn'): + if not which('yarn'): print("Please install yarn using below command and try again.") print("`npm install -g yarn`") return @@ -621,6 +619,8 @@ def update_npm_packages(bench_path='.'): if os.path.exists(package_json_path): with open(package_json_path, "r") as f: + from six import iteritems + app_package_json = json.loads(f.read()) # package.json is usually a dict in a dict for key, value in iteritems(app_package_json): @@ -658,9 +658,7 @@ def backup_all_sites(bench_path='.'): def is_root(): - if os.getuid() == 0: - return True - return False + return os.getuid() == 0 def set_mariadb_host(host, bench_path='.'): @@ -718,7 +716,8 @@ def drop_privileges(uid_name='nobody', gid_name='nogroup'): def fix_prod_setup_perms(bench_path='.', frappe_user=None): - from .config.common_site_config import get_config + from glob import glob + from bench.config.common_site_config import get_config if not frappe_user: frappe_user = get_config(bench_path).get('frappe_user') @@ -729,14 +728,14 @@ def fix_prod_setup_perms(bench_path='.', frappe_user=None): globs = ["logs/*", "config/*"] for glob_name in globs: - for path in glob.glob(glob_name): + for path in glob(glob_name): uid = pwd.getpwnam(frappe_user).pw_uid gid = grp.getgrnam(frappe_user).gr_gid os.chown(path, uid, gid) def run_frappe_cmd(*args, **kwargs): - from .cli import from_command_line + from bench.cli import from_command_line bench_path = kwargs.get('bench_path', '.') f = get_env_cmd('python', bench_path=bench_path) @@ -762,15 +761,15 @@ def run_frappe_cmd(*args, **kwargs): def validate_upgrade(from_ver, to_ver, bench_path='.'): if to_ver >= 6: - if not find_executable('npm') and not (find_executable('node') or find_executable('nodejs')): + if not which('npm') and not (which('node') or which('nodejs')): raise Exception("Please install nodejs and npm") def post_upgrade(from_ver, to_ver, bench_path='.'): - from .config.common_site_config import get_config - from .config import redis - from .config.supervisor import generate_supervisor_config - from .config.nginx import make_nginx_conf + from bench.config.common_site_config import get_config + from bench.config import redis + from bench.config.supervisor import generate_supervisor_config + from bench.config.nginx import make_nginx_conf conf = get_config(bench_path=bench_path) print("-" * 80 + "Your bench was upgraded to version {0}".format(to_ver)) @@ -848,8 +847,10 @@ def update_translations(app, lang): def print_output(p): + from select import select + while p.poll() is None: - readx = select.select([p.stdout.fileno(), p.stderr.fileno()], [], [])[0] + readx = select([p.stdout.fileno(), p.stderr.fileno()], [], [])[0] send_buffer = [] for fd in readx: if fd == p.stdout.fileno(): @@ -910,7 +911,7 @@ def set_git_remote_url(git_url, bench_path='.'): def run_playbook(playbook_name, extra_vars=None, tag=None): - if not find_executable('ansible'): + if not which('ansible'): print("Ansible is needed to run this command, please install it using 'pip install ansible'") sys.exit(1) args = ['ansible-playbook', '-c', 'local', playbook_name, '-vvvv'] @@ -982,6 +983,8 @@ def migrate_env(python, backup=False): # Backup venv: restore using `virtualenv --relocatable` if needed if backup: + from datetime import datetime + parch = os.path.join(path, 'archived_envs') if not os.path.exists(parch): os.mkdir(parch) From f04a9e6e0d5c7b46e6910ec0f29953e0c92af71a Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Fri, 23 Apr 2021 11:14:39 +0530 Subject: [PATCH 42/51] chore: Remove deprecated command switch-to-master --- bench/app.py | 3 --- bench/commands/__init__.py | 3 +-- bench/commands/update.py | 6 ------ 3 files changed, 1 insertion(+), 11 deletions(-) diff --git a/bench/app.py b/bench/app.py index b6e83444c..7ebaf8ffa 100755 --- a/bench/app.py +++ b/bench/app.py @@ -443,9 +443,6 @@ def switch_branch(branch, apps=None, bench_path='.', upgrade=False, check_upgrad def switch_to_branch(branch=None, apps=None, bench_path='.', upgrade=False): switch_branch(branch, apps=apps, bench_path=bench_path, upgrade=upgrade) -def switch_to_master(apps=None, bench_path='.', upgrade=True): - switch_branch('master', apps=apps, bench_path=bench_path, upgrade=upgrade) - def switch_to_develop(apps=None, bench_path='.', upgrade=True): switch_branch('develop', apps=apps, bench_path=bench_path, upgrade=upgrade) diff --git a/bench/commands/__init__.py b/bench/commands/__init__.py index 2b073b65b..54347f372 100755 --- a/bench/commands/__init__.py +++ b/bench/commands/__init__.py @@ -27,11 +27,10 @@ def bench_command(bench_path='.'): bench_command.add_command(pip) -from bench.commands.update import update, retry_upgrade, switch_to_branch, switch_to_master, switch_to_develop +from bench.commands.update import update, retry_upgrade, switch_to_branch, switch_to_develop bench_command.add_command(update) bench_command.add_command(retry_upgrade) bench_command.add_command(switch_to_branch) -bench_command.add_command(switch_to_master) bench_command.add_command(switch_to_develop) diff --git a/bench/commands/update.py b/bench/commands/update.py index e1113b40c..16ffefbf2 100755 --- a/bench/commands/update.py +++ b/bench/commands/update.py @@ -41,12 +41,6 @@ def switch_to_branch(branch, apps, upgrade=False): switch_to_branch(branch=branch, apps=list(apps), upgrade=upgrade) -@click.command('switch-to-master', help="[DEPRECATED]: Switch frappe and erpnext to master branch") -def switch_to_master(): - from bench.utils import log - log("`switch-to-master` has been deprecated as master branches were renamed to version-11") - - @click.command('switch-to-develop') def switch_to_develop(upgrade=False): "Switch frappe and erpnext to develop branch" From 405f41e434da5a321801c9126ffd21bc0713e3d2 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Fri, 23 Apr 2021 11:20:22 +0530 Subject: [PATCH 43/51] test: Use frappe_theme to test apps instead of erpnext * Don't skip assets --- bench/tests/test_base.py | 1 - bench/tests/test_init.py | 24 ++++++++++++------------ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/bench/tests/test_base.py b/bench/tests/test_base.py index 73cc90f54..ec38c8135 100644 --- a/bench/tests/test_base.py +++ b/bench/tests/test_base.py @@ -90,7 +90,6 @@ def init_bench(self, bench_name, **kwargs): python=sys.executable, no_procfile=True, no_backups=True, - skip_assets=True, frappe_path=frappe_tmp_path )) diff --git a/bench/tests/test_init.py b/bench/tests/test_init.py index 2f4098990..8ac7f5487 100755 --- a/bench/tests/test_init.py +++ b/bench/tests/test_init.py @@ -97,7 +97,7 @@ def test_new_site(self): def test_get_app(self): self.init_bench("test-bench") bench_path = os.path.join(self.benches_path, "test-bench") - bench.utils.exec_cmd("bench get-app frappe_theme --skip-assets", cwd=bench_path) + bench.utils.exec_cmd("bench get-app frappe_theme", cwd=bench_path) self.assertTrue(os.path.exists(os.path.join(bench_path, "apps", "frappe_theme"))) app_installed_in_env = "frappe_theme" in subprocess.check_output(["bench", "pip", "freeze"], cwd=bench_path).decode('utf8') self.assertTrue(app_installed_in_env) @@ -111,22 +111,22 @@ def test_install_app(self): self.init_bench(bench_name) bench.utils.exec_cmd("bench setup requirements --node", cwd=bench_path) bench.utils.exec_cmd("bench build", cwd=bench_path) - bench.utils.exec_cmd("bench get-app erpnext --branch {0}".format(FRAPPE_BRANCH), cwd=bench_path) + bench.utils.exec_cmd("bench get-app frappe_theme --branch master", cwd=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", "frappe_theme"))) # check if app is installed - app_installed_in_env = "erpnext" in subprocess.check_output(["bench", "pip", "freeze"], cwd=bench_path).decode('utf8') + app_installed_in_env = "frappe_theme" in subprocess.check_output(["bench", "pip", "freeze"], cwd=bench_path).decode('utf8') self.assertTrue(app_installed_in_env) # create and install app on site self.new_site(site_name, bench_name) - installed_erpnext = not bench.utils.exec_cmd("bench --site {0} install-app erpnext".format(site_name), cwd=bench_path) + installed_app = not bench.utils.exec_cmd("bench --site {0} install-app frappe_theme".format(site_name), cwd=bench_path) app_installed_on_site = subprocess.check_output(["bench", "--site", site_name, "list-apps"], cwd=bench_path).decode('utf8') - if installed_erpnext: - self.assertTrue("erpnext" in app_installed_on_site) + if installed_app: + self.assertTrue("frappe_theme" in app_installed_on_site) def test_remove_app(self): @@ -134,13 +134,13 @@ def test_remove_app(self): bench_path = os.path.join(self.benches_path, "test-bench") bench.utils.exec_cmd("bench setup requirements --node", cwd=bench_path) - bench.utils.exec_cmd("bench get-app erpnext --branch version-12 --skip-assets --overwrite", cwd=bench_path) - bench.utils.exec_cmd("bench remove-app erpnext", cwd=bench_path) + bench.utils.exec_cmd("bench get-app frappe_theme --branch master --overwrite", cwd=bench_path) + bench.utils.exec_cmd("bench remove-app frappe_theme", cwd=bench_path) with open(os.path.join(bench_path, "sites", "apps.txt")) as f: - self.assertFalse("erpnext" in f.read()) - self.assertFalse("erpnext" in subprocess.check_output(["bench", "pip", "freeze"], cwd=bench_path).decode('utf8')) - self.assertFalse(os.path.exists(os.path.join(bench_path, "apps", "erpnext"))) + self.assertFalse("frappe_theme" in f.read()) + self.assertFalse("frappe_theme" in subprocess.check_output(["bench", "pip", "freeze"], cwd=bench_path).decode('utf8')) + self.assertFalse(os.path.exists(os.path.join(bench_path, "apps", "frappe_theme"))) def test_switch_to_branch(self): From 89bc45e2d0f60f9defd3d7f2236148b1ec8eb9eb Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Fri, 23 Apr 2021 12:22:17 +0530 Subject: [PATCH 44/51] ci: Run all builds on 3.7, 3.8, 3.9 * Drop CI testing for older versions: 2.7, 3.5, 3.6 --- .travis.yml | 49 ++++++++++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8bc96c6ec..67c7f56bb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,35 +15,20 @@ addons: matrix: include: - - name: "Python 2.7 Basic Setup" - python: 2.7 - env: TEST=bench - script: python bench/tests/test_init.py TestBenchInit.basic - - - name: "Python 3.6 Basic Setup" - python: 3.6 - env: TEST=bench - script: python bench/tests/test_init.py TestBenchInit.basic - - name: "Python 3.7 Basic Setup" python: 3.7 env: TEST=bench script: python bench/tests/test_init.py TestBenchInit.basic - - name: "Python 3.8 Production Setup" + - name: "Python 3.8 Basic Setup" python: 3.8 env: TEST=bench - script: python bench/tests/test_setup_production.py TestSetupProduction.production - - - name: "Python 2.7 Production Setup" - python: 2.7 - env: TEST=bench - script: python bench/tests/test_setup_production.py TestSetupProduction.production + script: python bench/tests/test_init.py TestBenchInit.basic - - name: "Python 3.6 Production Setup" - python: 3.6 + - name: "Python 3.9 Basic Setup" + python: 3.9 env: TEST=bench - script: python bench/tests/test_setup_production.py TestSetupProduction.production + script: python bench/tests/test_init.py TestBenchInit.basic - name: "Python 3.7 Production Setup" python: 3.7 @@ -55,20 +40,25 @@ matrix: env: TEST=bench script: python bench/tests/test_setup_production.py TestSetupProduction.production - - name: "Python 2.7 Tests" - python: 2.7 + - name: "Python 3.9 Production Setup" + python: 3.9 env: TEST=bench - script: python -m unittest -v bench.tests.test_init + script: python bench/tests/test_setup_production.py TestSetupProduction.production - name: "Python 3.7 Tests" python: 3.7 env: TEST=bench script: python -m unittest -v bench.tests.test_init - - name: "Python 3.5 Easy Install" - python: 3.5 - env: TEST=easy_install - script: sudo python $TRAVIS_BUILD_DIR/install.py --user travis --run-travis --production --verbose + - name: "Python 3.8 Tests" + python: 3.8 + env: TEST=bench + script: python -m unittest -v bench.tests.test_init + + - name: "Python 3.9 Tests" + python: 3.9 + env: TEST=bench + script: python -m unittest -v bench.tests.test_init - name: "Python 3.7 Easy Install" python: 3.7 @@ -80,6 +70,11 @@ matrix: env: TEST=easy_install script: sudo python $TRAVIS_BUILD_DIR/install.py --user travis --run-travis --production --verbose + - name: "Python 3.9 Easy Install" + python: 3.9 + env: TEST=easy_install + script: sudo python $TRAVIS_BUILD_DIR/install.py --user travis --run-travis --production --verbose + install: - pip install urllib3 pyOpenSSL ndg-httpsclient pyasn1 From 75632a7616c839e0bd6a9559ed517b1e9196b4fd Mon Sep 17 00:00:00 2001 From: Revant Nandgaonkar Date: Fri, 23 Apr 2021 14:54:51 +0530 Subject: [PATCH 45/51] docs: add docker repo link in README remove docker installation details refer official link for installation details --- README.md | 59 ++++--------------------------------------------------- 1 file changed, 4 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index f11b78793..489d24840 100755 --- a/README.md +++ b/README.md @@ -8,9 +8,7 @@ Bench is a command-line utility that helps you to install, update, and manage mu ## Table of Contents - [Installation](#installation) - - [Docker Installation](#docker-installation) - - [Development Setup](#docker-installation-for-development) - - [Production Setup](#docker-installation-for-production) + - [Containerized Installation](#docker-installation) - [Easy Install Script](#easy-install-script) - [Manual Installation](#manual-installation) - [Usage](#basic-usage) @@ -28,7 +26,7 @@ A typical bench setup provides two types of environments — Development and The setup for each of these installations can be achieved in multiple ways: - - [Docker Installation](#docker-installation) + - [Containerized Installation](#containerized-installation) - [Easy Install Script](#easy-install-script) - [Manual Installation](#manual-installation) @@ -37,7 +35,7 @@ We recommend using either the Docker Installation or the Easy Install Script to Otherwise, if you are looking to evaluate ERPNext, you can also download the [Virtual Machine Image](https://erpnext.com/download) or register for [a free trial on erpnext.com](https://erpnext.com/pricing). -### Docker Installation +### Containerized Installation A Frappe/ERPNext instance can be setup and replicated easily using [Docker](https://docker.com). The officially supported Docker installation can be used to setup either of both Development and Production environments. @@ -48,56 +46,7 @@ $ git clone https://github.com/frappe/frappe_docker.git $ cd frappe_docker ``` -A quick setup guide for both the envionments can be found below. For more details, check out the [Frappe/ERPNext Docker Repository](https://github.com/frappe/frappe_docker). - -#### Docker Installation for Development - -To setup a development environment for Docker, follow the [Frappe/ERPNext Docker for Development Guide](https://github.com/frappe/frappe_docker/blob/develop/development/README.md). - -#### Docker Installation for Production - -Copy the `env-example` file to `.env` - -```sh -$ cp env-example .env -``` - -Optionally, you may also setup an [NGINX Proxy for SSL Certificates](https://github.com/evertramos/docker-compose-letsencrypt-nginx-proxy-companion) with auto-renewal for your Production instance. We recommend this for instances being accessed over the internet. For this to work, the DNS needs to be configured correctly so that [LetsEncrypt](https://letsencrypt.org) can verify the domain. To setup the proxy, run the following commands: - -```sh -$ git clone https://github.com/evertramos/docker-compose-letsencrypt-nginx-proxy-companion.git -$ cd docker-compose-letsencrypt-nginx-proxy-companion -$ cp .env.sample .env -$ ./start.sh -``` - -To get the Production instance running, run the following command: - -```sh -$ docker-compose \ - --project-name \ - -f installation/docker-compose-common.yml \ - -f installation/docker-compose-erpnext.yml \ - -f installation/docker-compose-networks.yml \ - --project-directory installation up -d -``` - -Make sure to replace `` with whatever you wish to call it. This should get the instance running through docker. Now, to create a new site on the instance you may run: - -```sh -docker exec -it \ - -e "SITE_NAME=$SITE_NAME" \ - -e "DB_ROOT_USER=$DB_ROOT_USER" \ - -e "MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD" \ - -e "ADMIN_PASSWORD=$ADMIN_PASSWORD" \ - -e "INSTALL_APPS=erpnext" \ # optional, if you want to install any other apps - _erpnext-python_1 docker-entrypoint.sh new -``` - -Once this is done, you may access the instance at `$SITE_NAME`. - -**Note:** The Production setup does not contain, require, or use bench. For a list of substitute commands, check out the [Frappe/ERPNext Docker Site Operations](https://github.com/frappe/frappe_docker/#site-operations). - +A quick setup guide for both the environments can be found below. For more details, check out the [Frappe/ERPNext Docker Repository](https://github.com/frappe/frappe_docker). ### Easy Install Script From b0ccb6efbea33acdb07b3500a07b37c8ffbeae23 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Fri, 23 Apr 2021 18:37:03 +0530 Subject: [PATCH 46/51] fix: Invoke pip via python Due to "WARNING: pip is being invoked by an old script wrapper. This will fail in a future version of pip. Please see https://github.com/pypa/pip/issues/5599 for advice on fixing the underlying issue. To avoid this problem you can invoke Python with '-m pip' instead of running pip directly." --- bench/app.py | 8 ++++---- bench/commands/make.py | 4 ++-- bench/utils.py | 15 +++++++-------- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/bench/app.py b/bench/app.py index 7ebaf8ffa..872270acd 100755 --- a/bench/app.py +++ b/bench/app.py @@ -174,12 +174,12 @@ def install_app(app, bench_path=".", verbose=False, no_cache=False, restart_benc print('\n{0}Installing {1}{2}'.format(color.yellow, app, color.nc)) logger.log("installing {}".format(app)) - pip_path = os.path.join(bench_path, "env", "bin", "pip") + python_path = os.path.join(bench_path, "env", "bin", "python") quiet_flag = "-q" if not verbose else "" app_path = os.path.join(bench_path, "apps", app) cache_flag = "--no-cache-dir" if no_cache else "" - exec_cmd("{pip} install {quiet} -U -e {app} {no_cache}".format(pip=pip_path, quiet=quiet_flag, app=app_path, no_cache=cache_flag)) + exec_cmd("{py_path} -m pip install {quiet} -U -e {app} {no_cache}".format(py_path=python_path, quiet=quiet_flag, app=app_path, no_cache=cache_flag)) if os.path.exists(os.path.join(app_path, 'package.json')): exec_cmd("yarn install", cwd=app_path) @@ -208,7 +208,7 @@ def remove_app(app, bench_path='.'): app_path = os.path.join(bench_path, 'apps', app) site_path = os.path.join(bench_path, 'sites') - pip = os.path.join(bench_path, 'env', 'bin', 'pip') + py = os.path.join(bench_path, 'env', 'bin', 'python') for site in os.listdir(site_path): req_file = os.path.join(site_path, site, 'site_config.json') @@ -218,7 +218,7 @@ def remove_app(app, bench_path='.'): print("Cannot remove, app is installed on site: {0}".format(site)) sys.exit(1) - exec_cmd("{0} uninstall -y {1}".format(pip, app), cwd=bench_path) + exec_cmd("{0} -m pip uninstall -y {1}".format(py, app), cwd=bench_path) remove_from_appstxt(app, bench_path) shutil.rmtree(app_path) run_frappe_cmd("build", bench_path=bench_path) diff --git a/bench/commands/make.py b/bench/commands/make.py index c20b25b30..f47a72e0d 100755 --- a/bench/commands/make.py +++ b/bench/commands/make.py @@ -98,5 +98,5 @@ def pip(ctx, args): "Run pip commands in bench env" import os from bench.utils import get_env_cmd - env_pip = get_env_cmd('pip') - os.execv(env_pip, (env_pip,) + args) + env_py = get_env_cmd('python') + os.execv(env_py, (env_py, '-m', 'pip') + args) diff --git a/bench/utils.py b/bench/utils.py index ede9b1691..7bb312ba4 100755 --- a/bench/utils.py +++ b/bench/utils.py @@ -339,13 +339,13 @@ def get_venv_path(): def setup_env(bench_path='.', python='python3'): frappe = os.path.join(bench_path, "apps", "frappe") - pip = os.path.join(bench_path, "env", "bin", "pip") + py = os.path.join(bench_path, "env", "bin", "python") virtualenv = get_venv_path() exec_cmd('{} -q env -p {}'.format(virtualenv, python), cwd=bench_path) if os.path.exists(frappe): - exec_cmd('{} install -q -U -e {}'.format(pip, frappe), cwd=bench_path) + exec_cmd('{} -m pip install -q -U -e {}'.format(py, frappe), cwd=bench_path) def setup_socketio(bench_path='.'): @@ -555,8 +555,8 @@ def set_default_site(site, bench_path='.'): def update_env_pip(bench_path): - env_pip = os.path.join(bench_path, 'env', 'bin', 'pip') - exec_cmd("{pip} install -q -U pip".format(pip=env_pip)) + env_py = os.path.join(bench_path, 'env', 'bin', 'python') + exec_cmd("{env_py} -m pip install -q -U pip".format(env_py=env_py)) def update_requirements(bench_path='.'): @@ -571,14 +571,14 @@ def update_requirements(bench_path='.'): def update_python_packages(bench_path='.'): from bench.app import get_apps - pip_path = os.path.join(bench_path, "env", "bin", "pip") + env_py = os.path.join(bench_path, "env", "bin", "python") print('Updating Python libraries...') update_env_pip(bench_path) for app in get_apps(): print('\n{0}Installing python dependencies for {1}{2}'.format(color.yellow, app, color.nc)) app_path = os.path.join(bench_path, "apps", app) - exec_cmd("{0} install -q -U -e {1}".format(pip_path, app_path), cwd=bench_path) + exec_cmd("{0} -m pip install -q -U -e {1}".format(env_py, app_path), cwd=bench_path) def update_node_packages(bench_path='.'): @@ -965,7 +965,6 @@ def migrate_env(python, backup=False): python = which(python) virtualenv = which('virtualenv') pvenv = os.path.join(path, nvenv) - pip = os.path.join(pvenv, 'bin', 'pip') # Clear Cache before Bench Dies. try: @@ -1006,7 +1005,7 @@ def migrate_env(python, backup=False): venv_creation = exec_cmd('{virtualenv} --python {python} {pvenv}'.format(virtualenv=virtualenv, python=python, pvenv=pvenv)) apps = ' '.join(["-e {}".format(os.path.join("apps", app)) for app in get_apps()]) - packages_setup = exec_cmd('{0} install -q -U {1}'.format(pip, apps)) + packages_setup = exec_cmd('{0} -m pip install -q -U {1}'.format(pvenv, apps)) logger.log('Migration Successful to {}'.format(python)) except: From 530a980ef74fd20a9de289284fde16875256b49b Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Fri, 23 Apr 2021 18:38:27 +0530 Subject: [PATCH 47/51] fix: Use execve and set envvars instead of execv Changed from execv to execve with empty env dict because bench commands on macOS 10.14.6 PY3.9.0a4 fails with "Error while finding module specification for 'frappe.utils.bench_helper' (ModuleNotFoundError: No module named 'frappe')" This error has come up in the past too. I'm now suspecting it has something to do with the current process passing on it's environment variables to the process that's going to replace it, which causes these issues. Note that direct execution of the commands without the bench wrapper worked fine although via bench failed with the specified error --- bench/cli.py | 6 +++--- bench/utils.py | 9 ++++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/bench/cli.py b/bench/cli.py index 05c74d86d..3b5d16b94 100755 --- a/bench/cli.py +++ b/bench/cli.py @@ -109,19 +109,19 @@ def change_uid(): def old_frappe_cli(bench_path='.'): f = get_frappe(bench_path=bench_path) os.chdir(os.path.join(bench_path, 'sites')) - os.execv(f, [f] + sys.argv[2:]) + os.execve(f, [f] + sys.argv[2:], {}) def app_cmd(bench_path='.'): f = get_env_cmd('python', bench_path=bench_path) os.chdir(os.path.join(bench_path, 'sites')) - os.execv(f, [f] + ['-m', 'frappe.utils.bench_helper'] + sys.argv[1:]) + os.execve(f, [f] + ['-m', 'frappe.utils.bench_helper'] + sys.argv[1:], {}) def frappe_cmd(bench_path='.'): f = get_env_cmd('python', bench_path=bench_path) os.chdir(os.path.join(bench_path, 'sites')) - os.execv(f, [f] + ['-m', 'frappe.utils.bench_helper', 'frappe'] + sys.argv[1:]) + os.execve(f, [f] + ['-m', 'frappe.utils.bench_helper', 'frappe'] + sys.argv[1:], {}) def get_frappe_commands(): diff --git a/bench/utils.py b/bench/utils.py index 7bb312ba4..49529c10e 100755 --- a/bench/utils.py +++ b/bench/utils.py @@ -453,12 +453,15 @@ def get_process_manager(): def start(no_dev=False, concurrency=None, procfile=None, no_prefix=False): + env = os.environ program = get_process_manager() + if not program: raise Exception("No process manager found") - os.environ['PYTHONUNBUFFERED'] = "true" + + env['PYTHONUNBUFFERED'] = "true" if not no_dev: - os.environ['DEV_SERVER'] = "true" + env['DEV_SERVER'] = "true" command = [program, 'start'] if concurrency: @@ -470,7 +473,7 @@ def start(no_dev=False, concurrency=None, procfile=None, no_prefix=False): if no_prefix: command.extend(['--no-prefix']) - os.execv(program, command) + os.execve(program, command, env=env) def get_git_version(): From 7e1db3fd74a9c610abf5c79e173d5faf4c4c24a4 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Fri, 23 Apr 2021 19:14:30 +0530 Subject: [PATCH 48/51] test: Update env test Env folder's include may be empty or non existent --- bench/tests/test_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bench/tests/test_base.py b/bench/tests/test_base.py index ec38c8135..edda52a37 100644 --- a/bench/tests/test_base.py +++ b/bench/tests/test_base.py @@ -44,7 +44,7 @@ def assert_virtual_env(self, bench_name): bench_path = os.path.abspath(bench_name) python_path = os.path.abspath(os.path.join(bench_path, "env", "bin", "python")) self.assertTrue(python_path.startswith(bench_path)) - for subdir in ("bin", "include", "lib", "share"): + for subdir in ("bin", "lib", "share"): self.assert_exists(bench_name, "env", subdir) def assert_config(self, bench_name): From 64fbeee1e6a9dbe65ce17131344a1d4ca2b5bcd8 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Mon, 26 Apr 2021 11:32:20 +0530 Subject: [PATCH 49/51] Revert "fix: Use execve and set envvars instead of execv" This reverts commit 530a980ef74fd20a9de289284fde16875256b49b. --- bench/cli.py | 6 +++--- bench/utils.py | 9 +++------ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/bench/cli.py b/bench/cli.py index 3b5d16b94..05c74d86d 100755 --- a/bench/cli.py +++ b/bench/cli.py @@ -109,19 +109,19 @@ def change_uid(): def old_frappe_cli(bench_path='.'): f = get_frappe(bench_path=bench_path) os.chdir(os.path.join(bench_path, 'sites')) - os.execve(f, [f] + sys.argv[2:], {}) + os.execv(f, [f] + sys.argv[2:]) def app_cmd(bench_path='.'): f = get_env_cmd('python', bench_path=bench_path) os.chdir(os.path.join(bench_path, 'sites')) - os.execve(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_path='.'): f = get_env_cmd('python', bench_path=bench_path) os.chdir(os.path.join(bench_path, 'sites')) - os.execve(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(): diff --git a/bench/utils.py b/bench/utils.py index 49529c10e..7bb312ba4 100755 --- a/bench/utils.py +++ b/bench/utils.py @@ -453,15 +453,12 @@ def get_process_manager(): def start(no_dev=False, concurrency=None, procfile=None, no_prefix=False): - env = os.environ program = get_process_manager() - if not program: raise Exception("No process manager found") - - env['PYTHONUNBUFFERED'] = "true" + os.environ['PYTHONUNBUFFERED'] = "true" if not no_dev: - env['DEV_SERVER'] = "true" + os.environ['DEV_SERVER'] = "true" command = [program, 'start'] if concurrency: @@ -473,7 +470,7 @@ def start(no_dev=False, concurrency=None, procfile=None, no_prefix=False): if no_prefix: command.extend(['--no-prefix']) - os.execve(program, command, env=env) + os.execv(program, command) def get_git_version(): From 324b58622c546dc71f6b341c450aa308c59b3080 Mon Sep 17 00:00:00 2001 From: Hussain Nagaria Date: Mon, 26 Apr 2021 15:42:45 +0530 Subject: [PATCH 50/51] chore: Remove set-default-site command --- bench/commands/utils.py | 6 ------ docs/bench_usage.md | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/bench/commands/utils.py b/bench/commands/utils.py index 5d9ac6d5d..94d87b06a 100644 --- a/bench/commands/utils.py +++ b/bench/commands/utils.py @@ -98,12 +98,6 @@ def set_redis_socketio_host(host): set_redis_socketio_host(host) -@click.command('set-default-site', help="Set default site for bench") -@click.argument('site') -def set_default_site(site): - from bench.utils import set_default_site - set_default_site(site) - @click.command('download-translations', help="Download latest translations") def download_translations(): diff --git a/docs/bench_usage.md b/docs/bench_usage.md index 807d021f4..7bf52a1a3 100644 --- a/docs/bench_usage.md +++ b/docs/bench_usage.md @@ -101,7 +101,7 @@ These commands belong directly to the bench group so they can be invoked directl - **set-redis-cache-host**: Set Redis cache host for bench - **set-redis-queue-host**: Set Redis queue host for bench - **set-redis-socketio-host**: Set Redis socketio host for bench - - **set-default-site**: Set default site for bench + - **use**: Set default site for bench - **download-translations**: Download latest translations From ed3f2d28fbf729ae14a0bdad74632a7332af9eb2 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Mon, 26 Apr 2021 20:16:16 +0530 Subject: [PATCH 51/51] fix: Remove set-default-site from CLI --- bench/commands/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bench/commands/__init__.py b/bench/commands/__init__.py index 54347f372..b5ba5a4fe 100755 --- a/bench/commands/__init__.py +++ b/bench/commands/__init__.py @@ -35,7 +35,7 @@ def bench_command(bench_path='.'): 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, backup_site, backup_all_sites, release, renew_lets_encrypt, + set_mariadb_host, 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, generate_command_cache, clear_command_cache) bench_command.add_command(start) @@ -48,7 +48,6 @@ def bench_command(bench_path='.'): bench_command.add_command(set_redis_cache_host) bench_command.add_command(set_redis_queue_host) bench_command.add_command(set_redis_socketio_host) -bench_command.add_command(set_default_site) bench_command.add_command(download_translations) bench_command.add_command(backup_site) bench_command.add_command(backup_all_sites)