summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apex/deploy.py3
-rw-r--r--apex/settings/deploy_settings.py4
-rw-r--r--apex/settings/network_settings.py4
-rw-r--r--apex/tests/config/nova_output.json23
-rw-r--r--apex/tests/config/test_overcloudrc17
-rw-r--r--apex/tests/constants.py1
-rw-r--r--apex/tests/test_apex_clean.py8
-rw-r--r--apex/tests/test_apex_common_parsers.py54
-rw-r--r--apex/tests/test_apex_common_utils.py35
-rw-r--r--apex/tests/test_apex_deploy_settings.py8
-rw-r--r--apex/tests/test_apex_inventory.py18
-rw-r--r--apex/tests/test_apex_ip_utils.py42
-rw-r--r--apex/tests/test_apex_network_environment.py21
-rw-r--r--apex/tests/test_apex_network_settings.py8
-rw-r--r--apex/undercloud/undercloud.py5
-rw-r--r--apex/virtual/virtual_utils.py3
-rw-r--r--build/bash_completion_apex2
-rwxr-xr-xci/deploy.sh22
-rwxr-xr-xci/dev_dep_check.sh7
-rwxr-xr-xcontrib/simple_deploy.sh15
-rw-r--r--lib/ansible/playbooks/configure_undercloud.yml2
21 files changed, 183 insertions, 119 deletions
diff --git a/apex/deploy.py b/apex/deploy.py
index 6866945b..1cab0d6c 100644
--- a/apex/deploy.py
+++ b/apex/deploy.py
@@ -13,6 +13,7 @@ import argparse
import json
import logging
import os
+import platform
import pprint
import shutil
import sys
@@ -77,7 +78,6 @@ def build_vms(inventory, network_settings,
name = 'baremetal{}'.format(idx)
volume = name + ".qcow2"
volume_path = os.path.join(constants.LIBVIRT_VOLUME_PATH, volume)
- # TODO(trozet): add back aarch64
# TODO(trozet): add error checking
vm_lib.create_vm(
name, volume_path,
@@ -357,6 +357,7 @@ def main():
deploy_vars = dict()
deploy_vars['virtual'] = args.virtual
deploy_vars['debug'] = args.debug
+ deploy_vars['aarch64'] = platform.machine() == 'aarch64'
deploy_vars['dns_server_args'] = ''
deploy_vars['apex_temp_dir'] = APEX_TEMP_DIR
deploy_vars['stackrc'] = 'source /home/stack/stackrc'
diff --git a/apex/settings/deploy_settings.py b/apex/settings/deploy_settings.py
index c8e347b7..793e43ac 100644
--- a/apex/settings/deploy_settings.py
+++ b/apex/settings/deploy_settings.py
@@ -43,10 +43,6 @@ VALID_ODL_VERSIONS = ['carbon', 'nitrogen', 'master']
class DeploySettings(dict):
"""
This class parses a APEX deploy settings yaml file into an object
-
- Currently the parsed object is dumped into a bash global definition file
- for deploy.sh consumption. This object will later be used directly as
- deployment script move to python.
"""
def __init__(self, filename):
if isinstance(filename, str):
diff --git a/apex/settings/network_settings.py b/apex/settings/network_settings.py
index 14870078..f6566834 100644
--- a/apex/settings/network_settings.py
+++ b/apex/settings/network_settings.py
@@ -35,10 +35,6 @@ class NetworkSettings(dict):
The resulting object will be used later to generate network environment
file as well as configuring post deployment networks.
-
- Currently the parsed object is dumped into a bash global definition file
- for deploy.sh consumption. This object will later be used directly as
- deployment script move to python.
"""
def __init__(self, filename):
init_dict = {}
diff --git a/apex/tests/config/nova_output.json b/apex/tests/config/nova_output.json
new file mode 100644
index 00000000..1348ef24
--- /dev/null
+++ b/apex/tests/config/nova_output.json
@@ -0,0 +1,23 @@
+[
+ {
+ "Status": "ACTIVE",
+ "Networks": "ctlplane=192.30.9.9",
+ "ID": "a5ff8aeb-5fd0-467f-9d89-791dfbc6267b",
+ "Image Name": "overcloud-full",
+ "Name": "overcloud-novacompute-1"
+ },
+ {
+ "Status": "ACTIVE",
+ "Networks": "ctlplane=192.30.9.10",
+ "ID": "c8be26ae-6bef-4841-bb03-c7f336cfd785",
+ "Image Name": "overcloud-full",
+ "Name": "overcloud-novacompute-0"
+ },
+ {
+ "Status": "ACTIVE",
+ "Networks": "ctlplane=192.30.9.8",
+ "ID": "105d1c61-78d3-498f-9191-6b21823b8544",
+ "Image Name": "overcloud-full",
+ "Name": "overcloud-controller-0"
+ }
+]
diff --git a/apex/tests/config/test_overcloudrc b/apex/tests/config/test_overcloudrc
new file mode 100644
index 00000000..2707184d
--- /dev/null
+++ b/apex/tests/config/test_overcloudrc
@@ -0,0 +1,17 @@
+# Clear any old environment that may conflict.
+for key in $( set | awk '{FS="="} /^OS_/ {print $1}' ); do unset $key ; done
+export OS_USERNAME=admin
+export OS_BAREMETAL_API_VERSION=1.29
+export NOVA_VERSION=1.1
+export OS_PROJECT_NAME=admin
+export OS_PASSWORD=Wd8ruyf6qG8cmcms6dq2HM93f
+export OS_NO_CACHE=True
+export COMPUTE_API_VERSION=1.1
+export no_proxy=,172.30.9.29,192.30.9.5
+export OS_CLOUDNAME=overcloud
+export OS_AUTH_URL=http://172.30.9.29:5000/v2.0
+export IRONIC_API_VERSION=1.29
+export OS_AUTH_TYPE=password
+export PYTHONWARNINGS="ignore:Certificate has no, ignore:A true SSLContext object is not available"
+export OS_PROJECT_ID=4695721d82c1421094005ef4ab86d33a
+export OS_TENANT_NAME=admin
diff --git a/apex/tests/constants.py b/apex/tests/constants.py
index 47e63e2c..eec64296 100644
--- a/apex/tests/constants.py
+++ b/apex/tests/constants.py
@@ -10,3 +10,4 @@
TEST_CONFIG_DIR = 'config'
TEST_BUILD_DIR = 'build'
TEST_PLAYBOOK_DIR = 'playbooks'
+TEST_DUMMY_CONFIG = 'apex/tests/config'
diff --git a/apex/tests/test_apex_clean.py b/apex/tests/test_apex_clean.py
index d0b87917..7b7df512 100644
--- a/apex/tests/test_apex_clean.py
+++ b/apex/tests/test_apex_clean.py
@@ -16,16 +16,16 @@ from nose import tools
from apex import clean_nodes
-class TestClean(object):
+class TestClean:
@classmethod
- def setup_class(klass):
+ def setup_class(cls):
"""This method is run once for each class before any tests are run"""
@classmethod
- def teardown_class(klass):
+ def teardown_class(cls):
"""This method is run once for each class _after_ all tests are run"""
- def setUp(self):
+ def setup(self):
"""This method is run once before _each_ test method is executed"""
def teardown(self):
diff --git a/apex/tests/test_apex_common_parsers.py b/apex/tests/test_apex_common_parsers.py
new file mode 100644
index 00000000..bed2a8c5
--- /dev/null
+++ b/apex/tests/test_apex_common_parsers.py
@@ -0,0 +1,54 @@
+##############################################################################
+# Copyright (c) 2016 Dan Radez (Red Hat)
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+import os
+
+from apex.tests import constants as con
+from apex.common import parsers as apex_parsers
+from nose.tools import (
+ assert_is_instance,
+ assert_dict_equal
+)
+
+
+class TestCommonParsers:
+ @classmethod
+ def setup_class(cls):
+ """This method is run once for each class before any tests are run"""
+
+ @classmethod
+ def teardown_class(cls):
+ """This method is run once for each class _after_ all tests are run"""
+
+ def setup(self):
+ """This method is run once before _each_ test method is executed"""
+
+ def teardown(self):
+ """This method is run once after _each_ test method is executed"""
+
+ def test_parse_nova_output(self):
+ output = apex_parsers.parse_nova_output(
+ os.path.join(con.TEST_DUMMY_CONFIG, 'nova_output.json'))
+ assert_is_instance(output, dict)
+ nodes = {
+ 'overcloud-controller-0': '192.30.9.8',
+ 'overcloud-novacompute-0': '192.30.9.10',
+ 'overcloud-novacompute-1': '192.30.9.9'
+ }
+ print(output)
+ assert_dict_equal(output, nodes)
+
+ def test_parse_overcloudrc(self):
+ output = apex_parsers.parse_overcloudrc(
+ os.path.join(con.TEST_DUMMY_CONFIG, 'test_overcloudrc'))
+ assert_is_instance(output, dict)
+ assert 'OS_AUTH_TYPE' in output.keys()
+ assert output['OS_AUTH_TYPE'] == 'password'
+ assert 'OS_PASSWORD' in output.keys()
+ assert output['OS_PASSWORD'] == 'Wd8ruyf6qG8cmcms6dq2HM93f'
diff --git a/apex/tests/test_apex_common_utils.py b/apex/tests/test_apex_common_utils.py
index 357ad1b0..12aeaf2c 100644
--- a/apex/tests/test_apex_common_utils.py
+++ b/apex/tests/test_apex_common_utils.py
@@ -8,7 +8,6 @@
##############################################################################
import ipaddress
-import nose.tools
import os
from apex.common import utils
@@ -17,43 +16,47 @@ from apex.tests.constants import (
TEST_CONFIG_DIR,
TEST_PLAYBOOK_DIR)
+from nose.tools import (
+ assert_equal,
+ assert_is_instance,
+ assert_not_is_instance)
+
NET_SETS = os.path.join(TEST_CONFIG_DIR, 'network', 'network_settings.yaml')
-class TestCommonUtils(object):
+class TestCommonUtils:
@classmethod
- def setup_class(klass):
+ def setup_class(cls):
"""This method is run once for each class before any tests are run"""
@classmethod
- def teardown_class(klass):
+ def teardown_class(cls):
"""This method is run once for each class _after_ all tests are run"""
- def setUp(self):
+ def setup(self):
"""This method is run once before _each_ test method is executed"""
def teardown(self):
"""This method is run once after _each_ test method is executed"""
def test_str2bool(self):
- nose.tools.assert_equal(utils.str2bool(True), True)
- nose.tools.assert_equal(utils.str2bool(False), False)
- nose.tools.assert_equal(utils.str2bool("True"), True)
- nose.tools.assert_equal(utils.str2bool("YES"), True)
+ assert_equal(utils.str2bool(True), True)
+ assert_equal(utils.str2bool(False), False)
+ assert_equal(utils.str2bool("True"), True)
+ assert_equal(utils.str2bool("YES"), True)
def test_parse_yaml(self):
- nose.tools.assert_is_instance(utils.parse_yaml(NET_SETS), dict)
+ assert_is_instance(utils.parse_yaml(NET_SETS), dict)
def test_dict_to_string(self):
net_settings = NetworkSettings(NET_SETS)
output = utils.dict_objects_to_str(net_settings)
- nose.tools.assert_is_instance(output, dict)
+ assert_is_instance(output, dict)
for k, v in output.items():
- nose.tools.assert_is_instance(k, str)
- nose.tools.assert_not_is_instance(v, ipaddress.IPv4Address)
+ assert_is_instance(k, str)
+ assert_not_is_instance(v, ipaddress.IPv4Address)
def test_run_ansible(self):
playbook = 'apex/tests/playbooks/test_playbook.yaml'
- nose.tools.assert_equal(
- utils.run_ansible(None, os.path.join(playbook),
- dry_run=True), None)
+ assert_equal(utils.run_ansible(None, os.path.join(playbook),
+ dry_run=True), None)
diff --git a/apex/tests/test_apex_deploy_settings.py b/apex/tests/test_apex_deploy_settings.py
index 312c1f3a..0338087c 100644
--- a/apex/tests/test_apex_deploy_settings.py
+++ b/apex/tests/test_apex_deploy_settings.py
@@ -64,16 +64,16 @@ deploy_options:
""",)
-class TestIpUtils(object):
+class TestIpUtils:
@classmethod
- def setup_class(klass):
+ def setup_class(cls):
"""This method is run once for each class before any tests are run"""
@classmethod
- def teardown_class(klass):
+ def teardown_class(cls):
"""This method is run once for each class _after_ all tests are run"""
- def setUp(self):
+ def setup(self):
"""This method is run once before _each_ test method is executed"""
def teardown(self):
diff --git a/apex/tests/test_apex_inventory.py b/apex/tests/test_apex_inventory.py
index ed95c53c..cca8068b 100644
--- a/apex/tests/test_apex_inventory.py
+++ b/apex/tests/test_apex_inventory.py
@@ -8,13 +8,11 @@
##############################################################################
import os
-import sys
-from io import StringIO
-from nose.tools import assert_equal
-from nose.tools import assert_is_instance
-from nose.tools import assert_raises
-from nose.tools import assert_regexp_matches
+from nose.tools import (
+ assert_equal,
+ assert_is_instance,
+ assert_raises)
from apex import Inventory
from apex.inventory.inventory import InventoryException
@@ -27,16 +25,16 @@ inventory_files = ('intel_pod2_settings.yaml',
files_dir = os.path.join(TEST_CONFIG_DIR, 'inventory')
-class TestInventory(object):
+class TestInventory:
@classmethod
- def setup_class(klass):
+ def setup_class(cls):
"""This method is run once for each class before any tests are run"""
@classmethod
- def teardown_class(klass):
+ def teardown_class(cls):
"""This method is run once for each class _after_ all tests are run"""
- def setUp(self):
+ def setup(self):
"""This method is run once before _each_ test method is executed"""
def teardown(self):
diff --git a/apex/tests/test_apex_ip_utils.py b/apex/tests/test_apex_ip_utils.py
index 04a1b2bb..eb4549d2 100644
--- a/apex/tests/test_apex_ip_utils.py
+++ b/apex/tests/test_apex_ip_utils.py
@@ -12,19 +12,21 @@ import re
from ipaddress import IPv4Address
from ipaddress import ip_network
-from nose.tools import assert_equal
-from nose.tools import assert_false
-from nose.tools import assert_is_instance
-from nose.tools import assert_raises
-from nose.tools import assert_regexp_matches
-from nose.tools import assert_true
-
-from apex.network.ip_utils import IPUtilsException
-from apex.network.ip_utils import _validate_ip_range
-from apex.network.ip_utils import find_gateway
-from apex.network.ip_utils import get_interface
-from apex.network.ip_utils import get_ip
-from apex.network.ip_utils import get_ip_range
+from nose.tools import (
+ assert_equal,
+ assert_false,
+ assert_is_instance,
+ assert_raises,
+ assert_regexp_matches,
+ assert_true)
+
+from apex.network.ip_utils import (
+ IPUtilsException,
+ _validate_ip_range,
+ find_gateway,
+ get_interface,
+ get_ip,
+ get_ip_range)
ip4_pattern = re.compile('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}')
ip4_range_pattern = re.compile('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3},\d{1,'
@@ -40,19 +42,19 @@ def get_default_gateway_linux():
return fields[0]
-class TestIpUtils(object):
+class TestIpUtils:
@classmethod
- def setup_class(klass):
+ def setup_class(cls):
"""This method is run once for each class before any tests are run"""
- klass.iface_name = get_default_gateway_linux()
- iface = get_interface(klass.iface_name)
- klass.iface = iface
+ cls.iface_name = get_default_gateway_linux()
+ iface = get_interface(cls.iface_name)
+ cls.iface = iface
@classmethod
- def teardown_class(klass):
+ def teardown_class(cls):
"""This method is run once for each class _after_ all tests are run"""
- def setUp(self):
+ def setup(self):
"""This method is run once before _each_ test method is executed"""
def teardown(self):
diff --git a/apex/tests/test_apex_network_environment.py b/apex/tests/test_apex_network_environment.py
index 5047adbb..4e3ae111 100644
--- a/apex/tests/test_apex_network_environment.py
+++ b/apex/tests/test_apex_network_environment.py
@@ -11,10 +11,11 @@ import os
from copy import copy
-from nose.tools import assert_equal
-from nose.tools import assert_is_instance
-from nose.tools import assert_not_equal
-from nose.tools import assert_raises
+from nose.tools import (
+ assert_equal,
+ assert_is_instance,
+ assert_not_equal,
+ assert_raises)
from apex.common.constants import (
EXTERNAL_NETWORK,
@@ -29,23 +30,23 @@ from apex.tests.constants import TEST_CONFIG_DIR
from apex.tests.constants import TEST_BUILD_DIR
-class TestNetworkEnvironment(object):
+class TestNetworkEnvironment:
@classmethod
- def setup_class(klass):
+ def setup_class(cls):
"""This method is run once for each class before any tests are run"""
- klass.ns = NetworkSettings(
+ cls.ns = NetworkSettings(
os.path.join(TEST_CONFIG_DIR, 'network/network_settings.yaml'))
- klass.ns_vlans = NetworkSettings(
+ cls.ns_vlans = NetworkSettings(
os.path.join(TEST_CONFIG_DIR,
'network/network_settings_vlans.yaml'))
- klass.ns_ipv6 = NetworkSettings(
+ cls.ns_ipv6 = NetworkSettings(
os.path.join(TEST_CONFIG_DIR, 'network/network_settings_v6.yaml'))
@classmethod
def teardown_class(klass):
"""This method is run once for each class _after_ all tests are run"""
- def setUp(self):
+ def setup(self):
"""This method is run once before _each_ test method is executed"""
def teardown(self):
diff --git a/apex/tests/test_apex_network_settings.py b/apex/tests/test_apex_network_settings.py
index adff8cff..5e2fa072 100644
--- a/apex/tests/test_apex_network_settings.py
+++ b/apex/tests/test_apex_network_settings.py
@@ -27,16 +27,16 @@ from apex.tests.constants import TEST_CONFIG_DIR
files_dir = os.path.join(TEST_CONFIG_DIR, 'network')
-class TestNetworkSettings(object):
+class TestNetworkSettings:
@classmethod
- def setup_class(klass):
+ def setup_class(cls):
"""This method is run once for each class before any tests are run"""
@classmethod
- def teardown_class(klass):
+ def teardown_class(cls):
"""This method is run once for each class _after_ all tests are run"""
- def setUp(self):
+ def setup(self):
"""This method is run once before _each_ test method is executed"""
def teardown(self):
diff --git a/apex/undercloud/undercloud.py b/apex/undercloud/undercloud.py
index da695f5b..513c4191 100644
--- a/apex/undercloud/undercloud.py
+++ b/apex/undercloud/undercloud.py
@@ -10,6 +10,7 @@
import libvirt
import logging
import os
+import platform
import shutil
import subprocess
import time
@@ -215,7 +216,7 @@ class Undercloud:
"enabled": ns_external['enabled']
}
- # FIXME (trozet): for now hardcoding aarch64 to false
- config['aarch64'] = False
+ # Check if this is an ARM deployment
+ config['aarch64'] = platform.machine() == 'aarch64'
return config
diff --git a/apex/virtual/virtual_utils.py b/apex/virtual/virtual_utils.py
index 5ebb0582..4582dbc7 100644
--- a/apex/virtual/virtual_utils.py
+++ b/apex/virtual/virtual_utils.py
@@ -11,6 +11,7 @@ import copy
import iptc
import logging
import os
+import platform
import pprint
import subprocess
@@ -26,7 +27,7 @@ DEFAULT_VIRT_IP = '192.168.122.1'
def generate_inventory(target_file, ha_enabled=False, num_computes=1,
- controller_ram=DEFAULT_RAM, arch='x86_64',
+ controller_ram=DEFAULT_RAM, arch=platform.machine(),
compute_ram=DEFAULT_RAM, vcpus=4):
"""
Generates inventory file for virtual deployments
diff --git a/build/bash_completion_apex b/build/bash_completion_apex
index b3c963e3..59c6afb6 100644
--- a/build/bash_completion_apex
+++ b/build/bash_completion_apex
@@ -50,7 +50,7 @@ __apex_complete () {
}
# run completion setup
-__apex_complete ./deploy.sh __deploy_main
+__apex_complete ./deploy.py __deploy_main
__apex_complete opnfv-deploy __deploy_main
__apex_complete ./util.sh __util_main
__apex_complete opnfv-util __util_main
diff --git a/ci/deploy.sh b/ci/deploy.sh
deleted file mode 100755
index 0ba0c74b..00000000
--- a/ci/deploy.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/env bash
-##############################################################################
-# Copyright (c) 2015 Tim Rozet (Red Hat), Dan Radez (Red Hat) and others.
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-# http://www.apache.org/licenses/LICENSE-2.0
-##############################################################################
-
-# Deploy script to install provisioning server for OPNFV Apex
-# author: Dan Radez (dradez@redhat.com)
-# author: Tim Rozet (trozet@redhat.com)
-#
-
-set -e
-yum -y install python34 python34-devel libvirt-devel python34-pip python-tox ansible
-mkdir -p /home/jenkins-ci/tmp
-mv -f .build /home/jenkins-ci/tmp/
-pip3 install --upgrade --force-reinstall .
-mv -f /home/jenkins-ci/tmp/.build .
-opnfv-deploy $@
diff --git a/ci/dev_dep_check.sh b/ci/dev_dep_check.sh
index 7a14563c..33f1319f 100755
--- a/ci/dev_dep_check.sh
+++ b/ci/dev_dep_check.sh
@@ -32,10 +32,9 @@ if ! sudo yum update -y ipxe-roms-qemu; then
fi
# check for other packages
-for i in epel-release python34-PyYAML openvswitch libguestfs \
- libguestfs-tools-c libvirt-python python2-oslo-config \
- python2-debtcollector python34-devel libxslt-devel \
- libxml2-devel python-virtualbmc python34-jinja2 python34-pip \
+for i in epel-release openvswitch libguestfs \
+ libguestfs-tools-c libvirt-python libxslt-devel \
+ libxml2-devel ansible python34-pip \
rpm-build wget libvirt ntpdate; do
# Make sure deploy deps are installed
if ! rpm -q $i > /dev/null; then
diff --git a/contrib/simple_deploy.sh b/contrib/simple_deploy.sh
index 24b67904..d6d07f38 100755
--- a/contrib/simple_deploy.sh
+++ b/contrib/simple_deploy.sh
@@ -1,20 +1,13 @@
#!/bin/bash
set -e
apex_home=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/../
-export BASE=$apex_home/build
-export LIB=$apex_home/lib
-export IMAGES=$apex_home/.build/
-export PYTHONPATH=$PYTHONPATH:$apex_home/lib/python
+export PYTHONPATH=$apex_home/apex:$PYTHONPATH
$apex_home/ci/dev_dep_check.sh || true
$apex_home/ci/clean.sh
-pushd $apex_home/build
-make clean
-make undercloud
-make overcloud-opendaylight
-popd
-pushd $apex_home/ci
+pip3 install -r $apex_home/requirements.txt
+pushd $apex_home/apex
echo "All further output will be piped to $PWD/nohup.out"
-(nohup ./deploy.sh -v -n $apex_home/config/network/network_settings.yaml -d $apex_home/config/deploy/os-odl-nofeature-noha.yaml &)
+(nohup python3 deploy.py -v -n ../config/network/network_settings.yaml -d ../config/deploy/os-nosdn-nofeature-noha.yaml --deploy-dir ../build --lib-dir ../lib --image-dir ../.build &)
[ -f nohup.out ] || sleep 3
tail -f nohup.out
popd
diff --git a/lib/ansible/playbooks/configure_undercloud.yml b/lib/ansible/playbooks/configure_undercloud.yml
index f19218c3..91a8f9a4 100644
--- a/lib/ansible/playbooks/configure_undercloud.yml
+++ b/lib/ansible/playbooks/configure_undercloud.yml
@@ -45,7 +45,7 @@
- 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)'
+ line: ' _link_mac_pxe_configs(task)'
when: aarch64
- block:
- name: undercloud install