Add LXD datasource#1040
Conversation
513a745 to
a5770a0
Compare
|
Thanks @blackboxsw . This is looking really good! Some observations: 2021-09-30 14:43:57,538 - DataSourceLXD.py[DEBUG]: {'meta-data': '#cloud-config\ninstance-id: me\nlocal-hostname: me\ninstance-id: i-87018aed\nlocal-hostname: myhost.internal', '1.0': {'config': {'user.user-data': "#cloud-config\nruncmd:\n - echo 'hi' > /root/hi", 'user.meta-data': 'instance-id: i-87018aed\nlocal-hostname: myhost.internal', 'user.vendor-data': "#cloud-config\nbootcmd:\n - echo 'hi from vendor' > /var/tmp/vendor"}}, 'user-data': "#cloud-config\nruncmd:\n - echo 'hi' > /root/hi", 'vendor-data': "#cloud-config\nbootcmd:\n - echo 'hi from vendor' > /var/tmp/vendor"} This isn't a problem, but in cloud-init query we only report the user metadata. It might be confusing not seeing the pre-existing metadata that we don't overwrite.
regardless of the user. Vendordata and userdata should be redacted from the non-root user. Regardling the |
|
Hmmm, I also just noticed this for each subsequent boot: |
|
Hello! Thank you for this proposed change to cloud-init. This pull request is now marked as stale as it has not seen any activity in 14 days. If no activity occurs within the next 7 days, this pull request will automatically close. If you are waiting for code review and you are seeing this message, apologies! Please reply, tagging mitechie, and he will ensure that someone takes a look soon. (If the pull request is closed and you would like to continue working on it, please do tag mitechie to reopen it.) |
d60c452 to
915aed4
Compare
d051c47 to
0cd95a8
Compare
TheRealFalcon
left a comment
There was a problem hiding this comment.
This looks really good! I left some comments, but they're all very minor.
| # this has to match the builtin list in cloud-init, it is what will | ||
| # be searched if there is no setting found in config. | ||
| DI_DSLIST_DEFAULT="MAAS ConfigDrive NoCloud AltCloud Azure Bigstep \ | ||
| DI_DSLIST_DEFAULT="MAAS ConfigDrive LXD NoCloud AltCloud Azure Bigstep \ |
There was a problem hiding this comment.
So < Jammy, we'll need quilt patches to put LXD after NoCloud?
There was a problem hiding this comment.
For the record, the order in ds-identify doesn't really matter as it is discovered based on the order configuration file on disk in the datasource_list config option in /etc/cloud/cloud.cfg or /etc/cloud/cloud.cfg.d/90_dpkg.cfg (included in cloud images), or cloudinit/settings.py or kernel_cmdline in the function read_datasource_list
you can see the ds-identify sources this order in /run/cloud-init/ds-identify.log even if LXD is listed before NoCloud in ./tools/ds-identify as I had here... you'll still see datasource_list sourced.
/etc/cloud/cloud.cfg.d/90_dpkg.cfg set datasource_list: [ NoCloud, ConfigDrive, LXD, OpenNebula, DigitalOcean, Azure, AltCloud, OVF, MAAS, GCE, OpenStack, CloudSigma, SmartOS, Bigstep, Scaleway, AliYun, Ec2, CloudStack, Hetzner, IBMCloud, Oracle, Exoscale, RbxCloud, UpCloud, VMware, Vultr, None ]
DSLIST=NoCloud ConfigDrive LXD OpenNebula DigitalOcean Azure AltCloud OVF MAAS GCE OpenStack CloudSigma SmartOS Bigstep Scaleway AliYun Ec2 CloudStack Hetzner IBMCloud Oracle Exoscale RbxCloud UpCloud VMware Vultr None
check for 'NoCloud' returned found
check for 'LXD' returned found
Found 2 datasources found=all: NoCloud LXDThat ordering found by ds-identify sets the ordering of python datasources discovery:
root@dev-bb:~# grep LXD /var/log/cloud-init.log
2021-10-30 02:34:33,682 - __init__.py[DEBUG]: Looking for data source in: ['NoCloud', 'LXD', 'None'], via packages ['', 'cloudinit.sources'] that matches dependencies ['FILESYSTEM']
All said though, it's best if we keep this ordering aligned. Because in absence of other defaults, eventually we'd fallback to ds-itentify ordering in the DI_DSLIST_DEFAULT.
| func=read_metadata) | ||
| self.metadata = self._crawled_metadata.get("meta-data", {}) | ||
| user_metadata = self._crawled_metadata.get( | ||
| "config", {}).get("user.meta-data", {}) |
There was a problem hiding this comment.
I know it's not likely, but if config is null in the metadata definition, then it will be None here, and the .get after it will fail.
There was a problem hiding this comment.
+1, reasonable. better to be defensive and schema warn than to fall over with an ugly trace
Well this was wrong to begin with as read_metadata actually returns the config key nested under the API version as in {"1.0": {"config": {...}}} That said, I've changed this to check of LXD_SOCKET_API_VERSION exists from read_metadata. When it does the "config" key is guaranteed to be a dict.
| response = read_metadata(metadata_only=True) | ||
| md = response.get("meta-data", {}) | ||
| if not isinstance(md, dict): | ||
| md = util.load_yaml(md) |
There was a problem hiding this comment.
This can return None which would traceback on the following line.
|
|
||
| dsname = 'LXD' | ||
|
|
||
| _network_config = sources.UNSET |
There was a problem hiding this comment.
Not something we need to change now, but I'd like to get away from setting things to sources.UNSET. Mypy raises hell all over this module because we're setting it to a string here, but the "actual" type after it's been set is a dict...and same with the crawled_metadata line two lines below.
There was a problem hiding this comment.
+1 let's look generally at better mypy cleanup on the 2nd pass here.
Thanks I added a ds["1,0"]["meta-data"] key too so we can see both from cloud-init query. LXD team might change how this is surfaced to LXD datasource mid-cycle so surfacing the raw content we see is probably the best plan forward. If that content changes to cloud-init.(network-config|vendor-data|user-data) keys we will surface those as well.
+1 |
TheRealFalcon
left a comment
There was a problem hiding this comment.
also test comments
| assert True is lxd_ds._get_data() | ||
| assert LXD_V1_METADATA == lxd_ds._crawled_metadata | ||
| # network-config is loaded as YAML | ||
| if "network-config" in LXD_V1_METADATA: |
There was a problem hiding this comment.
Were you planning on parametrizing LXD_V1_METADATA? If not, these if statements seem pointless since it'll only ever be one value.
There was a problem hiding this comment.
Originally, yes. I think it's probably worth me parametrizing this test. will tackle tomorrow.
There was a problem hiding this comment.
strike that dropping parametrization for this pass. I'll add a followup branch with intrumented VM support.
|
Should LXD be added here? https://github.com/canonical/cloud-init/blob/main/cloudinit/settings.py#L21 |
27d7ddf to
74b1e83
Compare
yes it should and should have the same ordering we want LXD after NoCloud & ConfigDrive. |
TheRealFalcon
left a comment
There was a problem hiding this comment.
There's still a couple of comments from my previous review that are unaddressed. I think the None checks and pep8 import stuff are minor enough we can do without, but I think we need to fix the wrong link in the docs (or tell me if I'm misunderstanding it).
|
|
||
| - user.meta-data: YAML metadata which will be appended to base meta-data | ||
| - user.vendor-data: YAML which overrides any meta-data values | ||
| :ref:`network_config_v2` format |
There was a problem hiding this comment.
Did you see this one?
LXD support added in canonical#1040.
LXD support added in canonical#1040.
LXD support added in canonical#1040.
LXD support added in canonical#1040.
LXD support added in canonical#1040.
LXD support added in canonical#1040.
LXD support added in canonical#1040.
LXD support added in #1040.
LXD support added in canonical#1040.
LXD support added in canonical#1040.
LXD support added in canonical#1040.
LXD support added in canonical#1040.
LXD support added in canonical#1040.
Add
DataSourceLXDwhich knows how to talk to the dev-lxd socket to obtain all instance metadata API: https://linuxcontainers.org/lxd/docs/master/dev-lxd.This first branch is to get deliver feature parity with the existing NoCloud datasource which is currently used to intialize LXC instances on first boot.
Introduce a SocketConnectionPool and LXDSocketAdapter to support performing HTTP GETs on the following routes which are surfaced by the LXD host to all containers:
These 4 routes minimally replace the static content provided in the following nocloud-net seed files:
/var/lib/cloud/nocloud-net/{meta-data,vendor-data,user-data,network-config}
The intent of this branch is to set a foundation for LXD socket communication that will allow us to build network hot-plug features by eventually consuming LXD's websocket upgrade route 1.0/events to react to network, meta-data and user-data config changes over time.
In the event that no custom network-config is provided, default to the same network-config definition provided by LXD to the NoCloud network-config seed file.
Supplemental features above NoCloud datasource:
cloud-init query dswhich aids in discoverability of features/tags/labels as well as conditional#cloud-configjinja templates operations based on custom config options.Proposed Commit Message
Test Steps:
Checklist: