[GH-ISSUE #159] How to use ssh-public-key in pct create for lxc #84

Closed
opened 2026-02-27 15:46:20 +03:00 by kerem · 6 comments
Owner

Originally created by @harshguptaserver on GitHub (Mar 5, 2024).
Original GitHub issue: https://github.com/proxmoxer/proxmoxer/issues/159

Originally assigned to: @jhollowe on GitHub.

Hello Proxmoxer team,

I have been using your python3 proxmoxer package to create pct container. However, while doing this I have been stuck at a place where i need to pass ssh-public-key argument while creating the lxc container.

This is mentioned in the Official Proxmox API here : https://pve.proxmox.com/pve-docs/api-viewer/#/nodes/{node}/lxc
-- In POST Section as "ssh-public-keys"

My goal is to use ssh key to pass on to container creation ( as it is quite possible in the UI ).

Here is my sample code:

 proxmox = proxmoxer.ProxmoxAPI(
            PROXMOX_HOST,
            user=PROXMOX_USER,
            password=PROXMOX_PASSWORD,
            verify_ssl=False,
            backend='https'
        )
template_location = 'local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst'
        MY_SSH_PUBLIC_KEY = 'ssh-rsa AA...........  harsh@mykey'
        ct_hostname = ct_json_data.get("ct")

        ct_cpu = int(ct_json_data.get("cpu"))

        ct_memory = int(ct_json_data.get("ram"))
        ct_id = int(ct_json_data.get("ctid"))
        ct_hdd_size = int(ct_json_data.get("hdd"))
        ct_hdd_location = ct_json_data.get("hdd_location")
        lxc_ct = proxmox.nodes(PROXMOX_NODE_NAME).lxc.create(
            vmid=ct_id,
            ostemplate=template_location,
            hostname=ct_hostname,
            storage=ct_hdd_location,
            memory=ct_memory,
            swap=2048,
            cores=ct_cpu,
            password=PROXMOX_PASSWORD,
            rootfs=ct_hdd_size,
            net0='name=eth0,bridge=vmbr0,ip=dhcp',
            nameserver='10.0.0.20,192.168.88.1',
            onboot=1,
            ostype='ubuntu',
            sshpublickeys=MY_SSH_PUBLIC_KEY,  # https://pve.proxmox.com/pve-docs/chapter-pct.html
        )

Despite trying multiple times/ multiple combinations for keyword 'sshpublickeys' it fails all the time with error:

400 Bad Request: Parameter verification failed. - {'sshpublickeys': 'property is not defined in schema and the schema does not allow additional properties'}

Originally created by @harshguptaserver on GitHub (Mar 5, 2024). Original GitHub issue: https://github.com/proxmoxer/proxmoxer/issues/159 Originally assigned to: @jhollowe on GitHub. Hello Proxmoxer team, I have been using your python3 proxmoxer package to create pct container. However, while doing this I have been stuck at a place where i need to pass ssh-public-key argument while creating the lxc container. This is mentioned in the Official Proxmox API here : https://pve.proxmox.com/pve-docs/api-viewer/#/nodes/{node}/lxc -- In POST Section as "ssh-public-keys" My goal is to use ssh key to pass on to container creation ( as it is quite possible in the UI ). Here is my sample code: ``` proxmox = proxmoxer.ProxmoxAPI( PROXMOX_HOST, user=PROXMOX_USER, password=PROXMOX_PASSWORD, verify_ssl=False, backend='https' ) template_location = 'local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst' MY_SSH_PUBLIC_KEY = 'ssh-rsa AA........... harsh@mykey' ct_hostname = ct_json_data.get("ct") ct_cpu = int(ct_json_data.get("cpu")) ct_memory = int(ct_json_data.get("ram")) ct_id = int(ct_json_data.get("ctid")) ct_hdd_size = int(ct_json_data.get("hdd")) ct_hdd_location = ct_json_data.get("hdd_location") lxc_ct = proxmox.nodes(PROXMOX_NODE_NAME).lxc.create( vmid=ct_id, ostemplate=template_location, hostname=ct_hostname, storage=ct_hdd_location, memory=ct_memory, swap=2048, cores=ct_cpu, password=PROXMOX_PASSWORD, rootfs=ct_hdd_size, net0='name=eth0,bridge=vmbr0,ip=dhcp', nameserver='10.0.0.20,192.168.88.1', onboot=1, ostype='ubuntu', sshpublickeys=MY_SSH_PUBLIC_KEY, # https://pve.proxmox.com/pve-docs/chapter-pct.html ) ``` Despite trying multiple times/ multiple combinations for keyword 'sshpublickeys' it fails all the time with error: ``` 400 Bad Request: Parameter verification failed. - {'sshpublickeys': 'property is not defined in schema and the schema does not allow additional properties'} ```
Author
Owner

@jhollowe commented on GitHub (Mar 5, 2024):

the ssh key(s) need to be encoded to make it through to PVE successfully. You can see how to do this in the cloud-init example docs.

Please reopen if this doesn't work for you.

<!-- gh-comment-id:1978877106 --> @jhollowe commented on GitHub (Mar 5, 2024): the ssh key(s) need to be encoded to make it through to PVE successfully. You can see how to do this in the [cloud-init example docs](https://proxmoxer.github.io/docs/dev/examples/cloud-init/#example-code-setting-cloud-init-options). Please reopen if this doesn't work for you.
Author
Owner

@harshguptaserver commented on GitHub (Mar 6, 2024):

Thank you for the quick reply. I have already tried that earlier as well but it does not work for lxc.

Here is the sample code with the Encoded keys that I have tried:

from urllib.parse import quote as urlquote
        ENCODED_KEYS = urlquote(SSH_PUBLIC_KEY_CT_VM, safe='')
        this_ct_ip = process_container_ip(ct_json_data.get('ip'))
        # # {'ipconfig0': {'ip': '10.0.0.90/24', 'gw': '10.0.0.1', 'vm_network': 'net0', 'vm_nic_name': 'vmbr1'}}
        this_net0_br = this_ct_ip['ipconfig0']['vm_nic_name']
        this_net0_ip = this_ct_ip['ipconfig0']['ip']
        this_net0_gw = this_ct_ip['ipconfig0']['gw']

        lxc_ct = proxmox.nodes(PROXMOX_NODE_NAME).lxc.create(
            vmid=ct_id,
            # ostemplate='local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst',
            ostemplate=template_location,
            hostname=ct_hostname,
            storage=ct_hdd_location,
            memory=ct_memory,
            swap=2048,
            cores=ct_cpu,
            password=PROXMOX_PASSWORD,
            rootfs=ct_hdd_size,
            # net0='name=eth0,bridge=vmbr0,ip=dhcp',

            net0=f"name=eth0,bridge={this_net0_br},ip={this_net0_ip},gw={this_net0_gw}",

            nameserver='10.0.0.20,192.168.88.1',
            onboot=1,
            ostype='ubuntu',
            sshkeys=ENCODED_KEYS,
        )

and here is the error when using the above code:

400 Bad Request: Parameter verification failed. - {'sshkeys': 'property is not defined in schema and the schema does not allow additional properties'}

As mentioned earlier, the property the lxc api is looking for is 'ssh-public-keys' per the api docs, in this case, there seems to be no such possibility to pass in the key.

Kindly help with the same and also how would one pass in multiple 'net' dynamically using python ?
i.e.
in the dictionary that has container data, we know there are say 3 net (net0, net1, net2) but how do we pass it dynamically from a python dictionary (as create uses arguments).

<!-- gh-comment-id:1980831066 --> @harshguptaserver commented on GitHub (Mar 6, 2024): Thank you for the quick reply. I have already tried that earlier as well but it does not work for lxc. Here is the sample code with the Encoded keys that I have tried: ``` from urllib.parse import quote as urlquote ENCODED_KEYS = urlquote(SSH_PUBLIC_KEY_CT_VM, safe='') this_ct_ip = process_container_ip(ct_json_data.get('ip')) # # {'ipconfig0': {'ip': '10.0.0.90/24', 'gw': '10.0.0.1', 'vm_network': 'net0', 'vm_nic_name': 'vmbr1'}} this_net0_br = this_ct_ip['ipconfig0']['vm_nic_name'] this_net0_ip = this_ct_ip['ipconfig0']['ip'] this_net0_gw = this_ct_ip['ipconfig0']['gw'] lxc_ct = proxmox.nodes(PROXMOX_NODE_NAME).lxc.create( vmid=ct_id, # ostemplate='local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst', ostemplate=template_location, hostname=ct_hostname, storage=ct_hdd_location, memory=ct_memory, swap=2048, cores=ct_cpu, password=PROXMOX_PASSWORD, rootfs=ct_hdd_size, # net0='name=eth0,bridge=vmbr0,ip=dhcp', net0=f"name=eth0,bridge={this_net0_br},ip={this_net0_ip},gw={this_net0_gw}", nameserver='10.0.0.20,192.168.88.1', onboot=1, ostype='ubuntu', sshkeys=ENCODED_KEYS, ) ``` and here is the error when using the above code: ``` 400 Bad Request: Parameter verification failed. - {'sshkeys': 'property is not defined in schema and the schema does not allow additional properties'} ``` As mentioned earlier, the property the lxc api is looking for is 'ssh-public-keys' per the api docs, in this case, there seems to be no such possibility to pass in the key. Kindly help with the same and also how would one pass in multiple 'net' dynamically using python ? i.e. in the dictionary that has container data, we know there are say 3 net (net0, net1, net2) but how do we pass it dynamically from a python dictionary (as create uses arguments).
Author
Owner

@harshguptaserver commented on GitHub (Mar 6, 2024):

@jhollowe please help in this regards, it will be very grateful of you & your team.

<!-- gh-comment-id:1980834450 --> @harshguptaserver commented on GitHub (Mar 6, 2024): @jhollowe please help in this regards, it will be very grateful of you & your team.
Author
Owner

@morph027 commented on GitHub (Mar 6, 2024):

for lxc, its ssh-public-keys

See https://pve.proxmox.com/pve-docs/api-viewer/index.html#/nodes/{node}/lxc

for multiple net, you could use python enumerate()

<!-- gh-comment-id:1981163053 --> @morph027 commented on GitHub (Mar 6, 2024): for lxc, its `ssh-public-keys` See https://pve.proxmox.com/pve-docs/api-viewer/index.html#/nodes/{node}/lxc for multiple net, you could use python [`enumerate()`](https://docs.python.org/3.8/library/functions.html#enumerate)
Author
Owner

@jhollowe commented on GitHub (Mar 6, 2024):

and to be able to use hyphens in the key name, you will want to create the data as a dict and then unpack that into the .post()/.create() call.

e.g.

ct_info = {"vmid": ctid, ... , "ssh-public-keys": ENCODED_KEYS}
lxc_ct = proxmox.nodes(PROXMOX_NODE_NAME).lxc.create(**ct_info)
<!-- gh-comment-id:1981198470 --> @jhollowe commented on GitHub (Mar 6, 2024): and to be able to use hyphens in the key name, you will want to create the data as a dict and then unpack that into the `.post()`/`.create()` call. e.g. ```python ct_info = {"vmid": ctid, ... , "ssh-public-keys": ENCODED_KEYS} lxc_ct = proxmox.nodes(PROXMOX_NODE_NAME).lxc.create(**ct_info) ```
Author
Owner

@harshguptaserver commented on GitHub (Mar 9, 2024):

Thank you so much @jhollowe & @morph027 , this resolved the issue of using ssh-public-keys, I can work on enumerate in my own time as I can use dict to create a ct now, it solves all the issues.

Really appreciate your quick responses and help :-)

For those who land on this issue, here is my code that works for creating lxc containers using dictionary :

MY_SSH_KEY = "ssh-rsa abc123.... harsh@myserver"
container_config = {
            "vmid": ct_id,
            "ostemplate": template_location,
            "hostname": ct_hostname,
            "ssh-public-keys": MY_SSH_KEY, ## note it works without using encoding in my case 
            "memory": ct_memory,
            "net0": f"name=eth0,bridge={this_net0_br},ip={this_net0_ip},gw={this_net0_gw}",
            "cores": ct_cpu,
            "nameserver": "10.0.0.20 192.168.88.1",
            "swap": 2048,
            "password": PROXMOX_PASSWORD,
            "ostype": "ubuntu",
            "arch": "amd64",
            "rootfs": ct_hdd_size,
            "storage": ct_hdd_location,
            "onboot": 1
        }
        print(f":DEBUG: Going to run lxc.create")
        lxc_ct = proxmox.nodes(PROXMOX_NODE_NAME).lxc.create(**container_config)
        print(f"lxc_ct Create: {lxc_ct}")
<!-- gh-comment-id:1986770058 --> @harshguptaserver commented on GitHub (Mar 9, 2024): Thank you so much @jhollowe & @morph027 , this resolved the issue of using ssh-public-keys, I can work on enumerate in my own time as I can use dict to create a ct now, it solves all the issues. Really appreciate your quick responses and help :-) For those who land on this issue, here is my code that works for creating lxc containers using dictionary : ``` MY_SSH_KEY = "ssh-rsa abc123.... harsh@myserver" container_config = { "vmid": ct_id, "ostemplate": template_location, "hostname": ct_hostname, "ssh-public-keys": MY_SSH_KEY, ## note it works without using encoding in my case "memory": ct_memory, "net0": f"name=eth0,bridge={this_net0_br},ip={this_net0_ip},gw={this_net0_gw}", "cores": ct_cpu, "nameserver": "10.0.0.20 192.168.88.1", "swap": 2048, "password": PROXMOX_PASSWORD, "ostype": "ubuntu", "arch": "amd64", "rootfs": ct_hdd_size, "storage": ct_hdd_location, "onboot": 1 } print(f":DEBUG: Going to run lxc.create") lxc_ct = proxmox.nodes(PROXMOX_NODE_NAME).lxc.create(**container_config) print(f"lxc_ct Create: {lxc_ct}") ```
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/proxmoxer#84
No description provided.