VFS idmap shifting - do you need to enable it?

In release notes for Incus 0.1 it is mentioned that VFS idmap shifting should automatically be used by Incus when present.

But when I share a folder between host and container, files created on host are seen inside container as owned by nobody. That’s the default behavior without shifting.

How can I enable VFS idmap shifting in Incus? Or maybe Ubuntu 22.04 with kernel 6.2.0-39 is too old for that?

I’m trying to avoid setting raw.idmap manually.

I think it is enabled by default for root filesystem of containers, but for mounts you should set the attribute shift to true when creating your share (default to false according to the documentation).

Thanks, that worked - kinda :slightly_smiling_face:

It seems that recent containers from community repository have wrong GID for group ubuntu. The 1000 gid is for group lxd, so with shift=true inside the container shared folder and files in it are now owned by ubuntu:lxd.

This is what I did:

incus launch images:ubuntu/jammy/cloud test
incus config device add test shared_folder disk shift=true source=~/Downloads path=/home/ubuntu/Downloads

ll inside container showed:

drwxr-xr-x 2 ubuntu lxd    4096 Dec 21 09:17 Downloads/

And getent group ubuntu shows 1002.

The most important thing is UID/GID matching, but from UI perspective, I guess it depends on what is configured on your container user database (/etc/passwd) since it’s not linked to the one on your host.
It should be working, you can check with ls -n [options] command-line, the UID/GID should be correct.

You’re right, UID/GID is being matched to 1000:1000 from the host.

What’s interesting is that this does not match to default user ubuntu in the recent container images:ubuntu/jammy/cloud, for whom cat /etc/passwd | grep ubuntu shows
ubuntu:x:1000:1002:Ubuntu:/home/ubuntu:/bin/bash.

Anyway, your solution is correct, thank you :smiling_face_with_three_hearts:

1 Like

I agree that this can be a bit confusing at first, but nonetheless glad it’s working for you :wink:

@monstermunchkin sorry to bother you, but is this expected behavior that default user ubuntu with UID 1000 in the recent container images:ubuntu/jammy/cloud has his default group ubuntu with GID 1002 instead of 1000?

Because GID 1000 is used for lxd group, when I enable shift for a shared folder with container, then inside container this folder belongs to ubuntu:lxd.

In other words, when I create a container and share a shifted folder with it:

incus launch images:ubuntu/jammy/cloud test
incus config device add test shared_folder disk shift=true source=~/Downloads path=/home/ubuntu/Downloads

ll inside container shows:

drwxr-xr-x 2 ubuntu lxd    4096 Dec 21 09:17 Downloads/

I created a little script that can be put in a profile to change GID of default user ubuntu in containers images:ubuntu/jammy/cloud from 1002 to 1000. This fixes ownership of shared folders inside containers with shift=true enabled. They now belong to ubuntu:ubuntu and not ubuntu:lxd.

As you can see, script is placed in /var/lib/cloud/scripts/per-once/ folder, which means it’s executed by cloud-init automatically per once. Per once means that the script will be run once on first boot of an instance, and it won’t be run again even if you clone an instance or create a new instance from a saved image.

In short, this script moves a group that has GID 1000 to the first free GID and assigns 1000 to group ubuntu, then fixes ownership of user’s home folder.

config:
  cloud-init.user-data: |
    #cloud-config
    write_files:
    - path: /var/lib/cloud/scripts/per-once/change_gid.sh
      permissions: 0755
      content: |
        #!/bin/bash
        users_uid=1000
        user=$( getent passwd ${users_uid} | cut -d: -f1 )
        users_gid=$( getent passwd ${user} | cut -d: -f4 )
        if [[ -n ${user} && ! ${users_uid} == ${users_gid} ]]; then
          group_to_move=$( getent group ${users_uid} | cut -d: -f1 )
          if [[ -n ${group_to_move} ]]; then
            for gid in {1000..6000}; do
              return_value=$( getent group ${gid} )
              if [[ -z ${return_value} ]]; then
                groupmod -g ${gid} ${group_to_move}
                break
              fi
            done
          fi
          users_group=$( getent group ${users_gid} | cut -d: -f1 )
          groupmod -g ${users_uid} ${users_group}
          chown -R ${users_uid}:${users_uid} $( getent passwd ${user} | cut -d: -f6 )
        fi