test(aws): fixed missing image upload code
import datetime
import logging
+import time
+import json
+import os
+import pathlib
+import subprocess
+import sys
+
from os import path
+from urllib.parse import urlparse
import boto3
+from botocore.exceptions import ClientError
from .sshclient import RemoteClient
@@ -42,6 +51,7 @@ class AWS:
else:
self.session = boto3.Session()
self.client = self.session.client("ec2")
+ self.s3 = self.session.client("s3")
self.ec2 = self.session.resource("ec2")
self.security_group_id = None
self.instance = None
@@ -155,8 +165,72 @@ class AWS:
except boto3.exceptions.Boto3Error as e:
logger.exception(e)
+
+ def upload_image(self, image_url):
+ o = urlparse(image_url)
+ image_name = "gl-integration-test-" + str(int(time.time()))
+
+ if o.scheme != "s3" and o.scheme != "file":
+ raise NotImplementedError("Only local image file uploads and S3 buckets are implemented.")
+
+ if o.scheme == "file":
+ logger.debug("Uploading image %s" % image_url)
+ image_file = o.path
+ repo_root = pathlib.Path(__file__).parent.parent.parent
+ cmd = [
+ os.path.join(repo_root, "bin", "make-ec2-ami"),
+ "--bucket",
+ self.config["bucket"],
+ "--region",
+ self.config["region"],
+ "--image-name",
+ image_name,
+ "--purpose",
+ "integration-test",
+ "--image-overwrite",
+ "false",
+ image_file,
+ ]
+ logger.debug("Running command: " + (" ".join([v for v in cmd])))
+ result = subprocess.run(cmd, capture_output=True)
+ if result.returncode != 0:
+ sys.exit("Error uploading image %s" % (result.stderr.decode("utf-8")))
+ logger.debug("Result of upload_image %s" % (result.stdout.decode("utf-8")))
+ return json.loads(result.stdout)
+
+ if o.scheme == "s3":
+ images = self.ec2.describe_images(Filters=[{
+ "Name": "name",
+ "Values": [image_name]
+ }])
+ if len(images['Images']) > 0:
+ ami_id = images['Images'][0]['ImageId']
+ logger.debug("Image with AMI id %s already exists", ami_id)
+ return {"ami-id": ami_id}
+
+ snapshot_task_id = glci.aws.import_snapshot(
+ ec2_client=self.ec2,
+ s3_bucket_name=o.netloc,
+ image_key=o.path.lstrip("/"),
+ )
+ snapshot_id = glci.aws.wait_for_snapshot_import(
+ ec2_client=self.ec2,
+ snapshot_task_id=snapshot_task_id,
+ )
+ initial_ami_id = glci.aws.register_image(
+ ec2_client=self.ec2,
+ snapshot_id=snapshot_id,
+ image_name="gl-integration-test-image-" + o.path.split("/objects/",1)[1],
+ )
+ logger.debug("Imported image %s as AMI %s", image_url, initial_ami_id)
+ return {"ami-id": initial_ami_id}
+
def create_instance(self):
"""Create AWS instance from given AMI and with given security group."""
+ if not "ami_id" in self.config:
+ ami = self.upload_image(self.config["image"])
+ self.config["ami_id"] = ami["ami-id"]
+
ami_id = self.config["ami_id"]
key_name = self.ssh_config["key_name"]
ssh_key_filepath = path.expanduser(self.ssh_config["ssh_key_filepath"])
