Fix container mac generation and remove extra tasks

The container create role will fail when adding a new network
to an existing set of container. The role attempts to read the hwaddr
file prior to its existence due to our use of local_facts. This change
simplifies how the mac addresses are generated by using a block / rescue
which will simply consume the known mac address from the container when
needed or fall back to the generation tasks as needed.

While working on this issue I noticed that we were still using a
pre-Ansible 2.0 failure notice which is no longer relevant as we've been
using Ansible 2.x for quite a while now. The old assertion has been
removed.

A new assertion has been added to notify the deployer that the
physical_host variable must be set to use this role.

Change-Id: Ic2800f1c17d10180e4e9a7be7f9b435ff8cc5487
Signed-off-by: Kevin Carter <kevin.carter@rackspace.com>
This commit is contained in:
Kevin Carter 2017-10-28 02:21:32 -05:00 committed by Kevin Carter (cloudnull)
parent 52284e75d5
commit 82c1dfa68f
2 changed files with 46 additions and 92 deletions

View File

@ -48,69 +48,52 @@
notify:
- Lxc container restart
# NOTE(cloudnull): Should a container already be up and running with a defined container interface
# the shell command will use the MAC address already set within the container as
# it's value. This allows the tasks to remain idempotent while ensuring that a
# container restart isn't required to set a static mac.
- name: Set define static mac address from an existing interface
shell: |
if lxc-attach -n {{ inventory_hostname }} -- cat /sys/class/net/{{ item.value.interface }}/address; then
lxc-attach -n {{ inventory_hostname }} -- cat /sys/class/net/{{ item.value.interface }}/address > /var/lib/lxc/{{ inventory_hostname }}/{{ item.value.interface }}.hwaddr
fi
args:
executable: /bin/bash
creates: "/var/lib/lxc/{{ inventory_hostname }}/{{ item.value.interface }}.hwaddr"
with_dict: "{{ container_networks | default({}) }}"
delegate_to: "{{ physical_host }}"
failed_when: false
- name: Network mac address block
block:
# NOTE(cloudnull): Should a container already be up and running with a defined container interface
# the shell command will use the MAC address already set within the container as
# it's value. This allows the tasks to remain idempotent while ensuring that a
# container restart isn't required to set a static mac.
- name: Set define static mac address from an existing interface
shell: |
C_PID="$(lxc-info --name {{ inventory_hostname }} --pid | awk '/PID:/ {print $2}')"
C_ADDR="/proc/${C_PID}/root/sys/class/net/{{ item.value.interface }}/address"
cat ${C_ADDR} > /var/lib/lxc/{{ inventory_hostname }}/{{ item.value.interface }}.hwaddr
args:
executable: /bin/bash
creates: "/var/lib/lxc/{{ inventory_hostname }}/{{ item.value.interface }}.hwaddr"
with_dict: "{{ container_networks | default({}) }}"
delegate_to: "{{ physical_host }}"
tags:
- skip_ansible_lint
rescue:
# NOTE(cloudnull): This task is being done to allow a container to have a static mac address.
# before this task a container had a dynamic mac address which would
# change when a container was restarted. This restart process causes terrible
# issues in several network intensive systems (RabbitMQ, Neutron, etc). To
# resolve the rotating mac address issue this task is setting the mac in a hwaddr
# file and a lookup is being used in the container-interface.ini template to render
# the static hardware address as expected.
- name: Set unique interface mac address (when no facts exist)
shell: |
echo "00:16:3e$(
for i in {1..6}; do
echo -n ${0123456789abcdef:$(( $RANDOM % 16 )):1}
done | sed -e 's/\(..\)/:\1/g'
)" > /var/lib/lxc/{{ inventory_hostname }}/{{ item.value.interface }}.hwaddr
args:
executable: /bin/bash
creates: "/var/lib/lxc/{{ inventory_hostname }}/{{ item.value.interface }}.hwaddr"
with_dict: "{{ container_networks | default({}) }}"
delegate_to: "{{ physical_host }}"
tags:
- skip_ansible_lint
when:
- lxc_container_fixed_mac | bool
# NOTE(cloudnull): This task is being done to allow a container to have a static mac address.
# before this task a container had a dynamic mac address which would
# change when a container was restarted. This restart process causes terrible
# issues in several network intensive systems (RabbitMQ, Neutron, etc). To
# resolve the rotating mac address issue this task is setting the mac in a hwaddr
# file and a lookup is being used in the container-interface.ini template to render
# the static hardware address as expected.
- name: Set unique interface mac address (when no facts exist)
environment:
hexchars: "0123456789abcdef"
shell: |
echo "00:16:3e$(
for i in {1..6}; do
echo -n ${hexchars:$(( $RANDOM % 16 )):1}
done | sed -e 's/\(..\)/:\1/g'
)" > /var/lib/lxc/{{ inventory_hostname }}/{{ item.value.interface }}.hwaddr
args:
executable: /bin/bash
creates: "/var/lib/lxc/{{ inventory_hostname }}/{{ item.value.interface }}.hwaddr"
with_dict: "{{ container_networks | default({}) }}"
delegate_to: "{{ physical_host }}"
when:
- lxc_container_fixed_mac | bool
- (ansible_local is not defined or
'mac' not in ansible_local or
inventory_hostname not in ansible_local['mac'])
# NOTE(palendae): If we have saved MACs, write those out instead of generating new ones.
# Parentheses on the mac in ansible_local check to make the YAML parser happy.
- name: Reuse saved interface mac address from host facts
shell: |
echo {{ item.value }} > /var/lib/lxc/{{ inventory_hostname }}/{{ item.key }}.hwaddr
args:
executable: /bin/bash
creates: "/var/lib/lxc/{{ inventory_hostname }}/{{ item.key }}.hwaddr"
with_dict: "{{ ansible_local['mac'][inventory_hostname] | default({}) }}"
delegate_to: "{{ physical_host }}"
when:
- lxc_container_fixed_mac | bool
- ansible_local is defined
- ('mac' in ansible_local)
- inventory_hostname in ansible_local['mac']
- name: Gather hardware addresses to be used as facts
command: cat /var/lib/lxc/{{ inventory_hostname }}/{{ item.value.interface }}.hwaddr
slurp:
src: "/var/lib/lxc/{{ inventory_hostname }}/{{ item.value.interface }}.hwaddr"
changed_when: false
register: macs
with_dict: "{{ container_networks | default({}) }}"
@ -120,34 +103,12 @@
# NOTE(cloudnull): To dynamically set the the mac address "facts" Ansible line format is being used
- name: Set fixed hardware address fact
set_fact: "{{item.item.value.interface }}_mac_address={{ item.stdout }}"
set_fact: "{{item.item.value.interface }}_mac_address={{ item.content | b64decode }}"
with_items:
- "{{ macs.results }}"
when:
- lxc_container_fixed_mac | bool
# NOTE(palendae): If a unique identifier (like the hostname) is not provided as the marker, only one block will be written.
# Each host will be written once, and whichever one came last will be the only one in the file.
- name: Ensure MAC address fact cache is up-to-date
blockinfile:
dest: /etc/ansible/facts.d/mac.fact
marker: "# {mark} Managed by OpenStack-Ansible {{ inventory_hostname }}"
block: "{{ lookup('template', 'macs.fact.j2') }}"
create: yes
when:
- lxc_container_fixed_mac | bool
delegate_to: "{{ physical_host }}"
# NOTE(palendae): This is necessary to read any local facts in to the 'ansible_local' dict.
- name: Read local facts in for use
setup:
filter: ansible_local
when:
- lxc_container_fixed_mac | bool
delegate_to: "{{ physical_host }}"
tags:
- always
- name: LXC host config for container networks
template:
src: "container-interface.ini.j2"

View File

@ -21,12 +21,11 @@
tags:
- always
- name: Ansible version and LXC backing store check
- name: Check the physical_host variable is set
fail:
msg: "Using overlayfs is not supported when using Ansible version < 2"
msg: "The physical_host variable is not defined."
when:
- lxc_container_backing_store == "overlayfs"
- ansible_version.major < 2
- physical_host is undefined
tags:
- always
@ -81,23 +80,17 @@
- include: lxc_container_destroy.yml
when:
- physical_host is defined
- inventory_hostname is defined
- physical_host != inventory_hostname
- lxc_container_recreate | bool
- include: lxc_container_create.yml
when:
- physical_host is defined
- inventory_hostname is defined
- physical_host != inventory_hostname
tags:
- lxc-create
- include: lxc_container_config.yml
when:
- physical_host is defined
- inventory_hostname is defined
- physical_host != inventory_hostname
tags:
- lxc-config