Packages

Build and Deploy Elixir Applications and perform Hot-Code Upgrades and Schema Migrations

Current section

Files

Jump to
edeliver_fork libexec erlang-init
Raw

libexec/erlang-init

#!/usr/bin/env bash
__version() {
echo -e "\n${txtbld}edeliver v$DELIVER_VERSION${txtrst} | $HOMEPAGE\n"
}
__help() {
__version
echo -e "${txtbld}Usage:${txtrst}
edeliver <build-command|deploy-command|node-command|local-command> command-info [Options]
edeliver --help|--version
edeliver help <command>
${txtbld}Build Commands:${txtrst}
edeliver build release [--revision=<git-revision>|--tag=<git-tag>] [--branch=<git-branch>] [Options]
edeliver build upgrade --from=<git-tag-or-revision>|--with=<release-version-from-store>
[--to=<git-tag-or-revision>] [--branch=<git-branch>] [Options]
${txtbld}Deploy Commands:${txtrst}
edeliver deploy release|upgrade [[to] staging|production] [--version=<release-version>] [Options]
edeliver upgrade [staging|production] [--to=<git-tag-or-revision>] [--branch=<git-branch>] [Options]
edeliver update [staging|production] [--to=<git-tag-or-revision>] [--branch=<git-branch>] [Options]
${txtbld}Node Commands:${txtrst}
edeliver start|stop|restart|ping|version [staging|production] [Options]
edeliver migrate [staging|production] [up|down] [--version=<migration-version>]
edeliver [show] migrations [on] [staging|production]
${txtbld}Local Commands:${txtrst}
edeliver show releases|appups
edeliver show relup <xyz.upgrade.tar.gz>
edeliver edit relup [--version=<release-version>]
edeliver upload|download [release|upgrade <release-version>]|<src-file-name> [<dest-file-name>]
edeliver increase [major|minor] versions [--from=<git-tag-or-revision>] [--to=<git-tag-or-revision>]
edeliver unpack|pack release|upgrade [--version=<release-version>]
"
__exec_if_defined "print_custom_commands_help"
echo -e "${txtbld}Options:${txtrst}
-C, --compact Displays every task as it's run, silences all output. (default mode)
-V, --verbose Same as above, does not silence output.
-P, --plain Displays every task as it's run, silences all output. No colouring. (CI)
-D, --debug Runs in shell debug mode, displays everything.
-S, --skip-existing Skip copying release archives if they exist already on the deploy hosts.
-F, --force Do not ask, just do, overwrite, delete or destroy everything
--clean-deploy Delete the release, lib and erts-* directories before deploying the release
--skip-git-clean Don't build from a clean state for faster builds. See $GIT_CLEAN_PATHS env
--skip-mix-clean Skip the 'mix clean step' for faster builds. Use in addition to --skip-git-clean
--skip-relup-mod Skip modification of relup file. Custom relup instructions are not added
--relup-mod=<module-name> The name of the module to modify the relup
--auto-version=revision|commit-count|branch|date Automatically append metadata to release version.
--increment-version=major|minor|patch Increment the version for the current build.
--set-version=<release-version> Set the release version for the current build.
--start-deploy Starts the deployed release. If release is running, it is restarted!
--host=[u@]vwx.yz Run command only on that host, even if different hosts are configured
--mix-env=<env> Build with custom mix env \$MIX_ENV. Default is 'prod'
${txtbld}Miscellaneous:${txtrst}
Sometimes you will be asked, if you omit a required argument (e.g --from for the build upgrade task).
You can overwrite any config at runtime:
BUILD_HOST=build-2.acme.com edeliver build release
GIT_CLEAN_PATHS='_build rel priv/generated' edeliver build release
"
}
__build_help() {
echo -e "
${bldwht}Usage:${txtrst}
edeliver build release|upgrade [Options]
${bldylw}Info:${txtrst}
Builds either a release or and upgrade on the build host and copies it
to the release store. A release can be used by the edeliver
${bldwht}deploy release${txtrst} command to deploy it on staging or production hosts.
${txtgrn}The built release can be used after a restart${txtrst} of the node.
An upgrade can be used by the edeliver ${bldwht}deploy upgrade${txtrst} command
to deploy it onstaging or production hosts. ${txtgrn}The built upgrade
can be used for hot code upgrades without a restart${txtrst} of the node.
For more information try ${bldwht}edeliver help build release${txtrst}
or ${bldwht}edeliver help build upgrade${txtrst}.
"
}
__deploy_help() {
echo -e "
${bldwht}Usage:${txtrst}
edeliver deploy release [[to] staging|production] [Options]
edeliver deploy upgrade [[to] staging|production] [Options]
${bldylw}Info:${txtrst}
Deploys either a release or an upgrade on all staging (default)
or production hosts. A release must have been built before by
the ${bldwht}build release${txtrst} command while an ${txtylw}upgrade must have been built
before${txtrst} by the ${bldwht}build upgrade${txtrst} command ${txtylw}from the version
that is running on that nodes${txtrst}.
Deploying a release requires a restart of the node
while deploying an upgrade updates the node by using
${txtgrn}hot code upgrade${txtrst} and no restart of the nodes is required.
For more information try ${bldwht}edeliver help deploy release${txtrst}
or ${bldwht}edeliver help deploy upgrade${txtrst}.
"
}
__available_strategies() {
__version
echo -e "${txtbld}Available strategies:${txtrst}"
for strategy in $STRATEGIES_NAME
do
echo " * $strategy"
done
echo ""
}
[[ "$1" == "help" ]] && PRINT_COMMAND_HELP=true && shift
# parse command
if (( $# )); then
arg="$1" && shift
case "${arg}" in
(build)
COMMAND="${arg}"
if (( $# )); then
arg="$1" && shift
case "${arg}" in
(release|upgrade)
COMMAND_INFO="${arg}"
;;
(appups|appup)
COMMAND_INFO="appup"
;;
(-*)
[[ "$PRINT_COMMAND_HELP" = "true" ]] && __build_help && exit 2
__help; error_message "No build type found. Use release|upgrade\n"; exit 2
;;
(*)
__help; error_message "Unknown build type ${arg}. Use release|upgrade\n"; exit 2
;;
esac
else # no build type found
[[ "$PRINT_COMMAND_HELP" = "true" ]] && __build_help && exit 2
__help; error_message "No build type found. Use release|upgrade\n"; exit 2
fi
;;
(deploy)
COMMAND="${arg}"
if (( $# )); then
arg="$1" && shift
case "${arg}" in
(release|upgrade)
COMMAND_INFO="${arg}"
;;
(-*)
[[ "$PRINT_COMMAND_HELP" = "true" ]] && __deploy_help && exit 2
__help; error_message "No deploy type found. Use release|upgrade\n"; exit 2
;;
(*)
__help; error_message "Unknown deploy type ${arg}. Use release|upgrade\n"; exit 2
;;
esac
else # no build type found
[[ "$PRINT_COMMAND_HELP" = "true" ]] && __deploy_help && exit 2
__help; error_message "No deploy type found. Use release|upgrade\n"; exit 2
fi
;;
(start|stop|restart|ping|version|migrate|migrations)
COMMAND="${arg}"
if (( $# )); then
[[ "$1" == "on" ]] && shift
arg="$1" && shift
case "${arg}" in
(*)
if [[ "${arg}" =~ ^-- ]]; then
NODE_ENVIRONMENT="staging"
else
NODE_ENVIRONMENT="$arg"
fi
;;
esac
else # no environment found, use staging as default
NODE_ENVIRONMENT="staging"
fi
;;
(check)
COMMAND="${arg}"
if (( $# )); then
arg="$1" && shift
case "${arg}" in
(release|config)
CHECK_CMD="${arg}"
;;
(-*)
__help; error_message "No check type found. Use release|config\n"; exit 2
;;
(*)
__help; error_message "Unknown check type ${arg}. Use release|config\n"; exit 2
;;
esac
else
__help; error_message "No check type found. Use release|config\n"; exit 2
fi
;;
(unpack|pack)
COMMAND="${arg}"
if (( $# )); then
arg="$1" && shift
case "${arg}" in
(release|upgrade)
COMMAND_INFO="${arg}"
;;
(-*)
__help; error_message "No release type found. Use release|upgrade\n"; exit 2
;;
(*)
__help; error_message "Unknown release type ${arg}. Use release|upgrade\n"; exit 2
;;
esac
else # no build type found
__help; error_message "No release type found. Use release|upgrade\n"; exit 2
fi
;;
(show)
COMMAND="${arg}"
if (( $# )); then
arg="$1" && shift
case "${arg}" in
(release|releases)
COMMAND_INFO="releases"
;;
(appup|appups)
COMMAND_INFO="appups"
;;
(relup|relups)
COMMAND_INFO="relup"
if (( $# )); then
RELEASE_FILE="$1" && shift
else
__help; error_message "No upgrade tar.gz passed as argument.\n"; exit 2
fi
;;
(migrations)
COMMAND="${arg}"
if (( $# )); then
[[ "$1" == "on" ]] && shift
arg="$1" && shift
case "${arg}" in
(*)
if [[ "${arg}" =~ ^-- ]]; then
NODE_ENVIRONMENT="staging"
else
NODE_ENVIRONMENT="$arg"
fi
;;
esac
else # no environment found, use staging as default
NODE_ENVIRONMENT="staging"
fi
;;
(-*)
__help; error_message "No show command found. Use releases|appups|relups\n"; exit 2
;;
(*)
__help; error_message "Unknown show command ${arg}. Use releases|appups|relups\n"; exit 2
;;
esac
else
__help; error_message "No show command found. Use releases|appups|relups\n"; exit 2
fi
;;
(upload|download)
COMMAND="${arg}"
if (( $# )); then
arg="$1" && shift
case "${arg}" in
(release|upgrade)
COMMAND_INFO="${arg}"
if (( $# )); then
arg="$1" && shift
VERSION="${arg}"
(( $# )) && ! [[ "$1" =~ ^- ]] && DESTINATION_FILE="$1" && shift
else
__help; error_message "No $COMMAND_INFO version given\n"; exit 2
fi
;;
(*)
RELEASE_FILE="${arg}"
(( $# )) && ! [[ "$1" =~ ^- ]] && DESTINATION_FILE="$1" && shift
;;
esac
else # no build type found
__help; error_message "No file to $COMMAND found. Use release|upgrade <version> or file name\n"; exit 2
fi
;;
(edit)
COMMAND="${arg}"
if (( $# )); then
arg="$1" && shift
case "${arg}" in
(appup|appups)
COMMAND_INFO="appups"
;;
(relup|relups)
COMMAND_INFO="relup"
;;
(-*)
__help; error_message "No edit command found. Use appup|relup\n"; exit 2
;;
(*)
__help; error_message "Unknown edit command ${arg}. Use appup|relup\n"; exit 2
;;
esac
else
__help; error_message "No edit command found. Use appup|relup\n"; exit 2
fi
;;
(increase)
COMMAND="${arg}"
if (( $# )); then
arg="$1" && shift
case "${arg}" in
(versions|version)
INCREASE_VERSION_TYPE="version"
COMMAND_INFO="versions"
;;
(minor|major)
INCREASE_VERSION_TYPE="$arg"
COMMAND_INFO="versions"
;;
(-*)
__help; error_message "Increase type not found. Use versions|major|minor\n"; exit 2
;;
(*)
__help; error_message "Unknown increase type ${arg}. Use versions|major|minor\n"; exit 2
;;
esac
else
INCREASE_VERSION_TYPE="minor"
COMMAND_INFO="versions"
fi
;;
(-h|--help)
__help
exit 0
;;
(-v|--version)
__version
exit 0
;;
(*)
COMMAND="${arg}";
;;
esac
else # no command found
__help
[[ "$PRINT_COMMAND_HELP" != "true" ]] && error_message "No command found.\n";
exit 2
fi
while (( $# ))
do
arg="$1" && shift
case "${arg}" in
(-C|--compact)
MODE="compact"
;;
(-D|--debug)
MODE="debug"
;;
(-V|--verbose)
MODE="verbose"
;;
(-S|--skip-existing)
SKIP_COPYING_EXISTING_FILES="skip"
;;
(-P|--plain)
# this was already captured in libexec/output
# noop
;;
(-F|--force)
FORCE="true"
;;
(--clean-deploy)
CLEAN_DEPLOY="true"
;;
(--skip-git-clean)
SKIP_GIT_CLEAN="true"
;;
(--skip-mix-clean)
SKIP_MIX_CLEAN="true"
[[ -n "$SET_RELEASE_VERSION" ]] && __help && error_message "Option --set-version= cannot be used together with the --skip-mix-clean option.\n" && exit 2
[[ -n "$INCREMENT_RELEASE_VERSION" ]] && __help && error_message "Option --increment-version= cannot be used together with the --skip-mix-clean option.\n" && exit 2
[[ -n "$AUTO_RELEASE_VERSION" ]] && __help && error_message "Option --auto-version= cannot be used together with the --skip-mix-clean option.\n" && exit 2
;;
(--start-deploy)
START_DEPLOY="true"
;;
(--skip-relup-mod|--skip-relup-modification)
SKIP_RELUP_MODIFICATIONS="true"
;;
(--runs-as-mix-task)
RUNS_AS_MIX_TASK="true"
;;
(-h|--help)
__help
exit 0
;;
(to)
;;
(staging)
DEPLOY_ENVIRONMENT="staging"
;;
(production)
DEPLOY_ENVIRONMENT="production"
;;
(check)
CHECK=true
;;
(*)
if [[ "${arg}" =~ ^--from= ]]; then
FROM="${arg##--from=}"
elif [[ "${arg}" =~ ^--with= ]]; then
WITH="${arg##--with=}"
elif [[ "${arg}" =~ ^--to= ]]; then
TO="${arg##--to=}"
elif [[ "${arg}" =~ ^--revision= ]]; then
REVISION="${arg##--revision=}"
elif [[ "${arg}" =~ ^--tag= ]]; then
TAG="${arg##--tag=}"
REVISION="$(git rev-parse $TAG)"
elif [[ "${arg}" =~ ^--branch= ]]; then
BRANCH=${arg##--branch=}
elif [[ "${arg}" =~ ^--version= ]]; then
VERSION=${arg##--version=}
elif [[ "${arg}" =~ ^--host= ]]; then
HOST=${arg##--host=}
elif [[ "${arg}" =~ ^--mix-env= ]]; then
TARGET_MIX_ENV=${arg##--mix-env=}
elif [[ "${arg}" =~ ^--relup-mod= ]]; then
RELUP_MODIFICATION_MODULE=${arg##--relup-mod=}
elif [[ "${arg}" =~ ^--auto-version= ]]; then
AUTO_RELEASE_VERSION=${arg##--auto-version=}
IFS='+' read -ra AUTO_VERSION_ARGS <<< "$AUTO_RELEASE_VERSION"
for AUTO_VERSION_ARG in "${AUTO_VERSION_ARGS[@]}"; do
ORIGINAL_AUTO_VERSION_ARG=$AUTO_VERSION_ARG
AUTO_VERSION_ARG=${AUTO_VERSION_ARG#append-*}
AUTO_VERSION_ARG=${AUTO_VERSION_ARG#git-*}
AUTO_VERSION_ARG=${AUTO_VERSION_ARG#build-*}
if ! [[ "$AUTO_VERSION_ARG" =~ ^(revision|commit-count|commit-count-branch|commit-count-all|commit-count-all-branches|branch|branch-unless-master|date)$ ]]; then
__help; error_message "Illegal value for --auto-version= option: '${ORIGINAL_AUTO_VERSION_ARG}'.\n"; exit 2
fi
done
unset AUTO_VERSION_ARGS AUTO_VERSION_ARG ORIGINAL_AUTO_VERSION_ARG
[[ "$SKIP_MIX_CLEAN" = "true" ]] && __help && error_message "Option --auto-version= cannot be used together with the --skip-mix-clean option.\n" && exit 2
elif [[ "${arg}" =~ ^--increment-version= ]]; then
INCREMENT_RELEASE_VERSION=${arg##--increment-version=}
! [[ "$INCREMENT_RELEASE_VERSION" =~ ^(patch|minor|major)$ ]] && __help && error_message "Value for --increment-version= option must be either patch, minor or major.\n" && exit 2
[[ -n "$SET_RELEASE_VERSION" ]] && __help && error_message "Option --increment-version= cannot be used together with the --set-version= option.\n" && exit 2
[[ "$SKIP_MIX_CLEAN" = "true" ]] && __help && error_message "Option --set-version= cannot be used together with the --skip-mix-clean option.\n" && exit 2
elif [[ "${arg}" =~ ^--set-version= ]]; then
SET_RELEASE_VERSION=${arg##--set-version=}
[[ -z "$SET_RELEASE_VERSION" ]] && __help && error_message "Value for --set-version= option must not be empty.\n" && exit 2
[[ -n "$INCREMENT_RELEASE_VERSION" ]] && __help && error_message "Option --set-version= cannot be used together with the --increment-version= option.\n" && exit 2
[[ "$SKIP_MIX_CLEAN" = "true" ]] && __help && error_message "Option --increment-version= cannot be used together with the --skip-mix-clean option.\n" && exit 2
else
[[ -n "${COMMAND}" ]] && __exec_if_defined "accepts_custom_command_argument" "${COMMAND}" "${arg}" || hint_message "Unknown argument ${arg} ignored"
fi
;;
esac
done
case "${MODE}" in
(compact)
VERBOSE=""
SILENCE="> /dev/null"
;;
(verbose)
VERBOSE=true
SILENCE=""
;;
(debug)
set -x
VERBOSE=true
SILENCE=""
;;
esac
case "${COMMAND}" in
(build)
STRATEGY="erlang-${COMMAND}-${COMMAND_INFO}"
if [[ ! ${COMMAND_INFO} = "release" ]] && [[ "$PRINT_COMMAND_HELP" != "true" ]] && [[ -z "$FROM" ]] && [[ -z "$WITH" ]]; then
__help; error_message "build command requires --from= or --with argument.\n"; exit 2
fi
;;
(deploy)
STRATEGY="erlang-deploy-${COMMAND_INFO}"
;;
(start|stop|restart|ping|version|migrate|migrations)
STRATEGY="erlang-node-execute"
NODE_ACTION="${COMMAND}"
;;
(upload|download)
STRATEGY="erlang-release-store-copy"
;;
(unpack|pack)
STRATEGY="erlang-unpack-pack"
;;
(increase)
STRATEGY="erlang-increase-versions"
;;
(*)
STRATEGY="erlang-${COMMAND}"
[[ -n "${COMMAND_INFO}" ]] && STRATEGY="${STRATEGY}-${COMMAND_INFO}"
if ! [[ -f "${BASE_PATH}/strategies/${STRATEGY}" ]]; then
if ! [[ -f "$ORIGIN_DIR/.deliver/strategies/${STRATEGY}" ]]; then
if [[ "${COMMAND}" = "publish" ]] && [[ -f "${BASE_PATH}/strategies/publish-edeliver" ]]; then
STRATEGY="publish-edeliver"
elif [[ "$PRINT_COMMAND_HELP" = "true" ]]; then
__help; exit 0
else
__help; error_message "Unknown command ${COMMAND}.\n"; exit 2
fi
fi
fi
;;
esac