Пример #1
0
def restart(web, supervisor, systemd):
    from bench.utils import restart_supervisor_processes, restart_systemd_processes
    from bench.config.common_site_config import get_config
    if get_config('.').get('restart_supervisor_on_update') or supervisor:
        restart_supervisor_processes(bench_path='.', web_workers=web)
    if get_config('.').get('restart_systemd_on_update') or systemd:
        restart_systemd_processes(bench_path='.', web_workers=web)
Пример #2
0
def setup_production(user, bench_path='.', yes=False):
	if get_config(bench_path).get('restart_supervisor_on_update') and get_config(bench_path).get('restart_systemd_on_update'):
		raise Exception("You cannot use supervisor and systemd at the same time. Modify your common_site_config accordingly." )

	if get_config(bench_path).get('restart_systemd_on_update'):
		generate_systemd_config(bench_path=bench_path, user=user, yes=yes)
	else:
		generate_supervisor_config(bench_path=bench_path, user=user, yes=yes)
	make_nginx_conf(bench_path=bench_path, yes=yes)
	fix_prod_setup_perms(bench_path, dataent_user=user)
	remove_default_nginx_configs()

	bench_name = get_bench_name(bench_path)
	nginx_conf = '/etc/nginx/conf.d/{bench_name}.conf'.format(bench_name=bench_name)

	if get_config(bench_path).get('restart_supervisor_on_update'):
		supervisor_conf_extn = "ini" if is_centos7() else "conf"
		supervisor_conf = os.path.join(get_supervisor_confdir(), '{bench_name}.{extn}'.format(
			bench_name=bench_name, extn=supervisor_conf_extn))

		# Check if symlink exists, If not then create it.
		if not os.path.islink(supervisor_conf):
			os.symlink(os.path.abspath(os.path.join(bench_path, 'config', 'supervisor.conf')), supervisor_conf)

	if not os.path.islink(nginx_conf):
		os.symlink(os.path.abspath(os.path.join(bench_path, 'config', 'nginx.conf')), nginx_conf)

	if get_config(bench_path).get('restart_supervisor_on_update'):
		reload_supervisor()

	if os.environ.get('NO_SERVICE_RESTART'):
		return

	reload_nginx()
Пример #3
0
def setup_production(user, bench_path='.', yes=False):
	if get_config(bench_path).get('restart_supervisor_on_update') and get_config(bench_path).get('restart_systemd_on_update'):
		raise Exception("You cannot use supervisor and systemd at the same time. Modify your common_site_config accordingly." )

	if get_config(bench_path).get('restart_systemd_on_update'):
		generate_systemd_config(bench_path=bench_path, user=user, yes=yes)
	else:
		generate_supervisor_config(bench_path=bench_path, user=user, yes=yes)
	make_nginx_conf(bench_path=bench_path, yes=yes)
	fix_prod_setup_perms(bench_path, frappe_user=user)
	remove_default_nginx_configs()

	bench_name = get_bench_name(bench_path)
	nginx_conf = '/etc/nginx/conf.d/{bench_name}.conf'.format(bench_name=bench_name)

	if get_config(bench_path).get('restart_supervisor_on_update'):
		supervisor_conf_extn = "ini" if is_centos7() else "conf"
		supervisor_conf = os.path.join(get_supervisor_confdir(), '{bench_name}.{extn}'.format(
			bench_name=bench_name, extn=supervisor_conf_extn))

		# Check if symlink exists, If not then create it.
		if not os.path.islink(supervisor_conf):
			os.symlink(os.path.abspath(os.path.join(bench_path, 'config', 'supervisor.conf')), supervisor_conf)

	if not os.path.islink(nginx_conf):
		os.symlink(os.path.abspath(os.path.join(bench_path, 'config', 'nginx.conf')), nginx_conf)

	if get_config(bench_path).get('restart_supervisor_on_update'):
		reload_supervisor()

	if os.environ.get('NO_SERVICE_RESTART'):
		return

	reload_nginx()
Пример #4
0
def remove_app(app, bench_path='.'):
    if app not in get_apps(bench_path):
        print("No app named {0}".format(app))
        sys.exit(1)

    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')

    for site in os.listdir(site_path):
        req_file = os.path.join(site_path, site, 'site_config.json')
        if os.path.exists(req_file):
            out = subprocess.check_output(
                ["bench", "--site", site, "list-apps"],
                cwd=bench_path).decode('utf-8')
            if re.search(r'\b' + app + r'\b', out):
                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)
    remove_from_appstxt(app, bench_path)
    shutil.rmtree(app_path)
    run_frappe_cmd("build", bench_path=bench_path)
    if get_config(bench_path).get('restart_supervisor_on_update'):
        restart_supervisor_processes(bench_path=bench_path)
    if get_config(bench_path).get('restart_systemd_on_update'):
        restart_systemd_processes(bench_path=bench_path)
Пример #5
0
def restart(web, supervisor, systemd):
	"Restart supervisor processes or systemd units"
	from bench.utils import restart_supervisor_processes, restart_systemd_processes
	from bench.config.common_site_config import get_config
	if get_config('.').get('restart_supervisor_on_update') or supervisor:
		restart_supervisor_processes(bench_path='.', web_workers=web)
	if get_config('.').get('restart_systemd_on_update') or systemd:
		restart_systemd_processes(bench_path='.', web_workers=web)
Пример #6
0
def get_sites_with_config(bench_path):
    from bench.config.common_site_config import get_config
    from bench.config.site_config import get_site_config

    sites = get_sites(bench_path=bench_path)
    dns_multitenant = get_config(bench_path).get('dns_multitenant')

    ret = []
    for site in sites:
        try:
            site_config = get_site_config(site, bench_path=bench_path)
        except Exception as e:
            strict_nginx = get_config(bench_path).get('strict_nginx')
            if strict_nginx:
                print(
                    "\n\nERROR: The site config for the site {} is broken.".
                    format(site),
                    "If you want this command to pass, instead of just throwing an error,",
                    "You may remove the 'strict_nginx' flag from common_site_config.json or set it to 0",
                    "\n\n")
                raise (e)
            else:
                print(
                    "\n\nWARNING: The site config for the site {} is broken.".
                    format(site),
                    "If you want this command to fail, instead of just showing a warning,",
                    "You may add the 'strict_nginx' flag to common_site_config.json and set it to 1",
                    "\n\n")
                continue

        ret.append({
            "name":
            site,
            "port":
            site_config.get('nginx_port'),
            "ssl_certificate":
            site_config.get('ssl_certificate'),
            "ssl_certificate_key":
            site_config.get('ssl_certificate_key')
        })

        if dns_multitenant and site_config.get('domains'):
            for domain in site_config.get('domains'):
                # domain can be a string or a dict with 'domain', 'ssl_certificate', 'ssl_certificate_key'
                if isinstance(domain, str) or isinstance(domain, unicode):
                    domain = {'domain': domain}

                domain['name'] = site
                ret.append(domain)

    use_wildcard_certificate(bench_path, ret)

    return ret
Пример #7
0
def install_app(app,
                bench_path=".",
                verbose=False,
                no_cache=False,
                restart_bench=True,
                skip_assets=False):
    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")
    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))

    if os.path.exists(os.path.join(app_path, 'package.json')):
        exec_cmd("yarn install", cwd=app_path)

    add_to_appstxt(app, bench_path=bench_path)

    if not skip_assets:
        build_assets(bench_path=bench_path, app=app)

    if restart_bench:
        conf = get_config(bench_path=bench_path)

        if conf.get('restart_supervisor_on_update'):
            restart_supervisor_processes(bench_path=bench_path)
        if conf.get('restart_systemd_on_update'):
            restart_systemd_processes(bench_path=bench_path)
Пример #8
0
def setup_backups(bench_path='.'):
    from bench.config.common_site_config import get_config
    logger.log('setting up backups')

    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])

    job_command = "{backup_command} >> {logfile} 2>&1".format(
        backup_command=backup_command, logfile=logfile)

    if job_command not in str(system_crontab):
        job = system_crontab.new(
            command=job_command,
            comment="bench auto backups set for every 6 hours")
        job.every(6).hours()
        system_crontab.write()
Пример #9
0
def pull_all_apps(bench_path='.', reset=False):
    '''Check all apps if there no local changes, pull'''
    rebase = '--rebase' if get_config(bench_path).get('rebase_on_pull') else ''

    # chech for local changes
    if not reset:
        for app in get_apps(bench_path=bench_path):
            excluded_apps = get_excluded_apps()
            if app in excluded_apps:
                print("Skipping reset for app {}".format(app))
                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 = out.decode('utf-8')
                if not re.search(
                        r'nothing to commit, working (directory|tree) clean',
                        out):
                    print('''

Cannot proceed with update: You have local changes in app "{0}" that are not committed.

Here are your choices:

1. Merge the {0} app manually with "git pull" / "git pull --rebase" and fix conflicts.
1. Temporarily remove your changes with "git stash" or discard them completely
	with "bench update --reset" or for individual repositries "git reset --hard"
2. If your changes are helpful for others, send in a pull request via GitHub and
	wait for them to be merged in the core.'''.format(app))
                    sys.exit(1)

    excluded_apps = get_excluded_apps()
    for app in get_apps(bench_path=bench_path):
        if app in excluded_apps:
            print("Skipping pull for app {}".format(app))
            continue
        app_dir = get_repo_dir(app, bench_path=bench_path)
        if os.path.exists(os.path.join(app_dir, '.git')):
            remote = get_remote(app)
            if not remote:
                # remote is False, i.e. remote doesn't exist, add the app to excluded_apps.txt
                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
            logger.info('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)
            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)
            exec_cmd('find . -name "*.pyc" -delete', cwd=app_dir)
Пример #10
0
def use_wildcard_certificate(bench_path, ret):
    '''
		stored in common_site_config.json as:
	    "wildcard": {
			"domain": "*.erpnext.com",
			"ssl_certificate": "/path/to/erpnext.com.cert",
			"ssl_certificate_key": "/path/to/erpnext.com.key"
		}
	'''
    from bench.config.common_site_config import get_config
    config = get_config(bench_path=bench_path)
    wildcard = config.get('wildcard')

    if not wildcard:
        return

    domain = wildcard['domain']
    ssl_certificate = wildcard['ssl_certificate']
    ssl_certificate_key = wildcard['ssl_certificate_key']

    if domain.startswith('*.'):
        domain = domain[1:]
    else:
        domain = '.' + domain

    for site in ret:
        if site.get('ssl_certificate'):
            continue

        if (site.get('domain') or site['name']).endswith(domain):
            # example: ends with .erpnext.com
            site['ssl_certificate'] = ssl_certificate
            site['ssl_certificate_key'] = ssl_certificate_key
            site['wildcard'] = 1
Пример #11
0
def setup_manager(yes=False, port=23624, domain=None):
	"Setup bench-manager.local site with the bench_manager app installed on it"
	from six.moves import input
	create_new_site = True
	if 'bench-manager.local' in os.listdir('sites'): 
		ans = input('Site aleady exists. Overwrite existing new site? [Y/n]: ')
		while ans.lower() not in ['y', 'n', '']:
			ans = input('Please type "y" or "n". Site aleady exists. Overwrite existing new site? [Y/n]: ')
		if ans=='n': create_new_site = False
	if create_new_site: exec_cmd("bench new-site --force bench-manager.local")

	if 'bench_manager' in os.listdir('apps'):
		print('App aleady exists. Skipping downloading the app')
	else: 
		exec_cmd("bench get-app bench_manager")

	exec_cmd("bench --site bench-manager.local install-app bench_manager")

	from bench.config.common_site_config import get_config
	bench_path = '.'
	conf = get_config(bench_path)
	if conf.get('restart_supervisor_on_update') or conf.get('restart_systemd_on_update'):
		# implicates a production setup or so I presume
		if not domain:
			print("Please specify the site name on which you want to host bench-manager using the 'domain' flag")
			sys.exit(1)
	
		from bench.utils import get_sites, get_bench_name
		bench_name = get_bench_name(bench_path)

		if domain not in get_sites(bench_path):
			raise Exception("No such site")

		from bench.config.nginx import make_bench_manager_nginx_conf
		make_bench_manager_nginx_conf(bench_path, yes=yes, port=port, domain=domain)
Пример #12
0
def make_nginx_conf(bench_path, force=False):
	from bench import env
	from bench.config.common_site_config import get_config

	template = env.get_template('nginx.conf')
	bench_path = os.path.abspath(bench_path)
	sites_path = os.path.join(bench_path, "sites")

	config = get_config(bench_path)
	sites = prepare_sites(config, bench_path)

	nginx_conf = template.render(**{
		"sites_path": sites_path,
		"http_timeout": config.get("http_timeout"),
		"sites": sites,
		"webserver_port": config.get('webserver_port'),
		"socketio_port": config.get('socketio_port'),
		"bench_name": get_bench_name(bench_path)
	})

	conf_path = os.path.join(bench_path, "config", "nginx.conf")
	if not force and os.path.exists(conf_path):
		click.confirm('nginx.conf already exists and this will overwrite it. Do you want to continue?',
			abort=True)

	with open(conf_path, "w") as f:
		f.write(nginx_conf)
Пример #13
0
def update(pull=False,
           patch=False,
           build=False,
           bench=False,
           auto=False,
           restart_supervisor=False,
           requirements=False,
           no_backup=False,
           force=False,
           reset=False):
    "Update bench"

    if not (pull or patch or build or bench or requirements):
        pull, patch, build, bench, requirements = True, True, True, True, True

    if auto:
        sys.exit(1)

    patches.run(bench_path='.')
    conf = get_config(".")

    if bench and conf.get('update_bench_on_update'):
        update_bench()
        restart_update({
            'pull': pull,
            'patch': patch,
            'build': build,
            'requirements': requirements,
            'no-backup': no_backup,
            'restart-supervisor': restart_supervisor,
            'reset': reset
        })

    if conf.get('release_bench'):
        print('Release bench, cannot update')
        sys.exit(1)

    version_upgrade = is_version_upgrade()

    if version_upgrade[0]:
        print()
        print()
        print(
            "This update will cause a major version change in Frappe/ERPNext from {0} to {1}."
            .format(*version_upgrade[1:]))
        print(
            "This would take significant time to migrate and might break custom apps."
        )
        click.confirm('Do you want to continue?', abort=True)

    _update(pull,
            patch,
            build,
            bench,
            auto,
            restart_supervisor,
            requirements,
            no_backup,
            force=force,
            reset=reset)
Пример #14
0
def _update(pull=False,
            patch=False,
            build=False,
            update_bench=False,
            auto=False,
            restart_supervisor=False,
            requirements=False,
            no_backup=False,
            upgrade=False,
            bench_path='.',
            force=False,
            reset=False,
            force_frappe=False,
            force_erpnext=False,
            force_frappe_erpnext=False):
    conf = get_config(bench_path=bench_path)
    version_upgrade = is_version_upgrade(bench_path=bench_path)

    # if version_upgrade[0] and not upgrade:
    #     raise Exception("Major Version Upgrade")
    #
    # if upgrade and (version_upgrade[0] or (not version_upgrade[0] and force)):
    #     validate_upgrade(version_upgrade[1], version_upgrade[2], bench_path=bench_path)

    before_update(bench_path=bench_path, requirements=requirements)

    if pull:
        pull_all_apps(bench_path=bench_path,
                      reset=reset,
                      force_frappe=force_frappe,
                      force_erpnext=force_erpnext,
                      force_frappe_erpnext=force_frappe_erpnext)

    # if requirements:
    #     update_requirements(bench_path=bench_path)

    if upgrade and (version_upgrade[0] or (not version_upgrade[0] and force)):
        pre_upgrade(version_upgrade[1],
                    version_upgrade[2],
                    bench_path=bench_path)
        import bench.utils, bench.app
        reload(bench.utils)
        reload(bench.app)

    if patch:
        if not no_backup:
            backup_all_sites(bench_path=bench_path)
        patch_sites(bench_path=bench_path)
    if build:
        build_assets(bench_path=bench_path)
    if upgrade and (version_upgrade[0] or (not version_upgrade[0] and force)):
        post_upgrade(version_upgrade[1],
                     version_upgrade[2],
                     bench_path=bench_path)
    if restart_supervisor or conf.get('restart_supervisor_on_update'):
        restart_supervisor_processes(bench_path=bench_path)

    print "_" * 80
    print "Bench: Open source installer + admin for Frappe and ERPNext (https://erpnext.com)"
    print
Пример #15
0
def setup_letsencrypt(site, custom_domain, bench_path, interactive):

    site_path = os.path.join(bench_path, "sites", site, "site_config.json")
    if not os.path.exists(os.path.dirname(site_path)):
        print("No site named " + site)
        return

    if custom_domain:
        domains = get_domains(site, bench_path)
        for d in domains:
            if (isinstance(d, dict) and d['domain'] == custom_domain):
                print(
                    "SSL for Domain {0} already exists".format(custom_domain))
                return

        if not custom_domain in domains:
            print("No custom domain named {0} set for site".format(
                custom_domain))
            return

    click.confirm(
        'Running this will stop the nginx service temporarily causing your sites to go offline\n'
        'Do you want to continue?',
        abort=True)

    if not get_config(bench_path).get("dns_multitenant"):
        print("You cannot setup SSL without DNS Multitenancy")
        return

    create_config(site, custom_domain)
    run_certbot_and_setup_ssl(site, custom_domain, bench_path, interactive)
    setup_crontab()
Пример #16
0
def setup_letsencrypt(site, custom_domain, bench_path):

	site_path = os.path.join(bench_path, "sites", site, "site_config.json")
	if not os.path.exists(os.path.dirname(site_path)):
		print "No site named "+site
		return

	if custom_domain:
		domains = get_domains(site, bench_path)
		for d in domains:
			if (isinstance(d, dict) and d['domain']==custom_domain):
				print "SSL for Domain {0} already exists".format(custom_domain)
				return

		if not custom_domain in domains:
			print "No custom domain named {0} set for site".format(custom_domain)
			return

	click.confirm('Running this will stop the nginx service temporarily causing your sites to go offline\n'
		'Do you want to continue?',
		abort=True)

	if not get_config(bench_path).get("dns_multitenant"):
		print "You cannot setup SSL without DNS Multitenancy"
		return

	create_config(site, custom_domain)
	run_certbot_and_setup_ssl(site, custom_domain, bench_path)
	setup_crontab()
Пример #17
0
def disable_production(bench_path='.'):
    bench_name = get_bench_name(bench_path)

    # supervisorctl
    supervisor_conf_extn = "ini" if is_centos7() else "conf"
    supervisor_conf = os.path.join(
        get_supervisor_confdir(),
        '{bench_name}.{extn}'.format(bench_name=bench_name,
                                     extn=supervisor_conf_extn))

    if os.path.islink(supervisor_conf):
        os.unlink(supervisor_conf)

    if get_config(bench_path).get('restart_supervisor_on_update'):
        exec_cmd('sudo supervisorctl reread')
        exec_cmd('sudo supervisorctl update')

    # nginx
    nginx_conf = '/etc/nginx/conf.d/{bench_name}.conf'.format(
        bench_name=bench_name)

    if os.path.islink(nginx_conf):
        os.unlink(nginx_conf)

    reload_nginx()
Пример #18
0
def get_sites_with_config(bench_path):
	from bench.config.common_site_config import get_config
	from bench.config.site_config import get_site_config

	sites = get_sites(bench_path=bench_path)
	dns_multitenant = get_config(bench_path).get('dns_multitenant')

	ret = []
	for site in sites:
		site_config = get_site_config(site, bench_path=bench_path)
		ret.append({
			"name": site,
			"port": site_config.get('nginx_port'),
			"ssl_certificate": site_config.get('ssl_certificate'),
			"ssl_certificate_key": site_config.get('ssl_certificate_key')
		})

		if dns_multitenant and site_config.get('domains'):
			for domain in site_config.get('domains'):
				# domain can be a string or a dict with 'domain', 'ssl_certificate', 'ssl_certificate_key'
				if isinstance(domain, basestring):
					domain = { 'domain': domain }

				domain['name'] = site
				ret.append(domain)

	use_wildcard_certificate(bench_path, ret)

	return ret
Пример #19
0
def get_sites_with_config(bench_path):
    from bench.config.common_site_config import get_config
    from bench.config.site_config import get_site_config

    sites = get_sites(bench_path=bench_path)
    dns_multitenant = get_config(bench_path).get('dns_multitenant')

    ret = []
    for site in sites:
        site_config = get_site_config(site, bench_path=bench_path)
        ret.append({
            "name":
            site,
            "port":
            site_config.get('nginx_port'),
            "ssl_certificate":
            site_config.get('ssl_certificate'),
            "ssl_certificate_key":
            site_config.get('ssl_certificate_key')
        })

        if dns_multitenant and site_config.get('domains'):
            for domain in site_config.get('domains'):
                # domain can be a string or a dict with 'domain', 'ssl_certificate', 'ssl_certificate_key'
                if isinstance(domain, basestring):
                    domain = {'domain': domain}

                domain['name'] = site
                ret.append(domain)

    use_wildcard_certificate(bench_path, ret)

    return ret
Пример #20
0
def remove_common_config(keys):
	common_site_config = get_config('.')
	for key in keys:
		if key in common_site_config:
			del common_site_config[key]

	put_config(common_site_config)
Пример #21
0
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
    conf = get_config(bench_path=bench_path)
    print("-" * 80 + "Your bench was upgraded to version {0}".format(to_ver))

    if conf.get('restart_supervisor_on_update'):
        redis.generate_config(bench_path=bench_path)
        generate_supervisor_config(bench_path=bench_path)
        make_nginx_conf(bench_path=bench_path)

        if from_ver == 4 and to_ver == 5:
            setup_backups(bench_path=bench_path)

        if from_ver <= 5 and to_ver == 6:
            setup_socketio(bench_path=bench_path)

        message = """
As you have setup your bench for production, you will have to reload configuration for nginx and supervisor. To complete the migration, please run the following commands
sudo service nginx restart
sudo supervisorctl reload
		""".strip()
        print(message)
Пример #22
0
def make_nginx_conf(bench_path, force=False):
    from bench import env
    from bench.config.common_site_config import get_config

    template = env.get_template('nginx.conf')
    bench_path = os.path.abspath(bench_path)
    sites_path = os.path.join(bench_path, "sites")

    config = get_config(bench_path)
    sites = prepare_sites(config, bench_path)

    nginx_conf = template.render(
        **{
            "sites_path": sites_path,
            "http_timeout": config.get("http_timeout"),
            "sites": sites,
            "webserver_port": config.get('webserver_port'),
            "socketio_port": config.get('socketio_port'),
            "bench_name": get_bench_name(bench_path)
        })

    conf_path = os.path.join(bench_path, "config", "nginx.conf")
    if not force and os.path.exists(conf_path):
        click.confirm(
            'nginx.conf already exists and this will overwrite it. Do you want to continue?',
            abort=True)

    with open(conf_path, "w") as f:
        f.write(nginx_conf)
Пример #23
0
def install_app(app,
                bench_path=".",
                verbose=False,
                no_cache=False,
                postprocess=True,
                skip_assets=False):
    logger.info("installing {}".format(app))

    pip_path = os.path.join(bench_path, "env", "bin", "pip")
    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))
    add_to_appstxt(app, bench_path=bench_path)

    if postprocess:
        if not skip_assets:
            build_assets(bench_path=bench_path, app=app)
        conf = get_config(bench_path=bench_path)

        if conf.get('restart_supervisor_on_update'):
            restart_supervisor_processes(bench_path=bench_path)
        if conf.get('restart_systemd_on_update'):
            restart_systemd_processes(bench_path=bench_path)
Пример #24
0
def execute(bench_path):
	# deprecate bench config
	bench_config_path = os.path.join(bench_path, 'config.json')
	if not os.path.exists(bench_config_path):
		return

	with open(bench_config_path, "r") as f:
		bench_config = json.loads(f.read())

	common_site_config = get_common_site_config(bench_path)
	common_site_config.update(bench_config)
	put_config(common_site_config, bench_path)

	# remove bench/config.json
	os.remove(bench_config_path)

	# change keys
	config = get_config(bench_path)
	changed = False
	for from_key, to_key, default in (
			("celery_broker", "redis_queue", "redis://localhost:6379"),
			("async_redis_server", "redis_socketio", "redis://localhost:12311"),
			("cache_redis_server", "redis_cache", "redis://localhost:11311")
		):
		if from_key in config:
			config[to_key] = config[from_key]
			del config[from_key]
			changed = True

		elif to_key not in config:
			config[to_key] = default
			changed = True

	if changed:
		put_config(config, bench_path)
Пример #25
0
def use_wildcard_certificate(bench_path, ret):
	'''
		stored in common_site_config.json as:
	    "wildcard": {
			"domain": "*.erpnext.com",
			"ssl_certificate": "/path/to/erpnext.com.cert",
			"ssl_certificate_key": "/path/to/erpnext.com.key"
		}
	'''
	from bench.config.common_site_config import get_config
	config = get_config(bench_path=bench_path)
	wildcard = config.get('wildcard')

	if not wildcard:
		return

	domain = wildcard['domain']
	ssl_certificate = wildcard['ssl_certificate']
	ssl_certificate_key = wildcard['ssl_certificate_key']

	if domain.startswith('*.'):
		domain = domain[1:]
	else:
		domain = '.' + domain

	for site in ret:
		if site.get('ssl_certificate'):
			continue

		if (site.get('domain') or site['name']).endswith(domain):
			# example: ends with .erpnext.com
			site['ssl_certificate'] = ssl_certificate
			site['ssl_certificate_key'] = ssl_certificate_key
			site['wildcard'] = 1
Пример #26
0
def generate_supervisor_config(bench_path, user=None):
	from bench.app import get_current_frappe_version
	from bench.utils import get_bench_name, find_executable
	from bench.config.common_site_config import get_config, update_config, get_gunicorn_workers

	template = bench.env.get_template('supervisor.conf')
	if not user:
		user = getpass.getuser()

	config = get_config(bench=bench_path)

	bench_dir = os.path.abspath(bench_path)

	config = template.render(**{
		"bench_dir": bench_dir,
		"sites_dir": os.path.join(bench_dir, 'sites'),
		"user": user,
		"http_timeout": config.get("http_timeout", 120),
		"redis_server": find_executable('redis-server'),
		"node": find_executable('node') or find_executable('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'),
		"frappe_version": get_current_frappe_version(),
		"webserver_port": config.get('webserver_port', 8000),
		"gunicorn_workers": config.get('gunicorn_workers', get_gunicorn_workers()["gunicorn_workers"]),
		"bench_name": get_bench_name(bench_path)
	})

	with open(os.path.join(bench_path, 'config', 'supervisor.conf'), 'w') as f:
		f.write(config)

	update_config({'restart_supervisor_on_update': True}, bench=bench_path)
Пример #27
0
def _update(pull=False,
            patch=False,
            build=False,
            update_bench=False,
            auto=False,
            restart_supervisor=False,
            requirements=False,
            no_backup=False,
            bench_path='.',
            force=False,
            reset=False):
    conf = get_config(bench_path=bench_path)
    version_upgrade = is_version_upgrade(bench_path=bench_path)

    if version_upgrade[0] or (not version_upgrade[0] and force):
        validate_upgrade(version_upgrade[1],
                         version_upgrade[2],
                         bench_path=bench_path)

    before_update(bench_path=bench_path, requirements=requirements)

    if pull:
        pull_all_apps(bench_path=bench_path, reset=reset)

    if requirements:
        update_requirements(bench_path=bench_path)
        update_npm_packages(bench_path=bench_path)

    if version_upgrade[0] or (not version_upgrade[0] and force):
        pre_upgrade(version_upgrade[1],
                    version_upgrade[2],
                    bench_path=bench_path)
        import bench.utils, bench.app
        print('Reloading bench...')
        reload(bench.utils)
        reload(bench.app)

    if patch:
        if not no_backup:
            print('Backing up sites...')
            backup_all_sites(bench_path=bench_path)

        print('Patching sites...')
        patch_sites(bench_path=bench_path)
    if build:
        build_assets(bench_path=bench_path)
    if version_upgrade[0] or (not version_upgrade[0] and force):
        post_upgrade(version_upgrade[1],
                     version_upgrade[2],
                     bench_path=bench_path)
    if restart_supervisor or conf.get('restart_supervisor_on_update'):
        restart_supervisor_processes(bench_path=bench_path)

    print("_" * 80)
    print(
        "Bench: Deployment tool for Frappe and ERPNext (https://erpnext.org).")
    print(
        "Open source depends on your contributions, so please contribute bug reports, patches, fixes or cash and be a part of the community"
    )
    print()
Пример #28
0
def update(pull=False,
           patch=False,
           build=False,
           bench=False,
           auto=False,
           restart_supervisor=False,
           requirements=False,
           no_backup=False,
           upgrade=False,
           force=False):
    "Update bench"

    if not (pull or patch or build or bench or requirements):
        pull, patch, build, bench, requirements = True, True, True, True, True

    if auto:
        sys.exit(1)

    patches.run(bench_path='.')
    conf = get_config(".")

    if bench and conf.get('update_bench_on_update'):
        update_bench()
        restart_update({
            'pull': pull,
            'patch': patch,
            'build': build,
            'requirements': requirements,
            'no-backup': no_backup,
            'restart-supervisor': restart_supervisor,
            'upgrade': upgrade
        })

    if conf.get('release_bench'):
        print 'Release bench, cannot update'
        sys.exit(1)

    version_upgrade = is_version_upgrade()

    if version_upgrade[0] and not upgrade:
        print
        print
        print "This update will cause a major version change in Frappe/ERPNext from {0} to {1}.".format(
            *version_upgrade[1:])
        print "This would take significant time to migrate and might break custom apps. Please run `bench update --upgrade` to confirm."
        print
        print "You can stay on the latest stable release by running `bench switch-to-master` or pin your bench to {0} by running `bench switch-to-v{0}`".format(
            version_upgrade[1])
        sys.exit(1)

    _update(pull,
            patch,
            build,
            bench,
            auto,
            restart_supervisor,
            requirements,
            no_backup,
            upgrade,
            force=force)
Пример #29
0
def make_nginx_conf(bench_path, yes=False):
	from bench import env
	from bench.config.common_site_config import get_config

	template = env.get_template('nginx.conf')
	bench_path = os.path.abspath(bench_path)
	sites_path = os.path.join(bench_path, "sites")

	config = get_config(bench_path)
	sites = prepare_sites(config, bench_path)

	nginx_conf = template.render(**{
		"sites_path": sites_path,
		"http_timeout": config.get("http_timeout"),
		"sites": sites,
		"webserver_port": config.get('webserver_port'),
		"socketio_port": config.get('socketio_port'),
		"bench_name": get_bench_name(bench_path),
		"error_pages": get_error_pages(),

		# for nginx map variable
		"random_string": "".join(random.choice(string.ascii_lowercase) for i in xrange(7))
	})

	conf_path = os.path.join(bench_path, "config", "nginx.conf")
	if not yes and os.path.exists(conf_path):
		click.confirm('nginx.conf already exists and this will overwrite it. Do you want to continue?',
			abort=True)

	with open(conf_path, "w") as f:
		f.write(nginx_conf)
Пример #30
0
def restart_supervisor_processes(bench_path='.', web_workers=False):
    from .config.common_site_config import get_config
    conf = get_config(bench_path=bench_path)
    bench_name = get_bench_name(bench_path)

    cmd = conf.get('supervisor_restart_cmd')
    if cmd:
        exec_cmd(cmd, cwd=bench_path)

    else:
        supervisor_status = subprocess.check_output(
            ['sudo', 'supervisorctl', 'status'], cwd=bench_path)
        supervisor_status = safe_decode(supervisor_status)

        if web_workers and '{bench_name}-web:'.format(
                bench_name=bench_name) in supervisor_status:
            group = '{bench_name}-web:	'.format(bench_name=bench_name)

        elif '{bench_name}-workers:'.format(
                bench_name=bench_name) in supervisor_status:
            group = '{bench_name}-workers: {bench_name}-web:'.format(
                bench_name=bench_name)

        # backward compatibility
        elif '{bench_name}-processes:'.format(
                bench_name=bench_name) in supervisor_status:
            group = '{bench_name}-processes:'.format(bench_name=bench_name)

        # backward compatibility
        else:
            group = 'frappe:'

        exec_cmd('sudo supervisorctl restart {group}'.format(group=group),
                 cwd=bench_path)
Пример #31
0
def migrate_env(python, backup=False):
    from bench.config.common_site_config import get_config
    from bench.app import get_apps

    log = logging.getLogger(__name__)
    log.setLevel(logging.DEBUG)

    nvenv = 'env'
    path = os.getcwd()
    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:
        config = get_config(bench_path=os.getcwd())
        rredis = urlparse(config['redis_cache'])

        redis = '{redis} -p {port}'.format(redis=which('redis-cli'),
                                           port=rredis.port)

        log.debug('Clearing Redis Cache...')
        exec_cmd('{redis} FLUSHALL'.format(redis=redis))
        log.debug('Clearing Redis DataBase...')
        exec_cmd('{redis} FLUSHDB'.format(redis=redis))
    except:
        log.warn('Please ensure Redis Connections are running or Daemonized.')

    # Backup venv: restore using `virtualenv --relocatable` if needed
    if backup:
        parch = os.path.join(path, 'archived_envs')
        if not os.path.exists(parch):
            os.mkdir(parch)

        source = os.path.join(path, 'env')
        target = parch

        log.debug('Backing up Virtual Environment')
        stamp = datetime.now().strftime('%Y%m%d_%H%M%S')
        dest = os.path.join(path, str(stamp))

        os.rename(source, dest)
        shutil.move(dest, target)

    # Create virtualenv using specified python
    try:
        log.debug('Setting up a New Virtual {} Environment'.format(python))
        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()])
        exec_cmd('{0} install -q -U {1}'.format(pip, apps))

        log.debug('Migration Successful to {}'.format(python))
    except:
        log.debug('Migration Error')
        raise
Пример #32
0
def remove_common_config(keys):
    from bench.config.common_site_config import get_config, put_config
    common_site_config = get_config('.')
    for key in keys:
        if key in common_site_config:
            del common_site_config[key]

    put_config(common_site_config)
Пример #33
0
def remove_common_config(keys):
	from bench.config.common_site_config import get_config, put_config
	common_site_config = get_config('.')
	for key in keys:
		if key in common_site_config:
			del common_site_config[key]

	put_config(common_site_config)
Пример #34
0
def generate_supervisor_config(bench_path, user=None, force=False):
    from bench.app import get_current_frappe_version, 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

    template = bench.env.get_template('supervisor.conf')
    if not user:
        user = getpass.getuser()

    config = get_config(bench=bench_path)

    bench_dir = os.path.abspath(bench_path)

    config = template.render(
        **{
            "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'),
            "node":
            find_executable('node') or find_executable('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'),
            "webserver_port":
            config.get('webserver_port', 8000),
            "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
        })

    conf_path = os.path.join(bench_path, 'config', 'supervisor.conf')
    if not force and os.path.exists(conf_path):
        click.confirm(
            'supervisor.conf already exists and this will overwrite it. Do you want to continue?',
            abort=True)

    with open(conf_path, 'w') as f:
        f.write(config)

    update_config({'restart_supervisor_on_update': True}, bench=bench_path)
Пример #35
0
def get_sites_with_config(bench_path):
	from bench.config.common_site_config import get_config
	from bench.config.site_config import get_site_config

	sites = get_sites(bench_path=bench_path)
	dns_multitenant = get_config(bench_path).get('dns_multitenant')

	ret = []
	for site in sites:
		try:
			site_config = get_site_config(site, bench_path=bench_path)
		except Exception as e:
			strict_nginx = get_config(bench_path).get('strict_nginx')
			if strict_nginx:
				print("\n\nERROR: The site config for the site {} is broken.".format(site),
					"If you want this command to pass, instead of just throwing an error,",
					"You may remove the 'strict_nginx' flag from common_site_config.json or set it to 0",
					"\n\n")
				raise (e)
			else:
				print("\n\nWARNING: The site config for the site {} is broken.".format(site),
					"If you want this command to fail, instead of just showing a warning,",
					"You may add the 'strict_nginx' flag to common_site_config.json and set it to 1",
					"\n\n")
				continue

		ret.append({
			"name": site,
			"port": site_config.get('nginx_port'),
			"ssl_certificate": site_config.get('ssl_certificate'),
			"ssl_certificate_key": site_config.get('ssl_certificate_key')
		})

		if dns_multitenant and site_config.get('domains'):
			for domain in site_config.get('domains'):
				# domain can be a string or a dict with 'domain', 'ssl_certificate', 'ssl_certificate_key'
				if isinstance(domain, str) or isinstance(domain, unicode):
					domain = { 'domain': domain }

				domain['name'] = site
				ret.append(domain)

	use_wildcard_certificate(bench_path, ret)

	return ret
Пример #36
0
def change_uid():
	if is_root() and not cmd_requires_root():
		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
		else:
			print 'You should not run this command as root'
			sys.exit(1)
Пример #37
0
def change_uid():
    if is_root() and not cmd_requires_root():
        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
        else:
            log(change_uid_msg, level=3)
            sys.exit(1)
Пример #38
0
def change_uid():
	if is_root() and not cmd_requires_root():
		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
		else:
			print 'You should not run this command as root'
			sys.exit(1)
Пример #39
0
def make_nginx_conf(bench_path, yes=False):
    conf_path = os.path.join(bench_path, "config", "nginx.conf")

    if not yes and os.path.exists(conf_path):
        if not click.confirm(
                'nginx.conf already exists and this will overwrite it. Do you want to continue?'
        ):
            return

    from bench import env
    from bench.config.common_site_config import get_config

    template = env.get_template('nginx.conf')
    bench_path = os.path.abspath(bench_path)
    sites_path = os.path.join(bench_path, "sites")

    config = get_config(bench_path)
    sites = prepare_sites(config, bench_path)
    bench_name = get_bench_name(bench_path)

    allow_rate_limiting = config.get('allow_rate_limiting', False)

    template_vars = {
        "sites_path":
        sites_path,
        "http_timeout":
        config.get("http_timeout"),
        "sites":
        sites,
        "webserver_port":
        config.get('webserver_port'),
        "socketio_port":
        config.get('socketio_port'),
        "bench_name":
        bench_name,
        "error_pages":
        get_error_pages(),
        "allow_rate_limiting":
        allow_rate_limiting,
        # for nginx map variable
        "random_string":
        "".join(random.choice(string.ascii_lowercase) for i in range(7))
    }

    if allow_rate_limiting:
        template_vars.update({
            'bench_name_hash':
            hashlib.sha256(bench_name).hexdigest()[:16],
            'limit_conn_shared_memory':
            get_limit_conn_shared_memory()
        })

    nginx_conf = template.render(**template_vars)

    with open(conf_path, "w") as f:
        f.write(nginx_conf)
Пример #40
0
def execute(bench_path):
    """This patch checks if bench sudoers is set and regenerate supervisor and sudoers files"""
    user = get_config('.').get("frappe_user") or getpass.getuser()

    if is_sudoers_set():
        if is_production_set(bench_path):
            exec_cmd("sudo bench setup supervisor --yes --user {user}".format(
                user=user))
            service("supervisord", "restart")

        exec_cmd("sudo bench setup sudoers {user}".format(user=user))
Пример #41
0
def setup_wildcard_ssl(domain, email, bench_path, exclude_base_domain):
    def _get_domains(domain):
        domain_list = [domain]

        if not domain.startswith('*.'):
            # add wildcard caracter to domain if missing
            domain_list.append('*.{0}'.format(domain))
        else:
            # include base domain based on flag
            domain_list.append(domain.replace('*.', ''))

        if exclude_base_domain:
            domain_list.remove(domain.replace('*.', ''))

        return domain_list

    if not get_config(bench_path).get("dns_multitenant"):
        print("You cannot setup SSL without DNS Multitenancy")
        return

    get_certbot()
    domain_list = _get_domains(domain.strip())

    email_param = ''
    if email:
        email_param = '--email {0}'.format(email)

    try:
        exec_cmd(
            "{path} certonly --manual --preferred-challenges=dns {email_param} \
			--server https://acme-v02.api.letsencrypt.org/directory \
			--agree-tos -d {domain}".format(path=get_certbot_path(),
                                   domain=' -d '.join(domain_list),
                                   email_param=email_param))

    except CommandFailedError:
        print("There was a problem trying to setup SSL")
        return

    ssl_path = "/etc/letsencrypt/live/{domain}/".format(domain=domain)
    ssl_config = {
        "wildcard": {
            "domain": domain,
            "ssl_certificate": os.path.join(ssl_path, "fullchain.pem"),
            "ssl_certificate_key": os.path.join(ssl_path, "privkey.pem")
        }
    }

    update_common_site_config(ssl_config)
    setup_crontab()

    make_nginx_conf(bench_path)
    print("Restrting Nginx service")
    service('nginx', 'restart')
Пример #42
0
def setup_wildcard_ssl(domain, email, bench_path, exclude_base_domain):

	def _get_domains(domain):
		domain_list = [domain]

		if not domain.startswith('*.'):
			# add wildcard caracter to domain if missing
			domain_list.append('*.{0}'.format(domain))
		else:
			# include base domain based on flag
			domain_list.append(domain.replace('*.', ''))

		if exclude_base_domain:
			domain_list.remove(domain.replace('*.', ''))

		return domain_list

	if not get_config(bench_path).get("dns_multitenant"):
		print("You cannot setup SSL without DNS Multitenancy")
		return

	get_certbot()
	domain_list = _get_domains(domain.strip())

	email_param = ''
	if email:
		email_param = '--email {0}'.format(email)

	try:
		exec_cmd("{path} certonly --manual --preferred-challenges=dns {email_param} \
			 --server https://acme-v02.api.letsencrypt.org/directory \
			 --agree-tos -d {domain}".format(path=get_certbot_path(), domain=' -d '.join(domain_list),
			 email_param=email_param))

	except CommandFailedError:
		print("There was a problem trying to setup SSL")
		return

	ssl_path = "/etc/letsencrypt/live/{domain}/".format(domain=domain)
	ssl_config = {
		"wildcard": {
			"domain": domain,
			"ssl_certificate": os.path.join(ssl_path, "fullchain.pem"),
			"ssl_certificate_key": os.path.join(ssl_path, "privkey.pem") 
		}
	}

	update_common_site_config(ssl_config)
	setup_crontab()

	make_nginx_conf(bench_path)
	print("Restrting Nginx service")
	service('nginx', 'restart')
	
Пример #43
0
def execute(bench_path):
    """
		This patch fixes a cron job that would backup sites every minute per 6 hours
	"""

    user = get_config(bench_path=bench_path).get('frappe_user')
    user_crontab = CronTab(user=user)

    for job in user_crontab.find_comment(
            "bench auto backups set for every 6 hours"):
        job.every(6).hours()
        user_crontab.write()
Пример #44
0
def setup_procfile(bench_path, yes=False):
	config = get_config(bench_path=bench_path)
	procfile_path = os.path.join(bench_path, 'Procfile')
	if not yes and os.path.exists(procfile_path):
		click.confirm('A Procfile already exists and this will overwrite it. Do you want to continue?',
			abort=True)

	procfile = bench.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'))

	with open(procfile_path, 'w') as f:
		f.write(procfile)
Пример #45
0
def _update(pull=False, patch=False, build=False, update_bench=False, auto=False, restart_supervisor=False,
		restart_systemd=False, requirements=False, no_backup=False, bench_path='.', force=False, reset=False):
	conf = get_config(bench_path=bench_path)
	version_upgrade = is_version_upgrade(bench_path=bench_path)

	if version_upgrade[0] or (not version_upgrade[0] and force):
		validate_upgrade(version_upgrade[1], version_upgrade[2], bench_path=bench_path)

	before_update(bench_path=bench_path, requirements=requirements)

	if pull:
		pull_all_apps(bench_path=bench_path, reset=reset)

	if requirements:
		update_requirements(bench_path=bench_path)
		update_node_packages(bench_path=bench_path)

	if version_upgrade[0] or (not version_upgrade[0] and force):
		pre_upgrade(version_upgrade[1], version_upgrade[2], bench_path=bench_path)
		import bench.utils, bench.app
		print('Reloading bench...')
		if sys.version_info >= (3, 4):
			import importlib
			importlib.reload(bench.utils)
			importlib.reload(bench.app)
		else:
			reload(bench.utils)
			reload(bench.app)

	if patch:
		if not no_backup:
			print('Backing up sites...')
			backup_all_sites(bench_path=bench_path)

		print('Patching sites...')
		patch_sites(bench_path=bench_path)
	if build:
		build_assets(bench_path=bench_path)
	if version_upgrade[0] or (not version_upgrade[0] and force):
		post_upgrade(version_upgrade[1], version_upgrade[2], bench_path=bench_path)
	if restart_supervisor or conf.get('restart_supervisor_on_update'):
		restart_supervisor_processes(bench_path=bench_path)
	if restart_systemd or conf.get('restart_systemd_on_update'):
		restart_systemd_processes(bench_path=bench_path)

	print("_"*80)
	print("Bench: Deployment tool for Frappe and ERPNext (https://erpnext.org).")
	print("Open source depends on your contributions, so please contribute bug reports, patches, fixes or cash and be a part of the community")
	print()
Пример #46
0
def setup_letsencrypt(site, bench_path):

	site_path = os.path.join(bench_path, "sites", site, "site_config.json")
	if not os.path.exists(os.path.dirname(site_path)):
		print "No site named "+site
		return

	click.confirm('Running this will stop the nginx service temporarily causing your sites to go offline\n'
		'Do you want to continue?',
		abort=True)

	if not get_config(bench_path).get("dns_multitenant"):
		print "You cannot setup SSL without DNS Multitenancy"
		return

	create_config(site)
	run_certbot_and_setup_ssl(site, bench_path)
	setup_crontab()
Пример #47
0
def _update(pull=False, patch=False, build=False, update_bench=False, auto=False, restart_supervisor=False, requirements=False, no_backup=False, upgrade=False, bench_path='.', force=False, reset=False):
	conf = get_config(bench_path=bench_path)
	version_upgrade = is_version_upgrade(bench_path=bench_path)

	if version_upgrade[0] and not upgrade:
		raise Exception("Major Version Upgrade")

	if upgrade and (version_upgrade[0] or (not version_upgrade[0] and force)):
		validate_upgrade(version_upgrade[1], version_upgrade[2], bench_path=bench_path)

	before_update(bench_path=bench_path, requirements=requirements)

	if pull:
		pull_all_apps(bench_path=bench_path, reset=reset)

	if requirements:
		print 'Updating Python libraries...'
		update_requirements(bench_path=bench_path)

	if upgrade and (version_upgrade[0] or (not version_upgrade[0] and force)):
		pre_upgrade(version_upgrade[1], version_upgrade[2], bench_path=bench_path)
		import bench.utils, bench.app
		print 'Reloading bench...'
		reload(bench.utils)
		reload(bench.app)

	if patch:
		if not no_backup:
			print 'Backing up sites...'
			backup_all_sites(bench_path=bench_path)

		print 'Patching sites...'
		patch_sites(bench_path=bench_path)
	if build:
		build_assets(bench_path=bench_path)
	if upgrade and (version_upgrade[0] or (not version_upgrade[0] and force)):
		post_upgrade(version_upgrade[1], version_upgrade[2], bench_path=bench_path)
	if restart_supervisor or conf.get('restart_supervisor_on_update'):
		restart_supervisor_processes(bench_path=bench_path)

	print "_"*80
	print "Bench: Deployment tool for Frappe and ERPNext (https://erpnext.org)."
	print "Open source depends on your contributions, so please contribute bug reports, patches, fixes or cash and be a part of the community"
	print
Пример #48
0
def make_nginx_conf(bench_path, yes=False):
	from bench import env
	from bench.config.common_site_config import get_config

	template = env.get_template('nginx.conf')
	bench_path = os.path.abspath(bench_path)
	sites_path = os.path.join(bench_path, "sites")

	config = get_config(bench_path)
	sites = prepare_sites(config, bench_path)
	bench_name = get_bench_name(bench_path)

	allow_rate_limiting = config.get('allow_rate_limiting', False)

	template_vars = {
		"sites_path": sites_path,
		"http_timeout": config.get("http_timeout"),
		"sites": sites,
		"webserver_port": config.get('webserver_port'),
		"socketio_port": config.get('socketio_port'),
		"bench_name": bench_name,
		"error_pages": get_error_pages(),
		"allow_rate_limiting": allow_rate_limiting,
		# for nginx map variable
		"random_string": "".join(random.choice(string.ascii_lowercase) for i in xrange(7))
	}

	if allow_rate_limiting:
		template_vars.update({
			'bench_name_hash': hashlib.sha256(bench_name).hexdigest()[:16],
			'limit_conn_shared_memory': get_limit_conn_shared_memory()
		})

	nginx_conf = template.render(**template_vars)

	conf_path = os.path.join(bench_path, "config", "nginx.conf")
	if not yes and os.path.exists(conf_path):
		click.confirm('nginx.conf already exists and this will overwrite it. Do you want to continue?',
			abort=True)

	with open(conf_path, "w") as f:
		f.write(nginx_conf)
Пример #49
0
def generate_supervisor_config(bench_path, user=None, yes=False):
	from bench.app import get_current_frappe_version, 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

	template = bench.env.get_template('supervisor.conf')
	if not user:
		user = getpass.getuser()

	config = get_config(bench_path=bench_path)

	bench_dir = os.path.abspath(bench_path)

	config = template.render(**{
		"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'),
		"node": find_executable('node') or find_executable('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'),
		"webserver_port": config.get('webserver_port', 8000),
		"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')
	})

	conf_path = os.path.join(bench_path, 'config', 'supervisor.conf')
	if not yes and os.path.exists(conf_path):
		click.confirm('supervisor.conf already exists and this will overwrite it. Do you want to continue?',
			abort=True)

	with open(conf_path, 'w') as f:
		f.write(config)

	update_config({'restart_supervisor_on_update': True}, bench_path=bench_path)
	update_config({'restart_systemd_on_update': False}, bench_path=bench_path)
Пример #50
0
def update(pull=False, patch=False, build=False, bench=False, auto=False, restart_supervisor=False, requirements=False, no_backup=False, upgrade=False, force=False):
	"Update bench"

	if not (pull or patch or build or bench or requirements):
		pull, patch, build, bench, requirements = True, True, True, True, True

	patches.run(bench_path='.')

	conf = get_config(".")

	version_upgrade = is_version_upgrade()

	if version_upgrade[0] and not upgrade:
		print
		print
		print "This update will cause a major version change in Frappe/ERPNext from {0} to {1}.".format(*version_upgrade[1:])
		print "This would take significant time to migrate and might break custom apps. Please run `bench update --upgrade` to confirm."
		print
		print "You can stay on the latest stable release by running `bench switch-to-master` or pin your bench to {0} by running `bench switch-to-v{0}`".format(version_upgrade[1])
		sys.exit(1)

	if conf.get('release_bench'):
		print 'Release bench, cannot update'
		sys.exit(1)

	if auto:
		sys.exit(1)

	if bench and conf.get('update_bench_on_update'):
		update_bench()
		restart_update({
				'pull': pull,
				'patch': patch,
				'build': build,
				'requirements': requirements,
				'no-backup': no_backup,
				'restart-supervisor': restart_supervisor,
				'upgrade': upgrade
		})

	_update(pull, patch, build, bench, auto, restart_supervisor, requirements, no_backup, upgrade, force=force)
Пример #51
0
def disable_production(bench_path='.'):
	bench_name = get_bench_name(bench_path)

	# supervisorctl
	supervisor_conf_extn = "ini" if is_centos7() else "conf"
	supervisor_conf = os.path.join(get_supervisor_confdir(), '{bench_name}.{extn}'.format(
		bench_name=bench_name, extn=supervisor_conf_extn))

	if os.path.islink(supervisor_conf):
		os.unlink(supervisor_conf)

	if get_config(bench_path).get('restart_supervisor_on_update'):
		reload_supervisor()

	# nginx
	nginx_conf = '/etc/nginx/conf.d/{bench_name}.conf'.format(bench_name=bench_name)

	if os.path.islink(nginx_conf):
		os.unlink(nginx_conf)

	reload_nginx()
Пример #52
0
def make_nginx_conf(bench_path):
	from bench import env
	from bench.config.common_site_config import get_config

	template = env.get_template('nginx.conf')
	bench_path = os.path.abspath(bench_path)
	sites_path = os.path.join(bench_path, "sites")

	config = get_config(bench_path)
	sites = prepare_sites(config, bench_path)

	nginx_conf = template.render(**{
		"sites_path": sites_path,
		"http_timeout": config.get("http_timeout"),
		"sites": sites,
		"webserver_port": config.get('webserver_port'),
		"socketio_port": config.get('socketio_port'),
		"bench_name": get_bench_name(bench_path)
	})

	with open(os.path.join(bench_path, "config", "nginx.conf"), "w") as f:
		f.write(nginx_conf)
Пример #53
0
def _update(pull=False, patch=False, build=False, bench=False, auto=False, restart_supervisor=False, requirements=False, no_backup=False, upgrade=False, bench_path='.', force=False):
	conf = get_config(bench=bench_path)
	version_upgrade = is_version_upgrade(bench=bench_path)

	if version_upgrade[0] and not upgrade:
		raise Exception("Major Version Upgrade")

	if upgrade and (version_upgrade[0] or (not version_upgrade[0] and force)):
		validate_upgrade(version_upgrade[1], version_upgrade[2], bench=bench_path)

	before_update(bench=bench_path, requirements=requirements)

	if pull:
		pull_all_apps(bench=bench_path)

	if requirements:
		update_requirements(bench=bench_path)

	if upgrade and (version_upgrade[0] or (not version_upgrade[0] and force)):
		pre_upgrade(version_upgrade[1], version_upgrade[2], bench=bench_path)
		import utils, app
		reload(utils)
		reload(app)

	if patch:
		if not no_backup:
			backup_all_sites(bench=bench_path)
		patch_sites(bench=bench_path)
	if build:
		build_assets(bench=bench_path)
	if upgrade and (version_upgrade[0] or (not version_upgrade[0] and force)):
		post_upgrade(version_upgrade[1], version_upgrade[2], bench=bench_path)
	if restart_supervisor or conf.get('restart_supervisor_on_update'):
		restart_supervisor_processes(bench=bench_path)

	print "_"*80
	print "Bench: Open source installer + admin for Frappe and ERPNext (https://erpnext.com)"
	print
Пример #54
0
def make_bench_manager_nginx_conf(bench_path, yes=False, port=23624, domain=None):
	from bench import env
	from bench.config.site_config import get_site_config
	from bench.config.common_site_config import get_config

	template = env.get_template('bench_manager_nginx.conf')
	bench_path = os.path.abspath(bench_path)
	sites_path = os.path.join(bench_path, "sites")

	config = get_config(bench_path)
	site_config = get_site_config(domain, bench_path=bench_path)
	sites = prepare_sites(config, bench_path)
	bench_name = get_bench_name(bench_path)

	template_vars = {
		"port": port,
		"domain": domain,
		"bench_manager_site_name": "bench-manager.local",
		"sites_path": sites_path,
		"http_timeout": config.get("http_timeout"),
		"webserver_port": config.get('webserver_port'),
		"socketio_port": config.get('socketio_port'),
		"bench_name": bench_name,
		"error_pages": get_error_pages(),
		"ssl_certificate": site_config.get('ssl_certificate'),
		"ssl_certificate_key": site_config.get('ssl_certificate_key')
	}

	bench_manager_nginx_conf = template.render(**template_vars)

	conf_path = os.path.join(bench_path, "config", "nginx.conf")

	if not yes and os.path.exists(conf_path):
		click.confirm('nginx.conf already exists and bench-manager configuration will be appended to it. Do you want to continue?',
			abort=True)

	with open(conf_path, "a") as myfile:
		myfile.write(bench_manager_nginx_conf)
Пример #55
0
def update(pull=False, patch=False, build=False, bench=False, auto=False, restart_supervisor=False, restart_systemd=False, requirements=False, no_backup=False, force=False, reset=False):
	"Update bench"

	if not (pull or patch or build or bench or requirements):
		pull, patch, build, bench, requirements = True, True, True, True, True

	if auto:
		sys.exit(1)

	patches.run(bench_path='.')
	conf = get_config(".")

	if bench and conf.get('update_bench_on_update'):
		update_bench()
		restart_update({
				'pull': pull,
				'patch': patch,
				'build': build,
				'requirements': requirements,
				'no-backup': no_backup,
				'restart-supervisor': restart_supervisor,
				'reset': reset
		})

	if conf.get('release_bench'):
		print('Release bench, cannot update')
		sys.exit(1)

	version_upgrade = is_version_upgrade()

	if version_upgrade[0]:
		print()
		print()
		print("This update will cause a major version change in Frappe/ERPNext from {0} to {1}.".format(*version_upgrade[1:]))
		print("This would take significant time to migrate and might break custom apps.")
		click.confirm('Do you want to continue?', abort=True)

	_update(pull, patch, build, bench, auto, restart_supervisor, restart_systemd, requirements, no_backup, force=force, reset=reset)
Пример #56
0
def generate_systemd_config(bench_path, user=None, yes=False,
	stop=False, create_symlinks=False,
	delete_symlinks=False):

	if not user:
		user = getpass.getuser()

	config = get_config(bench_path=bench_path)

	bench_dir = os.path.abspath(bench_path)
	bench_name = get_bench_name(bench_path)

	if stop:
		exec_cmd('sudo systemctl stop -- $(systemctl show -p Requires {bench_name}.target | cut -d= -f2)'.format(bench_name=bench_name))
		return

	if create_symlinks:
		_create_symlinks(bench_path)
		return

	if delete_symlinks:
		_delete_symlinks(bench_path)
		return

	number_of_workers = config.get('background_workers') or 1
	background_workers = []
	for i in range(number_of_workers):
		background_workers.append(get_bench_name(bench_path) + "-frappe-default-worker@" + str(i+1) + ".service")

	for i in range(number_of_workers):
		background_workers.append(get_bench_name(bench_path) + "-frappe-short-worker@" + str(i+1) + ".service")

	for i in range(number_of_workers):
		background_workers.append(get_bench_name(bench_path) + "-frappe-long-worker@" + str(i+1) + ".service")

	bench_info = {
		"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'),
		"node": find_executable('node') or find_executable('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'),
		"webserver_port": config.get('webserver_port', 8000),
		"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')
	}

	if not yes:
		click.confirm('current systemd configuration will be overwritten. Do you want to continue?',
			abort=True)

	setup_systemd_directory(bench_path)
	setup_main_config(bench_info, bench_path)
	setup_workers_config(bench_info, bench_path)
	setup_web_config(bench_info, bench_path)
	setup_redis_config(bench_info, bench_path)

	update_config({'restart_systemd_on_update': True}, bench_path=bench_path)
	update_config({'restart_supervisor_on_update': False}, bench_path=bench_path)
Пример #57
0
def migrate_env(python, no_backup = False):
	"""
	Migrate Virtual Environment to desired Python Version.
	"""
	try:
		# Clear Cache before Bench Dies.
		config = get_config(bench_path = os.getcwd())
		rredis = urlparse(config['redis_cache'])

		redis  = '{redis} -p {port}'.format(
			redis = which('redis-cli'),
			port  = rredis.port
		)

		log.debug('Clearing Redis Cache...')
		exec_cmd('{redis} FLUSHALL'.format(redis = redis))
		log.debug('Clearing Redis DataBase...')
		exec_cmd('{redis} FLUSHDB'.format(redis = redis))
	except Exception:
		log.warn('Please ensure Redis Connections are running or Daemonized.')

	try:
		# This is with the assumption that a bench is set-up within path.
		path       = os.getcwd()

		# I know, bad name for a flag. Thanks, Ameya! :| - <*****@*****.**>
		if not no_backup:
			# Back, the f*ck up.
			parch = osp.join(path, 'archived_envs')
			if not osp.exists(parch):
				os.mkdir(parch)

			# Simply moving. Thanks, Ameya.
			# I'm keen to zip.
			source = osp.join(path, 'env')
			target = parch

			log.debug('Backing up Virtual Environment')
			stamp  = datetime.now().strftime('%Y%m%d_%H%M%S')
			dest   = osp.join(path, str(stamp))

			# WARNING: This is an archive, you might have to use virtualenv --relocate
			# That's because virtualenv creates symlinks with shebangs pointing to executables.
			# shebangs, shebangs - ricky martin.

			# ...and shutil.copytree is a f*cking mess.
			os.rename(source, dest)
			shutil.move(dest, target)

		log.debug('Setting up a New Virtual {python} Environment'.format(
			python = python
		))

		# Path to Python Executable (Basically $PYTHONPTH)
		python     = which(python)


		virtualenv = which('virtualenv')

		nvenv      = 'env'
		pvenv      = osp.join(path, nvenv)

		exec_cmd('{virtualenv} --python {python} {pvenv}'.format(
			virtualenv = virtualenv,
			python     = python,
			pvenv      = pvenv
		), cwd = path)

		pip = osp.join(pvenv, 'bin', 'pip')
		# pip 10 seems to have a few problems associated with it, temporary freeze pip at 9.0.3 
		exec_cmd('{pip} install --upgrade pip==9.0.3'.format(pip=pip))
		exec_cmd('{pip} install --upgrade setuptools'.format(pip=pip))
		# TODO: Options

		papps  = osp.join(path, 'apps')
		apps   = ['frappe', 'erpnext'] + [app for app in os.listdir(papps) if app not in ['frappe', 'erpnext']]

		for app in apps:
			papp = osp.join(papps, app)
			if osp.isdir(papp) and osp.exists(osp.join(papp, 'setup.py')):
				exec_cmd('{pip} install -e {app}'.format(
					pip = pip, app = papp
				))

		log.debug('Migration Successful to {python}'.format(
			python = python
		))
	except:
		log.debug('Migration Error')
		raise