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 install(packages, update=False, options=None): """ Install one or more packages. If *update* is ``True``, the package definitions will be updated first, using :py:func:`~fabtools.deb.update_index`. Extra *options* may be passed to ``apt-get`` if necessary. Example:: import fabtools # Update index, then install a single package fabtools.deb.install('build-essential', update=True) # Install multiple packages fabtools.deb.install([ 'python-dev', 'libxml2-dev', ]) """ manager = MANAGER if update: update_index() if options is None: options = [] if not isinstance(packages, basestring): packages = " ".join(packages) options.append("--quiet") options.append("--assume-yes") options = " ".join(options) run_as_root('%(manager)s install %(options)s %(packages)s' % locals())
def test_require_user_with_ssh_public_keys(): from fabtools.user import authorized_keys from fabtools.require import user try: tests_dir = os.path.dirname(os.path.dirname(__file__)) public_key_filename = os.path.join(tests_dir, 'id_test.pub') with open(public_key_filename) as public_key_file: public_key = public_key_file.read().strip() user('req4', home='/tmp/req4', ssh_public_keys=public_key_filename) keys = authorized_keys('req4') assert keys == [public_key] # let's try add same keys second time user('req4', home='/tmp/req4', ssh_public_keys=public_key_filename) keys = authorized_keys('req4') assert keys == [public_key] finally: run_as_root('userdel -r req4')
def test_git_require_sudo_user(gituser): """ Test working_copy() with sudo as a user """ from fabtools.require.git import working_copy username, groupname = gituser with cd('/tmp'): try: working_copy(REMOTE_URL, path='wc_nobody', use_sudo=True, user=username) assert is_dir('wc_nobody') assert is_dir('wc_nobody/.git') with cd('wc_nobody'): remotes = sudo('git remote -v', user=username) assert remotes == \ 'origin\thttps://github.com/disko/fabtools.git (fetch)\r\n' \ 'origin\thttps://github.com/disko/fabtools.git (push)' assert _current_branch() == 'master' assert owner('wc_nobody') == username assert group('wc_nobody') == groupname finally: run_as_root('rm -rf wc_nobody')
def upgrade(): """ Upgrade all packages. """ manager = MANAGER cmd = 'upgrade' run_as_root("%(manager)s %(cmd)s" % locals(), pty=False)
def test_add_apt_key_without_key_id_from_url(): from fabtools.deb import add_apt_key try: add_apt_key(url='http://repo.varnish-cache.org/debian/GPG-key.txt') run_as_root('apt-key finger | grep -q C4DEFFEB') finally: run_as_root('apt-key del C4DEFFEB', quiet=True)
def test_require_deb_key_from_specific_keyserver(): from fabtools.require.deb import key as require_key try: require_key(keyid='7BD9BF62', keyserver='keyserver.ubuntu.com') run_as_root('apt-key finger | grep -q 7BD9BF62') finally: run_as_root('apt-key del 7BD9BF62', quiet=True)
def update(path, branch="default", use_sudo=False, user=None, force=False): """ Merge changes to a working copy and/or switch branches. :param path: Path of the working copy directory. This directory must exist and be a Mercurial working copy. :type path: str :param use_sudo: If ``True`` execute ``hg`` with :func:`fabric.operations.sudo`, else with :func:`fabric.operations.run`. :type use_sudo: bool :param user: If ``use_sudo is True``, run :func:`fabric.operations.sudo` with the given user. If ``use_sudo is False`` this parameter has no effect. :type user: str """ cmd = "hg up %s" % branch with cd(path): if use_sudo and user is None: run_as_root(cmd) elif use_sudo: sudo(cmd, user=user) else: run(cmd)
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 import require require.user('redis', home='/var/lib/redis') 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() require.file(tarball, url='http://redis.googlecode.com/files/' + tarball) run('tar xzf %(tarball)s' % locals()) # Compile and install binaries require.deb.package('build-essential') 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 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 fetch(path, use_sudo=False, user=None): """ Fetch changes from the default remote repository. This will fetch new changesets, but will not update the contents of the working tree unless yo do a merge or rebase. :param path: Path of the working copy directory. This directory must exist and be a Git working copy with a default remote to fetch from. :type path: str :param use_sudo: If ``True`` execute ``git`` with :func:`fabric.operations.sudo`, else with :func:`fabric.operations.run`. :type use_sudo: bool :param user: If ``use_sudo is True``, run :func:`fabric.operations.sudo` with the given user. If ``use_sudo is False`` this parameter has no effect. :type user: str """ if path is None: raise ValueError("Path to the working copy is needed to fetch from a " "remote repository.") cmd = 'git fetch' with cd(path): if use_sudo and user is None: run_as_root(cmd) elif use_sudo: sudo(cmd, user=user) else: run(cmd)
def repolist(status="", media=None): """ Get the list of ``yum`` repositories. Returns enabled repositories by default. Extra *status* may be passed to list disabled repositories if necessary. Media and debug repositories are kept disabled, except if you pass *media*. :: import fabtools # Install a package that may be included in disabled repositories fabtools.rpm.install('vim', fabtools.rpm.repolist('disabled')) """ manager = MANAGER with settings(hide("running", "stdout")): if media: repos = run_as_root("%(manager)s repolist %(status)s | sed '$d' | sed -n '/repo id/,$p'" % locals()) else: repos = run_as_root( "%(manager)s repolist %(status)s | sed '/Media\\|Debug/d' | sed '$d' | sed -n '/repo id/,$p'" % locals() ) return map(lambda line: line.split(" ")[0], repos.splitlines()[1:])
def install_miniconda(prefix='~/miniconda', use_sudo=False, keep_installer=False): """ Install the latest version of `miniconda`_. :param prefix: prefix for the miniconda installation :param use_sudo: use sudo for this operation :param keep_installer: keep the miniconda installer after installing :: import fabtools fabtools.conda.install_miniconda() """ with cd("/tmp"): if not fabtools.files.is_file('Miniconda-latest-Linux-x86_64.sh'): download(MINICONDA_URL) command = 'bash Miniconda-latest-Linux-x86_64.sh -b -p %(prefix)s' % locals() if use_sudo: run_as_root(command) else: run(command) files.append('~/.bash_profile', 'export PATH=%(prefix)s/bin:$PATH' % locals()) if not keep_installer: run('rm -f Miniconda-latest-Linux-x86_64.sh')
def reset(): from fabric.api import settings from fabtools.utils import run_as_root with settings(warn_only=True): run_as_root('apt-key del 7BD9BF62') run_as_root('apt-key del C4DEFFEB')
def clone(remote_url, path=None, use_sudo=False, user=None): """ Clone a remote Git repository into a new directory. :param remote_url: URL of the remote repository to clone. :type remote_url: str :param path: Path of the working copy directory. Must not exist yet. :type path: str :param use_sudo: If ``True`` execute ``git`` with :func:`fabric.operations.sudo`, else with :func:`fabric.operations.run`. :type use_sudo: bool :param user: If ``use_sudo is True``, run :func:`fabric.operations.sudo` with the given user. If ``use_sudo is False`` this parameter has no effect. :type user: str """ cmd = 'git clone --quiet %s' % remote_url if path is not None: cmd = cmd + ' %s' % path if use_sudo and user is None: run_as_root(cmd) elif use_sudo: sudo(cmd, user=user) else: run(cmd)
def locales(names): """ Require the list of locales to be available. """ config_file = '/var/lib/locales/supported.d/local' if not is_file(config_file): 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: if distrib_id() == "Archlinux": run_as_root('locale-gen') else: run_as_root('dpkg-reconfigure --frontend=noninteractive locales')
def test_add_apt_key_with_key_id_from_specific_key_server(): from fabtools.deb import add_apt_key try: add_apt_key(keyid='7BD9BF62', keyserver='keyserver.ubuntu.com') run_as_root('apt-key finger | grep -q 7BD9BF62') finally: run_as_root('apt-key del 7BD9BF62', quiet=True)
def set_hostname(hostname, persist=True): """ Set the hostname. """ run_as_root('hostname %s' % hostname) if persist: run_as_root('echo %s >/etc/hostname' % hostname)
def test_require_deb_key_from_url(): from fabtools.require.deb import key as require_key try: require_key(keyid='C4DEFFEB', url='http://repo.varnish-cache.org/debian/GPG-key.txt') run_as_root('apt-key finger | grep -q C4DEFFEB') finally: run_as_root('apt-key del C4DEFFEB', quiet=True)
def download_template(name=None, url=None): """ Download an OpenVZ template. Example:: from fabtools.openvz import download_template # Use custom OS template download_template(url='http://example.com/templates/mybox.tar.gz') If no *url* is provided, the OS template will be downloaded from the `download.openvz.org <http://download.openvz.org/template/precreated/>`_ repository:: from fabtools.openvz import download_template # Use OS template from http://download.openvz.org/template/precreated/ download_template('debian-6.0-x86_64') """ if url is None: url = 'http://download.openvz.org/template/precreated/%s.tar.gz' % name with cd('/var/lib/vz/template/cache'): run_as_root('wget --progress=dot:mega "%s"' % url)
def test_git_require_sudo(): """ Test working_copy() with sudo """ from fabtools.require.git import working_copy try: 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 = run('git remote -v') assert remotes == \ 'origin\thttps://github.com/disko/fabtools.git (fetch)\r\n' \ 'origin\thttps://github.com/disko/fabtools.git (push)' assert _current_branch() == 'master' assert owner('wc_root') == 'root' assert group('wc_root') == 'root' finally: run_as_root('rm -rf wc_root')
def checkout(path, branch="master", use_sudo=False, user=None): """ Checkout an existing branch of an existing Git working copy. :param path: Path of the working copy directory. This directory must exist and be a Git working copy. :type path: str :param branch: Name of the branch to checkout. :type branch: str :param use_sudo: If ``True`` execute ``git`` with :func:`fabric.operations.sudo`, else with :func:`fabric.operations.run`. :type use_sudo: bool :param user: If ``use_sudo is True``, run :func:`fabric.operations.sudo` with the given user. If ``use_sudo is False`` this parameter has no effect. :type user: str """ if path is None: raise ValueError("Path to the working copy is needed to checkout a " "branch") cmd = 'git checkout %s' % branch with cd(path): if use_sudo and user is None: run_as_root(cmd) elif use_sudo: sudo(cmd, user=user) else: run(cmd)
def install(packages, update=False, options=None): """ Install one or more packages. If *update* is ``True``, the package definitions will be updated first, using :py:func:`~fabtools.opkg.update_index`. Extra *options* may be passed to ``opkg`` if necessary. Example:: import fabtools # Update index, then install a single package fabtools.opkg.install('build-essential', update=True) # Install multiple packages fabtools.opkg.install([ 'mc', 'htop', ]) """ manager = MANAGER if update: update_index() if options is None: options = [] if not isinstance(packages, basestring): packages = " ".join(packages) options.append("--verbosity=0") options = " ".join(options) cmd = '%(manager)s install %(options)s %(packages)s' % locals() run_as_root(cmd, pty=False)
def pull(path, use_sudo=False, user=None): """ Pull from a remote Git repository on an existing working copy. :param path: Path of the working copy directory. This directory must exist and be a Git working copy with a default remote to pull from. :type path: str :param use_sudo: If ``True`` execute ``git`` with :func:`fabric.operations.sudo`, else with :func:`fabric.operations.run`. :type use_sudo: bool :param user: If ``use_sudo is True``, run :func:`fabric.operations.sudo` with the given user. If ``use_sudo is False`` this parameter has no effect. :type user: str """ if path is None: raise ValueError("Path to the working copy is needed to pull from a " "remote repository.") cmd = 'git pull' with cd(path): if use_sudo and user is None: run_as_root(cmd) elif use_sudo: sudo(cmd, user=user) else: run(cmd)
def ismounted(device): """ Check if partition is mounted Example:: from fabtools.disk import ismounted if ismounted('/dev/sda1'): print ("disk sda1 is mounted") """ # Check filesystem with settings(hide('running', 'stdout')): res = run_as_root('mount') for line in res.splitlines(): fields = line.split() if fields[0] == device: return True # Check swap with settings(hide('running', 'stdout')): res = run_as_root('swapon -s') for line in res.splitlines(): fields = line.split() if fields[0] == device: return True return False
def createDirectory(rootdir, webserver): # Log directory require.files.directory( '%(rootdir)s/%(webserver)s/conf' % locals(), ) # Log directory require.files.directory( '%(rootdir)s/%(webserver)s/log' % locals(), ) # Web directory webdirectory = '%(rootdir)s/%(webserver)s/www' % locals() require.files.directory( webdirectory, ) require.python.virtualenv( '%(rootdir)s/%(webserver)s/venv' % locals(), use_sudo = True, user = webserver ) if webserver == 'default': return chown = 'chown -R %(webserver)s:%(webserver)s %(webdirectory)s' % locals() run_as_root(chown)
def ppa(name, auto_yes=False): """ Require a `PPA`_ package source. Example:: from fabtools import require # Node.js packages by Chris Lea require.deb.ppa('ppa:chris-lea/node.js', auto_yes=True) .. _PPA: https://help.launchpad.net/Packaging/PPA """ assert name.startswith('ppa:') user, repo = name[4:].split('/', 2) distrib = distrib_codename() source = '%(user)s-%(repo)s-%(distrib)s.list' % locals() if not is_file(source): package('python-software-properties') if auto_yes: prompt = '-y ' else: prompt = '' run_as_root('add-apt-repository %s %s' % (prompt, name), pty=False) update_index()
def install(packages, update=False, options=None): """ Install one or more Arch Linux packages. If *update* is ``True``, the package definitions will be updated first, using :py:func:`~fabtools.arch.update_index`. Extra *options* may be passed to ``pacman`` if necessary. Example:: import fabtools # Update index, then install a single package fabtools.arch.install('mongodb', update=True) # Install multiple packages fabtools.arch.install([ 'mongodb', 'python-pymongo', ]) """ manager = pkg_manager() if update: update_index() if options is None: options = [] if not isinstance(packages, basestring): packages = " ".join(packages) options = " ".join(options) cmd = '%(manager)s -S %(options)s %(packages)s' % locals() run_as_root(cmd, pty=False)
def directories(): """ Check directory creation and modification """ from fabtools import require import fabtools with cd('/tmp'): run_as_root('rm -rf dir1 dir2') # Test directory creation require.directory('dir1') assert fabtools.files.is_dir('dir1') assert fabtools.files.owner('dir1') == env.user # Test initial owner requirement require.user('dirtest', create_home=False) require.directory('dir2', owner='dirtest', use_sudo=True) assert fabtools.files.is_dir('dir2') assert fabtools.files.owner('dir2') == 'dirtest' # Test changed owner requirement require.user('dirtest2', create_home=False) require.directory('dir2', owner='dirtest2', use_sudo=True) assert fabtools.files.is_dir('dir2') assert fabtools.files.owner('dir2') == 'dirtest2'
def install_pip(python_cmd='python', use_sudo=True): """ Install the latest version of `pip`_, using the given Python interpreter. :: import fabtools if not fabtools.python.is_pip_installed(): fabtools.python.install_pip() .. note:: pip is automatically installed inside a virtualenv, so there is no need to install it yourself in this case. .. _pip: http://www.pip-installer.org/ """ with cd('/tmp'): run('curl --silent -O https://raw.github.com/pypa/pip/master/contrib/get-pip.py') command = '%(python_cmd)s get-pip.py' % locals() if use_sudo: run_as_root(command, pty=False) else: run(command, pty=False) run('rm -f get-pip.py')
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 upload_template(filename, destination, context=None, use_jinja=False, template_dir=None, use_sudo=False, backup=True, mirror_local_mode=False, mode=None, mkdir=False, chown=False, user=None): """ Upload a template file. This is a wrapper around :func:`fabric.contrib.files.upload_template` that adds some extra parameters. If ``mkdir`` is True, then the remote directory will be created, as the current user or as ``user`` if specified. If ``chown`` is True, then it will ensure that the current user (or ``user`` if specified) is the owner of the remote file. """ if mkdir: remote_dir = os.path.dirname(destination) if use_sudo: sudo('mkdir -p %s' % quote(remote_dir), user=user) else: run('mkdir -p %s' % quote(remote_dir)) _upload_template( filename=filename, destination=destination, context=context, use_jinja=use_jinja, template_dir=template_dir, use_sudo=use_sudo, backup=backup, mirror_local_mode=mirror_local_mode, mode=mode, ) if chown: if user is None: user = env.user run_as_root('chown %s: %s' % (user, quote(destination)))
def uninstall(packages, options=None): """ Remove one or more Portage packages. Extra *options* may be passed to ``emerge`` if necessary. """ manager = MANAGER options = options or [] options = " ".join(options) if not isinstance(packages, six.string_types): packages = " ".join(packages) cmd = '%(manager)s --unmerge %(options)s %(packages)s' % locals() run_as_root(cmd, pty=False)
def enable_site(config): """ Create link from /etc/apache2/sites-available/ in /etc/apache2/sites-enabled/ (does not reload apache config) :: from fabtools import require require.apache.enable_site('default') .. seealso:: :py:func:`fabtools.require.apache.site_enabled` """ if not is_site_enabled(config): run_as_root('a2ensite %s' % _get_config_name(config))
def update(kernel=False): """ Upgrade all packages, skip obsoletes if ``obsoletes=0`` in ``yum.conf``. Exclude *kernel* upgrades by default. """ manager = MANAGER cmds = { 'yum -y --color=never': { False: '--exclude=kernel* update', True: 'update' } } cmd = cmds[manager][kernel] run_as_root("%(manager)s %(cmd)s" % locals())
def status(): """ Get the firewall status. """ with settings(hide('running', 'stdout', 'warnings'), warn_only=True): res = run_as_root('shorewall status') return re.search(r'\nShorewall is (\w+)', res).group(1)
def test_require_user_without_home(): from fabtools.require import user from fabtools.user import exists try: user('req1', create_home=False) assert exists('req1') assert not is_dir('/home/req1') # require again user('req1') finally: run_as_root('userdel -r req1', warn_only=True)
def partitions(device=""): """ Get a partition list for all disk or for selected device only Example:: from fabtools.disk import partitions spart = {'Linux': 0x83, 'Swap': 0x82} parts = partitions() # parts = {'/dev/sda1': 131, '/dev/sda2': 130, '/dev/sda3': 131} r = parts['/dev/sda1'] == spart['Linux'] r = r and parts['/dev/sda2'] == spart['Swap'] if r: print("You can format these partitions") """ partitions_list = {} with settings(hide('running', 'stdout')): res = run_as_root('sfdisk -d %(device)s' % locals()) spart = re.compile(r'(?P<pname>^/.*) : .* Id=(?P<ptypeid>[0-9a-z]+)') for line in res.splitlines(): m = spart.search(line) if m: partitions_list[m.group('pname')] = int(m.group('ptypeid'), 16) return partitions_list
def enable_module(module): """ Create link from /etc/apache2/mods-available/ in /etc/apache2/mods-enabled/ (does not reload apache config) :: from fabtools import require require.apache.enable_module('rewrite') .. seealso:: :py:func:`fabtools.require.apache.module_enabled` """ if not is_module_enabled(module): run_as_root('a2enmod %s' % module)
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 list_ctids(): """ Get the list of currently used CTIDs. """ with settings(hide('running', 'stdout')): res = run_as_root('vzlist -a -1') return list(map(int, res.splitlines()))
def force_reload(service): """ Force reload a service. :: import fabtools # Force reload service fabtools.service.force_reload('foo') .. warning:: The service needs to support the ``force-reload`` operation. """ run_as_root('service %(service)s force-reload' % locals(), pty=False)
def reload(service): """ Reload a service. :: import fabtools # Reload service fabtools.service.reload('foo') .. warning:: The service needs to support the ``reload`` operation. """ run_as_root('service %(service)s reload' % locals(), pty=False)
def disable_module(module): """ Delete link in /etc/apache/mods-enabled/ (does not reload apache config) :: from fabtools import require require.apache.disable_module('rewrite') .. seealso:: :py:func:`fabtools.require.apache.module_disabled` """ if is_module_enabled(module): run_as_root('a2dismod %s' % module)
def uninstall(packages, options=None): """ Remove one or more packages. Extra *options* may be passed to ``yum`` if necessary. """ manager = MANAGER if options is None: options = [] elif isinstance(options, str): options = [options] if not isinstance(packages, basestring): packages = " ".join(packages) options = " ".join(options) run_as_root('%(manager)s %(options)s remove %(packages)s' % locals())
def upgrade(kernel=False): """ Upgrade all packages, including obsoletes. Exclude *kernel* upgrades by default. """ manager = MANAGER cmds = { 'yum -y --color=never': { False: '--exclude=kernel* upgrade', True: 'upgrade' } } cmd = cmds[manager][kernel] run_as_root("%(manager)s %(cmd)s" % locals())
def disable_site(config): """ Delete link in /etc/apache/sites-enabled/ (does not reload apache config) :: from fabtools import require require.apache.disable_site('default') .. seealso:: :py:func:`fabtools.require.apache.site_disabled` """ if is_site_enabled(config): run_as_root('a2dissite %s' % _get_config_name(config))
def host(ipaddress, hostnames, use_sudo=False): """ Add a ipadress and hostname(s) in /etc/hosts file Example:: from fabtools import require require.network.host('127.0.0.1','hostname-a hostname-b') """ res = run_as_root('cat /etc/hosts | egrep "^%(ipaddress)s"' % locals()) if res.succeeded: m = re.match('^%(ipaddress)s (.*)' % locals(), res) # If ipadress allready exists if m: toadd = list() hostnames = hostnames.split(' ') inthehosts = m.group(1).split(' ') for h in hostnames: if h not in inthehosts: toadd.append(h) if len(toadd) > 0: print "ADD: %s" % toadd print res hostline = "%s %s" % (res, ' '.join(toadd)) with hide('stdout', 'warnings'): sed('/etc/hosts', res, hostline, use_sudo=use_sudo) else: hostline = "%s %s" % (res, hostnames) append('/etc/hosts', hostline, use_sudo=use_sudo)
def disable(config): """ Delete link in /etc/nginx/sites-enabled/ (does not reload nginx config) :: from fabtools import require require.nginx.disable('default') .. seealso:: :py:func:`fabtools.require.nginx.disabled` """ link_filename = '/etc/nginx/sites-enabled/%s' % config if is_link(link_filename): run_as_root("rm %(link_filename)s" % locals())
def ppa(name, auto_accept=True, keyserver=None): """ Require a `PPA`_ package source. Example:: from fabtools import require # Node.js packages by Chris Lea require.deb.ppa('ppa:chris-lea/node.js', keyserver='my.keyserver.com') .. _PPA: https://help.launchpad.net/Packaging/PPA """ assert name.startswith('ppa:') user, repo = name[4:].split('/', 2) release = float(distrib_release()) if release >= 12.04: repo = repo.replace('.', '_') auto_accept = '--yes' if auto_accept else '' else: auto_accept = '' if not isinstance(keyserver, basestring) and keyserver: keyserver = keyserver[0] if keyserver: keyserver = '--keyserver ' + keyserver else: keyserver = '' distrib = distrib_codename() source = '/etc/apt/sources.list.d/%(user)s-%(repo)s-%(distrib)s.list' % locals( ) if not is_file(source): if release >= 14.04: # add-apt-repository moved to software-properties-common in 14.04 package('software-properties-common') else: package('python-software-properties') run_as_root( 'add-apt-repository %(auto_accept)s %(keyserver)s %(name)s' % locals(), pty=False) update_index()
def require_internet(): """ Check if they have a internet connexion """ with settings(warn_only=True): res = run_as_root('ping -c1 -W1 8.8.8.8') if res.return_code == 1: abort("You must have internet to be continue")
def upgrade(safe=True): """ Upgrade all packages. """ manager = MANAGER cmds = { 'apt-get': { False: 'dist-upgrade', True: 'upgrade' }, 'aptitude': { False: 'full-upgrade', True: 'safe-upgrade' } } cmd = cmds[manager][safe] run_as_root("%(manager)s --assume-yes %(cmd)s" % locals(), pty=False)
def install_pip(): """ Install the latest version of `pip`_. .. _pip: http://www.pip-installer.org/ :: import fabtools if not fabtools.python.is_pip_installed(): fabtools.python.install_pip() """ with cd('/tmp'): run('curl --silent -O https://raw.github.com/pypa/pip/master/contrib/get-pip.py') run_as_root('python get-pip.py', pty=False)
def _easy_install(argv, python_cmd, use_sudo): """ Install packages using easy_install We don't know if the easy_install command in the path will be the right one, so we use the setuptools entry point to call the script's main function ourselves. """ command = """python -c "\ from pkg_resources import load_entry_point;\ ez = load_entry_point('setuptools', 'console_scripts', 'easy_install');\ ez(argv=%(argv)r)\ """ % locals() if use_sudo: run_as_root(command) else: run(command)
def pull(path, use_sudo=False, user=None, recursive=True, force=False): """ Fetch changes from the default remote repository and merge them. :param path: Path of the working copy directory. This directory must exist and be a Git working copy with a default remote to pull from. :type path: str :param use_sudo: If ``True`` execute ``git`` with :func:`fabric.operations.sudo`, else with :func:`fabric.operations.run`. :type use_sudo: bool :param user: If ``use_sudo is True``, run :func:`fabric.operations.sudo` with the given user. If ``use_sudo is False`` this parameter has no effect. :type user: str :param recursive: If ``True`` use ``git submodule update`` for submodules. :type recursive: bool :param force: If ``True``, append the ``--force`` option to the command. :type force: bool """ if path is None: raise ValueError('Path to the working copy is needed to pull from a ' 'remote repository.') options = [] if force: options.append('--force') options = ' '.join(options) cmd = 'git pull %s' % options if recursive: cmd += '&& git submodule update' with cd(path): if use_sudo and user is None: run_as_root(cmd) elif use_sudo: sudo(cmd, user=user) else: run(cmd)
def configure_base(): # Configure python environement python_cmd = 'python2.7' require.python.pip(python_cmd=python_cmd) require.python.package('virtualenv', python_cmd=python_cmd, use_sudo=True) require.python.package('virtualenvwrapper', python_cmd=python_cmd, use_sudo=True) # Active service # Dont forget edit the /etc/udev/10-network.rules for mac address systemd.disable('dhcpcd') systemd.enable('sshd') systemd.enable('netctl-ifplugd@net0') systemd.enable('netctl-auto@wifi0') # Copy udev netework interface fileexists = is_file("/etc/udev/rules.d/10-network.rules") if not fileexists: run_as_root("mv /etc/udev/rules.d/10-network.rules.autoinstall /etc/udev/rules.d/10-network.rules")
def install_distribute(): """ Install the latest version of `distribute`_. .. _distribute: http://packages.python.org/distribute/ :: from fabtools.python_distribute import * if not is_distribute_installed(): install_distribute() """ with cd("/tmp"): run("curl --silent -O http://python-distribute.org/distribute_setup.py" ) run_as_root("python distribute_setup.py")
def uninstall(packages, purge=False, options=None): """ Remove one or more packages. If *purge* is ``True``, the package configuration files will be removed from the system. Extra *options* may be passed to ``apt-get`` if necessary. """ manager = MANAGER command = "purge" if purge else "remove" if options is None: options = [] if not isinstance(packages, basestring): packages = " ".join(packages) options.append("--assume-yes") options = " ".join(options) cmd = '%(manager)s %(command)s %(options)s %(packages)s' % locals() run_as_root(cmd, pty=False)
def disable_module(module): """ Disable an Apache module. This deletes the symbolink link in ``/etc/apache2/mods-enabled/``. This does not cause Apache to reload its configuration. :: import fabtools fabtools.apache.disable_module('rewrite') fabtools.service.reload('apache2') .. seealso:: :py:func:`fabtools.require.apache.module_disabled` """ if is_module_enabled(module): run_as_root('a2dismod %s' % module)
def disable_site(site_name): """ Disable an Apache site. This deletes the symbolink link in ``/etc/apache2/sites-enabled/``. This does not cause Apache to reload its configuration. :: import fabtools fabtools.apache.disable_site('default') fabtools.service.reload('apache2') .. seealso:: :py:func:`fabtools.require.apache.site_disabled` """ if is_site_enabled(site_name): run_as_root('a2dissite %s' % _site_config_filename(site_name))