I was solving a problem for Testling and run into difficulties. Every Github user who signs up for Testling gets a Unix user on Testling's servers. When they commit code, we get a Github hook, switch to their user, clone their repo, and run their tests.
To quickly get it running, I copied /
to /chroot
and then when the hook comes, I just chroot
to this environment, then su - username
, and then run a script that run the tests. I do it all with a single command:
sudo chroot /chroot su - user -c "command_that_runs_testling_tests <args>"
This is pretty nifty!
This command combines four commands together - sudo
, chroot
, su
and cmd
. Each command calls the next one and when the last command finishes it returns back to the shell and exits (instead of being left inside of chroot in an interactive shell mode as user
.)
Now here's the problem I run into.
For some reason user
's environment never got executed. Our test runners setup PATH
s and other customizations but .bash_profile
was never ran.
The solution that I found was to run .bash_profile
yourself, like this:
sudo chroot /chroot su - user -c ". ~/.bash_profile; cmd args"
This does what I wanted and runs cmd args
inside of chroot located at /chroot
as user
, initializes .bash_profile
and after running cmd
it quits.
On Sourcing ~/.bash_profile
Some people couldn't understand why I was sourcing ~/.bash_profile
. The reason is because I was unable to find another way to invoke the login shell and have the environment initialized.
I tried this:
sudo chroot /chroot su -l user -c "cmd args"
And it just wouldn't execute ~/.bash_profile
. Su's man page says that -l
invokes a login shell, however I don't see that happening. Here's the transcript that demonstrates it:
pkrumins$ pwd /chroot pkrumins$ sudo cat ./home/testuser1/.bash_profile echo "moo" PATH="/test/bin" pkrumins$ sudo chroot /chroot su -l testuser1 -c 'echo $PATH' /bin:/usr/bin pkrumins$ sudo chroot /chroot su -l testuser1 moo testuser1$ echo $PATH /test/bin testuser1$ ^D logout pkrumins$ sudo chroot /chroot su -l testuser1 -c '. ~/.bash_profile; echo $PATH' moo /test/bin pkrumins$ sudo chroot /chroot su -l testuser1 moo testuser1$ /bin/bash -l -c 'echo $PATH' moo /test/bin
I don't know what is happening here. Bash profile file never gets run .The only way that I found to get the environment loaded is by sourcing the initialization files yourself. It works and I'm happy.
Until next time!