Skip to content

os.access() fails on NFSv4 filesystems #324

@asmacdo

Description

@asmacdo

Summary

babs init fails with "parent folder is not writable" on NFSv4 filesystems even when the user has full write permissions. This is because os.access() cannot interpret NFSv4 ACLs.

Additional details

  • BABS version (pip show babs): babs v0.5.4
  • DataLad version (datalad --version): datalad 1.3.0
  • Git version (git --version): git version 2.39.2
  • git-annex version (git-annex version: git-annex version: 10.20240831+git21-gd717e9aca0-1~ndall+1
  • datalad-container version (datalad containers-add --version): datalad_container 1.2.6
  • Singularity version (singularity --version): apptainer version 1.4.5-2.el8

Steps to Reproduce

  1. On an HPC cluster using NFSv4 ACLs, attempt to run babs init in a directory where you have write access via NFSv4 ACLs

  2. babs init fails with:

    ValueError: The parent folder '/path/to/dir' is not writable! `babs init` won't proceed.
    

Actual Error Output

Full traceback from `babs init`
`babs init` failed! Below is the error message:

Cleaning up created BABS project...

Created BABS project has been cleaned up.
Traceback (most recent call last):
  File "/dartfs/rc/lab/D/DBIC/DBIC/CON/asmacdo/preprocess-sandbox/babs-test/.venv/bin/babs", line 10, in <module>
    sys.exit(_main())
             ^^^^^^^
  File "/dartfs/rc/lab/D/DBIC/DBIC/CON/asmacdo/preprocess-sandbox/babs-test/.venv/lib64/python3.12/site-packages/babs/cli.py", line 722, in _main
    options.func(**args)
  File "/dartfs/rc/lab/D/DBIC/DBIC/CON/asmacdo/preprocess-sandbox/babs-test/.venv/lib64/python3.12/site-packages/babs/cli.py", line 199, in babs_init_main
    raise exc
  File "/dartfs/rc/lab/D/DBIC/DBIC/CON/asmacdo/preprocess-sandbox/babs-test/.venv/lib64/python3.12/site-packages/babs/cli.py", line 184, in babs_init_main
    babs_proj.babs_bootstrap(
  File "/dartfs/rc/lab/D/DBIC/DBIC/CON/asmacdo/preprocess-sandbox/babs-test/.venv/lib64/python3.12/site-packages/babs/bootstrap.py", line 76, in babs_bootstrap
    raise ValueError(
ValueError: The parent folder '/dartfs/rc/lab/D/DBIC/DBIC/CON/asmacdo/preprocess-sandbox' is not writable! `babs init` won't proceed.

Root Cause

bootstrap.py:81 uses os.access(parent_dir, os.W_OK) to check write permissions:

if not os.access(parent_dir, os.W_OK):
    raise ValueError(
        f"The parent folder '{parent_dir}' is not writable! `babs init` won't proceed."
    )

os.access() only checks POSIX permission bits. It cannot interpret NFSv4 ACLs, which are common on HPC networked filesystems.

Workaround: I commented out those lines, and babs init completed successfully.

NFSv4 ACL details

On Dartmouth Discovery, the directory has NFSv4 ACLs granting full access:

$ nfs4_getfacl /dartfs/rc/lab/D/DBIC/DBIC/CON/asmacdo/preprocess-sandbox
# file: /dartfs/rc/lab/D/DBIC/DBIC/CON/asmacdo/preprocess-sandbox
A::OWNER@:rwadxtTnNcy
A:fdi:OWNER@:rwadxtTnNcy
A:fdg:rc-DBIC-admin@KIEWIT.DARTMOUTH.EDU:rwaDdxtTnNcCoy
A:fd:GROUP@:rwadxtTnNcy
...

The w in rwadxtTnNcy confirms write permission. However, os.access(path, os.W_OK) returns False.

Affected Code

  1. bootstrap.py:81 - os.access(parent_dir, os.W_OK) - blocks babs init
  2. check_setup.py:180 - os.access(temp_fn, os.X_OK) - may block babs check-setup

Suggested Fix

Replace os.access() checks with EAFP (Easier to Ask Forgiveness than Permission) pattern - attempt the operation and catch PermissionError.

If necessary to catch the error earlier, maybe actually attempt to create a tempfile instead of using os.access

babs check-setup

This would probably fail for the same reason, but I never got to the check due to an unrelated bug. I just skipped check-setup and submit and merge completed!

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugIssues noting problems and PRs fixing those problems.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions