0
# Decorators and Tasks
1
2
Decorators and functions for defining Fabric tasks, specifying target hosts and roles, controlling execution patterns, and managing the task execution lifecycle. These components enable the creation of reusable deployment scripts and automation workflows.
3
4
## Capabilities
5
6
### Task Definition
7
8
Core decorator for marking Python functions as Fabric tasks that can be executed via the command line interface.
9
10
```python { .api }
11
def task(*args, **kwargs):
12
"""
13
Decorator to mark functions as Fabric tasks.
14
15
Args:
16
*args: Positional arguments passed to task function
17
**kwargs: Keyword arguments for task configuration
18
name (str): Custom task name (default: function name)
19
aliases (list): Alternative names for the task
20
default (bool): Make this the default task
21
22
Returns:
23
Decorated function that can be executed as a Fabric task
24
"""
25
```
26
27
**Usage Examples:**
28
29
```python
30
from fabric.api import task, run, sudo
31
32
# Basic task definition
33
@task
34
def deploy():
35
"""Deploy the application"""
36
run('git pull origin master')
37
sudo('systemctl restart nginx')
38
39
# Task with custom name
40
@task(name='db-backup')
41
def backup_database():
42
"""Create database backup"""
43
run('pg_dump myapp > backup.sql')
44
45
# Task with aliases
46
@task(aliases=['up'])
47
def update():
48
"""Update system packages"""
49
sudo('apt-get update && apt-get upgrade')
50
51
# Default task (runs when no task specified)
52
@task(default=True)
53
def status():
54
"""Show system status"""
55
run('uptime')
56
run('df -h')
57
58
# Task with parameters
59
@task
60
def restart_service(service_name):
61
"""Restart a specific service"""
62
sudo(f'systemctl restart {service_name}')
63
64
# Execute with: fab restart_service:nginx
65
```
66
67
### Host and Role Specification
68
69
Decorators for specifying which hosts or roles a task should execute against, enabling targeted deployment and management operations.
70
71
```python { .api }
72
def hosts(*host_list):
73
"""
74
Decorator to specify target hosts for a task.
75
76
Args:
77
*host_list: List of host strings (user@host:port format)
78
79
Returns:
80
Decorated function that executes on specified hosts
81
"""
82
83
def roles(*role_list):
84
"""
85
Decorator to specify target roles for a task.
86
87
Args:
88
*role_list: List of role names defined in env.roledefs
89
90
Returns:
91
Decorated function that executes on hosts with specified roles
92
"""
93
```
94
95
**Usage Examples:**
96
97
```python
98
from fabric.api import task, hosts, roles, run, env
99
100
# Execute on specific hosts
101
@task
102
@hosts('user@web1.example.com', 'user@web2.example.com:2222')
103
def deploy_web():
104
"""Deploy to web servers"""
105
run('git pull origin master')
106
107
# Execute on role-based hosts
108
env.roledefs = {
109
'web': ['web1.example.com', 'web2.example.com'],
110
'db': ['db1.example.com'],
111
'cache': ['redis1.example.com', 'redis2.example.com']
112
}
113
114
@task
115
@roles('web')
116
def update_web():
117
"""Update web servers"""
118
sudo('apt-get update')
119
120
@task
121
@roles('db')
122
def backup_db():
123
"""Backup database servers"""
124
run('pg_dump myapp > /backups/$(date +%Y%m%d).sql')
125
126
# Multiple roles
127
@task
128
@roles('web', 'cache')
129
def restart_services():
130
"""Restart services on web and cache servers"""
131
sudo('systemctl restart nginx')
132
133
# Combine with other decorators
134
@task
135
@hosts('admin@mgmt.example.com')
136
@runs_once
137
def deploy_config():
138
"""Deploy configuration from management server"""
139
run('ansible-playbook deploy.yml')
140
```
141
142
### Execution Control
143
144
Decorators for controlling how and when tasks execute, including execution frequency, parallelism, and settings management.
145
146
```python { .api }
147
def runs_once(func):
148
"""
149
Decorator to ensure function runs only once per session.
150
151
Args:
152
func: Function to decorate
153
154
Returns:
155
Decorated function that executes only once regardless of host count
156
"""
157
158
def serial(func):
159
"""
160
Decorator to force sequential execution.
161
162
Args:
163
func: Function to decorate
164
165
Returns:
166
Decorated function that executes serially across hosts
167
"""
168
169
def parallel(pool_size=None):
170
"""
171
Decorator to force parallel execution.
172
173
Args:
174
pool_size (int): Maximum concurrent connections (default: unlimited)
175
176
Returns:
177
Decorator function for parallel execution
178
"""
179
```
180
181
**Usage Examples:**
182
183
```python
184
from fabric.api import task, runs_once, serial, parallel, run, local
185
186
# Run only once regardless of host count
187
@task
188
@runs_once
189
def build_assets():
190
"""Build static assets locally once"""
191
local('npm run build')
192
local('tar czf assets.tar.gz dist/')
193
194
# Force sequential execution even with parallel enabled
195
@task
196
@serial
197
def database_migration():
198
"""Run database migrations sequentially"""
199
run('python manage.py migrate')
200
201
# Force parallel execution with connection limit
202
@task
203
@parallel(pool_size=5)
204
def update_packages():
205
"""Update packages on all hosts in parallel"""
206
sudo('apt-get update && apt-get upgrade -y')
207
208
# Combine execution control decorators
209
@task
210
@roles('web')
211
@parallel(pool_size=3)
212
def rolling_restart():
213
"""Restart services in parallel batches"""
214
sudo('systemctl restart nginx')
215
run('sleep 10') # Brief pause between restarts
216
217
@task
218
@hosts('build.example.com')
219
@runs_once
220
def prepare_release():
221
"""Prepare release package once"""
222
run('git tag v$(date +%Y%m%d)')
223
run('make dist')
224
```
225
226
### Settings Management
227
228
Decorator for applying temporary environment settings to task execution, equivalent to wrapping task body in settings context manager.
229
230
```python { .api }
231
def with_settings(*arg_settings, **kw_settings):
232
"""
233
Decorator equivalent of settings() context manager.
234
235
Args:
236
*arg_settings: Context managers to apply
237
**kw_settings: Environment variables to temporarily override
238
239
Returns:
240
Decorated function with temporary settings applied
241
"""
242
```
243
244
**Usage Examples:**
245
246
```python
247
from fabric.api import task, with_settings, run, hide, warn_only
248
249
# Apply settings to entire task
250
@task
251
@with_settings(warn_only=True)
252
def optional_cleanup():
253
"""Cleanup that continues on errors"""
254
run('rm -f /tmp/old_files*')
255
run('service optional-service stop')
256
257
# Hide output for entire task
258
@task
259
@with_settings(hide('stdout'))
260
def silent_check():
261
"""Perform checks silently"""
262
result = run('systemctl is-active nginx')
263
if result.failed:
264
print("Nginx is not running")
265
266
# Complex settings combination
267
@task
268
@with_settings(
269
hide('running', 'stdout'),
270
warn_only=True,
271
parallel=True
272
)
273
def health_check():
274
"""Check health across all hosts"""
275
result = run('curl -s http://localhost/health')
276
if 'OK' in result:
277
print(f"Host {env.host} is healthy")
278
279
# Combine with other decorators
280
@task
281
@roles('web')
282
@with_settings(user='deploy', key_filename='/path/to/deploy_key')
283
def deploy_as_user():
284
"""Deploy using specific user credentials"""
285
run('git pull origin master')
286
run('npm install --production')
287
```
288
289
### Task Execution
290
291
Function for programmatically executing tasks with host/role resolution and argument passing.
292
293
```python { .api }
294
def execute(task, *args, **kwargs):
295
"""
296
Execute task with host/role resolution.
297
298
Args:
299
task: Task function to execute or task name string
300
*args: Positional arguments to pass to task
301
**kwargs: Keyword arguments to pass to task
302
303
Keyword Args:
304
hosts (list): Override hosts for execution
305
roles (list): Override roles for execution
306
307
Returns:
308
dict: Results keyed by host string
309
"""
310
```
311
312
**Usage Examples:**
313
314
```python
315
from fabric.api import task, execute, run, env
316
317
@task
318
def uptime():
319
"""Get system uptime"""
320
return run('uptime')
321
322
@task
323
def disk_usage(path='/'):
324
"""Check disk usage for path"""
325
return run(f'df -h {path}')
326
327
# Execute tasks programmatically
328
@task
329
def system_check():
330
"""Comprehensive system check"""
331
# Execute on current hosts
332
uptimes = execute(uptime)
333
disk_info = execute(disk_usage, '/var/log')
334
335
# Execute on specific hosts
336
db_status = execute(uptime, hosts=['db1.example.com'])
337
338
# Execute with roles
339
web_disk = execute(disk_usage, '/var/www', roles=['web'])
340
341
# Process results
342
for host, result in uptimes.items():
343
print(f"{host}: {result.strip()}")
344
345
# Execute by task name
346
@task
347
def deploy():
348
"""Full deployment process"""
349
execute('build_assets') # Task name as string
350
execute('update_code')
351
execute('restart_services')
352
353
# Conditional execution
354
@task
355
def conditional_deploy():
356
"""Deploy based on conditions"""
357
if env.environment == 'production':
358
execute(deploy, hosts=['prod1.com', 'prod2.com'])
359
else:
360
execute(deploy, hosts=['staging.com'])
361
```
362
363
## Task Classes
364
365
Advanced task definition using class-based approach for complex task hierarchies and reusable task components.
366
367
```python { .api }
368
class Task:
369
"""
370
Abstract base class for custom tasks.
371
372
Attributes:
373
name (str): Task name for CLI
374
aliases (list): Alternative names
375
is_default (bool): Whether this is the default task
376
"""
377
378
class WrappedCallableTask(Task):
379
"""
380
Wrapper for regular functions as tasks.
381
382
Args:
383
callable: Function to wrap as task
384
name (str): Custom task name
385
aliases (list): Task aliases
386
default (bool): Make default task
387
"""
388
```
389
390
**Usage Examples:**
391
392
```python
393
from fabric.api import Task, run, sudo
394
395
class DatabaseTask(Task):
396
"""Base class for database tasks"""
397
398
def __init__(self, db_name):
399
self.db_name = db_name
400
self.name = f'db_{db_name}'
401
402
def run(self):
403
"""Override this method in subclasses"""
404
raise NotImplementedError
405
406
class BackupTask(DatabaseTask):
407
"""Database backup task"""
408
409
def run(self):
410
backup_file = f'/backups/{self.db_name}_{datetime.now().strftime("%Y%m%d")}.sql'
411
run(f'pg_dump {self.db_name} > {backup_file}')
412
return backup_file
413
414
# Register custom tasks
415
backup_main = BackupTask('maindb')
416
backup_analytics = BackupTask('analytics')
417
418
# Use in fabfile or programmatically
419
results = execute(backup_main)
420
```
421
422
## Command Line Integration
423
424
Tasks integrate with the `fab` command-line tool for execution:
425
426
```bash
427
# Execute single task
428
fab deploy
429
430
# Execute task with arguments
431
fab restart_service:nginx
432
433
# Execute on specific hosts
434
fab -H web1.com,web2.com deploy
435
436
# Execute with roles
437
fab -R web,cache update
438
439
# List available tasks
440
fab --list
441
442
# Get task help
443
fab --help deploy
444
445
# Parallel execution
446
fab --parallel deploy
447
448
# Set environment variables
449
fab -s user=deploy -s key_filename=/path/to/key deploy
450
```
451
452
Task functions can access command-line provided settings through the global `env` dictionary:
453
454
```python
455
@task
456
def deploy(branch='master'):
457
"""Deploy specific branch"""
458
print(f"Deploying branch: {branch}")
459
print(f"Target hosts: {env.hosts}")
460
print(f"User: {env.user}")
461
run(f'git checkout {branch}')
462
run('git pull origin {branch}')
463
```