Hi all.
I’ve just found out that my deploy is broken because an action with “state=restarted” just removes the container! I didn’t dig into yet, though I saw in the sources stuff like
def restarted(manager, containers, count, name):
…
for container in manager.get_differing_containers():
manager.stop_containers([container])
manager.remove_containers([container])
That’s not correct - to remove/recreate containers, while ‘restarted’ state is just expected to be stop/start. And for updating from a newer image we have ‘reloaded’.
Anyways in my case the image doesn’t change at all, it all looks like a bug. In the same playbook I create a container (glassfish), set it up and then restart (else glassfish won’t pick up new settings) and end up with “fatal: [dev]: FAILED! => {“changed”: true, “failed”: true, “msg”: “Docker API Error: No such container: 9a0b0f6fad397a47f6b5ae4147deab24aeb1af5428c39f1134f30ad64fddfc2c”}”
`
def started(manager, containers, count, name):
…
if name and containers.deployed:
A stopped container exists with the requested name.
Clean it up before attempting to start a new one.
manager.remove_containers(containers.deployed)
`
Whoever implemented this in 2.0 please explain why?
According to the Docker principles a container doesn’t disappear when it’s stopped. It is not a mere process, it has a more complicated lifecycle and being stopped is not the end, it can be started afterwards. Even several times. It has some data, some logs inside, some operational changes on its own filesystem layer. Deleteing a container is a very different operation in Docker.
There are use cases: imagine an application that has to be restarted sometimes during its lifespan (reload config or such). Imagine an environment where some users have the permission to create containers (developers) and some only to start/stop them (quality engineers).
Ansible 1.9 supported this container lifecycle. Ansible 2.0 doesn’t. That’s a real regression.
The refactoring of the module’s states happened almost exactly a year ago, with this commit.
We’re working on a new docker module (actually a set of docker modules). So your questions and concerns are quite relevant and point to some obvious flaws in the current module that I don’t want to repeat. Hopefully this thread will generate some good discussion and help shape the new module, although it unfortunately won’t immediately fix the issues you’re running into.
We’re just now determining the scope, parameters, return values, etc. for what will be the docker_container module, which will manage container state. I agree that the “started” state should not be deleting containers. “started” should find the matching container, and if it is not running, attempt to start it. The same with “restarted”. It should simply stop and start the matching container.
Another challenge with the existing docker module is that it attempts to manage a set of containers. This makes things complicated, if not confusing. Because it’s always working on a set, a container identifier (i.e. name, long ID, short ID) is not required. When an identifier is not provided, the set of containers to operate on is determined by image, command and entry point. This may be why there is confusion between the definition and implementation of the “started” and “restarted” states.
What we have spec’d out so far for the new modules is on an etherpad. Comments welcome.
Which is a good excuse to tell everybody about "proposals!"
At the contributor summit, one of the key areas of discussion was how
to shape proposals. The traditional answer has been "submit a pull
request" or "discuss it on the list".
The problem with "discuss it on the list" is that we don't have any
process for tracking mailing list discussions, and it's painful even
to go find these kinds of discussions.
The problem with "submit a pull request" is that people often want
feedback before sinking a lot of time into code.
Thus: proposals. Anyone can submit a proposal, and we will be able to
set aside time to discuss the proposals that bubble up to the top --
which is a process we have yet to figure out entirely.
One question that has come up with the proposals, should the discussion be on the PR ticket that creates the proposal or should we annotate the ‘code’ and use subsequent PRs to update it?
One question that has come up with the proposals, should the discussion be
on the PR ticket that creates the proposal or should we annotate the 'code'
and use subsequent PRs to update it?
I'll move it to a proposal when it's in a proposal state. It seems
difficult, and time consuming to attempt having a conversation through PRs.
I just submitted a PR to update the Will Thames proposal. No idea if I
updated the doc in a way that's helpful. And, how long will it take to get
the PR reviewed and merged? Will anyone find it and read it? To me the
proposal should be the culmination or conclusion to a discussion thread, not
the start of it.
You may be right that "conversation through PR" is clever but too painful.
Note that we can have mailing list discussions that point back to an
artifact. They don't have to be mutually exclusive.
To me, the most important thing is to have an artifact, somewhere,
that is public and can be revised and reshaped. An artifact tells
people "hey, this is a thing that's being worked on!" I don't have a
right answer for how that looks. I only know that it needs to exist.
I’m working on the ‘proposal’ for docker_container module now. I’ll submit a PR In a bit. Under docs/proposal I’m creating a docker folder where in my head all the docker proposals should forevermore live.
I don’t know what the right format is, what should be included, what the life expectancy of the thing is, what it’s final purpose is, what the proper protocol for updating the thing might be, or any of that. Maybe none of that matters? I’ll just be able to point to something and say, “That. I did that.”
I didn’t get where to discuss the proposals, so I comment here:
Agree with dropping off the “count” parameter.
“image” should not be required parameter if container name or id is provided (from my production use case where each build goes into its own tagged image and the deploy script has to delete an old container by name no matter which image has been used for it).
Need to clarify what happens if “entrypoint” interferes with “command” in the same task.