[SOLVED] Proxmox API agent exec escape chars

azhv

New Member
Oct 5, 2020
14
0
1
34
Hello,
I'm trying to automate the VM management via scripts that will reconfigure sets of VMs. However I'm struggling with changing file content. Here's an example:

curl -sSk --header ${AUTH} -X POST --data-urlencode command="echo 1 > /path/to/file" https://IP:8006/api2/json/nodes/NODE/qemu/100/agent/exec

The agent exec works fine with everything else but when I try to echo something into file nothing happens.
I tried with all sorts of escapes I could think of but without any result.
I know I'm supposed to do this with file write instead of agent exec but further in the project I'll have to use sed substitution and I need a way to figure out the escapes.
Proxmox version is 6.2-4
Thanks. Any help will be greatly appreciated.
 
Hi,
The agent exec works fine with everything else but when I try to echo something into file nothing happens.
thats because you do not run the command in shell context, which handles such redirections normally.

Try: command="sh -c 'echo 1 > /path/to/file'"

Alternative, avoid the shell to handle file writes and use things like awk, sed or other such tools which can operate directly on files, not relying on a shell to handle that.
 
Last edited:
Hello and thanks for the quick reply.
I've tried that but it also doesn't seem to work.
As soon as I put some special character like > or |the command no longer works.
 
Ah sorry, misremembered the way command arguments need to be passed. As those arguments can contain any character we actually have only one way to encode when transferred as single string:
The API expects the command as \0 separated list, posting actual \0 bytes with the CLI version of CURL is actually impressively hard, so lets use JSON encoding instead:

Bash:
curl -sSk -H 'Authorization: PVEAPIToken=TOKEN' -H "Content-Type: application/json" -X POST --data '{"command": "sh\u0000-c\u0000echo hello > /foo"}'  https://HOST:8006/api2/json/nodes/NODE/qemu/100/agent/exec
JSON uses \u0000 to encode NUL in strings, so basically you just have to insert that every time there starts a new argument for the command.

Alternatively we could just use another tool for assembling the data, as either URL-encoded or JSON, or a programming language/toolkit which can handle \0 in strings (always available a quick to prototype are perl, python, ...).

For completeness' sake: URL encoded example:
Bash:
curl -sSk -H 'Authorization: PVEAPIToken=TOKEN' -X POST --data command="sh%00-c%00echo%20hello%20%3E%20%2Ffoo" https://HOST:8006/api2/json/nodes/NODE/qemu/100/agent/exec

I tested both above successfully, so just ensure token/host/node gets replaced correctly.

FYI, if you're on the same host as that VM you could go a bit simpler and just use the qm CLI tool:
Bash:
qm guest exec 115 -- "/bin/bash" "-c"  "echo hello > /foo"
 
  • Like
Reactions: azhv

About

The Proxmox community has been around for many years and offers help and support for Proxmox VE, Proxmox Backup Server, and Proxmox Mail Gateway.
We think our community is one of the best thanks to people like you!

Get your subscription!

The Proxmox team works very hard to make sure you are running the best software and getting stable updates and security enhancements, as well as quick enterprise support. Tens of thousands of happy customers have a Proxmox subscription. Get yours easily in our online shop.

Buy now!