{"id":20358130,"url":"https://github.com/irods/irods_client_nfsrods","last_synced_at":"2025-04-12T03:15:19.620Z","repository":{"id":44606380,"uuid":"144880817","full_name":"irods/irods_client_nfsrods","owner":"irods","description":"An nfs4j Virtual File System implementation supporting the iRODS Data Grid","archived":false,"fork":false,"pushed_at":"2024-05-22T16:38:57.000Z","size":522,"stargazers_count":9,"open_issues_count":23,"forks_count":9,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-04-12T03:15:16.692Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/irods.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-08-15T17:06:56.000Z","updated_at":"2024-11-15T07:07:40.000Z","dependencies_parsed_at":"2024-05-21T00:25:15.083Z","dependency_job_id":"28195548-a7a1-44e0-97df-e0833b35d6a7","html_url":"https://github.com/irods/irods_client_nfsrods","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/irods%2Firods_client_nfsrods","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/irods%2Firods_client_nfsrods/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/irods%2Firods_client_nfsrods/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/irods%2Firods_client_nfsrods/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/irods","download_url":"https://codeload.github.com/irods/irods_client_nfsrods/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248510001,"owners_count":21116130,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-14T23:25:29.349Z","updated_at":"2025-04-12T03:15:19.601Z","avatar_url":"https://github.com/irods.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NFSRODS\nA standalone NFSv4.1 server (via [nfs4j](https://github.com/dCache/nfs4j)) with a Virtual File System implementation supporting the [iRODS Data Management Platform](https://irods.org).\n\n![NFSRODS network diagram](nfsrods_diagram.png)\n\n## Features\n- Configurable\n- Exposes iRODS through a mount point\n- Clients avoid the need for learning icommands\n- Clients avoid the need to install additional iRODS packages\n- Supports many common *nix commands and software (e.g. mkdir, cat, etc.)\n\n## Requirements\n- iRODS v4.2.9+\n- Docker (as of this writing, v20.10.7)\n- OS NFS packages (e.g. Ubuntu 18.04: nfs-common)\n\n## General Information\nThe following instructions assume you're running Ubuntu 18.04 and Bash.\n\n### Building (from source)\n```bash\n$ cd /path/to/irods_client_nfsrods\n$ bash build_jar.sh # Consider passing --non-interactive if building in an environment without TTY support.\n$ docker build -t local/nfsrods .\n```\n\n### Configuring\nThere are three config files located under `/path/to/irods_client_nfsrods/config`:\n- exports\n- log4j.properties\n- server.json\n\nThe first step in configuring the server is to copy these files into another location on disk like so:\n```bash\n$ mkdir ~/nfsrods_config\n$ cp /path/to/irods_client_nfsrods/config/* ~/nfsrods_config\n```\nThese files will be mounted into the NFSRODS docker container. This will be discussed later.\n\n#### Configuration File: exports\nAt this time, this file should not be modified. Administrators are expected to limit access to the mount point through other means.\n\n#### Configuration File: log4j.properties\nNFSRODS uses [Log4j 2](https://logging.apache.org/log4j/2.x/) for managing and writing log files. The default config will log messages with a level \u003e= `WARN` to `stdout`. Configuring Log4j is out of scope for this documentation.\n\n#### Configuration File: server.json\nYou'll need to set each option to match your iRODS environment. Each option is explained below.\n```javascript\n{\n    // This section defines options for the NFSRODS NFS server.\n    \"nfs_server\": {\n        // The port number within the container to listen for NFS requests.\n        \"port\": 2049,\n        \n        // The path within iRODS that will represent the root collection.\n        // We recommend setting this to the zone. Using the zone as the root\n        // collection allows all clients to access shared collections and data\n        // objects outside of their home collection.\n        \"irods_mount_point\": \"/tempZone\",\n\n        // The refresh time for cached user information.\n        \"user_information_refresh_time_in_milliseconds\": 3600000,\n\n        // The refresh time for cached stat information.\n        \"file_information_refresh_time_in_milliseconds\": 1000\n\n        // The refresh time for cached user access (NFS ACL) information.\n        \"user_access_refresh_time_in_milliseconds\": 1000,\n        \n        // The refresh time for cached iRODS object type information.\n        \"object_type_refresh_time_in_milliseconds\": 300000,\n        \n        // The refresh time for cached iRODS user permissions information.\n        \"user_permissions_refresh_time_in_milliseconds\": 300000,\n\n        // The refresh time for cached iRODS user type information.\n        \"user_type_refresh_time_in_milliseconds\": 300000,\n\n        // The refresh time for cached GenQuery results used to produce the\n        // output of a list operation.\n        \"list_operation_query_results_refresh_time_in_milliseconds\": 30000,\n\n        // Specifies whether the force flag should be applied when overwriting\n        // an existing file. If this option is false, an error will be reported\n        // back to the client.\n        \"allow_overwrite_of_existing_files\": true,\n\n        // Allows NFSRODS to make adjustments for running against an Oracle-backed\n        // iRODS deployment.\n        \"using_oracle_database\": false\n    },\n\n    // This section defines the location of the iRODS server being presented\n    // by NFSRODS. The NFSRODS server can only be configured to present a single iRODS zone.\n    \"irods_client\": {\n        \"host\": \"hostname\",\n        \"port\": 1247,\n        \"zone\": \"tempZone\",\n        \n        // Defines the target resource for new data objects.\n        \"default_resource\": \"demoResc\",\n\n        // Enables/disables SSL/TLS between NFSRODS and the iRODS server.\n        //\n        // The following options are available:\n        // - CS_NEG_REQUIRE: Only use SSL/TLS.\n        // - CS_NEG_DONT_CARE: Use SSL/TLS if the iRODS server is not set to CS_NEG_REFUSE.\n        // - CS_NEG_REFUSE: Do NOT use SSL/TLS.\n        \"ssl_negotiation_policy\": \"CS_NEG_REFUSE\",\n        \n        // The total amount of time before an idle connection times out.\n        // Defaults to 600 seconds.\n        \"connection_timeout_in_seconds\": 600,\n\n        // An administrative iRODS account is required to carry out each request.\n        // The account specified here is used as a proxy to connect to the iRODS\n        // server for some administrative actions. iRODS will still apply policies\n        // based on the requesting user's account, not the proxy admin account.\n        \"proxy_admin_account\": {\n            \"username\": \"rods\",\n            \"password\": \"rods\"\n        }\n    }\n}\n```\n\n### Running\nAfter updating the config file, you should be able to run the server using the following commands:\n```bash\n$ docker run -d --name nfsrods \\\n             -p \u003cpublic_port\u003e:2049 \\\n             -v \u003c/full/path/to/nfsrods_config\u003e:/nfsrods_config:ro \\\n             -v \u003c/full/path/to/etc/passwd/formatted/file\u003e:/etc/passwd:ro \\\n             local/nfsrods\n```\n\nThis command does the following:\n- Launches the container as a daemon\n- Names the container **nfsrods**\n- Exposes NFSRODS via the port `\u003cpublic_port\u003e`\n- Maps the local config directory into the container as read-only.\n- Maps the local `/etc/passwd` formatted file into the container as read-only.\n\n**IMPORTANT:** `/etc/passwd` is expected to contain all of the users planning to use NFSRODS. The users defined in this file **MUST** be defined in iRODS as well. Their usernames must match the names defined in this file exactly as this is how NFSRODS matches users to the correct account in iRODS.\n\nIf you want to see the output of the server, run the following command:\n```bash\n$ docker logs -f nfsrods\n```\nThis only works if the logging has been configured to write to stdout.\n\nOn startup, the NFSRODS server logs the build information (time, version, and git-SHA). You can get this information at any time by executing the following command:\n```bash\n$ docker run --rm nfsrods sha\n```\n\n#### SSL\n\nIf you want to connect NFSRODS to an iRODS Zone that is using SSL, a certificate file can be mounted for use within the container:\n```bash\n             -v \u003c/full/path/to/certificate.crt\u003e:/nfsrods_ssl.crt:ro\n```\n\nThe container will load any cert it finds at `/nfsrods_ssl.crt` within the container into the OpenJDK keystore.\n\n#### sssd integration\n\nAs an alternative to an `/etc/passwd` file, the default NFSRODS container also\nsupports `libnss-sss`. It can be used by configuring sssd on the container\nhost and binding the sssd socket into the container.\n\n```bash\n$ docker run -d --name nfsrods \\\n             -p \u003cpublic_port\u003e:2049 \\\n             -v \u003c/full/path/to/nfsrods_config\u003e:/nfsrods_config:ro \\\n             -v /var/lib/sss:/var/lib/sss \\\n             local/nfsrods\n```\n\nUsing sssd, NFSRODS can use any sssd domain for ID mapping, including AD or LDAP. If sssd and `/etc/passwd` are used together, passwd will be consulted first.\n\n#### Docker Compose\nUsing `docker run` to launch NFSRODS can be inconvenient given the number of arguments one has to pass. Docker Compose makes up for this by giving users the ability to define and run their applications in a manageable way.\n\nFor that reason, we've provided a `docker-compose.yml.template` file. Copy it to `docker-compose.yml`, point to your configuration directory, and then run.\n\n### Mounting\n```bash\n$ sudo mkdir \u003cmount_point\u003e\n$ sudo mount -o sec=sys,port=\u003cpublic_port\u003e \u003chostname\u003e:/ \u003cmount_point\u003e\n```\n\nIf you do not receive any errors after mounting, then you should be able to access the mount point like so:\n```bash\n$ cd \u003cmount_point\u003e/path/to/collection_or_data_object\n```\n\n#### Things To Consider\nDepending on your environment and deployment of NFSRODS, you may want to consider passing `lookupcache=none` to the mount command. This instructs the kernel to NOT cache directory entries which forces NFSRODS to lookup information about a directory on every request. While doing this will make NFSRODS less responsive, the benefit is that NFSRODS is less likely to leak information between users if they are operating within the same directory.\n\n## Unix Permissions and NFSv4 ACLs\nIn iRODS, multiple users and groups can be given different permissions on a collection or data object. Unix does not provide this capability and therefore, iRODS permissions cannot be mapped into Unix permissions without losing information. To get around this, NFSRODS uses NFSv4 ACLs.\n\n![NFSRODS ACLs](nfsrods_acls.png)\n\nNFSv4 ACLs provide more than enough control for reflecting iRODS permissions in Unix. To manage permissions through NFSRODS, you'll need to install the package that contains `nfs4_getfacl` and `nfs4_setfacl`. On Ubuntu 18.04, that package would be `nfs4-acl-tools`. With these commands, you can view and modify all permissions in iRODS.\n\n**IMPORTANT:** The order of ACEs within an ACL does not matter in NFSRODS. When NFSRODS has to decide whether a user is allowed to execute an operation, it takes the highest level of permission for that user (including groups the user is a member of).\n\n### Using nfs4_setfacl\nWhen using `nfs4_setfacl`, it's important to remember the following:\n- Domain names within the user and group name field are ignored.\n- Special ACE user/group names (e.g. OWNER, GROUP, EVERYONE, etc.) are not supported.\n- Unsupported permission bits are ignored.\n- The highest permission level provided is what NFSRODS will set as the permission.\n\nBelow is the permissions translation table used by NFSRODS when `nfs4_setfacl` is invoked. The list is in descending order of iRODS permissions.\n\n| NFSv4 ACE \u003cbr/\u003e Permission Bit | NFSv4 ACE \u003cbr/\u003e Permission Bit Name | iRODS \u003cbr/\u003e Permission |\n|:-------------------:|:------------------------:|:-----------:|\n| o                   | ACE4_WRITE_OWNER         | own         |\n| a                   | ACE4_APPEND_DATA         | write       |\n| w                   | ACE4_WRITE_DATA          | write       |\n| r                   | ACE4_READ_DATA           | read        |\n\n#### Example\nGiven the following:\n```bash\n$ nfs4_setfacl -a A::john@:ro foo.txt\n```\nNFSRODS will see that the **ACE4_READ_DATA** and **ACE4_WRITE_OWNER** bits are set. It then maps these to appropriate iRODS permissions and takes the max of those. NFSRODS will then set `john`'s permission on `foo.txt` to `own`.\n\n### Using nfs4_getfacl\nUsing this command is much simpler. When invoked, it returns the list of iRODS permissions on an object as an ACL. The mapping used for translation is shown below.\n\n| iRODS \u003cbr /\u003e Permission | NFSv4 ACE \u003cbr/\u003e Permission Bits |\n|:-----------:|:--------------------:|\n| own         | rwado                |\n| write       | rwa                  |\n| read        | r                    |\n\n### nfs4_setfacl Allowlist\nNFSRODS offers a allowlist for granting `nfs4_setfacl` permission to particular users.\n\nIf a user is in the allowlist or in a group in the allowlist, they can run `nfs4_setfacl` on the specified logical path or any collection or data object **below** it, regardless of their iRODS permissions on that collection or data object.\n\nA `rodsadmin` can add a user to the allowlist by adding a specific iRODS AVU (metadata) on the user.\n```bash\n$ imeta add -u \u003cusername\u003e irods::nfsrods::grant_nfs4_setfacl \u003clogical_path_prefix\u003e\n```\nThe following example demonstrates adding `alice#tempZone` to the allowlist with a prefix of `/tempZone/project_a/lab/notes`:\n```bash\n$ imeta add -u alice irods::nfsrods::grant_nfs4_setfacl /tempZone/project_a/lab/notes\n$ imeta ls -u alice\nAVUs defined for user alice#tempZone:\nattribute: irods::nfsrods::grant_nfs4_setfacl\nvalue: /tempZone/project_a/lab/notes\nunits:\n```\n\nA user can set permissions via `nfs4_setfacl` on a collection or data object if any of the following are true:\n1. The user is an iRODS administrator (i.e. `rodsadmin`).\n2. The user has `own` permission on the collection or data object.\n3. The user is a member of a group that has `own` permission on the collection or data object.\n4. The user is in the allowlist with a prefix that covers the collection or data object.\n5. The user is a member of a group in the allowlist with a prefix that covers the collection or data object.\n\n### Additional NFSv4 Information\n- [RFC 7530](https://tools.ietf.org/html/rfc7530)\n- [HOWTO: Use NFSv4 ACL](https://www.osc.edu/book/export/html/4523)\n\n## Notes\n- `chmod` is currently implemented as a `NOP` and will return `0`.\n- NFSRODS currently reports disk free (`df -a`) as `0` to avoid being misleading to other programs.\n- Resizing data objects requires iRODS 4.3.2 or later.\n\n## Limitations\n### Limitation 1: Write operations do not trigger replication on a replication resource\nThis is primarily due to NFSRODS being at the mercy of the client-side application. NFSRODS cannot make assumptions about what a client-side application will do with regard to multiple streams into a particular data object.\n\nSee https://github.com/irods/irods/issues/6142 for more details.\n\n**Workaround**: Configure NFSRODS to point at a resource hierarchy that does not contain a replication resource.\n\nA delay rule could be configured to replicate any data to the eventual target location (including the replication resource) or the [Storage Tiering Capability](https://github.com/irods/irods_capability_storage_tiering) could be leveraged to provide this more generally.\n\n## Troubleshooting\n### Q. The NFSRODS docker container won't start. Why?\nIt is likely that your `server.json` configuration is incorrect. To verify this, try running the container using `-it` instead of `-d` like so:\n```bash\n$ docker run -it --name nfsrods \\\n             -p \u003cpublic_port\u003e:2049 \\\n             -v \u003c/full/path/to/nfsrods_config\u003e:/nfsrods_config:ro \\\n             -v \u003c/full/path/to/etc/passwd/formatted/file\u003e:/etc/passwd:ro \\\n             nfsrods\n```\nThis command will cause the log messages to appear in your terminal. If there are any errors during start-up, they will appear in the output. Missing configuration options will have a prefix of **Missing server configuration option**.\n\n### Q. NFSRODS performs a lot of stat operations. Is there any way to decrease the number of stats?\nYes. There are a couple ways to improve performance. They are listed below:\n- Decrease the amount of logging. Try setting `logger.nfsrods.level` to `info` or higher.\n- Disable color output on `ls` output. Compare the timing of `/bin/ls` with `ls`.\n\n### Q. Listing large collections is extremely slow against an Oracle-backed iRODS zone. How do I fix this?\nIt is likely that your iRODS zone does not contain the correct specific queries for an Oracle database.\n\nYou'll need to verify that the SQL mapped to the following specific query names matches the SQL below.\n- ilsLACollections\n- ilsLADataObjects\n\nThe following command can be used to display the current SQL mapped to a specific query.\n```bash\n$ iquest --sql ls | grep -A1 \u003cspecific_query_name\u003e\n```\n\n#### SQL: ilsLACollections\n```sql\nSELECT * FROM (\n  SELECT c.parent_coll_name, c.coll_name, c.create_ts, c.modify_ts,\n         c.coll_id, c.coll_owner_name, c.coll_owner_zone, c.coll_type, u.user_name, u.zone_name,\n         a.access_type_id, u.user_id, rownum as limit_rn\n  FROM R_COLL_MAIN c\n  JOIN R_OBJT_ACCESS a ON c.coll_id = a.object_id\n  JOIN R_USER_MAIN u ON a.user_id = u.user_id\n  WHERE c.parent_coll_name = ?\n  ORDER BY c.coll_name, u.user_name, a.access_type_id, c.parent_coll_name, c.create_ts, c.modify_ts,\n           c.coll_id, c.coll_owner_name, c.coll_owner_zone, c.coll_type, u.zone_name, u.user_id DESC\n) WHERE limit_rn \u003e ? AND limit_rn \u003c= ?\n```\n\n#### SQL: ilsLADataObjects\n```sql\nSELECT * FROM (\n  SELECT s.coll_name, s.data_name, s.create_ts, s.modify_ts, s.data_id,\n         s.data_size, s.data_repl_num, s.data_owner_name, s.data_owner_zone, u.user_name,\n         u.user_id, a.access_type_id, u.user_type_name, u.zone_name, rownum as limit_rn\n  FROM (\n      SELECT c.coll_name, d.data_name, d.create_ts, d.modify_ts, d.data_id, d.data_repl_num,\n             d.data_size, d.data_owner_name, d.data_owner_zone\n      FROM R_COLL_MAIN c\n      JOIN R_DATA_MAIN d ON c.coll_id = d.coll_id\n      WHERE c.coll_name = ?\n  ) s\n  JOIN R_OBJT_ACCESS a ON s.data_id = a.object_id\n  JOIN R_USER_MAIN u ON a.user_id = u.user_id\n  ORDER BY s.coll_name, s.data_name, u.user_name, a.access_type_id, s.create_ts, s.modify_ts,\n           s.data_id, s.data_size, s.data_repl_num, s.data_owner_name, s.data_owner_zone,\n           u.user_id, u.user_type_name, u.zone_name DESC\n) WHERE limit_rn \u003e ? and limit_rn \u003c= ?\n```\n\nReplace (or add) the specific queries if they are incorrect. Use the following commands to add or remove a specific query.\n```bash\n$ iadmin asq \u003csql_query\u003e \u003cspecific_query_name\u003e # Adds a specific query.\n$ iadmin rsq \u003cspecific_query_name\u003e             # Removes a specific query.\n```\n\nOnce you have the specific queries in place, all that is left is to tell NFSRODS that the iRODS zone is backed by an Oracle database. To do this, set `using_oracle_database` to `true` in the NFSRODS configuration file.\nSee the [section on configuring NFSRODS](#configuring) for the location of this option.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Firods%2Firods_client_nfsrods","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Firods%2Firods_client_nfsrods","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Firods%2Firods_client_nfsrods/lists"}