Last active
December 30, 2015 10:39
-
-
Save termie/7817384 to your computer and use it in GitHub Desktop.
example code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from fabric import tasks | |
| from fabric.api import env | |
| env.skip_missing_roles = True | |
| # Copied from https://github.com/fabric/fabric with a small change to | |
| # use our class instead of the default | |
| def task(*args, **kwargs): | |
| """ | |
| Decorator declaring the wrapped function to be a new-style task. | |
| May be invoked as a simple, argument-less decorator (i.e. ``@task``) or | |
| with arguments customizing its behavior (e.g. ``@task(alias='myalias')``). | |
| Please see the :ref:`new-style task <task-decorator>` documentation for | |
| details on how to use this decorator. | |
| .. versionchanged:: 1.2 | |
| Added the ``alias``, ``aliases``, ``task_class`` and ``default`` | |
| keyword arguments. See :ref:`task-decorator-arguments` for details. | |
| .. versionchanged:: 1.5 | |
| Added the ``name`` keyword argument. | |
| .. seealso:: `~fabric.docs.unwrap_tasks`, `~fabric.tasks.WrappedCallableTask` | |
| """ | |
| invoked = bool(not args or kwargs) | |
| task_class = kwargs.pop("task_class", AdvancedRolesTask) | |
| if not invoked: | |
| func, args = args[0], () | |
| def wrapper(func): | |
| return task_class(func, *args, **kwargs) | |
| return wrapper if invoked else wrapper(func) | |
| def build_real_roles(roles): | |
| all_roles = env.roledefs.keys() | |
| out_roles = set() | |
| # Special role that resolves to all defined hosts. | |
| if 'all' in roles: | |
| out_roles.add(all_roles) | |
| for role in roles: | |
| if role == 'all': | |
| continue | |
| if role.startswith('+'): | |
| out_roles.add(role[1:]) | |
| elif role.startswith('-'): | |
| out_roles.discard(role[1:]) | |
| else: | |
| # If we skip missing check whether this role is defined first | |
| if env.skip_missing_roles: | |
| if role in all_roles: | |
| out_roles.add(role) | |
| else: | |
| out_roles.add(role) | |
| print list(out_roles) | |
| return list(out_roles) | |
| class AdvancedRolesTask(tasks.WrappedCallableTask): | |
| """Task that adds some additional features to roles. | |
| Allows: | |
| Prepending a role with '+' to require include. | |
| Prepending a role with a '-' to force exclude. | |
| A special role 'all' that resolves to all the roles. | |
| By default skips roles that are missing. | |
| """ | |
| def get_hosts(self, *args, **kw): | |
| roles = build_real_roles(getattr(self, 'roles', [])) | |
| setattr(self, 'roles', roles) | |
| return super(AdvancedRolesTask, self).get_hosts(*args, **kw) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| @roles('all') | |
| @parallel | |
| @task | |
| def hosts(): | |
| hostsfile = util.files('farmboy/hosts') | |
| hosts = [] | |
| # TODO(termie): does this break if we use callable roledefs? | |
| for role, role_hosts in env.roledefs.iteritems(): | |
| if len(role_hosts) == 1: | |
| hosts.append('%s %s' % (util.host(role_hosts[0]), role)) | |
| continue | |
| for i, role_host in enumerate(role_hosts): | |
| hosts.append('%s %s-%s' % (util.host(role_host), role, i)) | |
| hosts_str = '\n'.join(hosts) | |
| print hosts_str | |
| fabtools.require.files.template_file( | |
| template_source = hostsfile, | |
| context = {'hosts': hosts_str}, | |
| path = '/etc/hosts', | |
| owner = 'root', | |
| group = 'root', | |
| mode = '644', | |
| use_sudo = True) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment