You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by to...@apache.org on 2020/01/08 05:40:42 UTC

[libcloud] branch trunk updated: Support for aws ec2 spot instances

This is an automated email from the ASF dual-hosted git repository.

tomaz pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/libcloud.git


The following commit(s) were added to refs/heads/trunk by this push:
     new b1b59d1  Support for aws ec2 spot instances
     new 55e89d3  Merge pull request #1398 from yukw777/ec2-spot
b1b59d1 is described below

commit b1b59d1062f0118aacefef205914304aa452a363
Author: Peter Yu <20...@users.noreply.github.com>
AuthorDate: Sat Dec 28 01:14:13 2019 -0500

    Support for aws ec2 spot instances
---
 libcloud/compute/drivers/ec2.py                    | 18 +++++++++++-
 .../compute/fixtures/ec2/run_instances_spot.xml    | 32 ++++++++++++++++++++++
 libcloud/test/compute/test_ec2.py                  | 18 ++++++++++++
 3 files changed, 67 insertions(+), 1 deletion(-)

diff --git a/libcloud/compute/drivers/ec2.py b/libcloud/compute/drivers/ec2.py
index 4b00d96..dd31e48 100644
--- a/libcloud/compute/drivers/ec2.py
+++ b/libcloud/compute/drivers/ec2.py
@@ -1825,7 +1825,8 @@ class BaseEC2NodeDriver(NodeDriver):
                     ex_clienttoken=None, ex_blockdevicemappings=None,
                     ex_iamprofile=None, ex_ebs_optimized=None,
                     ex_subnet=None, ex_placement_group=None,
-                    ex_assign_public_ip=False, ex_terminate_on_shutdown=False):
+                    ex_assign_public_ip=False, ex_terminate_on_shutdown=False,
+                    ex_spot=False, ex_spot_max_price=None):
         """
         Create a new EC2 node.
 
@@ -1891,6 +1892,15 @@ class BaseEC2NodeDriver(NodeDriver):
                                               the operating systems command
                                               for system shutdown.
         :type       ex_terminate_on_shutdown: ``bool``
+
+        :keyword    ex_spot: If true, ask for a Spot Instance instead of
+                             requesting On-Demand.
+        :type       ex_spot: ``bool``
+
+        :keyword    ex_spot_max_price: Maximum price to pay for the spot
+                                       instance. If not specified, the
+                                       on-demand price will be used.
+        :type       ex_spot_max_price: ``float``
         """
         params = {
             'Action': 'RunInstances',
@@ -1903,6 +1913,12 @@ class BaseEC2NodeDriver(NodeDriver):
         if ex_terminate_on_shutdown:
             params["InstanceInitiatedShutdownBehavior"] = "terminate"
 
+        if ex_spot:
+            params["InstanceMarketOptions.MarketType"] = "spot"
+            if ex_spot_max_price is not None:
+                params["InstanceMarketOptions.SpotOptions.MaxPrice"] = \
+                    str(ex_spot_max_price)
+
         if ex_security_groups and ex_securitygroup:
             raise ValueError('You can only supply ex_security_groups or'
                              ' ex_securitygroup')
diff --git a/libcloud/test/compute/fixtures/ec2/run_instances_spot.xml b/libcloud/test/compute/fixtures/ec2/run_instances_spot.xml
new file mode 100644
index 0000000..0d2107c
--- /dev/null
+++ b/libcloud/test/compute/fixtures/ec2/run_instances_spot.xml
@@ -0,0 +1,32 @@
+<RunInstancesResponse xmlns="http://ec2.amazonaws.com/doc/2016-11-15/">
+  <reservationId>r-47a5402e</reservationId>
+  <ownerId>AIDADH4IGTRXXKCD</ownerId>
+  <groupSet>
+    <item>
+      <groupId>default</groupId>
+    </item>
+  </groupSet>
+  <instancesSet>
+    <item>
+      <instanceId>i-2ba64344</instanceId>
+      <instanceLifecycle>spot</instanceLifecycle>
+      <imageId>ami-be3adfd7</imageId>
+      <instanceState>
+        <code>0</code>
+        <name>pending</name>
+      </instanceState>
+      <privateDnsName></privateDnsName>
+      <dnsName></dnsName>
+      <keyName>example-key-name</keyName>
+      <amiLaunchIndex>0</amiLaunchIndex>
+      <instanceType>m1.small</instanceType>
+      <launchTime>2007-08-07T11:51:50.000Z</launchTime>
+      <placement>
+        <availabilityZone>us-east-1b</availabilityZone>
+      </placement>
+      <monitoring>
+        <enabled>true</enabled>
+      </monitoring>
+    </item>
+  </instancesSet>
+</RunInstancesResponse>
diff --git a/libcloud/test/compute/test_ec2.py b/libcloud/test/compute/test_ec2.py
index d302a55..c74a50a 100644
--- a/libcloud/test/compute/test_ec2.py
+++ b/libcloud/test/compute/test_ec2.py
@@ -464,6 +464,20 @@ class EC2Tests(LibcloudTestCase, TestCaseMixin):
         self.assertEqual(node2.extra['iam_profile'], iamProfile['id'])
         self.assertEqual(node3.extra['iam_profile'], iamProfile['id'])
 
+    def test_ex_create_node_with_ex_spot(self):
+        image = NodeImage(id='ami-be3adfd7',
+                          name=self.image_name,
+                          driver=self.driver)
+        size = NodeSize('m1.small', 'Small Instance', None, None, None, None,
+                        driver=self.driver)
+        EC2MockHttp.type = 'ex_spot'
+        node = self.driver.create_node(name='foo', image=image, size=size,
+                                       ex_spot=True)
+        self.assertEqual(node.extra['instance_lifecycle'], 'spot')
+        node = self.driver.create_node(name='foo', image=image, size=size,
+                                       ex_spot=True, ex_spot_max_price=1.5)
+        self.assertEqual(node.extra['instance_lifecycle'], 'spot')
+
     def test_list_images(self):
         images = self.driver.list_images()
 
@@ -1485,6 +1499,10 @@ class EC2MockHttp(MockHttp):
         body = self.fixtures.load('run_instances_iam_profile.xml')
         return (httplib.OK, body, {}, httplib.responses[httplib.OK])
 
+    def _ex_spot_RunInstances(self, method, url, body, headers):
+        body = self.fixtures.load('run_instances_spot.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
     def _TerminateInstances(self, method, url, body, headers):
         body = self.fixtures.load('terminate_instances.xml')
         return (httplib.OK, body, {}, httplib.responses[httplib.OK])