Migrate the role
This commit is contained in:
46
roles/miniforge/README.md
Normal file
46
roles/miniforge/README.md
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
Role Name
|
||||||
|
=========
|
||||||
|
|
||||||
|
Install the Miniforge distribution for each supplied user and, optionally, deploy Mamba environment from provided YAML files.
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
------------
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Role Variables
|
||||||
|
--------------
|
||||||
|
|
||||||
|
`miniforge_release`: Miniforge release version
|
||||||
|
`miniforge_script_path`: where to download the installation script
|
||||||
|
`miniforge_release_base_url`: base URL
|
||||||
|
`miniforge_create_envs`: whethere to create environments for each user or not
|
||||||
|
|
||||||
|
`miniforge_users`: a list of dictionaries representing user accounts that need Miniforge
|
||||||
|
`manifest_dir`: path to folder on the Ansible controller host where environment files are kept
|
||||||
|
`miniforge_condarc`: a dictionary that will be YAMLified into the condarc file
|
||||||
|
|
||||||
|
NOTE: `miniforge_users` items must have `name` string attribute and, optionally, a `mamba_files` list attribute (filenames must be available under the `manifest_dir`).
|
||||||
|
|
||||||
|
Dependencies
|
||||||
|
------------
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Example Playbook
|
||||||
|
----------------
|
||||||
|
|
||||||
|
See `molecule` > `default` > `converge.yml`
|
||||||
|
|
||||||
|
----------------
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
|
||||||
|
BSD
|
||||||
|
|
||||||
|
Author Information
|
||||||
|
------------------
|
||||||
|
|
||||||
|
corvus-migratorius@proton.me
|
||||||
|
masayganova@gmail.com
|
||||||
5
roles/miniforge/defaults/main.yml
Normal file
5
roles/miniforge/defaults/main.yml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
miniforge_release: 24.3.0-0
|
||||||
|
miniforge_script_path: "/tmp/{{ miniforge_install_script_name }}.sh"
|
||||||
|
miniforge_release_base_url: "https://github.com/conda-forge/miniforge/releases/download/"
|
||||||
|
miniforge_create_envs: false
|
||||||
1
roles/miniforge/handlers/main.yml
Normal file
1
roles/miniforge/handlers/main.yml
Normal file
@@ -0,0 +1 @@
|
|||||||
|
---
|
||||||
17
roles/miniforge/meta/main.yml
Normal file
17
roles/miniforge/meta/main.yml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
role_name: miniforge
|
||||||
|
namespace: genlab
|
||||||
|
author: Alexander Gorelyshev
|
||||||
|
company: Genlab, LLC
|
||||||
|
description: Deploy the Miniforge distribution of the Mamba package manager
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: "2.1"
|
||||||
|
|
||||||
|
platforms:
|
||||||
|
- name: "Ubuntu"
|
||||||
|
versions: ["jammy", "noble"]
|
||||||
|
|
||||||
|
galaxy_tags: []
|
||||||
|
|
||||||
|
dependencies: []
|
||||||
29
roles/miniforge/molecule/default/converge.yml
Normal file
29
roles/miniforge/molecule/default/converge.yml
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
---
|
||||||
|
# you can use {{all_users | selectattr('name', 'in', mamba_users)}} to narrow down a larger list
|
||||||
|
- name: Converge
|
||||||
|
hosts: all
|
||||||
|
vars:
|
||||||
|
mamba_users:
|
||||||
|
- name: alice
|
||||||
|
mamba_files: [project-alpha.yml, project-beta.yml]
|
||||||
|
- name: bob
|
||||||
|
mamba_files: [project-alpha.yml, project-beta.yml]
|
||||||
|
- name: charlie
|
||||||
|
|
||||||
|
|
||||||
|
pre_tasks:
|
||||||
|
- name: "Create test users"
|
||||||
|
loop: [alice, bob, charlie]
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: present
|
||||||
|
create_home: true
|
||||||
|
|
||||||
|
roles:
|
||||||
|
- role: genlab.common.miniforge
|
||||||
|
miniforge_release: 24.3.0-0
|
||||||
|
miniforge_users: "{{ mamba_users }}"
|
||||||
|
manifest_dir: "manifests"
|
||||||
|
miniforge_create_envs: true
|
||||||
|
miniforge_condarc:
|
||||||
|
channels: [conda-forge]
|
||||||
10
roles/miniforge/molecule/default/manifests/project-alpha.yml
Normal file
10
roles/miniforge/molecule/default/manifests/project-alpha.yml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
name: env_alpha
|
||||||
|
channels:
|
||||||
|
- conda-forge
|
||||||
|
dependencies:
|
||||||
|
- python~=3.12
|
||||||
|
- pip>=22.2
|
||||||
|
- stress-ng==0.17.03
|
||||||
|
- pip:
|
||||||
|
- humanfriendly
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
name: cucubeta
|
||||||
|
channels:
|
||||||
|
- conda-forge
|
||||||
|
dependencies:
|
||||||
|
- python~=3.10
|
||||||
|
- pip>=22.2
|
||||||
|
- pip:
|
||||||
|
- arrow
|
||||||
27
roles/miniforge/molecule/default/molecule.yml
Normal file
27
roles/miniforge/molecule/default/molecule.yml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
dependency:
|
||||||
|
name: galaxy
|
||||||
|
|
||||||
|
driver:
|
||||||
|
name: docker
|
||||||
|
|
||||||
|
platforms:
|
||||||
|
- name: ubuntu
|
||||||
|
image: geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2204}-ansible:latest
|
||||||
|
pre_build_image: true
|
||||||
|
command: ${MOLECULE_DOCKER_COMMAND:-""}
|
||||||
|
volumes:
|
||||||
|
- /sys/fs/cgroup:/sys/fs/cgroup:rw
|
||||||
|
cgroupns_mode: host
|
||||||
|
privileged: true
|
||||||
|
|
||||||
|
provisioner:
|
||||||
|
name: ansible
|
||||||
|
|
||||||
|
verifier:
|
||||||
|
name: ansible
|
||||||
|
|
||||||
|
lint: |
|
||||||
|
set -e
|
||||||
|
yamllint .
|
||||||
|
ansible-lint .
|
||||||
50
roles/miniforge/molecule/default/verify.yml
Normal file
50
roles/miniforge/molecule/default/verify.yml
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
---
|
||||||
|
- name: Verify
|
||||||
|
hosts: all
|
||||||
|
gather_facts: false
|
||||||
|
any_errors_fatal: true
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: "Check Mamba installing correct tools from channels"
|
||||||
|
become: true
|
||||||
|
become_user: alice
|
||||||
|
changed_when: false
|
||||||
|
vars:
|
||||||
|
env: env_alpha
|
||||||
|
register: miniforge_tool_version
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: ~/miniforge3/envs/{{ env }}/bin/stress-ng --version
|
||||||
|
|
||||||
|
- name: "Verify the version of the installed tool"
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that: "'stress-ng, version 0.17.03' in miniforge_tool_version.stdout"
|
||||||
|
success_msg: "Correct version installed"
|
||||||
|
fail_msg: "Error: incorrect version installed"
|
||||||
|
|
||||||
|
- name: "Check the deployed environments for Alice (pip)"
|
||||||
|
become: true
|
||||||
|
become_user: alice
|
||||||
|
loop:
|
||||||
|
- { env: 'env_alpha', module: 'humanfriendly' }
|
||||||
|
- { env: 'cucubeta', module: 'arrow' }
|
||||||
|
changed_when: false
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: ~/miniforge3/envs/{{ item.env }}/bin/python -c 'import {{ item.module }}'
|
||||||
|
|
||||||
|
- name: "Check the deployed environments for Bob"
|
||||||
|
become: true
|
||||||
|
become_user: bob
|
||||||
|
loop:
|
||||||
|
- { env: 'cucubeta', module: 'arrow' }
|
||||||
|
changed_when: false
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: ~/miniforge3/envs/{{ item.env }}/bin/python -c 'import {{ item.module }}'
|
||||||
|
|
||||||
|
- name: "Check that no environments were deployed for Charlie"
|
||||||
|
become: true
|
||||||
|
become_user: charlie
|
||||||
|
register: miniforge_charlie_envs
|
||||||
|
failed_when: miniforge_charlie_envs.stdout_lines | length > 0
|
||||||
|
changed_when: false
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "ls ~/miniforge3/envs"
|
||||||
15
roles/miniforge/tasks/main.yml
Normal file
15
roles/miniforge/tasks/main.yml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
- name: "Download miniforge from '{{ miniforge_release_base_url }}'"
|
||||||
|
retries: 3
|
||||||
|
delay: 1
|
||||||
|
ansible.builtin.get_url:
|
||||||
|
timeout: 10
|
||||||
|
url: "{{ miniforge_release_base_url }}/{{ miniforge_release }}/{{ miniforge_install_script_name }}.sh"
|
||||||
|
dest: "{{ miniforge_script_path }}"
|
||||||
|
mode: "0664"
|
||||||
|
|
||||||
|
- name: "Deploy Mamba in a user loop"
|
||||||
|
loop: "{{ miniforge_users }}"
|
||||||
|
loop_control:
|
||||||
|
loop_var: user
|
||||||
|
ansible.builtin.include_tasks: "miniforge.yml"
|
||||||
24
roles/miniforge/tasks/manifests.yml
Normal file
24
roles/miniforge/tasks/manifests.yml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
- name: "Get contents of the manifest file"
|
||||||
|
register: miniforge_manifest_content
|
||||||
|
ansible.builtin.slurp:
|
||||||
|
src: "{{ miniforge_homedir }}/{{ file }}"
|
||||||
|
|
||||||
|
# Since the file can be named whatever, we need to extract the environment name
|
||||||
|
# as that is what the actual environment folder name will be
|
||||||
|
- name: "Extract enviroment name from manifest file"
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
miniforge_env_name: '{{ (miniforge_manifest_content.content | b64decode | from_yaml).name }}'
|
||||||
|
|
||||||
|
- name: "Display the extracted environment name"
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "{{ miniforge_env_name }}"
|
||||||
|
|
||||||
|
- name: "Create environment: {{ miniforge_env_name }}"
|
||||||
|
become: true
|
||||||
|
become_user: "{{ user.name }}"
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "{{ miniforge_homedir }}/miniforge3/bin/mamba env create -f {{ miniforge_homedir }}/{{ file }}"
|
||||||
|
executable: /bin/bash
|
||||||
|
# ensures that the task runs only when the environment doesn't exist
|
||||||
|
creates: "{{ miniforge_homedir }}/miniforge3/envs/{{ miniforge_env_name }}"
|
||||||
101
roles/miniforge/tasks/miniforge.yml
Normal file
101
roles/miniforge/tasks/miniforge.yml
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
---
|
||||||
|
# These variables are registered as host vars, for whatever deep reason
|
||||||
|
- name: "Get current user entity info ({{ user.name }})"
|
||||||
|
ansible.builtin.getent:
|
||||||
|
database: passwd
|
||||||
|
key: "{{ user.name }}"
|
||||||
|
split: ":"
|
||||||
|
|
||||||
|
- name: "Get current user home directory ({{ user.name }})"
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
miniforge_homedir: "{{ getent_passwd[user.name][4] }}"
|
||||||
|
|
||||||
|
- name: "Set miniforge dir ({{ user.name }})"
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
miniforge_dir: "{{ miniforge_homedir }}/miniforge3"
|
||||||
|
|
||||||
|
- name: "Build miniforge bin path ({{ user.name }})"
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
miniforge_mamba_bin_path: "{{ miniforge_dir }}/bin/mamba"
|
||||||
|
|
||||||
|
- name: "Display miniforge script path ({{ user.name }})"
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "{{ miniforge_script_path }}"
|
||||||
|
|
||||||
|
- name: "Install miniforge ({{ user.name }})"
|
||||||
|
become: true
|
||||||
|
become_user: "{{ user.name }}"
|
||||||
|
vars:
|
||||||
|
allow_world_readable_tmpfiles: true
|
||||||
|
block:
|
||||||
|
- name: "Check Mamba availability ({{ user.name }})"
|
||||||
|
changed_when: false
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "{{ miniforge_mamba_bin_path }} info"
|
||||||
|
rescue:
|
||||||
|
- name: "Install miniforge in a non-interactive mode ({{ user.name }})"
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "/bin/bash {{ miniforge_script_path }} -b"
|
||||||
|
creates: "{{ miniforge_homedir }}/miniforge3"
|
||||||
|
|
||||||
|
- name: "Initialize Mamba/Conda ({{ user.name }})"
|
||||||
|
changed_when: false
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "{{ miniforge_mamba_bin_path }} init"
|
||||||
|
|
||||||
|
- name: "Check if Mamba has become available ({{ user.name }})"
|
||||||
|
changed_when: false
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "{{ miniforge_mamba_bin_path }} info"
|
||||||
|
|
||||||
|
|
||||||
|
- name: "Deploy default .condarc if it doesn't exist already ({{ user.name }})"
|
||||||
|
become: true
|
||||||
|
become_user: "{{ user.name }}"
|
||||||
|
block:
|
||||||
|
- name: "Check if .condarc already exists ({{ user.name }})"
|
||||||
|
register: miniforge_condarc_stat
|
||||||
|
failed_when: miniforge_condarc_stat.stat.exists is false
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: "{{ miniforge_homedir }}/.condarc"
|
||||||
|
|
||||||
|
rescue:
|
||||||
|
- name: "Set default .condarc from external file if provided ({{ user.name }})"
|
||||||
|
when: condarc_file is defined and condarc_file != ""
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ condarc_file }}"
|
||||||
|
dest: "{{ miniforge_homedir }}/.condarc"
|
||||||
|
mode: "0600"
|
||||||
|
|
||||||
|
- name: "Set default content via .condarc ({{ user.name }})"
|
||||||
|
when: condarc_file is not defined or condarc_file == ""
|
||||||
|
ansible.builtin.copy:
|
||||||
|
dest: "{{ miniforge_homedir }}/.condarc"
|
||||||
|
content: "{{ miniforge_condarc | to_nice_yaml }}"
|
||||||
|
mode: "0600"
|
||||||
|
|
||||||
|
|
||||||
|
- name: "Deploy manifest files for user: {{ user.name }}"
|
||||||
|
when:
|
||||||
|
- "manifest_dir is defined"
|
||||||
|
- "user.mamba_files is defined"
|
||||||
|
loop: "{{ user.mamba_files }}"
|
||||||
|
become: true
|
||||||
|
become_user: "{{ user.name }}"
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ manifest_dir }}/{{ item }}"
|
||||||
|
dest: "{{ miniforge_homedir }}/{{ item }}"
|
||||||
|
owner: "{{ user.name }}"
|
||||||
|
group: "{{ user.name }}"
|
||||||
|
mode: "0660"
|
||||||
|
|
||||||
|
|
||||||
|
# Variables from the outer scope (like 'user') will get passed down to the included tasks
|
||||||
|
- name: "Create environments from deployed manifests for user: {{ user.name }}"
|
||||||
|
when:
|
||||||
|
- "miniforge_create_envs is true"
|
||||||
|
- "user.mamba_files is defined"
|
||||||
|
loop: "{{ user.mamba_files }}"
|
||||||
|
loop_control:
|
||||||
|
loop_var: file
|
||||||
|
ansible.builtin.include_tasks: "manifests.yml"
|
||||||
2
roles/miniforge/vars/main.yml
Normal file
2
roles/miniforge/vars/main.yml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
---
|
||||||
|
miniforge_install_script_name: "Miniforge3-{{ ansible_system }}-{{ ansible_architecture }}"
|
||||||
Reference in New Issue
Block a user