def restart(web, supervisor, systemd): "Restart supervisor processes or systemd units" from zinuit.utils import restart_supervisor_processes, restart_systemd_processes from zinuit.config.common_site_config import get_config if get_config('.').get('restart_supervisor_on_update') or supervisor: restart_supervisor_processes(zinuit_path='.', web_workers=web) if get_config('.').get('restart_systemd_on_update') or systemd: restart_systemd_processes(zinuit_path='.', web_workers=web)
def setup_letsencrypt(site, custom_domain, zinuit_path, interactive): site_path = os.path.join(zinuit_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, zinuit_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(zinuit_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, zinuit_path, interactive) setup_crontab()
def setup_production(user, zinuit_path='.', yes=False): if get_config(zinuit_path).get( 'restart_supervisor_on_update') and get_config(zinuit_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(zinuit_path).get('restart_systemd_on_update'): generate_systemd_config(zinuit_path=zinuit_path, user=user, yes=yes) else: generate_supervisor_config(zinuit_path=zinuit_path, user=user, yes=yes) make_nginx_conf(zinuit_path=zinuit_path, yes=yes) fix_prod_setup_perms(zinuit_path, metel_user=user) remove_default_nginx_configs() zinuit_name = get_zinuit_name(zinuit_path) nginx_conf = '/etc/nginx/conf.d/{zinuit_name}.conf'.format( zinuit_name=zinuit_name) if get_config(zinuit_path).get('restart_supervisor_on_update'): supervisor_conf_extn = "ini" if is_centos7() else "conf" supervisor_conf = os.path.join( get_supervisor_confdir(), '{zinuit_name}.{extn}'.format(zinuit_name=zinuit_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(zinuit_path, 'config', 'supervisor.conf')), supervisor_conf) if not os.path.islink(nginx_conf): os.symlink( os.path.abspath(os.path.join(zinuit_path, 'config', 'nginx.conf')), nginx_conf) if get_config(zinuit_path).get('restart_supervisor_on_update'): reload_supervisor() if os.environ.get('NO_SERVICE_RESTART'): return reload_nginx()
def remove_common_config(keys): from zinuit.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)
def change_uid(): if is_root() and not cmd_requires_root(): metel_user = get_config(".").get('metel_user') if metel_user: drop_privileges(uid_name=metel_user, gid_name=metel_user) os.environ['HOME'] = pwd.getpwnam(metel_user).pw_dir else: print('You should not run this command as root') sys.exit(1)
def setup_wildcard_ssl(domain, email, zinuit_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(zinuit_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(zinuit_path) print("Restrting Nginx service") service('nginx', 'restart')
def setup_procfile(zinuit_path, yes=False): config = get_config(zinuit_path=zinuit_path) procfile_path = os.path.join(zinuit_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 = zinuit.env.get_template('Procfile').render( node=find_executable("node") or find_executable("nodejs"), use_rq=use_rq(zinuit_path), webserver_port=config.get('webserver_port'), CI=os.environ.get('CI')) with open(procfile_path, 'w') as f: f.write(procfile)
def setup_manager(yes=False, port=23624, domain=None): "Setup zinuit-manager.local site with the zinmanager app installed on it" from six.moves import input create_new_site = True if 'zinuit-manager.local' in os.listdir('sites'): ans = input( 'Site already exists. Overwrite existing site? [Y/n]: ').lower() while ans not in ('y', 'n', ''): ans = input( 'Please enter "y" or "n". Site already exists. Overwrite existing site? [Y/n]: ' ).lower() if ans == 'n': create_new_site = False if create_new_site: exec_cmd("zinuit new-site --force zinuit-manager.local") if 'zinmanager' in os.listdir('apps'): print('App already exists. Skipping app download.') else: exec_cmd("zinuit get-app zinmanager") exec_cmd("zinuit --site zinuit-manager.local install-app zinmanager") from zinuit.config.common_site_config import get_config zinuit_path = '.' conf = get_config(zinuit_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 zinuit-manager using the 'domain' flag" ) sys.exit(1) from zinuit.utils import get_sites, get_zinuit_name zinuit_name = get_zinuit_name(zinuit_path) if domain not in get_sites(zinuit_path): raise Exception("No such site") from zinuit.config.nginx import make_zinmanager_nginx_conf make_zinmanager_nginx_conf(zinuit_path, yes=yes, port=port, domain=domain)
def disable_production(zinuit_path='.'): zinuit_name = get_zinuit_name(zinuit_path) # supervisorctl supervisor_conf_extn = "ini" if is_centos7() else "conf" supervisor_conf = os.path.join( get_supervisor_confdir(), '{zinuit_name}.{extn}'.format(zinuit_name=zinuit_name, extn=supervisor_conf_extn)) if os.path.islink(supervisor_conf): os.unlink(supervisor_conf) if get_config(zinuit_path).get('restart_supervisor_on_update'): reload_supervisor() # nginx nginx_conf = '/etc/nginx/conf.d/{zinuit_name}.conf'.format( zinuit_name=zinuit_name) if os.path.islink(nginx_conf): os.unlink(nginx_conf) reload_nginx()
def generate_supervisor_config(zinuit_path, user=None, yes=False): from zinuit.app import get_current_metel_version, use_rq from zinuit.utils import get_zinuit_name, find_executable from zinuit.config.common_site_config import get_config, update_config, get_gunicorn_workers template = zinuit.env.get_template('supervisor.conf') if not user: user = getpass.getuser() config = get_config(zinuit_path=zinuit_path) zinuit_dir = os.path.abspath(zinuit_path) config = template.render( **{ "zinuit_dir": zinuit_dir, "sites_dir": os.path.join(zinuit_dir, 'sites'), "user": user, "metel_version": get_current_metel_version(zinuit_path), "use_rq": use_rq(zinuit_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(zinuit_dir, 'config', 'redis_cache.conf'), "redis_socketio_config": os.path.join(zinuit_dir, 'config', 'redis_socketio.conf'), "redis_queue_config": os.path.join(zinuit_dir, 'config', 'redis_queue.conf'), "webserver_port": config.get('webserver_port', 8000), "gunicorn_workers": config.get('gunicorn_workers', get_gunicorn_workers()["gunicorn_workers"]), "zinuit_name": get_zinuit_name(zinuit_path), "background_workers": config.get('background_workers') or 1, "zinuit_cmd": find_executable('zinuit') }) conf_path = os.path.join(zinuit_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}, zinuit_path=zinuit_path) update_config({'restart_systemd_on_update': False}, zinuit_path=zinuit_path)
def generate_systemd_config(zinuit_path, user=None, yes=False, stop=False, create_symlinks=False, delete_symlinks=False): if not user: user = getpass.getuser() config = get_config(zinuit_path=zinuit_path) zinuit_dir = os.path.abspath(zinuit_path) zinuit_name = get_zinuit_name(zinuit_path) if stop: exec_cmd( 'sudo systemctl stop -- $(systemctl show -p Requires {zinuit_name}.target | cut -d= -f2)' .format(zinuit_name=zinuit_name)) return if create_symlinks: _create_symlinks(zinuit_path) return if delete_symlinks: _delete_symlinks(zinuit_path) return number_of_workers = config.get('background_workers') or 1 background_workers = [] for i in range(number_of_workers): background_workers.append( get_zinuit_name(zinuit_path) + "-metel-default-worker@" + str(i + 1) + ".service") for i in range(number_of_workers): background_workers.append( get_zinuit_name(zinuit_path) + "-metel-short-worker@" + str(i + 1) + ".service") for i in range(number_of_workers): background_workers.append( get_zinuit_name(zinuit_path) + "-metel-long-worker@" + str(i + 1) + ".service") zinuit_info = { "zinuit_dir": zinuit_dir, "sites_dir": os.path.join(zinuit_dir, 'sites'), "user": user, "metel_version": get_current_metel_version(zinuit_path), "use_rq": use_rq(zinuit_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(zinuit_dir, 'config', 'redis_cache.conf'), "redis_socketio_config": os.path.join(zinuit_dir, 'config', 'redis_socketio.conf'), "redis_queue_config": os.path.join(zinuit_dir, 'config', 'redis_queue.conf'), "webserver_port": config.get('webserver_port', 8000), "gunicorn_workers": config.get('gunicorn_workers', get_gunicorn_workers()["gunicorn_workers"]), "zinuit_name": get_zinuit_name(zinuit_path), "worker_target_wants": " ".join(background_workers), "zinuit_cmd": find_executable('zinuit') } if not yes: click.confirm( 'current systemd configuration will be overwritten. Do you want to continue?', abort=True) setup_systemd_directory(zinuit_path) setup_main_config(zinuit_info, zinuit_path) setup_workers_config(zinuit_info, zinuit_path) setup_web_config(zinuit_info, zinuit_path) setup_redis_config(zinuit_info, zinuit_path) update_config({'restart_systemd_on_update': True}, zinuit_path=zinuit_path) update_config({'restart_supervisor_on_update': False}, zinuit_path=zinuit_path)
def update(pull=False, patch=False, build=False, zinuit=False, auto=False, restart_supervisor=False, restart_systemd=False, requirements=False, no_backup=False, force=False, reset=False): "Update zinuit" if not (pull or patch or build or zinuit or requirements): pull, patch, build, zinuit, requirements = True, True, True, True, True if auto: sys.exit(1) patches.run(zinuit_path='.') conf = get_config(".") if zinuit and conf.get('update_zinuit_on_update'): update_zinuit() restart_update({ 'pull': pull, 'patch': patch, 'build': build, 'requirements': requirements, 'no-backup': no_backup, 'restart-supervisor': restart_supervisor, 'reset': reset }) if conf.get('release_zinuit'): print('Release zinuit, 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 Metel/Redapple 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, zinuit, auto, restart_supervisor, restart_systemd, requirements, no_backup, force=force, reset=reset)
def _update(pull=False, patch=False, build=False, update_zinuit=False, auto=False, restart_supervisor=False, restart_systemd=False, requirements=False, no_backup=False, zinuit_path='.', force=False, reset=False): conf = get_config(zinuit_path=zinuit_path) version_upgrade = is_version_upgrade(zinuit_path=zinuit_path) if version_upgrade[0] or (not version_upgrade[0] and force): validate_upgrade(version_upgrade[1], version_upgrade[2], zinuit_path=zinuit_path) before_update(zinuit_path=zinuit_path, requirements=requirements) if pull: pull_all_apps(zinuit_path=zinuit_path, reset=reset) if requirements: update_requirements(zinuit_path=zinuit_path) update_node_packages(zinuit_path=zinuit_path) if version_upgrade[0] or (not version_upgrade[0] and force): pre_upgrade(version_upgrade[1], version_upgrade[2], zinuit_path=zinuit_path) import zinuit.utils, zinuit.app print('Reloading zinuit...') if sys.version_info >= (0, 1): import importlib importlib.reload(zinuit.utils) importlib.reload(zinuit.app) else: reload(zinuit.utils) reload(zinuit.app) if patch: if not no_backup: print('Backing up sites...') backup_all_sites(zinuit_path=zinuit_path) print('Patching sites...') patch_sites(zinuit_path=zinuit_path) if build: build_assets(zinuit_path=zinuit_path) if version_upgrade[0] or (not version_upgrade[0] and force): post_upgrade(version_upgrade[1], version_upgrade[2], zinuit_path=zinuit_path) if restart_supervisor or conf.get('restart_supervisor_on_update'): restart_supervisor_processes(zinuit_path=zinuit_path) if restart_systemd or conf.get('restart_systemd_on_update'): restart_systemd_processes(zinuit_path=zinuit_path) print("_" * 80) print( "Zinuit: Deployment tool for Metel and Redapple (https://alphamonak.com)." ) print()
def migrate_env(python, no_backup=False): """ Migrate Virtual Environment to desired Python Version. """ try: # Clear Cache before Zinuit Dies. config = get_config(zinuit_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 zinuit is set-up within path. path = os.getcwd() # I know, bad name for a flag. Thanks, Ameya! :| - <Administrator> 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') exec_cmd('{pip} install --upgrade pip'.format(pip=pip)) exec_cmd('{pip} install --upgrade setuptools'.format(pip=pip)) # TODO: Options papps = osp.join(path, 'apps') apps = ['metel', 'redapple'] + [ app for app in os.listdir(papps) if app not in ['metel', 'redapple'] ] 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