fab-user
[Top][All Lists]
Advanced

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

[Fab-user] [PATCH] Fix #7: Implement "something like roles."


From: Christian Vest Hansen
Subject: [Fab-user] [PATCH] Fix #7: Implement "something like roles."
Date: Thu, 6 Nov 2008 21:32:50 +0100

Actually, what this gives is a way to simulate roles.

We allow fab_hosts (and other places) to be a string rather
than a list of hosts. This string will then be used to
look up a variable that contains the real list of hosts to
connect to.

So we can have fabfiles like this:

config.servers = ['localhost', '127.0.0.1']
def prod():
  config.servers = ['...', '...']
@hosts('servers')
def deploy():
  run('stuff on $(fab_host)')

Here, we are allowed to define as many variables with lists
of hosts as we want, and we can change them any time we want.
---
 TODO                         |    3 ---
 doc/samples/roles/fabfile.py |   14 ++++++--------
 fabric.py                    |   18 +++++++++++++-----
 3 files changed, 19 insertions(+), 16 deletions(-)

diff --git a/TODO b/TODO
index 183a74d..ea4969e 100644
--- a/TODO
+++ b/TODO
@@ -1,7 +1,4 @@
 1   Ctrl-C dosn't quite work... especially not with the tail example
-7   need something like roles in Capistrano
-    - I'm thinking the ability to work with variable environments as
first class
-      objects
 9   make parallel submode work
 11  add built-in help for built-in variables
     - and modes and submodes
diff --git a/doc/samples/roles/fabfile.py b/doc/samples/roles/fabfile.py
index 169fa8a..fd54c53 100644
--- a/doc/samples/roles/fabfile.py
+++ b/doc/samples/roles/fabfile.py
@@ -1,27 +1,25 @@

 # Our server roles:
-rdbms = ['127.0.0.1']
-httpd = ['localhost']
+config.rdbms = ['127.0.0.1']
+config.httpd = ['localhost']

 def production():
     # this would set `rdbms` and `httpd` to prod. values.
     # for now we just switch them around in order to observe the effect
-    global httpd, rdbms
-    rdbms, httpd = httpd, rdbms
-    # ... except, this dosn't actually work :(
+    config.rdbms, config.httpd = config.httpd, config.rdbms

 def build():
     local('echo Building project')

address@hidden(*rdbms)
address@hidden('rdbms')
 def prepare_db():
     run("echo Preparing database for deployment")

address@hidden(*httpd)
address@hidden('httpd')
 def prepare_web():
     run("echo Preparing web servers for deployment")

 @depends(prepare_db, prepare_web)
address@hidden(*httpd)
address@hidden('httpd')
 def deploy():
     run("echo Doing final deployment things to $(fab_host)")
diff --git a/fabric.py b/fabric.py
index 952f94b..c1ae55a 100644
--- a/fabric.py
+++ b/fabric.py
@@ -1250,21 +1250,29 @@ def _args_hash(args):
     return hash(tuple(sorted(args.items())))

 def _execute_at_target(command, args):
-    ENV['fab_local_mode'] = getattr(command, 'mode', ENV['fab_mode'])
-    ENV['fab_local_hosts'] = getattr(command, 'hosts', ENV.get('fab_hosts'))
+    mode = ENV['fab_local_mode'] = getattr(command, 'mode', ENV['fab_mode'])
+    hosts = ENV['fab_local_hosts'] = getattr(
+        command, 'hosts', ENV.get('fab_hosts'))
+    if hosts and len(hosts) == 1 and isinstance(hosts[0], basestring):
+        # we allow the hosts to be a string-alias for another variable
+        # that will contain the real array of hosts to connect to.
+        host_alias = _lazy_format(hosts[0])
+        hosts = ENV.get(host_alias)
+        print "Resoling host alias", host_alias, "to", (', '.join(hosts))
+        ENV['fab_local_hosts'] = hosts
     # Determine whether we need to connect for this command, do so if so
     if _needs_connect(command):
         _check_fab_hosts()
         _connect()
-    if ENV['fab_local_mode'] in ('rolling', 'fanout'):
+    if mode in ('rolling', 'fanout'):
         print("Warning: The 'rolling' and 'fanout' fab_modes are " +
               "deprecated.\n   Use 'broad' and 'deep' instead.")
         ENV['fab_local_mode'] = 'broad'
     # Run command once, with each operation running once per host.
-    if ENV['fab_local_mode'] == 'broad':
+    if mode == 'broad':
         command(**(args or {}))
     # Run entire command once per host.
-    elif ENV['fab_local_mode'] == 'deep':
+    elif mode == 'deep':
         # Gracefully handle local-only commands
         if CONNECTIONS:
             for host_conn in CONNECTIONS:
-- 
1.6.0.1

Attachment: 0001-Fix-7-Implement-something-like-roles.patch
Description: Binary data


reply via email to

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