From f0c9864021ddb58b259439ee644bede5a1063d9f Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 21 Feb 2023 14:21:33 +0100 Subject: [PATCH] Replace singularity with apptainer Except where used in combination with python ewatercycle package As https://github.com/eWaterCycle/ewatercycle/pull/324 has not been merged/released yet --- research-cloud-plugin.yml | 98 +++++++++---------- roles/apptainer/molecule/default/INSTALL.rst | 15 --- roles/apptainer/molecule/default/converge.yml | 8 -- roles/apptainer/molecule/default/create.yml | 35 ------- roles/apptainer/molecule/default/destroy.yml | 24 ----- roles/apptainer/molecule/default/molecule.yml | 11 --- roles/apptainer/molecule/default/verify.yml | 10 -- roles/apptainer/tests/test.yml | 3 +- roles/ewatercycle/README.md | 6 +- roles/ewatercycle/defaults/main.yml | 4 +- roles/ewatercycle/tasks/main.yml | 13 --- .../ewatercycle/templates/ewatercycle.yaml.j2 | 2 +- roles/prep_shared_data/README.md | 18 ++-- roles/prep_shared_data/defaults/main.yml | 22 ++--- .../tasks/apptainer-images.yml | 11 +++ roles/prep_shared_data/tasks/main.yml | 4 +- .../tasks/singularity-images.yml | 11 --- shared-data-disk.yml | 6 +- 18 files changed, 93 insertions(+), 208 deletions(-) delete mode 100644 roles/apptainer/molecule/default/INSTALL.rst delete mode 100644 roles/apptainer/molecule/default/converge.yml delete mode 100644 roles/apptainer/molecule/default/create.yml delete mode 100644 roles/apptainer/molecule/default/destroy.yml delete mode 100644 roles/apptainer/molecule/default/molecule.yml delete mode 100644 roles/apptainer/molecule/default/verify.yml create mode 100644 roles/prep_shared_data/tasks/apptainer-images.yml delete mode 100644 roles/prep_shared_data/tasks/singularity-images.yml diff --git a/research-cloud-plugin.yml b/research-cloud-plugin.yml index 7a2100fd..fb205f14 100644 --- a/research-cloud-plugin.yml +++ b/research-cloud-plugin.yml @@ -51,57 +51,57 @@ # Container engines - name: apptainer include_role: - name: ewatercycle.apptainer + name: apptainer # Install Conda + mamba - - name: Install conda - include_role: - name: conda - - # TODO mount a home and scratch disk, see https://github.com/eWaterCycle/infra/issues/89 - # - name: Scratch disk - # mount: - # path: /scratch - # src: # TODO find correct value, possibly extracted from SRC API or ansible vars/facts - # state: present - # - name: Home disk - # mount: - # path: /home - # src: # TODO find correct value, possibly extracted from SRC API or ansible vars/facts - # state: present - - - name: Mount shared data dcache with rclone - include_role: - name: rclone - tasks_from: mount - - # https://lab.ewatercycle.org/ functionality - - name: Welcome page - include_role: - name: labstart - - # https://explore.ewatercycle.org/ functionality - - name: Experiment launcher - include_role: - name: launcher - - - name: Explorer - include_role: - name: terria - - # https://jupyter.ewatercycle.org/ functionality - - name: Create eWaterCycle conda env - include_role: - name: ewatercycle - - - name: Set up Jupyter lab/hub - include_role: - name: jupyter - - - name: Clean apt cache - apt: - autoclean: yes - autoremove: yes + # - name: Install conda + # include_role: + # name: conda + + # # TODO mount a home and scratch disk, see https://github.com/eWaterCycle/infra/issues/89 + # # - name: Scratch disk + # # mount: + # # path: /scratch + # # src: # TODO find correct value, possibly extracted from SRC API or ansible vars/facts + # # state: present + # # - name: Home disk + # # mount: + # # path: /home + # # src: # TODO find correct value, possibly extracted from SRC API or ansible vars/facts + # # state: present + + # - name: Mount shared data dcache with rclone + # include_role: + # name: rclone + # tasks_from: mount + + # # https://lab.ewatercycle.org/ functionality + # - name: Welcome page + # include_role: + # name: labstart + + # # https://explore.ewatercycle.org/ functionality + # - name: Experiment launcher + # include_role: + # name: launcher + + # - name: Explorer + # include_role: + # name: terria + + # # https://jupyter.ewatercycle.org/ functionality + # - name: Create eWaterCycle conda env + # include_role: + # name: ewatercycle + + # - name: Set up Jupyter lab/hub + # include_role: + # name: jupyter + + # - name: Clean apt cache + # apt: + # autoclean: yes + # autoremove: yes - name: Debug debug: diff --git a/roles/apptainer/molecule/default/INSTALL.rst b/roles/apptainer/molecule/default/INSTALL.rst deleted file mode 100644 index 1b38d098..00000000 --- a/roles/apptainer/molecule/default/INSTALL.rst +++ /dev/null @@ -1,15 +0,0 @@ -*********************************** -Delegated driver installation guide -*********************************** - -Requirements -============ - -This driver is delegated to the developer. Up to the developer to implement -requirements. - -Install -======= - -This driver is delegated to the developer. Up to the developer to implement -requirements. diff --git a/roles/apptainer/molecule/default/converge.yml b/roles/apptainer/molecule/default/converge.yml deleted file mode 100644 index 3398fd09..00000000 --- a/roles/apptainer/molecule/default/converge.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -- name: Converge - hosts: all - gather_facts: false - tasks: - - name: "Include ewatercycle.apptainer" - ansible.builtin.include_role: - name: "ewatercycle.apptainer" diff --git a/roles/apptainer/molecule/default/create.yml b/roles/apptainer/molecule/default/create.yml deleted file mode 100644 index 09489e30..00000000 --- a/roles/apptainer/molecule/default/create.yml +++ /dev/null @@ -1,35 +0,0 @@ ---- -- name: Create - hosts: localhost - connection: local - gather_facts: false - no_log: "{{ molecule_no_log }}" - tasks: - - # TODO: Developer must implement and populate 'server' variable - - - when: server.changed | default(false) | bool - block: - - name: Populate instance config dict - ansible.builtin.set_fact: - instance_conf_dict: { - 'instance': "{{ }}", - 'address': "{{ }}", - 'user': "{{ }}", - 'port': "{{ }}", - 'identity_file': "{{ }}", } - with_items: "{{ server.results }}" - register: instance_config_dict - - - name: Convert instance config dict to a list - ansible.builtin.set_fact: - instance_conf: "{{ instance_config_dict.results | map(attribute='ansible_facts.instance_conf_dict') | list }}" - - - name: Dump instance config - ansible.builtin.copy: - content: | - # Molecule managed - - {{ instance_conf | to_json | from_json | to_yaml }} - dest: "{{ molecule_instance_config }}" - mode: 0600 diff --git a/roles/apptainer/molecule/default/destroy.yml b/roles/apptainer/molecule/default/destroy.yml deleted file mode 100644 index dd6e2203..00000000 --- a/roles/apptainer/molecule/default/destroy.yml +++ /dev/null @@ -1,24 +0,0 @@ ---- -- name: Destroy - hosts: localhost - connection: local - gather_facts: false - no_log: "{{ molecule_no_log }}" - tasks: - # Developer must implement. - - # Mandatory configuration for Molecule to function. - - - name: Populate instance config - ansible.builtin.set_fact: - instance_conf: {} - - - name: Dump instance config - ansible.builtin.copy: - content: | - # Molecule managed - - {{ instance_conf | to_json | from_json | to_yaml }} - dest: "{{ molecule_instance_config }}" - mode: 0600 - when: server.changed | default(false) | bool diff --git a/roles/apptainer/molecule/default/molecule.yml b/roles/apptainer/molecule/default/molecule.yml deleted file mode 100644 index 74c85572..00000000 --- a/roles/apptainer/molecule/default/molecule.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -dependency: - name: galaxy -driver: - name: delegated -platforms: - - name: instance -provisioner: - name: ansible -verifier: - name: ansible diff --git a/roles/apptainer/molecule/default/verify.yml b/roles/apptainer/molecule/default/verify.yml deleted file mode 100644 index e707420a..00000000 --- a/roles/apptainer/molecule/default/verify.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- -# This is an example playbook to execute Ansible tests. - -- name: Verify - hosts: all - gather_facts: false - tasks: - - name: Example assertion - ansible.builtin.assert: - that: true diff --git a/roles/apptainer/tests/test.yml b/roles/apptainer/tests/test.yml index f7346dc4..a8c9c4d1 100644 --- a/roles/apptainer/tests/test.yml +++ b/roles/apptainer/tests/test.yml @@ -1,5 +1,6 @@ --- -- hosts: localhost +- name: Test + hosts: localhost remote_user: root roles: - apptainer diff --git a/roles/ewatercycle/README.md b/roles/ewatercycle/README.md index 1eeddb2b..0ec1b83b 100644 --- a/roles/ewatercycle/README.md +++ b/roles/ewatercycle/README.md @@ -41,8 +41,8 @@ climate_data_root_dir: '{{ data_root }}/climate-data' grdc_location: '{{ data_root }}/observation/grdc/dailies' # Location where example parameter sets should be downloaded and where any other read-only pararmeter set can be put parameterset_dir: '{{ data_root }}/parameter-sets' -# Location where Singularity image files (*sif) of hydrological models should be stored -singularity_image_root: '{{ data_root }}/singularity-images' +# Location where Apptainer image files (*sif) of hydrological models should be stored +apptainer_image_root: '{{ data_root }}/singularity-images' # Location where all home-directories are located home_root: /home ``` @@ -52,7 +52,7 @@ Dependencies Conda should be installed in `conda_root` directory. Use [../conda](../conda) role to install conda. -Requires singularity executable which can be installed with [../singularity](../singularity) role. +Requires apptainer executable which can be installed with [../apptainer](../apptainer) role. Example Playbook ---------------- diff --git a/roles/ewatercycle/defaults/main.yml b/roles/ewatercycle/defaults/main.yml index 21d3f160..44d71460 100644 --- a/roles/ewatercycle/defaults/main.yml +++ b/roles/ewatercycle/defaults/main.yml @@ -13,7 +13,7 @@ climate_data_root_dir: '{{ data_root }}/climate-data' grdc_location: '{{ data_root }}/observation/grdc/dailies' # Location where example parameter sets should be downloaded and where any other read-only pararmeter set can be put parameterset_dir: '{{ data_root }}/parameter-sets' -# Location where Singularity image files (*sif) of hydrological models should be stored -singularity_image_root: '{{ data_root }}/singularity-images' +# Location where Apptainer image files (*sif) of hydrological models should be stored +apptainer_image_root: '{{ data_root }}/singularity-images' # Location where all home-directories are located home_root: /home diff --git a/roles/ewatercycle/tasks/main.yml b/roles/ewatercycle/tasks/main.yml index dc8f3a9f..994c9255 100644 --- a/roles/ewatercycle/tasks/main.yml +++ b/roles/ewatercycle/tasks/main.yml @@ -15,19 +15,6 @@ line: conda activate {{ conda_environment }} regexp: '^conda activate {{ conda_environment }}' -# Checklist system setup https://ewatercycle.readthedocs.io/en/latest/system_setup.html : -# Conda environment -> done on line 10 -# Install ewatercycle package -> done on line 18 -# Configure ESMValTool -> done on line 42-49 -# Download climate data -> from dcache mounted on /mnt/data -# Install container engine -> done in singularity role -# Configure ewatercycle -> done on line 51-54 -# Model container images -> from dcache mounted on /mnt/data -# Download example parameter sets -> from dcache mounted on /mnt/data -# Prepare other parameter sets -> from dcache mounted on /mnt/data -# Download example forcing -> from dcache mounted on /mnt/data -# Download observation data -> from dcache mounted on /mnt/data - # Loop over users in /home to copy .esmvaltool/config-user.yml using home_root=/home var - name: List my users shell: set -o pipefail && ls -1 | grep -v lost+found diff --git a/roles/ewatercycle/templates/ewatercycle.yaml.j2 b/roles/ewatercycle/templates/ewatercycle.yaml.j2 index 66abdcfe..f58aa383 100644 --- a/roles/ewatercycle/templates/ewatercycle.yaml.j2 +++ b/roles/ewatercycle/templates/ewatercycle.yaml.j2 @@ -102,4 +102,4 @@ parameter_sets: target_model: wflow supported_model_versions: !!set {2020.1.1: null, 2020.1.2: null, 2020.1.3: null} parameterset_dir: {{ parameterset_dir }} -singularity_dir: {{ singularity_image_root }} +singularity_dir: {{ apptainer_image_root }} diff --git a/roles/prep_shared_data/README.md b/roles/prep_shared_data/README.md index 362402e7..6e09224d 100644 --- a/roles/prep_shared_data/README.md +++ b/roles/prep_shared_data/README.md @@ -47,20 +47,20 @@ era5_variables: Variables for hydrological models ```yaml -# Docker container images that will be downloaded and converted to singularity image files +# Docker container images that will be downloaded and converted to Apptainer image files grpc4bmi_images: # - docker: ewatercycle/walrus-grpc4bmi - # singularity: ewatercycle-walrus-grpc4bmi.sif + # apptainer: ewatercycle-walrus-grpc4bmi.sif - docker: ewatercycle/pcrg-grpc4bmi:setters - singularity: ewatercycle-pcrg-grpc4bmi_setters.sif + apptainer: ewatercycle-pcrg-grpc4bmi_setters.sif - docker: ewatercycle/wflow-grpc4bmi:2020.1.1 - singularity: ewatercycle-wflow-grpc4bmi_2020.1.1.sif + apptainer: ewatercycle-wflow-grpc4bmi_2020.1.1.sif - docker: ewatercycle/marrmot-grpc4bmi:2020.11 - singularity: ewatercycle-marrmot-grpc4bmi_2020.11.sif + apptainer: ewatercycle-marrmot-grpc4bmi_2020.11.sif # - docker: ewatercycle/hype-grpc4bmi - # singularity: ewatercycle-hype-grpc4bmi.sif + # apptainer: ewatercycle-hype-grpc4bmi.sif - docker: ewatercycle/lisflood-grpc4bmi:20.10 - singularity: ewatercycle-lisflood-grpc4bmi_20.10.sif + apptainer: ewatercycle-lisflood-grpc4bmi_20.10.sif ``` Other optional variables @@ -68,8 +68,8 @@ Other optional variables ```yaml # Where all data should be put data_root: /mnt/data -# Directory where singularity sif files can be stored and read by other -singularity_image_root: '{{ data_root }}/singularity-images' +# Directory where apptainer sif files can be stored and read by other +apptainer_image_root: '{{ data_root }}/singularity-images' # Location where conda is installed conda_root: /opt/conda # Name of conda environment to use diff --git a/roles/prep_shared_data/defaults/main.yml b/roles/prep_shared_data/defaults/main.yml index a78568e7..ff288687 100644 --- a/roles/prep_shared_data/defaults/main.yml +++ b/roles/prep_shared_data/defaults/main.yml @@ -1,26 +1,26 @@ --- # Where all data should be put data_root: /mnt/data -# Directory where singularity sif files can be stored and read by other -singularity_image_root: '{{ data_root }}/singularity-images' -# Docker container images that will be downloaded and converted to singularity image files +# Directory where Apptainer sif files can be stored and read by other +apptainer_image_root: '{{ data_root }}/singularity-images' +# Docker container images that will be downloaded and converted to apptainer image files grpc4bmi_images: # - docker: ewatercycle/walrus-grpc4bmi - # singularity: ewatercycle-walrus-grpc4bmi.sif + # apptainer: ewatercycle-walrus-grpc4bmi.sif - docker: ewatercycle/pcrg-grpc4bmi:setters - singularity: ewatercycle-pcrg-grpc4bmi_setters.sif + apptainer: ewatercycle-pcrg-grpc4bmi_setters.sif - docker: ewatercycle/wflow-grpc4bmi:2020.1.1 - singularity: ewatercycle-wflow-grpc4bmi_2020.1.1.sif + apptainer: ewatercycle-wflow-grpc4bmi_2020.1.1.sif - docker: ewatercycle/wflow-grpc4bmi:2020.1.2 - singularity: ewatercycle-wflow-grpc4bmi_2020.1.2.sif + apptainer: ewatercycle-wflow-grpc4bmi_2020.1.2.sif - docker: ewatercycle/wflow-grpc4bmi:2020.1.3 - singularity: ewatercycle-wflow-grpc4bmi_2020.1.3.sif + apptainer: ewatercycle-wflow-grpc4bmi_2020.1.3.sif - docker: ewatercycle/marrmot-grpc4bmi:2020.11 - singularity: ewatercycle-marrmot-grpc4bmi_2020.11.sif + apptainer: ewatercycle-marrmot-grpc4bmi_2020.11.sif - docker: ewatercycle/lisflood-grpc4bmi:20.10 - singularity: ewatercycle-lisflood-grpc4bmi_20.10.sif + apptainer: ewatercycle-lisflood-grpc4bmi_20.10.sif - docker: ewatercycle/hype-grpc4bmi:feb2021 - singularity: ewatercycle-hype-grpc4bmi_feb2021.sif + apptainer: ewatercycle-hype-grpc4bmi_feb2021.sif # Location where conda is installed conda_root: /opt/conda # Name of conda environment to use diff --git a/roles/prep_shared_data/tasks/apptainer-images.yml b/roles/prep_shared_data/tasks/apptainer-images.yml new file mode 100644 index 00000000..98795c1f --- /dev/null +++ b/roles/prep_shared_data/tasks/apptainer-images.yml @@ -0,0 +1,11 @@ +--- +- name: Apptainer image dir + file: + path: '{{ apptainer_image_root }}' + state: directory + mode: 0755 +- name: grpc4bmi Apptainer images + command: apptainer build {{ apptainer_image_root }}/{{ item.apptainer }} docker://{{ item.docker }} + args: + creates: '{{ apptainer_image_root }}/{{ item.apptainer }}' + loop: '{{ grpc4bmi_images }}' diff --git a/roles/prep_shared_data/tasks/main.yml b/roles/prep_shared_data/tasks/main.yml index 13af04bb..d6abd021 100644 --- a/roles/prep_shared_data/tasks/main.yml +++ b/roles/prep_shared_data/tasks/main.yml @@ -3,8 +3,8 @@ include: climate-data.yml - name: ESMValTool aux data include: esmvaltool-aux-data.yml -- name: Build singularity image files (sif) for each model - include: singularity-images.yml +- name: Build apptainer image files (sif) for each model + include: apptainer-images.yml - name: Download example parameter sets include: example-parameter-sets.yml - name: Download example forcing diff --git a/roles/prep_shared_data/tasks/singularity-images.yml b/roles/prep_shared_data/tasks/singularity-images.yml deleted file mode 100644 index 6cfbc365..00000000 --- a/roles/prep_shared_data/tasks/singularity-images.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -- name: Singularity image dir - file: - path: '{{ singularity_image_root }}' - state: directory - mode: 0755 -- name: grpc4bmi Singularity images - command: singularity build {{ singularity_image_root }}/{{ item.singularity }} docker://{{ item.docker }} - args: - creates: '{{ singularity_image_root }}/{{ item.singularity }}' - loop: '{{ grpc4bmi_images }}' diff --git a/shared-data-disk.yml b/shared-data-disk.yml index 7f0546bb..a169b56d 100644 --- a/shared-data-disk.yml +++ b/shared-data-disk.yml @@ -7,15 +7,15 @@ cds_uid: null # Must be filled from other place cds_api_key: null # Must be filled from other place # To add more ERA5 variables edit or overwrite roles/prep_shared_data/defaults/main.yml#era5_variables - # To add more singularity images of hydrological models edit or overwrite roles/prep_shared_data/defaults/main.yml#era5_variables#grpc4bmi_images + # To add more apptainer images of hydrological models edit or overwrite roles/prep_shared_data/defaults/main.yml#era5_variables#grpc4bmi_images climate_begin_year: 1990 climate_end_year: 1990 # dCache token for uploading files dcache_rw_token: null # Must be filled from command line tasks: - - name: singularity + - name: apptainer include_role: - name: singularity + name: apptainer - name: Install conda include_role: