Skip to content
Draft
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
9cbd8d7
role fact_workspace_info: define venv fact here
dometto Mar 23, 2026
c4723f7
role irods_server: don't use pyton rules plugin
dometto Mar 23, 2026
f85cccc
role irods_server: add support for hooks
dometto Mar 23, 2026
6f23575
role irods_server: support external storage
dometto Mar 23, 2026
38eee31
role irods_server: small refactor
dometto Mar 23, 2026
fa64336
role irods_server: try removing hostname hacks
dometto Mar 23, 2026
a4c2ea0
role irods_server: allow enabling or disabling training config
dometto Mar 23, 2026
38ab55f
fix template loop
dometto Mar 23, 2026
2abb6c5
fix loop syntax
dometto Mar 23, 2026
801873b
add dependency for setup_irods.py
dometto Mar 23, 2026
3080ece
role irods_server: use system python for setup_irods.py
dometto Mar 23, 2026
2472a56
fix jinja newlines
dometto Mar 23, 2026
6251be5
simplify hooks
dometto Mar 23, 2026
80eda25
fix json template
dometto Mar 23, 2026
81b11fe
add tests
dometto Mar 23, 2026
0eba283
playbook irods_server: pass workspace fqdn var
dometto Mar 24, 2026
b66bd59
fix ternary
dometto Mar 24, 2026
6460ad4
attempt to fix config template for irods v5
dometto Mar 24, 2026
958d3ab
fix json
dometto Mar 24, 2026
92359b9
fix json
dometto Mar 24, 2026
62275dc
fix json for irods v5
dometto Mar 24, 2026
95154ea
optionally support python rules plugin
dometto Mar 24, 2026
9bb99f5
fix var name
dometto Mar 24, 2026
e0dc19d
fix json
dometto Mar 24, 2026
ba261d3
try supporting different irods versions
dometto Mar 24, 2026
8df229b
fix multiple version support
dometto Mar 24, 2026
1db829d
add service files for distinct versions
dometto Mar 24, 2026
ec2262d
fix
dometto Mar 24, 2026
9522d08
debug setup_irods call
dometto Mar 24, 2026
250379c
fix json
dometto Mar 24, 2026
fa0c624
more debug
dometto Mar 24, 2026
fd2e871
refactor systemd restarts
dometto Mar 24, 2026
d6c2aa0
Update playbooks/roles/irods_server/templates/server_unattended_confi…
dometto Mar 25, 2026
5fb4eb3
Update playbooks/roles/irods_server/templates/server_unattended_confi…
dometto Mar 25, 2026
4982a14
Update playbooks/roles/irods_server/templates/server_unattended_confi…
dometto Mar 25, 2026
c6e0cfc
implicit .re in hooks files default
dometto Mar 25, 2026
06a6401
debug fqdn
dometto Mar 25, 2026
90063de
Update iRODS service task to not fail on errors
dometto Mar 26, 2026
a3538b0
refactor handlers, add debug
dometto Mar 26, 2026
dfda43a
fix restart logic
dometto Mar 26, 2026
30be257
fix json
dometto Mar 26, 2026
552d1c8
Merge branch 'main' into irods_server_updates
dometto Apr 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion docs/roles/fact_regular_users.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ Defines the following facts:

- `fact_regular_users` -- list of dicts containing user info about regular users.
- `fact_co_groups` -- dict with group names from the CO as keys, and lists of usernames in those groups as values.
- `fact_src_ansible_venv` -- string path to the python environment currently being used by Ansible. Can be used to install additional `pip` dependencies for Ansible modules into the correct environment. Empty string if Ansible is not using a virtual environment (but instead the global system python environment).

## Requires
Linux flavor operating system.
Expand Down
1 change: 1 addition & 0 deletions docs/roles/fact_workspace_info.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Makes information about the workspace and CO available as Ansible facts. Provide
- `fact_workspace_info` -- Dict. Object containing info about the workspace (CO, user endpoint URL, etc.)/
- `fact_desktop_workspace` -- Boolean. True if the workspace has a desktop environment.
- `fact_workspace_storage` -- List. List of Strings of paths to ResearchCloud storage volumes mounted on the workspace.
- `fact_src_ansible_venv` -- string path to the python environment currently being used by Ansible. Can be used to install additional `pip` dependencies for Ansible modules into the correct environment. Empty string if Ansible is not using a virtual environment (but instead the global system python environment).

## Requires
Linux flavor operating system.
Expand Down
4 changes: 3 additions & 1 deletion playbooks/irods_server.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@
# irods server will use a local postgresql database

roles:
- irods_server
- role: irods_server
vars:
irods_server_host: "{{ workspace_fqdn | default(ansible_fqdn) }}"
2 changes: 2 additions & 0 deletions playbooks/roles/fact_regular_users/meta/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@ galaxy_info:
- name: EL
versions:
- all
dependencies:
- fact_workspace_info
9 changes: 0 additions & 9 deletions playbooks/roles/fact_regular_users/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,6 @@
- min
when: ansible_os_family is not defined

- name: Determine whether ansible is running in a virtual env
ansible.builtin.stat:
path: /etc/src/venv/src-venv
register: src_ansible_venv

- name: Set src_ansible_venv fact
ansible.builtin.set_fact:
fact_src_ansible_venv: "{{ src_ansible_venv.stat.exists | ternary('/etc/src/venv/src-venv', '') }}"

# jmespath is required for filter
- name: Install jmespath globally
when: not fact_src_ansible_venv # ansible is using the global python interpreter
Expand Down
9 changes: 9 additions & 0 deletions playbooks/roles/fact_workspace_info/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
---
- name: Determine whether ansible is running in a virtual env
ansible.builtin.stat:
path: /etc/src/venv/src-venv
register: src_ansible_venv

- name: Set src_ansible_venv fact
ansible.builtin.set_fact:
fact_src_ansible_venv: "{{ src_ansible_venv.stat.exists | ternary('/etc/src/venv/src-venv', '') }}"

- name: Get workspace.json file
ansible.builtin.command: cat /etc/rsc/workspace.json
changed_when: false
Expand Down
11 changes: 8 additions & 3 deletions playbooks/roles/irods_server/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
---
# Note: db_name must be lowercase
irods_server_version: ""
irods_server_admin_password: rods
irods_server_zone: tempZone
irods_server_host: "{{ ansible_fqdn }}"
irods_server_db_name: icat
irods_server_db_name: icat # must be lowercase
irods_server_db_username: irods
irods_server_db_password: db{{ irods_server_admin_password }}
irods_server_db_host: localhost
irods_server_db_port: 5432
irods_server_db_driver: "PostgreSQL ANSI"
irods_server_start: start
irods_server_core_re: false # set to a string to override default core rules
irods_server_hooks_files:
hooks.re: "{{ irods_server_hooks_training }}"
irods_server_default_rsc_name: trainingResc
irods_server_use_external_storage: true
irods_server_python_plugin: false
34 changes: 34 additions & 0 deletions playbooks/roles/irods_server/files/hooks_training.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
acPostProcForPut{
ON($objPath like "/$rodsZoneClient/home/$userNameClient/event/*"){
msiWriteRodsLog("LOGGING: object", *Status);
msiWriteRodsLog("$objPath triggered event hook", *Status);
msiAddKeyVal(*Keyval,"TRIGGER","acPostProcForPut");
msiGetObjType($objPath, *objType);
msiAssociateKeyValuePairsToObj(*Keyval,$objPath,*objType);
msiSetACL("default", "read", $userNameClient, $objPath);
msiWriteRodsLog("LOGGING END", *Status);
}
}

acPostProcForPut{
ON($objPath like "*/santa.txt"){
msiWriteRodsLog("$objPath triggered event hook", *Status);
msiGetObjType($objPath, *objType);
msiAddKeyVal(*Keyval,"Santa says","Merry Christmas!");
msiAssociateKeyValuePairsToObj(*Keyval,$objPath,*objType);
}
}

acPostProcForPut { }

acPostProcForCollCreate{
ON($collName like "/$rodsZoneClient/home/$userNameClient/event/*"){
msiWriteRodsLog("LOGGING: Collection", *Status);
msiWriteRodsLog("$collName triggered event hook", *Status);
msiAddKeyVal(*Keyval,"TRIGGER","acPostProcForCollCreate");
msiAssociateKeyValuePairsToObj(*Keyval,$collName,"-C");
msiWriteRodsLog("LOGGING END", *Status);
}
}

acPostProcForCollCreate { }
10 changes: 10 additions & 0 deletions playbooks/roles/irods_server/handlers/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
- name: Reload systemd service
ansible.builtin.systemd:
daemon_reload: true

- name: Restart irods
ansible.builtin.service:
enabled: true
name: irods
state: restarted
6 changes: 6 additions & 0 deletions playbooks/roles/irods_server/molecule/default/converge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
- name: Converge
hosts: all
gather_facts: true
roles:
- role: irods_server
20 changes: 20 additions & 0 deletions playbooks/roles/irods_server/molecule/default/molecule.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
platforms:
- name: workspace-src-ubuntu_jammy
image: ghcr.io/utrechtuniversity/src-test-workspace:ubuntu_jammy
command: /sbin/init
pre_build_image: true
privileged: true
registry:
url: $DOCKER_REGISTRY
credentials:
username: $DOCKER_USER
password: $DOCKER_PW
provisioner:
name: ansible
playbooks:
converge: ./converge.yml
prepare: ./prepare.yml
env:
ANSIBLE_ROLES_PATH: ../../../
role_name_check: 1
11 changes: 11 additions & 0 deletions playbooks/roles/irods_server/molecule/default/prepare.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
- name: Prepare
hosts: all
gather_facts: true
tasks:
# Apt cache is normally updated at deploy time by the SRC-OS component.
# Make sure it is fresh so our tests use recent apt repo information.
- name: Update apt cache
ansible.builtin.apt:
update_cache: true
when: ansible_os_family == 'Debian'
94 changes: 51 additions & 43 deletions playbooks/roles/irods_server/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,34 @@
ansible.builtin.package:
state: present
name:
- irods-server
- irods-database-plugin-postgres
- irods-rule-engine-plugin-python
- irods-icommands
- irods-server{% if irods_server_version %}={{ irods_server_version }}{% endif %}
- irods-database-plugin-postgres{% if irods_server_version %}={{ irods_server_version }}{% endif %}
- irods-icommands{% if irods_server_version %}={{ irods_server_version }}{% endif %}
- python3-distro # needed for the setup_irods.py script

- name: Install iRODS python rules plugin
when: irods_server_python_plugin
ansible.builtin.package:
state: present
name:
- irods-rule-engine-plugin-python{% if irods_server_version %}={{ irods_server_version }}{% endif %}

- name: Get installed packages
ansible.builtin.package_facts:

- name: Get irods major version
ansible.builtin.set_fact:
irods_server_version: "{{ ansible_facts.packages['irods-server'][0]['version'] | split('.') | list | first }}"

- name: Prepare systemd unit file for irods
notify: Reload systemd service
ansible.builtin.template:
src: irods.service.j2
src: irods.service_v{{ irods_server_version }}.j2
dest: /lib/systemd/system/irods.service
owner: root
group: root
mode: "0644"

- name: Reload systemd daemon
ansible.builtin.systemd:
daemon_reload: true

- name: Configure ODBC driver for Rocky 9+
ansible.builtin.set_fact:
irods_server_db_driver: "PostgreSQL"
when: ansible_pkg_mgr == 'dnf'

- name: Create ICAT database and db user and password protect PostgreSQL loopback access
ansible.builtin.include_tasks: icat.yml
args:
Expand All @@ -43,62 +49,64 @@
name: postgresql
state: restarted

- name: Register if iRODS server is initialized.
ansible.builtin.stat:
path: /etc/irods/server_config.json
register: irods_config_data

- name: Register FQDN (hack needed because hostname FQDN incomplete during workspace deployment)
ansible.builtin.set_fact:
irods_server_host: "{{ workspace_fqdn }}"
when: workspace_fqdn is defined

# below update of hostname ensures that demoResc iRODS resource will have proper host attribute
- name: Ensure hostname is FQDN (hack needed because hostname FQDN incomplete)
ansible.builtin.command: hostname "{{ workspace_fqdn }}"
when: workspace_fqdn is defined

- name: Generate zone key
ansible.builtin.command: openssl rand -hex 16
register: irods_server_zone_key
changed_when: false

- name: Generate negotiation key
ansible.builtin.command: openssl rand -hex 16
register: irods_server_negotiation_key
changed_when: false

- name: Generate control plane key
ansible.builtin.command: openssl rand -hex 16
register: irods_server_control_plane_key
changed_when: false

- name: Prepare iRODS server configuration file
when: not irods_config_data.stat.exists
ansible.builtin.template:
src: server_unattended_config.json.j2
src: server_unattended_config_v{{ irods_server_version }}.json.j2
dest: /etc/irods/server_unattended_config.json
owner: root
group: root
mode: "0600"
register: place_irods_config

- name: Bypass hostname check in iRODS setup (hack needed for irods 4.3.3 because workspace FQDN != localhost)
ansible.builtin.lineinfile:
path: /var/lib/irods/scripts/setup_irods.py
insertafter: ^def check_hostname
state: present
line: " return"
- name: Configure ruleset
notify: Restart irods
when: irods_server_core_re or irods_server_core_re == ""
ansible.builtin.copy:
content: "{{ irods_server_core_re }}"
dest: /etc/irods/core.re
mode: "0644"
force: false

- name: Configure empty python ruleset core.py
- name: Configure hooks
notify: Restart irods
loop: "{{ irods_server_hooks_files | dict2items }}"
ansible.builtin.copy:
content: ""
dest: /etc/irods/core.py
content: "{{ item.value }}"
dest: /etc/irods/{{ item.key }}
mode: "0644"
force: false

- name: Run irods configuration script
when: irods_server_start == "start"
ansible.builtin.command: python3 /var/lib/irods/scripts/setup_irods.py --json_configuration_file /etc/irods/server_unattended_config.json
when: place_irods_config.changed
notify: Restart irods
ansible.builtin.command: /var/lib/irods/scripts/setup_irods.py -v --json_configuration_file /etc/irods/server_unattended_config.json
failed_when: false
register: irods_config

- name: Debug config script output
ansible.builtin.debug:
msg: "{{ irods_config.stdout }}"

- name: Kill test server # debug

Check failure on line 105 in playbooks/roles/irods_server/tasks/main.yml

View workflow job for this annotation

GitHub Actions / Ansible Lint

command-instead-of-shell

Use shell only when shell functionality is required.
ansible.builtin.shell: killall -r "irods"
failed_when: false

- name: Start and enable iRODS as service
when: irods_server_start == "start"
ansible.builtin.service:
enabled: true
name: irods
Expand Down
17 changes: 17 additions & 0 deletions playbooks/roles/irods_server/templates/irods.service_v5.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[Unit]
Description=iRODS
After=network.target

[Service]
Type=notify
ExecStart=/usr/sbin/irodsServer
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
Restart=on-failure
User=irods
Group=irods
WorkingDirectory=/var/lib/irods
LimitNOFILE=1048576

[Install]
WantedBy=multi-user.target
Loading
Loading