question about the docker module

Hi all!

I have what I think is a simple question. It pertains to what is visible/available in the “docker_containers” dictionary when running a run book.

Ok, so, what’s throwing me off is whether to use one of the following:

  • name launch containers

docker: image=df02bd73464a count={{ start_containers_count }}

Or

  • name launch containers

docker: image=df02bd73464a name=somename_{{item}}

with_sequence: count={{ start_containers_count }}

It is the first snippet that works for doing this next task:

  • name: print container info

debug: msg=“{{item[‘NetworkSettings’][‘IPAddress’]}}”

with_items: docker_containers

Why? Because the latter results in “docker_containers” only having the last container’s information (last container launched), whereas the former gives me all of them.

It’s probably something really simple…

I’ll venture a guess as to what is happening here, but I don’t know for sure. I guess I could look at the source. :wink:

I think what’s happening here is that with_sequence is actually invoking a new module build/upload/run for every item in the with_sequence, and thereby overwriting the docker_containers variable with the facts from the last docker module run. So, it’s a guess, but you could probably verify that by running with some extra verbosity (I think you need at least -vv). This is definitely not happening in the first container launch, because it’s passing those values directly to the module, running only once.

If you don’t give it a shot, I’ll probably take a look at it in the morning.

Let me know what you find!

Thanks! I could actually tinker with this. I’m comfortable with ansible source now, having a pull-request in for the nova_compute module (ahem :slight_smile: What you describe seems to be the case and in fact I was running with -vvvv and noticed this.

Yep yep!

Paul nailed it.

Ideally every cloud module would support an exact_count like was done for Rackspace and EC2, where it makes that number of containers exist.

Though I’m a little unclear why you’d want multiple docker containers on the same host, the way that sucker runs (i.e. it’s not a cloud API so those images get all on the same box).

–Michael

Hi Paul,

When are you around in IRC? I wouldn’t mind going over this with you. I was looking at the code, poking around and had some questions.

I’m EDT.

I’m in the channel as angstwad. I’m not very good at paying attention to my IRC, but I’ll keep an eye on it. :slight_smile:

Michael,

With containers (versus VMs), you ideally can run a LOT of them on a single host. RedHat did a demo with 1000s of them running: http://www.theregister.co.uk/2014/04/15/red_hat_project_atomic_docker/

Maybe I’m not understanding what you are saying, and apologies in advance :wink:

So, I was looking at the code but having a heck of a time figuring out how to do some in-depth debugging. I want to print out a dictionary (“containers” in this case)

def get_deployed_containers(self):

determine which images/commands are running already

containers = self.client.containers(all=True)
image = self.module.params.get(‘image’)
command = self.module.params.get(‘command’)
if command:
command = command.strip()
name = self.module.params.get(‘name’)
if name and not name.startswith(‘/’):
name = ‘/’ + name
deployed =

I’m new to Ansible, I will admit, and using my tried-and-true “print” statement debugging tool breaks an ansible run. I’d like to know the trick to being able to debug Python code that runs ansible.

Regards,

Patrick

Hey Patrick,

I typically use “raise Exception(message)” when debugging in modules, since Ansible captures this output and prints it to the console.

Hi Patrick,

Actually i don’t know if it has anything to do with the “with_sequences” clause. I have the following code

docker: name=“cluster-data” hostname=“{{ data_hostname }}” image=“lgueye/cluster-data” state=present

.
.
.
docker: name=“cluster-index” hostname=“{{ index_hostname }}” image=“lgueye/cluster-index” state=present

When I loop over the docker_containers dict, seeking for IP adresses, I only get one IP adress.
I dumped the dict and It contains information only about the last running container.

I’m just providing information, unfortunately I I’m totally unable to provide a fix right now. Sorry.

This has to do with the way that new facts are returned from ansible
modules. Anytime a task is run, the module that is run by that task
has an opportunity to return new facts in an _ansible_facts entry.
This is usually a mapping of names to values that were determined
during the module's run. Ansible on the controlling machine reads the
data in _ansible_facts and adds the new facts to the global facts
dictionary that is available to subsequent tasks. Ansible does not
provide any automatic namespacing for the facts returned by tasks.
That means that if two tasks return dicts that use some of the same
keys in _ansible_facts then the values from the latest task to be run
will overwrite the earlier ones.

So to take three examples we have:

tasks:
  - docker: name="cluster-data" hostname="{{ data_hostname }}"
image="lgueye/cluster-data" state=present
  - docker: name="cluster-data" hostname="{{ index_hostname }}"
image="lgueye/cluster-data" state=present

In this example, we have two tasks calling the same module to do the
same thing to different hostnames. The module is almost certainly
going to return the same _ansible_facts dictionary entries for both
calls which means only the latest one will be seen by subsequent
tasks.

tasks:
  - docker: image=df02bd73464a name=somename_{{item}}
    with_sequence: count={{ start_containers_count }}

In this example, we are looping start_containers_count times and
invoking the docker module each time with a slightly different name
parameter. So even though it's not as apparent, it's doing the same
thing as the above example.

tasks:
  - docker: image=df02bd73464a count={{ start_containers_count }}

Only in this example are we actually executing the docker module only
a single time. We're telling the module that it is responsible for
starting up start_countainr_count instances on its own. Since the
module has all the information in its one invocation to start all of
hte containers, it is able to return information about all of the
containers that it started in its one run to the ansible controller so
the facts are set so that you can see all of the ip and host
information.

Hope that explanation is helpful!
-Toshio

Thank you very much for your answer. Now I get it fully.

Is there a way to append the docker_containers result in a dict after each execution: I need all containers {IP,name} couple later in the execution?

you can use a add_host or set_fact task after each docker task.

I did not know about set_fact. I'll give it a try.
Also, I will review my understanding of add_host. I could not save both name and IP.
Anyway thank you all for your answers. This community is one of the most active and helpful.
Regards,

Louis