Browse Source

new: [compose-core] add ``status`` global action

master
Valentin Lab 4 weeks ago
parent
commit
662d3f778b
  1. 5
      Dockerfile
  2. 316
      bin/compose-core

5
Dockerfile

@ -15,7 +15,7 @@ ENV KAL_SHLIB_ARRAY_VERSION="0.2.0" \
KAL_SHLIB_CACHE_VERSION="0.0.1" \ KAL_SHLIB_CACHE_VERSION="0.0.1" \
KAL_SHLIB_CHARM_VERSION="0.5.3" \ KAL_SHLIB_CHARM_VERSION="0.5.3" \
KAL_SHLIB_CMDLINE_VERSION="0.0.5" \ KAL_SHLIB_CMDLINE_VERSION="0.0.5" \
KAL_SHLIB_COMMON_VERSION="0.4.22" \
KAL_SHLIB_COMMON_VERSION="0.5.1" \
KAL_SHLIB_CONFIG_VERSION="0.0.2" \ KAL_SHLIB_CONFIG_VERSION="0.0.2" \
KAL_SHLIB_CORE_VERSION="0.7.0" \ KAL_SHLIB_CORE_VERSION="0.7.0" \
KAL_SHLIB_FIREWALL_VERSION="0.2.0" \ KAL_SHLIB_FIREWALL_VERSION="0.2.0" \
@ -131,6 +131,9 @@ RUN apk add curl wget
## handy in some charms or action to recode some output ## handy in some charms or action to recode some output
RUN apk add recode RUN apk add recode
## used for column resizing
RUN apk add gawk
## handy yaml2json converter for charm ## handy yaml2json converter for charm
RUN wget https://github.com/bronze1man/yaml2json/releases/download/v1.3/yaml2json_linux_amd64 \ RUN wget https://github.com/bronze1man/yaml2json/releases/download/v1.3/yaml2json_linux_amd64 \
-O /usr/local/bin/yaml2json && \ -O /usr/local/bin/yaml2json && \

316
bin/compose-core

@ -113,36 +113,6 @@ quick_cat_stdin() { local IFS=''; while read -r line; do echo "$line"; done ; }
export -f quick_cat_file quick_cat_stdin md5_compat export -f quick_cat_file quick_cat_stdin md5_compat
read-0-err() {
local ret="$1" eof="" idx=0 last=
read -r -- "${ret?}" <<<"0"
shift
while [ "$1" ]; do
last=$idx
read -r -d '' -- "$1" || {
## Put this last value in ${!ret}
eof="$1"
read -r -- "$ret" <<<"${!eof}"
break
}
((idx++))
shift
done
[ -z "$eof" ] || {
if [ "$last" != 0 ]; then
echo "Error: read-0-err couldn't fill all value" >&2
read -r -- "$ret" <<<"127"
else
if [ -z "${!ret}" ]; then
echo "Error: last value is not a number, did you finish with an errorlevel ?" >&2
read -r -- "$ret" <<<"126"
fi
fi
false
}
}
export -f read-0-err
p-err() { p-err() {
"$@" "$@"
echo "$?" echo "$?"
@ -2692,9 +2662,7 @@ service:state() {
echo "down" echo "down"
fi fi
} }
export -f service:state
_get_charm_metadata_uses() { _get_charm_metadata_uses() {
local metadata="$1" cache_file="$CACHEDIR/$FUNCNAME.cache.$(printf "%s\0" "$@" | md5_compat)" local metadata="$1" cache_file="$CACHEDIR/$FUNCNAME.cache.$(printf "%s\0" "$@" | md5_compat)"
@ -4585,6 +4553,10 @@ get_docker_compose_single_opts_list() {
display_commands_help() { display_commands_help() {
local charm_actions local charm_actions
echo echo
echo "${WHITE}Commands${NORMAL} (added by compose):"
echo " ${DARKCYAN}cache${NORMAL} Control compose's cache"
echo " ${DARKCYAN}status${NORMAL} Display statuses of services"
echo
echo "${WHITE}Commands${NORMAL} (thanks to docker-compose):" echo "${WHITE}Commands${NORMAL} (thanks to docker-compose):"
get_docker_compose_commands_help | sed -r "s/ ([a-z]+)(\s+)/ ${DARKCYAN}\1${NORMAL}\2/g" get_docker_compose_commands_help | sed -r "s/ ([a-z]+)(\s+)/ ${DARKCYAN}\1${NORMAL}\2/g"
charm_actions_help=$(get_docker_charm_action_help) || return 1 charm_actions_help=$(get_docker_charm_action_help) || return 1
@ -5127,8 +5099,21 @@ while read-0 arg; do
shift shift
done < <(cla.normalize "$@") done < <(cla.normalize "$@")
## These actions are additions to docker-compose actions and charm
## actions
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." [ -n "$CACHEDIR" ] || die "No cache directory defined."
[ -d "$CACHEDIR" ] || die "Cache directory '$CACHEDIR' doesn't exists." [ -d "$CACHEDIR" ] || die "Cache directory '$CACHEDIR' doesn't exists."
case "$action" in case "$action" in
cache) cache)
case "${remainder_args[0]}" in case "${remainder_args[0]}" in
@ -5156,6 +5141,109 @@ EOF
;; ;;
esac esac
;; ;;
status)
state_inner_cols=(name charm type state root)
state_all_services=
state_services=()
state_columns=()
state_columns_default=(name charm type state version)
state_filters=()
state_columns_default_msg=""
for col in "${state_columns_default[@]}"; do
if [ -n "$state_columns_default_msg" ]; then
state_columns_default_msg+=","
fi
state_columns_default_msg+="$col"
done
help="\
Display status information on services.
If no services are provided, all services in the root compose file
will be displayed. Use the --all option to display status of all
services (including dependencies).
$exname offers a few possible columns that can be complete on a charm
level by implementing an \`actions/get-COLNAME\` script.
These are the compose's columns: ${state_inner_cols[@]}.
Usage: status [options] [SERVICE...]
Options:
-h, --help Print this message and quit
-a, --all Display status of all services
(removes all filter, and will add a
'root' first column by default)
-c, --column Column to display, can provide several
separated by commas, or option can be repeated.
(default: ${state_columns_default_msg})
-f, --filter Filter services by a key=value pair,
separated by commas or can be repeated.
(default: --filter root=yes)
"
while read-0 arg; do
case "$arg" in
--help|-h)
echo "$help"
exit 0
;;
--all|-a)
if [ "${#state_services[@]}" -gt 0 ]; then
err "Cannot use --all and provide services at the same time."
exit 1
fi
if [[ "${#state_filters[@]}" -gt 0 ]]; then
err "Cannot use --all and provide filters at the same time."
exit 1
fi
state_all_services=1
;;
--column|-c)
read-0 value
if [[ "$value" == *,* ]]; then
state_columns+=(${value//,/ })
else
state_columns+=("$value")
fi
;;
--filter|-f)
if [ "${#state_services[@]}" -gt 0 ]; then
err "Cannot use --filter and provide services at the same time."
exit 1
fi
if [ -n "$state_all_services" ]; then
err "Cannot use --all and provide filters at the same time."
exit 1
fi
read-0 value
if [[ "$value" == *,* ]]; then
state_filters+=(${value//,/ })
else
state_filters+=("$value")
fi
;;
--*|-*)
err "Unknown option '$arg'. Please check help:"
echo "$help" >&2
;;
*)
if [ -n "$state_all_services" ]; then
err "Cannot use --all and provide services at the same time."
exit 1
fi
if [[ "${#state_filters[@]}" -gt 0 ]]; then
err "Cannot use --filter and provide filters at the same time."
exit 1
fi
state_services+=("$arg")
;;
esac
done < <(cla.normalize "${remainder_args[@]}")
if [ "${#state_columns[@]}" == 0 ]; then
state_columns=("${state_columns_default[@]}")
fi
;;
esac esac
@ -5188,7 +5276,8 @@ charm.sanity_checks || die "Sanity checks about charm-store failed. Please corre
## Get services in command line. ## 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]} action_service=${remainder_args[0]}
if [ -z "$action_service" ]; then if [ -z "$action_service" ]; then
err "No such command or action: ${DARKCYAN}$action${NORMAL}" err "No such command or action: ${DARKCYAN}$action${NORMAL}"
@ -5236,6 +5325,12 @@ else
services_args=($(compose:yml:root:services)) || return 1 services_args=($(compose:yml:root:services)) || return 1
fi fi
;; ;;
status)
services_args=("${state_services[@]}")
if [ "${#services_args[@]}" == 0 ] && [ -z "$state_all_services" ]; then
services_args=($(compose:yml:root:services)) || return 1
fi
;;
config) config)
services_args=("${action_posargs[@]}") services_args=("${action_posargs[@]}")
;; ;;
@ -5245,7 +5340,7 @@ fi
export COMPOSE_ACTION="$action" export COMPOSE_ACTION="$action"
NO_CONSTRAINT_CHECK=True NO_CONSTRAINT_CHECK=True
case "$action" in case "$action" in
up)
up|status)
NO_CONSTRAINT_CHECK= NO_CONSTRAINT_CHECK=
if [ -n "$DEBUG" ]; then if [ -n "$DEBUG" ]; then
Elt "solve all relations" Elt "solve all relations"
@ -5325,6 +5420,11 @@ case "$action" in
done done
fi fi
;; ;;
status)
if [ -n "${state_all_services}" ] || [[ "${#state_filters[@]}" -gt 0 ]]; then
services_args=("${all_services[@]}")
fi
;;
esac esac
if [ -n "$is_docker_compose_action_multi_service" ]; then if [ -n "$is_docker_compose_action_multi_service" ]; then
@ -5372,6 +5472,7 @@ get_docker_compose "${services_args[@]}" >/dev/null || { ## precalculate variab
exit 1 exit 1
} }
## ##
## Pre-action ## Pre-action
## ##
@ -5386,7 +5487,7 @@ case "$action" in
full_init=true full_init=true
post_hook=true post_hook=true
;; ;;
""|down|restart|logs|config|ps)
""|down|restart|logs|config|ps|status)
full_init= full_init=
;; ;;
*) *)
@ -5450,6 +5551,149 @@ if [ "${PIPESTATUS[0]}" != 0 ]; then
fi fi
[ "$action" == "build" ] && exit 0 [ "$action" == "build" ] && exit 0
if [ "$action" == "status" ]; then
if [[ -n "${state_all_services}" ]] || [[ "${#state_filters[@]}" -gt 0 ]]; then
compose_yml_services=($(compose:yml:root:services)) || exit 1
fi
if [[ -n "${state_all_services}" ]]; then
state_columns=("root" ${state_columns[@]})
fi
state_columns_raw=()
for col in "${state_columns[@]}"; do
if [[ "$col" == "-"* ]]; then
col=${col#-}
fi
state_columns_raw+=("$col")
done
state_columns_align=""
for col in "${state_columns[@]}"; do
if [[ "$col" == "-"* ]]; then
state_columns_align+="+"
else
state_columns_align+="-"
fi
done
while read-0-err E "${state_columns_raw[@]}"; do
values=()
for col in "${state_columns_raw[@]}"; do
color=
value="${!col}"
read -r -- value_trim <<<"${!col}"
case "$col" in
root)
case "$value_trim" in
0) value=" ";;
1) value="*";;
esac
;;
name) color=darkyellow;;
charm) color=darkpink;;
state)
case "$value_trim" in
up) color=green;;
down) color=gray;;
deploying) color=yellow;;
*) color=red;;
esac
;;
type)
case "$value_trim" in
run-once) color=gray;;
stub) color=gray;;
*) color=darkcyan;;
esac
;;
*)
if [[ "${value_trim}" == "N/A" ]]; then
color=gray
fi
;;
esac
color="${color^^}"
if [ -n "$color" ]; then
values+=("${!color}$value${NORMAL}")
else
values+=("$value")
fi
done
first=1
for value in "${values[@]}"; do
if [ -n "$first" ]; then
first=
else
printf " "
fi
printf "%s" "$value"
done
printf "\n"
done < <(
set -o pipefail
filter_cols=()
for filter in "${state_filters[@]}"; do
IFS="=" read -r key value <<<"$filter"
## if not already in state_columns_raw
[[ " ${state_columns_raw[*]} " == *" $key "* ]] ||
filter_cols+=("$key")
done
for service in "${services_args[@]}"; do
declare -A values=()
for col in "${state_columns_raw[@]}" "${filter_cols[@]}"; do
case "$col" in
root)
if [[ " ${compose_yml_services[*]} " == *" ${service} "* ]]; then
value="1"
else
value="0"
fi
;;
name) value="$service" ;;
charm)
value=$(get_service_charm "$service") || { echo 1; exit 1; }
;;
state)
value=$(service:state "$service") || { echo 1; exit 1; }
;;
type)
value=$(get_service_type "$service") || { echo 1; exit 1; }
;;
*)
if has_service_action "$service" "get-$col" >/dev/null; then
state_msg=$(run_service_action "$service" "get-$col") || { echo 1; exit 1 ; }
if [[ "$state_msg" == *$'\n'* ]]; then
value="${state_msg%%$'\n'*}"
## XXXvlab: For now, these are not used, but we could
## display them in additional lines (in same "cell")
msgs="${state_msg#*$'\n'}"
else
value=${state_msg}
fi
else
value="N/A"
fi
;;
esac
values["$col"]="$value"
done
for filter in "${state_filters[@]}"; do
IFS="=" read -r key value <<<"$filter"
[[ "${values[$key]}" != "$value" ]] &&
continue 2
done
for col in "${state_columns_raw[@]}"; do
p0 "${values[$col]}"
done
done | col-0:normalize:size "${state_columns_align}"
echo 0
)
if [ "$E" != 0 ]; then
echo "E: '$E'" >&2
exit 1
fi
exit 0
fi
if [ "$action" == "run" ] && [ "${#services_args}" != 0 ]; then if [ "$action" == "run" ] && [ "${#services_args}" != 0 ]; then
charm=$(get_service_charm "${services_args[0]}") || exit 1 charm=$(get_service_charm "${services_args[0]}") || exit 1

Loading…
Cancel
Save