Handle split kernel/ramdisk images

Change-Id: I39462a3374c816c855670ff88d3b9556baedce7a
diff --git a/tempest/api/compute/admin/test_volume.py b/tempest/api/compute/admin/test_volume.py
index e7c931e..2813d7a 100644
--- a/tempest/api/compute/admin/test_volume.py
+++ b/tempest/api/compute/admin/test_volume.py
@@ -59,6 +59,11 @@
             'min_ram': image['min_ram'],
             'visibility': 'public',
         }
+        if 'kernel_id' in image:
+            create_dict['kernel_id'] = image['kernel_id']
+        if 'ramdisk_id' in image:
+            create_dict['ramdisk_id'] = image['ramdisk_id']
+
         create_dict.update(kwargs)
         try:
             new_image = self.admin_image_client.create_image(**create_dict)
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 0450d94..8848507 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -16,7 +16,11 @@
 
 import copy
 import os
+import re
+import shutil
 import subprocess
+import tarfile
+import tempfile
 
 import netaddr
 
@@ -793,6 +797,60 @@
         if img_properties:
             params.update(img_properties)
         params.update(kwargs)
+
+        # This code is basically copying the devstack code that extracts and
+        # uploads split kernel/ramdisk images.
+        if tarfile.is_tarfile(img_path):
+            extract_dir = os.path.join(tempfile.gettempdir(), 'images', name)
+            self.addCleanup(shutil.rmtree, extract_dir)
+            os.makedirs(extract_dir)
+            with tarfile.open(img_path) as tar:
+                tar.extractall(extract_dir, filter='data')
+            filenames = os.listdir(extract_dir)
+            for fname in filenames:
+                if re.search(r'(.*-vmlinuz.*|aki-.*/image$)', fname):
+                    kernel_img_path = os.path.join(extract_dir, fname)
+                elif re.search(r'(.*-initrd.*|ari-.*/image$)', fname):
+                    ramdisk_img_path = os.path.join(extract_dir, fname)
+                elif re.search(f'(.*\\.img$|ami-.*/image$)', fname):
+                    img_path = os.path.join(extract_dir, fname)
+            # Create the kernel image.
+            kparams = {
+                'name': name + '-kernel',
+                'container_format': 'aki',
+                'disk_format': 'aki',
+                'visibility': 'private'
+            }
+            body = self.image_client.create_image(**kparams)
+            image = body['image'] if 'image' in body else body
+            kernel_id = image['id']
+            self.addCleanup(self.image_client.delete_image, kernel_id)
+            self.assertEqual("queued", image['status'])
+            with open(kernel_img_path, 'rb') as image_file:
+                self.image_client.store_image_file(kernel_id, image_file)
+            LOG.debug("image:%s", kernel_id)
+            # Create the ramdisk image.
+            rparams = {
+                'name': name + '-ramdisk',
+                'container_format': 'ari',
+                'disk_format': 'ari',
+                'visibility': 'private'
+            }
+            body = self.image_client.create_image(**rparams)
+            image = body['image'] if 'image' in body else body
+            ramdisk_id = image['id']
+            self.addCleanup(self.image_client.delete_image, ramdisk_id)
+            self.assertEqual("queued", image['status'])
+            with open(ramdisk_img_path, 'rb') as image_file:
+                self.image_client.store_image_file(ramdisk_id, image_file)
+            LOG.debug("image:%s", ramdisk_id)
+            # Set the kernel_id, ramdisk_id, container format, disk format for
+            # the split image.
+            params['kernel_id'] = kernel_id
+            params['ramdisk_id'] = ramdisk_id
+            params['container_format'] = 'ami'
+            params['disk_format'] = 'ami'
+
         body = self.image_client.create_image(**params)
         image = body['image'] if 'image' in body else body
         self.addCleanup(self.image_client.delete_image, image['id'])