Skip to content

Commit 3a33494

Browse files
authored
Merge pull request #538 from stackhpc/hotfix-containers-playbook
Add playbooks to allow hotfixing containers
2 parents 91fda15 + 40cab15 commit 3a33494

File tree

5 files changed

+169
-0
lines changed

5 files changed

+169
-0
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
===============
2+
Hotfix Playbook
3+
===============
4+
5+
Using the Container Hotfix Playbook
6+
===================================
7+
8+
The StackHPC Kayobe configuration contains a playbook called
9+
``hotfix-containers.yml`` which can be used to execute commands on, and copy
10+
files into, a given set of containers.
11+
12+
This playbook will first copy across any hotfix files, and then run the
13+
hotfix command. If either of these are not specified, the corresponding step
14+
will be skipped.
15+
16+
This playbook is designed for use in high-severity hotfixes ONLY and should not
17+
be used for regular operations.
18+
19+
The playbook can be invoked with:
20+
21+
.. code-block:: console
22+
23+
kayobe playbook run ${KAYOBE_CONFIG_PATH}/ansible/hotfix-containers.yml
24+
25+
Playbook variables:
26+
-------------------
27+
28+
* ``container_hotfix_command``: A command to run on each of the target
29+
containers. Default is an empty string.
30+
31+
* ``container_hotfix_files``: A list of files to copy into each target
32+
container. Consists of a list of dicts with keys ``src`` and ``dest``
33+
(required), and ``mode`` (optional - default 400). Default is an empty list.
34+
35+
* ``container_hotfix_container_regex``: Regex to match container names against.
36+
Must match the entire name e.g. "nova" or "nova*" will result in only
37+
matching a single container called "nova". To properly match every container
38+
starting with "nova", the regex must be "nova.*" Default is an empty string.
39+
40+
* ``container_hotfix_restart_containers``: Whether to restart containers after
41+
applying the hotfix. Default is False.
42+
43+
* ``container_hotfix_become``: Create files and exec as root in the target
44+
containers. Default is False.
45+
46+
47+
It is strongly recommended that you write your container_hotfix_* variables
48+
to a file, then add them as an extra var. e.g:
49+
50+
.. code-block:: console
51+
52+
kayobe playbook run ${KAYOBE_CONFIG_PATH}/ansible/hotfix-containers.yml -e "@~/vars.yml"
53+
54+
55+
Example Variables file
56+
----------------------
57+
58+
.. code-block:: yaml
59+
60+
---
61+
container_hotfix_command: "/tmp/quick-fix.sh"
62+
container_hotfix_files:
63+
- src: "~/quick-fix.sh"
64+
dest: "/tmp/quick-fix.sh"
65+
mode: "700"
66+
- src: "/home/stackhpc/new_nova_conf.conf"
67+
dest: "/etc/nova/nova.conf"
68+
container_hotfix_container_regex: "nova.*"
69+
container_hotfix_restart_containers: True
70+
container_hotfix_become: True

doc/source/operations/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ This guide is for operators of the StackHPC Kayobe configuration project.
99

1010
rabbitmq
1111
octavia
12+
hotfix-playbook
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
---
2+
# NOTE: This playbook is designed for use in high-severity hotfixes ONLY.
3+
# If you're considering using this for regular operations, please consider
4+
# developing a more suitable solution instead.
5+
#
6+
# See https://stackhpc-kayobe-config.readthedocs.io/en/stackhpc-yoga/operations/hotfix-containers.html
7+
# for more information.
8+
9+
- name: Hotfix containers
10+
hosts: overcloud
11+
tags:
12+
- hotfix-containers
13+
vars:
14+
container_hotfix_command: ""
15+
container_hotfix_files: []
16+
container_hotfix_container_regex: ""
17+
container_hotfix_restart_containers: False
18+
container_hotfix_become: False
19+
tasks:
20+
- name: Ensure inputs are valid
21+
fail:
22+
msg: "Invalid input. Container list cannot be empty. Either container_hotfix_command or container_hotfix_files must be populated."
23+
when:
24+
- container_hotfix_container_regex == "" or
25+
container_hotfix_command == "" and container_hotfix_files == []
26+
27+
- name: Get list of containers to hotfix
28+
command: '{{ kolla_container_engine | default("docker")}} ps --format {% raw %}"{{.Names}}"{% endraw %}'
29+
register: host_containers
30+
31+
- name: Set fact for containers list
32+
set_fact:
33+
containers_list: host_containers.stdout
34+
35+
- name: Fail if no containers match given regex
36+
vars:
37+
hotfix_containers: "{{ containers_list | split('\n') | regex_search(container_hotfix_container_regex) }}"
38+
fail:
39+
msg: "No containers matched. Please check your regex. Containers running on host: {{ host_containers | split('\n') }}"
40+
when: hotfix_containers == ""
41+
42+
- name: Ensure hotfix-files directory exists on the remote host
43+
ansible.builtin.file:
44+
path: /tmp/hotfix-files
45+
state: directory
46+
47+
- name: Ensure container hotfix file(s) exist on host
48+
ansible.builtin.copy:
49+
src: "{{ item.src }}"
50+
dest: "/tmp/hotfix-files/{{ index }}"
51+
loop: "{{ container_hotfix_files }}"
52+
loop_control:
53+
index_var: index
54+
when: container_hotfix_files != []
55+
56+
- name: Apply hotfix
57+
include_tasks: run-container-hotfix.yml
58+
loop: "{{ containers_list | regex_findall(container_hotfix_container_regex, multiline=True) | list | unique }}"
59+
loop_control:
60+
loop_var: hotfix_container
61+
62+
- name: Cleanup temporary files
63+
ansible.builtin.file:
64+
path: /tmp/hotfix-files
65+
state: absent
66+
67+
- name: Restart containers if requested
68+
command: "{{ kolla_container_engine | default('docker')}} restart {{ item }}"
69+
loop: "{{ containers_list | regex_findall(container_hotfix_container_regex, multiline=True) | list | unique }}"
70+
when: container_hotfix_restart_containers
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
- block:
3+
- name: Ensure any required directories exist in container(s)
4+
command: "{{ kolla_container_engine | default('docker') }} exec {{ '-u 0' if container_hotfix_become else '' }} {{ hotfix_container }} mkdir -p {{ item.dest | dirname }}"
5+
loop: "{{ container_hotfix_files }}"
6+
7+
- name: Copy file into container(s)
8+
command: "{{ kolla_container_engine | default('docker') }} cp /tmp/hotfix-files/{{ index }} {{ hotfix_container }}:{{ item.dest }}"
9+
loop: "{{ container_hotfix_files }}"
10+
loop_control:
11+
index_var: index
12+
13+
- name: Set mode for copied files
14+
command: "{{ kolla_container_engine | default('docker') }} exec {{ '-u 0' if container_hotfix_become else '' }} {{ hotfix_container }} chmod {{ item.mode | default('400') }} {{ item.dest }}"
15+
loop: "{{ container_hotfix_files }}"
16+
loop_control:
17+
index_var: index
18+
19+
when: container_hotfix_files != []
20+
21+
- name: Run container_hotfix_command
22+
command: "{{ kolla_container_engine | default('docker')}} exec {{ '-u 0' if container_hotfix_become else '' }} {{ hotfix_container }} {{ container_hotfix_command }}"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
features:
3+
- |
4+
The playbook ``hotfix-containers.yml`` has been added. This allows
5+
arbitrary files to be copied into, and/or arbitrary commands to be executed
6+
within, overcloud containers.

0 commit comments

Comments
 (0)