-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Datasource for UpCloud #743
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
Merged
Merged
Changes from all commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
7b5ca7a
New datasource: UpCloud
806b711
DataSourceUpCloud: small styling fixes
a6df540
UpCloud datasource: unit tests
f6c3254
UpCloud datasource: support both local and networked init
3d77ab8
UpCloud datasource: Use SLAAC config for IPv6 interfaces
0bb8a99
Documentation for UpCloud datasource
d9166b0
UpCloud datasource: required styling for tests
7f9bddd
Merge branch 'master' into datasource-upcloud
ajmyyra e5b434c
Documentation addition/fix
f6b06dd
UpCloud to ds-identity
4046d40
UpCloud datasource default to v2 network config
ee6e557
Merge branch 'datasource-upcloud' of github.com:ajmyyra/cloud-init in…
7cb9f76
Flake: forgotten styling
03aa632
UpCloud datasource: revert to net config v1, fix accept-ra in v2
327927f
Flake: style change
b0de834
Network config: remove v2
74d6281
Merge branch 'master' into datasource-upcloud
TheRealFalcon 03e37b9
UpCloud datasource: retries to 30
c605655
UpCloud: update for docs
60793fa
Merge branch 'master' into datasource-upcloud
TheRealFalcon File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,6 +39,7 @@ | |
| 'SAP Converged Cloud', | ||
| 'Scaleway', | ||
| 'SmartOS', | ||
| 'UpCloud', | ||
| 'VMware', | ||
| 'ZStack', | ||
| 'Other' | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,165 @@ | ||
| # Author: Antti Myyrä <antti.myyra@upcloud.com> | ||
| # | ||
| # This file is part of cloud-init. See LICENSE file for license information. | ||
|
|
||
| # UpCloud server metadata API: | ||
| # https://developers.upcloud.com/1.3/8-servers/#metadata-service | ||
|
|
||
| from cloudinit import log as logging | ||
| from cloudinit import sources | ||
| from cloudinit import util | ||
| from cloudinit import net as cloudnet | ||
| from cloudinit.net.dhcp import EphemeralDHCPv4, NoDHCPLeaseError | ||
|
|
||
|
|
||
| from cloudinit.sources.helpers import upcloud as uc_helper | ||
|
|
||
| LOG = logging.getLogger(__name__) | ||
|
|
||
| BUILTIN_DS_CONFIG = {"metadata_url": "http://169.254.169.254/metadata/v1.json"} | ||
|
|
||
| # Wait for a up to a minute, retrying the meta-data server | ||
| # every 2 seconds. | ||
| MD_RETRIES = 30 | ||
| MD_TIMEOUT = 2 | ||
| MD_WAIT_RETRY = 2 | ||
|
|
||
|
|
||
| class DataSourceUpCloud(sources.DataSource): | ||
|
|
||
| dsname = "UpCloud" | ||
|
|
||
| # We'll perform DHCP setup only in init-local, see DataSourceUpCloudLocal | ||
| perform_dhcp_setup = False | ||
|
|
||
| def __init__(self, sys_cfg, distro, paths): | ||
| sources.DataSource.__init__(self, sys_cfg, distro, paths) | ||
| self.distro = distro | ||
| self.metadata = dict() | ||
| self.ds_cfg = util.mergemanydict( | ||
| [ | ||
| util.get_cfg_by_path(sys_cfg, ["datasource", "UpCloud"], {}), | ||
| BUILTIN_DS_CONFIG, | ||
| ] | ||
| ) | ||
| self.metadata_address = self.ds_cfg["metadata_url"] | ||
| self.retries = self.ds_cfg.get("retries", MD_RETRIES) | ||
| self.timeout = self.ds_cfg.get("timeout", MD_TIMEOUT) | ||
| self.wait_retry = self.ds_cfg.get("wait_retry", MD_WAIT_RETRY) | ||
| self._network_config = None | ||
|
|
||
| def _get_sysinfo(self): | ||
| return uc_helper.read_sysinfo() | ||
|
|
||
| def _read_metadata(self): | ||
| return uc_helper.read_metadata( | ||
| self.metadata_address, | ||
| timeout=self.timeout, | ||
| sec_between=self.wait_retry, | ||
| retries=self.retries, | ||
| ) | ||
|
|
||
| def _get_data(self): | ||
| (is_upcloud, server_uuid) = self._get_sysinfo() | ||
|
|
||
| # only proceed if we know we are on UpCloud | ||
| if not is_upcloud: | ||
| return False | ||
|
|
||
| LOG.info("Running on UpCloud. server_uuid=%s", server_uuid) | ||
|
|
||
| if self.perform_dhcp_setup: # Setup networking in init-local stage. | ||
| try: | ||
| LOG.debug("Finding a fallback NIC") | ||
| nic = cloudnet.find_fallback_nic() | ||
| LOG.debug("Discovering metadata via DHCP interface %s", nic) | ||
| with EphemeralDHCPv4(nic): | ||
| md = util.log_time( | ||
| logfunc=LOG.debug, | ||
| msg="Reading from metadata service", | ||
| func=self._read_metadata, | ||
| ) | ||
| except (NoDHCPLeaseError, sources.InvalidMetaDataException) as e: | ||
| util.logexc(LOG, str(e)) | ||
| return False | ||
| else: | ||
| try: | ||
| LOG.debug( | ||
| "Discovering metadata without DHCP-configured networking" | ||
| ) | ||
| md = util.log_time( | ||
| logfunc=LOG.debug, | ||
| msg="Reading from metadata service", | ||
| func=self._read_metadata, | ||
| ) | ||
| except sources.InvalidMetaDataException as e: | ||
| util.logexc(LOG, str(e)) | ||
| LOG.info( | ||
| "No DHCP-enabled interfaces available, " | ||
| "unable to fetch metadata for %s", | ||
| server_uuid, | ||
| ) | ||
| return False | ||
|
|
||
| self.metadata_full = md | ||
| self.metadata["instance-id"] = md.get("instance_id", server_uuid) | ||
| self.metadata["local-hostname"] = md.get("hostname") | ||
| self.metadata["network"] = md.get("network") | ||
| self.metadata["public-keys"] = md.get("public_keys") | ||
| self.metadata["availability_zone"] = md.get("region", "default") | ||
| self.vendordata_raw = md.get("vendor_data", None) | ||
| self.userdata_raw = md.get("user_data", None) | ||
|
|
||
| return True | ||
|
|
||
| def check_instance_id(self, sys_cfg): | ||
| return sources.instance_id_matches_system_uuid(self.get_instance_id()) | ||
|
|
||
| @property | ||
| def network_config(self): | ||
| """ | ||
| Configure the networking. This needs to be done each boot, | ||
| since the IP and interface information might have changed | ||
| due to reconfiguration. | ||
| """ | ||
|
|
||
| if self._network_config: | ||
| return self._network_config | ||
|
|
||
| raw_network_config = self.metadata.get("network") | ||
| if not raw_network_config: | ||
| raise Exception("Unable to get network meta-data from server....") | ||
|
|
||
| self._network_config = uc_helper.convert_network_config( | ||
| raw_network_config, | ||
| ) | ||
|
|
||
| return self._network_config | ||
|
|
||
|
|
||
| class DataSourceUpCloudLocal(DataSourceUpCloud): | ||
| """ | ||
| Run in init-local using a DHCP discovery prior to metadata crawl. | ||
|
|
||
| In init-local, no network is available. This subclass sets up minimal | ||
| networking with dhclient on a viable nic so that it can talk to the | ||
| metadata service. If the metadata service provides network configuration | ||
| then render the network configuration for that instance based on metadata. | ||
| """ | ||
|
|
||
| perform_dhcp_setup = True # Get metadata network config if present | ||
|
|
||
|
|
||
| # Used to match classes to dependencies | ||
| datasources = [ | ||
| (DataSourceUpCloudLocal, (sources.DEP_FILESYSTEM, )), | ||
| (DataSourceUpCloud, (sources.DEP_FILESYSTEM, sources.DEP_NETWORK)), | ||
| ] | ||
|
|
||
|
|
||
| # Return a list of data sources that match this set of dependencies | ||
| def get_datasource_list(depends): | ||
| return sources.list_from_depends(depends, datasources) | ||
|
|
||
|
|
||
| # vi: ts=4 expandtab | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.