'virtctl works when executed via command line but not from php exec()
I am trying to run kubectl virt commands to manage my virtual machine via PHP. First, I log in to my server with phpseclib with the following code:
$ssh = new SSH2('localhost');
if (!$ssh->login('root', 'rootPassword')) {
throw new \Exception('Login failed');
}
This part works fine, and when I try to run $ssh->exec('whoami && echo $PATH')
, I get the following output:
root
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
But, whenever I try to run kubectl virt
via PHP, I get the following output:
error: unknown command "virt" for "kubectl"
kubectl
and kubectl virt
work perfectly fine when I run them via terminal but somehow do not work with PHP exec(). I also tried to check the $PATH
via terminal and I get a different output:
/root/.krew/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
I thought that it may be because of $PATH
but the interesting part is when I try to run sudo kubectl virt
via terminal I also get the same error:
error: unknown command "virt" for "kubectl"
At that point, I am completely lost and don't even know where to look for a problem. I am thankful for all the answers.
Solution 1:[1]
When you are issuing ad-hoc ssh commands, you are not using interactive shell, and depending on your default shell behavior it may or may not load your .bashrc file . See https://serverfault.com/questions/936746/bashrc-is-not-sourced-on-ssh-command and Running command via ssh also runs .bashrc? for more details.
So by default, krew modifies your PATH
variable, and appends it's bin path to it, i.e. my config contains export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"
. But what exactly is kubectl plugin? Usually it's just a single binary, with kubectl-plugin_name name. So by invoking which kubectl-virt
you can easily know where is your virt binary located and invoke it directly, so something like
$ssh->exec('~/.krew/bin/kubectl-virt')
should work
The other way is to modify PATH all by yourself, setting PATH=$PATH:~/.krew/bin
should make it work, at least in my case
ssh localhost 'PATH=$PATH:~/.krew/bin kubectl virt'
worked nicely.
You can try to force loading of .bashrc in your shell configuration, but personally i think it's a bad practice, and ssh commands are not usually loading rc files for a reason, command execution speed and consistency between systems are the first things that come to mind.
Regarding sudo, it's actually not that surprising, because without -E
or -i
flags it won't load your current environment / won't start interactive shell. See https://unix.stackexchange.com/questions/228314/sudo-command-doesnt-source-root-bashrc for more info
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Andrew |