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 Vultr support #827

Merged
merged 37 commits into from
Apr 13, 2021
Merged

Add Vultr support #827

merged 37 commits into from
Apr 13, 2021

Conversation

ddymko
Copy link
Contributor

@ddymko ddymko commented Mar 3, 2021

Proposed Commit Message

    Add support for Vultr cloud.

    This PR adds in support so that cloud-init can run on instances 
    deployed on Vultr cloud. This was originally brought up in #628.

    Co-authored-by: Eric Benner <ebenner@vultr.com>

Additional Context

Greets from Vultr 👋

This PR adds in support so that cloud-init can run on instances deploy on Vultr instances. This was originally brought up in #628

Please let me know if there are any updates or additions that may need to be made.

Test Steps

Checklist:

  • My code follows the process laid out in the documentation
  • I have updated or added any unit tests accordingly
  • I have updated or added any documentation accordingly

@ddymko
Copy link
Contributor Author

ddymko commented Mar 3, 2021

@smoser as per the other PR pinging you for review of this one

Copy link
Collaborator

@smoser smoser left a comment

Choose a reason for hiding this comment

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

Thanks for the pull request.
I have some questions/comments in line. I guess the big things are:

  • avoid the use of globals.
  • lots of INFO that are DEBUG
  • some of the datasources have a 'main', which can be used for easy debugging. They're inconsistent, but for a developer its a useful way to poke around. see SmartOS or GCE for examples.
  • perhaps the vendor_script stuff that you're doing could make use of activate_datasource (see 9e904bb for an explanation).
  • if the instance_id is available locally anywhere (through dmi data?) then it would be great to have a check_instance_id method in the datasource.

Again, thanks for the PR. It will be great to have proper Vultr support in cloud-init.

'timeout': 2,
'wait': 2
}
CONFIG = BUILTIN_DS_CONFIG.copy()
Copy link
Collaborator

Choose a reason for hiding this comment

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

i think we'd rather avoid the global here, and it is kind of confusing how it is used. What were you hoping to accomplish here?


import cloudinit.sources.helpers.vultr as vultr

LOGGER = log.getLogger(__name__)
Copy link
Collaborator

Choose a reason for hiding this comment

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

use LOG for consistency that is the variable name we use everywhere else.

LOGGER.info("Machine is not a Vultr instance")
return False

LOGGER.info("Machine is a Vultr instance")
Copy link
Collaborator

Choose a reason for hiding this comment

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

the majority of these log statements are more debug than info.

info is very sparingly used in cloud-init (it probably should be used more, and logging in cloud-init can definitely use an overhaul, but these are debug).

self.metadata_full = md
self.metadata['instanceid'] = self.metadata_full['instanceid']
self.metadata['local-hostname'] = re.sub(
r'\W+', '', self.metadata_full['hostname'])
Copy link
Collaborator

Choose a reason for hiding this comment

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

the hostname from the metadata service has trailing whitespace ?


# Write vendor startup script
def write_vendor_script(fname, content):
os.makedirs("/var/lib/scripts/vendor/", exist_ok=True)
Copy link
Collaborator

Choose a reason for hiding this comment

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

this feels like it probably can be accomplished with generic vendor data... not needing a datasource specific solution.

other comments on the implementation, this is really just write_file



# Get kernel parameters
def get_kernel_parameters():
Copy link
Collaborator

Choose a reason for hiding this comment

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

util.get_cmdline()



# Close EphermalDHCP so its not left open
def close_ephermeral():
Copy link
Collaborator

Choose a reason for hiding this comment

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

the spelling is wrong here ephemeral not ephermeral.

global METADATA

if not METADATA:
# Bring up interface in local
Copy link
Collaborator

Choose a reason for hiding this comment

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

use a context for this rather htan the global EHP state.

I think you're basically just doing:

with EphemeralDHCPv4(connectivity_url=params['url']):
    v1 = fetch_metadata(params)

and that should take care of EPH entirely.

cloudinit/sources/helpers/vultr.py Show resolved Hide resolved

# Define vendor script
vendor_script = []
vendor_script.append("!/bin/bash")
Copy link
Collaborator

Choose a reason for hiding this comment

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

append ?

and thats not even a proper shebang. odd.

@ddymko
Copy link
Contributor Author

ddymko commented Mar 3, 2021

@smoser Thanks for the review...we'll start work on updating all of these issues/concerns

@smoser
Copy link
Collaborator

smoser commented Mar 5, 2021

@ddymko inspired by your work here, i dusted off my vultr accout to build a https://github.com/cirros-dev/cirros release. (next you can add support to cirros for vultr 😉 )

@Oogy Oogy mentioned this pull request Mar 5, 2021
3 tasks
@ddymko
Copy link
Contributor Author

ddymko commented Mar 5, 2021

@smoser I can't take the credit...most of the work was done by @Oogy and @eb3095.

As for Cirros please let us know if there is any way we could help!

@ddymko ddymko requested a review from smoser March 5, 2021 18:10
CloudSigma CloudStack DigitalOcean AliYun Ec2 GCE OpenNebula OpenStack \
OVF SmartOS Scaleway Hetzner IBMCloud Oracle Exoscale RbxCloud UpCloud"
CloudSigma CloudStack DigitalOcean Vultr AliYun Ec2 GCE OpenNebula OpenStack \
OVF SmartOS Scaleway Hetzner IBMCloud Oracle Exoscale RbxCloud upCloud"
Copy link
Collaborator

Choose a reason for hiding this comment

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

you broke upcloud here.


LOG.debug("Machine is a Vultr instance")

config = vultr.generate_config(BUILTIN_DS_CONFIG)
Copy link
Collaborator

Choose a reason for hiding this comment

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

why would you not use self.ds_config here ?

# Compare subid as instance id
def check_instance_id(self, sys_cfg):
if not vultr.is_vultr():
return None
Copy link
Collaborator

Choose a reason for hiding this comment

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

this function should return a boolean. so return False here.


# Baremetal has no way to implement this in local
if vultr.is_baremetal():
return None
Copy link
Collaborator

Choose a reason for hiding this comment

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

same. False.

@property
def network_config(self):
config = vultr.generate_network_config(BUILTIN_DS_CONFIG)
config_raw = json.dumps(config)
Copy link
Collaborator

Choose a reason for hiding this comment

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

this seems unnecessarily loud to log the dumpped config here. but if you wanted to do it, just skip the 'config_raw' assignment and use 'json.dumps()` and do something like:

LOG.debug("Generated Network: %s", json.dumps(config))

config = vultr.generate_config(BUILTIN_DS_CONFIG)
sysinfo = vultr.get_sysinfo()

print(json.dumps(sysinfo, indent=1))
Copy link
Collaborator

Choose a reason for hiding this comment

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

util.json_dumps() will pretty-print. also sorts keys and other htings that you probably wanted anyway.

# Fetch the metadata
v1 = fetch_metadata(params)
except (NoDHCPLeaseError) as exc:
LOG.error("DHCP failed, cannot continue. Exception: %s",
Copy link
Collaborator

Choose a reason for hiding this comment

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

did this really need a line break ? probably not.

@ddymko
Copy link
Contributor Author

ddymko commented Apr 1, 2021

@eb3095 merged your latest changes

@eb3095
Copy link
Contributor

eb3095 commented Apr 1, 2021

@smoser when you get around to that review I had a question about vendor-data and the network config. I am currently adding the network config to the vendor-data kind of like how user-data functions. Is this required? Do I need to even do that? Seems like the networking config is pulled in a separate function.

@smoser
Copy link
Collaborator

smoser commented Apr 2, 2021

@smoser when you get around to that review I had a question about vendor-data and the network config. I am currently adding the network config to the vendor-data kind of like how user-data functions. Is this required? Do I need to even do that? Seems like the networking config is pulled in a separate function.

If I understand the question correctly, then the answer is 'no'. the only place that network_config has to be present is returned by DataSource.network_config()

Eric Benner and others added 3 commits April 2, 2021 12:03
BUILTIN_DS_CONFIG['timeout'] = self.ds_cfg.get(
'timeout', BUILTIN_DS_CONFIG['timeout'])
BUILTIN_DS_CONFIG['wait'] = self.ds_cfg.get(
'wait', BUILTIN_DS_CONFIG['wait'])
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 pretty sure these lines (32-39) are not needed.

>>> import cloudinit.util as util
>>> util.mergemanydict([{}, BUILTIN_DS_CONFIG])
{'url': 'http://169.254.169.254', 'retries': 30, 'timeout': 2, 'wait': 2}

>>> util.mergemanydict([{'url': 'http://1.1.1.1/foo'}, BUILTIN_DS_CONFIG])
{'url': 'http://1.1.1.1/foo', 'retries': 30, 'timeout': 2, 'wait': 2}

Am I wrong?

Copy link
Collaborator

Choose a reason for hiding this comment

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

yeah, i'm pretty sure they are not required anymore. As you're just updating BUILTIN_DS_CONFIG. but since we do not use that global anywhere else (except the main, which won't have executed this code), the lines are not needed.

i think they were left over from when you were using a global more.

Copy link
Contributor

Choose a reason for hiding this comment

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

Indeed, just left over code I missed. Its removed now.

Copy link
Collaborator

@smoser smoser left a comment

Choose a reason for hiding this comment

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

I really think I'm down to one change request ('interfaces' rather than 'md' as variable name).

thank you so much for your patience.

@smoser smoser mentioned this pull request Apr 13, 2021
3 tasks
Copy link
Collaborator

@smoser smoser left a comment

Choose a reason for hiding this comment

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

OK. last request.

Can you squash everything and commit with the commit message in the PR?

I'm requesting that for 2 reasons:
a.) so i dont mess it up.
b.) I went to do this and saw:

Co-authored-by: Eric Benner <ebenner@vultr.com>
Co-authored-by: eb3095 <45504889+eb3095@users.noreply.github.com>

We'd like to have real human names in 'Author' and any other such references.

So in my head, ideally the commit would look like the following, but with
@ddymko 's @vultr email address if you could.

Author: David Dymko <dymkod@gmail.com>
Date: Some Date

    Add support for Vultr cloud.

    This PR adds in support so that cloud-init can run on instances 
    deployed on Vultr cloud. This was originally brought up in #628.

    Co-authored-by: Eric Benner <erics-vultr@>

@ddymko
Copy link
Contributor Author

ddymko commented Apr 13, 2021

@smoser I can do that but wouldn't be it be easier to do that from github to squash and merge and update the message?

I also don't use @vultr email for github that won't be a problem will it?

@smoser
Copy link
Collaborator

smoser commented Apr 13, 2021

@smoser I can do that but wouldn't be it be easier to do that from github to squash and merge and update the message?

well 2 things:
a.) when i hit 'squash and merge', i can't change the 'author'
b.) If you update the co-authored-by, i assume you will do it right (and have Eric's permission to do so). If I do it... who knows.

I also don't use @vultr email for github that won't be a problem will it?

i don't think so... although i guess you might lose the link to you if it does that based on known email addresses. I'm ok with you keeping the @gmail if you want.

@ddymko
Copy link
Contributor Author

ddymko commented Apr 13, 2021

Yeah, I don't mind using the @gmail

As for the proposed commit message. I updated the message here:
#827 (comment)

I'll work on cleaning up the commits into a single one

@smoser smoser merged commit 0ae0b1d into canonical:master Apr 13, 2021
smoser added a commit to smoser/cloud-init that referenced this pull request Apr 20, 2021
Vultr support was added under canonical#827.  This enables it by default
in the debian package.
smoser added a commit to smoser/cloud-init that referenced this pull request Apr 20, 2021
Vultr support was added under canonical#827.  This enables it by default
in the debian package.
smoser added a commit that referenced this pull request Apr 27, 2021
Vultr support was added under #827.  This enables it by default
in the debian package.
@ddymko ddymko deleted the vultr-cloudinit branch September 17, 2021 19:03
holmanb pushed a commit to holmanb/cloud-init that referenced this pull request Feb 7, 2024
Vultr support was added under canonical#827.  This enables it by default
in the debian package.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants