Set "features" via http api2 doesn't work

DebianDEV

New Member
Jan 12, 2022
4
0
1
31
Hello,

I'm running some proxmox nodes and wrote my own webinterface (php) to manage my virtual servers.
For this, I'm using the proxmox class of saleh7 on GITHub (https://github.com/Saleh7/ProxmoxVE_PHP_API).

To set nesting for id 100 (lxc container):
PHP:
# Test 1
$this->nodes->setLxcConfig("node1", "100", array("features" => "nesting=1"));

#Result is:
object(stdClass)#43 (1) { ["data"]=> NULL }

But the nesting feature isn't set and also not waiting for restart (pending).

I've tested a few things to exclude an error of the class:

PHP:
## Test 2 set nesting to 5 instead of 0|1
$this->nodes->setLxcConfig("node1", "100", array("features" => "nesting=5"));

# Result:
object(stdClass)#54 (2) { ["errors"]=> object(stdClass)#43 (1) { ["features"]=> string(88) "invalid format - format error features.nesting: type check ('boolean') failed - got '5' " } ["data"]=> NULL }
   

## Test 3 --> set Nesting instead of nesting
$this->nodes->setLxcConfig("node1", "100", array("features" => "Nesting=1"));

# Result:
object(stdClass)#43 (2) { ["data"]=> NULL ["errors"]=> object(stdClass)#54 (1) { ["features"]=> string(134) "invalid format - format error features.Nesting: property is not defined in schema and the schema does not allow additional properties " } }

With this both tests I've excluded the php class as point of failure. In my opinion, the proxmox api is returning the correct errors for the wrong values, so the submitted values within "Test 1" are interpreted correctly by the proxmox api and should be applied.

For whatever reason, the "features" aren't applied by the api.

Notice:
On shell
Bash:
pvesh set /nodes/node1/lxc/100/config -features "nesting=1"
is working fine!

Setting these value within the proxmox webgui is working fine too.


Any ideas?


Code:
Using: Debian 11

Version overview:
proxmox-ve: 7.1-1 (running kernel: 5.13.19-2-pve)
pve-manager: 7.1-8 (running version: 7.1-8/5b267f33)
pve-kernel-helper: 7.1-6
pve-kernel-5.13: 7.1-5
pve-kernel-5.4: 6.4-11
pve-kernel-5.13.19-2-pve: 5.13.19-4
pve-kernel-5.4.157-1-pve: 5.4.157-1
ceph-fuse: 14.2.21-1
corosync: 3.1.5-pve2
criu: 3.15-1+pve-1
glusterfs-client: 9.2-1
ifupdown: residual config
ifupdown2: 3.1.0-1+pmx3
libjs-extjs: 7.0.0-1
libknet1: 1.22-pve2
libproxmox-acme-perl: 1.4.0
libproxmox-backup-qemu0: 1.2.0-1
libpve-access-control: 7.1-5
libpve-apiclient-perl: 3.2-1
libpve-common-perl: 7.0-14
libpve-guest-common-perl: 4.0-3
libpve-http-server-perl: 4.0-4
libpve-storage-perl: 7.0-15
libspice-server1: 0.14.3-2.1
lvm2: 2.03.11-2.1
lxc-pve: 4.0.11-1
lxcfs: 4.0.11-pve1
novnc-pve: 1.3.0-1
proxmox-backup-client: 2.1.2-1
proxmox-backup-file-restore: 2.1.2-1
proxmox-mini-journalreader: 1.3-1
proxmox-widget-toolkit: 3.4-4
pve-cluster: 7.1-3
pve-container: 4.1-3
pve-docs: 7.1-2
pve-edk2-firmware: 3.20210831-2
pve-firewall: 4.2-5
pve-firmware: 3.3-4
pve-ha-manager: 3.3-1
pve-i18n: 2.6-2
pve-qemu-kvm: 6.1.0-3
pve-xtermjs: 4.12.0-1
qemu-server: 7.1-4
smartmontools: 7.2-pve2
spiceterm: 3.2-2
swtpm: 0.7.0~rc1+2
vncterm: 1.7-1
zfsutils-linux: 2.1.1-pve3
 
Last edited:
please post the CT config and information about the user/token you are using for your API call (e.g., pveum user permissions 'user@realm' --path /vms/100).
 
based on your output I believe the PHP lib you are using is not giving you the full response - e.g., when repeating the action you want to do:

Code:
$ curl .... --data-raw 'features=nesting%3D5'
{"data":null,"success":0,"message":"Parameter verification failed.\n","errors":{"features":"invalid format - format error\nfeatures.nesting: type check ('boolean') failed - got '5'\n"},"status":"400"}%

not how the status, success and message fields are missing from your output.

repeating the same, but with a CT where this action requires root@pam since it's privileged:

Code:
$ curl .... --data-raw 'features=nesting%3D1'
{"status":"403","message":"Permission check failed (changing feature flags for privileged container is only allowed for root@pam)\n","success":0,"data":null}%

removing success, status and message, this leaves just data like in your example!

repeating, but with an unprivileged CT:
Code:
$ curl .... --data-raw 'features=nesting%3D1'
{"data":null,"success":1}%
 
Hi Fabian,

after a long time debugging, the problem is that ....

If I request a ticket with root@pam and try to set the config, it works fine.
Then I try to do the same request with a user with the following rights:

username@pve
Perm Path: /
Role: Administrator (Built-In Role)

So in my world the "username@pve" user is a admin and should have the same perms like the root user - or not?

//EDIT:

My test bash looks like this:

Fine:

Bash:
#!/bin/bash
GETTICKET=$(curl -s -k -d "username=root@pam&password=SECRET" https://DOMAIN/api2/json/access/ticket)
COOKIE=$(echo $GETTICKET | jq '.data.ticket' | sed 's/\"//g')
CSRF=$(echo $GETTICKET | jq '.data.CSRFPreventionToken' | sed 's/\"//g')

curl -v -s -b "PVEAuthCookie=$COOKIE" -H "CSRFPreventionToken: $CSRF" -X PUT \
        -d 'features=nesting%3D1' \
        "https://DOMAIN/api2/json/nodes/NODE/lxc/VMID/config"


Crap-Code (user differs from above):

Bash:
#!/bin/bash
GETTICKET=$(curl -s -k -d "username=user@pve&password=SECRET" https://DOMAIN/api2/json/access/ticket)
COOKIE=$(echo $GETTICKET | jq '.data.ticket' | sed 's/\"//g')
CSRF=$(echo $GETTICKET | jq '.data.CSRFPreventionToken' | sed 's/\"//g')

curl -v -s -b "PVEAuthCookie=$COOKIE" -H "CSRFPreventionToken: $CSRF" -X PUT \
        -d 'features=nesting%3D1' \
        "https://DOMAIN/api2/json/nodes/NODE/lxc/VMID/config"

Jesus - I never thought that "full-admin" rights are not enough.

//EDIT2:
Is it a feature or a bug?
 
Last edited:
full admin rights are enough (I did my tests above with exactly such a user!) - please double check you actually have them (e.g. with pveum user permissions 'user@realm' --path /vms/100 - like I said before ;))
 
and if you repeat your tests - could you please include the full curl output? just to make sure..
 
I've tested that again and the problem persists.
As I said: In my world if the user have perms to path "/" it schould work for ALL VMs, Storages and so on (inherit) ...

I set the perms:

Bash:
root@NODE:/home/nico# pveum user permissions 'USER@pve' --path /vms/802
┌──────────┬────────────────────────────────┐
│ ACL path │ Permissions                    │
╞══════════╪════════════════════════════════╡
│ /vms/802 │ Datastore.Allocate (*)         │
│          │ Datastore.AllocateSpace (*)    │
│          │ Datastore.AllocateTemplate (*) │
│          │ Datastore.Audit (*)            │
│          │ Group.Allocate (*)             │
│          │ Permissions.Modify (*)         │
│          │ Pool.Allocate (*)              │
│          │ Pool.Audit (*)                 │
│          │ Realm.Allocate (*)             │
│          │ Realm.AllocateUser (*)         │
│          │ SDN.Allocate (*)               │
│          │ SDN.Audit (*)                  │
│          │ Sys.Audit (*)                  │
│          │ Sys.Console (*)                │
│          │ Sys.Modify (*)                 │
│          │ Sys.PowerMgmt (*)              │
│          │ Sys.Syslog (*)                 │
│          │ User.Modify (*)                │
│          │ VM.Allocate (*)                │
│          │ VM.Audit (*)                   │
│          │ VM.Backup (*)                  │
│          │ VM.Clone (*)                   │
│          │ VM.Config.CDROM (*)            │
│          │ VM.Config.CPU (*)              │
│          │ VM.Config.Cloudinit (*)        │
│          │ VM.Config.Disk (*)             │
│          │ VM.Config.HWType (*)           │
│          │ VM.Config.Memory (*)           │
│          │ VM.Config.Network (*)          │
│          │ VM.Config.Options (*)          │
│          │ VM.Console (*)                 │
│          │ VM.Migrate (*)                 │
│          │ VM.Monitor (*)                 │
│          │ VM.PowerMgmt (*)               │
│          │ VM.Snapshot (*)                │
│          │ VM.Snapshot.Rollback (*)       │
└──────────┴────────────────────────────────┘
Permissions marked with '(*)' have the 'propagate' flag set.

Then I've run the following code

Bash:
root@NODE:/home/nico# cat test.sh
#!/bin/bash

GETTICKET=$(curl -s -k -d "username=USER@pve&password=PASSWORD" https://DOMAIN/api2/json/access/ticket)


COOKIE=$(echo $GETTICKET | jq '.data.ticket' | sed 's/\"//g')
CSRF=$(echo $GETTICKET | jq '.data.CSRFPreventionToken' | sed 's/\"//g')

curl -s -b "PVEAuthCookie=$COOKIE" -H "CSRFPreventionToken: $CSRF" -X PUT \
        -d 'features=nesting%3D1' \
        "https://DOMAIN/api2/json/nodes/NODE/lxc/802/config"

Result:
Bash:
root@NODE:/home/nico# ./test.sh
{"data":null}

Bash:
root@NODE:/home/nico# cat /etc/pve/lxc/802.conf
arch: amd64
cores: 1
hostname: XXXX.XXXX.XXXX
memory: 512
net0: name=eth0,bridge=vmbr0,firewall=1,gw=X.X.X.X,gw6=fe80::1,hwaddr=ee:19:b8:XX:XX:XX,ip=XX.XX.XX.XXX/32,ip6=XXXX:XXXX:XXXX:XX::XX:X/128,rate=13,type=veth
ostype: ubuntu
rootfs: local:802/vm-802-disk-0.raw,size=10G
swap: 0
root@NODE:/home/nico#



//Edit

Tested on updated version, too

Bash:
root@NODE:/home/nico# pveversion -v
proxmox-ve: 7.1-1 (running kernel: 5.13.19-2-pve)
pve-manager: 7.1-9 (running version: 7.1-9/0740a2bc)
pve-kernel-helper: 7.1-8
pve-kernel-5.13: 7.1-6
pve-kernel-5.4: 6.4-11
pve-kernel-5.13.19-3-pve: 5.13.19-6
pve-kernel-5.13.19-2-pve: 5.13.19-4
pve-kernel-5.4.157-1-pve: 5.4.157-1
ceph-fuse: 14.2.21-1
corosync: 3.1.5-pve2
criu: 3.15-1+pve-1
glusterfs-client: 9.2-1
ifupdown: residual config
ifupdown2: 3.1.0-1+pmx3
libjs-extjs: 7.0.0-1
libknet1: 1.22-pve2
libproxmox-acme-perl: 1.4.1
libproxmox-backup-qemu0: 1.2.0-1
libpve-access-control: 7.1-5
libpve-apiclient-perl: 3.2-1
libpve-common-perl: 7.1-2
libpve-guest-common-perl: 4.0-3
libpve-http-server-perl: 4.1-1
libpve-storage-perl: 7.0-15
libspice-server1: 0.14.3-2.1
lvm2: 2.03.11-2.1
lxc-pve: 4.0.11-1
lxcfs: 4.0.11-pve1
novnc-pve: 1.3.0-1
proxmox-backup-client: 2.1.3-1
proxmox-backup-file-restore: 2.1.3-1
proxmox-mini-journalreader: 1.3-1
proxmox-widget-toolkit: 3.4-5
pve-cluster: 7.1-3
pve-container: 4.1-3
pve-docs: 7.1-2
pve-edk2-firmware: 3.20210831-2
pve-firewall: 4.2-5
pve-firmware: 3.3-4
pve-ha-manager: 3.3-1
pve-i18n: 2.6-2
pve-qemu-kvm: 6.1.0-3
pve-xtermjs: 4.12.0-1
qemu-server: 7.1-4
smartmontools: 7.2-pve2
spiceterm: 3.2-2
swtpm: 0.7.0~rc1+2
vncterm: 1.7-1
zfsutils-linux: 2.1.2-pve1
 
Last edited:
if you don't use '-s' you'll actually see the error as well ;)
 
The Output is still the same.

Bash:
root@NODE:/home/nico# cat test.sh
#!/bin/bash

GETTICKET=$(curl -s -k -d "username=USER@pve&password=PASSWORD" https://DOMAIN/api2/json/access/ticket)


COOKIE=$(echo $GETTICKET | jq '.data.ticket' | sed 's/\"//g')
CSRF=$(echo $GETTICKET | jq '.data.CSRFPreventionToken' | sed 's/\"//g')

curl -b "PVEAuthCookie=$COOKIE" -H "CSRFPreventionToken: $CSRF" -X PUT \
        -d 'features=fuse%3D1' \
        "https://DOMAIN/api2/json/nodes/NODE/lxc/802/config"

#echo $COOKIE

root@NODE:/home/nico# ./test.sh
{"data":null}root@NODE:/home/nico#

//Edit: Its unnecessary if I try to set fuse or nesting - setting features in general doesn't work
 
Last edited:
if you can set it via the GUI, but can't set it via the API (using the same user and guest) - then you are doing something wrong when using the API. the GUI is not special in any way, all it does is do API calls and present the results.. (and you are right - if you use the json endpoint, you need '-v' to see the status code and error message - the 'extjs' endpoint will give that in the response body as well together with the success field)

note that nesting is special in that it is allowed for unprivileged containers and regular users that can modify that container's config - the other features are limited to root@pam..
 

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!