diff options
author | Maxime Dufour <maxime.dufour@outscale.com> | 2022-09-03 00:21:56 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-02 16:21:56 -0600 |
commit | d469008d7316cc8c5e66112ee85c8bf27234ba1c (patch) | |
tree | 14ffa93fc27b4dd38d98d6eaaef4c7f5ca22cf5c /cloudinit/sources/DataSourceEc2.py | |
parent | 071493220d6c453bb493013221330ca1076ad9b7 (diff) | |
download | cloud-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.py | 28 |
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 |