Using Fabric and the .succeeded and .failed attributes

At work, I’ve written a Fabric script that would allow me to check if a user existed across multiple systems.  The script also has the capability to add a missing user and update an existing users’s password.  To make the script easier to read and use, I’ll put in enhancements every now and then.

Recently, I’ve been wanting to improve the logic in my Fabric script.  Specifically, I wanted the script to determine if a user did not exist on a system, add the user.  So, I figured I’d try using Fabric’s .succeeded and .failed attributes when executing a task using run.  I tried the following if statement:

if run("id " + username || echo "ERROR").succeeded:

    do things

I thought that the .succeeded attribute would not work if the script determined the user was not found.  I was wrong.  It turns out that it doesn’t matter if a && or || operator is being used; the .succeeded or .failed attributes will work based off the success or failure of the entire run command and not what occurs after the && and || operators.  The code above demonstrates that if no user was found, the system would produce the “ERROR” string. Since Fabric saw this as a command being successfully completed, any code in the if block would execute.

After some Googling and reading the Fabric documentation, I ended up using the .return_code attribute to determine if a run command on the system was successful.  Here’s an example:

if run("id " + username).return_code == 0:

return True

Granted, I don’t need to use the .return_code attribute because Fabric can still determine truthiness of the command without it.  I’ve included the attribute into my Fabric script as I plan on implementing further logic to work with the error codes that the useradd command provides.