def bzr_wc_target_exists_plain_no_force(): """ Test working copy when target is an already existing plain directory and force was not specified. """ test = 'bzr_wc_target_exists_plain_no_force' wt = '%s-test-%s' % (DIR, test) puts(magenta('Executing test: %s' % test)) from fabric.api import run from fabtools.files import is_dir from fabtools import require run('mkdir %s' % wt) assert not is_dir(path.join(wt, '.bzr')) try: require.bazaar.working_copy(REMOTE_URL, wt) except SystemExit: pass else: assert False, "working_copy didn't raise exception" assert not is_dir(path.join(wt, '.bzr'))
def git_require_sudo_user(): """ Test working_copy() with sudo as a user """ from fabric.api import cd, sudo from fabtools.files import group, is_dir, owner from fabtools import require require.user('gituser', group='gitgroup') require.git.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', user='******') assert remotes == \ 'origin\thttps://github.com/disko/fabtools.git (fetch)\r\n' \ 'origin\thttps://github.com/disko/fabtools.git (push)' branch = sudo('git branch', user='******') assert branch == '* master' assert owner('wc_nobody') == 'gituser' assert group('wc_nobody') == 'gitgroup'
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 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 git_require_sudo_user(): """ Test working_copy() with sudo as a user """ from fabric.api import cd, sudo from fabtools.files import group, is_dir, owner from fabtools import require require.user("gituser", group="gitgroup") require.git.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", user="******") assert ( remotes == "origin\thttps://github.com/disko/fabtools.git (fetch)\r\n" "origin\thttps://github.com/disko/fabtools.git (push)" ) branch = sudo("git branch", user="******") assert branch == "* master" assert owner("wc_nobody") == "gituser" assert group("wc_nobody") == "gitgroup"
def install(): """ Install a jobcatcher in python2 virtualenv """ if not env.host_string: env.host_string = 'localhost' pkgs = [ 'python2', 'git', ] require.arch.packages(pkgs) project_root = '$HOME/projects' project_name = 'JobCatcher' use_python = 'python2.7' virtualenv = '.virtualenvs/jobcatcher' gitproject = '[email protected]:yoannsculo/JobCatcher.git' require.python.pip(python_cmd=use_python) require.python.package( 'virtualenv', python_cmd=use_python, use_sudo=True, ) require.python.package( 'virtualenvwrapper', python_cmd=use_python, use_sudo=True, ) require.python.virtualenv( virtualenv, python_cmd=use_python, venv_python='python2.7', ) # Get a jobcatcher github repository cloned = False project = '%s/%s' % (project_root, project_name) if not is_dir(project): require.files.directory(project_root) cmd = 'cd %s ; git clone %s ; cd jobcatcher ; git checkout server' % (project_root, gitproject) run(cmd) cloned = True if not cloned and not is_dir(project): cmd = 'cd (%project)s ; git pull' % locals() run(cmd) # Install jobcatcher with python.virtualenv(virtualenv): here = os.path.dirname(__file__) requirements = '%(here)s/requirements.txt' % locals() put(requirements, '/tmp/requirements.txt') require.python.requirements( '/tmp/requirements.txt', )
def working_copy(remote_url, path=None, branch="master", update=True, use_sudo=False, user=None): """ Require a working copy of the repository from the ``remote_url``. Clones or pulls from the repository under ``remote_url`` and checks out ``branch``. :param remote_url: URL of the remote repository (e.g. https://github.com/ronnix/fabtools.git). The given URL will be the ``origin`` remote of the working copy. :type remote_url: str :param path: Absolute or relative path of the working copy on the filesystem. If this directory doesn't exist yet, a new working copy is created through ``git clone``. If the directory does exist *and* ``update == True``, a ``git pull`` is issued. If ``path is None`` the ``git clone`` is issued in the current working directory and the directory name of the working copy is created by ``git``. :type path: str :param branch: Branch to switch to after cloning or pulling. :type branch: str :param update: Whether or not to update an existing working copy via ``git pull``. :type update: bool :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 is_dir(path, use_sudo=use_sudo) and update: # git pull git.pull(path=path, use_sudo=use_sudo, user=user) elif is_dir(path, use_sudo=use_sudo) and not update: # do nothing return elif not is_dir(path, use_sudo=use_sudo): # git clone git.clone(remote_url, path=path, use_sudo=use_sudo, user=user) if path is None: path = remote_url.split('/')[-1].replace('.git', '') else: raise ValueError("Invalid combination of parameters.") git.checkout(path=path, branch=branch, use_sudo=use_sudo, user=user)
def create(venv=None, pyver=None): deb.packages(['libjpeg8', 'libjpeg8-dev', 'libfreetype6', 'libfreetype6-dev', 'zlib1g-dev']) validate = "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$" if not env.get("new_user"): if env.no_input_mode: env.new_user = env.new_user_default else: prompt("User: "******"new_user", env.get('new_user_default', ''), validate=validate) if not fabtools.user.exists(env.new_user): prompt("Password for {0}: ".format(env.new_user), "new_passwd", '', validate=validate) env.home_dir = '{0}/{1}'.format(env.home_user, env.new_user) fabtools.user.create(env.new_user, home=env.home_dir, group=env.new_user, create_home=True, system=False, shell='/bin/bash', create_group=True, password=env.new_passwd) if not env.get("project"): if env.no_input_mode: env.project = env.project_default else: prompt("Project name: ", "project", env.get('project_default', '')) if not env.get("repository"): if env.no_input_mode: env.repository = env.repository_default else: prompt("Deploy from: ", "repository", env.get('repository_default', '')) if not env.get("domain"): if env.no_input_mode: abort("Need set env.domain !") else: prompt("Project DNS url: ", "domain", env.get('domain_default', ''), validate=validate) else: if not re.findall(validate, env.domain): abort("Invalid env.domain !") require('repository', 'domain', 'project') if venv is not None: env.venv = venv else: prompt("Virtual ENV: ", "venv", env.get('venv_default', ''), validate=validate) if pyver is not None: env.pyver = pyver else: prompt("Python VERSION: ", "pyver", env.get('pyver_default', ''), validate=validate) env.virt = '{0}/{1}/{2}'.format(env.home_user, env.new_user, env.virt_home) pyver_dir = '{0}{1}/{2}-{3}'.format(env.python_dir, env.pyver, env.new_user, env.venv) files.directory(env.virt, mode='750', owner=env.new_user, group=env.new_user, use_sudo=True) if not is_dir(posixpath.join(env.virt, env.venv)): with prefix('pythonbrew use {0}'.format(env.pyver)): if not is_dir(pyver_dir): sudo('pythonbrew venv create {0}-{1}'.format(env.new_user, env.venv)) sudo('ln -s /usr/lib/x86_64-linux-gnu/libjpeg.so {0}/lib/'.format(pyver_dir)) sudo('ln -s /usr/lib/x86_64-linux-gnu/libfreetype.so {0}/lib/'.format(pyver_dir)) sudo('ln -s /usr/lib/x86_64-linux-gnu/libz.so {0}/lib/'.format(pyver_dir)) sudo("find {2}/venvs/ -type d -iname '{1}-{0}' -print0 | xargs -I{3} -0 chown -R --preserve-root --no-dereference {1}:pythonbrew '{3}'".format(env.venv, env.new_user, '${PYTHONBREW_ROOT}', '{}')) sudo('ln -s {0} {1}/'.format(pyver_dir, env.virt)) sudo('chown -R {0}:{0} {1}'.format(env.new_user, env.virt))
def setup_dotfiles(): if files.is_dir('$HOME/dotfiles') and not files.is_dir('$HOME/.dotfiles'): install_dotfiles() run('mv $HOME/dotfiles/ $HOME/.dotfiles') with cd('$HOME/.dotfiles'): run('bash bash_setup.sh') with cd('$HOME/.dotfiles/.vim/bundle'): run('rm -rf neobundle.vim') git.working_copy('https://github.com/Shougo/neobundle.vim.git')
def test_temporary_directory_as_context_manager(): from fabtools.files import is_dir from fabtools.require.files import temporary_directory with temporary_directory() as path: assert is_dir(path) with cd(path): run('touch foo') assert not is_dir(path)
def test_create_user_with_home_directory(): from fabtools.user import create, exists try: create("user3", home="/tmp/user3") assert exists("user3") assert not is_dir("/home/user3") assert is_dir("/tmp/user3") finally: run_as_root("userdel -r user3", warn_only=True)
def test_create_user_with_home_directory(): from fabtools.user import create, exists try: create('user3', home='/tmp/user3') assert exists('user3') assert not is_dir('/home/user3') assert is_dir('/tmp/user3') finally: run_as_root('userdel -r user3')
def temporary_directory_as_context_manager(): """ Check temporary directory used as a context manager """ from fabtools.files import is_dir from fabtools.require.files import temporary_directory with temporary_directory() as path: assert is_dir(path) with cd(path): run('touch foo') assert not is_dir(path)
def mount_partitions(): """ mount all paritions """ disk.mount(env.part['/']['device'], "/mnt/") if not is_dir('/mnt/boot'): run_as_root('mkdir /mnt/boot') if not is_dir('/mnt/home'): run_as_root('mkdir /mnt/home') disk.mount(env.part['/boot']['device'], "/mnt/boot") disk.mount('/dev/mapper/home', "/mnt/home") disk.swapon(env.part['swap']['device'])
def test_require_user_with_custom_home(): from fabtools.require import user from fabtools.user import exists try: user('req3', home='/home/other') assert exists('req3') assert not is_dir('/home/req3') assert is_dir('/home/other') finally: run_as_root('userdel -r req3')
def test_temporary_directory_as_function(): from fabtools.files import is_dir from fabtools.require.files import temporary_directory path1 = temporary_directory() path2 = temporary_directory() assert is_dir(path1) assert is_dir(path2) assert path1 != path2 run('rmdir %s' % quote(path1)) run('rmdir %s' % quote(path2))
def test_require_user_with_custom_home(): from fabtools.require import user from fabtools.user import exists try: user("req3", home="/home/other") assert exists("req3") assert not is_dir("/home/req3") assert is_dir("/home/other") finally: run_as_root("userdel -r req3", warn_only=True)
def setup(): sudo('apt-get install -y python-dev autoconf g++ libmysqlclient-dev') app_name = 'minarepo-web-viewer' require.files.directory( '/usr/local/%s' % app_name, owner='root', group='root', use_sudo=True ) # copy mysql.secret.json require.files.file( '/usr/local/%s/mysql.secret.json' % app_name, source='./files/mysql.secret.json', owner='root', group='root', mode='0600', use_sudo=True ) # put supervisord conf require.files.file( '/etc/supervisor/conf.d/%s.conf' % app_name, source='./files/supervisor/etc/supervisor/conf.d/%s.conf' % app_name, owner='root', group='root', use_sudo=True ) # create virtualenv if not is_dir('/usr/local/%s/.venv' % app_name): with cd('/usr/local/%s' % app_name): sudo('virtualenv ./.venv') pip_path = '/usr/local/%s/.venv/bin/pip' % app_name sudo('%s install gunicorn' % pip_path) _deploy() sudo('supervisorctl reload')
def put_if_changed(local_path, remote_path): # create random temporary path hasher = hashlib.sha1() hasher.update(str(random.random())) temp_name = hasher.hexdigest() temp_path = posixpath.join('/tmp', temp_name) target_path = remote_path if is_dir(remote_path): target_path = posixpath.join(remote_path, basename(local_path)) exists_ = exists(remote_path) if exists_: # put to temp location put(local_path, temp_path) # get hashes hash_old = run('shasum %s | cut -d \' \' -f 1' % (target_path)) hash_new = run('shasum %s | cut -d \' \' -f 1' % (temp_path)) if(hash_old == hash_new): run('rm %s' % (temp_path)) else: run('mv %s %s' % (temp_path, target_path)) else: put(local_path, target_path)
def directory(path, use_sudo=False, owner='', group='', mode=''): """ Require a directory to exist. :: from fabtools import require require.directory('/tmp/mydir', owner='alice', use_sudo=True) .. note:: This function can be accessed directly from the ``fabtools.require`` module for convenience. """ func = use_sudo and run_as_root or run if not is_dir(path): func('mkdir -p "%(path)s"' % locals()) # Ensure correct owner if (owner and _owner(path, use_sudo) != owner) or \ (group and _group(path, use_sudo) != group): func('chown %(owner)s:%(group)s "%(path)s"' % locals()) # Ensure correct mode if mode and _mode(path, use_sudo) != mode: func('chmod %(mode)s "%(path)s"' % locals())
def bzr_wc_target_exists_local_mods_force(): """ Test working copy when a target already exists and has local modifications and force was specified. """ test = 'bzr_wc_target_exists_local_mods_force' wt = '%s-test-%s' % (DIR, test) puts(magenta('Executing test: %s' % test)) from fabric.api import cd, run from fabtools.files import is_dir from fabtools import require require.bazaar.working_copy(REMOTE_URL, wt) assert is_dir(wt) with cd(wt): assert run('bzr status') == '' run('echo "# a new comment" >> __init__.py') assert run('bzr status') != '' require.bazaar.working_copy(REMOTE_URL, wt, force=True) assert run('bzr status %s' % wt) == ''
def bzr_wc_target_exists_local_mods_no_force(): """ Test working copy when a target already exists and has local modifications but force was not specified. """ test = 'bzr_wc_target_exists_local_mods_no_force' wt = '%s-test-%s' % (DIR, test) puts(magenta('Executing test: %s' % test)) from fabric.api import cd, run from fabtools.files import is_dir from fabtools import require require.bazaar.working_copy(REMOTE_URL, wt) assert is_dir(wt) with cd(wt): assert run('bzr status') == '' run('echo "# a new comment" >> __init__.py') assert run('bzr status') != '' try: require.bazaar.working_copy(REMOTE_URL, wt) except SystemExit: pass else: assert False, "working_copy didn't raise exception"
def source_fetch(): if not files.is_dir(SRC_DIR): with cd(HOME_DIRECTORY): run('git clone %s src' % (GIT_REPOSITORY,)) else: with cd(SRC_DIR): run('git pull')
def setup_s3cmd(aws_access_key_id, aws_secret_access_key, s3cfg=None): """ Install s3cmd for multipart uploads to Amazon S3 """ s3cfg = s3cfg if s3cfg is not None else DEFAULT_S3_CFG # Install s3cmd if not is_file('/usr/local/bin/s3cmd'): require.file(url='http://sourceforge.net/projects/s3tools/files/s3cmd/1.5.0-alpha1/s3cmd-1.5.0-alpha1.tar.gz') if not is_dir('s3cmd-1.5.0-alpha1'): run('tar xzf s3cmd-1.5.0-alpha1.tar.gz') with cd('s3cmd-1.5.0-alpha1'): require.deb.package('python-setuptools') sudo('python setup.py install') # Optional dependencies require.python.package('python-magic', use_sudo=True) # S3 config file (including credentials) require.file( '/var/lib/postgresql/.s3cfg', contents=s3cfg.format( aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key), use_sudo=True )
def temporary_directories(): """ Check temporary directories """ from fabtools.files import is_dir from fabtools.require.files import temporary_directory path1 = temporary_directory() path2 = temporary_directory() assert is_dir(path1) assert is_dir(path2) assert path1 != path2 run('rmdir %s' % quote(path1)) run('rmdir %s' % quote(path2))
def install_from_oracle_site(version=DEFAULT_VERSION): """ Download tarball from Oracle site and install JDK. :: import fabtools # Install Oracle JDK fabtools.oracle_jdk.install_from_oracle_site() """ prefix = '/opt' release, build = version.split('-') major, update = release.split('u') if len(update) == 1: update = '0' + update arch = _required_jdk_arch() self_extracting_archive = (major == '6') extension = 'bin' if self_extracting_archive else 'tar.gz' filename = 'jdk-%(release)s-linux-%(arch)s.%(extension)s' % locals() download_path = posixpath.join('/tmp', filename) url = 'http://download.oracle.com/otn-pub/java/jdk/'\ '%(version)s/%(filename)s' % locals() _download(url, download_path) # Prepare install dir install_dir = 'jdk1.%(major)s.0_%(update)s' % locals() with cd(prefix): if is_dir(install_dir): run_as_root('rm -rf %s' % quote(install_dir)) # Extract if self_extracting_archive: run('chmod u+x %s' % quote(download_path)) with cd('/tmp'): run_as_root('rm -rf %s' % quote(install_dir)) run_as_root('./%s' % filename) run_as_root('mv %s %s' % (quote(install_dir), quote(prefix))) else: with cd(prefix): run_as_root('tar xzvf %s' % quote(download_path)) # Set up link link_path = posixpath.join(prefix, 'jdk') if is_link(link_path): run_as_root('rm -f %s' % quote(link_path)) run_as_root('ln -s %s %s' % (quote(install_dir), quote(link_path))) # Remove archive run('rm -f %s' % quote(download_path)) _create_profile_d_file(prefix)
def update(commit=None): site_root = join(home_directory(SITE_USER), 'site') repodir = join(site_root, SITE_NAME) if not files.is_dir(repodir): with cd(site_root): su('git clone %s %s' % (SITE_REPO, SITE_NAME)) with cd(repodir): su('git fetch') if commit is None: commit = 'origin/master' su('git checkout %s' % commit)
def setup_tyr(): require.users.user('www-data') require_directories([env.tyr_base_instances_dir, env.tyr_basedir, ], owner=env.TYR_USER, group=env.TYR_USER, mode='755', use_sudo=True) require_directory(env.tyr_base_logdir, owner=env.TYR_USER, group=env.TYR_USER, mode='777', use_sudo=True) require_directory(env.tyr_base_destination_dir, is_on_nfs4=False, owner=env.TYR_USER, group=env.TYR_USER, mode='755', use_sudo=True) require.files.file(env.tyr_base_logfile, owner=env.TYR_USER, group=env.TYR_USER, mode='766', use_sudo=True) require.files.file(env.tyr_logfile_pattern, owner=env.TYR_USER, group=env.TYR_USER, mode='766', use_sudo=True) update_tyr_confs() if env.use_systemd: _upload_template('tyr/systemd_tyr_worker.jinja', env.service_name('tyr_worker'), user='******', mode='644', context={'env': env}) else: _upload_template('tyr/tyr_worker.jinja', env.service_name('tyr_worker'), user='******', mode='755', context={'env': env}) update_init(host='tyr') if not files.is_dir(env.tyr_migration_dir): idempotent_symlink('/usr/share/tyr/migrations/', env.tyr_migration_dir, use_sudo=True) sudo("chown www-data:www-data {}".format(env.tyr_migration_dir)) # we create a symlink for tyr manage_py tyr_symlink = os.path.join(env.tyr_basedir, 'manage.py') if not files.is_file(tyr_symlink): idempotent_symlink('/usr/bin/manage_tyr.py', tyr_symlink, use_sudo=True)
def homeassistant_dev(): """ Install homeassistant """ if not is_dir('/opt/home-assistant'): run_as_root('cd /opt/&& git clone https://github.com/balloob/home-assistant.git') with cd('/opt/home-assistant'): run_as_root('script/setup')
def directory(path, use_sudo=False, owner='', group='', mode=''): """ I can haz directory """ func = use_sudo and sudo or run if not is_dir(path): func('mkdir -p "%(path)s"' % locals()) if owner: func('chown %(owner)s:%(group)s "%(path)s"' % locals()) if mode: func('chmod %(mode)s "%(path)s"' % locals())
def test_create_user_with_default_home_directory(): from fabtools.user import create, exists try: create('user2') assert exists('user2') assert is_dir('/home/user2') finally: run_as_root('userdel -r user2', warn_only=True)
def test_create_user_without_home_directory(): from fabtools.user import create, exists try: create('user1', create_home=False) assert exists('user1') assert not is_dir('/home/user1') finally: run_as_root('userdel -r user1', warn_only=True)
def git_require_remote_url_and_path(): """ Test working_copy() with remote URL and path """ from fabric.api import cd, run from fabtools.files import is_dir from fabtools import require require.git.working_copy(REMOTE_URL, path='wc') assert is_dir('wc') assert is_dir('wc/.git') with cd('wc'): 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)' branch = run('git branch') assert branch == '* master'
def test_directory_creation(): from fabtools.require import directory try: directory('testdir') assert is_dir('testdir') assert owner('testdir') == env.user finally: run('rmdir testdir')
def test_create_system_user_without_home_directory(): from fabtools.user import create, exists try: create('user4', system=True) assert exists('user4') assert not is_dir('/home/user4') finally: run_as_root('userdel -r user4')
def git_require_branch(): """ Test checkout of a branch """ from fabric.api import cd, run from fabtools.files import is_dir from fabtools import require require.git.working_copy(REMOTE_URL, path='wc', branch='test_git') assert is_dir('wc') assert is_dir('wc/.git') with cd('wc'): 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)' branch = run('git branch') assert branch == 'master\r\n* test_git'
def test_create_system_user_with_home_directory(): from fabtools.user import create, exists try: create('user5', system=True, create_home=True, home='/var/lib/foo') assert exists('user5') assert is_dir('/var/lib/foo') finally: run_as_root('userdel -r user5', warn_only=True)
def fetch(git=''): """ Clone dotfiles project to ~/dotfiles """ cloned = False if 'dotfiles' in env: git = env.dotfiles # Check project is already cloned if git != '' and not is_dir('/home/%(user)s/dotfiles' % env): cmd = 'cd ; git clone %(git)s' % locals() run(cmd) cloned = True # update locally dotfiles dotfiles = '/home/%(user)s/dotfiles' % env if not cloned and not is_dir(dotfiles): abort(red("Please execute dotfiles.fetch")) cmd = 'cd %(dotfiles)s ; git pull' % locals() run(cmd)
def test_initial_owner_requirement(users): from fabtools.require import directory try: directory('testdir', owner='testuser', use_sudo=True) assert is_dir('testdir') assert owner('testdir') == 'testuser' finally: run_as_root('rmdir testdir')
def test_require_user_with_default_home(): from fabtools.require import user from fabtools.user import exists try: user('req2', create_home=True) assert exists('req2') assert is_dir('/home/req2') finally: run_as_root('userdel -r req2', warn_only=True)
def git_require_sudo(): """ Test working_copy() with sudo """ from fabric.api import cd, sudo from fabtools.files import group, is_dir, owner from fabtools import require require.git.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'
def test_git_require_branch(): """ Test checkout of a branch """ from fabtools.require.git import working_copy try: working_copy(REMOTE_URL, path='wc', branch='test_git') assert is_dir('wc') assert is_dir('wc/.git') with cd('wc'): 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() == 'test_git' finally: run('rm -rf wc')
def test_git_require_remote_url(): """ Test with remote URL only """ from fabtools.require.git import working_copy try: working_copy(REMOTE_URL) assert is_dir('fabtools') assert is_dir('fabtools/.git') with cd('fabtools'): 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' finally: run('rm -rf fabtools')
def test_require_virtualenv(): """ Test Python virtualenv creation """ from fabtools.require.python import virtualenv try: virtualenv('/tmp/venv') assert is_dir('/tmp/venv') assert is_file('/tmp/venv/bin/python') finally: run('rm -rf /tmp/venv')
def bzr_wc_default_target(): """ Test creating a working copy at a default target location. """ test = 'bzr_wc_default_target' puts(magenta('Executing test: %s' % test)) from fabtools.files import is_dir from fabtools import require assert not is_dir(DIR) require.bazaar.working_copy(REMOTE_URL) assert_wc_exists(DIR)
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 env_base_requirement(direct=True, sync_dotfiles='fabrecipes'): """ Install requirement base system """ pkgs = [ 'zsh', 'wget', 'netctl', 'dialog', 'yaourt', 'python2', 'ifplugd', 'net-tools', 'wpa_actiond', 'wpa_supplicant', ] # Check if a custom package for computer env_section = inspect.stack()[0][3] if 'pkgs' in env and env_section in env.pkgs: pkgs = list(set(pkgs + env.pkgs[env_section])) # Install required packages run_as_root('dirmngr </dev/null') run_as_root('pacman-key --init') run_as_root('pacman-key --populate archlinux') run_as_root('pacman-key --refresh-keys') run_as_root('pacman --noconfirm -Syyu') run_as_root('pacman-db-upgrade') require.arch.packages(pkgs, options=["--noconfirm"]) # Install oh-my-zsh ohmyzsh = '$HOME/.oh-my-zsh' if not is_dir(ohmyzsh): run( 'git clone git://github.com/robbyrussell/oh-my-zsh.git %(ohmyzsh)s' % locals() ) # Set default ZSH shell for user if user.exists(env.useraccount): user.modify(env.useraccount, shell='/usr/bin/zsh') # Synchronize user dotfiles sync_dotfiles = 'fabrecipes/autoinstall/%(env_section)s' % locals() dotfiles.sync('%(sync_dotfiles)s/user/' % locals(), '$HOME/') dotfiles.sync('%(sync_dotfiles)s/sys/' % locals(), '/', use_sudo='true')
def bzr_wc_source_remote(): """ Test creating working copy from a remote source. """ test = 'bzr_wc_source_remote' wt = '%s-test-%s' % (DIR, test) puts(magenta('Executing test: %s' % test)) from fabtools.files import is_dir from fabtools import require assert not is_dir(wt) require.bazaar.working_copy(REMOTE_URL, wt) assert_wc_exists(wt)
def jsl_acer_inspireone_fix(): """ Fix for Acer Aspire One netbook - set xorg modesetting - disable numlock in notebook """ xorgconf = '/etc/X11/xorg.conf.d/20-gpudriver.conf' if not is_dir(xorgconf): append(xorgconf, 'Section "Device"') append(xorgconf, ' Identifier "gma500_gfx"') append(xorgconf, ' Driver "modesetting"') append(xorgconf, ' Option "SWCursor" "ON"') append(xorgconf, 'EndSection') # Configure slim slim_file = '/etc/slim.conf' comment(slim_file, '^numlock.*')
def setup_app(): """ Setup the application """ if not exists(user): puts(green("Creating user: {0}".format(user))) create(user, comment="logparser applicaiton user", system=True, shell="/sbin/nologin") if not is_dir("/var/log/{0}".format(app)): with cd("/var/log"): require.files.directory(app, owner=user, group=user, use_sudo=True) with cd("{0}/{1}".format(app_dir, app)): if not virtualenv_exists("{0}_env".format(app)): sudo("virtualenv {0}_env".format(app)) if virtualenv_exists("{0}_env".format(app)): with virtualenv("{0}_env".format(app)): sudo("pip install -r requirements.txt", )
def bzr_wc_version(): """ Test creating a working copy at a specified revision. """ test = 'bzr_wc_version' wt = '%s-test-%s' % (DIR, test) puts(magenta('Executing test: %s' % test)) from fabric.api import run from fabtools.files import is_dir from fabtools import require assert not is_dir(wt) require.bazaar.working_copy(REMOTE_URL, wt, version='2') assert_wc_exists(wt) assert run('bzr revno %s' % wt) == '2'
def sync(src, dst, force_sync=True, use_sudo='false'): """ Copy file from dotfiles dot dst """ use_sudo = use_sudo.lower() == 'true' # Update dotfiles if force_sync: fetch() # Synchronize system dotfiles = '/home/%(user)s/dotfiles' % env env_dotfiles = '%(dotfiles)s/%(src)s' % locals() if is_dir(env_dotfiles): with settings(hide('running', 'stdout', 'stderr', 'warnings'), warn_only=True): cmd = 'rsync -avr --exclude ".git/" "%(env_dotfiles)s" "%(dst)s"' % locals() if use_sudo: sudo(cmd) else: run(cmd)
def bzr_wc_source_local(): """ Test creating working copy from a local source. Note: this requires bzr to be installed on local host, if bzr is not available, this test is skipped with a warning. """ test = 'bzr_wc_source_local' wt = '%s-test-%s' % (DIR, test) puts(magenta('Executing test: %s' % test)) import os from fabric.api import lcd, local, settings if not os.getenv('BZR_LOCAL_TEST'): puts(('%s: SKIP: interactive test, ' 'set BZR_LOCAL_TEST env var to enable') % test) return with settings(warn_only=True): bzr = local('which bzr', capture=True) if bzr.failed: puts('%s: SKIP: Bazaar not installed on local host' % test) return from fabtools.files import is_dir from fabtools import require local('test ! -e %(wt)s || rm -rf %(wt)s' % {'wt': wt}) local('bzr branch %s %s' % (REMOTE_URL, wt)) assert not is_dir(wt) with lcd(wt): require.bazaar.working_copy('.', wt) assert_wc_exists(wt) local('rm -rf %s' % wt)
def directory(path, use_sudo=False, owner='', group='', mode=''): """ Require a directory to exist. :: from fabtools import require require.directory('/tmp/mydir', owner='alice') .. note:: this function can be accessed directly from the ``fabtools.require`` module for convenience. """ func = use_sudo and sudo or run if not is_dir(path): func('mkdir -p "%(path)s"' % locals()) if owner: func('chown %(owner)s:%(group)s "%(path)s"' % locals()) if mode: func('chmod %(mode)s "%(path)s"' % locals())
def bzr_wc_target_exists_plain_force(): """ Test working copy when target is an already existing plain directory and force was specified. """ test = 'bzr_wc_target_exists_plain_force' wt = '%s-test-%s' % (DIR, test) puts(magenta('Executing test: %s' % test)) from fabric.api import run from fabtools.files import is_dir from fabtools import require run('mkdir %s' % wt) assert not is_dir(path.join(wt, '.bzr')) require.bazaar.working_copy(REMOTE_URL, wt, force=True) assert_wc_exists(wt)
def bzr_wc_sudo(): """ Test working copy with sudo. """ test = 'bzr_wc_sudo' wt = '%s-test-%s' % (DIR, test) puts(magenta('Executing test: %s' % test)) from fabric.api import sudo from fabtools.files import group, is_dir, owner from fabtools import require assert not is_dir(wt) require.bazaar.working_copy(REMOTE_URL, wt, use_sudo=True) assert_wc_exists(wt) assert owner(wt) == 'root' assert group(wt) == 'root'
def root_rsync(local_dir, remote_dir, exclude=[], delete=False): def _end_with_slash(dir_path): if dir_path[-1] == '/': return dir_path else: return dir_path + '/' local_dir = _end_with_slash(local_dir) remote_dir = _end_with_slash(remote_dir) m = hashlib.md5() m.update(remote_dir) me = local('whoami', capture=True) remote_tmp_dir = '/tmp/%s/%s/' % (me, m.hexdigest()) run('mkdir -p %s' % remote_tmp_dir) if is_dir(remote_dir): run('rsync -a %s %s' % (remote_dir, remote_tmp_dir)) # already exists rsync_project(remote_dir=remote_tmp_dir, local_dir=local_dir, exclude=exclude, delete=delete) sudo('rsync -a %s %s' % (remote_tmp_dir, remote_dir))
def setupsupervisor(): """ Setup supervisor on remote host. """ if not is_installed("supervisor"): puts(green("Installing supervisor.")) sudo("pip install supervisor") if not exists("supervisor"): puts(green("Creating supervisor user")) create("supervisor", comment="supervisord user", system=True) supervisor_context = {"logpath": "/var/log/supervisord.log"} puts(green("Uploading supervisord.conf")) upload_template("templates/supervisord.conf", "/etc/supervisord.conf", \ context=supervisor_context, mode=0700, use_sudo=True) texts = ["[include]", "files=/etc/supervisor.d/*.conf"] for text in texts: if not contains("/etc/supervisord.conf", text, use_sudo=True): append("/etc/supervisord.conf", text, use_sudo=True) with cd("/etc"): if not is_dir("supervisor.d"): puts(green("Making supervisor.d configuration directory")) sudo("mkdir supervisor.d") sudo("chown supervisor:root -R supervisor.d") sudo("chown supervisor:root supervisord.conf") with cd("init.d"): if not is_file("supervisord"): puts(green("Uploading supervisord startup script")) put(local_path="files/supervisord", remote_path="/etc/init.d/supervisord", \ mode=0700, use_sudo=True) sudo("chown supervisor:root supervisord") puts(green("Starting supervisord service")) sudo("chkconfig --add supervisord") sudo("chkconfig --level 3 supervisord on") sudo("service supervisord start") with cd("/var/log"): if not is_file("supervisord.log"): puts(green("Creating supervisor log file")) sudo( "touch supervisord.log && chown supervisor:root supervisord.log" )
def bzr_wc_target_exists_version(): """ Test updating a working copy when a target already exists. """ test = 'bzr_wc_target_exists_version' wt = '%s-test-%s' % (DIR, test) puts(magenta('Executing test: %s' % test)) from fabric.api import run from fabtools.files import is_dir from fabtools import require assert not is_dir(wt) require.bazaar.working_copy(REMOTE_URL, wt, version='2') require.bazaar.working_copy(REMOTE_URL, wt, version='4', update=True) assert_wc_exists(wt) assert run('bzr revno %s' % wt) == '4'
def bzr_wc_sudo_user(): """ Test working copy with sudo as a user. """ test = 'bzr_wc_sudo_user' wt = '%s-test-%s' % (DIR, test) puts(magenta('Executing test: %s' % test)) from fabric.api import cd, sudo from fabtools.files import group, is_dir, owner from fabtools import require require.user('bzruser', group='bzrgroup') assert not is_dir(wt) require.bazaar.working_copy(REMOTE_URL, wt, use_sudo=True, user='******') assert_wc_exists(wt) assert owner(wt) == 'bzruser' assert group(wt) == 'bzrgroup'