2017-02-10 4 views
0

Я пытаюсь написать сценарий Bash, который остановит хранилище контейнеров Docker, перестроит их и запустит некоторые тесты на них (используя Pytest). Для того, чтобы сделать код DRY, я попытался определить функцию wait_for_container следующим образом:Как использовать локальные переменные в функции Bash

docker stop $(docker ps -a -q) 

docker-compose build 

docker-compose up -d 

function wait_for_container { 
    local CONTAINER=$1 
    local PORT=$2 

    ADDR=$(docker inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $CONTAINER) 

    until nc -z $CONTAINER $PORT 
    do 
     echo "Waiting for the $CONTAINER container..." 
     sleep 0.5 
    done 
    echo "$CONTAINER listening at $ADDR:$PORT" 
} 

RETHINKDB_CONTAINER=ipercroncompose_rethinkdb_1 
RETHINKDB_PORT=28015 
wait_for_container $RETHINKDB_CONTAINER $RETHINKDB_PORT 

RABBITMQ_CONTAINER=ipercroncompose_rabbitmq_1 
RABBITMQ_PORT=5672 
wait_for_container $RABBITMQ_CONTAINER $RABBITMQ_PORT 

cd test 
pytest 

Однако, я считаю, что это не работает: я повторно получить

nc: getaddrinfo: Temporary failure in name resolution 
Waiting for the ipercroncompose_rethinkdb_1 container... 

С другой стороны, следующий не DRY скрипт делает работы:

docker stop $(docker ps -a -q) 

docker-compose build 

docker-compose up -d 

RETHINKDB_CONTAINER=ipercroncompose_rethinkdb_1 
RETHINKDB_ADDR=$(docker inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $RETHINKDB_CONTAINER) 
RETHINKDB_PORT=28015 

until nc -z $RETHINKDB_ADDR $RETHINKDB_PORT 
do 
    echo "Waiting for the RethinkDB container..." 
    sleep 0.5 
done 
echo "RethinkDB listening at ${RETHINKDB_ADDR}:${RETHINKDB_PORT}." 

RABBITMQ_CONTAINER=ipercroncompose_rabbitmq_1 
RABBITMQ_ADDR=$(docker inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $RABBITMQ_CONTAINER) 
RABBITMQ_PORT=5672 

until nc -z $RABBITMQ_ADDR $RABBITMQ_PORT 
do 
    echo "Waiting for the RabbitMQ container..." 
    sleep 0.5 
done 
echo "RabbitMQ listening at ${RABBITMQ_ADDR}:${RABBITMQ_PORT}." 

cd test 
pytest 

и эхо

RethinkDB listening at 172.18.0.2:28015. 
Waiting for the RabbitMQ container... 
Waiting for the RabbitMQ container... 
Waiting for the RabbitMQ container... 
Waiting for the RabbitMQ container... 
Waiting for the RabbitMQ container... 
Waiting for the RabbitMQ container... 
Waiting for the RabbitMQ container... 
Waiting for the RabbitMQ container... 
Waiting for the RabbitMQ container... 
Waiting for the RabbitMQ container... 
Waiting for the RabbitMQ container... 
Waiting for the RabbitMQ container... 
Waiting for the RabbitMQ container... 
Waiting for the RabbitMQ container... 
Waiting for the RabbitMQ container... 
Waiting for the RabbitMQ container... 
Waiting for the RabbitMQ container... 
Waiting for the RabbitMQ container... 
Waiting for the RabbitMQ container... 
Waiting for the RabbitMQ container... 
Waiting for the RabbitMQ container... 
Waiting for the RabbitMQ container... 
Waiting for the RabbitMQ container... 
Waiting for the RabbitMQ container... 
Waiting for the RabbitMQ container... 
Waiting for the RabbitMQ container... 
Waiting for the RabbitMQ container... 
Waiting for the RabbitMQ container... 
RabbitMQ listening at 172.19.0.2:5672. 

, а затем результаты испытаний Pytests. Как я могу улучшить функцию wait_for_container для достижения такого же эффекта?

+1

Я не вижу ничего плохого на беглом взгляде (вы, вероятно, должны указывать переменные разложения, но ваши образцы данных не выглядят проблематичными с неупорядоченными расширениями), и странно проблема связана с вызываемой утилитой 'nc'. Не могли бы вы добавить ведение журнала в свой скрипт, чтобы вы могли видеть, как выглядит вся команда 'nc' при исполнении? – Fred

+1

Кстати, использование функций, позволяющих избежать дублирования кода, - это путь, и нет причин, по которым он не должен работать, поэтому найдите время, чтобы это исправить (это, вероятно, всего лишь небольшая проблема с жесткой точкой, которая может не связаны с использованием функции вообще). – Fred

+1

'до nc -z $ CONTAINER $ PORT' ==>' до nc -z $ ADDR $ PORT' –

ответ

0

После Grisha Levit «s и Fred» s комментарии, вот адаптированный сценарий:

docker stop $(docker ps -a -q) 
docker-compose build 
docker-compose up -d 

function wait_for_container { 
    local CONTAINER=$1 
    local PORT=$2 

    local ADDR=$(docker inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $CONTAINER) 
    echo $ADDR 

    until nc -z $ADDR $PORT 
    do 
     echo "Waiting for the $CONTAINER container..." 
     sleep 0.5 
    done 
    echo "$CONTAINER listening at $ADDR:$PORT" 
} 

wait_for_container ipercroncompose_rethinkdb_1 28015 
wait_for_container ipercroncompose_rabbitmq_1 5672 

cd test 
pytest 

Проблема заключалась в том, что на самом деле netcat требует IP-адреса в качестве первого ввода, а не имя контейнера Докер. (Я также сделал переменную ADDR локальной).

+1

Просто общая практика кода, капитализированные переменные предназначены для использования только для переменных среды, в нижнем регистре используются ваши локальные переменные сценария для лучшей читаемости. – Inian

Смежные вопросы