Friday, October 7, 2022

[SOLVED] How can I run shell commands for non-root user during cloud-init configuration?

Issue

During installation of a cloud VM with cloud-init e.g. when installing Rust toolchain

#cloud-config
package_upgrade: true
packages:
- apt-transport-https
- build-essential
- cmake
runcmd:
- export RUSTUP_HOME=/opt/rust
- export CARGO_HOME=/opt/rust
- curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | bash -s -- -y --no-modify-path --default-toolchain stable --profile default

I also want to execute the toolchain configuration rustup default stable in user space so that it is ready to use when user first signs in.


Solution

One key element is to determine the (target/adminsitration) user, that is currently installed on the VM with export USER=$(awk -v uid=1000 -F":" '{ if($3==uid){print $1} }' /etc/passwd), so that environment variable $USER holds the username during the cloud-init configuration process. Then to use sudo -H -u $USER to run a shell in target user's context. Also import is to enhance the user's environment to include the installed toolchain - permanently with extending .profile or alike as well as temporarily while executing this shell operation.

#cloud-config
package_upgrade: true
packages:
- apt-transport-https
- build-essential
- cmake
runcmd:
- export USER=$(awk -v uid=1000 -F":" '{ if($3==uid){print $1} }' /etc/passwd)
- export RUSTUP_HOME=/opt/rust
- export CARGO_HOME=/opt/rust
- curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | bash -s -- -y --no-modify-path --default-toolchain stable --profile default
- echo '\n\n# added by cloud init\nsource /opt/rust/env' >> /home/$USER/.profile
- sudo -H -u $USER bash -c 'source /opt/rust/env && rustup default stable'

check out complete post with background information



Answered By - Kai Walter
Answer Checked By - Willingham (WPSolving Volunteer)