bootleg v0.3.0 Bootleg.Config

Configuration DSL for Bootleg.

Link to this section Summary

Functions

Defines an after hook for a task

Defines a before hook for a task

Fetches all key/value pairs currently defined in the Bootleg configuration

Sets key in the Bootleg configuration to value

Invokes the task identified by task

Loads a configuration file

Executes commands on all remote hosts

Executes commands on all remote hosts within a role

Executes commands on a remote host

Defines a task idefintied by task

Uploads a local file to remote hosts

Link to this section Functions

Link to this macro after_task(task, other_task) (macro)

Defines an after hook for a task.

Behaves exactly like a before hook, but executes after the task has run. See before_task/2 for more details.

use Bootleg.Config

after_task :build, :store_artifact
after_task :deploy do
  Notify.team "Deployed!"
end
Link to this macro before_task(task, other_task) (macro)

Defines a before hook for a task.

A hook is a piece of code that is executed before/after a task has been run. The hook can either be a standalone code block, or the name of another task. Hooks are executed in an unconditional fashion. Only an uncaught exeception will prevent futher execution. If a task name is provided, it will be invoked via invoke/1.

Just like with invoke/1, a task does not need to be defined to have a hook registered for it, nor does the task need to be defined in order to be triggered via a hook. Tasks may also be defined at a later point, provided execution has not begun.

If multiple hooks are defined for the same task, they are executed in the order they were originally defined.

use Bootleg.Config

before_task :build, :checksum_code
before_task :deploy do
  Notify.team "Here we go!"
end

Relying on the ordering of hook execution is heavily discouraged. It’s better to explicitly define the order using extra tasks and hooks. For example

use Bootleg.Config

before_task :build, :do_first
before_task :build, :do_second

would be much better written as

use Bootleg.Config

before_task :build, :do_first
before_task :do_first, :do_second
Link to this macro config() (macro)

Fetches all key/value pairs currently defined in the Bootleg configuration.

Link to this macro config(key, value) (macro)

Sets key in the Bootleg configuration to value.

One of the cornerstones of the Bootleg DSL, config/2 is used to pass configuration options to Bootleg. See the documentation for the specific task you are trying to configure for what keys it supports.

use Bootleg.Config

config :app, :my_cool_app
config :version, "1.0.0"
Link to this function invoke(task)
invoke(atom) :: :ok

Invokes the task identified by task.

This is one of the cornerstones of the Bootleg DSL. Executing a task first calls any registered before_task/2 hooks, then executes the task itself (which was defined via task/2), then any registered after_task/2 hooks.

The execution of the hooks and the task are unconditional. Return values are ignored, though an uncuaght exception will stop further execution. The task does not need to exist. Any hooks for a task with the name of task will still be executed, and no error or warning will be emitted. This can be used to create events which a developer wants to be able to install hooks around without needing to define no-op tasks.

invoke/1 executes immediately, so it should always be called from inside a task. If it’s placed directly inside config/deploy.exs, the task will be invoked when the configuration is first read. This is probably not what is desired.

use Bootleg.Config

task :hello do
  IO.puts "Hello?"
  invoke :world
end

task :world do
  IO.puts "World!"
end
Link to this function load(file)
load(binary | charlist) :: :ok | {:error, :enoent}

Loads a configuration file.

file is the path to the configuration file to be read and loaded. If that file doesn’t exist {:error, :enoent} is returned. If there’s an error loading it, a Code.LoadError exception will be raised.

Link to this macro remote(lines) (macro)

Executes commands on all remote hosts.

This is equivalent to calling remote/2 with a role of :all.

Link to this macro remote(role, lines) (macro)

Executes commands on all remote hosts within a role.

This is equivalent to calling remote/3 with a filter of [].

Link to this macro remote(role, filter, lines) (macro)

Executes commands on a remote host.

This is the workhorse of the DSL. It executes shell commands on all hosts associated with the role. If any of the shell commands exits with a non-zero status, execution will be stopped and an SSHError will be raised.

lines can be a List of commands to execute, or a code block where each line’s return value is used as a command. Each command will be simulataneously executed on all hosts in the role. Once all hosts have finished executing the command, the next command in the list will be sent.

filter is an optional Keyword list of host options to filter with. Any host whose options match the filter will be included in the remote execution. A host matches if it has all of the filtering options defined and the values match (via ==/2) the filter.

role can be a single role, a list of roles, or the special role :all (all roles). If the same host exists in multiple roles, the commands will be run once for each role where the host shows up. In the case of multiple roles, each role is processed sequentially.

Returns the results to the caller, per command and per host. See Bootleg.SSH.run! for more details.

use Bootleg.Config

remote :build, ["uname -a", "date"]
remote :build do
  "ls -la"
  "echo " <> Time.to_string(Time.utc_now) <> " > local_now"
end

# will raise an error since `false` exits with a non-zero status
remote :build, ["false", "touch never_gonna_happen"]

# runs for hosts found in all roles
remote do: "hostname"
remote :all, do: "hostname"

# runs for hosts found in :build first, then for hosts in :app
remote [:build, :app], do: "hostname"

# only runs on `host1.example.com`
role :build, "host2.example.com"
role :build, "host1.example.com", primary: true, another_attr: :cat

remote :build, primary: true do
  "hostname"
end
Link to this macro role(name, hosts, options \\ []) (macro)

Defines a role.

Roles are a collection of hosts and their options that are responsible for the same function, for example building a release, archiving a release, or executing commands against a running application.

name is the name of the role, and is globally unique. Calling role/3 multiple times with the same name will result in the host lists being merged. If the same host shows up mutliple times, it will have its options merged. The name :all is reserved and cannot be used here.

hosts can be a single hostname, or a List of hostnames.

options is an optional Keyword used to provide configuration details about a specific host (or collection of hosts). Certain options are passed to SSH directly (see Bootleg.SSH.supported_options/0), others are used internally (user for example, is used by both SSH and Git), and unknown options are simply stored. In the future remote/1,2 will allow for host filtering based on role options. Some Bootleg extensions may also add support for additional options.

use Bootleg.Config

role :build, ["build1.example.com", "build2.example.com"], user: "foo", identity: "~/.ssh/id_rsa"
Link to this macro task(task, list) (macro)

Defines a task idefintied by task.

This is one of the cornerstones of the Bootleg DSL. It takes a task name (task) a block of code and registers the code to be executed when task is invoked. Inside the block, the full Bootleg DSL is available.

A warning will be emitted if a task is redefined.

use Bootleg.Config

task :hello do
  IO.puts "Hello World!"
end
Link to this macro upload(role, local_path, remote_path) (macro)

Uploads a local file to remote hosts.

Uploading works much like remote/3, but instead of transferring shell commands over SSH, it transfers files via SCP. The remote host does need to support SCP, which should be provided by most SSH implementations automatically.

role can either be a single role name, a list of roles, or a list of roles and filter attributes. The special :all role is also supported. See remote/3 for details.

local_path can either be a file or directory found on the local machine. If its a directory, the entire directory will be recursively copied to the remote hosts. Relative paths are resolved relative to the root of the local project.

remote_path is the file or directory where the transfered files should be placed. The semantics of how remote_path is treated vary depending on what local_path refers to. If local_path points to a file, remote_path is treated as a file unless it’s . or ends in /, in which case it’s treated as a directory and the filename of the local file will be used. If local_path is a directory, remote_path is treated as a directory as well. Relative paths are resolved relative to the projects remote workspace. Missing directories are not implicilty created.

The files on the remote server are created using the authenticating user’s uid/gid and umask.

use Bootleg.Config

# copies ./my_file to ./new_name on the remote host
upload :app, "my_file", "new_name"

# copies ./my_file to ./a_dir/my_file on the remote host. ./a_dir must already exist
upload :app, "my_file", "a_dir/"

# recursively copies ./some_dir to ./new_dir on the remote host. ./new_dir will be created if missing
upload :app, "some_dir", "new_dir"

# copies ./my_file to /tmp/foo on the remote host
upload :app, "my_file", "/tmp/foo"