def locales(names): """ Require the list of locales to be available. Raises UnsupportedLocales if some of the required locales are not supported. """ family = distrib_family() if family == 'debian': command = 'dpkg-reconfigure --frontend=noninteractive locales' if distrib_id() == 'Ubuntu': config_file = '/var/lib/locales/supported.d/local' if not is_file(config_file): run_as_root('touch %s' % config_file) else: config_file = '/etc/locale.gen' _locales_generic(names, config_file=config_file, command=command) elif family in ['arch', 'gentoo']: _locales_generic(names, config_file='/etc/locale.gen', command='locale-gen') elif distrib_family() == 'redhat': _locales_redhat(names) else: raise UnsupportedFamily( supported=['debian', 'arch', 'gentoo', 'redhat'])
def command(): """ Require the git command-line tool. Example:: from fabric.api import run from fabtools import require require.git.command() run('git --help') """ from fabtools.require.deb import package as require_deb_package from fabtools.require.rpm import package as require_rpm_package from fabtools.system import distrib_family res = run('git --version', quiet=True) if res.failed: family = distrib_family() if family == 'debian': require_deb_package('git-core') elif family == 'redhat': require_rpm_package('git') else: raise NotImplementedError()
def setuptools(version=MIN_SETUPTOOLS_VERSION, python_cmd='python'): """ Require `setuptools`_ to be installed. If setuptools is not installed, or if a version older than *version* is installed, the latest version will be installed. .. _setuptools: http://pythonhosted.org/setuptools/ """ from fabtools.require.deb import packages as require_deb_packages from fabtools.require.rpm import packages as require_rpm_packages if not is_setuptools_installed(python_cmd=python_cmd): family = distrib_family() if family == 'debian': require_deb_packages([ 'curl', 'python-dev', ]) elif family == 'redhat': require_rpm_packages([ 'curl', 'python-devel', ]) install_setuptools(python_cmd=python_cmd)
def setuptools(version=MIN_SETUPTOOLS_VERSION, python_cmd='python'): """ Require `setuptools`_ to be installed. If setuptools is not installed, or if a version older than *version* is installed, the latest version will be installed. .. _setuptools: http://pythonhosted.org/setuptools/ """ from fabtools.require.deb import package as require_deb_package from fabtools.require.rpm import package as require_rpm_package if not is_setuptools_installed(python_cmd=python_cmd): family = distrib_family() if family == 'debian': require_deb_package('python-dev') elif family == 'redhat': require_rpm_package('python-devel') elif family == 'arch': pass # ArchLinux installs header with base package else: raise UnsupportedFamily(supported=['debian', 'redhat', 'arch']) install_setuptools(python_cmd=python_cmd)
def is_running(service): """ Check if a service is running. :: import fabtools if fabtools.service.is_running('foo'): print "Service foo is running!" """ with settings(hide('running', 'stdout', 'stderr', 'warnings'), warn_only=True): if using_systemd(): return systemd.is_running(service) else: if distrib_family() != "gentoo": test_upstart = run_as_root('test -f /etc/init/%s.conf' % service) status = _service(service, 'status') if test_upstart.succeeded: return 'running' in status else: return status.succeeded else: # gentoo status = _service(service, 'status') return ' started' in status
def install(java_version=None): """ Install dependencies (curl and unzip) and Install GVM :: import fabtools # Install GVM fabtools.gvm.install() """ res = run('gvm help', quiet=True) if res.failed: family = distrib_family() packages = ['curl', 'unzip'] if family == 'debian': require_deb_packages(packages) elif family == 'redhat': require_rpm_packages(packages) elif family == 'sun': require_pkg_packages(packages) else: raise UnsupportedFamily(supported=['debian', 'redhat', 'sun']) if java_version is None: java() else: java(version=java_version) run('curl -s get.gvmtool.net | bash') user = run('whoami') run('source "/home/%s/.gvm/bin/gvm-init.sh"' % user) configFile = "/home/%s/.gvm/etc/config" % user sed(configFile, 'gvm_auto_answer=false', 'gvm_auto_answer=true')
def command(): """ Require the git command-line tool. Example:: from fabric.api import run from fabtools import require require.git.command() run('git --help') """ from fabtools.require.deb import package as require_deb_package from fabtools.require.pkg import package as require_pkg_package from fabtools.require.rpm import package as require_rpm_package from fabtools.require.portage import package as require_portage_package res = run('git --version', quiet=True) if res.failed: family = distrib_family() if family == 'debian': require_deb_package('git-core') elif family == 'redhat': require_rpm_package('git') elif family == 'sun': require_pkg_package('scmgit-base') elif family == 'gentoo': require_portage_package('dev-vcs/git') else: raise UnsupportedFamily( supported=['debian', 'redhat', 'sun', 'gentoo'])
def command(): """ Require the git command-line tool. Example:: from fabric.api import run from fabtools import require require.git.command() run('git --help') """ from fabtools.require.deb import package as require_deb_package from fabtools.require.pkg import package as require_pkg_package from fabtools.require.rpm import package as require_rpm_package from fabtools.system import distrib_family res = run('git --version', quiet=True) if res.failed: family = distrib_family() if family == 'debian': require_deb_package('git-core') elif family == 'redhat': require_rpm_package('git') elif family == 'sun': require_pkg_package('scmgit-base') else: raise NotImplementedError()
def distribute(use_python='python'): """ Require `distribute`_ to be installed. .. _distribute: http://packages.python.org/distribute/ """ from fabtools.require.deb import packages as require_deb_packages from fabtools.require.rpm import packages as require_rpm_packages family = distrib_family() if family == 'debian': require_deb_packages([ 'curl', 'python-dev', ]) elif family == 'redhat': require_rpm_packages([ 'curl', 'python-devel', ]) if not is_distribute_installed(use_python=use_python): install_distribute(use_python=use_python)
def command(): """ Require the ``hg`` command-line tool. Example:: from fabric.api import run from fabtools import require require.mercurial.command() run('hg --help') """ from fabtools.require.deb import package as require_deb_package from fabtools.require.rpm import package as require_rpm_package from fabtools.require.portage import package as require_portage_package res = run('hg --version', quiet=True) if res.failed: family = distrib_family() if family == 'debian': require_deb_package('mercurial') elif family == 'gentoo': require_portage_package('mercurial') elif family == 'redhat': require_rpm_package('mercurial') else: raise UnsupportedFamily(supported=['debian', 'redhat', 'gentoo'])
def setup_container(name, template, ipadd): from fabtools import require from fabtools.require.openvz import container from fabtools.system import distrib_family import fabtools if distrib_family() == 'debian': require.deb.package('vzctl') require.openvz.template(template) with container(name, template, hostname=name, ipadd=ipadd) as ct: # Make sure the container is started if not ct.running(): ct.start() # Set up name servers NAMESERVERS = fabtools.network.nameservers() ct.set(nameserver=NAMESERVERS) # Wait until we can ping the container from the host with settings(warn_only=True): timeout = 0 while True: if run('ping -c 1 %s' % ipadd).succeeded: break time.sleep(1) timeout += 1 assert timeout < 10, "Timeout trying to ping container"
def git_require(): """ Test high level git tools. These tests should also cover the low level tools as all of them are called indirectly. """ from fabric.api import cd, sudo from fabtools import require from fabtools.system import distrib_family family = distrib_family() if family == "debian": require.deb.package("git-core") elif family == "redhat": require.rpm.package("git") with cd("/tmp"): # Clean up sudo("rm -rf *") git_require_remote_url() git_require_remote_url_and_path() git_require_no_update() git_require_branch() git_require_sudo() git_require_sudo_user()
def locales(names): """ Require the list of locales to be available. """ if distrib_id() == "Ubuntu": config_file = '/var/lib/locales/supported.d/local' if not is_file(config_file): run_as_root('touch %s' % config_file) else: config_file = '/etc/locale.gen' # Regenerate locales if config file changes with watch(config_file, use_sudo=True) as config: # Add valid locale names to the config file supported = dict(supported_locales()) for name in names: if name in supported: charset = supported[name] locale = "%s %s" % (name, charset) uncomment(config_file, escape(locale), use_sudo=True, shell=True) append(config_file, locale, use_sudo=True, partial=True, shell=True) else: warn('Unsupported locale name "%s"' % name) if config.changed: family = distrib_family() if family == 'debian': run_as_root('dpkg-reconfigure --frontend=noninteractive locales') elif family in ['arch', 'gentoo']: run_as_root('locale-gen') else: raise UnsupportedFamily(supported=['debian', 'arch', 'gentoo'])
def git_require(): """ Test high level git tools. These tests should also cover the low level tools as all of them are called indirectly. """ from fabric.api import cd, sudo from fabtools import require from fabtools.system import distrib_family family = distrib_family() if family == 'debian': require.deb.package('git-core') elif family == 'redhat': require.rpm.package('git') with cd('/tmp'): # Clean up sudo('rm -rf *') git_require_remote_url() git_require_remote_url_and_path() git_require_no_update() git_require_branch() git_require_sudo() git_require_sudo_user()
def command(): """ Require the git command-line tool. Example:: from fabric.api import run from fabtools import require require.git.command() run('git --help') """ from fabtools.require.deb import package as require_deb_package from fabtools.require.pkg import package as require_pkg_package from fabtools.require.rpm import package as require_rpm_package from fabtools.require.portage import package as require_portage_package res = run('git --version', quiet=True) if res.failed: family = distrib_family() if family == 'debian': require_deb_package('git-core') elif family == 'redhat': require_rpm_package('git') elif family == 'sun': require_pkg_package('scmgit-base') elif family == 'gentoo': require_portage_package('dev-vcs/git') else: raise UnsupportedFamily(supported=['debian', 'redhat', 'sun', 'gentoo'])
def command(): """ Require the curl command-line tool. Example:: from fabric.api import run from fabtools import require require.curl.command() run('curl --help') """ from fabtools.require.deb import package as require_deb_package from fabtools.require.rpm import package as require_rpm_package family = distrib_family() if family == 'debian': require_deb_package('curl') elif family == 'redhat': require_rpm_package('curl') else: raise UnsupportedFamily(supported=['debian', 'redhat'])
def command(): """ Require the ``bzr`` command-line tool. Example:: from fabric.api import run from fabtools import require require.bazaar.command() run('bzr --help') """ from fabtools.require.deb import package as require_deb_package from fabtools.require.rpm import package as require_rpm_package from fabtools.require.portage import package as require_portage_package from fabtools.system import distrib_family res = run('bzr --version', quiet=True) if res.failed: family = distrib_family() if family == 'debian': require_deb_package('bzr') elif family == 'gentoo': require_portage_package('bzr') elif family == 'redhat': require_rpm_package('bzr') else: raise UnsupportedFamily(supported=['debian', 'redhat', 'gentoo'])
def distribute(): """ Require `distribute`_ to be installed. .. _distribute: http://packages.python.org/distribute/ """ from fabtools.require.deb import packages as require_deb_packages from fabtools.require.rpm import packages as require_rpm_packages family = distrib_family() if family == 'debian': require_deb_packages([ 'curl', 'python-dev', ]) elif family == 'redhat': require_rpm_packages([ 'curl', 'python-devel', ]) if not is_distribute_installed(): install_distribute()
def core(): """ Require the docker core installation. Example:: from fabtools import require require.docker.core() """ from fabtools.require.deb import package as require_deb_package from fabtools.require.rpm import package as require_rpm_package family = distrib_family() # Check if sudo command exists if not files.exists('/usr/bin/sudo'): raise Exception("Please install the sudo package and execute adduser %s sudo" % env.user) if not files.exists('/usr/bin/docker'): if family == 'debian': require_deb_package('curl') elif family == 'redhat': require_rpm_package('curl') else: raise UnsupportedFamily(supported=['debian', 'redhat']) # Download docker installation run_as_root('curl -sSL https://get.docker.com/ | sh')
def _choose(old_style, new_style): family = distrib_family() if family == 'debian': distrib = distrib_id() at_least_trusty = (distrib == 'Ubuntu' and V(distrib_release()) >= V('14.04')) at_least_jessie = (distrib == 'Debian' and V(distrib_release()) >= V('8.0')) if at_least_trusty or at_least_jessie: return new_style else: return old_style else: raise UnsupportedFamily(supported=['debian'])
def _service(service, action): """ Compatibility layer for distros that use ``service`` and those that don't. """ if distrib_family() != "gentoo": status = run_as_root('service %(service)s %(action)s' % locals(), pty=False) else: # gentoo status = run_as_root('/etc/init.d/%(service)s %(action)s' % locals(), pty=False) return status
def locales(names): """ Require the list of locales to be available. Raises UnsupportedLocales if some of the required locales are not supported. """ family = distrib_family() if family == 'debian': command = 'dpkg-reconfigure --frontend=noninteractive locales' config_file = '/etc/locale.gen' _locales_generic(names, config_file=config_file, command=command) elif family in ['arch', 'gentoo']: _locales_generic(names, config_file='/etc/locale.gen', command='locale-gen') elif distrib_family() == 'redhat': _locales_redhat(names) else: raise UnsupportedFamily( supported=['debian', 'arch', 'gentoo', 'redhat'])
def install_from_source(version=DEFAULT_VERSION): """ Install Node JS from source. :: import fabtools # Install Node.js fabtools.nodejs.install_nodejs() .. note:: This function may not work for old versions of Node.js. """ from fabtools.require.deb import packages as require_deb_packages from fabtools.require.rpm import packages as require_rpm_packages from fabtools.require import file as require_file family = distrib_family() if family == 'debian': require_deb_packages([ 'build-essential', 'libssl-dev', 'python', ]) elif family == 'redhat': require_rpm_packages([ 'gcc', 'gcc-c++', 'make', 'openssl-devel', 'python', ]) filename = 'node-v%s.tar.gz' % version foldername = filename[0:-7] require_file(url='http://nodejs.org/dist/v%(version)s/%(filename)s' % { 'version': version, 'filename': filename, }) run('tar -xzf %s' % filename) with cd(foldername): run('./configure') run('make -j%d' % (cpus() + 1)) run_as_root('make install') run('rm -rf %(filename)s %(foldername)s' % locals())
def installed_from_source(version=VERSION): """ Require Redis to be installed from source. The compiled binaries will be installed in ``/opt/redis-{version}/``. """ from fabtools.require import directory as require_directory from fabtools.require import file as require_file from fabtools.require import user as require_user from fabtools.require.deb import packages as require_deb_packages from fabtools.require.rpm import packages as require_rpm_packages family = distrib_family() if family == 'debian': require_deb_packages([ 'build-essential', ]) elif family == 'redhat': require_rpm_packages([ 'gcc', 'make', ]) require_user('redis', home='/var/lib/redis', system=True) require_directory('/var/lib/redis', owner='redis', use_sudo=True) dest_dir = '/opt/redis-%(version)s' % locals() require_directory(dest_dir, use_sudo=True, owner='redis') if not is_file('%(dest_dir)s/redis-server' % locals()): with cd('/tmp'): # Download and unpack the tarball tarball = 'redis-%(version)s.tar.gz' % locals() url = _download_url(version) + tarball require_file(tarball, url=url) run('tar xzf %(tarball)s' % locals()) # Compile and install binaries with cd('redis-%(version)s' % locals()): run('make') for filename in BINARIES: run_as_root( 'cp -pf src/%(filename)s %(dest_dir)s/' % locals()) run_as_root( 'chown redis: %(dest_dir)s/%(filename)s' % locals())
def _service_name(version=None): if distrib_family() == "arch": if is_file('/usr/bin/postgres'): return 'postgresql' else: if is_file('/etc/init.d/postgresql'): return 'postgresql' if version and is_file('/etc/init.d/postgresql-%s' % version): return 'postgresql-%s' % version with cd('/etc/init.d'): with settings(hide('running', 'stdout')): return run('ls postgresql-*').splitlines()[0]
def default_locale(name): """ Require the locale to be the default. """ from fabtools.require import file as require_file # Ensure the locale is available locale(name) # Make it the default contents = 'LANG="%s"\n' % name if distrib_family() == 'arch': config_file = '/etc/locale.conf' else: config_file = '/etc/default/locale' require_file(config_file, contents, use_sudo=True)
def server(version=None): """ Require a PostgreSQL server to be installed and running. :: from fabtools import require require.postgres.server() """ family = distrib_family() if family == 'debian': _server_debian(version) else: raise UnsupportedFamily(supported=['debian'])
def server(): """ Require the Apache HTTP server to be installed and running. :: from fabtools import require require.apache.server() """ family = distrib_family() if family == 'debian': _server_debian() else: raise UnsupportedFamily(supported=['debian'])
def server(version=None): """ Require a PostgreSQL server to be installed and running. :: from fabtools import require require.postgres.server() """ family = distrib_family() if family == "debian": _server_debian(version) else: raise UnsupportedFamily(supported=["debian"])
def timezone(timezone): ''' ''' family = distrib_family() if family == 'debian': with settings(hide('commands'), warn_only=True): result = run('grep -q "^%s$" /etc/timezone' % timezone) ret_code = result.return_code if ret_code == 0: return elif ret_code == 1: set_timezone(timezone) else: raise SystemExit() else: raise NotImplementedError('timezone is not implemented for "%(family)s"' % locals())
def firewall(zones=None, interfaces=None, policy=None, rules=None, routestopped=None, masq=None): """ Ensure that a firewall is configured. Example:: from fabtools.shorewall import * from fabtools import require # We need a firewall with some custom rules require.shorewall.firewall( rules=[ Ping(), SSH(), HTTP(), HTTPS(), SMTP(), rule(port=1234, source=hosts(['example.com'])), ] ) """ family = distrib_family() if family != 'debian': raise UnsupportedFamily(supported=['debian']) require_deb_package('shorewall') with watch(CONFIG_FILES) as config: _zone_config(zones) _interfaces_config(interfaces) _policy_config(policy) _rules_config(rules) _routestopped_config(routestopped) _masq_config(masq) if config.changed: puts("Shorewall configuration changed") if is_started(): restart('shorewall') with settings(hide('running'), shell_env()): sed('/etc/default/shorewall', 'startup=0', 'startup=1', use_sudo=True)
def server(version=None, password=None): """ Require a MySQL server to be installed and running. Example:: from fabtools import require require.mysql.server(password='******') """ family = distrib_family() if family == 'debian': _server_debian(version, password) elif family == 'redhat': _server_redhat(version, password) else: raise UnsupportedFamily(supported=['debian', 'redhat'])
def timezone(timezone): ''' ''' family = distrib_family() if family == 'debian': with settings(hide('commands'), warn_only=True): result = run('grep -q "^%s$" /etc/timezone' % timezone) ret_code = result.return_code if ret_code == 0: return elif ret_code == 1: set_timezone(timezone) else: raise SystemExit() else: raise NotImplementedError( 'timezone is not implemented for "%(family)s"' % locals())
def firewall(zones=None, interfaces=None, policy=None, rules=None, routestopped=None, masq=None): """ Ensure that a firewall is configured. Example:: from fabtools.shorewall import * from fabtools import require # We need a firewall with some custom rules require.shorewall.firewall( rules=[ Ping(), SSH(), HTTP(), HTTPS(), SMTP(), rule(port=1234, source=hosts(['example.com'])), ] ) """ family = distrib_family() if family != "debian": raise UnsupportedFamily(supported=["debian"]) require_deb_package("shorewall") with watch(CONFIG_FILES) as config: _zone_config(zones) _interfaces_config(interfaces) _policy_config(policy) _rules_config(rules) _routestopped_config(routestopped) _masq_config(masq) if config.changed: puts("Shorewall configuration changed") if is_started(): restart("shorewall") with settings(hide("running"), shell_env()): sed("/etc/default/shorewall", "startup=0", "startup=1", use_sudo=True)
def installed_from_source(version=VERSION): """ Require Redis to be installed from source. The compiled binaries will be installed in ``/opt/redis-{version}/``. """ from fabtools.require import directory as require_directory from fabtools.require import file as require_file from fabtools.require import user as require_user from fabtools.require.deb import packages as require_deb_packages from fabtools.require.rpm import packages as require_rpm_packages family = distrib_family() if family == "debian": require_deb_packages(["build-essential"]) elif family == "redhat": require_rpm_packages(["gcc", "make"]) require_user("redis", home="/var/lib/redis", system=True) require_directory("/var/lib/redis", owner="redis", use_sudo=True) dest_dir = "/opt/redis-%(version)s" % locals() require_directory(dest_dir, use_sudo=True, owner="redis") if not is_file("%(dest_dir)s/redis-server" % locals()): with cd("/tmp"): # Download and unpack the tarball tarball = "redis-%(version)s.tar.gz" % locals() url = _download_url(version) + tarball require_file(tarball, url=url) run("tar xzf %(tarball)s" % locals()) # Compile and install binaries with cd("redis-%(version)s" % locals()): run("make") for filename in BINARIES: run_as_root("cp -pf src/%(filename)s %(dest_dir)s/" % locals()) run_as_root("chown redis: %(dest_dir)s/%(filename)s" % locals())
def server(package_name='nginx'): """ Require the nginx web server to be installed and running. You can override the system package name, if you need to install a specific variant such as `nginx-extras` or `nginx-light`. :: from fabtools import require require.nginx.server() """ family = distrib_family() if family == 'debian': _server_debian(package_name) else: raise UnsupportedFamily(supported=['debian'])
def sysctl(key, value, persist=True): """ Require a kernel parameter to have a specific value. """ if get_sysctl(key) != value: set_sysctl(key, value) if persist: from fabtools.require import file as require_file filename = '/etc/sysctl.d/60-%s.conf' % key with watch(filename, use_sudo=True) as config: require_file(filename, contents='%(key)s = %(value)s\n' % locals(), use_sudo=True) if config.changed: if distrib_family() == 'debian': run_as_root('service procps start')
def query(query, use_sudo=True, **kwargs): """ Run a MySQL query. """ family = distrib_family() if family == 'debian': from fabtools.deb import install, is_installed elif family == 'redhat': from fabtools.rpm import install, is_installed else: raise UnsupportedFamily(supported=['debian', 'redhat']) func = use_sudo and run_as_root or run user = kwargs.get('mysql_user') or env.get('mysql_user') password = kwargs.get('mysql_password') or env.get('mysql_password') func_mysql = 'mysql' mysql_host = kwargs.get('mysql_host') or env.get('mysql_host') options = [ '--batch', '--raw', '--skip-column-names', ] if user: options.append('--user=%s' % quote(user)) if password: if not is_installed('sshpass'): install('sshpass') func_mysql = 'sshpass -p %(password)s mysql' % { 'password': quote(password) } options.append('--password') if mysql_host: options.append('--host=%s' % quote(mysql_host)) options = ' '.join(options) return func('%(cmd)s %(options)s --execute=%(query)s' % { 'cmd': func_mysql, 'options': options, 'query': quote(query), })
def query(query, use_sudo=True, **kwargs): """ Run a MySQL query. """ family = distrib_family() if family == 'debian': from fabtools.deb import install, is_installed elif family == 'redhat': from fabtools.rpm import install, is_installed else: raise UnsupportedFamily(supported=['debian', 'redhat']) func = use_sudo and run_as_root or run user = kwargs.get('mysql_user') or env.get('mysql_user') password = kwargs.get('mysql_password') or env.get('mysql_password') func_mysql = 'mysql' mysql_host = kwargs.get('mysql_host') or env.get('mysql_host') options = [ '--batch', '--raw', '--skip-column-names', ] if user: options.append('--user=%s' % quote(user)) if password: if not is_installed('sshpass'): install('sshpass') func_mysql = 'sshpass -p %(password)s mysql' % {'password': password} options.append('--password') options.append('--password=%s' % quote(password)) if mysql_host: options.append('--host=%s' % quote(mysql_host)) options = ' '.join(options) return func('%(cmd)s %(options)s --execute=%(query)s' % { 'cmd': func_mysql, 'options': options, 'query': quote(query), })
def server(version=None): """ Require a PostgreSQL server to be installed and running. :: from fabtools import require require.postgres.server() """ if distrib_family() == "arch": pkg_name = 'postgresql' arch.package(pkg_name) init_postgres() else: if version: pkg_name = 'postgresql-%s' % version else: pkg_name = 'postgresql' package(pkg_name) started(_service_name(version))
def server(package_name='nginx'): """ Require the nginx web server to be installed and running. You can override the system package name, if you need to install a specific variant such as `nginx-extras` or `nginx-light`. :: from fabtools import require require.nginx.server() """ family = distrib_family() if family == 'debian': require_deb_package(package_name) elif family == 'redhat': require_rpm_package(package_name) elif distrib_id() is 'Archlinux': require_arch_package(package_name) require_started('nginx')
def process(name, **kwargs): """ Require a supervisor process to be running. Keyword arguments will be used to build the program configuration file. Some useful arguments are: - ``command``: complete command including arguments (**required**) - ``directory``: absolute path to the working directory - ``user``: run the process as this user - ``stdout_logfile``: absolute path to the log file You should refer to the `supervisor documentation`_ for the complete list of allowed arguments. .. note:: the default values for the following arguments differs from the ``supervisor`` defaults: - ``autorestart``: defaults to ``true`` - ``redirect_stderr``: defaults to ``true`` Example:: from fabtools import require require.supervisor.process('myapp', command='/path/to/venv/bin/myapp --config production.ini --someflag', directory='/path/to/working/dir', user='******', stdout_logfile='/path/to/logs/myapp.log', ) .. _supervisor documentation: http://supervisord.org/configuration.html#program-x-section-values """ from fabtools.require import file as require_file from fabtools.require.deb import package as require_deb_package from fabtools.require.rpm import package as require_rpm_package from fabtools.require.arch import package as require_arch_package from fabtools.require.service import started as require_started family = distrib_family() if family == 'debian': require_deb_package('supervisor') require_started('supervisor') elif family == 'redhat': require_rpm_package('supervisor') require_started('supervisord') elif family == 'arch': require_arch_package('supervisor') require_started('supervisord') else: raise UnsupportedFamily(supported=['debian', 'redhat', 'arch']) # Set default parameters params = {} params.update(kwargs) params.setdefault('autorestart', 'true') params.setdefault('redirect_stderr', 'true') # Build config file from parameters lines = [] lines.append('[program:%(name)s]' % locals()) for key, value in sorted(params.items()): lines.append("%s=%s" % (key, value)) # Upload config file if family == 'debian': filename = '/etc/supervisor/conf.d/%(name)s.conf' % locals() elif family == 'redhat': filename = '/etc/supervisord.d/%(name)s.ini' % locals() elif family == 'arch': filename = '/etc/supervisor.d/%(name)s.ini' % locals() with watch(filename, callback=update_config, use_sudo=True): require_file(filename, contents='\n'.join(lines), use_sudo=True) # Start the process if needed if process_status(name) == 'STOPPED': start_process(name)
def site(server_name, template_contents=None, template_source=None, enabled=True, check_config=True, **kwargs): """ Require an nginx site. You must provide a template for the site configuration, either as a string (*template_contents*) or as the path to a local template file (*template_source*). :: from fabtools import require CONFIG_TPL = ''' server { listen %(port)d; server_name %(server_name)s %(server_alias)s; root %(docroot)s; access_log /var/log/nginx/%(server_name)s.log; }''' require.nginx.site('example.com', template_contents=CONFIG_TPL, port=80, server_alias='www.example.com', docroot='/var/www/mysite', ) .. seealso:: :py:func:`fabtools.require.files.template_file` """ family = distrib_family() # nginx-common is always installed if nginx exists if family == 'debian' and not is_deb_installed('nginx-common'): server() elif family == 'redhat' and not is_rpm_installed('nginx-common'): server() elif distrib_id() is 'Archlinux' and not is_arch_installed('nginx-common'): server() config_filename = '/etc/nginx/sites-available/%s.conf' % server_name context = { 'port': 80, } context.update(kwargs) context['server_name'] = server_name template_file(config_filename, template_contents, template_source, context, use_sudo=True) link_filename = '/etc/nginx/sites-enabled/%s.conf' % server_name if enabled: if not is_link(link_filename): run_as_root("ln -s %(config_filename)s %(link_filename)s" % locals()) # Make sure we don't break the config if check_config: with settings(hide('running', 'warnings'), warn_only=True): if run_as_root('nginx -t').failed: run_as_root("rm %(link_filename)s" % locals()) message = red("Error in %(server_name)s nginx site config (disabling for safety)" % locals()) abort(message) else: if is_link(link_filename): run_as_root("rm %(link_filename)s" % locals()) reload_service('nginx')
def git_require(): """ Test high level git tools. These tests should also cover the low level tools as all of them are called indirectly. """ from fabric.api import cd, sudo from fabtools import require from fabtools.files import group, is_dir, owner from fabtools.system import distrib_family from fabtools.require.git import working_copy family = distrib_family() if family == 'debian': require.deb.package('git-core') elif family == 'redhat': require.rpm.package('git') with cd('/tmp'): # clean up... sudo('rm -rf *') # working_copy(remote_url, path=None, branch="master", update=True, # use_sudo=False, user=None) # Test with remote_url only working_copy(remote_url) assert is_dir('fabtools') assert is_dir('fabtools/.git') with cd('fabtools'): remotes = sudo('git remote -v') assert remotes == \ 'origin\thttps://github.com/disko/fabtools.git (fetch)\r\n' \ 'origin\thttps://github.com/disko/fabtools.git (push)' branch = sudo('git branch') assert branch == '* master' # Test with remote_url and path working_copy(remote_url, path='wc') assert is_dir('wc') assert is_dir('wc/.git') with cd('wc'): remotes = sudo('git remote -v') assert remotes == \ 'origin\thttps://github.com/disko/fabtools.git (fetch)\r\n' \ 'origin\thttps://github.com/disko/fabtools.git (push)' branch = sudo('git branch') assert branch == '* master' # Test that nothing is upated sudo('tar cf wc_old.tar wc') old_md5 = sudo('md5sum wc_old.tar').split(' ')[0] working_copy(remote_url, path='wc', update=False) sudo('tar cf wc_new.tar wc') new_md5 = sudo('md5sum wc_new.tar').split(' ')[0] assert old_md5 == new_md5 # Test checkout of a branch working_copy(remote_url, path='wc', branch="test_git") assert is_dir('wc') assert is_dir('wc/.git') with cd('wc'): remotes = sudo('git remote -v') assert remotes == \ 'origin\thttps://github.com/disko/fabtools.git (fetch)\r\n' \ 'origin\thttps://github.com/disko/fabtools.git (push)' branch = sudo('git branch') assert branch == 'master\r\n* test_git' # Test use_sudo without user working_copy(remote_url, path='wc_root', use_sudo=True) assert is_dir('wc_root') assert is_dir('wc_root/.git') with cd('wc_root'): remotes = sudo('git remote -v') assert remotes == \ 'origin\thttps://github.com/disko/fabtools.git (fetch)\r\n' \ 'origin\thttps://github.com/disko/fabtools.git (push)' branch = sudo('git branch') assert branch == '* master' assert owner('wc_root') == 'root' assert group('wc_root') == 'root' # Test use_sudo with user nobody working_copy(remote_url, path='wc_nobody', use_sudo=True, user='******') assert is_dir('wc_nobody') assert is_dir('wc_nobody/.git') with cd('wc_nobody'): remotes = sudo('git remote -v') assert remotes == \ 'origin\thttps://github.com/disko/fabtools.git (fetch)\r\n' \ 'origin\thttps://github.com/disko/fabtools.git (push)' branch = sudo('git branch') assert branch == '* master' assert owner('wc_nobody') == 'nobody' if family == 'debian': assert group('wc_nobody') == 'nogroup' elif family == 'redhat': assert group('wc_nobody') == 'nobody'
def _update_package_index(): from fabtools.system import distrib_family family = distrib_family() if family == 'debian': from fabtools.require.deb import uptodate_index uptodate_index()
def install_from_source(version=DEFAULT_VERSION, checkinstall=False): """ Install Node JS from source. If *checkinstall* is ``True``, a distribution package will be built. :: import fabtools # Install Node.js fabtools.nodejs.install_nodejs() .. note:: This function may not work for old versions of Node.js. """ from fabtools.require.deb import packages as require_deb_packages from fabtools.require.rpm import packages as require_rpm_packages from fabtools.require import file as require_file family = distrib_family() if family == 'debian': packages = [ 'build-essential', 'libssl-dev', 'python', ] if checkinstall: packages.append('checkinstall') require_deb_packages(packages) elif family == 'redhat': packages = [ 'gcc', 'gcc-c++', 'make', 'openssl-devel', 'python', ] if checkinstall: packages.append('checkinstall') require_rpm_packages(packages) filename = 'node-v%s.tar.gz' % version foldername = filename[0:-7] require_file(url='http://nodejs.org/dist/v%(version)s/%(filename)s' % { 'version': version, 'filename': filename, }) run('tar -xzf %s' % filename) with cd(foldername): run('./configure') run('make -j%d' % (cpus() + 1)) if checkinstall: run_as_root( 'checkinstall -y --pkgname=nodejs --pkgversion=%(version) ' '--showinstall=no make install' % locals()) else: run_as_root('make install') run('rm -rf %(filename)s %(foldername)s' % locals())