fix(agent-call): support automatic spot pricing
This commit is contained in:
@@ -216,15 +216,18 @@ def create_params(cfg):
|
|||||||
raise CloudError(
|
raise CloudError(
|
||||||
"creation requires approved image/type/VSwitch/security group/SSH KeyPair"
|
"creation requires approved image/type/VSwitch/security group/SSH KeyPair"
|
||||||
)
|
)
|
||||||
|
spot_strategy = cfg.get("spot_strategy", "SpotWithPriceLimit")
|
||||||
|
if spot_strategy not in ("SpotWithPriceLimit", "SpotAsPriceGo"):
|
||||||
|
raise CloudError("spot_strategy must be SpotWithPriceLimit or SpotAsPriceGo")
|
||||||
price = cfg.get("spot_price_limit")
|
price = cfg.get("spot_price_limit")
|
||||||
if (
|
if spot_strategy == "SpotWithPriceLimit" and (
|
||||||
isinstance(price, bool)
|
isinstance(price, bool)
|
||||||
or not isinstance(price, (int, float))
|
or not isinstance(price, (int, float))
|
||||||
or not math.isfinite(price)
|
or not math.isfinite(price)
|
||||||
or price <= 0
|
or price <= 0
|
||||||
):
|
):
|
||||||
raise CloudError(
|
raise CloudError(
|
||||||
"a positive, finite spot_price_limit approved by the owner is required"
|
"a positive, finite spot_price_limit is required for SpotWithPriceLimit"
|
||||||
)
|
)
|
||||||
disk = cfg.get("system_disk_gib", 40)
|
disk = cfg.get("system_disk_gib", 40)
|
||||||
if isinstance(disk, bool) or not isinstance(disk, int) or not 40 <= disk <= 200:
|
if isinstance(disk, bool) or not isinstance(disk, int) or not 40 <= disk <= 200:
|
||||||
@@ -241,14 +244,15 @@ def create_params(cfg):
|
|||||||
"InstanceName": cfg["project_tag"],
|
"InstanceName": cfg["project_tag"],
|
||||||
"InstanceChargeType": "PostPaid",
|
"InstanceChargeType": "PostPaid",
|
||||||
"InternetMaxBandwidthOut": 0,
|
"InternetMaxBandwidthOut": 0,
|
||||||
"SpotStrategy": "SpotWithPriceLimit",
|
"SpotStrategy": spot_strategy,
|
||||||
"SpotPriceLimit": price,
|
|
||||||
"SystemDisk.Category": cfg.get("system_disk_category", "cloud_essd"),
|
"SystemDisk.Category": cfg.get("system_disk_category", "cloud_essd"),
|
||||||
"SystemDisk.Size": disk,
|
"SystemDisk.Size": disk,
|
||||||
"SystemDisk.PerformanceLevel": cfg.get("system_disk_performance_level", "PL1"),
|
"SystemDisk.PerformanceLevel": cfg.get("system_disk_performance_level", "PL1"),
|
||||||
"Tag.1.Key": "project",
|
"Tag.1.Key": "project",
|
||||||
"Tag.1.Value": cfg["project_tag"],
|
"Tag.1.Value": cfg["project_tag"],
|
||||||
}
|
}
|
||||||
|
if spot_strategy == "SpotWithPriceLimit":
|
||||||
|
params["SpotPriceLimit"] = price
|
||||||
user_data_file = cfg.get("user_data_file")
|
user_data_file = cfg.get("user_data_file")
|
||||||
if user_data_file is not None:
|
if user_data_file is not None:
|
||||||
if not isinstance(user_data_file, str) or not user_data_file.strip():
|
if not isinstance(user_data_file, str) or not user_data_file.strip():
|
||||||
|
|||||||
@@ -138,6 +138,14 @@ class CloudTests(unittest.TestCase):
|
|||||||
self.assertEqual(params["SystemDisk.PerformanceLevel"], "PL1")
|
self.assertEqual(params["SystemDisk.PerformanceLevel"], "PL1")
|
||||||
self.assertEqual(api.mutations(), ["RunInstances", "AssociateEipAddress"])
|
self.assertEqual(api.mutations(), ["RunInstances", "AssociateEipAddress"])
|
||||||
|
|
||||||
|
def test_automatic_spot_price_omits_price_limit(self):
|
||||||
|
cfg = config()
|
||||||
|
cfg["spot_strategy"] = "SpotAsPriceGo"
|
||||||
|
cfg.pop("spot_price_limit")
|
||||||
|
params = cloud.create_params(cfg)
|
||||||
|
self.assertEqual(params["SpotStrategy"], "SpotAsPriceGo")
|
||||||
|
self.assertNotIn("SpotPriceLimit", params)
|
||||||
|
|
||||||
def test_user_data_is_base64_encoded_without_logging_content(self):
|
def test_user_data_is_base64_encoded_without_logging_content(self):
|
||||||
with tempfile.TemporaryDirectory() as d:
|
with tempfile.TemporaryDirectory() as d:
|
||||||
user_data = Path(d) / "bootstrap.sh"
|
user_data = Path(d) / "bootstrap.sh"
|
||||||
|
|||||||
Reference in New Issue
Block a user