Fabric Basics ============= `Fabric`_ is a Python package which may be used along with SSH to run commands on (and copy files to) a target machine, among other things. .. _Fabric: https://www.fabfile.org/ The idea is to install Fabric (and related things) to *your* local/dev machine, and from there you can run Fabric commands as needed to build out various other machines. Fabric will connect to each machine over SSH and then execute shell commands, copy files etc. The target machine need not run any special service for this to work. It's just like you connected to the target machine via SSH and then ran commands manually, only this way is (ideally) automated and self-documenting. Supported Platforms ------------------- There are two "sides" to the equation, which must be addressed separately. Your *local* (e.g. dev) machine is where you'll run Fabric itself. This machine must have Python 3 installed, and must be able to make SSH client connections to other machines. .. todo:: I *believe* it should be possible to do this on Windows, but I've not tried as I only use Linux desktop. Should confirm if it works on Windows; maybe document setup. The *target* machine however is in all cases assumed to be Linux, either Debian or Ubuntu. It must run a SSH service. .. note:: Fabric supports more target platforms than just Debian/Ubuntu; most likely anything with SSH would work. But within the Rattail Project those are the only 2 being used in production. Note about Versions ------------------- TL;DR - we use ``fabric2`` instead of just ``fabric``, to be explicit Fabric v1 was created when Python 2 was prevalent. Later on, Python 3 became prevalent, and Fabric v2 came out to support that. Fabric v2 is a total rewrite and not compatible with v1. If you're just getting started you'll use only v2 and will not need to know about v1. But for historical reasons, the Rattail Project still supports both versions of Fabric. Because of this background, and to be extra clear *which* version of Fabric is in use, the Rattail Project uses the name ``fabric2`` when referencing Fabric v2 in code etc. For more on this see the following Fabric docs: * https://www.fabfile.org/installing.html#installing-as-fabric2 * https://www.fabfile.org/upgrading.html#running-both-fabric-versions-simultaneously The ``fab2`` command -------------------- When using Fabric to operate on a target machine, you will - on *your* (local) machine - run one or more ``fab2`` commands. Each ``fab2`` command specifies a particular task, which is defined in your ``fabfile.py`` (see below). The command also specifies which machine it should act on. Fabric then will connect to the machine via SSH, and execute the task logic on the target machine. For example, to run the ``bootstrap_all`` task on "myserver" might be: .. code-block:: sh fab2 -e -H myserver.example.com bootstrap-all Note that even though the task is *actually* (in Python) named ``bootstrap_all``, it must be specified with hyphen as ``bootstrap-all`` on the ``fab2`` command line. Also note the ``-e`` (``--echo``) flag which causes Fabric to emit (to local STDOUT) the full command being ran on the target machine, as it goes along. (Most tasks execute several commands on the target machine, so this can be helpful to make sense of output.) The "fabfile" ------------- Fabric is rather flexible but here in the Rattail Project we'll set some guidelines for usage, for simplicity's sake. When running the ``fab2`` command, there should be a file named ``fabfile.py`` in the current directory. This "fabfile" will contain a number of "tasks" - each of which may contain multiple commands to be ran on the target machine, etc. In our context, normally one "fabfile" contains all task logic for building out a particular machine. For more on how Fabric locates the fabfile (and therefore, tasks), see https://docs.fabfile.org/en/stable/cli.html#seeking-loading-tasks A simple yet complete ``fabfile.py`` example:: from fabric2 import task @task def hello_world(c): # nb. this runs locally on *your* machine print("hello world") # nb. this runs on target machine c.run('bash -c "echo my name is `whoami`"') This contains one task, but as you can see does *not* specify which machine it targets. You always must specify that yourself when running ``fab2`` commands. rattail-fabric2 --------------- Rattail offers some utilitiy functions for use with Fabric, in `rattail-fabric2`_. .. _rattail-fabric2: https://kallithea.rattailproject.org/rattail-project/rattail-fabric2/ The "machine bundle" -------------------- The general idea then, is for you to create and maintain a "fabric bundle" for each machine you wish to manage in this way. Bundles are described elsewhere, but the gist is, they contain all necessary commands and config files to build out the machine. See :doc:`bundles` for more about these.