Skip to content

Commit

Permalink
Fix container mac generation and remove extra tasks
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
cloudnull committed Oct 29, 2017
1 parent 52284e7 commit 82c1dfa
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 92 deletions.
125 changes: 43 additions & 82 deletions tasks/lxc_container_config.yml
Expand Up @@ -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({}) }}"
Expand All @@ -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"
Expand Down
13 changes: 3 additions & 10 deletions tasks/main.yml
Expand Up @@ -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

Expand Down Expand Up @@ -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

0 comments on commit 82c1dfa

Please sign in to comment.