..for Greater Good.
Save CI resources and shorten wait-in-zuul-queue times
for other patches, when tox/pep8 checks failed.
NOTE: for example, standalone jobs are defined as a template in
tripleo-ci, and here we are adding and override the listed jobs for the
dependencies/files options. If a job is added to the standlone template
in tripleo-ci, we need to add the job and dependency here manually.
If we won't, that job will be consumed as is and run w/o dependencies.
That is the price to pay for not having overrides managed centrally in
tripleo-ci. The latter wouldn't work neither as a single template
cannot fit all the specific needs of numerous tripleo repos. So the
final call was made to manage overrides via local overrides for tripleo
repos.
For core openstack python projects it might make sense to
not split them apart and run them all together. For things like
TripleO/Kolla/Puppet/etc where we have layers of interactions that can
be affected by the results from the linters/unit jobs it makes
sense to split them out.
For example, in tripleo since we use packages, if the unit test fails
the integration test may fail because when we go to built the package
with the new source, the unit test int he package build fails. Thus
we know that'll be a wasted execution and you won't actually get any
results.
An alternative Today:
patchset one:
pep8 SUCCESS
unittest FAILURE
integration FAILURE
patchset two:
pep8 SUCCESS
unittest SUCCESS
integration FAILURE
patchset three:
pep8 SUCCESS
unittest SUCCESS
integration SUCCESS
Future:
patchset one:
pep8 SUCCESS
unittest FAILURE
integration SKIPPED
patchset two:
pep8 SUCCESS
unittest SUCCESS
integration FAILURE
patchset three:
pep8 SUCCESS
unittest SUCCESS
integration SUCCESS
This may not be true for devstack but if the unit
tests are failing, then the code is likely bad (backwards
compatibility/wrong assumptions about change/etc) and we shouldn't be
running an actual deployment.
Related upstream ML threads:
* http://lists.openstack.org/pipermail/openstack-dev/2018-March/
127869.html
* http://lists.openstack.org/pipermail/openstack-discuss/
2019-February/003142.html
Change-Id: I967ff0323756e63e9bd66049080dde2a870399fd
Signed-off-by: Bogdan Dobrelya <bdobreli@redhat.com>
paunch
Utility to launch and manage containers using YAML based configuration data
- Free software: Apache license
- Documentation: https://docs.openstack.org/developer/paunch
- Source: https://git.openstack.org/cgit/openstack/paunch
- Bugs: https://bugs.launchpad.net/paunch
- Release Notes: https://docs.openstack.org/releasenotes/paunch
Features
- Single host only, operations are performed via the docker client on the currently configured docker service.
- Zero external state, only labels on running containers are used when determining which containers an operation will perform on.
- Single threaded and blocking, containers which are not configured to detach will halt further configuration until they exit.
- Co-exists with other container configuration tools. Only containers created by paunch will be modified by paunch. Unique container names are assigned if the desired name is taken, and containers are renamed when the desired name becomes available.
- Accessable via the
paunchcommand line utility, or by importing python packagepaunch. - Builtin
debugcommand lets you see how individual containers are run, get configuration information for them, and run them any way you need to.
Running Paunch Commands
The only state that paunch is aware of is the labels that it sets on running containers, so it is up to the user to keep track of what paunch configs should be running so that others can be deleted on cleanup. For these examples we're going to store that state in a simple text file:
$ touch paunch-state.txt
We'll start of by deleting any containers that were started by
previous calls to paunch apply:
$ paunch --verbose cleanup $(cat paunch-state.txt)
Next we'll apply a simple hello-world config found in
examples/hello-world.yml which contains the following:
hello:
image: hello-world
detach: false
Applied by running:
$ paunch --verbose apply --file examples/hello-world.yml --config-id hi
$ echo hi >> paunch-state.txt
A container called hello will be created, print a Hello
World message, then exit. You can confirm that it still exists by
running docker ps -a.
Now lets try running the exact same paunch apply
command:
$ paunch --verbose apply --file examples/hello-world.yml --config-id hi
This will not make any changes at all due to the idempotency behaviour of paunch.
Lets try again with a unique --config-id:
$ paunch --verbose apply --file examples/hello-world.yml --config-id hi-again
$ echo hi-again >> paunch-state.txt
Doing a docker ps -a now will show that there are now 2
containers, one called hello and the other called
hello-(random suffix). Lets delete the one associated with
the hi config-id:
$ cat paunch-state.txt
$ echo hi-again > paunch-state.txt
$ cat paunch-state.txt
$ paunch --verbose cleanup $(cat paunch-state.txt)
Doing a docker ps -a will show that the original
hello container has been deleted and
hello-(random suffix) has been renamed to
hello
Generally paunch cleanup will be run first to delete
containers for configs that are no longer apply. Then a series of
paunch apply commands can be run. If these
apply calls are part of a live upgrade where a mixture of
old and new containers are left running, the upgrade can be completed in
the next run to paunch cleanup with the updated list of
config-id state.
Paunch can also be used as a library by other tools. By default
running the paunch command won't affect these other
containers due to the different managed_by label being set
on those containers. For example if you wanted to run paunch commands
masquerading as the heat-agents
docker-cmd
hook then you can run:
paunch --verbose apply --file examples/hello-world.yml --config-id hi --managed-by docker-cmd
This will result in a hello container being run, which
will be deleted the next time the docker-cmd hook does its
own cleanup run since it won't be aware of a
config_id called hi.
Idempotency Behaviour
In many cases the user will want to use the same --config-id with changed config data. The aim of the idempotency behaviour is to leave containers running when their config has not changed, but replace containers which have modified config.
When paunch apply is run with the same
--config-id but modified config data, the following logic
is applied:
- For each existing container with a matching config_id and
managed_by:
- delete containers which no longer exist in config
- delete containers with missing config_data label
- delete containers where config_data label differs from current config
- Do a full rename to desired names since deletes have occured
- Only create containers from config if there is no container running with that name
execactions will be run regardless, so commands they run may require their own idempotency behaviour
Only configuration data is used to determine whether something has
changed to trigger replacing the container during apply.
This means that changing the contents of a file referred to in
env_file will not trigger replacement unless
something else changes in the configuration data (such as the path
specified in env_file).
The most common reason to restart containers is to have them running
with an updated image. As such it is recommended that stable image tags
such as latest are not used when specifying the
image, and that changing the release version tag in the
configuration data is the recommended way of propagating image changes
to the running containers.
Debugging with Paunch
The paunch debug command allows you to perform specific
actions on a given container. This can be used to:
- Run a container with a specific configuration.
- Dump the configuration of a given container in either json or yaml.
- Output the docker command line used to start the container.
- Run a container with any configuration additions you wish such that you can run it with a shell as any user etc.
The configuration options you will likely be interested in here include:
--file <file> YAML or JSON file containing configuration data
--action <name> Action can be one of: "dump-json", "dump-yaml",
"print-cmd", or "run"
--container <name> Name of the container you wish to manipulate
--interactive Run container in interactive mode - modifies config
and execution of container
--shell Similar to interactive but drops you into a shell
--user <name> Start container as the specified user
--overrides <name> JSON configuration information used to override
default config values
file is the name of the configuration file to use
containing the configuration for the container you wish to use.
Here is an example of using paunch debug to start a root
shell inside the test container:
# paunch debug --file examples/hello-world.yml --interactive --shell --user root --container hello --action run
This will drop you an interactive session inside the hello world container starting /bin/bash running as root.
To see how this container is started normally:
# paunch debug --file examples/hello-world.yml --container hello --action print-cmd
You can also dump the configuration of this to a file so you can edit it and rerun it with different a different configuration. This is more useful when there are multiple configurations in a single file:
# paunch debug --file examples/hello-world.yml --container hello --action dump-json > hello.json
You can then use hello.json as your --file
argument after editing it to your liking.
You can also add any configuration elements you wish on the command
line to test paunch or debug containers etc. In this example I'm running
the hello container with net=host.
# paunch debug --file examples/hello-world.yml --overrides '{"net": "host"}' --container hello --action run
Configuration Format
The current format is loosely based on a subset of the docker-compose v1 format with modifications. The intention is for the format to evolve to faithfully implement existing formats such as the Kubernetes Pod format.
The top-level of the YAML format is a dict where the keys (generally)
correspond to the name of the container to be created. The following
config creates 2 containers called hello1 and
hello2:
hello1:
image: hello-world
hello2:
image: hello-world
The values are a dict which specifies the arguments that are used when the container is launched. Supported keys which comply with the docker-compose v1 format are as follows:
- command:
-
String or list. Overrides the default command.
- detach:
-
Boolean, defaults to true. If true the container is run in the background. If false then paunch will block until the container has exited.
- environment:
-
List of the format ['KEY1=value1', 'KEY2=value2']. Sets environment variables that are available to the process launched in the container.
- env_file:
-
List of file paths containing line delimited environment variables.
- image:
-
String, mandatory. Specify the image to start the container from. Can either be a repositorys/tag or a partial image ID.
- net:
-
String. Set the network mode for the container.
- pid:
-
String. Set the PID mode for the container.
- uts:
-
String. Set the UTS namespace for the container.
- privileged:
-
Boolean, defaults to false. If true, give extended privileges to this container.
- restart:
-
String. Restart policy to apply when a container exits.
- remove:
-
Boolean: Remove container after running.
- interactive:
-
Boolean: Run container in interactive mode.
- tty:
-
Boolean: Allocate a tty to interact with the container.
- user:
-
String. Sets the username or UID used and optionally the groupname or GID for the specified command.
- volumes:
-
List of strings. Specify the bind mount for this container.
- volumes_from:
-
List of strings. Mount volumes from the specified container(s).
- log_tag:
-
String. Set the log tag for the specified container.