diff --git a/bin/compose b/bin/compose index 98f39b5..00e69a9 100755 --- a/bin/compose +++ b/bin/compose @@ -979,8 +979,7 @@ get_compose_service_def () { fi [ -z "$service" ] && print_syntax_error "Missing service as first argument." - - docker_compose=$([ "$COMPOSE_YML_FILE" -a -e "$COMPOSE_YML_FILE" ] && cat "$COMPOSE_YML_FILE") + docker_compose=$(get_compose_yml_content) || return 1 result=$(_get_compose_service_def_cached "$service" "$docker_compose") || return 1 echo "$result" | tee "$cache_file" || return 1 } @@ -1664,13 +1663,12 @@ _run_service_action_direct() { return 1 fi - compose_file=$(get_compose_yml_location) || return 1 export action_errlvl_file="$state_tmpdir/action-$service-$charm-$action-errlvl" export state_tmpdir { ( set +e ## Prevents unwanted leaks from parent shell - export COMPOSE_CONFIG=$(cat "$compose_file") + export COMPOSE_CONFIG=$(get_compose_yml_content) export METADATA_CONFIG=$(charm.metadata "$charm") export SERVICE_NAME=$service export ACTION_NAME=$action @@ -1705,7 +1703,6 @@ _run_service_action_relation() { export RELATION_DATA_FILE=$(get_relation_data_file "$service" "$target_service" "$relation_name" "$relation_config") - compose_file=$(get_compose_yml_location) || return 1 export action_errlvl_file="$state_tmpdir/action-$service-$charm-$action-errlvl" export state_tmpdir { @@ -2100,7 +2097,7 @@ get_default_project_name() { return 0 fi fi - echo "project" + echo "orphan" return 0 } export -f get_default_project_name @@ -2169,6 +2166,10 @@ launch_docker_compose() { export -f launch_docker_compose get_compose_yml_location() { + if ! [ -z ${COMPOSE_YML_FILE+x} ]; then ## if set, even if empty + echo "$COMPOSE_YML_FILE" + return 0 + fi parent=$(while ! [ -e "./compose.yml" ]; do [ "$PWD" == "/" ] && exit 0 cd .. @@ -2178,22 +2179,62 @@ get_compose_yml_location() { echo "$parent/compose.yml" return 0 fi + ## XXXvlab: do we need this additional environment variable, + ## COMPOSE_YML_FILE is not sufficient ? if [ "$DEFAULT_COMPOSE_FILE" ]; then if ! [ -e "$DEFAULT_COMPOSE_FILE" ]; then - err "No 'compose.yml' was found in current or parent dirs," \ + warn "No 'compose.yml' was found in current or parent dirs," \ "and \$DEFAULT_COMPOSE_FILE points to an unexistent file." \ "(${DEFAULT_COMPOSE_FILE})" - die "Please provide a 'compose.yml' file." + return 0 fi echo "$DEFAULT_COMPOSE_FILE" return 0 fi - err "No 'compose.yml' was found in current or parent dirs, and no \$DEFAULT_COMPOSE_FILE was set." - die "Please provide a 'compose.yml' file." - return 1 + warn "No 'compose.yml' was found in current or parent dirs, and no \$DEFAULT_COMPOSE_FILE was set." + return 0 } export -f get_compose_yml_location +get_compose_yml_content() { + local cache_file="$state_tmpdir/$FUNCNAME.cache" + if [ -e "$cache_file" ]; then + cat "$cache_file" && + touch "$cache_file" || return 1 + return 0 + fi + + if [ -z "$COMPOSE_YML_FILE" ]; then + COMPOSE_YML_FILE=$(get_compose_yml_location) || exit 1 + fi + if [ -e "$COMPOSE_YML_FILE" ]; then + debug "Found $WHITE$exname$NORMAL YAML file in '$COMPOSE_YML_FILE'." + COMPOSE_YML_CONTENT=$(cat "$COMPOSE_YML_FILE") + else + debug "No compose file found. Using an empty one." + COMPOSE_YML_CONTENT="" + fi + + output=$(echo "$COMPOSE_YML_CONTENT"| shyaml get-value 2>&1) + if [ "$?" != 0 ]; then + outputed_something= + while IFS='' read -r line1 && IFS='' read -r line2; do + [ "$outputed_something" ] || err "Invalid YAML in '$COMPOSE_YML_FILE':" + outputed_something=true + echo "$line1 $GRAY($line2)$NORMAL" + done < <(echo "$output" | grep ^yaml.scanner -A 100 | + sed -r 's/^ in "", //g' | sed -r 's/^yaml.scanner.[a-zA-Z]+: //g') | + prefix " $GRAY|$NORMAL " + [ "$outputed_something" ] || { + err "Unexpected error while running 'shyaml get-value' on '$COMPOSE_YML_FILE':" + echo "$output" | prefix " $GRAY|$NORMAL " + } + exit 1 + fi + echo "$COMPOSE_YML_CONTENT" | tee "$cache_file" || return 1 +} +export -f get_compose_yml_content + get_default_target_services() { local services=("$@") @@ -2769,26 +2810,10 @@ done < <(cla.normalize "$@") export DOCKER_DATASTORE=${DOCKER_DATASTORE:-/srv/docker-datastore} + COMPOSE_YML_FILE=$(get_compose_yml_location) || exit 1 -export COMPOSE_YML_FILE -debug "Found $WHITE$exname$NORMAL YAML file in '$COMPOSE_YML_FILE'." - -output=$(shyaml get-value < "$COMPOSE_YML_FILE" 2>&1) -if [ "$?" != 0 ]; then - outputed_something= - while IFS='' read -r line1 && IFS='' read -r line2; do - [ "$outputed_something" ] || err "Invalid YAML in '$COMPOSE_YML_FILE':" - outputed_something=true - echo "$line1 $GRAY($line2)$NORMAL" - done < <(echo "$output" | grep ^yaml.scanner -A 100 | - sed -r 's/^ in "", //g' | sed -r 's/^yaml.scanner.[a-zA-Z]+: //g') | - prefix " $GRAY|$NORMAL " - [ "$outputed_something" ] || { - err "Unexpected error while running 'shyaml get-value' on '$COMPOSE_YML_FILE':" - echo "$output" | prefix " $GRAY|$NORMAL " - } - exit 1 -fi +export COMPOSE_YML_FILE COMPOSE_YML_CONTENT + charm.sanity_checks || die "Sanity checks about charm-store failed. Please correct." @@ -2818,7 +2843,7 @@ if [ -z "$is_docker_compose_action" -a "$action" ]; then fi else if [[ "$action" =~ (up|ps) && "${#services_args[@]}" == 0 ]]; then - services_args=($(shyaml keys <"$COMPOSE_YML_FILE")) + services_args=($(echo "$COMPOSE_YML_CONTENT" | shyaml keys)) fi if [ "$action" == "config" ]; then services_args=("${action_posargs[@]}") @@ -2931,7 +2956,7 @@ case "$action" in launch_docker_compose "${compose_opts[@]}" "$action" "${action_opts[@]}" "${action_posargs[@]}" "${remainder_args[@]}" fi ;; -esac +esac || exit 1 if [ "$post_hook" -a "${#services_args[@]}" != 0 ]; then