esl / release_poller

3 stars 2 forks source link

[travis] CI with docker rabbitmq container #13

Closed ghost closed 6 years ago

ghost commented 6 years ago

Ok - port clash on 15672 with travis.

Suggested plan of attack :

docker run --detach --rm --hostname bugs-bunny \
--name roger_rabbit \
-p 5672:5672 \
-p 15672 \
rabbitmq:3.7.7-management

Note how '-p 15672' is not mapped to a host port.

Extract the mapped port number :

docker inspect --format '{{ (index (index .NetworkSettings.Ports "15672/tcp") 0).HostPort }}' roger_rabbit

32768

ghost commented 6 years ago

@sescobb27 - an explanation of what the .travis.yml file is doing :

language: elixir
install: true
sudo: false
before_install:

First we launch a rabbitmq container - but we don't specify which port to map amqp to on the host as a consequence amqp will be assigned a random port such as 32431

-docker run --detach --rm --hostname bugs-bunny --name roger_rabbit -p 5672 rabbitmq:3.7.7`

Next we evaluate the docker inspect command and place its output into the variable POLLER_RMQ_PORT

- export POLLER_RMQ_PORT=$(docker inspect --format '{{ (index (index .NetworkSettings.Ports "5672/tcp") 0).HostPort }}' roger_rabbit )

This trick relies upon golang format strings - lets look at a couple of examples (taken from container-solutions.com)

docker inspect --format '{{ .Name }}' roger_rabbit
/roger_rabbit
docker inspect --format '{{ .NetworkSettings }}' roger_rabbit
{{ 1c0695e828a0708af8ae609b22f7c10e29aef97e34ddd4d006eb0ba9db62e27c false  0 map[25672/tcp:[] 4369/tcp:[] 5671/tcp:[] 5672/tcp:[{0.0.0.0 32771}]] /var/run/docker/netns/1c0695e828a0 [] []} {561311f5ab8ac8b9692154ea44aba202d9374de79d2548173a6e4e0dda093d96 172.17.0.1  0 172.17.0.3 16  02:42:ac:11:00:03} map[bridge:0xc42015e540]}
docker inspect --format '{{ .NetworkSettings.Ports }}' roger_rabbit
map[25672/tcp:[] 4369/tcp:[] 5671/tcp:[] 5672/tcp:[{0.0.0.0 32771}]]
docker inspect --format '{{ index .NetworkSettings.Ports "5672/tcp"}}' roger_rabbit
[map[HostIp:0.0.0.0 HostPort:32771]]

The next bit is cute, we want to wait until rabbitmq has initialized an is ready to use.

So what we do is we use the bash until shell built in command and have it curl the AMQP URL until it returns with a success (0) exit code.

We print a "." every time it executes so we have some feedback about how many times it's executed.

We pipe all the output (both stdout and stderr) to /dev/null because we don't want to fill the logfile with failed curl commands.

 - until curl --silent -XGET --fail http://127.0.0.1:${POLLER_RMQ_PORT} &> /dev/null ; do printf '.'; sleep 1; done

Then the rest of the yaml file

elixir:
  - '1.7.2'
before_script: 
  - "mix local.hex --force"
  - "mix local.rebar --force"  
  - "mix deps.get"                                                                                                                 
script: 
  - "mix test"
otp_release:
  - '21.0'
cache:
  directories:
    - _build
    - deps