|
|
@ -104,6 +104,8 @@ else |
|
|
|
fi |
|
|
|
export VARDIR CACHEDIR |
|
|
|
|
|
|
|
export SERVICE_STATE_PATH=${SERVICE_STATE_PATH:-/var/lib/compose/state} |
|
|
|
|
|
|
|
|
|
|
|
md5_compat() { md5sum | cut -c -32; } |
|
|
|
quick_cat_file() { quick_cat_stdin < "$1"; } |
|
|
@ -2583,7 +2585,7 @@ get_service_incoming_relations() { |
|
|
|
cache_file="$state_tmpdir/$FUNCNAME.cache.$(H "$@" "$SUBSET_ALL_RELATIONS_HASH")" \ |
|
|
|
s rn ts rc td |
|
|
|
if [ -e "$cache_file" ]; then |
|
|
|
#debug "$FUNCNAME: SESSION cache hit $1" |
|
|
|
debug "$FUNCNAME: SESSION cache hit $1" |
|
|
|
cat "$cache_file" |
|
|
|
return 0 |
|
|
|
fi |
|
|
@ -2593,8 +2595,8 @@ get_service_incoming_relations() { |
|
|
|
relation_data_file=$(get_relation_data_file "$s" "$ts" "$rn" "$rc") || return 1 |
|
|
|
printf "%s\0" "$s" "$(cat "$relation_data_file")" || return 1 |
|
|
|
debug "Found relation $rn from $s to $ts" >&2 |
|
|
|
done < "$SUBSET_ALL_RELATIONS" > "$cache_file" |
|
|
|
|
|
|
|
done < "$SUBSET_ALL_RELATIONS" > "$cache_file.wip" |
|
|
|
mv "$cache_file"{.wip,} || return 1 |
|
|
|
cat "$cache_file" |
|
|
|
} |
|
|
|
export -f get_service_incoming_relations |
|
|
@ -5078,8 +5080,22 @@ while read-0 arg; do |
|
|
|
shift |
|
|
|
done < <(cla.normalize "$@") |
|
|
|
|
|
|
|
|
|
|
|
more_actions=(status) |
|
|
|
|
|
|
|
if [[ "$action" == *" "* ]]; then |
|
|
|
err "Invalid action name containing spaces: ${DARKCYAN}$action${NORMAL}" |
|
|
|
exit 1 |
|
|
|
fi |
|
|
|
|
|
|
|
is_more_action= |
|
|
|
[[ " ${more_actions[*]} " == *" $action "* ]] && is_more_action=true |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[ -n "$CACHEDIR" ] || die "No cache directory defined." |
|
|
|
[ -d "$CACHEDIR" ] || die "Cache directory '$CACHEDIR' doesn't exists." |
|
|
|
|
|
|
|
case "$action" in |
|
|
|
cache) |
|
|
|
case "${remainder_args[0]}" in |
|
|
@ -5139,7 +5155,8 @@ charm.sanity_checks || die "Sanity checks about charm-store failed. Please corre |
|
|
|
## Get services in command line. |
|
|
|
## |
|
|
|
|
|
|
|
if [ -z "$is_docker_compose_action" -a "$action" ]; then |
|
|
|
|
|
|
|
if [ -z "$is_docker_compose_action" ] && [ -z "$is_more_action" ] && [ -n "$action" ]; then |
|
|
|
action_service=${remainder_args[0]} |
|
|
|
if [ -z "$action_service" ]; then |
|
|
|
err "No such command or action: ${DARKCYAN}$action${NORMAL}" |
|
|
@ -5187,6 +5204,12 @@ else |
|
|
|
services_args=($(compose:yml:root:services)) || return 1 |
|
|
|
fi |
|
|
|
;; |
|
|
|
status) |
|
|
|
services_args=("${remainder_args[@]}") |
|
|
|
if [ "${#services_args[@]}" == 0 ]; then |
|
|
|
services_args=($(compose:yml:root:services)) || return 1 |
|
|
|
fi |
|
|
|
;; |
|
|
|
config) |
|
|
|
services_args=("${action_posargs[@]}") |
|
|
|
;; |
|
|
@ -5196,7 +5219,7 @@ fi |
|
|
|
export COMPOSE_ACTION="$action" |
|
|
|
NO_CONSTRAINT_CHECK=True |
|
|
|
case "$action" in |
|
|
|
up) |
|
|
|
up|status) |
|
|
|
NO_CONSTRAINT_CHECK= |
|
|
|
if [ -n "$DEBUG" ]; then |
|
|
|
Elt "solve all relations" |
|
|
@ -5226,6 +5249,66 @@ case "$action" in |
|
|
|
;; |
|
|
|
esac |
|
|
|
|
|
|
|
|
|
|
|
case "$action" in |
|
|
|
up) |
|
|
|
PROJECT_NAME=$(get_default_project_name) || exit 1 |
|
|
|
|
|
|
|
## Required by get_ordered_service_dependencies |
|
|
|
array_read-0 services_args < <(printf "%s" "$COMPOSE_YML_CONTENT" | shyaml keys-0 2>/dev/null) |
|
|
|
NO_CONSTRAINT_CHECK=1 get_all_relations "${services_args[@]}" >/dev/null || exit 1 |
|
|
|
|
|
|
|
## Remove all intents (*ing states) |
|
|
|
rm -f "$SERVICE_STATE_PATH/$PROJECT_NAME"/*/*ing || true |
|
|
|
|
|
|
|
## Notify that we have the intent to bring up all these |
|
|
|
## This will be use in inner or concurrent 'run' to include the |
|
|
|
## services that are supposed to be up. |
|
|
|
mkdir -p "$SERVICE_STATE_PATH/$PROJECT_NAME" || exit 1 |
|
|
|
services_args_deps=($(get_ordered_service_dependencies "${services_args[@]}")) || exit 1 |
|
|
|
for service in "${services_args_deps[@]}"; do |
|
|
|
mkdir -p "$SERVICE_STATE_PATH/$PROJECT_NAME"/"$service" || exit 1 |
|
|
|
[ -e "$SERVICE_STATE_PATH/$PROJECT_NAME"/"$service"/up ] || { |
|
|
|
touch "$SERVICE_STATE_PATH/$PROJECT_NAME"/"$service"/deploying || exit 1 |
|
|
|
} |
|
|
|
done |
|
|
|
## remove services not included in compose.yml anymore |
|
|
|
array_read-0 all_services < <(printf "%s" "$COMPOSE_YML_CONTENT" | shyaml keys-0 2>/dev/null) |
|
|
|
all_services_deps=($(get_ordered_service_dependencies "${all_services[@]}")) || exit 1 |
|
|
|
for service in "$SERVICE_STATE_PATH/$PROJECT_NAME"/*/up; do |
|
|
|
[ -e "$service" ] || continue |
|
|
|
state=${service##*/} |
|
|
|
service=${service%/$state} |
|
|
|
service=${service##*/} |
|
|
|
|
|
|
|
if [[ " ${all_services_deps[*]} " != *" ${service} "* ]]; then |
|
|
|
touch "$SERVICE_STATE_PATH/$PROJECT_NAME"/"${service}"/orphaning || exit 1 |
|
|
|
fi |
|
|
|
done |
|
|
|
;; |
|
|
|
|
|
|
|
run) |
|
|
|
PROJECT_NAME=$(get_default_project_name) || return 1 |
|
|
|
if [ -d "$SERVICE_STATE_PATH/$PROJECT_NAME" ]; then |
|
|
|
## Notify that we have the intent to bring up all these |
|
|
|
## This will be use in inner or concurrent 'run' to include the |
|
|
|
## services that are supposed to be up. |
|
|
|
for service in "$SERVICE_STATE_PATH/$PROJECT_NAME"/*/{up,deploying}; do |
|
|
|
[ -e "$service" ] || continue |
|
|
|
state=${service##*/} |
|
|
|
service=${service%/$state} |
|
|
|
service=${service##*/} |
|
|
|
## don't add if orphaning |
|
|
|
[ -e "$SERVICE_STATE_PATH/$PROJECT_NAME"/"${service}"/orphaning ] && continue |
|
|
|
## add in ${services_args[@]} if not already there |
|
|
|
if [[ " ${services_args[*]} " != *" ${service} "* ]]; then |
|
|
|
services_args+=("$service") |
|
|
|
fi |
|
|
|
done |
|
|
|
fi |
|
|
|
;; |
|
|
|
esac |
|
|
|
|
|
|
|
if [ -n "$is_docker_compose_action_multi_service" ]; then |
|
|
|
if [ -n "$DEBUG" ]; then |
|
|
|
Elt "get relation subet" |
|
|
@ -5241,7 +5324,7 @@ if [ -n "$is_docker_compose_action_multi_service" ]; then |
|
|
|
fi |
|
|
|
fi |
|
|
|
|
|
|
|
if [ "$is_docker_compose_action" -a "${#services_args[@]}" -gt 0 ]; then |
|
|
|
if [ -n "$is_docker_compose_action" ] && [ "${#services_args[@]}" -gt 0 ]; then |
|
|
|
services=($(get_master_services "${services_args[@]}")) || exit 1 |
|
|
|
if [ "$action" == "up" ]; then |
|
|
|
declare -A seen |
|
|
@ -5266,10 +5349,13 @@ if [ "$is_docker_compose_action" -a "${#services_args[@]}" -gt 0 ]; then |
|
|
|
fi |
|
|
|
|
|
|
|
|
|
|
|
get_docker_compose "${services_args[@]}" >/dev/null || { ## precalculate variable \$_current_docker_compose |
|
|
|
err "Fails to compile base 'docker-compose.yml'" |
|
|
|
exit 1 |
|
|
|
} |
|
|
|
# if [ "$action" != "status" ]; then |
|
|
|
get_docker_compose "${services_args[@]}" >/dev/null || { ## precalculate variable \$_current_docker_compose |
|
|
|
err "Fails to compile base 'docker-compose.yml'" |
|
|
|
exit 1 |
|
|
|
} |
|
|
|
# fi |
|
|
|
|
|
|
|
|
|
|
|
## |
|
|
|
## Pre-action |
|
|
@ -5285,7 +5371,7 @@ case "$action" in |
|
|
|
full_init=true |
|
|
|
post_hook=true |
|
|
|
;; |
|
|
|
""|down|restart|logs|config|ps) |
|
|
|
""|down|restart|logs|config|ps|status) |
|
|
|
full_init= |
|
|
|
;; |
|
|
|
*) |
|
|
@ -5350,6 +5436,47 @@ fi |
|
|
|
[ "$action" == "build" ] && exit 0 |
|
|
|
|
|
|
|
|
|
|
|
service:state() { |
|
|
|
local service="$1" states state |
|
|
|
project_name=$(get_default_project_name) || return 1 |
|
|
|
states=() |
|
|
|
for state in "$SERVICE_STATE_PATH"/"$project_name"/"$service"/*; do |
|
|
|
[ -e "$state" ] || continue |
|
|
|
state=${state##*/} |
|
|
|
states+=("$state") |
|
|
|
done |
|
|
|
|
|
|
|
if [[ " ${states[*]} " == *" deploying "* ]]; then |
|
|
|
echo "deploying" |
|
|
|
elif [[ " ${states[*]} " == *" up "* ]]; then |
|
|
|
echo "up" |
|
|
|
else |
|
|
|
echo "down" |
|
|
|
fi |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if [ "$action" == "status" ]; then |
|
|
|
for service in "${services_args[@]}"; do |
|
|
|
msgs="" |
|
|
|
if has_service_action "$service" "get-version" >/dev/null; then |
|
|
|
version_msg=$(run_service_action "$service" "get-version") || exit 1 |
|
|
|
if [[ "$version_msg" == *$'\n'* ]]; then |
|
|
|
version="${version_msg%%$'\n'*}" |
|
|
|
msgs="${version_msg#*$'\n'}" |
|
|
|
else |
|
|
|
version=${version_msg} |
|
|
|
fi |
|
|
|
else |
|
|
|
version="N/A" |
|
|
|
fi |
|
|
|
state=$(service:state "$service") |
|
|
|
printf "%-20s %8s %10s %s\n" "$service" "$state" "$version" "$msgs" |
|
|
|
done |
|
|
|
exit 0 |
|
|
|
fi |
|
|
|
|
|
|
|
|
|
|
|
if [ "$action" == "run" ] && [ "${#services_args}" != 0 ]; then |
|
|
|
charm=$(get_service_charm "${services_args[0]}") || exit 1 |
|
|
|
metadata=$(charm.metadata "$charm") || exit 1 |
|
|
@ -5432,6 +5559,38 @@ if [ "$action" == "run" -a "${#services_args}" != 0 ]; then |
|
|
|
fi |
|
|
|
fi |
|
|
|
|
|
|
|
case "$action" in |
|
|
|
up) |
|
|
|
## Notify that services in 'deploying' states have been deployed |
|
|
|
for service in "$SERVICE_STATE_PATH/$PROJECT_NAME"/*/deploying; do |
|
|
|
[ -e "$service" ] || continue |
|
|
|
state=${service##*/} |
|
|
|
service=${service%/$state} |
|
|
|
service=${service##*/} |
|
|
|
|
|
|
|
mv "$SERVICE_STATE_PATH/$PROJECT_NAME"/"${service}"/{deploying,up} |
|
|
|
done |
|
|
|
## Notify that services in 'orphaning' states have been removed |
|
|
|
for service in "$SERVICE_STATE_PATH/$PROJECT_NAME"/*/orphaning; do |
|
|
|
[ -e "$service" ] || continue |
|
|
|
state=${service##*/} |
|
|
|
service=${service%/$state} |
|
|
|
service=${service##*/} |
|
|
|
|
|
|
|
rm "$SERVICE_STATE_PATH/$PROJECT_NAME"/"${service}"/orphaning |
|
|
|
done |
|
|
|
;; |
|
|
|
down) |
|
|
|
PROJECT_NAME=$(get_default_project_name) || return 1 |
|
|
|
if [ -d "$SERVICE_STATE_PATH/$PROJECT_NAME" ]; then |
|
|
|
if ! dir_is_empty "$SERVICE_STATE_PATH/$PROJECT_NAME"; then |
|
|
|
rm -f "$SERVICE_STATE_PATH/$PROJECT_NAME"/*/* |
|
|
|
fi |
|
|
|
rmdir "$SERVICE_STATE_PATH/$PROJECT_NAME"/{*,} |
|
|
|
fi |
|
|
|
;; |
|
|
|
esac |
|
|
|
|
|
|
|
clean_unused_docker_compose || exit 1 |
|
|
|
|
|
|
|
exit "$errlvl" |