How to make Fabric continue running the next command after getting the exit status: 1?
Asked Answered
A

4

17

I'm going to install check_mk plugin by writing a simple fabfile like this:

from fabric.api import env, run, roles, execute, parallel

env.roledefs = {
    'monitoring': ['192.168.3.118'],
    'mk-agent': ['192.168.3.230', '192.168.3.231', '192.168.3.232']
}

@roles('monitoring')
def mk():
    run('[ -f check_mk-1.1.12p7.tar.gz ] || wget http://mathias-kettner.de/download/check_mk-1.1.12p7.tar.gz')
    run('[ -d check_mk-1.1.12p7 ] || tar zxvf check_mk-1.1.12p7.tar.gz')
    run('cd check_mk-1.1.12p7 && sudo ./setup.sh')

@parallel    
@roles('mk-agent')
def mk_agent():
    run('[ `rpm -qa | grep -c xinetd` -eq 0 ] && sudo yum -y install xinetd.x86_64')
    run('sudo rpm -ivh http://mathias-kettner.de/download/check_mk-agent-1.2.0b2-1.noarch.rpm') 

def check_mk():
    execute(mk)
    execute(mk_agent)

But, as you can guess, if the xinetd package is already installed, Fabric will be stopped with below errors:

Fatal error: run() received nonzero return code 1 while executing!

Requested: [ `rpm -qa | grep -c xinetd` -eq 0 ] && sudo yum -y install xinetd.x86_64
Executed: /bin/bash -l -c "[ \`rpm -qa | grep -c xinetd\` -eq 0 ] && sudo yum -y install xinetd.x86_64"

Aborting.

Is there any solution in this situation?

Afloat answered 18/4, 2012 at 10:34 Comment(0)
M
21

since stackoverflow doesn't let me upvote Morgan's answer without more rep, I'll contribute more detail from http://docs.fabfile.org/en/1.4.1/api/core/context_managers.html#fabric.context_managers.settings

Outside the 'with settings' in the code below, behaviour will return to normal :

def my_task():
    with settings(
        hide('warnings', 'running', 'stdout', 'stderr'),
        warn_only=True
    ):
        if run('ls /etc/lsb-release'):
            return 'Ubuntu'
        elif run('ls /etc/redhat-release'):
            return 'RedHat'

This is desirable since you can essentially 'catch' what would've been an error in one section without it being fatal, but leave errors fatal elsewhere.

Marten answered 4/9, 2013 at 4:17 Comment(0)
M
2

Perhaps in 2020 it will be useful. In Fabric 2.5, you just need to add the warn=True to the command to avoid interruption.

For example: connection.run('test -f /path/to/file && tail /path/to/file, warn=True)

Malversation answered 14/7, 2020 at 7:56 Comment(0)
A
1

You simply need to add "env.warn_only = True" to the def mk_agent(): task.

Autism answered 19/4, 2012 at 21:47 Comment(0)
T
0

Fabric Failure handling

Once the task list has been constructed, Fabric will start executing them as outlined in Execution strategy, until all tasks have been run on the entirety of their host lists. However, Fabric defaults to a “fail-fast” behavior pattern: if anything goes wrong, such as a remote program returning a nonzero return value or your fabfile’s Python code encountering an exception, execution will halt immediately.

This is typically the desired behavior, but there are many exceptions to the rule, so Fabric provides env.warn_only, a Boolean setting. It defaults to False, meaning an error condition will result in the program aborting immediately. However, if env.warn_only is set to True at the time of failure – with, say, the settings context manager – Fabric will emit a warning message but continue executing.

def my_task():
    with settings(
        hide('warnings', 'running', 'stdout', 'stderr'),
        warn_only=True
    ):
        if run('ls /etc/lsb-release'):
            return 'Ubuntu'
        elif run('ls /etc/redhat-release'):
            return 'RedHat'
Tabanid answered 5/5, 2017 at 1:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.