Home directory has wrong ownership if created by lxd in arranging a mount first

Bug #1665943 reported by Robie Basak
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
cloud-init (Ubuntu)
Triaged
Low
Unassigned
lxd (Ubuntu)
Invalid
Undecided
Unassigned

Bug Description

I'm doing something like this in my lxc config:

config:
  raw.idmap: both 1000 1000
devices:
  foo:
    path: /home/ubuntu/foo
    source: /home/<user>/foo
    type: disk

This is to make /home/ubuntu/foo map to my host's /home/<user>/foo.

However, if I do this before starting the container for the first time, then /home/ubuntu inside the container ends up owned by root. The ubuntu user cannot write to it, which causes various problems.

Presumably this is because at the time that cloud-init attempts to create the ubuntu user, /home/ubuntu already exists, so it leaves it alone. But this breaks my use case.

I wonder if there's a way that cloud-init could detect and accomodate this situation?

Workaround: I can fix this with:
  runcmd:
    - chown ubuntu. /home/ubuntu

Using a 16.04 host, lxd 2.0.8-0ubuntu1~ubuntu16.04.2, and a Xenial guest with cloud-init 0.7.8-49-g9e904bb-0ubuntu1~16.04.4.

Revision history for this message
Dan Watkins (oddbloke) wrote :

I've just been able to reproduce this by following these steps:

```
$ lxc init ubuntu:x c1
$ lxc config set c1 raw.idmap "both 1000 1000"
$ lxc config device add c1 foo disk path=/home/ubuntu/foo source=/home/daniel/jjl
$ lxc start c1
$ lxc exec c1 -- ls -lah /home/ubuntu
total 16K
drwxr-xr-x 4 root root 4.0K Feb 19 12:46 .
drwxr-xr-x 3 root root 4.0K Feb 19 12:46 ..
drwx------ 2 ubuntu ubuntu 4.0K Feb 19 12:46 .ssh
drwxr-xr-x 6 ubuntu ubuntu 4.0K Oct 23 2017 foo
```

Creation of the directory is performed by lxd before boot and therefore before cloud-init runs. When cloud-init calls useradd, useradd sees that the directory already exists and therefore doesn't do anything with it (as it treats it as an existing home directory). This means that (a) the user doesn't own the home directory (it is owned by root, the only user in the container when the directory was created), and (b) the contents of the skeleton directory don't get copied over to home directory (because useradd, sensibly, doesn't want to overwrite any existing files). As such, the workaround above is incomplete, because the skeleton directory isn't copied over.

We've just spent some time discussing this at the sprint, and there isn't a clear, quick solution; cloud-init doesn't know that this home directory isn't _meant_ to already exist, and lxd doesn't know that it's bind-mounting somewhere that's going to be a home directory once boot is complete. We discussed that an alternate workaround would be to bind-mount in to a non-home location and then re-bind (using cloud-config) in a runcmd to the eventual destination. A more complete solution might involve a lxd cloud-init data source, or lxd generating cloud-config to perform the aforementioned new workaround transparently.

Changed in cloud-init (Ubuntu):
importance: Undecided → Low
status: New → Triaged
Revision history for this message
Dan Watkins (oddbloke) wrote :

(I've added lxd to the bug, as it's also a component in the issue.)

Revision history for this message
Stéphane Graber (stgraber) wrote :

Yeah, not much LXD can do about this unfortunately. We do create any missing intermediate directories as can be seen in this case, but there's no good way to know what the owner of every one of those intermediate directories should be, nor would it help here as skel still wouldn't get applied.

You pretty much have two options:
 1) Only add the device after the container initial's start
 2) Bind-mount this stuff somewhere other than the user's home directory

In the second case, I guess you could have a cloud-init snippet which then sets up a systemd unit to bind-mount that inside the container from /srv/whatever to /home/ubuntu/foo.

Changed in lxd (Ubuntu):
status: New → Invalid
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.