Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add Equinix Metal metadata service #680

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add EquinixMetal to ds-identify
Signed-off-by: Marques Johansson <mjohansson@equinix.com>
  • Loading branch information
displague committed Jun 28, 2021
commit 0d200f908bb01545a8b9a2e9d81e79237d6786cc
1 change: 1 addition & 0 deletions cloudinit/apport.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
'DigitalOcean',
'E24Cloud',
'GCE - Google Compute Engine',
'EquinixMetal',
'Exoscale',
'Hetzner Cloud',
'IBM - (aka SoftLayer or BlueMix)',
Expand Down
1 change: 1 addition & 0 deletions cloudinit/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
'Exoscale',
'RbxCloud',
'UpCloud',
'EquinixMetal',
# At the end to act as a 'catch' when none of the above work...
'None',
],
Expand Down
10 changes: 9 additions & 1 deletion tests/unittests/test_ds_identify.py
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,10 @@ def test_e24cloud_not_active(self):
"""EC2: bobrightbox.com in product_serial is not brightbox'"""
self._test_ds_not_found('Ec2-E24Cloud-negative')

def test_equinixmetal_identified(self):
"""Test that Equinix Metal is identified by metadata"""
self._test_ds_found('EquinixMetal')


class TestBSDNoSys(DsIdentifyBase):
"""Test *BSD code paths
Expand Down Expand Up @@ -1136,7 +1140,11 @@ def _print_run_output(rc, out, err, cfg, files):
'Ec2-E24Cloud-negative': {
'ds': 'Ec2',
'files': {P_SYS_VENDOR: 'e24cloudyday\n'},
}
},
'EquinixMetal': {
'ds': 'EquinixMetal',
'mocks': [], # TODO how do I mock metadata responses?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't. at least not for ds-identify. It only identifies via locally available data.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could add DS support for the models that do report "Packet" back somewhere in the DMI, but I would have to survey the available models to identify any variations in the fields and values.

Should I (can I?) remove DS support and only rely on metadata service detection?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what you mean by "DS support".

Maybe some background would help you to understand what ds-identify does here.

  1. We want vendors to be able to make OS images (like https://cloud-images.ubuntu.com/) that "just work" wherever you try to run them, and an OS with cloud-init installed but not on a cloud would not do anything differently. datasource_list can configure which datasources will be searched, but ideally there would be no need for such a thing. cloud-init would just "do the right thing".

  2. Previously, cloud-init (in python) would walk through each datasource in datasource_list and try to get data. That meant that boot was always impacted (cloud-init always ran). On EC2, that meant doing a dhcp and checking to see if the metadata service was there. That is obviously less than ideal. It was slow, and meant if you booted such an image elsewhere, and there happened to be http://169.254.169.254/latest/user-data, then it would execute that code.

Now, with ds-identify if it determines that the system is not on a cloud platform, cloud-init does not run at all. From systemd's perspective, cloud-init.target is not even enabled. But in order to do that... we only look at local data. We want those checks to be very fast, and thus far, they are. When ds-identify finds that it is on Equinox, as told to it by DMI data, it knows that it will find an equinox metadata service (or... if someone is lying to it, then failure is somewhat expected. As an example... if cpu identifies itself as x86_64, but didn't implement some of the interfaces, you'd expect that a program might fail).

Copy link
Author

@displague displague Dec 8, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there examples of providers that have no local representation (no guarantee of identifiable DMI ids)?

The presence of packet.net (or equinix) in metadata.platformequinix.com/2009-04-04/iqn is the only approach that will work for a majority of our infrastructure (that I am aware of). Very few devices report Packet somewhere in their DMI (that I am aware of).

/cc @mmlb @dustinmiller1337 @pereztr5

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@smoser Is there a possible alternative to dmi data? We can likely go that route for our own machines, but should not be an expectation for making use of tinkerbell. We can control kernel boot args very easily, can we have cloud-init also check there?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh wait this would apply at runtime not install-time 🤦‍♂️ so we don't have as much control over kernel args :/

Copy link
Author

@displague displague Dec 9, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@smoser Tinkerbell has an EM descendent metadata service and deployment architecture, but in that environment users bring their own hardware and DMI stamping may not be possible.

Related issue: tinkerbell/cluster-api-provider-tinkerbell#6

Copy link
Author

@displague displague Dec 9, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm leaving Tinkerbell concerns out of this PR, but I was hopeful that we could leverage this PR in some way in support of https://tinkerbell.org/ environments later.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there examples of providers that have no local representation (no guarantee of identifiable DMI ids)?

MAAS. It sounds like MAAS is something very similar to what you're working on.
The way MAAS works is:

  • network booted environment sends cmdline with 'ci.ds=MAAS'

    ds-identify generically reads the ci.ds kernel parameter to be declaring
    the datasource to use.

  • installed system declares the datasource_list to have only MAAS in it.

    during the install, maas writes a cloud-init config file to the target system. that declares 'datasource_list' to just have MAAS and ds-identify reespects that.

},
}

# vi: ts=4 expandtab
11 changes: 10 additions & 1 deletion tools/ds-identify
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@ DI_DSNAME=""
# be searched if there is no setting found in config.
DI_DSLIST_DEFAULT="MAAS ConfigDrive NoCloud AltCloud Azure Bigstep \
CloudSigma CloudStack DigitalOcean Vultr AliYun Ec2 GCE OpenNebula OpenStack \
OVF SmartOS Scaleway Hetzner IBMCloud Oracle Exoscale RbxCloud UpCloud"
OVF SmartOS Scaleway Hetzner IBMCloud Oracle Exoscale RbxCloud UpCloud \
EquinixMetal"
DI_DSLIST=""
DI_MODE=""
DI_ON_FOUND=""
Expand Down Expand Up @@ -1302,6 +1303,14 @@ dscheck_Oracle() {
return ${DS_NOT_FOUND}
}

dscheck_EquinixMetal() {
check_seed_dir "EquinixMetal" meta-data user-data && return ${DS_FOUND}
if dmi_product_name_matches "Equinix Metal"; then
return $DS_FOUND
fi
return $DS_NOT_FOUND
}

is_ibm_provisioning() {
local pcfg="${PATH_ROOT}/root/provisioningConfiguration.cfg"
local logf="${PATH_ROOT}/root/swinstall.log"
Expand Down