-
Notifications
You must be signed in to change notification settings - Fork 937
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
cloud-init: Include user.*
keys in meta-data
file
#14983
Conversation
2397234
to
c21ceef
Compare
user.*
keys on meta-data
file
user.*
keys on meta-data
fileuser.*
keys in meta-data
file
Why is that? |
Cloud-init limitations. The NoCloud DS doesn't support this so it would require changing upstream to my understanding. LXD is the only cloud I'm aware of not following the convention of |
I wonder why cloud-init chose to expose the user vars from /dev/lxd under Its rather unfortunate that we cant offer a consistent experience here. Any ideas @holmanb ? |
Indeed 😢
Just as additional info, and I am not entirely sure of this, but apparentely that accessing values through Edit: Just saw this information was already stated by @stew3254 above |
OK I'm going to hold off on this until we've had confirmation from @holmanb that there's no way of doing this consistently. Thanks |
lxd/device/disk.go
Outdated
// Add other user.* keys to meta-data so that cloud-init has access to this information. | ||
for key, value := range instanceConfig { | ||
if strings.HasPrefix(key, "user.") && !shared.ValueInSlice(key, reservedUserKeys) { | ||
fmt.Println(key) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this old debug ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than using fmt.Sprintf and string concatenation in this function, how about using strings.Builder to build up the contents of the file? As I understand strings.Builder is faster than concatenation and this file might end up being quite large depending on how many vars we're putting into it. It'll also likely be easier to read too :)
c21ceef
to
9e13da3
Compare
@tomponline We had confirmation from another member of the cloud-init team as mentioned in the issue (I am afraid I don't know his GH handle). You can check the cloud-init channel on Mattermost if you'd like 😉 |
Will you provide a link? |
Here it is, I was on my phone and preferred to come to the computer to get the link: https://chat.canonical.com/canonical/pl/ieahsfitgjrd9p6okssof9r4yw |
lxd/device/disk.go
Outdated
@@ -2597,11 +2597,21 @@ func (d *disk) generateVMConfigDrive() (string, error) { | |||
} | |||
} | |||
|
|||
// Append any custom meta-data to our predefined meta-data config. | |||
reservedUserKeys := []string{"user.network-config", "user.user-data", "user.vendor-data", "user.meta-data"} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does not, every user.*
key is added to ds.config
. I have adjusted the implementation to match it.
Your other suggestion regarding the use of strings.Builder was also addressed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please can you use strings.Builder to build up the file data rather than fmt.Sprintf, it should work out clearer than having placeholders.
9e13da3
to
c74036c
Compare
c74036c
to
bacea4e
Compare
lxd/device/disk.go
Outdated
|
||
err = os.WriteFile(filepath.Join(scratchDir, "meta-data"), []byte(metaData), 0400) | ||
// Append strings to the builder | ||
metaDataBuilder.WriteString("instance-id: ") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we do 1 function call per line, e.g.
metaDataBuilder.WriteString("instance-id: "+d.inst.Name()+"\n")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The string build refacotring was done.
bacea4e
to
aa6d6eb
Compare
lxd/device/disk.go
Outdated
|
||
// Add other user.* keys to meta-data so that cloud-init has access to this information. | ||
for key, value := range instanceConfig { | ||
if strings.HasPrefix(key, "user.") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need to skip the legacy cloud-init keys here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, we do not since the LXD datasource doesn't do this when including user.*
keys on ds.config
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hrm that sounds like a bug though. It shouldnt serving up the legacy cloud-init config keys into the template right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I should have been clearer. cloud-init
just includes every defined config key that it has access to into ds.config
. So this includes all user.*
and cloud-init.*
keys with the exception of cloud-init.ssh-keys.*.
I included a duplicate logic here to derive if a hey can be exposed to cloud-init, but I will be moving it to the cloudinit
package on SSH key injection improvement PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am wondering if we should exclude user.meta-data
though since its content is already included on ds.meta_data
. But it could be used to distinguish the source of the meta-data and we are planning to remove it so this shouldn't be a big problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dont think we should include user.user-data, user.vendor-data or user.meta-data as these are already included and are not custom user vars for accessing in the template.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cloud-init just includes every defined config key that it has access to into ds.config. So this includes all user.* and cloud-init.*
Yeah, this sounds like a bug, why would I want to reference user.user-data
or cloud-init.user-data
as a custom user template var?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We cannot do anything about it on the LXD DataSource, as we just show the defined keys and the logic for creating the datasource structure, such as ds.config
, is part of cloud-init
. But we can limit the keys we are including on meta_data
on NoCloud
datasource disk device.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@holmanb Since we already called your attention, we are working on making user.*
keys availlable for use in jinja templates when using the NoCloud datasource on LXD and we are discussing the fact that keys like cloud-init.user-data
and user.network-config
are included in ds.config
, but this seems redundant since these keys are already used as a source of other data available to cloud-init, such as user-data
or network-config
. So the same information is included in more than one place. Do you think this could use some improvement?
621c19d
to
64099c8
Compare
ea8403c
to
cb014b3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thought I had with this now.
Is it possible that by introducing this change we break an existing working instance that uses the NoCloud data store drive by including user.*
keys that contain characters that render the meta-data unparseable by cloud-init?
cb014b3
to
5d93e3c
Compare
Good point. With the implementation you saw it is possible indeed, but single quoting added values prevents this. Single quotes included in the value itself can be escaped by using |
We can't add make these values available through `ds.config` as we do when using the LXD datastore, so this is the next best thing. Signed-off-by: hamistao <[email protected]>
This fits the standard that we use for the LXD datasource, and there is no reason to use a different one in NoCloud. This also hepls to make changes to cloud-init configuration apply on every boot by updating the `instance-id` and allows a user to set a custom `instance-id` through `volatile.cloud-init.instance-id.` Signed-off-by: hamistao <[email protected]>
5d93e3c
to
c4207d2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
We can't add make these values available through
ds.config
as we do when using the LXD datastore, so this is the next best thing.This does raise the risk of adding duplicate keys since
user.meta-data
could include the same key as someuser.*
. Similarly to what is reported in #13853. But this won't be a concern afteruser.meta-data
is removed.Closes #14803