canonical / cloud-init

Official upstream for the cloud-init: cloud instance initialization
https://cloud-init.io/
Other
2.86k stars 855 forks source link

write_files runs before users/groups, renders "owner" useless #2573

Closed ubuntu-server-builder closed 1 year ago

ubuntu-server-builder commented 1 year ago

This bug was originally filed in Launchpad as LP: #1486113

Launchpad details
affected_projects = []
assignee = None
assignee_name = None
date_closed = 2023-03-23T19:47:09.488638+00:00
date_created = 2015-08-18T15:49:28.532879+00:00
date_fix_committed = 2023-03-23T19:47:09.488638+00:00
date_fix_released = 2023-03-23T19:47:09.488638+00:00
id = 1486113
importance = medium
is_complete = True
lp_url = https://bugs.launchpad.net/cloud-init/+bug/1486113
milestone = None
owner = minfrin-y
owner_name = Graham Leggett
private = False
status = fix_released
submitter = minfrin-y
submitter_name = Graham Leggett
tags = []
duplicates = [1231541, 1745978, 1781549, 1942152]

Launchpad user Graham Leggett(minfrin-y) wrote on 2015-08-18T15:49:28.532879+00:00

When the following cloud-init script is run the expectation is that a group called ssl-cert-client is created, and this group is applied to the file that is written via the "owner" tag.

groups:

What happens instead is that the writing of the file is attempted before the creation of the group, and this file write fails because the group ssl-cert-server does not yet exist.

The two tasks need to be swapped round before they are practically useful.

ubuntu-server-builder commented 1 year ago

Launchpad user Joshua Powers(powersj) wrote on 2017-07-27T21:44:07.953986+00:00

Thank you for taking the time to report this bug. In an effort to keep an up-to-date and valid list of bugs to work on, I have reviewed this report verifying it still requires effort and occurs on a supported version of Ubuntu.

I do agree that the situation you spell out occurs. Consider the following simplier example:

userdata.yaml:

cloud-config

groups:

This should write a file to /root/testfile with the permissions set to root:testgroup.

$ lxc init ubuntu-daily:x x $ lxc config set x user.user-data - < userdata.yaml $ lxc start x $ lxc exec x2 -- ls -l /root/testfile -rw-r----- 1 root root 9 Jul 27 21:42 /root/testfile

ubuntu-server-builder commented 1 year ago

Launchpad user Scott Moser(smoser) wrote on 2018-07-13T16:17:52.871297+00:00

To be fair, this isn't completely useless. If we simply moved the writing of files to after users were created, then less of the boot could be affected by your written files.

As a (possibly contrived) example, as it is right now you can use write_files to replace 'adduser' and then cloud-init would call the replaced version of adduser when adding users. If write_files happened later you could not do that.

I would like to get this to work though. 2 options: a.) add 'write_files_late' that runs after users are created (or write_files_early and write_files) basically 2 different points in boot. b.) magically determine if 'owner' isn't around that we should re-try this after the usergroups are created. c.) extend format of write_files to include 'early' or 'late' that would indicate to cloud-init explicitly that it should happen after users or before users creation.

ubuntu-server-builder commented 1 year ago

Launchpad user Pedro A. Aranda(paaguti-p) wrote on 2018-07-14T10:30:43+00:00

I accept your reasoning. And following it, I would add the write_files_late for “my” purpose ;-) and leave the current write_files as is. Either this, or include a new sub item in users, like users - - write_files to write files of a specific user...

Don’t know how you feel about this alternative. But it seems logical and would be backwards-compatible

Best, /PA

Enviado desde mi iPad

El 13 jul 2018, a las 18:17, Scott Moser ssmoser2+ubuntu@gmail.com escribió:

To be fair, this isn't completely useless. If we simply moved the writing of files to after users were created, then less of the boot could be affected by your written files.

As a (possibly contrived) example, as it is right now you can use write_files to replace 'adduser' and then cloud-init would call the replaced version of adduser when adding users. If write_files happened later you could not do that.

I would like to get this to work though. 2 options: a.) add 'write_files_late' that runs after users are created (or write_files_early and write_files) basically 2 different points in boot. b.) magically determine if 'owner' isn't around that we should re-try this after the usergroups are created. c.) extend format of write_files to include 'early' or 'late' that would indicate to cloud-init explicitly that it should happen after users or before users creation.

-- You received this bug notification because you are subscribed to a duplicate bug report (1781549). https://bugs.launchpad.net/bugs/1486113

Title: write_files runs before users/groups, renders "owner" useless

Status in cloud-init: Confirmed

Bug description: When the following cloud-init script is run the expectation is that a group called ssl-cert-client is created, and this group is applied to the file that is written via the "owner" tag.

groups:

  • ssl-cert-server
  • ssl-cert-client write_files:

    • encoding: gzip content: !!binary | $(echo ${rsa_client_private_key} | gzip - | openssl base64 | sed -e "s/^/ /") owner: root:ssl-cert-client path: /etc/ssl/certs/${resourcegroup}-${machine}.${domain}-client.key permissions: '0640'

    What happens instead is that the writing of the file is attempted before the creation of the group, and this file write fails because the group ssl-cert-server does not yet exist.

    The two tasks need to be swapped round before they are practically useful.

To manage notifications about this bug go to: https://bugs.launchpad.net/cloud-init/+bug/1486113/+subscriptions

ubuntu-server-builder commented 1 year ago

Launchpad user Adam Spiers(adam.spiers) wrote on 2019-01-10T18:20:22.332231+00:00

This was first reported in 2013 in bug #1231541 and I still see the issue :-/ Is there any reason not to simply just swap the order? Why would it ever be a problem to run write_files after users_groups?

ubuntu-server-builder commented 1 year ago

Launchpad user Scott Moser(smoser) wrote on 2019-01-11T07:04:49+00:00

On Thu, Jan 10, 2019, 1:30 PM Adam Spiers <aspiers@suse.com wrote:

This was first reported in 2013 in bug #1231541 and I still see the issue :-/

I understand the frustration.

Is there any reason not to simply just swap the order?

Backwards compatibility

Why

would it ever be a problem to run write_files after users_groups?

The simple example of writing a file to /etc/skel that you wanted to have copied into created users' do.

ubuntu-server-builder commented 1 year ago

Launchpad user manuel(boillodmanuel) wrote on 2020-04-15T17:01:12.690788+00:00

Hello,

I wonder why there is a backwards compatibility issue.

As write_files runs before users/groups, the current version of write_files should use existing users or group. If not, the write_files should fail.

If we swap the order to runs write_files after users/groups, the existing write_files should still works, don't they?

ubuntu-server-builder commented 1 year ago

Launchpad user Dan Watkins(oddbloke) wrote on 2020-04-15T17:23:12+00:00

On Wed, Apr 15, 2020 at 05:01:12PM -0000, manuel wrote:

I wonder why there is a backwards compatibility issue.

As write_files runs before users/groups, the current version of write_files should use existing users or group. If not, the write_files should fail.

If we swap the order to runs write_files after users/groups, the existing write_files should still works, don't they?

The example Scott gave would not generate a traceback, but it would fail in the sense that the created users would not have the contents that were added to /etc/skel. The proposed change in order would lead to a regression for users who are using this (or similar) configurations.

ubuntu-server-builder commented 1 year ago

Launchpad user manuel(boillodmanuel) wrote on 2020-04-16T15:58:49.584687+00:00

Hi Dan,

Thanks for the quick reply. I read carefully the Scott answer, and I got it :) It's somehow weird, but I understand that it can break compatibility.

I guess 95% of people will benefits from creating users before write_files, but it can break something for other 5%.

So, it's an 5y old issue, and I see only 2 exits:

ubuntu-server-builder commented 1 year ago

Launchpad user Ian T Price(iantprice) wrote on 2020-04-27T16:20:57.143761+00:00

I've just hit this seven year old issue and wasted a good morning trying to figure it out - many thanks to @Odd_Bloke on FreeNode #cloud-init for steering me here.

Scott's Option 2a is the obvious answer here to add the functionality and still maintain backwards compatability.

Plus 1 for 2a

ubuntu-server-builder commented 1 year ago

Launchpad user Brian Candler(b-candler) wrote on 2020-04-28T09:02:20.363009+00:00

It's not just write_files. It appears that runcmd also runs before users/groups, so you can't do this as a workaround:

runcmd:

My comments:

  1. It would be helpful if the order in which modules are run were documented.

  2. I'd like users/groups to be created early - controlled by a flag if backwards-compatibility is required. Otherwise: write_files, runcmd etc are unable to depend on the existence of a uid/gid.

The only downside I can see is that extra files dropped in /etc/skel wouldn't be honoured - but these could always be be created explicitly using write_files.

ubuntu-server-builder commented 1 year ago

Launchpad user Dan Watkins(oddbloke) wrote on 2020-04-28T14:16:32+00:00

On Tue, Apr 28, 2020 at 09:02:20AM -0000, Brian Candler wrote:

It's not just write_files. It appears that runcmd also runs before users/groups, so you can't do this as a workaround:

This is not the case in cloud-init's default configuration.

  1. It would be helpful if the order in which modules are run were documented.

The order of modules is configured in /etc/cloud/cloud.cfg, so you can see exactly the order your image is configured to use there. The template that is used to generate cloud.cfg upstream is https://github.com/canonical/cloud-init/blob/master/config/cloud.cfg.tmpl

(I agree that we should surface this info in our documentation!)

  1. I'd like users/groups to be created early - controlled by a flag if backwards-compatibility is required. Otherwise: write_files, runcmd etc are unable to depend on the existence of a uid/gid.

On an Ubuntu system (which uses the upstream order), these are the first set of modules executed:

cloud_init_modules:
 - migrator
 - seed_random
 - bootcmd
 - write-files
 - growpart
 - resizefs
 - disk_setup
 - mounts
 - set_hostname
 - update_hostname
 - update_etc_hosts
 - ca-certs
 - rsyslog
 - users-groups
 - ssh

As you can see, write-files is the only one that is likely to be user/group-sensitive. (runcmd is in the next stanza, executed later in boot.)

If your image is configured this way and you're still seeing an issue using runcmd, please file a separate bug. :)

ubuntu-server-builder commented 1 year ago

Launchpad user Henry Ford(hrford) wrote on 2020-10-30T21:18:00.459642+00:00

Hi,

Regarding comment from manuel (boillodmanuel): I feel I'm one of the 95% of users where write_files would be very useful to occur after the users module.

Currently, my work-around is: runcmd:

...which runs over the same files created before, but now applies the correct permissions, at least on an EC2 with Amazon Linux 2.

My question is, as this bug is still "open" is there an official work-around?

ubuntu-server-builder commented 1 year ago

Launchpad user Dan Watkins(oddbloke) wrote on 2020-11-02T19:15:50.272008+00:00

The workaround is to use runcmd (which runs later in boot) to either (a) write the files in their entirety, or (b) fix up the owners/permissions/locations of the files. (Using it to rerun the entire module is good if it works for you, though I'd want to spend more time thinking about potential consequences before recommending it myself. :)

The exact shape of the workaround depends on what you're doing, really: if you have large base64 encoded files then using write_files to get them onto disk and then runcmd to shift them around probably makes sense; if you're writing out a single small file, then just doing it in runcmd probably makes most sense.

If anyone is interested in contributing a doc fix to mention this ordering issue in the write_files docs (https://github.com/canonical/cloud-init/blob/master/cloudinit/config/cc_write_files.py#L44-L60) and/or a more general fix to introduce a write_files stage executed later in boot (as suggested by Scott in comment #2), both would be most welcome! (In the latter case, though, please do reach out so we can determine a specific path forward!)

ubuntu-server-builder commented 1 year ago

Launchpad user Lucen Dio(lucendio) wrote on 2021-07-04T21:27:11.972891+00:00

Hi everyone,

I created https://github.com/canonical/cloud-init/pull/916 to start solutioning. I tried to summarize the different approaches and I'd love to get your feedback. Maybe we can continue the conversation over there. It would also be the chance to share other approaches that come to your mind!

ubuntu-server-builder commented 1 year ago

Launchpad user Brett Holman(holmanb) wrote on 2023-03-23T19:47:04.165934+00:00

This was resolved in the aforementioned pull request with the addition of writing deferred files.