From f1d99cea05ef09a57a8bc10595455bd4e6a43d03 Mon Sep 17 00:00:00 2001 From: Valentin Lab Date: Fri, 16 Sep 2022 09:22:40 +0200 Subject: [PATCH] new: [compose-core] add ``after`` option in relation definition With ``after``, you can specify another relation name or a list of relation names, after which the current relation must wait before launching it's relation hook. Signed-off-by: Valentin Lab --- bin/compose-core | 88 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 83 insertions(+), 5 deletions(-) diff --git a/bin/compose-core b/bin/compose-core index 68662d0..9d2a042 100755 --- a/bin/compose-core +++ b/bin/compose-core @@ -2423,10 +2423,33 @@ _out_new_relation_from_defs() { td=${td:-True} rc=$(merge_yaml_str "$rc_prov" "$rc") || return 1 - printf "%s\0" "$service" "$relation_name" "$ts" "$rc" "$td" + after=$(_out_after_value_from_def "$service" "$rn" "$rel_def") || return 1 + printf "%s\0" "$after" "$service" "$relation_name" "$ts" "$rc" "$td" } +_out_after_value_from_def() { + local service="$1" relation_name="$2" relation_def="$3" after_t after + if after_t=$(echo "$relation_def" | shyaml get-type after 2>/dev/null); then + case "$after_t" in + sequence) + after="$(echo "$relation_def" | shyaml get-values after 2>/dev/null)" || return 1 + after=",$service:${after//$'\n'/,$service:}," + ;; + struct) + err "Invalid type for ${WHITE}after${NORMAL}'s value in ${DARKBLUE}$relation_name${NORMAL}'s definition." + return 1 + ;; + str) + after=",$service:$(echo "$relation_def" | shyaml get-value after "" 2>/dev/null)," || return 1 + ;; + esac + else + after="" + fi + e "$after" +} + get_all_relations () { local cache_file="$state_tmpdir/$FUNCNAME.cache.$(H "$@" "$(declare -p without_relations)")" \ @@ -2460,7 +2483,8 @@ get_all_relations () { debug "Ignoring compose $DARKYELLOW$service$NORMAL --$DARKBLUE$relation_name$NORMAL--> ${DARKYELLOW}$ts$NORMAL" continue } - printf "%s\0" "$service" "$relation_name" "$ts" "$relation_config" "$tech_dep" + ## First is priority, that can be adjusted in second step + printf "%s\0" "" "$service" "$relation_name" "$ts" "$relation_config" "$tech_dep" ## adding target services ? [ "${services[$ts]}" ] && continue @@ -2489,16 +2513,18 @@ get_all_relations () { } default_options=$(printf "%s" "$relation_def" | shyaml -y get-value "default-options" 2>/dev/null) + after=$(_out_after_value_from_def "$service" "$relation_name" "$relation_def") || return 1 ## is this "use" declaration satisfied ? found= - while read-0 s rn ts rc td; do + while read-0 p s rn ts rc td; do if [ -z "$found" -a "$service" == "$s" -a "$relation_name" == "$rn" ]; then if [ "$default_options" ]; then rc=$(merge_yaml_str "$default_options" "$rc") || return 1 fi found="$ts" + p="$after" fi - printf "%s\0" "$s" "$rn" "$ts" "$rc" "$td" + printf "%s\0" "$p" "$s" "$rn" "$ts" "$rc" "$td" done < "${cache_file}.wip" > "${cache_file}.wip.new" mv "${cache_file}.wip.new" "${cache_file}.wip" if [ "$found" ]; then ## this "use" declaration was satisfied @@ -2638,8 +2664,60 @@ get_all_relations () { rm -f "${cache_file}"{,.wip,.wip.new} ## no cache return 1 fi + + ## + ## Sort relations thanks to uses =metadata.yml= relations. + ## + + mv "${cache_file}.wip"{,.in} && + rm -f "${cache_file}.wip.final" && + touch "${cache_file}.wip.final" || { + err "Unexpected error when mangling cache files." + return 1 + } + declare -A relation_done=() + while true; do + had_remaining_relation= + had_new_relation= + while read-0 p s rn ts rc td; do + if [ -z "$p" ] || [ "$p" == "," ]; then + relation_done["$s:$rn"]=1 + # printf " .. %-30s %-30s %-30s\n" "--" "$s" "$rn" >&2 + printf "%s\0" "$s" "$rn" "$ts" "$rc" "$td" >> "${cache_file}.wip.final" + had_new_relation=1 + else + # printf " !! %-30s %-30s %-30s\n" "$p" "$s" "$rn" >&2 + printf "%s\0" "$p" "$s" "$rn" "$ts" "$rc" "$td" >> "${cache_file}.wip.out" + had_remaining_relation=1 + fi + done < "${cache_file}.wip.in" + [ -z "$had_remaining_relation" ] && break + mv "${cache_file}.wip."{out,in} + while read-0 p s rn ts rc td; do + for rel in "${!relation_done[@]}"; do + p="${p//,$rel,/,}" + done + # printf " CC %-30s %-30s %-30s\n" "$p" "$s" "$rn" >&2 + if [ -z "$had_new_relation" ]; then + err "${DARKYELLOW}$s${NORMAL} --${DARKBLUE}$rn${NORMAL}--> ${DARKYELLOW}$ts${NORMAL} missing required ${WHITE}after${NORMAL} relations:" + for rel in ${p//,/ }; do + rel_s=${rel%%:*} + rel_r=${rel##*:} + echo " - ${DARKYELLOW}$rel_s${NORMAL} --${DARKBLUE}$rel_r${NORMAL}--> ${DARKGRAY}*${NORMAL}" >&2 + done + else + printf "%s\0" "$p" "$s" "$rn" "$ts" "$rc" "$td" >> "${cache_file}.wip.out" + fi + done < "${cache_file}.wip.in" + if [ -z "$had_new_relation" ]; then + rm -f "${cache_file}"{,.wip{,new,in,out,final}} ## no cache + return 1 + fi + mv "${cache_file}.wip."{out,in} + done + export ALL_RELATIONS="$cache_file" - mv "${cache_file}"{.wip,} + mv "${cache_file}"{.wip.final,} || return 1 cat "$cache_file" } export -f get_all_relations