qm guest exec or the pvesh create /nodes/{node}/qemu/{vmid}/agent/exec how to send array

Craig St George

Well-Known Member
Jul 31, 2018
114
14
58
62
HI I m provisioning Mikrotik Routers and as there is No cloud-init M trying to use the guest exec
when I use guest exec by hand via socat I can get it to work below

But I m having a hell time with qm guest exec 689 or via the API or
pvesh create /nodes/{node}/qemu/{vmid}/agent/exec

basically I need to send no PATH just attributes called input-data

like

input-data ':ip address add address=192.168.201.100/24 interface=wan

OR maybe my question is HOW to pass a string that gets converted to an array as I see the work is done by
so how to pass that array

/usr/share/perl5/PVE/QemuServer/Agent.pm
sub qemu_exec {
my ($vmid, $cmd) = @_;


my $path = shift @$cmd;
my $arguments = $cmd;


Basically I have to send something like this as the final output e.g there is no PATH


in socat this works

{"execute": "guest-exec", "arguments": {"input-data": "OmlwIGFkZHJlc3MgYWRkIGFkZHJlc3M9MTkyLjE2OC4wLjEvMjQgaW50ZXJmYWNlPWV0aGVyMTs=" ,"capture-output": true } }

Thanks
 
OK I worked it out can do like -c stuff -c extra stuff BUT now I see the real problem


QemuServer/Agent.pm
it treats this as an Arg not a key called input-data and without hacking the Agent.pm I cant do it :-(

so will have to work on my plan C


'arg' =>

Command: guest-exec
Execute a command in the guest

Arguments:

path: string
path or executable name to execute

arg: array of string (optional)
argument list to pass to executable

env: array of string (optional)
environment variables to pass to executable

input-data: string (optional)
data to be passed to process stdin (base64 encoded)

capture-output: boolean (optional)
bool flag to enable capture of stdout/stderr of running process. defaults to false.
 
what command do you want to execute? the input data is not implemented in the api ( you can open a feature request though on bugzilla.proxmox.com )
for the api /pvesh you have to give the 'command' parameter again for each part e.g.
for '/bin/ping 8.8.8.8' you have to give

--command '/bin/ping' --command '8.8.8.8'

on the cli there is a shortcut for the current node with 'qm guest exec VMID -- /bin/ping 8.8.8.8'
 
yes I finally worked out the adding like --command '/bin/ping' --command '8.8.8.8'
Aculally what I m trying to do run a script on the Mikotick Router
https://wiki.mikrotik.com/wiki/Manual:CHR#KVM

To set the Interface IP address after I create the VM so that I can then finish the conf off automatically
Now I m trying the file upload method to see if I can work around that

And yes I will ask for the feature and thanks for your help
 
Hi,

you may try this crude shell script, depends on socat and jq, first argument/word is vm id, everything after space is command to vm. It is a little bit of work in progress, but maybe some code may help you somehow...
 

Attachments

Last edited:
I am working on something similar, however I would like to be able to configure CHR through the proxmox RESTAPI interface with agent sending these commands. How would I go about this?
 
I had to use the write file in the end and then run that script
maybe this will help




$data = array('content' => $file_content, 'file' => 'firstboot');
//this always fails we will catch it latter any way
$action = '/nodes/' . $server->hostname . '/' . $this->vtype . '/' . $spcobj->username . '/agent/file-write';
$ret = $this->_api_call($action, 'POST', $data);

//try to execute the script
$data = array();
$data['command'] = 'config-startup';
$action = '/nodes/' . $server->hostname . '/' . $this->vtype . '/' . $spcobj->username . '/agent/exec';
$ret = $this->_api_call($action, 'POST', $data);
 
Thank you very much! I will take a look at it and see what we can do with it.
Did you every inquiry into why that call always fails?