fab-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Fab-user] Different roledefs per task


From: Francisco José Marques Vieira
Subject: Re: [Fab-user] Different roledefs per task
Date: Tue, 18 Dec 2012 20:12:01 +0000
User-agent: Mozilla/5.0 (X11; Linux i686; rv:17.0) Gecko/17.0 Thunderbird/17.0

Wow, this actually worked! And looks better than I ever hoped!

Now my fab_settings.py file looks like this:

--------------------------------------
from fabric.api import env

if env.get('group') == 'staging':
    ROLEDEFS = {
        'master': [
            'staging.host.01',
        ],
        'slaves': [
            'staging.host.02',
            'staging.host.03',
        ],
    }
elif env.get('group') == 'production':
    ROLEDEFS = {
        'master': [
            'production.host.01',
        ],
        'slaves': [
            'production.host.02',
            'production.host.03',
        ],
    }
else:
ROLEDEFS = {} # This is required to avoid breaking the fabfile and thus breaking every fab command like fab -l
--------------------------------------


Then in my fabfile.py I have this:

--------------------------------------
from fab_settings import ROLEDEFS

env.roledefs = ROLEDEFS

@task
@roles('master')
def task1():
        ...

@task
@roles('slaves')
def task2():
        ...
--------------------------------------

And I can call the tasks like this:

--------------------------------------
fab task1 --set group=staging
--------------------------------------

So, the settings file became even simpler, and I can now have tasks for different roles in the same file while still being able to run them only in staging or production. And the only downside is that I have to use "--set group=staging" instead of just "-R staging"! xD

Thanks a lot, to you and to Fabric developers!
Francisco Vieira





On 12/18/2012 07:05 PM, Todd DeLuca wrote:
This *might* answer your question.  I recommend providing more example
code or output when posting to reduce ambiguity.


The following fabfile.py allows you to define some tasks to run on
"master" hosts and some on "slave" hosts.  You can then vary which hosts
apply to these roles by using "prod" or "stage" to define env.roledefs
when fabfile.py is imported.  Below I demonstrate using different
command line syntaxes to accomplish the same thing, either `-R <role>`
or `--set de=<role>` or using a task `<role>`.  I've used all 3 of these
syntaxes in various fabfiles, depending on my mood the day I wrote them.
  Personally I would avoid using `-R` to define `env.roledefs`, since
they already have a different semantic association.

The demo fabfile.py:

from fabric.api import *

# Using -R to set roledefs
if 'prod' in env.roles:
     env.roledefs = {'master': ['host1'], 'slave': ['host2', 'host3']}
elif 'stage' in env.roles:
     env.roledefs = {'master': ['host4'], 'slave': ['host5', 'host6']}


# Using --set to set roledefs
if env.get('de') == 'prod':
     env.roledefs = {'master': ['host1'], 'slave': ['host2', 'host3']}
elif env.get('de') == 'stage':
     env.roledefs = {'master': ['host4'], 'slave': ['host5', 'host6']}


# Using tasks to set roledefs
@task
def prod():
     env.roledefs = {'master': ['host1'], 'slave': ['host2', 'host3']}


@task
def stage():
     env.roledefs = {'master': ['host4'], 'slave': ['host5', 'host6']}


# Roles to be executed on different sets of hosts
@roles('master')
@task
def do_master():
     print env.host_string

@roles('slave')
@task
def do_slave():
     print env.host_string



Here you can see that the effect is the same no matter which command
line syntax you use (though your edge cases might vary):

$ fab --set de=prod do_master do_slave
[host1] Executing task 'do_master'
host1
[host2] Executing task 'do_slave'
host2
[host3] Executing task 'do_slave'
host3

Done.
$ fab --set de=stage do_master do_slave
[host4] Executing task 'do_master'
host4
[host5] Executing task 'do_slave'
host5
[host6] Executing task 'do_slave'
host6

Done.
$ fab -R prod do_master do_slave
[host1] Executing task 'do_master'
host1
[host2] Executing task 'do_slave'
host2
[host3] Executing task 'do_slave'
host3

Done.
$ fab -R stage do_master do_slave
[host4] Executing task 'do_master'
host4
[host5] Executing task 'do_slave'
host5
[host6] Executing task 'do_slave'
host6

Done.
$ fab prod do_master do_slave
[host1] Executing task 'do_master'
host1
[host2] Executing task 'do_slave'
host2
[host3] Executing task 'do_slave'
host3

Done.
$ fab stage do_master do_slave
[host4] Executing task 'do_master'
host4
[host5] Executing task 'do_slave'
host5
[host6] Executing task 'do_slave'
host6

Done.

Hope that helps,
Todd


On Tue, Dec 18, 2012 at 11:50 AM, Francisco José Marques Vieira
<address@hidden <mailto:address@hidden>>
wrote:

    Hi everyone! This is my first post on this mailing list, so please
    excuse me if I don't follow some rule or convention of yours.
    My name is Francisco and I started using Fabric a couple weeks ago,
    and so far I'm happy with what I've seen.
    Nevertheless, there always comes a time when even the best tool
    fails to accomplish some task, and that's why I'm here.

    The thing is, I have two different ways to group my hosts: one is by
    role (master or slave), the other is by staging or production, i.e.
    there is a master and many slaves in staging, and another master and
    many slaves in production.
    I have tasks that I need to run only on the master and others to run
    in the slaves. Also, I want to be able to run tasks only on staging
    or only on production.

    The way I've been handling this is by having two different roledefs,
    one for master hosts and another for slaves. Each roledef has two
    roles, staging and production, meaning I can do something like "fab
    deploy -R staging" and this makes sure I won't be installing things
    into production by mistake.
    These roledefs are defined in a settings file and each fabfile of
    mine imports one of them and sets env.roledefs to it.

    This works as long as all the tasks in each file are to be executed
    in hosts with the same role, either master or slaves. And so far
    that's what happened naturally.
    Now I have a fabfile which has some tasks that should run in the
    master host and another task that should run in the slaves, but I
    have no way of saying to fabric "please use a different roledef for
    this task", since by the time my code inside the task starts to
    execute, the roledefs have already been processed.
    Is there any way around this which does not require me to separate
    the tasks in two different files?

    Francisco Vieira


    P.S: Sorry for the such a big post for such a trivial matter...

    _________________________________________________
    Fab-user mailing list
    address@hidden <mailto:address@hidden>
    https://lists.nongnu.org/__mailman/listinfo/fab-user
    <https://lists.nongnu.org/mailman/listinfo/fab-user>




--
Todd DeLuca
http://todddeluca.com
http://wall.hms.harvard.edu/






reply via email to

[Prev in Thread] Current Thread [Next in Thread]