From e311cb657ee15495cb771c9f70d804c5cb08ec55 Mon Sep 17 00:00:00 2001 From: Nolan Brubaker Date: Tue, 2 May 2017 15:08:20 -0400 Subject: [PATCH] Write MAC addresses to local facts folder This change allows for caching of the MAC addresses between runs by using local facts on the physical host. This saves calculation time after the first run, since the facts are effectively cached. This also means any containers that rely on having stable MAC addresses (such as neutron agents or rabbitmq) can be recreated with the same MAC address if the container is destroyed. It will *not* be retained if destroyed and removed from inventory, however, since the facts rely on using the exact same hostname. Change-Id: Id3d13299c1416cc4862437629b32f4309c2dc595 --- .../save-mac-addresses-8b1e6e6301d99a37.yaml | 7 +++ tasks/container_create.yml | 54 ++++++++++++++++++- tasks/main.yml | 8 +++ templates/macs.fact.j2 | 4 ++ 4 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 releasenotes/notes/save-mac-addresses-8b1e6e6301d99a37.yaml create mode 100644 templates/macs.fact.j2 diff --git a/releasenotes/notes/save-mac-addresses-8b1e6e6301d99a37.yaml b/releasenotes/notes/save-mac-addresses-8b1e6e6301d99a37.yaml new file mode 100644 index 0000000..7c70f8f --- /dev/null +++ b/releasenotes/notes/save-mac-addresses-8b1e6e6301d99a37.yaml @@ -0,0 +1,7 @@ +--- +features: + - MAC addresses for containers with a fixed MAC (`lxc_container_fixed_mac` + variable) are now saved to the ``/etc/ansible/facts.d/mac.fact`` file. + Should such a container be destroyed but not removed from inventory, + the interfaces will be recreated with the same MAC address when the + container is recreated. diff --git a/tasks/container_create.yml b/tasks/container_create.yml index 211af68..126f73a 100644 --- a/tasks/container_create.yml +++ b/tasks/container_create.yml @@ -13,6 +13,13 @@ # See the License for the specific language governing permissions and # limitations under the License. +- name: Read custom facts from previous runs + setup: + filter: ansible_local + delegate_to: "{{ physical_host }}" + tags: + - always + - name: Check for lxc volume group shell: "(which vgs > /dev/null && vgs | grep -o '{{ lxc_container_vg_name }}') || false" register: vg_result @@ -199,7 +206,7 @@ # 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 +- name: Set unique interface mac address (when no facts exist) environment: hexchars: "0123456789abcdef" shell: | @@ -215,9 +222,30 @@ 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']) tags: - lxc_container_create-networks +# 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'] + tags: + - lxc_container_create-networks + - name: Gather hardware addresses to be used as facts command: cat /var/lib/lxc/{{ inventory_hostname }}/{{ item.value.interface }}.hwaddr changed_when: false @@ -239,6 +267,30 @@ tags: - lxc_container_create-networks +# 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 }}" + tags: + - lxc_container_create-networks + +# 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" diff --git a/tasks/main.yml b/tasks/main.yml index a04152e..29a3be7 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -13,6 +13,14 @@ # See the License for the specific language governing permissions and # limitations under the License. +- name: Allow the usage of local facts + file: + path: /etc/ansible/facts.d/ + state: directory + delegate_to: "{{ physical_host }}" + tags: + - lxc_container_create-install + - name: Ansible version and LXC backing store check fail: msg: "Using overlayfs is not supported when using Ansible version < 2" diff --git a/templates/macs.fact.j2 b/templates/macs.fact.j2 new file mode 100644 index 0000000..bbd49d3 --- /dev/null +++ b/templates/macs.fact.j2 @@ -0,0 +1,4 @@ +[{{ inventory_hostname }}] +{% for mac in macs.results %} +{{ mac.item.value.interface }} = {{ mac.stdout }} +{% endfor %}