summaryrefslogtreecommitdiff
path: root/cloudinit/sources/DataSourceEc2.py
diff options
context:
space:
mode:
authorMaxime Dufour <maxime.dufour@outscale.com>2022-09-03 00:21:56 +0200
committerGitHub <noreply@github.com>2022-09-02 16:21:56 -0600
commitd469008d7316cc8c5e66112ee85c8bf27234ba1c (patch)
tree14ffa93fc27b4dd38d98d6eaaef4c7f5ca22cf5c /cloudinit/sources/DataSourceEc2.py
parent071493220d6c453bb493013221330ca1076ad9b7 (diff)
downloadcloud-init-git-d469008d7316cc8c5e66112ee85c8bf27234ba1c.tar.gz
Identify 3DS Outscale Datasource as Ec2 (#1686)
Outscale has an Ec2-compatible metadata service and is detected by: DMI product name: 3DS Outscale VM DMI vendor: 3DS Outscale The difference between stock Ec2 IMDS and Outscale is that the tags routes in their IMDS can return 404s if tags contain certain characters which result in 404 errors in cloud-int logs (LP: #1988157) To avoid errors in cloud-init on tag-related route 404s, add a parameter to retrieval_exception_ignore_cb to helpers/ec2/_get_instance_metadata to allow 404s on tag-related routes to be skipped.
Diffstat (limited to 'cloudinit/sources/DataSourceEc2.py')
-rw-r--r--cloudinit/sources/DataSourceEc2.py28
1 files changed, 26 insertions, 2 deletions
diff --git a/cloudinit/sources/DataSourceEc2.py b/cloudinit/sources/DataSourceEc2.py
index 2240e9c5..a25af495 100644
--- a/cloudinit/sources/DataSourceEc2.py
+++ b/cloudinit/sources/DataSourceEc2.py
@@ -43,6 +43,7 @@ class CloudNames(object):
BRIGHTBOX = "brightbox"
ZSTACK = "zstack"
E24CLOUD = "e24cloud"
+ OUTSCALE = "outscale"
# UNKNOWN indicates no positive id. If strict_id is 'warn' or 'false',
# then an attempt at the Ec2 Metadata service will be made.
UNKNOWN = "unknown"
@@ -51,6 +52,11 @@ class CloudNames(object):
NO_EC2_METADATA = "no-ec2-metadata"
+# Drop when LP: #1988157 tag handling is fixed
+def skip_404_tag_errors(exception):
+ return exception.code == 404 and "meta-data/tags/" in exception.url
+
+
class DataSourceEc2(sources.DataSource):
dsname = "Ec2"
@@ -530,8 +536,12 @@ class DataSourceEc2(sources.DataSource):
if self.cloud_name == CloudNames.AWS:
exc_cb = self._refresh_stale_aws_token_cb
exc_cb_ud = self._skip_or_refresh_stale_aws_token_cb
- else:
+ skip_cb = None
+ elif self.cloud_name == CloudNames.OUTSCALE:
exc_cb = exc_cb_ud = None
+ skip_cb = skip_404_tag_errors
+ else:
+ exc_cb = exc_cb_ud = skip_cb = None
try:
crawled_metadata["user-data"] = ec2.get_instance_userdata(
api_version,
@@ -546,6 +556,7 @@ class DataSourceEc2(sources.DataSource):
headers_cb=self._get_headers,
headers_redact=redact,
exception_cb=exc_cb,
+ retrieval_exception_ignore_cb=skip_cb,
)
if self.cloud_name == CloudNames.AWS:
identity = ec2.get_instance_identity(
@@ -670,7 +681,7 @@ class DataSourceEc2Local(DataSourceEc2):
perform_dhcp_setup = True # Use dhcp before querying metadata
def get_data(self):
- supported_platforms = (CloudNames.AWS,)
+ supported_platforms = (CloudNames.AWS, CloudNames.OUTSCALE)
if self.cloud_name not in supported_platforms:
LOG.debug(
"Local Ec2 mode only supported on %s, not %s",
@@ -760,6 +771,14 @@ def identify_e24cloud(data):
return CloudNames.E24CLOUD
+def identify_outscale(data):
+ if (
+ data["product_name"] == "3DS Outscale VM".lower()
+ and data["vendor"] == "3DS Outscale".lower()
+ ):
+ return CloudNames.OUTSCALE
+
+
def identify_platform():
# identify the platform and return an entry in CloudNames.
data = _collect_platform_data()
@@ -768,6 +787,7 @@ def identify_platform():
identify_brightbox,
identify_zstack,
identify_e24cloud,
+ identify_outscale,
lambda x: CloudNames.UNKNOWN,
)
for checker in checks:
@@ -790,6 +810,7 @@ def _collect_platform_data():
serial: dmi 'system-serial-number' (/sys/.../product_serial)
asset_tag: 'dmidecode -s chassis-asset-tag'
vendor: dmi 'system-manufacturer' (/sys/.../sys_vendor)
+ product_name: dmi 'system-product-name' (/sys/.../system-manufacturer)
On Ec2 instances experimentation is that product_serial is upper case,
and product_uuid is lower case. This returns lower case values for both.
@@ -821,6 +842,9 @@ def _collect_platform_data():
vendor = dmi.read_dmi_data("system-manufacturer")
data["vendor"] = (vendor if vendor else "").lower()
+ product_name = dmi.read_dmi_data("system-product-name")
+ data["product_name"] = (product_name if product_name else "").lower()
+
return data