Bring in aarch64 support in apex 63/63063/31
authorCharalampos Kominos <Charalampos.Kominos@enea.com>
Mon, 1 Oct 2018 11:12:46 +0000 (13:12 +0200)
committerCharalampos Kominos <charalampos.kominos@enea.com>
Sun, 18 Nov 2018 15:18:08 +0000 (16:18 +0100)
RDO builds packages which are aarch64 compatible but some configuration
is needed to succesfully deploy.
This change:

- Prepares the aarch64 docker.io repo as the source for Kolla Containers
- Configures VM sizing for aarch64 undercloud.
- Configures VM sizing for aarch64 virtual deploy targets.
  Vms need to be larger on aarch64 compared to x86 to avoid
  starvation of resources. (MYSQL)
- Configures vda2 as the location of the Linux Kernel in aarch64 in
  an UEFI system
- Configures the vNICs to be on the pci-bus instead of the virtio-mmio
  bus.This will enalbe the Nics to come up in the same order as the
  x86 ones,  so the extra configuration in ansible is not needed
- Configures apex to use a stable version of the ceph:daemon container
- Configure apex for containerized undercloud in Rocky
- Add extra ansible.cfg file for aarch64 which increases waiting
  times in ansible for aarch64
- Provide helper scripts for DIB to create aarch64 UEFI images

Known limitations:

- Selinux is interfering with DHCP requests in ironic and ssh
  so it must be disabled before the deploy command is ran.
- The aarch64 containers are frozen for in this commit:
  https://trunk.rdoproject.org/centos7-rocky/f3/18/f3180de6439333a2813119ad4b00ef897fcd596f_70883030
- The 600s timeout defined in :
  https://bugs.launchpad.net/tripleo/+bug/1789680  is not enough for
  aarch64. A value of 1200s is recommended

JIRA: APEX-619

Change-Id: Ia3f067821e12bba44939bbf8c0e4676f2da70239
Signed-off-by: Charalampos Kominos <Charalampos.Kominos@enea.com>
Signed-off-by: ting wu <ting.wu@enea.com>
13 files changed:
apex/builders/common_builder.py
apex/common/constants.py
apex/deploy.py
apex/overcloud/deploy.py
apex/tests/test_apex_common_builder.py
apex/undercloud/undercloud.py
apex/virtual/configure_vm.py
build/ansible.cfg [new file with mode: 0644]
contrib/aarch64/overcloud-full-rootfs.yaml [new file with mode: 0644]
contrib/aarch64/undercloud-full.yaml [new file with mode: 0644]
lib/ansible/playbooks/configure_undercloud.yml
lib/ansible/playbooks/deploy_overcloud.yml
lib/ansible/playbooks/undercloud_aarch64.yml

index 2934a1d..7627ae3 100644 (file)
@@ -59,7 +59,7 @@ def project_to_path(project, patch=None):
         return "/usr/lib/python2.7/site-packages/"
 
 
-def project_to_docker_image(project):
+def project_to_docker_image(project, docker_url):
     """
     Translates OpenStack project to OOO services that are containerized
     :param project: name of OpenStack project
@@ -69,7 +69,8 @@ def project_to_docker_image(project):
     # based on project
 
     hub_output = utils.open_webpage(
-        urllib.parse.urljoin(con.DOCKERHUB_OOO, '?page_size=1024'), timeout=10)
+        urllib.parse.urljoin(docker_url,
+                             '?page_size=1024'), timeout=10)
     try:
         results = json.loads(hub_output.decode())['results']
     except Exception as e:
@@ -89,7 +90,7 @@ def project_to_docker_image(project):
     return docker_images
 
 
-def is_patch_promoted(change, branch, docker_image=None):
+def is_patch_promoted(change, branch, docker_url, docker_image=None):
     """
     Checks to see if a patch that is in merged exists in either the docker
     container or the promoted tripleo images
@@ -122,8 +123,8 @@ def is_patch_promoted(change, branch, docker_image=None):
             return True
     else:
         # must be a docker patch, check docker tag modified time
-        docker_url = con.DOCKERHUB_OOO.replace('tripleomaster',
-                                               "tripleo{}".format(branch))
+        docker_url = docker_url.replace('tripleomaster',
+                                        "tripleo{}".format(branch))
         url_path = "{}/tags/{}".format(docker_image, con.DOCKER_TAG)
         docker_url = urllib.parse.urljoin(docker_url, url_path)
         logging.debug("docker url is: {}".format(docker_url))
@@ -176,10 +177,15 @@ def add_upstream_patches(patches, image, tmp_dir,
         # and move the patch into the containers directory.  We also assume
         # this builder call is for overcloud, because we do not support
         # undercloud containers
+        if platform.machine() == 'aarch64':
+            docker_url = con.DOCKERHUB_AARCH64
+        else:
+            docker_url = con.DOCKERHUB_OOO
         if docker_tag and 'python' in project_path:
             # Projects map to multiple THT services, need to check which
             # are supported
-            ooo_docker_services = project_to_docker_image(patch['project'])
+            ooo_docker_services = project_to_docker_image(patch['project'],
+                                                          docker_url)
             docker_img = ooo_docker_services[0]
         else:
             ooo_docker_services = []
@@ -189,6 +195,7 @@ def add_upstream_patches(patches, image, tmp_dir,
                                         patch['change-id'])
         patch_promoted = is_patch_promoted(change,
                                            branch.replace('stable/', ''),
+                                           docker_url,
                                            docker_img)
 
         if patch_diff and not patch_promoted:
@@ -288,7 +295,8 @@ def prepare_container_images(prep_file, branch='master', neutron_driver=None):
             p_set['neutron_driver'] = neutron_driver
         p_set['namespace'] = "docker.io/tripleo{}".format(branch)
         if platform.machine() == 'aarch64':
-            p_set['ceph_tag'] = 'master-fafda7d-luminous-centos-7-aarch64'
+            p_set['namespace'] = "docker.io/armbandapex"
+            p_set['ceph_tag'] = 'v3.1.0-stable-3.1-luminous-centos-7-aarch64'
 
     except KeyError:
         logging.error("Invalid prep file format: {}".format(prep_file))
index e89e7e7..dbdf70d 100644 (file)
@@ -67,6 +67,8 @@ VALID_DOCKER_SERVICES = {
 }
 DOCKERHUB_OOO = 'https://registry.hub.docker.com/v2/repositories' \
                 '/tripleomaster/'
+DOCKERHUB_AARCH64 = 'https://registry.hub.docker.com/v2/repositories' \
+                    '/armbandapex/'
 KUBESPRAY_URL = 'https://github.com/kubernetes-incubator/kubespray.git'
 OPNFV_ARTIFACTS = 'http://storage.googleapis.com/artifacts.opnfv.org'
 CUSTOM_OVS = '{}/apex/random/openvswitch-2.9.0-9.el7fdn.x86_64.' \
index b74d529..670fb6b 100644 (file)
@@ -293,12 +293,24 @@ def main():
                                 'requires at least 12GB per controller.')
                 logging.info('Increasing RAM per controller to 12GB')
             elif args.virt_default_ram < 10:
-                control_ram = 10
-                logging.warning('RAM per controller is too low.  nosdn '
-                                'requires at least 10GB per controller.')
-                logging.info('Increasing RAM per controller to 10GB')
+                if platform.machine() == 'aarch64':
+                    control_ram = 16
+                    logging.warning('RAM per controller is too low for '
+                                    'aarch64 ')
+                    logging.info('Increasing RAM per controller to 16GB')
+                else:
+                    control_ram = 10
+                    logging.warning('RAM per controller is too low.  nosdn '
+                                    'requires at least 10GB per controller.')
+                    logging.info('Increasing RAM per controller to 10GB')
             else:
                 control_ram = args.virt_default_ram
+            if platform.machine() == 'aarch64' and args.virt_cpus < 16:
+                vcpus = 16
+                logging.warning('aarch64 requires at least 16 vCPUS per '
+                                'target VM. Increasing to 16.')
+            else:
+                vcpus = args.virt_cpus
             if ha_enabled and args.virt_compute_nodes < 2:
                 logging.debug(
                     'HA enabled, bumping number of compute nodes to 2')
@@ -307,7 +319,7 @@ def main():
                                           num_computes=args.virt_compute_nodes,
                                           controller_ram=control_ram * 1024,
                                           compute_ram=compute_ram * 1024,
-                                          vcpus=args.virt_cpus
+                                          vcpus=vcpus
                                           )
         inventory = Inventory(args.inventory_file, ha_enabled, args.virtual)
         logging.info("Inventory is:\n {}".format(pprint.pformat(
@@ -435,6 +447,12 @@ def main():
         docker_env = 'containers-prepare-parameter.yaml'
         shutil.copyfile(os.path.join(args.deploy_dir, docker_env),
                         os.path.join(APEX_TEMP_DIR, docker_env))
+        # Upload extra ansible.cfg
+        if platform.machine() == 'aarch64':
+            ansible_env = 'ansible.cfg'
+            shutil.copyfile(os.path.join(args.deploy_dir, ansible_env),
+                            os.path.join(APEX_TEMP_DIR, ansible_env))
+
         c_builder.prepare_container_images(
             os.path.join(APEX_TEMP_DIR, docker_env),
             branch=branch.replace('stable/', ''),
index c526a98..e317706 100644 (file)
@@ -245,12 +245,16 @@ def create_deploy_cmd(ds, ns, inv, tmp_dir,
     if net_data:
         cmd += ' --networks-file network_data.yaml'
     libvirt_type = 'kvm'
-    if virtual:
+    if virtual and (platform.machine() != 'aarch64'):
         with open('/sys/module/kvm_intel/parameters/nested') as f:
             nested_kvm = f.read().strip()
             if nested_kvm != 'Y':
                 libvirt_type = 'qemu'
+    elif virtual and (platform.machine() == 'aarch64'):
+        libvirt_type = 'qemu'
     cmd += ' --libvirt-type {}'.format(libvirt_type)
+    if platform.machine() == 'aarch64':
+        cmd += ' --override-ansible-cfg /home/stack/ansible.cfg '
     logging.info("Deploy command set: {}".format(cmd))
 
     with open(os.path.join(tmp_dir, 'deploy_command'), 'w') as fh:
index dc4383b..3ff95bb 100644 (file)
@@ -57,7 +57,8 @@ class TestCommonBuilder(unittest.TestCase):
         dummy_change = {'submitted': '2017-06-05 20:23:09.000000000',
                         'status': 'MERGED'}
         self.assertTrue(c_builder.is_patch_promoted(dummy_change,
-                                                    'master'))
+                                                    'master',
+                                                    con.DOCKERHUB_OOO))
 
     def test_is_patch_promoted_docker(self):
         dummy_change = {'submitted': '2017-06-05 20:23:09.000000000',
@@ -65,13 +66,15 @@ class TestCommonBuilder(unittest.TestCase):
         dummy_image = 'centos-binary-opendaylight'
         self.assertTrue(c_builder.is_patch_promoted(dummy_change,
                                                     'master',
+                                                    con.DOCKERHUB_OOO,
                                                     docker_image=dummy_image))
 
     def test_patch_not_promoted(self):
         dummy_change = {'submitted': '2900-06-05 20:23:09.000000000',
                         'status': 'MERGED'}
         self.assertFalse(c_builder.is_patch_promoted(dummy_change,
-                                                     'master'))
+                                                     'master',
+                                                     con.DOCKERHUB_OOO))
 
     def test_patch_not_promoted_docker(self):
         dummy_change = {'submitted': '2900-06-05 20:23:09.000000000',
@@ -79,13 +82,15 @@ class TestCommonBuilder(unittest.TestCase):
         dummy_image = 'centos-binary-opendaylight'
         self.assertFalse(c_builder.is_patch_promoted(dummy_change,
                                                      'master',
+                                                     con.DOCKERHUB_OOO,
                                                      docker_image=dummy_image))
 
     def test_patch_not_promoted_and_not_merged(self):
         dummy_change = {'submitted': '2900-06-05 20:23:09.000000000',
                         'status': 'BLAH'}
         self.assertFalse(c_builder.is_patch_promoted(dummy_change,
-                                                     'master'))
+                                                     'master',
+                                                     con.DOCKERHUB_OOO))
 
     @patch('builtins.open', mock_open())
     @patch('apex.builders.common_builder.is_patch_promoted')
@@ -241,7 +246,8 @@ class TestCommonBuilder(unittest.TestCase):
                          '/dummytmp/dummyrepo.tar')
 
     def test_project_to_docker_image(self):
-        found_services = c_builder.project_to_docker_image(project='nova')
+        found_services = c_builder.project_to_docker_image('nova',
+                                                           con.DOCKERHUB_OOO)
         assert 'nova-api' in found_services
 
     @patch('apex.common.utils.open_webpage')
@@ -250,7 +256,8 @@ class TestCommonBuilder(unittest.TestCase):
         mock_open_web.return_value = b'{"blah": "blah"}'
         self.assertRaises(exceptions.ApexCommonBuilderException,
                           c_builder.project_to_docker_image,
-                          'nova')
+                          'nova',
+                          con.DOCKERHUB_OOO)
 
     def test_get_neutron_driver(self):
         ds_opts = {'dataplane': 'fdio',
index feae43c..ccdcd16 100644 (file)
@@ -64,7 +64,7 @@ class Undercloud:
         if self.external_net:
             networks.append('external')
         console = 'ttyAMA0' if platform.machine() == 'aarch64' else 'ttyS0'
-        root = 'vda' if platform.machine() == 'aarch64' else 'sda'
+        root = 'vda2' if platform.machine() == 'aarch64' else 'sda'
 
         self.vm = vm_lib.create_vm(name='undercloud',
                                    image=self.volume,
@@ -112,7 +112,7 @@ class Undercloud:
             # give 10 seconds to come up
             time.sleep(10)
         # set IP
-        for x in range(5):
+        for x in range(10):
             if self._set_ip():
                 logging.info("Undercloud started.  IP Address: {}".format(
                     self.ip))
index ba0398b..9d47bf0 100755 (executable)
@@ -102,6 +102,10 @@ def create_vm(name, image, diskbus='sata', baremetal_interfaces=['admin'],
     with open(os.path.join(template_dir, 'domain.xml'), 'r') as f:
         source_template = f.read()
     imagefile = os.path.realpath(image)
+
+    if arch == 'aarch64' and diskbus == 'sata':
+        diskbus = 'virtio'
+
     memory = int(memory) * 1024
     params = {
         'name': name,
@@ -118,9 +122,6 @@ def create_vm(name, image, diskbus='sata', baremetal_interfaces=['admin'],
         'user_interface': '',
     }
 
-    # assign virtio as default for aarch64
-    if arch == 'aarch64' and diskbus == 'sata':
-        diskbus = 'virtio'
     # Configure the bus type for the target disk device
     params['diskbus'] = diskbus
     nicparams = {
@@ -171,7 +172,7 @@ def create_vm(name, image, diskbus='sata', baremetal_interfaces=['admin'],
         """
         params['user_interface'] = """
         <controller type='virtio-serial' index='0'>
-          <address type='virtio-mmio'/>
+          <address type='pci'/>
         </controller>
         <serial type='pty'>
           <target port='0'/>
diff --git a/build/ansible.cfg b/build/ansible.cfg
new file mode 100644 (file)
index 0000000..a9db58a
--- /dev/null
@@ -0,0 +1,11 @@
+[defaults]
+retry_files_enabled = False
+forks = 25
+timeout = 60
+gather_timeout = 30
+
+[ssh_connection]
+ssh_args = -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o ControlMaster=auto -o ControlPersist=30m -o ServerAliveInterval=5 -o ServerAliveCountMax=5
+retries = 8
+pipelining = True
+
diff --git a/contrib/aarch64/overcloud-full-rootfs.yaml b/contrib/aarch64/overcloud-full-rootfs.yaml
new file mode 100644 (file)
index 0000000..ad42042
--- /dev/null
@@ -0,0 +1,54 @@
+disk_images:
+  -
+    imagename: overcloud-full-rootfs
+    arch: aarch64
+    type: qcow2
+    distro: centos7
+    elements:
+      - baremetal
+      - dhcp-all-interfaces
+      - cloud-init
+      - openvswitch
+      - overcloud-agent
+      - overcloud-full
+      - overcloud-controller
+      - overcloud-compute
+      - overcloud-ceph-storage
+      - puppet-modules
+      - enable-serial-console
+      - stable-interface-names
+      - selinux-permissive
+      - grub2
+      - growroot
+      - devuser
+      - element-manifest
+      - dynamic-login
+      - iptables
+      - enable-packages-install
+      - pip-and-virtualenv-override
+      - dracut-regenerate
+      - remove-machine-id
+      - remove-resolvconf
+    packages:
+      - openstack-utils
+      - python-tripleoclient
+      - python-tripleoclient-heat-installer
+      - python-psutil
+      - python-debtcollector
+      - plotnetcfg
+      - sos
+      - yum-plugin-priorities
+      - ntp
+      - jq
+      - openstack-heat-agents
+      - device-mapper-multipath
+      - os-net-config
+      - grub2-efi-aa64
+      - grub2-efi-aa64-modules
+    options:
+      - " --no-tmpfs"
+    environment:
+      DIB_PYTHON_VERSION: '2'
+      DIB_DEV_USER_USERNAME: 'stack'
+      DIB_DEV_USER_PASSWORD: 'stack'
+      DIB_DEV_USER_PWDLESS_SUDO: 'Yes'
diff --git a/contrib/aarch64/undercloud-full.yaml b/contrib/aarch64/undercloud-full.yaml
new file mode 100644 (file)
index 0000000..42084c8
--- /dev/null
@@ -0,0 +1,87 @@
+disk_images:
+  -
+    imagename: undercloud-full
+    arch: aarch64
+    type: qcow2
+    distro: centos7
+    elements:
+      - vm
+      - block-device-efi
+      - baremetal
+      - dhcp-all-interfaces
+      - disable-selinux
+      - cloud-init-nocloud
+      - openvswitch
+      - overcloud-agent
+      - overcloud-full
+      - overcloud-controller
+      - overcloud-compute
+      - overcloud-ceph-storage
+      - puppet-modules
+      - enable-serial-console
+      - stable-interface-names
+      - grub2
+      - bootloader
+      - devuser
+      - element-manifest
+      - dynamic-login
+      - iptables
+      - enable-packages-install
+      - pip-and-virtualenv-override
+      - dracut-regenerate
+      - remove-machine-id
+      - remove-resolvconf
+    packages:
+      - openstack-utils
+      - python-tripleoclient
+      - python-tripleoclient-heat-installer
+      - python-psutil
+      - python-debtcollector
+      - plotnetcfg
+      - sos
+      - yum-plugin-priorities
+      - ntp
+      - jq
+      - openstack-heat-agents
+      - device-mapper-multipath
+      - os-net-config
+    options:
+      - " --no-tmpfs"
+    environment:
+      DIB_PYTHON_VERSION: '2'
+      DIB_DEV_USER_USERNAME: 'stack'
+      DIB_DEV_USER_PASSWORD: 'stack'
+      DIB_DEV_USER_PWDLESS_SUDO: 'Yes'
+  -
+    imagename: ironic-python-agent
+    # This is bogus, but there's no initrd type in diskimage-builder
+    arch: aarch64
+    type: qcow2
+    distro: centos7
+
+    # So we just override the extension instead
+    imageext: initramfs
+    elements:
+      - ironic-agent
+      - ironic-agent-multipath
+      - dynamic-login
+      - devuser
+      - disable-selinux
+      - element-manifest
+      - network-gateway
+      - enable-packages-install
+      - pip-and-virtualenv-override
+    packages:
+      - util-linux
+      - grub2-efi-aa64
+      - grub2-efi-aa64-module
+      - python-hardware-detect
+      - yum-plugin-priorities
+      - iscsi-initiator-utils
+    options:
+      - " --no-tmpfs"
+    environment:
+      DIB_PYTHON_VERSION: '2'
+      DIB_DEV_USER_USERNAME: 'stack'
+      DIB_DEV_USER_PASSWORD: 'stack'
+      DIB_DEV_USER_PWDLESS_SUDO: 'Yes'
index 45d18e4..80f3e67 100644 (file)
         - ironic_conductor
         - ironic_inspector
       become: yes
-    # will need to modify the below to patch the container
-    - lineinfile:
-        path: /usr/lib/python2.7/site-packages/ironic/common/pxe_utils.py
-        regexp: '_link_ip_address_pxe_configs'
-        line: '        _link_mac_pxe_configs(task)'
-      when: aarch64
     - name: configure external network vlan ifcfg
       template:
         src: external_vlan_ifcfg.yml.j2
       when:
         - external_network.vlan == "native"
         - external_network.enabled
-        - not aarch64
     - name: bring up eth2
       shell: ip link set up dev eth2
       when:
         - external_network.vlan == "native"
         - external_network.enabled
-        - not aarch64
-      become: yes
-    - name: assign IP to native eth0 if aarch64
-      shell: ip a a {{ external_network.ip }}/{{ external_network.prefix }} dev eth0
       become: yes
-      when:
-        - external_network.vlan == "native"
-        - external_network.enabled
-        - aarch64
     - name: bring up eth0 if aarch64
       shell: ip link set up dev eth0
       when:
index b8fb493..e2e84d1 100644 (file)
         - baremetal-environment.yaml
         - kubernetes-environment.yaml
         - "{{ apex_env_file }}"
+    - name: Copy ansible.cfg data to undercloud in aarch64
+      copy:
+        src: "{{ apex_temp_dir }}/ansible.cfg"
+        dest: "/home/stack/ansible.cfg"
+        owner: stack
+        group: stack
+        mode: 0644
+      when: aarch64
     - name: Copy network data to undercloud
       copy:
         src: "{{ apex_temp_dir }}/network_data.yaml"
         allow_downgrade: yes
         name: ceph-ansible-3.1.6
       become: yes
+    - name: Re-enable ceph config for aarch64
+      replace:
+        path: "/usr/share/ceph-ansible/roles/ceph-client/tasks/create_users_keys.yml"
+        regexp: "x86_64"
+        replace: "aarch64"
+        backup: yes
+      when: aarch64
     - name: Configure DNS server for ctlplane network
       shell: "{{ stackrc }} && openstack subnet set ctlplane-subnet {{ dns_server_args }}"
     - block:
index ddaf1b0..efcbdab 100644 (file)
@@ -3,13 +3,12 @@
   tasks:
     - name: aarch64 configuration
       block:
-        - shell: yum -y reinstall grub2-efi shim
         - copy:
             src: /boot/efi/EFI/centos/grubaa64.efi
-            dest: /tftpboot/grubaa64.efi
+            dest: /var/lib/config-data/puppet-generated/ironic/var/lib/ironic/tftpboot/grubaa64.efi
             remote_src: yes
         - file:
-            path: /tftpboot/EFI/centos
+            path: /var/lib/config-data/puppet-generated/ironic/var/lib/ironic/tftpboot/EFI/centos
             state: directory
             mode: 0755
         - copy:
                      set timeout=5
                      set hidden_timeout_quiet=false
                      menuentry "local"  {
-                     configfile (hd0,gpt3)/boot/grub2/grub.cfg
+                     configfile /var/lib/ironic/tftpboot/$net_default_mac.conf
                      }
-            dest: /tftpboot/EFI/centos/grub.cfg
+            dest: /var/lib/config-data/puppet-generated/ironic/var/lib/ironic/tftpboot/EFI/centos/grub.cfg
             mode: 0644
-        - shell: 'openstack-config --set /etc/ironic/ironic.conf pxe uefi_pxe_bootfile_name grubaa64.efi'
-        - shell: 'openstack-config --set /etc/ironic/ironic.conf pxe uefi_pxe_config_template \$pybasedir/drivers/modules/pxe_grub_config.template'
-
-        - systemd:
-            name: openstack-ironic-conductor
-            state: restarted
-            enabled: yes
-        - replace:
-            path: /usr/lib/python2.7/site-packages/ironic/drivers/modules/pxe_grub_config.template
-            regexp: 'linuxefi'
-            replace: 'linux'
-        - replace:
-            path: /usr/lib/python2.7/site-packages/ironic/drivers/modules/pxe_grub_config.template
-            regexp: 'initrdefi'
-            replace: 'initrd'
+        - shell: 'sudo crudini --set /var/lib/config-data/puppet-generated/ironic/etc/ironic/ironic.conf pxe pxe_bootfile_name_by_arch aarch64:grubaa64.efi'
+        - shell: 'sudo crudini --set /var/lib/config-data/puppet-generated/ironic/etc/ironic/ironic.conf pxe pxe_config_template_by_arch aarch64:\$pybasedir/drivers/modules/pxe_grub_config.template'
+        - shell: 'docker exec -u root ironic_conductor sed -i "s/initrdefi/initrd/g" /usr/lib/python2.7/site-packages/ironic/drivers/modules/pxe_grub_config.template'
+        - shell: 'docker exec -u root ironic_conductor sed -i "s/linuxefi/linux/g" /usr/lib/python2.7/site-packages/ironic/drivers/modules/pxe_grub_config.template'
         - lineinfile:
-            path: /tftpboot/map-file
+            path: /var/lib/config-data/puppet-generated/ironic/var/lib/ironic/tftpboot/map-file
             insertafter: EOF
             state: present
             line: ''
-        - shell: "echo 'r ^/EFI/centos/grub.cfg-(.*) /tftpboot/pxelinux.cfg/\\1' | sudo tee --append /tftpboot/map-file"
-        - shell: "echo 'r ^/EFI/centos/grub.cfg /tftpboot/EFI/centos/grub.cfg' | sudo tee --append /tftpboot/map-file"
+        - shell: "echo 'r ^/EFI/centos/grub.cfg-(.*) /var/lib/ironic/tftpboot/pxelinux.cfg/\\1' | sudo tee --append /var/lib/config-data/puppet-generated/ironic/var/lib/ironic/tftpboot/map-file"
+        - shell: "echo 'r ^/EFI/centos/grub.cfg /var/lib/ironic/tftpboot/EFI/centos/grub.cfg' | sudo tee --append /var/lib/config-data/puppet-generated/ironic/var/lib/ironic/tftpboot/map-file"
+        - shell: "docker restart {{ item }}"
+          with_items:
+            - ironic_conductor
+            - ironic_pxe_tftp
         - systemd:
             name: xinetd
             state: restarted