--- # Copyright 2017, Rackspace US, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - name: Check for aa-profile stat: path: /etc/apparmor.d/usr.sbin.dnsmasq register: aa_profile - name: Set dnsmasq aa profile to complain command: "aa-complain /etc/apparmor.d/usr.sbin.dnsmasq" when: - aa_profile.stat.exists | bool - name: Add proxies when needed block: - name: Create machined proxy override unit directories file: path: "/etc/systemd/system/{{ item }}" owner: root group: root mode: '0755' state: directory with_items: - systemd-machined.service.d - systemd-importd.service.d - name: Drop the machined proxy override units template: src: systemd-proxy-unit.conf.j2 dest: /etc/systemd/system/{{ item }}/proxy.conf owner: root group: root mode: '0644' with_items: - systemd-machined.service.d - systemd-importd.service.d when: - (deployment_environment_variables | default({})).keys() | length > 0 - name: Load override systemd-nspawn@ template: src: systemd-nspawn@.service.j2 dest: /etc/systemd/system/systemd-nspawn@.service notify: - Reload systemd-daemon - name: Run the systemd service role include_role: name: systemd_service private: true vars: systemd_user_name: "root" systemd_group_name: "root" systemd_tempd_prefix: machine systemd_slice_name: machine systemd_lock_path: /var/lock/machine systemd_services: - service_name: "nspawn-macvlan" program_sandboxing: PrivateTmp: True PrivateDevices: True config_overrides: Unit: After: network-online.target Before: systemd-networkd.service PartOf: systemd-networkd.service Description: nspawn host macvlan integrations Wants: network-online.target Service: RemainAfterExit: yes service_type: oneshot execstarts: |- {%- set start_commands = [] %} {%- set seen_start_interfaces = [] %} {%- for key, value in nspawn_combined_networks.items() %} {%- if value.interface is defined %} {%- set interface = value.interface %} {%- set mv_interface = value.interface %} {%- else %} {%- set interface = value.bridge.split('br-')[-1] %} {%- set mv_interface = 'mv-' + interface %} {%- endif %} {%- if value.bridge not in seen_start_interfaces %} {%- if value.private_device | default(false) | bool %} {%- set _ = start_commands.append('-/sbin/ip link add dev ' + value.bridge + ' type dummy') %} {%- set _ = start_commands.append('-/sbin/ip link set dev ' + value.bridge + ' up') %} {%- endif %} {%- set interface_from_ansible = 'ansible_' + value.bridge | replace('-', '_') %} {%- set interface_data = hostvars[inventory_hostname][interface_from_ansible] | default({'type': none}) %} {%- if interface_data['type'] == 'bridge' %} {%- set _ = start_commands.append('-/sbin/ip link add dev veth-' + interface + '1 type veth peer name veth-' + interface + '2') %} {%- set _ = start_commands.append('-/sbin/ip link set dev veth-' + interface + '1 up') %} {%- set _ = start_commands.append('-/sbin/ip link set dev veth-' + interface + '1 mtu ' ~ (interface_data["mtu"] | default(1500))) %} {%- set _ = start_commands.append('-/sbin/ip link set dev veth-' + interface + '2 up') %} {%- set _ = start_commands.append('-/sbin/ip link set dev veth-' + interface + '2 mtu ' ~ (interface_data["mtu"] | default(1500))) %} {%- set _ = start_commands.append('-/sbin/ip link set dev veth-' + interface + '1 master ' + value.bridge) %} {%- set _ = start_commands.append('-/sbin/ip link add ' + mv_interface + ' link veth-' + interface + '2 mtu ' ~ (interface_data["mtu"] | default(1500)) ~ ' type macvlan mode ' + value.macvlan_mode | default(nspawn_macvlan_mode)) %} {%- set _ = start_commands.append('-/sbin/ip link set dev ' + mv_interface + ' up') %} {%- else %} {%- set _ = start_commands.append('-/sbin/ip link add ' + mv_interface + ' link ' + value.bridge + ' mtu ' ~ (interface_data["mtu"] | default(1500)) ~ ' type macvlan mode ' + value.macvlan_mode | default(nspawn_macvlan_mode)) %} {%- set _ = start_commands.append('-/sbin/ip link set dev ' + mv_interface + ' up') %} {% if hostvars[inventory_hostname][key.split('_')[0] + '_cidr'] is defined and (value.address is undefined) %} {% set net_cidr = hostvars[inventory_hostname][key.split('_')[0] + '_cidr'] %} {% set _ = start_commands.append('-/sbin/ip route add ' ~ net_cidr ~ ' dev ' ~ (value.routed_interface | default(nspawn_primary_interface)) ~ ' metric 100 proto kernel scope link table local') %} {% elif (value.address is defined) and ((interface_data['ipv4'] | default({'address': none}))['address'] != value.address) and ((value.host_only | default(false)) | bool) %} {% set net_cidr = (value.address ~ '/' ~ (value.netmask | default('32'))) %} {% set _ = start_commands.append('-/sbin/ip address add ' ~ net_cidr ~ ' dev ' ~ mv_interface ~ ' scope host noprefixroute') %} {% set _ = start_commands.append('-/sbin/ip route add ' ~ (net_cidr | ipaddr('network')) ~ '/' ~ (value.netmask | default('32')) ~ ' dev ' ~ mv_interface ~ ' metric 100 proto kernel scope link table local') %} {%- endif %} {%- endif %} {%- endif %} {%- endfor %} {{ start_commands }} enabled: yes state: started tags: - network-config - systemd-networkd - name: Run the systemd-networkd role include_role: name: systemd_networkd private: true vars: systemd_networkd_prefix: "nspawn_host" systemd_run_networkd: true systemd_interface_cleanup: true systemd_netdevs: |- {% set seen_netdevs = [] %} {% set _netdevs = [] %} {% for _, value in (nspawn_networks | combine(container_extra_networks)).items() %} {% set netname = value.interface | default('mv-' + value.bridge.split('br-')[-1]) %} {% set _netdev = {'NetDev': {'Name': netname, 'Kind': 'macvlan'}, 'MACVLAN': {'Mode': 'bridge'}} %} {% if netname not in seen_netdevs %} {% set _ = _netdevs.append(_netdev) %} {% set _ = seen_netdevs.append(netname) %} {% endif %} {% endfor %} {{ _netdevs | sort(attribute='NetDev.Name') }} systemd_networks: |- {% set seen_networks = [] %} {% set _networks = [] %} {# All nspawn_networks and container_extra_networks will be iterated over. #} {# If a device is found, a networkd config will be generated for it. #} {% for _, value in (nspawn_networks | combine(container_extra_networks)).items() %} {% set netname = value.interface | default('mv-' + value.bridge.split('br-')[-1]) %} {% set _network = {'interface': netname} %} {% if (not (value.host_only | default(false)) | bool) %} {% if netname not in seen_networks %} {% set _ = seen_networks.append(netname) %} {% if value.address is defined %} {% set _ = _network.__setitem__('address', value.address) %} {% if (value.netmask is defined) and (_network.address != 'dhcp') %} {% set _ = _network.__setitem__('netmask', value.netmask) %} {% set prefix = (value.address + '/' + value.netmask) | ipaddr('prefix') %} {% set _ = _network.__setitem__('address', [value.address + '/' + prefix | string]) %} {% endif %} {% endif %} {% set _ = _network.__setitem__('usedns', (value.usedns | default(true) | bool) | ternary('yes', 'no')) %} {% set _ = _network.__setitem__('static_routes', value.static_routes | default([])) %} {% if value.gateway is defined %} {% set _ = _network.__setitem__('gateway', value.gateway) %} {% endif %} {% set _ = _network.__setitem__('mtu', value.mtu | default(1500 | string)) %} {% set _ = _network.__setitem__('config_overrides', {'Network': {'IPForward': 'yes', 'IPMasquerade': 'yes'}, 'Link': {'ARP': 'yes'}}) %} {% set _ = _networks.append(_network) %} {% endif %} {% endif %} {% endfor %} {{ _networks | sort(attribute='interface') }} tags: - network-config - systemd-networkd - name: Create dnsmasq config(s) template: src: "dnsmasq-config.conf.j2" dest: "/etc/dnsmasq.d/dnsmasq-{{ 'mv-' + item.value.bridge.split('br-')[-1] }}.conf" with_dict: "{{ nspawn_combined_networks }}" when: - item.value.enable_dhcp | default(false) | bool notify: - Enable network dnsmasq service - name: Run the systemd service role include_role: name: systemd_service private: true vars: systemd_user_name: "root" systemd_group_name: "root" systemd_tempd_prefix: machine systemd_slice_name: machine systemd_lock_path: /var/lock/machine systemd_CPUAccounting: true systemd_BlockIOAccounting: true systemd_MemoryAccounting: true systemd_TasksAccounting: true systemd_services: - service_name: "dnsmasq-{{ 'mv-' + dnsmasq_var.value.bridge.split('br-')[-1] }}" program_sandboxing: PrivateTmp: True PrivateDevices: True config_overrides: Unit: Description: networking-post-up After: ? network-online.target ? systemd-networkd.service ? nspawn-macvlan.service PartOf: systemd-networkd.service Wants: network-online.target Service: RemainAfterExit: yes ExecStartPre: "-{{ nspawn_network_utils[ansible_pkg_mgr]['iptables'] }} -t nat -A POSTROUTING -s {{ dnsmasq_var.value.address }}/{{ (dnsmasq_var.value.address | string + '/' + dnsmasq_var.value.netmask | string) | ipaddr('prefix') }} ! -d {{ dnsmasq_var.value.address }}/{{ (dnsmasq_var.value.address | string + '/' + dnsmasq_var.value.netmask | string) | ipaddr('prefix') }} -j MASQUERADE" ExecStopPost: "-{{ nspawn_network_utils[ansible_pkg_mgr]['iptables'] }} -t nat -D POSTROUTING -s {{ dnsmasq_var.value.address }}/{{ (dnsmasq_var.value.address | string + '/' + dnsmasq_var.value.netmask | string) | ipaddr('prefix') }} ! -d {{ dnsmasq_var.value.address }}/{{ (dnsmasq_var.value.address | string + '/' + dnsmasq_var.value.netmask | string) | ipaddr('prefix') }} -j MASQUERADE" PIDFile: /run/run/nspawn-{{ dnsmasq_var.value.bridge }}-dnsmasq.pid execstarts: - "/usr/sbin/dnsmasq --keep-in-foreground --conf-file=/etc/dnsmasq.d/dnsmasq-{{ 'mv-' + dnsmasq_var.value.bridge.split('br-')[-1] }}.conf" execstops: - "-/usr/bin/killall -u systemd-network --regexp ^dnsmasq" enabled: yes state: started when: - dnsmasq_var.value.enable_dhcp | default(false) | bool - dnsmasq_var.value.address is defined - dnsmasq_var.value.netmask is defined with_dict: "{{ nspawn_combined_networks }}" loop_control: loop_var: dnsmasq_var tags: - network-config - systemd-service