From 960e150bee2e34ac491dcdb59d2ac0cdcd4cc467 Mon Sep 17 00:00:00 2001
From: Mark Hamzy <hamzy@us.ibm.com>
Date: Mon, 20 Nov 2017 14:04:11 -0600
Subject: [PATCH] Support multiple architectures

Currently TripleO is hard coded for x86_64 architecture.  There are
files for Ironic IPA {bm-deploy-kernel,bm-deploy-ramdisk} and deploying
the overcloud image
{overcloud-full,overcloud-full-initrd,overcloud-full-vmlinuz}.

This needs to change to support other architectures like PowerPC.  I am
currently proposing that the images be consistently renamed to include
the uname string.

(undercloud) [stack@oscloud5 ~]$ openstack image list
...
| ... | ppc64le-bm-deploy-kernel      | active |
| ... | ppc64le-bm-deploy-ramdisk     | active |
| ... | ppc64le-overcloud-full        | active |
| ... | x86_64-bm-deploy-kernel       | active |
| ... | x86_64-bm-deploy-ramdisk      | active |
| ... | x86_64-overcloud-full         | active |
| ... | x86_64-overcloud-full-initrd  | active |
| ... | x86_64-overcloud-full-vmlinuz | active |
...

Change-Id: Ie5884895bb996e65bc0148908aa3cdf99b25d1b6
Partial-Bug: 1738228
---
 .../v1/overcloud_image/test_overcloud_image.py     |  35 ++---
 .../tests/v1/overcloud_node/test_overcloud_node.py |  11 +-
 tripleoclient/v1/overcloud_deploy.py               |   2 -
 tripleoclient/v1/overcloud_image.py                | 143 ++++++++++++++++++---
 tripleoclient/v1/overcloud_node.py                 |  10 +-
 5 files changed, 146 insertions(+), 55 deletions(-)

diff --git a/tripleoclient/tests/v1/overcloud_image/test_overcloud_image.py b/tripleoclient/tests/v1/overcloud_image/test_overcloud_image.py
index 64cd93b..b723f26 100644
--- a/tripleoclient/tests/v1/overcloud_image/test_overcloud_image.py
+++ b/tripleoclient/tests/v1/overcloud_image/test_overcloud_image.py
@@ -211,23 +211,23 @@ class TestUploadOvercloudImage(TestPluginV1):
             self.app.client_manager.image.images.create.call_count
         )
         self.assertEqual(
-            [mock.call(name='overcloud-full-vmlinuz',
+            [mock.call(name='x86_64-overcloud-full-vmlinuz',
                        disk_format='aki',
                        container_format='bare',
                        visibility='public'),
-             mock.call(name='overcloud-full-initrd',
+             mock.call(name='x86_64-overcloud-full-initrd',
                        disk_format='ari',
                        container_format='bare',
                        visibility='public'),
-             mock.call(name='overcloud-full',
+             mock.call(name='x86_64-overcloud-full',
                        disk_format='qcow2',
                        container_format='bare',
                        visibility='public'),
-             mock.call(name='bm-deploy-kernel',
+             mock.call(name='x86_64-bm-deploy-kernel',
                        disk_format='aki',
                        container_format='bare',
                        visibility='public'),
-             mock.call(name='bm-deploy-ramdisk',
+             mock.call(name='x86_64-bm-deploy-ramdisk',
                        disk_format='ari',
                        container_format='bare',
                        visibility='public')
@@ -265,25 +265,25 @@ class TestUploadOvercloudImage(TestPluginV1):
         )
         self.assertEqual(
             [mock.call(data=b'IMGDATA',
-                       name='overcloud-full-vmlinuz',
+                       name='x86_64-overcloud-full-vmlinuz',
                        disk_format='aki',
                        is_public=True),
              mock.call(data=b'IMGDATA',
-                       name='overcloud-full-initrd',
+                       name='x86_64-overcloud-full-initrd',
                        disk_format='ari',
                        is_public=True),
              mock.call(properties={'kernel_id': 10, 'ramdisk_id': 10},
-                       name='overcloud-full',
+                       name='x86_64-overcloud-full',
                        data=b'IMGDATA',
                        container_format='bare',
                        disk_format='qcow2',
                        is_public=True),
              mock.call(data=b'IMGDATA',
-                       name='bm-deploy-kernel',
+                       name='x86_64-bm-deploy-kernel',
                        disk_format='aki',
                        is_public=True),
              mock.call(data=b'IMGDATA',
-                       name='bm-deploy-ramdisk',
+                       name='x86_64-bm-deploy-ramdisk',
                        disk_format='ari',
                        is_public=True)
              ], self.app.client_manager.image.images.create.call_args_list
@@ -311,15 +311,16 @@ class TestUploadOvercloudImage(TestPluginV1):
         self.cmd.take_action(parsed_args)
 
         expected = [
-            mock.call('overcloud-full-vmlinuz', '/foo/overcloud-full.vmlinuz',
+            mock.call('x86_64-overcloud-full-vmlinuz', '/foo/overcloud-full.vmlinuz',
                       mock.ANY),
-            mock.call('overcloud-full-initrd', '/foo/overcloud-full.initrd',
+            mock.call('x86_64-overcloud-full-initrd', '/foo/overcloud-full.initrd',
                       mock.ANY),
-            mock.call('overcloud-full', '/foo/overcloud-full.qcow2',
+            mock.call('x86_64-overcloud-full', '/foo/overcloud-full.qcow2',
                       mock.ANY),
-            mock.call('bm-deploy-kernel', '/foo/ironic-python-agent.kernel',
+            mock.call('x86_64-bm-deploy-kernel',
+                      '/foo/ironic-python-agent.kernel',
                       mock.ANY),
-            mock.call('bm-deploy-ramdisk',
+            mock.call('x86_64-bm-deploy-ramdisk',
                       '/foo/ironic-python-agent.initramfs',
                       mock.ANY),
             ]
@@ -426,11 +427,11 @@ class TestUploadOvercloudImageFull(TestPluginV1):
                        disk_format='qcow2',
                        container_format='bare',
                        visibility='public'),
-             mock.call(name='bm-deploy-kernel',
+             mock.call(name='x86_64-bm-deploy-kernel',
                        disk_format='aki',
                        container_format='bare',
                        visibility='public'),
-             mock.call(name='bm-deploy-ramdisk',
+             mock.call(name='x86_64-bm-deploy-ramdisk',
                        disk_format='ari',
                        container_format='bare',
                        visibility='public')
diff --git a/tripleoclient/tests/v1/overcloud_node/test_overcloud_node.py b/tripleoclient/tests/v1/overcloud_node/test_overcloud_node.py
index 97b85c3..1d6ad63 100644
--- a/tripleoclient/tests/v1/overcloud_node/test_overcloud_node.py
+++ b/tripleoclient/tests/v1/overcloud_node/test_overcloud_node.py
@@ -379,10 +379,8 @@ class TestImportNode(fakes.TestOvercloudNode):
         call_list = [mock.call(
             'tripleo.baremetal.v1.register_or_update', workflow_input={
                 'nodes_json': nodes_list,
-                'kernel_name': None if no_deploy_image else 'bm-deploy-kernel',
-                'ramdisk_name': (None
-                                 if no_deploy_image else 'bm-deploy-ramdisk'),
-                'instance_boot_option': 'local' if local else 'netboot'
+                'instance_boot_option': 'local' if local else 'netboot',
+                'no_deploy_image': no_deploy_image
             }
         )]
 
@@ -469,6 +467,7 @@ class TestConfigureNode(fakes.TestOvercloudNode):
         # Get the command object to test
         self.cmd = overcloud_node.ConfigureNode(self.app, None)
 
+        # @TODO(hamzy)
         self.workflow_input = {'kernel_name': 'bm-deploy-kernel',
                                'ramdisk_name': 'bm-deploy-ramdisk',
                                'instance_boot_option': None,
@@ -657,7 +656,7 @@ class TestDiscoverNode(fakes.TestOvercloudNode):
             'tripleo.baremetal.v1.discover_and_enroll_nodes',
             workflow_input={'ip_addresses': '10.0.0.0/24',
                             'credentials': [['admin', 'password']],
-                            'kernel_name': 'bm-deploy-kernel',
+                            'kernel_name': 'bm-deploy-kernel',  # @TODO(hamzy)
                             'ramdisk_name': 'bm-deploy-ramdisk',
                             'instance_boot_option': 'local'}
         )
@@ -675,7 +674,7 @@ class TestDiscoverNode(fakes.TestOvercloudNode):
             'tripleo.baremetal.v1.discover_and_enroll_nodes',
             workflow_input={'ip_addresses': ['10.0.0.1', '10.0.0.2'],
                             'credentials': [['admin', 'password']],
-                            'kernel_name': 'bm-deploy-kernel',
+                            'kernel_name': 'bm-deploy-kernel',  # @TODO(hamzy)
                             'ramdisk_name': 'bm-deploy-ramdisk',
                             'instance_boot_option': 'local'}
         )
diff --git a/tripleoclient/v1/overcloud_deploy.py b/tripleoclient/v1/overcloud_deploy.py
index 2b6bc6f..9a088a1 100644
--- a/tripleoclient/v1/overcloud_deploy.py
+++ b/tripleoclient/v1/overcloud_deploy.py
@@ -644,8 +644,6 @@ class DeployOvercloud(command.Command):
         self.log.debug("Starting _pre_verify_capabilities")
 
         validation_params = {
-            'deploy_kernel_name': 'bm-deploy-kernel',
-            'deploy_ramdisk_name': 'bm-deploy-ramdisk',
             'roles_info': utils.get_roles_info(parsed_args),
             'stack_id': parsed_args.stack,
             'parameters': parameters,
diff --git a/tripleoclient/v1/overcloud_image.py b/tripleoclient/v1/overcloud_image.py
index 69020b7..addd762 100644
--- a/tripleoclient/v1/overcloud_image.py
+++ b/tripleoclient/v1/overcloud_image.py
@@ -262,31 +262,63 @@ class UploadOvercloudImage(command.Command):
         )
         return parser
 
+    def _determine_image_files(self,
+                               whole_disk,
+                               os_image_name,
+                               image_path):
+        try_again = False
+        if os.environ['AGENT_ARCH'] == 'x86_64':
+            try_again = True
+
+        if whole_disk:
+            image_files = [
+                os_image_name
+            ]
+        else:
+            image_files = [
+                '%s.initramfs' % os.environ['AGENT_NAME'],
+                '%s.kernel' % os.environ['AGENT_NAME'],
+                os_image_name
+            ]
+
+        try:
+            for image in image_files:
+                self._check_file_exists(os.path.join(image_path,
+                                                     image))
+            return image_files
+        except exceptions.CommandError:
+            if not try_again:
+                raise
+
+        ipa_name = '%s-%s' % (os.environ['AGENT_ARCH'],
+                              os.environ['AGENT_NAME'])
+        image_files = [
+            '%s.initramfs' % ipa_name,
+            '%s.kernel' % ipa_name,
+            '%s-%s' % (os.environ['AGENT_ARCH'], os_image_name)
+        ]
+        for image in image_files:
+            self._check_file_exists(os.path.join(image_path,
+                                                 image))
+        return image_files
+
     def take_action(self, parsed_args):
         self.log.debug("take_action(%s)" % parsed_args)
         glance_client_adaptor = self._get_glance_client_adaptor()
 
         self._env_variable_or_set('AGENT_NAME', 'ironic-python-agent')
+        self._env_variable_or_set('AGENT_ARCH', 'x86_64')
 
         self.log.debug("checking if image files exist")
+        self._determine_image_files(parsed_args.whole_disk,
+                                    parsed_args.os_image_name,
+                                    parsed_args.image_path)
 
         if parsed_args.whole_disk:
-            image_files = [
-                parsed_args.os_image_name
-            ]
             overcloud_image_type = 'whole disk'
         else:
-            image_files = [
-                '%s.initramfs' % os.environ['AGENT_NAME'],
-                '%s.kernel' % os.environ['AGENT_NAME'],
-                parsed_args.os_image_name
-            ]
             overcloud_image_type = 'partition'
 
-        for image in image_files:
-            self._check_file_exists(os.path.join(parsed_args.image_path,
-                                                 image))
-
         image_name = parsed_args.os_image_name.split('.')[0]
 
         self.log.debug("uploading %s overcloud images to glance" %
@@ -294,11 +326,21 @@ class UploadOvercloudImage(command.Command):
 
         # vmlinuz and initrd only need to be uploaded for a partition image
         if not parsed_args.whole_disk:
-            oc_vmlinuz_name = '%s-vmlinuz' % image_name
+            oc_vmlinuz_name = '%s-%s-vmlinuz' % (os.environ['AGENT_ARCH'],
+                                                 image_name)
             oc_vmlinuz_extension = '.vmlinuz'
             oc_vmlinuz_file = os.path.join(parsed_args.image_path,
                                            image_name +
                                            oc_vmlinuz_extension)
+            try:
+                self._check_file_exists(oc_vmlinuz_file)
+            except exceptions.CommandError:
+                if os.environ['AGENT_ARCH'] != 'x86_64':
+                    raise
+                new_name = "%s-%s" % (os.environ['AGENT_ARCH'], image_name)
+                oc_vmlinuz_file = os.path.join(parsed_args.image_path,
+                                               new_name +
+                                               oc_vmlinuz_extension)
             kernel = (self._image_try_update(oc_vmlinuz_name,
                                              oc_vmlinuz_file,
                                              parsed_args) or
@@ -310,11 +352,21 @@ class UploadOvercloudImage(command.Command):
                               parsed_args.image_path, oc_vmlinuz_file)
             ))
 
-            oc_initrd_name = '%s-initrd' % image_name
+            oc_initrd_name = '%s-%s-initrd' % (os.environ['AGENT_ARCH'],
+                                               image_name)
             oc_initrd_extension = '.initrd'
             oc_initrd_file = os.path.join(parsed_args.image_path,
                                           image_name +
                                           oc_initrd_extension)
+            try:
+                self._check_file_exists(oc_initrd_file)
+            except exceptions.CommandError:
+                if os.environ['AGENT_ARCH'] != 'x86_64':
+                    raise
+                new_name = "%s-%s" % (os.environ['AGENT_ARCH'], image_name)
+                oc_initrd_file = os.path.join(parsed_args.image_path,
+                                              new_name +
+                                              oc_vmlinuz_extension)
             ramdisk = (self._image_try_update(oc_initrd_name,
                                               oc_initrd_file,
                                               parsed_args) or
@@ -326,11 +378,20 @@ class UploadOvercloudImage(command.Command):
                                parsed_args.image_path, oc_initrd_file)
             ))
 
-            oc_name = image_name
+            oc_name = '%s-%s' % (os.environ['AGENT_ARCH'], image_name)
             oc_extension = '.qcow2'
             oc_file = os.path.join(parsed_args.image_path,
                                    image_name +
                                    oc_extension)
+            try:
+                self._check_file_exists(oc_file)
+            except exceptions.CommandError:
+                if os.environ['AGENT_ARCH'] != 'x86_64':
+                    raise
+                new_name = "%s-%s" % (os.environ['AGENT_ARCH'], image_name)
+                oc_file = os.path.join(parsed_args.image_path,
+                                       new_name +
+                                       oc_extension)
             overcloud_image = (self._image_try_update(oc_name, oc_file,
                                                       parsed_args) or
                                glance_client_adaptor.upload_image(
@@ -374,11 +435,21 @@ class UploadOvercloudImage(command.Command):
 
         self.log.debug("uploading bm images to glance")
 
-        deploy_kernel_name = 'bm-deploy-kernel'
+        deploy_kernel_name = '%s-bm-deploy-kernel' % os.environ['AGENT_ARCH']
         deploy_kernel_extension = '.kernel'
         deploy_kernel_file = os.path.join(parsed_args.image_path,
                                           os.environ['AGENT_NAME'] +
                                           deploy_kernel_extension)
+        try:
+            self._check_file_exists(deploy_kernel_file)
+        except exceptions.CommandError:
+            if os.environ['AGENT_ARCH'] != 'x86_64':
+                raise
+            new_name = "%s-%s" % (os.environ['AGENT_ARCH'],
+                                  os.environ['AGENT_NAME'])
+            deploy_kernel_file = os.path.join(parsed_args.image_path,
+                                              new_name +
+                                              deploy_kernel_extension)
         self._image_try_update(deploy_kernel_name, deploy_kernel_file,
                                parsed_args) or \
             glance_client_adaptor.upload_image(
@@ -389,11 +460,21 @@ class UploadOvercloudImage(command.Command):
                     parsed_args.image_path,
                     deploy_kernel_file))
 
-        deploy_ramdisk_name = 'bm-deploy-ramdisk'
+        deploy_ramdisk_name = '%s-bm-deploy-ramdisk' % os.environ['AGENT_ARCH']
         deploy_ramdisk_extension = '.initramfs'
         deploy_ramdisk_file = os.path.join(parsed_args.image_path,
                                            os.environ['AGENT_NAME'] +
                                            deploy_ramdisk_extension)
+        try:
+            self._check_file_exists(deploy_ramdisk_file)
+        except exceptions.CommandError:
+            if os.environ['AGENT_ARCH'] != 'x86_64':
+                raise
+            new_name = "%s-%s" % (os.environ['AGENT_ARCH'],
+                                  os.environ['AGENT_NAME'])
+            deploy_ramdisk_file = os.path.join(parsed_args.image_path,
+                                               new_name +
+                                               deploy_ramdisk_extension)
         self._image_try_update(deploy_ramdisk_name, deploy_ramdisk_file,
                                parsed_args) or \
             glance_client_adaptor.upload_image(
@@ -405,16 +486,36 @@ class UploadOvercloudImage(command.Command):
 
         self.log.debug("copy agent images to HTTP BOOT dir")
 
+        agent_kernel = os.path.join(parsed_args.image_path,
+                                    '%s.kernel' % os.environ['AGENT_NAME'])
+        try:
+            self._check_file_exists(agent_kernel)
+        except exceptions.CommandError:
+            if os.environ['AGENT_ARCH'] != 'x86_64':
+                raise
+            new_name = "%s-%s.kernel" % (os.environ['AGENT_ARCH'],
+                                         os.environ['AGENT_NAME'])
+            agent_kernel = os.path.join(parsed_args.image_path,
+                                        new_name)
         self._file_create_or_update(
-            os.path.join(parsed_args.image_path,
-                         '%s.kernel' % os.environ['AGENT_NAME']),
+            agent_kernel,
             os.path.join(parsed_args.http_boot, 'agent.kernel'),
             parsed_args.update_existing
         )
 
+        agent_ramdisk = os.path.join(parsed_args.image_path,
+                                     '%s.initramfs' % os.environ['AGENT_NAME'])
+        try:
+            self._check_file_exists(agent_ramdisk)
+        except exceptions.CommandError:
+            if os.environ['AGENT_ARCH'] != 'x86_64':
+                raise
+            new_name = "%s-%s.initramfs" % (os.environ['AGENT_ARCH'],
+                                            os.environ['AGENT_NAME'])
+            agent_ramdisk = os.path.join(parsed_args.image_path,
+                                         new_name)
         self._file_create_or_update(
-            os.path.join(parsed_args.image_path,
-                         '%s.initramfs' % os.environ['AGENT_NAME']),
+            agent_ramdisk,
             os.path.join(parsed_args.http_boot, 'agent.ramdisk'),
             parsed_args.update_existing
         )
diff --git a/tripleoclient/v1/overcloud_node.py b/tripleoclient/v1/overcloud_node.py
index 0ff413c..f1a19d6 100644
--- a/tripleoclient/v1/overcloud_node.py
+++ b/tripleoclient/v1/overcloud_node.py
@@ -213,18 +213,10 @@ class ImportNode(command.Command):
 
         nodes_config = oooutils.parse_env_file(parsed_args.env_file)
 
-        if parsed_args.no_deploy_image:
-            deploy_kernel = None
-            deploy_ramdisk = None
-        else:
-            deploy_kernel = 'bm-deploy-kernel'
-            deploy_ramdisk = 'bm-deploy-ramdisk'
-
         nodes = baremetal.register_or_update(
             self.app.client_manager,
             nodes_json=nodes_config,
-            kernel_name=deploy_kernel,
-            ramdisk_name=deploy_ramdisk,
+            no_deploy_image=parsed_args.no_deploy_image,
             instance_boot_option=parsed_args.instance_boot_option
         )
 
-- 
2.14.3

