Skip to content

feat(lxc): implement idmap support via SSH config file editing#2579

Merged
bpg-dev merged 5 commits intobpg:mainfrom
LTe:lxc-id-maps
Feb 21, 2026
Merged

feat(lxc): implement idmap support via SSH config file editing#2579
bpg-dev merged 5 commits intobpg:mainfrom
LTe:lxc-id-maps

Conversation

@LTe
Copy link
Copy Markdown
Contributor

@LTe LTe commented Feb 11, 2026

What does this PR do?

Adds idmap block support to the proxmox_virtual_environment_container resource, enabling UID/GID mapping configuration for unprivileged LXC containers.

The Proxmox API does not support writing lxc[n] parameters, so lxc.idmap entries cannot be set through the standard API. This implementation writes idmap entries directly to /etc/pve/lxc/<vmid>.conf via SSH after container creation or update, reads them back through the API's lxc config field, and manages full lifecycle (create, update, remove).

resource "proxmox_virtual_environment_container" "example" {
  # ...
  unprivileged = true

  idmap {
    type         = "uid"
    container_id = 0
    host_id      = 100000
    size         = 65536
  }

  idmap {
    type         = "gid"
    container_id = 0
    host_id      = 100000
    size         = 65536
  }
}

Contributor's Note

  • I have run make lint and fixed any issues.
  • I have updated documentation (FWK: schema descriptions + make docs; SDK: manual /docs/ edits).
  • I have added / updated acceptance tests (required for new resources and bug fixes — see ADR-006).
  • I have considered backward compatibility (no breaking schema changes without ! in PR title).
  • For new resources: I followed the reference examples.
  • I have run make example to verify the change works (mainly for SDK / provider config changes).

Proof of Work

Acceptance test TestAccResourceContainerIDMap passes — covers create (2 idmap entries), update (modify + add entries), and remove (clear all entries). Each step verifies no perpetual diffs.

$ ./testacc TestAccResourceContainerIDMap -- -v

=== RUN   TestAccResourceContainerIDMap
=== PAUSE TestAccResourceContainerIDMap
=== CONT  TestAccResourceContainerIDMap
--- PASS: TestAccResourceContainerIDMap (7.08s)
PASS
ok  	github.com/bpg/terraform-provider-proxmox/fwprovider/test	7.088s

Step 1 — Create: Container created via API, idmap written via SSH, API read-back confirms:

{"lxc": [["lxc.idmap", "u 0 100000 65536"], ["lxc.idmap", "g 0 100000 65536"]]}
SSH commands executed
try_sudo sed -i '/^lxc\.idmap:/d' /etc/pve/lxc/113717.conf
echo 'lxc.idmap: u 0 100000 65536' | try_sudo tee -a /etc/pve/lxc/113717.conf > /dev/null
echo 'lxc.idmap: g 0 100000 65536' | try_sudo tee -a /etc/pve/lxc/113717.conf > /dev/null

Step 2 — Update: GID mapping modified, additional entry added, API read-back confirms:

{"lxc": [["lxc.idmap", "u 0 100000 65536"], ["lxc.idmap", "g 0 100000 44"], ["lxc.idmap", "g 44 44 1"]]}

Step 3 — Remove: All idmap blocks removed, API read-back has no lxc field — entries fully cleared.

Lint passes with 0 issues in the changed files.

Community Note

  • Please vote on this pull request by adding a 👍 reaction to the original pull request comment to help the community and maintainers prioritize this request
  • Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for pull request followers and do not help prioritize the request

Relates #256
Relates #1801

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @LTe, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the proxmox_virtual_environment_container resource by adding support for UID/GID mapping (idmap) in unprivileged LXC containers. This feature is crucial for managing user and group ID discrepancies between the host and container environments. Due to limitations in the Proxmox API, the implementation cleverly bypasses the API by directly manipulating container configuration files via SSH, ensuring that users can fully manage idmap entries through Terraform.

Highlights

  • IDMap Support for LXC Containers: Introduced a new idmap block within the proxmox_virtual_environment_container resource, allowing configuration of UID/GID mappings for unprivileged LXC containers.
  • SSH-based Configuration: Implemented idmap configuration by directly editing /etc/pve/lxc/<vmid>.conf via SSH, as the Proxmox API does not support setting lxc.idmap parameters directly.
  • Full Lifecycle Management: Ensured comprehensive lifecycle management for idmap entries, covering creation, reading, updating, and removal of mappings.
  • Enhanced Testing: Added new acceptance tests (TestAccResourceContainerIDMap) to validate the functionality across create, update, and delete operations, confirming no perpetual diffs.
Changelog
  • docs/resources/virtual_environment_container.md
    • Documented the new idmap block, including its purpose and sub-attributes (type, container_id, host_id, size).
  • fwprovider/test/resource_container_test.go
    • Added TestAccResourceContainerIDMap to thoroughly test the create, update, and delete functionality of idmap entries in containers.
  • proxmox/nodes/containers/containers_types.go
    • Defined new Go types CustomIDMaps and CustomIDMapEntry to represent UID/GID mapping data.
    • Implemented a custom UnmarshalJSON method for CustomIDMaps to parse lxc.idmap entries from the Proxmox API response, converting them into structured Go types.
    • Updated the GetResponseData struct to use the new CustomIDMaps type for the lxc field.
  • proxmox/nodes/containers/containers_types_test.go
    • Added a new file containing unit tests for the CustomIDMaps_UnmarshalJSON method, covering various scenarios including null, empty, single, multiple, and mixed idmap entries, as well as error handling for unknown types.
    • Included a test for GetResponseData_UnmarshalJSON_WithIDMaps to ensure correct unmarshalling of idmap data within the container response.
  • proxmoxtf/resource/container/container.go
    • Imported necessary proxmox and ssh packages.
    • Defined new constants for idmap block and its attributes.
    • Added the idmap schema block to the Container resource, including validation for type, container_id, host_id, and size fields.
    • Implemented containerGetIDMaps to convert Terraform schema data into CustomIDMaps Go types.
    • Implemented containerSetIDMaps to execute SSH commands for writing lxc.idmap entries to the container's configuration file.
    • Integrated idmap handling into containerCreateClone and containerCreateCustom functions to apply mappings during container creation.
    • Modified containerRead to properly read and set idmap data from the container configuration.
    • Updated containerUpdate to handle changes to the idmap block, applying updates via SSH and triggering a reboot if necessary.
    • Adjusted the containerUpdate logic to conditionally call UpdateContainer only if there are changes other than mkIDMap or if Delete fields are present, preventing unnecessary API calls when only idmap changes.
  • proxmoxtf/resource/container/container_test.go
    • Updated TestContainerSchema to include the new mkIDMap field in the list of expected schema attributes.
    • Added schema assertions for the idmap block, verifying its existence, required arguments, and value types.
Activity
  • The author has confirmed that make lint was run and issues were fixed.
  • Documentation for the new idmap feature has been updated.
  • Acceptance tests for the idmap functionality have been added and passed, covering create, update, and remove operations without perpetual diffs.
  • Backward compatibility has been considered, with no breaking schema changes introduced.
  • Proof of work includes detailed JSON outputs and SSH commands executed during acceptance tests, demonstrating successful idmap creation, modification, and removal.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This is a great feature addition, enabling idmap support for LXC containers. The implementation via SSH to work around API limitations is a clever solution. The code is well-structured, and the inclusion of comprehensive acceptance tests is excellent. I have one suggestion to improve the robustness of parsing idmap entries from the API response.

Comment thread proxmox/nodes/containers/containers_types.go Outdated
The Proxmox REST API does not support writing lxc[n] parameters (like
lxc.idmap) - it rejects them with "property is not defined in schema".
The API can read these entries but not write them.

Switch idmap CRUD operations to edit /etc/pve/lxc/<vmid>.conf directly
via SSH, following the same pattern used for VM disk imports in disk.go.
The API read path remains unchanged since GET returns lxc entries.

Signed-off-by: Piotr Niełacny <[email protected]>
@bpg-dev
Copy link
Copy Markdown
Member

bpg-dev commented Feb 17, 2026

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces valuable idmap support for LXC containers, and the SSH-based workaround for the API limitation is a practical approach. However, there are a couple of significant issues that need to be addressed before this can be merged.

Critical Issues:

  • Architectural Violation: This feature is implemented in the legacy SDK provider (proxmoxtf), but the project's contribution guidelines (GEMINI.md, line 51) require new features to be implemented in the modern Framework provider (fwprovider/) only. The acceptance tests are correctly placed in fwprovider/test, but the corresponding resource implementation for the framework provider is missing. This needs to be corrected.
  • Data Loss in API Parsing: The custom JSON unmarshaler for idmap entries discards all other lxc.* properties returned by the Proxmox API. This will break any functionality that relies on reading other LXC settings and should be fixed to avoid data loss. I've added a specific comment on this.

Suggestions:

  • Command Atomicity: The SSH commands used to update the container configuration file are not atomic. I've left a suggestion to improve the robustness of this operation by combining multiple commands into one.

Comment thread proxmox/nodes/containers/containers_types.go Outdated
Comment thread proxmoxtf/resource/container/container.go Outdated
LTe added 2 commits February 18, 2026 08:27
Restructure CustomIDMaps into CustomLXCConfig struct that holds both
the raw [][2]string from the API and the parsed idmap entries. This
prevents silent data loss of non-idmap LXC configuration entries
(e.g. lxc.cgroup2.*, lxc.cap.drop) during JSON unmarshaling.

Signed-off-by: Piotr Niełacny <[email protected]>
Consolidate per-entry SSH tee commands into a single write operation
to avoid leaving the config file in an inconsistent state if a
command fails mid-way.

Signed-off-by: Piotr Niełacny <[email protected]>
@LTe
Copy link
Copy Markdown
Contributor Author

LTe commented Feb 18, 2026

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for idmap in LXC containers by modifying the configuration file via SSH. The implementation is well-structured, includes thorough tests for both the parsing logic and the resource lifecycle, and updates the documentation. However, there is a critical concern regarding the project's architecture: the new feature is implemented in the legacy SDK provider, which contradicts the contribution guidelines stating that new features should be added to the modern framework provider. The implementation for the framework provider appears to be missing in this PR.

Comment thread proxmoxtf/resource/container/container.go
Copy link
Copy Markdown
Member

@bpg-dev bpg-dev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot @LTe for contributing this, solid work! ❤️

I made a few tweaks in the flow to ensure the ssh config update happens after the config file unlock, to prevent conflicts / overrides by PVE.
Also added the new requirements to sudoers file in docs.

LGTM! 🚀

@bpg bpg deleted a comment from allcontributors Bot Feb 21, 2026
@bpg-dev
Copy link
Copy Markdown
Member

bpg-dev commented Feb 21, 2026

@all-contributors please add @LTe for code

@allcontributors
Copy link
Copy Markdown
Contributor

@bpg-dev

I've put up a pull request to add @LTe! 🎉

@bpg-dev bpg-dev merged commit 63334e1 into bpg:main Feb 21, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants