mirror of
https://github.com/frappe/bench.git
synced 2025-01-23 15:08:24 +00:00
[enhancement] multi-bench setup and test cases for bench with [travis]
This commit is contained in:
parent
2a4665ca37
commit
6797768572
16
.travis.yml
Normal file
16
.travis.yml
Normal file
@ -0,0 +1,16 @@
|
||||
language: python
|
||||
|
||||
python:
|
||||
- "2.7"
|
||||
|
||||
install:
|
||||
- sudo apt-get purge -y mysql-common
|
||||
- sudo bash $TRAVIS_BUILD_DIR/install_scripts/setup_frappe.sh --skip-install-bench --mysql-root-password travis
|
||||
- mkdir -p ~/bench-repo
|
||||
- cp -r $TRAVIS_BUILD_DIR/* ~/bench-repo/
|
||||
|
||||
script:
|
||||
- cd ~
|
||||
- sudo pip install --upgrade pip
|
||||
- sudo pip install -e bench-repo
|
||||
- sudo python -m unittest bench.tests.test_setup_production
|
12
bench/cli.py
12
bench/cli.py
@ -18,7 +18,7 @@ from .utils import (build_assets, patch_sites, exec_cmd, update_bench, get_env_c
|
||||
from .app import get_app as _get_app
|
||||
from .app import new_app as _new_app
|
||||
from .app import pull_all_apps, get_apps, get_current_frappe_version, is_version_upgrade, switch_to_v4, switch_to_v5, switch_to_master, switch_to_develop
|
||||
from .config import generate_nginx_config, generate_supervisor_config, generate_redis_cache_config, generate_redis_async_broker_config
|
||||
from .config import generate_nginx_config, generate_supervisor_config, generate_redis_cache_config, generate_redis_async_broker_config, generate_redis_celery_broker_config
|
||||
from .production_setup import setup_production as _setup_production
|
||||
from .migrate_to_v5 import migrate_to_v5
|
||||
import os
|
||||
@ -74,7 +74,7 @@ def check_uid():
|
||||
|
||||
def change_uid():
|
||||
if is_root() and not cmd_requires_root():
|
||||
frappe_user = get_config().get('frappe_user')
|
||||
frappe_user = get_config(".").get('frappe_user')
|
||||
if frappe_user:
|
||||
drop_privileges(uid_name=frappe_user, gid_name=frappe_user)
|
||||
os.environ['HOME'] = pwd.getpwnam(frappe_user).pw_dir
|
||||
@ -206,7 +206,7 @@ def _update(pull=False, patch=False, build=False, bench=False, auto=False, resta
|
||||
if not (pull or patch or build or bench or requirements):
|
||||
pull, patch, build, bench, requirements = True, True, True, True, True
|
||||
|
||||
conf = get_config()
|
||||
conf = get_config(".")
|
||||
|
||||
version_upgrade = is_version_upgrade()
|
||||
|
||||
@ -449,6 +449,11 @@ def setup_redis_async_broker():
|
||||
"generate config for redis async broker"
|
||||
generate_redis_async_broker_config()
|
||||
|
||||
@click.command('redis-celery-broker')
|
||||
def setup_redis_celery_broker():
|
||||
"generate config for redis celery broker"
|
||||
generate_redis_celery_broker_config()
|
||||
|
||||
@click.command('production')
|
||||
@click.argument('user')
|
||||
def setup_production(user):
|
||||
@ -496,6 +501,7 @@ setup.add_command(setup_sudoers)
|
||||
setup.add_command(setup_supervisor)
|
||||
setup.add_command(setup_redis_cache)
|
||||
setup.add_command(setup_redis_async_broker)
|
||||
setup.add_command(setup_redis_celery_broker)
|
||||
setup.add_command(setup_auto_update)
|
||||
setup.add_command(setup_dnsmasq)
|
||||
setup.add_command(setup_backups)
|
||||
|
@ -6,7 +6,7 @@ import shutil
|
||||
import socket
|
||||
from distutils.spawn import find_executable
|
||||
from jinja2 import Environment, PackageLoader
|
||||
from .utils import get_sites, get_config, update_config, get_redis_version
|
||||
from .utils import get_sites, get_config, update_config, get_redis_version, update_common_site_config
|
||||
|
||||
env = Environment(loader=PackageLoader('bench', 'templates'), trim_blocks=True)
|
||||
|
||||
@ -30,6 +30,7 @@ def generate_supervisor_config(bench='.', user=None):
|
||||
sites = get_sites(bench=bench)
|
||||
if not user:
|
||||
user = getpass.getuser()
|
||||
|
||||
config = get_config(bench=bench)
|
||||
|
||||
config = template.render(**{
|
||||
@ -41,9 +42,11 @@ def generate_supervisor_config(bench='.', user=None):
|
||||
"node": find_executable('node') or find_executable('nodejs'),
|
||||
"redis_cache_config": os.path.join(bench_dir, 'config', 'redis_cache.conf'),
|
||||
"redis_async_broker_config": os.path.join(bench_dir, 'config', 'redis_async_broker.conf'),
|
||||
"redis_celery_broker_config": os.path.join(bench_dir, 'config', 'redis_celery_broker.conf'),
|
||||
"frappe_version": get_current_frappe_version(),
|
||||
"webserver_port": config.get('webserver_port'),
|
||||
"n_workers": config.get('max_workers')
|
||||
"webserver_port": config.get('webserver_port', 8000),
|
||||
"n_workers": config.get('max_workers', 2),
|
||||
"bench_name": os.path.basename(os.path.abspath(bench))
|
||||
})
|
||||
write_config_file(bench, 'supervisor.conf', config)
|
||||
update_config({'restart_supervisor_on_update': True})
|
||||
@ -55,26 +58,23 @@ def get_site_config(site, bench='.'):
|
||||
def generate_common_site_config(bench='.'):
|
||||
'''Generates the default common_site_config.json while a new bench is created'''
|
||||
config = get_config(bench=bench)
|
||||
|
||||
celery_broker_port = config.get('redis_celery_broker_port', '11311')
|
||||
celery_broker = 'redis://localhost:{0}'.format(celery_broker_port)
|
||||
common_site_config = {}
|
||||
|
||||
async_redis_server_port = config.get('redis_async_broker_port', '12311')
|
||||
async_redis_server = 'redis://localhost:{0}'.format(async_redis_server_port)
|
||||
for bench_config_field, site_config_field in (
|
||||
("redis_celery_broker_port", "celery_broker"),
|
||||
("redis_async_broker_port", "async_redis_server"),
|
||||
("redis_cache_port", "cache_redis_server")
|
||||
):
|
||||
|
||||
cache_redis_server_port = config.get('redis_cache_port', '13311')
|
||||
cache_redis_server = 'redis://localhost:{0}'.format(cache_redis_server_port)
|
||||
port = config.get(bench_config_field)
|
||||
if config.get(bench_config_field):
|
||||
redis_url = "redis://localhost:{0}".format(port)
|
||||
common_site_config[site_config_field] = redis_url
|
||||
|
||||
default_common_site_config = {
|
||||
"celery_broker" : celery_broker,
|
||||
"async_redis_server": async_redis_server,
|
||||
"cache_redis_server": cache_redis_server
|
||||
}
|
||||
# TODO Optionally we need to add the host or domain name in case dns_multitenant is false
|
||||
|
||||
#TODO Optionally we need to add the host or domain name in case dns_multitenant is false
|
||||
|
||||
with open(os.path.join(bench, 'sites', 'common_site_config.json'), 'wb') as f:
|
||||
json.dump(default_common_site_config, f, indent=1, sort_keys=True)
|
||||
if common_site_config:
|
||||
update_common_site_config(common_site_config, bench=bench)
|
||||
|
||||
def get_sites_with_config(bench='.'):
|
||||
sites = get_sites(bench=bench)
|
||||
@ -111,7 +111,10 @@ def generate_nginx_config(bench='.'):
|
||||
"http_timeout": config.get("http_timeout", 120),
|
||||
"default_site": default_site,
|
||||
"dns_multitenant": config.get('dns_multitenant'),
|
||||
"sites": sites
|
||||
"sites": sites,
|
||||
"webserver_port": config.get('webserver_port', 8000),
|
||||
"socketio_port": config.get('socketio_port', 3000),
|
||||
"bench_name": os.path.basename(os.path.abspath(bench))
|
||||
})
|
||||
write_config_file(bench, 'nginx.conf', config)
|
||||
|
||||
|
@ -55,16 +55,21 @@ def setup_production(user, bench='.'):
|
||||
fix_prod_setup_perms(bench, frappe_user=user)
|
||||
remove_default_nginx_configs()
|
||||
|
||||
bench_name = os.path.basename(os.path.abspath(bench))
|
||||
nginx_conf = '/etc/nginx/conf.d/{bench_name}.conf'.format(bench_name=bench_name)
|
||||
|
||||
if is_centos7():
|
||||
supervisor_conf_filename = 'frappe.ini'
|
||||
supervisor_conf_extn = "ini"
|
||||
copy_default_nginx_config()
|
||||
else:
|
||||
supervisor_conf_filename = 'frappe.conf'
|
||||
supervisor_conf_extn = "conf"
|
||||
|
||||
supervisor_conf = os.path.join(get_supervisor_confdir(), '{bench_name}.{extn}'.format(
|
||||
bench_name=bench_name, extn=supervisor_conf_extn))
|
||||
|
||||
links = (
|
||||
(os.path.abspath(os.path.join(bench, 'config', 'nginx.conf')), '/etc/nginx/conf.d/frappe.conf'),
|
||||
(os.path.abspath(os.path.join(bench, 'config', 'supervisor.conf')), os.path.join(get_supervisor_confdir(), supervisor_conf_filename)),
|
||||
(os.path.abspath(os.path.join(bench, 'config', 'nginx.conf')), nginx_conf),
|
||||
(os.path.abspath(os.path.join(bench, 'config', 'supervisor.conf')), supervisor_conf),
|
||||
)
|
||||
|
||||
for src, dest in links:
|
||||
@ -74,4 +79,5 @@ def setup_production(user, bench='.'):
|
||||
exec_cmd('supervisorctl reload')
|
||||
if os.environ.get('NO_SERVICE_RESTART'):
|
||||
return
|
||||
|
||||
restart_service('nginx')
|
||||
|
@ -1,12 +1,9 @@
|
||||
|
||||
server_names_hash_bucket_size 64;
|
||||
|
||||
upstream frappe {
|
||||
server 127.0.0.1:8000 fail_timeout=0;
|
||||
upstream {{ bench_name }}-frappe {
|
||||
server 127.0.0.1:{{ webserver_port }} fail_timeout=0;
|
||||
}
|
||||
|
||||
upstream socketio-server {
|
||||
server 127.0.0.1:3000 fail_timeout=0;
|
||||
upstream {{ bench_name}}-socketio-server {
|
||||
server 127.0.0.1:{{ socketio_port }} fail_timeout=0;
|
||||
}
|
||||
|
||||
{% macro location_block(site, port=80, default=False, server_name=None, sites=None, dns_multitenant=False) -%}
|
||||
@ -24,7 +21,7 @@ upstream socketio-server {
|
||||
}
|
||||
|
||||
location /socket.io {
|
||||
proxy_pass http://socketio-server;
|
||||
proxy_pass http://{{ bench_name }}-socketio-server;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
@ -36,10 +33,10 @@ upstream socketio-server {
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files /{{ "$host" if dns_multitenant else site.name }}/public/$uri @magic;
|
||||
try_files /{{ "$host" if dns_multitenant else site.name }}/public/$uri @webserver;
|
||||
}
|
||||
|
||||
location @magic {
|
||||
location @webserver {
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
{% if not dns_multitenant %}
|
||||
@ -47,9 +44,9 @@ upstream socketio-server {
|
||||
{% endif %}
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Use-X-Accel-Redirect True;
|
||||
proxy_read_timeout {{http_timeout}};
|
||||
proxy_read_timeout {{ http_timeout }};
|
||||
proxy_redirect off;
|
||||
proxy_pass http://frappe;
|
||||
proxy_pass http://{{ bench_name }}-frappe;
|
||||
}
|
||||
{%- endmacro %}
|
||||
|
||||
|
@ -33,6 +33,8 @@ http {
|
||||
#keepalive_timeout 0;
|
||||
keepalive_timeout 65;
|
||||
|
||||
server_names_hash_bucket_size 64;
|
||||
|
||||
#gzip on;
|
||||
|
||||
index index.html index.htm;
|
||||
@ -41,4 +43,4 @@ http {
|
||||
# See http://nginx.org/en/docs/ngx_core_module.html#include
|
||||
# for more information.
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,8 @@
|
||||
; priority=1 --> Lower priorities indicate programs that start first and shut down last
|
||||
; killasgroup=true --> send kill signal to child processes too
|
||||
|
||||
[program:frappe-web]
|
||||
command={{ bench_dir }}/env/bin/gunicorn -b 127.0.0.1:{{webserver_port}} -w {{n_workers}} -t {{http_timeout}} frappe.app:application
|
||||
[program:{{ bench_name }}-frappe-web]
|
||||
command={{ bench_dir }}/env/bin/gunicorn -b 127.0.0.1:{{ webserver_port }} -w {{ n_workers }} -t {{ http_timeout }} frappe.app:application --preload
|
||||
priority=4
|
||||
autostart=true
|
||||
autorestart=true
|
||||
@ -12,7 +12,7 @@ stderr_logfile={{ bench_dir }}/logs/web.error.log
|
||||
user={{ user }}
|
||||
directory={{ sites_dir }}
|
||||
|
||||
[program:frappe-worker]
|
||||
[program:{{ bench_name }}-frappe-worker]
|
||||
command={{ bench_dir }}/env/bin/python -m frappe.celery_app worker -n jobs@%%h --soft-time-limit 360 --time-limit 390 --loglevel INFO -Ofair
|
||||
priority=4
|
||||
autostart=true
|
||||
@ -24,7 +24,7 @@ stopwaitsecs=400
|
||||
directory={{ sites_dir }}
|
||||
killasgroup=true
|
||||
|
||||
[program:frappe-longjob-worker]
|
||||
[program:{{ bench_name }}-frappe-longjob-worker]
|
||||
command={{ bench_dir }}/env/bin/python -m frappe.celery_app worker -n longjobs@%%h --soft-time-limit 1500 --time-limit 1530 --loglevel INFO
|
||||
priority=2
|
||||
autostart=true
|
||||
@ -36,7 +36,7 @@ stopwaitsecs=1540
|
||||
directory={{ sites_dir }}
|
||||
killasgroup=true
|
||||
|
||||
[program:frappe-async-worker]
|
||||
[program:{{ bench_name }}-frappe-async-worker]
|
||||
command={{ bench_dir }}/env/bin/python -m frappe.celery_app worker -n async@%%h --soft-time-limit 1500 --time-limit 1530 --loglevel INFO
|
||||
priority=2
|
||||
autostart=true
|
||||
@ -48,7 +48,7 @@ stopwaitsecs=1540
|
||||
directory={{ sites_dir }}
|
||||
killasgroup=true
|
||||
|
||||
[program:frappe-workerbeat]
|
||||
[program:{{ bench_name }}-frappe-workerbeat]
|
||||
command={{ bench_dir }}/env/bin/python -m frappe.celery_app beat -s beat.schedule
|
||||
priority=3
|
||||
autostart=true
|
||||
@ -58,9 +58,7 @@ stderr_logfile={{ bench_dir }}/logs/workerbeat.error.log
|
||||
user={{ user }}
|
||||
directory={{ sites_dir }}
|
||||
|
||||
|
||||
{% if frappe_version > 4%}
|
||||
[program:redis-cache]
|
||||
[program:{{ bench_name }}-redis-cache]
|
||||
command={{ redis_server }} {{ redis_cache_config }}
|
||||
priority=1
|
||||
autostart=true
|
||||
@ -69,10 +67,19 @@ stdout_logfile={{ bench_dir }}/logs/redis-cache.log
|
||||
stderr_logfile={{ bench_dir }}/logs/redis-cache.error.log
|
||||
user={{ user }}
|
||||
directory={{ sites_dir }}
|
||||
{% endif %}
|
||||
|
||||
{% if frappe_version > 5%}
|
||||
[program:redis-async-broker]
|
||||
[program:{{ bench_name }}-redis-celery-broker]
|
||||
command={{ redis_server }} {{ redis_celery_broker_config }}
|
||||
priority=1
|
||||
autostart=true
|
||||
autorestart=true
|
||||
stdout_logfile={{ bench_dir }}/logs/redis-celery-broker.log
|
||||
stderr_logfile={{ bench_dir }}/logs/redis-celery-broker.error.log
|
||||
user={{ user }}
|
||||
directory={{ sites_dir }}
|
||||
|
||||
{% if frappe_version > 5 %}
|
||||
[program:{{ bench_name }}-redis-async-broker]
|
||||
command={{ redis_server }} {{ redis_async_broker_config }}
|
||||
priority=1
|
||||
autostart=true
|
||||
@ -83,7 +90,7 @@ user={{ user }}
|
||||
directory={{ sites_dir }}
|
||||
|
||||
{% if node %}
|
||||
[program:node-socketio]
|
||||
[program:{{ bench_name }}-node-socketio]
|
||||
command={{ node }} {{ bench_dir }}/apps/frappe/socketio.js
|
||||
priority=4
|
||||
autostart=true
|
||||
@ -96,5 +103,8 @@ directory={{ sites_dir }}
|
||||
|
||||
{% endif %}
|
||||
|
||||
[group:frappe]
|
||||
programs=frappe-web,frappe-worker,frappe-workerbeat
|
||||
[group:{{ bench_name }}-processes]
|
||||
programs={{ bench_name }}-frappe-web,{{ bench_name }}-frappe-worker,{{ bench_name }}-frappe-longjob-worker,{{ bench_name }}-frappe-async-worker,{{ bench_name }}-frappe-workerbeat {%- if node -%} ,{{ bench_name }}-node-socketio {%- endif%}
|
||||
|
||||
[group:{{ bench_name }}-redis]
|
||||
programs={{ bench_name }}-redis-cache,{{ bench_name }}-redis-celery-broker {%- if frappe_version > 5 -%} ,{{ bench_name }}-redis-async-broker {%- endif %}
|
||||
|
@ -5,7 +5,6 @@ import bench.utils
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import socket
|
||||
|
||||
class TestBenchInit(unittest.TestCase):
|
||||
def setUp(self):
|
||||
@ -19,9 +18,7 @@ class TestBenchInit(unittest.TestCase):
|
||||
shutil.rmtree(bench_path)
|
||||
|
||||
def test_init(self, bench_name="test-bench"):
|
||||
self.benches.append(bench_name)
|
||||
|
||||
bench.utils.init(bench_name)
|
||||
self.init_bench(bench_name)
|
||||
|
||||
self.assert_folders(bench_name)
|
||||
|
||||
@ -34,25 +31,43 @@ class TestBenchInit(unittest.TestCase):
|
||||
self.assert_socketio(bench_name)
|
||||
|
||||
def test_multiple_benches(self):
|
||||
# 1st bench
|
||||
self.test_init("test-bench-1")
|
||||
test_bench_1_ports = {
|
||||
|
||||
self.assert_ports("test-bench-1", {
|
||||
"webserver_port": 8000,
|
||||
"socketio_port": 9000,
|
||||
"redis_celery_broker_port": 11000,
|
||||
"redis_async_broker_port": 12000,
|
||||
"redis_cache_port": 13000
|
||||
}
|
||||
self.assert_ports("test-bench-1", test_bench_1_ports)
|
||||
})
|
||||
|
||||
self.assert_common_site_config("test-bench-1", {
|
||||
"celery_broker": "redis://localhost:11000",
|
||||
"async_redis_server": "redis://localhost:12000",
|
||||
"cache_redis_server": "redis://localhost:13000"
|
||||
})
|
||||
|
||||
# 2nd bench
|
||||
self.test_init("test-bench-2")
|
||||
test_bench_2_ports = {
|
||||
|
||||
self.assert_ports("test-bench-2", {
|
||||
"webserver_port": 8001,
|
||||
"socketio_port": 9001,
|
||||
"redis_celery_broker_port": 11001,
|
||||
"redis_async_broker_port": 12001,
|
||||
"redis_cache_port": 13001
|
||||
}
|
||||
self.assert_ports("test-bench-2", test_bench_2_ports)
|
||||
})
|
||||
|
||||
self.assert_common_site_config("test-bench-2", {
|
||||
"celery_broker": "redis://localhost:11001",
|
||||
"async_redis_server": "redis://localhost:12001",
|
||||
"cache_redis_server": "redis://localhost:13001"
|
||||
})
|
||||
|
||||
def init_bench(self, bench_name):
|
||||
self.benches.append(bench_name)
|
||||
bench.utils.init(bench_name)
|
||||
|
||||
def assert_folders(self, bench_name):
|
||||
for folder in bench.utils.folders_in_bench:
|
||||
@ -70,13 +85,12 @@ class TestBenchInit(unittest.TestCase):
|
||||
self.assert_exists(bench_name, "env", "lib", "python2.7", "site-packages", "pip")
|
||||
|
||||
def assert_bench_config(self, bench_name):
|
||||
config_json = os.path.exists(os.path.join(bench_name, "config.json"))
|
||||
self.assertTrue(config_json)
|
||||
with open(config_json, "r") as f:
|
||||
print f
|
||||
config_dict = json.loads(f.read().decode("utf-8"))
|
||||
for key, value in bench.utils.default_config.items():
|
||||
self.assertEquals(config_dict.get(key), value)
|
||||
config_json = os.path.join(bench_name, "config.json")
|
||||
self.assertTrue(os.path.exists(config_json))
|
||||
|
||||
config = self.load_json(config_json)
|
||||
for key, value in bench.utils.default_config.items():
|
||||
self.assertEquals(config.get(key), value)
|
||||
|
||||
def assert_config(self, bench_name):
|
||||
for config, search_key in (
|
||||
@ -86,7 +100,7 @@ class TestBenchInit(unittest.TestCase):
|
||||
|
||||
self.assert_exists(bench_name, "config", config)
|
||||
|
||||
with open(os.path.join(self.bench, "config", config), "r") as f:
|
||||
with open(os.path.join(bench_name, "config", config), "r") as f:
|
||||
f = f.read().decode("utf-8")
|
||||
self.assertTrue(search_key in f)
|
||||
|
||||
@ -95,16 +109,22 @@ class TestBenchInit(unittest.TestCase):
|
||||
self.assert_exists(bench_name, "node_modules", "socket.io")
|
||||
|
||||
def assert_ports(self, bench_name, ports):
|
||||
config_path = os.path.join(self.benches_path, bench_name, 'config', 'config.json')
|
||||
config_path = os.path.join(bench_name, 'config.json')
|
||||
config = self.load_json(config_path)
|
||||
|
||||
with open(config_path, "r") as f:
|
||||
config_json = json.load(f)
|
||||
for key, port in ports.items():
|
||||
self.assertEquals(config.get(key), port)
|
||||
|
||||
for key, port in ports:
|
||||
self.assertEqual(config_json.get(key), port)
|
||||
def assert_common_site_config(self, bench_name, expected_config):
|
||||
common_site_config_path = os.path.join(bench_name, 'sites', 'common_site_config.json')
|
||||
config = self.load_json(common_site_config_path)
|
||||
|
||||
def assert_site_config(self, bench_name):
|
||||
pass
|
||||
for key, value in expected_config.items():
|
||||
self.assertEquals(config.get(key), value)
|
||||
|
||||
def assert_exists(self, *args):
|
||||
self.assertTrue(os.path.exists(os.path.join(*args)))
|
||||
|
||||
def load_json(self, path):
|
||||
with open(path, "r") as f:
|
||||
return json.loads(f.read().decode("utf-8"))
|
||||
|
95
bench/tests/test_setup_production.py
Normal file
95
bench/tests/test_setup_production.py
Normal file
@ -0,0 +1,95 @@
|
||||
from __future__ import unicode_literals
|
||||
from bench.tests.test_init import TestBenchInit
|
||||
from bench.production_setup import setup_production
|
||||
import bench.utils
|
||||
import os
|
||||
import getpass
|
||||
import re
|
||||
import unittest
|
||||
|
||||
class TestSetupProduction(TestBenchInit):
|
||||
# setUp, tearDown and other tests are defiend in TestBenchInit
|
||||
|
||||
def test_setup_production(self):
|
||||
self.test_multiple_benches()
|
||||
|
||||
user = getpass.getuser()
|
||||
|
||||
for bench_name in ("test-bench-1", "test-bench-2"):
|
||||
setup_production(user, bench_name)
|
||||
self.assert_nginx_config(bench_name)
|
||||
self.assert_supervisor_config(bench_name)
|
||||
|
||||
self.assert_supervisor_process(bench_name)
|
||||
|
||||
self.assert_nginx_process()
|
||||
|
||||
def assert_nginx_config(self, bench_name):
|
||||
conf_src = os.path.join(os.path.abspath(bench_name), 'config', 'nginx.conf')
|
||||
conf_dest = "/etc/nginx/conf.d/{bench_name}.conf".format(bench_name=bench_name)
|
||||
|
||||
self.assertTrue(os.path.exists(conf_src))
|
||||
self.assertTrue(os.path.exists(conf_dest))
|
||||
|
||||
# symlink matches
|
||||
self.assertEquals(os.path.realpath(conf_dest), conf_src)
|
||||
|
||||
# file content
|
||||
with open(conf_src, "r") as f:
|
||||
f = f.read().decode("utf-8")
|
||||
|
||||
for key in (
|
||||
"upstream { bench_name }-frappe",
|
||||
"upstream { bench_name}-socketio-server"
|
||||
):
|
||||
self.assertTrue(key.format(bench_name) in f)
|
||||
|
||||
def assert_supervisor_config(self, bench_name):
|
||||
conf_src = os.path.join(os.path.abspath(bench_name), 'config', 'supervisor.conf')
|
||||
conf_dest = "/etc/supervisor.d/{bench_name}.conf".format(bench_name=bench_name)
|
||||
|
||||
self.assertTrue(os.path.exists(conf_src))
|
||||
self.assertTrue(os.path.exists(conf_dest))
|
||||
|
||||
# symlink matches
|
||||
self.assertEquals(os.path.realpath(conf_dest), conf_src)
|
||||
|
||||
# file content
|
||||
with open(conf_src, "r") as f:
|
||||
f = f.read().decode("utf-8")
|
||||
|
||||
for key in (
|
||||
"program:{ bench_name }-frappe-web",
|
||||
"program:{ bench_name }-frappe-worker",
|
||||
"program:{ bench_name }-frappe-longjob-worker",
|
||||
"program:{ bench_name }-frappe-async-worker",
|
||||
"program:{ bench_name }-frappe-workerbeat",
|
||||
"program:{ bench_name }-redis-cache",
|
||||
"program:{ bench_name }-redis-celery-broker",
|
||||
"program:{ bench_name }-redis-async-broker",
|
||||
"program:{ bench_name }-node-socketio",
|
||||
"group:{ bench_name }-processes",
|
||||
"group:{ bench_name }-redis"
|
||||
):
|
||||
self.assertTrue(key.format(bench_name) in f)
|
||||
|
||||
def assert_supervisor_process(self, bench_name):
|
||||
out = bench.utils.get_cmd_output("sudo supervisorctl status")
|
||||
for key in (
|
||||
"{bench_name}-process:{ bench_name }-frappe-web[\s]*RUNNING",
|
||||
"{bench_name}-process:{ bench_name }-frappe-worker[\s]*RUNNING",
|
||||
"{bench_name}-process:{ bench_name }-frappe-longjob-worker[\s]*RUNNING",
|
||||
"{bench_name}-process:{ bench_name }-frappe-async-worker[\s]*RUNNING",
|
||||
"{bench_name}-process:{ bench_name }-frappe-workerbeat[\s]*RUNNING",
|
||||
"{bench_name}-process:{ bench_name }-node-socketio[\s]*RUNNING",
|
||||
"{bench_name}-redis:{ bench_name }-redis-cache[\s]*RUNNING",
|
||||
"{bench_name}-redis:{bench_name}-redis-celery-broker[\s]*RUNNING",
|
||||
"{bench_name}-redis:{bench_name}-redis-async-broker[\s]*RUNNING",
|
||||
):
|
||||
self.assertTrue(re.match(key.format(bench_name), out))
|
||||
|
||||
def assert_nginx_process(self):
|
||||
out = bench.utils.get_cmd_output("sudo nginx -t")
|
||||
self.assertTrue("nginx: configuration file /etc/nginx/nginx.conf test is successful" in out)
|
||||
|
||||
|
@ -105,8 +105,9 @@ def get_max_worker_count():
|
||||
'''This function will return the maximum workers that can be started depending upon
|
||||
number of cpu's present on the machine'''
|
||||
n_cpus = multiprocessing.cpu_count()
|
||||
return dict(max_workers=2 * n_cpus)
|
||||
|
||||
return {
|
||||
"max_workers": (2 * n_cpus) + 1
|
||||
}
|
||||
|
||||
def make_ports(benches_path="."):
|
||||
default_ports = {
|
||||
@ -449,11 +450,16 @@ def update_common_site_config(ddict, bench='.'):
|
||||
update_json_file(os.path.join(bench, 'sites', 'common_site_config.json'), ddict)
|
||||
|
||||
def update_json_file(filename, ddict):
|
||||
with open(filename, 'r') as f:
|
||||
content = json.load(f)
|
||||
if os.path.exists(filename):
|
||||
with open(filename, 'r') as f:
|
||||
content = json.load(f)
|
||||
|
||||
else:
|
||||
content = {}
|
||||
|
||||
content.update(ddict)
|
||||
with open(filename, 'w') as f:
|
||||
content = json.dump(content, f, indent=1)
|
||||
content = json.dump(content, f, indent=1, sort_keys=True)
|
||||
|
||||
def drop_privileges(uid_name='nobody', gid_name='nogroup'):
|
||||
# from http://stackoverflow.com/a/2699996
|
||||
|
@ -16,7 +16,7 @@ get_passwd() {
|
||||
}
|
||||
|
||||
set_opts () {
|
||||
OPTS=`getopt -o v --long verbose,mysql-root-password:,frappe-user:,bench-branch:,setup-production,skip-setup-bench,help -n 'parse-options' -- "$@"`
|
||||
OPTS=`getopt -o v --long verbose,mysql-root-password:,frappe-user:,bench-branch:,setup-production,skip-install-bench,skip-setup-bench,help -n 'parse-options' -- "$@"`
|
||||
|
||||
if [ $? != 0 ] ; then echo "Failed parsing options." >&2 ; exit 1 ; fi
|
||||
|
||||
@ -27,6 +27,7 @@ set_opts () {
|
||||
FRAPPE_USER=false
|
||||
BENCH_BRANCH="master"
|
||||
SETUP_PROD=false
|
||||
INSTALL_BENCH=true
|
||||
SETUP_BENCH=true
|
||||
|
||||
if [ -f ~/frappe_passwords.sh ]; then
|
||||
@ -50,6 +51,7 @@ set_opts () {
|
||||
--setup-production ) SETUP_PROD=true; shift;;
|
||||
--bench-branch ) BENCH_BRANCH="$2"; shift;;
|
||||
--skip-setup-bench ) SETUP_BENCH=false; shift;;
|
||||
--skip-install-bench ) INSTALL_BENCH=false; shift;;
|
||||
-- ) shift; break ;;
|
||||
* ) break ;;
|
||||
esac
|
||||
@ -202,14 +204,12 @@ install_packages() {
|
||||
elif [ $OS == "debian" ] || [ $OS == "Ubuntu" ]; then
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
setup_debconf
|
||||
if [ $OS == "debian" ]; then
|
||||
run_cmd bash -c "curl -sL https://deb.nodesource.com/setup_0.12 | bash -"
|
||||
fi
|
||||
run_cmd bash -c "curl -sL https://deb.nodesource.com/setup_0.12 | sudo bash -"
|
||||
run_cmd sudo apt-get update
|
||||
run_cmd sudo apt-get install -y python-dev python-setuptools build-essential python-mysqldb git \
|
||||
ntp vim screen htop mariadb-server mariadb-common libmariadbclient-dev \
|
||||
libxslt1.1 libxslt1-dev redis-server libssl-dev libcrypto++-dev postfix nginx \
|
||||
supervisor python-pip fontconfig libxrender1 libxext6 xfonts-75dpi xfonts-base nodejs npm
|
||||
supervisor python-pip fontconfig libxrender1 libxext6 xfonts-75dpi xfonts-base nodejs
|
||||
|
||||
if [ $OS_VER == "precise" ]; then
|
||||
run_cmd sudo apt-get install -y libtiff4-dev libjpeg8-dev zlib1g-dev libfreetype6-dev liblcms2-dev libwebp-dev tcl8.5-dev tk8.5-dev python-tk
|
||||
@ -454,9 +454,12 @@ main() {
|
||||
configure_mariadb
|
||||
echo "Adding frappe user"
|
||||
add_user
|
||||
install_bench
|
||||
if $SETUP_BENCH; then
|
||||
setup_bench
|
||||
|
||||
if $INSTALL_BENCH; then
|
||||
install_bench
|
||||
if $SETUP_BENCH; then
|
||||
setup_bench
|
||||
fi
|
||||
fi
|
||||
|
||||
echo
|
||||
|
Loading…
x
Reference in New Issue
Block a user