From aae89f5f5ec378c8d230e2b4c17d7e2a4394987a Mon Sep 17 00:00:00 2001 From: patrick Date: Mon, 27 Jul 2026 17:58:15 -0400 Subject: [PATCH] fix(proxmox_lxc_provision): apply idmaps/GPU config via lineinfile, wire into flow edit-config.yml was never included by the role, so lxc_id_mappings and GPU passthrough were silently ignored. It also used blockinfile, whose comment markers are incompatible with Proxmox hoisting all comments to the top of the .conf on every write -- which orphans the markers and empties the managed block. Rewrite edit-config.yml to manage raw lxc.* lines with lineinfile (keyed on each exact line, churn-free, immune to comment hoisting), delegated to the Proxmox host. Include it from main.yml after clone/create but before start.yml, while the container is stopped, since ID mappings can't change on a running container. --- .../tasks/edit-config.yml | 60 ++++++++----------- roles/proxmox_lxc_provision/tasks/main.yml | 9 +++ 2 files changed, 35 insertions(+), 34 deletions(-) diff --git a/roles/proxmox_lxc_provision/tasks/edit-config.yml b/roles/proxmox_lxc_provision/tasks/edit-config.yml index 6b37b47..cd843a6 100755 --- a/roles/proxmox_lxc_provision/tasks/edit-config.yml +++ b/roles/proxmox_lxc_provision/tasks/edit-config.yml @@ -1,43 +1,35 @@ --- +# Proxmox's container config parser hoists all comment lines to the top of the +# .conf on every write (pct set, container start/stop, API calls), which orphans +# blockinfile's # BEGIN/# END markers and breaks idempotency. Manage the raw lxc.* +# lines directly with lineinfile instead -- these are real config keys that Proxmox +# preserves in place. Each line is keyed on its own exact content, so no comment +# markers are needed and re-runs stay churn-free. -- name: Remove all existing ID mappings - lineinfile: +- name: Configure ID mappings + ansible.builtin.lineinfile: path: "/etc/pve/lxc/{{ lxc_vmid }}.conf" - regexp: '^lxc\.idmap:' - state: absent - when: lxc_id_mappings is defined - -- name: Add ID mappings - blockinfile: - path: "/etc/pve/lxc/{{ lxc_vmid }}.conf" - block: "{{ lxc_id_mappings }}" + line: "{{ item }}" + regexp: "^{{ item | regex_escape }}$" insertafter: EOF + loop: "{{ lxc_id_mappings.splitlines() | select | list }}" + delegate_to: "{{ proxmox_delegate_host }}" + become: true when: lxc_id_mappings is defined -- name: Remove existing GPU configuration - lineinfile: +- name: Configure NVIDIA GPU passthrough + ansible.builtin.lineinfile: path: "/etc/pve/lxc/{{ lxc_vmid }}.conf" - regexp: "{{ item }}" - state: absent + line: "{{ item }}" + regexp: "^{{ item | regex_escape }}$" + insertafter: EOF loop: - - '^lxc\.cgroup2\.devices\.allow: c {{ gpu_device_id }}:\* rwm' - - '^lxc\.cgroup2\.devices\.allow: c {{ uvm_device_id }}:\* rwm' - - '^lxc\.mount\.entry: /dev/nvidia0' - - '^lxc\.mount\.entry: /dev/nvidiactl' - - '^lxc\.mount\.entry: /dev/nvidia-uvm ' - - '^lxc\.mount\.entry: /dev/nvidia-uvm-tools' + - "lxc.cgroup2.devices.allow: c {{ gpu_device_id }}:* rwm" + - "lxc.cgroup2.devices.allow: c {{ uvm_device_id }}:* rwm" + - "lxc.mount.entry: /dev/nvidia0 dev/nvidia0 none bind,optional,create=file" + - "lxc.mount.entry: /dev/nvidiactl dev/nvidiactl none bind,optional,create=file" + - "lxc.mount.entry: /dev/nvidia-uvm dev/nvidia-uvm none bind,optional,create=file" + - "lxc.mount.entry: /dev/nvidia-uvm-tools dev/nvidia-uvm-tools none bind,optional,create=file" + delegate_to: "{{ proxmox_delegate_host }}" + become: true when: lxc_nvidia_gpu_mount - -- name: Add GPU device for passthrough - blockinfile: - path: /etc/pve/lxc/{{ lxc_vmid }}.conf - block: | - lxc.cgroup2.devices.allow: c {{ gpu_device_id }}:* rwm - lxc.cgroup2.devices.allow: c {{ uvm_device_id }}:* rwm - lxc.mount.entry: /dev/nvidia0 dev/nvidia0 none bind,optional,create=file - lxc.mount.entry: /dev/nvidiactl dev/nvidiactl none bind,optional,create=file - lxc.mount.entry: /dev/nvidia-uvm dev/nvidia-uvm none bind,optional,create=file - lxc.mount.entry: /dev/nvidia-uvm-tools dev/nvidia-uvm-tools none bind,optional,create=file - when: lxc_nvidia_gpu_mount - - \ No newline at end of file diff --git a/roles/proxmox_lxc_provision/tasks/main.yml b/roles/proxmox_lxc_provision/tasks/main.yml index 94111b9..3b2d080 100755 --- a/roles/proxmox_lxc_provision/tasks/main.yml +++ b/roles/proxmox_lxc_provision/tasks/main.yml @@ -32,6 +32,15 @@ file: create.yml when: lxc_template is defined and lxc_clone_from is undefined +# Must run while the container is stopped (before start.yml): ID mappings cannot be +# changed on a running container. Writes /etc/pve/lxc/.conf on the Proxmox host. +- name: Apply raw LXC config (ID mappings, GPU passthrough) + ansible.builtin.include_tasks: + file: edit-config.yml + vars: + lxc_vmid: "{{ lxc_result.vmid | default(lxc_vmid) }}" + when: lxc_id_mappings is defined or lxc_nvidia_gpu_mount + - name: Start the created container and wait for ssh vars: lxc_vmid: "{{ lxc_result.vmid }}"