Class: Cartage::Remote
- Inherits:
-
Plugin
- Object
- Plugin
- Cartage::Remote
- Defined in:
- lib/cartage/plugins/remote.rb
Overview
Connect to a remote machine and build a package remotely. cartage-remote uses Fog::SSH with key-based authentication (not password-based) to connect to a remote server.
cartage-remote assumes a relatively stable build server, but does not require one (custom prebuild
and postbuild
scripts could be used to manage that).
Remote Build Isolation
cartage-remote allows for safe builds across multiple projects and branches with path-based isolation. The pattern for the build path is shown below, where the last part of the path is where the code will be cloned to.
~<remote_user>/cartage/<project-name>/<timestamp>/<project-name>
| | | | |
v | | | |
build root v | | |
cartage | | |
path v | |
project v |
path isolation |
path v
build
path
So that if I am deploying on a project called calliope
and my remote user is build
, my isolated build path might be:
~build/cartage/calliope/20160321091432/calliope
Remote Build Steps
The steps for a remote build are:
-
Configure Cartage and save the active Cartage configuration as a temporary file that will be copied to the remote server.
-
Configure the Fog::SSH and Fog::SCP adapters with the keys to connect to the remote system.
-
Create the
prebuild
script and run it locally (where the cartage CLI was run). -
Connect to the remote server, put the Cartage configuration file in the isolation path, and clone the repository. Check the repo out to the appropriate
release_hashref
. -
Create the
build
script, copy it remotely, and run it from the build isolation path (build_path
). This is effectively:cd "$build_path" && $build_script
-
Clean up the remote server fromt his build.
-
Create the
postbuild
script and run it locally (where the cartage CLI was run).
Configuration
cartage-remote is configured in the plugins.remote
section of the Cartage configuration file. It supports two primary keys:
hosts
-
A dictionary of hosts, as described below, that indicate the remote machine where the build script will be run. The host keys will be used as the
host
value. host
-
The name of the target host to be used. If missing, uses the
default
location.
For backwards compatibility, a single host may be specified in a server
key, using the same format as the host
values. This host will become the default
host unless one is already specified in the hosts
dictionary (which is an error).
The following keys are optional and may be provided globally in plugins.remote
, or per host in plugins.remote.hosts.$name. If provided, host-level values override the global configuration.
keys
-
The SSH key(s) used to connect to the server. There are two basic ways that keys can be provided:
-
If provided as a string or an array of strings, the value(s) will be applied as glob patterns to find key files on disk.
-
If provided as a dictionary, the values are the ASCII representations of the private keys.
If keys are not provided, keys will be found on the local machine using the pattern
~/.ssh/*id_[rd]sa
. -
build
-
A multiline YAML string that is copied to the remote machine and executed as a script there. If not provided, the following script will be run:
#!/bin/bash set -e if [ -f Gemfile ]; then bundle install --path %{remote_bundle} bundle exec cartage \ --config-file %{config_file} \ --target %{project_path} \ pack else cartage \ --config-file %{config_file} \ --target %{project_path} \ pack fi
prebuild
-
A multiline YAML string that is run as a script on the local machine to prepare for running remotely. If not provided, the following script will be run:
#!/bin/bash ssh-keyscan -H %{remote_adddress} >> ~/.ssh/known_hosts
postbuild
-
A multiline YAML string that is run as a script on the local machine to finish the build process locally. There is no default postbuild script. The script will be passed the stage (
local_config
,ssh_config
,prebuild
,remote_clone
,remote_build
,cleanup
, orfinished
) and, if the stage is notfinished
, the error message.
Hosts
A host describes the remote server. It may be specified either as a string in the form [user@]host[:port]
or a dictionary with required keys:
user
-
The user to connect to the remote server as. If not provided, defaults to $USER.
address
-
The host address for connecting to the remote server. Also called
host
. port
-
The optional port to connect to the remote server on; used if not using the standard SSH port, 22.
Additionally, keys
, build
, prebuild
, and postbuild
scripts may be specified to override the global scripts.
Script Substitution
The build
, prebuild
, and postbuild
scripts require information from the Cartage and Cartage::Remote instances. When these scripts are rendered to disk, they will be run through Kernel#sprintf with string substitution parameters (%{parameter-name}
). All of these values are computed from the local Cartage configuration.
repo_url
-
The repository URL.
name
-
The package name.
release_hashref
-
The release hashref to build.
timestamp
-
The build timestamp.
remote_address
-
The remote build host. Also available as
remote_host
for backwards compatability. remote_port
-
The remote build host SSH port (may be empty).
remote_user
-
The remote build user.
build_root
-
The remote build root, (usually
~remote_user
). cartage_path
-
build_root/cartage
. project_path
-
cartage_path/name
. isolation_path
-
project_path/timestamp
. build_path
-
The remote build path (contains the code to package).
isolation_path/name
remote_bundle
-
A place where dependencies for the build can be installed locally.
isolation_path/deps
. Typically used in thebuild
script.bundle install --path %{remote_bundle}
dependency_cache
-
The
dependency_cachevendor_cache
for the remote server. Set the same asproject_path
. config_file
-
The remote filename of the computed Cartage configuration. Must be provided to the remote run of
cartage
.bundle exec cartage --config-file %{config_file} pack
build_script
-
The full path to the remote build script.
isolation_path/cartage-build-remote
.
Configuration Example
---
plugins:
remote:
hosts:
default: build-server
script: |
#! /bin/bash
bundle install --path %{remote_bundle} &&
bundle exec cartage --config-file %{config_file} pack &&
bundle exec cartage --config-file %{config_file} s3 put
Defined Under Namespace
Classes: Host
Constant Summary collapse
- VERSION =
:nodoc:
'2.2'
Instance Method Summary collapse
-
#build ⇒ Object
Build on the remote server.
-
#check_config(require_host: false, ¬ify) ⇒ Object
Check that the configuration is correct.
Instance Method Details
#build ⇒ Object
Build on the remote server.
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/cartage/plugins/remote.rb', line 188 def build stage.trigger! :local_setup stage.trigger! :ssh_setup stage.trigger! :run_prebuild stage.trigger! :clone_remote stage.trigger! :build_remote stage.trigger! :clean_remote stage.trigger! :complete rescue Cartage::CLI::CustomExit raise rescue => e error = e.exception("Remote error in stage #{stage.state}: #{e.}") error.set_backtrace(e.backtrace) raise error ensure if postbuild_script cartage.display 'Running postbuild script...' system make_tmpscript('postbuild', postbuild_script, subs).path, stage.state.to_s, error.to_s end tmpfiles.each do |tmpfile| tmpfile.close tmpfile.unlink end tmpfiles.clear end |
#check_config(require_host: false, ¬ify) ⇒ Object
Check that the configuration is correct. If require_host
is present, an exception will be thrown if a host is required and not present.
The optional notify
block parameter is used primarily for testing.
220 221 222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/cartage/plugins/remote.rb', line 220 def check_config(require_host: false, ¬ify) config = cartage.config(for_plugin: :remote) puts "#{__method__}: verify_hosts(#{config.hosts.inspect})" verify_hosts(config.hosts, ¬ify) if require_host name = config.host || 'default' fail "No host #{name} present" unless config.hosts.dig(name) end true end |