Rust: Permissions Question
Scenario
The rust image currently has umask 022 set.
$ docker run -it --rm --user root mcr.microsoft.com/devcontainers/rust:1-1-bullseye
root ➜ / $ umask
0022
root ➜ / $ grep ^rustlang /etc/group
rustlang:x:999:vscode
Should a build step, such as a feature use cargo install the resulting permissions prevent group write usage.
root ➜ / $ cargo install --quiet bacon
root ➜ / $ ls -ld $CARGO_HOME/registry
drwxr-sr-x 5 root rustlang 4096 Nov 14 19:04 /usr/local/cargo/registry
Which then in turn breaks user-level usage of other cargo commands.
root ➜ / $ su vscode
vscode ➜ / $ cd
vscode ➜ ~ $ cargo install cargo-watch
Updating crates.io index
Downloaded cargo-watch v8.4.1
error: failed to download replaced source registry `crates-io`
Caused by:
failed to open `/usr/local/cargo/registry/cache/index.crates.io-6f17d22bba15001f/cargo-watch-8.4.1.crate`
Caused by:
Permission denied (os error 13)
Question
What is the correct course of action?
- Set
umask 002here, at the image level? Perhaps in/etc/profile? - Set
umask 002inside featureinstall.shscripts?
Hi 👋
Thanks for opening a detailed issue.
What is the correct course of action?
As cargo is installed by the Rust Feature, it makes sense to update permissions in the Feature. However, looking at https://github.com/devcontainers/features/blob/main/src/rust/install.sh#L156, I do see umask 0002 set. However, I think there's a bug in this line https://github.com/devcontainers/features/blob/main/src/rust/install.sh#L163, it updates permissions only for the specific directory, instead of doing that recursively.
I believe, updating chmod g+r+w+s "${RUSTUP_HOME}" "${CARGO_HOME}" to 👇 should help.
chmod -R g+r+w+s "${RUSTUP_HOME}" "${CARGO_HOME}"
@CodeMan99 Let me know if that makes sense to you, thanks!
Opened https://github.com/devcontainers/features/pull/754
Let me know if that makes sense to you, thanks!
I am not completely sure to be honest. I don't think the feature creates $CARGO_HOME/regitstry. I believe that folder is only created after usage of cargo install.
So the rust feature still isn't responsible for the creation of the problem directory.
I think I missed the part where you switch the users between running cargo install command. As the registry is created by the root user, it won't automatically allow the vscode user to use it unless the permissions are updated.
Curious, @CodeMan99 why do you switch users? I believe these Features/images were created hoping that the same user is been used for lifecycle of the dev container. Else, it would cause permission issues as seen in this issue ^
Curious, @CodeMan99 why do you switch users? I believe these Features/images were created hoping that the same user is been used for lifecycle of the dev container. Else, it would cause permission issues as seen in this issue ^
Usage of root is build-like usage. For example, using cargo install inside a feature install.sh. My understanding that executing that script will always be root. Is that an incorrect assumption?
Then, during development cargo will need write access to that folder. Including cargo build. The $CARGO_HOME/registry folder is created with the correct group (rustlang) in my example.
My understanding that executing that script will always be root. Is that an incorrect assumption?
Yes, that is correct. All Feature's install scripts are run with the root user.
With the Rust Feature, CARGO_HOME directory is correctly owned by the vscode user. However, as you are running cargo commands with the root user, it creates the registry folder with root permissions. The non-root user cannot modify the files that were created by root as basically you can't mix something like sudo cargo install and cargo install.
Hence, I believe you should do either of the following to fix the issue -
- Always stick with a single user
vscodeorroot, else, you will run into this issue- Else, manually give permissions for the
registrydirectory to thevscodeuser
- Else, manually give permissions for the
- When running with
root, make sure to run commands asvscodeuser (eg. vscode -c "cargo install bacon")
However, as you are running
cargocommands with therootuser, it creates theregistryfolder withrootpermissions.
The folder is created with exactly these permissions.
root ➜ / $ cargo install --quiet bacon
root ➜ / $ ls -ld $CARGO_HOME/registry
drwxr-sr-x 5 root rustlang 4096 Nov 14 19:04 /usr/local/cargo/registry
The vscode user is added to the rustlang group by the rust feature. The only thing that needs to change is the write permissions for the group.
- Always stick with a single user
vscodeorroot, else, you will run into this issue
This advice does not resolve the issue. Example devcontainer.json file:
{
"image": "mcr.microsoft.com/devcontainers/rust:1-1-bullseye",
"features": {
"ghcr.io/lee-orr/rusty-dev-containers/bacon:0": {}
}
}
This very simple configuration creates the problem:
cargo install baconis run in the install.sh of the feature.- The
remoteUserisvscode.
So again, what is the correct course of action?
Use of umask 002 in the image's /etc/profile file? Or use of umask 002 in the install.sh script of any given feature?
Let me clarify a little - "the course of action" is a question of who needs to own this knowledge.
- Setting the
umask 002in/etc/profilewould be an image-wide change, affecting all system user's default. Only image maintainers would be required to have knowledge. - Setting the
umask 002in any given feature is a very specific change that requires documentation. Both documentation maintainers and community feature maintainers are required to have knowledge. - Just providing a guideline puts the ownership of this issue in the hands of any user that wants to use
cargo installas a build step (Dockerfile or using a feature).
A configuração de umask influencia as permissões padrão atribuídas a novos arquivos e diretórios criados pelos processos no sistema. O valor padrão, umask 022, significa que as permissões padrão são 755 para diretórios e 644 para arquivos. Se você deseja alterar o valor padrão do umask, pode fazer isso no arquivo de perfil (como .bashrc ou .bash_profile) do usuário ou no script de inicialização do contêiner.
Aqui está um exemplo de como você poderia configurar o umask em um arquivo de perfil (por exemplo, .bashrc) no Dockerfile:
FROM mcr.microsoft.com/devcontainers/rust:1-1-bullseye
Configurando o umask no perfil do usuário
RUN echo "umask 022" >> /etc/skel/.bashrc
Configurando o umask para o usuário existente 'vscode'
RUN echo "umask 022" >> /home/vscode/.bashrc
Dockerfile
Copy code FROM mcr.microsoft.com/devcontainers/rust:1-1-bullseye
Configurando o umask no perfil do usuário
RUN echo "umask 022" >> /etc/skel/.bashrc
Configurando o umask para o usuário existente 'vscode'
RUN echo "umask 022" >> /home/vscode/.bashrc Este Dockerfile adiciona a linha umask 022 ao final do arquivo .bashrc no diretório /etc/skel (um esqueleto usado para criar novos usuários) e ao arquivo .bashrc do usuário existente 'vscode'. Isso garantirá que o umask seja configurado corretamente para qualquer novo usuário que seja criado e para o usuário existente.
Lembre-se de que esta é uma sugestão geral, e a configuração específica pode depender dos requisitos e das práticas recomendadas em sua organização. Certifique-se de ajustar conforme necessário para atender às suas necessidades específicas.
Parece que o problema está relacionado às permissões do diretório /usr/local/cargo/registry. Você pode otimizar isso ajustando as permissões para garantir que o usuário vscode tenha as permissões apropriadas para acessar e gravar nesse diretório. Uma abordagem possível seria adicionar o usuário vscode ao grupo rustlang e ajustar as permissões do diretório.
Aqui estão as etapas que você pode adicionar ao seu Dockerfile:
FROM mcr.microsoft.com/devcontainers/rust:1-1-bullseye
# Adiciona o usuário 'vscode' ao grupo 'rustlang'
RUN usermod -aG rustlang vscode
# Define as permissões do diretório '/usr/local/cargo/registry'
RUN chown root:rustlang /usr/local/cargo/registry && chmod 775 /usr/local/cargo/registry
# Configura o umask no perfil do usuário
RUN echo "umask 022" >> /etc/skel/.bashrc
RUN echo "umask 022" >> /home/vscode/.bashrc
FROM mcr.microsoft.com/devcontainers/rust:1-1-bullseye
# Adiciona o usuário 'vscode' ao grupo 'rustlang'
RUN usermod -aG rustlang vscode
# Define as permissões do diretório '/usr/local/cargo/registry'
RUN chown root:rustlang /usr/local/cargo/registry && chmod 775 /usr/local/cargo/registry
# Configura o umask no perfil do usuário
RUN echo "umask 022" >> /etc/skel/.bashrc
RUN echo "umask 022" >> /home/vscode/.bashrc
Estas são as principais alterações:
usermod -aG rustlang vscode: Adiciona o usuáriovscodeao gruporustlang.chown root:rustlang /usr/local/cargo/registry: Define o proprietário do diretório/usr/local/cargo/registrycomoroote o grupo comorustlang.chmod 775 /usr/local/cargo/registry: Define as permissões do diretório como775, permitindo que o gruporustlangtambém escreva no diretório.
Depois de adicionar essas linhas ao seu Dockerfile e reconstruir a imagem, o usuário vscode deve ter as permissões adequadas para instalar pacotes Cargo sem erros de permissão. Certifique-se de que essas alterações atendam aos requisitos específicos do seu ambiente.
Peço desculpas pela confusão anterior. Parece que mesmo após adicionar o usuário vscode ao grupo rustlang e ajustar as permissões do diretório, ainda ocorrem problemas de permissão.
A solução proposta anteriormente para alterar as permissões do diretório pode não ser suficiente. É possível que as permissões específicas do arquivo index.crates.io-6f17d22bba15001f/cargo-watch-8.4.1.crate não estejam permitindo que o usuário vscode acesse.
Uma solução mais robusta pode ser garantir que todos os arquivos e diretórios dentro de /usr/local/cargo/registry tenham as permissões adequadas para o grupo rustlang. Você pode fazer isso recursivamente usando o comando chmod:
FROM mcr.microsoft.com/devcontainers/rust:1-1-bullseye
# Adiciona o usuário 'vscode' ao grupo 'rustlang'
RUN usermod -aG rustlang vscode
# Define as permissões do diretório '/usr/local/cargo/registry'
RUN chown -R root:rustlang /usr/local/cargo/registry && chmod -R 775 /usr/local/cargo/registry
# Configura o umask no perfil do usuário
RUN echo "umask 022" >> /etc/skel/.bashrc
RUN echo "umask 022" >> /home/vscode/.bashrc
FROM mcr.microsoft.com/devcontainers/rust:1-1-bullseye
# Adiciona o usuário 'vscode' ao grupo 'rustlang'
RUN usermod -aG rustlang vscode
# Define as permissões do diretório '/usr/local/cargo/registry'
RUN chown -R root:rustlang /usr/local/cargo/registry && chmod -R 775 /usr/local/cargo/registry
# Configura o umask no perfil do usuário
RUN echo "umask 022" >> /etc/skel/.bashrc
RUN echo "umask 022" >> /home/vscode/.bashrc
Nesta versão, a alteração chmod -R 775 /usr/local/cargo/registry é usada para aplicar as permissões recursivamente a todos os arquivos e subdiretórios dentro de /usr/local/cargo/registry. Isso deve garantir que o usuário vscode tenha acesso suficiente para instalar pacotes Cargo sem problemas de permissão.
Após fazer essas alterações e reconstruir a imagem, tente novamente instalar o cargo-watch como o usuário vscode. Isso deve resolver os problemas de permissão.
Opened devcontainers/features#754
This PR is what I want.
Now I have an error using the cargo build command due to permission being denied. Perhaps it's because I used cargo to install some tools in the dockerfile before run rust feature script, so the gid in the registry directory is root
non-root@702362714ab7:~$ ls -l $CARGO_HOME
total 24
drwxrwxrwx 1 root root 4096 May 22 08:04 bin
-rwxr-xr-x 1 root rustlang 690 May 21 16:06 config.toml
-rw-rw-rw- 1 root root 308 May 14 03:57 env
drwxrwxr-x 1 root root 4096 May 22 08:04 registry
non-root@702362714ab7:~$ ls -l $RUSTUP_HOME
total 20
drwxrwxrwx 1 root root 4096 May 22 09:04 downloads
-rw-rw-rw- 1 root root 151 May 14 03:58 settings.toml
drwxrwxrwx 1 root root 4096 May 22 09:04 tmp
drwxrwxrwx 1 root root 4096 May 22 09:04 toolchains
drwxrwxrwx 1 root root 4096 May 22 09:04 update-hashes
Can this PR be merged?