Current section
Files
Jump to
Current section
Files
guides/1.basics.md
# Realbook Basics
A Realbook is a fundamentally a shorthand way of specifying
an Elixir `Module`. Anything you could write inside a `Kernel.defmodule/2` clause you can write inside of a realbook, and in fact your realbook
script will wrapped inside of a `defmodule` statement.
A realbook (or set of realbooks) executes linearly in a single BEAM
process.
## Bridging the imperative with declarative
The realbook script itself should be considered a unit of declarative
provisioning. In order to bridge imperative code and declarative Realbook
provides three pre-imported macros:
- `Realbook.Macros.requires/1` (optional) lets you declare a list of
other realbook scripts which must be run prior to the current one
to guarantee successful execution.
- `Realbook.Macros.verify/1` (required) specifies instructions which
are run prior to execution; if `verify` passes, the `Realbook.Macros.play/1`
contents will not be executed. After executing the `play` contents,
`verify` will be rerun to assess the overall success of the provision.
- `Realbook.Macros.play/1` (required) specifies instructions to actually
be run.
## Checking variable existence prior to running.
Realbook scripts provide way of sharing configuration variables between
scripts. It may also be the case that a script could optionally define
a variable to be used by a downstream script. Two pre-imported macros help
you share configuration variables:
- `Realbook.Commands.get/1` lets you retrieve a configuration variable
using an atom key.
- `Realbook.Commands.set/1` lets you set a configuration variable from
within a script.
Realbook modules perform code analysis at compile time, and remember which
configuration variables must be set prior to running. If a necessary
configuration variable has not been set, then the script will not enter the
first `verify`, and will raise with an error warning that the variable hasn't
been set.
To set a variable prior to executing the module, use the `Realbook.set/1`
function.
Note that Realbook variables are threadsafe, they aren't shared between
concurrently running Realbook processes. That also means that you must
set them on a process-by-process basis.
## Provisioning connections and commands
A process running a realbook script is associated with a *provisioning
conn*. This is a connection value representing the communication between
the provisioning host (that is running realbook) and the provisioning
target. Use `Realbook.connect!/1` (typically outside of the realbook
script). See [running a realbook](3-running_a_realbook.html).
Once you are in, the following pre-imported commands can be used to
perform imperative functions on the target (these should typically be in
either the `verify` or the ):
- To run commands directly, use:
- `Realbook.Commands.run/1`
- `Realbook.Commands.run!/1`
- Or if you need to be superuser:
- `Realbook.Commands.sudo_run/1`
- `Realbook.Commands.sudo_run!/1`
- If you require a tty connections (`:ssh` only), for example `apt-get` use:
- `Realbook.Commands.run_tty!/1` and
- `Realbook.Commands.sudo_run_tty!/1`
Note that the bang! versions of the functions will raise if a non-zero
return code (failure) is emitted by the program. If you are expecting a
non-zero code or need to take decisions based on more detailed information,
use the non-bang versions, which will return `{:ok, stdout}` or
`{:error, stderr, return_code}`. The non-bang functions will still raise if
there's a connection error between the host and the target.
- To send files to the target, use:
- `Realbook.Commands.send!/2` and
- `Realbook.Commands.sudo_send!/2` if you need to be superuser.
- To append to files on the target, use:
- `Realbook.Commands.append!/2` and
- `Realbook.Commands.sudo_append!/2` if you need to be superuser.