Skip to content

Replace LDAP user management with extrausers file-based system#16

Draft
maltejk wants to merge 7 commits into
masterfrom
claude/remove-ldap-dependency-asnae
Draft

Replace LDAP user management with extrausers file-based system#16
maltejk wants to merge 7 commits into
masterfrom
claude/remove-ldap-dependency-asnae

Conversation

@maltejk
Copy link
Copy Markdown
Owner

@maltejk maltejk commented May 9, 2026

Summary

This PR removes the LDAP-based user management system and replaces it with a file-based approach using the libnss-extrausers library. User information is now synced to /var/lib/extrausers/passwd and /var/lib/extrausers/group files instead of being stored in an LDAP directory.

Key Changes

  • Removed LDAP dependencies: Eliminated mprov-django-ldapdb, python-ldap, and related LDAP packages from requirements
  • New extrausers module: Created src/borghive/lib/extrausers.py with sync_extrausers() function that atomically writes user data to extrausers passwd/group files
  • Updated RepositoryUser model: Replaced sync_to_ldap() method with sync_to_extrausers() that regenerates extrausers files from the database
  • Removed RepositoryLdapUser model: Deleted the LDAP model class and its migration, replaced with migration 0006_remove_repository_ldap_user.py to clean up the database
  • Updated signal handlers: Modified repository_user_created and repository_user_deleted signals to call the new extrausers sync function
  • Docker configuration:
    • Removed LDAP service from docker-compose files
    • Added extrausers-data volume to app, watcher, and borg services
    • Updated Dockerfile.borg to use libnss-extrausers instead of LDAP libraries
  • SSH/PAM configuration:
    • Updated nsswitch.conf to use extrausers instead of LDAP
    • Simplified pam-sshd.conf to use pam_permit instead of pam_ldap
    • Removed nslcd configuration from borg/init.sh
  • Helm charts: Removed LDAP-related environment variables and openldap dependency configuration
  • Settings: Removed LDAP database configuration and replaced with EXTRAUSERS_PATH setting

Implementation Details

The new system uses atomic file writes (write to temp file, then rename) to ensure consistency when updating user files. The sync_extrausers() function is called whenever a RepositoryUser is created, updated, or deleted, ensuring the extrausers files stay in sync with the database. This approach is simpler than LDAP and doesn't require a separate directory service.

https://claude.ai/code/session_01KEFp9XaE1Rreo5drdE8w73

claude added 5 commits May 9, 2026 16:48
Django now writes POSIX user entries atomically to a shared volume at
/var/lib/extrausers/passwd on every RepositoryUser save/delete.
The borg SSH container resolves those users via libnss-extrausers
instead of querying an OpenLDAP server over the network.

Removes: OpenLDAP container, NSLCD daemon, pam_ldap, mprov-django-ldapdb,
python-ldap, RepositoryLdapUser model, ldapdb DB backend and router.
Adds: extrausers-data shared volume, migration 0006 to drop any residual
LDAP table, BORGHIVE_EXTRAUSERS_PATH setting (default /var/lib/extrausers).

https://claude.ai/code/session_01KEFp9XaE1Rreo5drdE8w73
Migrations 0002-0005 still imported ldapdb.models.fields at the top
level, causing ModuleNotFoundError during test collection after python-ldap
was removed from requirements. The ldapdb import in 0005 was also used in
an AlterField operation for the now-removed RepositoryLdapUser model;
that operation is dropped.

Also add a TEST_MODE guard to sync_extrausers() itself so no code path
tries to write to /var/lib/extrausers during CI runs, and drop the
now-unused libsasl2-dev / libldap2-dev from the CI system deps.

https://claude.ai/code/session_01KEFp9XaE1Rreo5drdE8w73
extrausers.py (new file) and four pre-existing files failed the black
--check step in CI. Auto-formatted with black.

https://claude.ai/code/session_01KEFp9XaE1Rreo5drdE8w73
pylint 4.x removed the suggestion-mode option; comment it out in .pylintrc.
Add missing docstring to sync_to_extrausers to satisfy C0116.

https://claude.ai/code/session_01KEFp9XaE1Rreo5drdE8w73
setuptools>=81 removed pkg_resources, which pylama 8.4.1 still imports
at startup. Without the pin, pylama crashes with ModuleNotFoundError
on a clean install, which is exactly what CI does.

https://claude.ai/code/session_01KEFp9XaE1Rreo5drdE8w73
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented May 9, 2026

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 93.02326% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.21%. Comparing base (89376ff) to head (ed41319).

Files with missing lines Patch % Lines
...borghive/management/commands/watch_repositories.py 0.00% 1 Missing ⚠️
src/borghive/models/repository.py 75.00% 1 Missing ⚠️
src/borghive/signals.py 66.66% 1 Missing ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@            Coverage Diff             @@
##           master      #16      +/-   ##
==========================================
+ Coverage   84.28%   85.21%   +0.92%     
==========================================
  Files          60       61       +1     
  Lines        1222     1224       +2     
  Branches       77       79       +2     
==========================================
+ Hits         1030     1043      +13     
+ Misses        165      154      -11     
  Partials       27       27              
Flag Coverage Δ
unittests 85.21% <93.02%> (+0.92%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

claude added 2 commits May 9, 2026 19:30
Add 8 new tests covering _atomic_write (happy path, dir creation,
permissions, error cleanup, unlink failure swallowing) and
sync_extrausers (passwd content, empty list, TEST_MODE guard).
extrausers.py goes from 20% to 100% coverage.

Remove src/borghive/models/ldap.py — it was a 3-line re-export shim
with 0% coverage that nothing imported.

https://claude.ai/code/session_01KEFp9XaE1Rreo5drdE8w73
Add RepositoryUserSignalTest with a delete test that exercises the
post_delete signal handler (signals.py:40-41). All new lines introduced
in this PR are now covered.

https://claude.ai/code/session_01KEFp9XaE1Rreo5drdE8w73
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants