Nitin Tripathi
Nitin Tripathi

Reputation: 491

fabric.api execute stuck in loop

Please find the my fabfile.py content below. You may like to change the list of env.hosts to check for yourself.

Kindly note that direct call to chk_* methods would get execute but then also execute against unintended hosts for e.g. chk_kafka also execute against zookeeper group of nodes.

Any help is appreciated. Thanks for bearing with me.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
    auto ssh
"""
import os
from fabric.colors import *
from fabric.api import *
from fabric.context_managers import *
from fabric.contrib.console import confirm

env.user = 'centos'
env.password = 'centos'

env.hosts = [
                '10.41.121.78',
                '10.41.121.79',
                '10.41.121.80',
                '10.41.121.81',
                '10.41.121.82',
                '10.41.121.83',
                '10.41.121.84',
                '10.41.121.85'
            ]

clusters = env.hosts

env.hostnames = dict([h, 'gt-%d' % (i + 1)] for i, h in enumerate(clusters))

env.roledefs = {
    'clusters' : clusters,
    'kafka' : clusters[0:5],
    'zookeeper' : clusters[5:8]
}

@task
def status(op=None):
    if op=='zookeeper':
        execute(chk_zk)
    elif op == 'kafka':
        execute(chk_kafka)
    else:
        execute(chk_all)

@roles('zookeeper')
def chk_zk():
    run('jps')

@roles('kafka')
def chk_kafka():
    run('jps')

@roles('clusters')
def chk_all():
    run('jps')

Upvotes: 1

Views: 567

Answers (2)

Daniel Werner
Daniel Werner

Reputation: 1370

The problem is that you are setting env.hosts explicitly. This is the list of hosts that Fabric will execute tasks on. Usually it would be set via the -H (--hosts) command line option if you wanted to select specific hosts to execute on. In your setup, it is most sensible to leave env.hosts out completely, as you are executing mosts tasks on hosts of specific roles via the @roles decorator.

I'm not sure whether your solution works exactly as intended. @runs_once will cause the status task to only execute once per fab run, which effectively means it will run on only one machine, whichever that is, instead of running once for every machine and subsequently triggering the chk_* tasks multiple times. I would expect the other tasks to then still be run on all machines mentioned in env.hosts, regardless of the roles given via @roles.

TL;DR: Remove env.hosts and keep @runs_once on the status task, and you should be fine.

Upvotes: 0

Nitin Tripathi
Nitin Tripathi

Reputation: 491

adding @runs_once annotation to the method 'status' solved the problem for me.

Upvotes: 1

Related Questions