diff --git a/.env.yml b/.env.yml index 3606ed6..f9f79e4 100644 --- a/.env.yml +++ b/.env.yml @@ -4,5 +4,5 @@ PLAYBOOK_DIR: ../../../../ # Relative to the default molecule.yml (molecule/ext/molecule-src/molecule.yml) ANSIBLE_VERBOSITY: '2' ANSIBLE_ROLES_PATH: ../../../roles # Relative to your scenario (e.g. molecule/role-foo/..) -ANSIBLE_STDOUT_CALLBACK: yaml +ANSIBLE_RESULT_FORMAT: yaml REQUIREMENTS_FILE: requirements.txt # Relative to the default molecule.yml diff --git a/.github/workflows/molecule.yml b/.github/workflows/molecule.yml index ab877cf..b8f2b6c 100644 --- a/.github/workflows/molecule.yml +++ b/.github/workflows/molecule.yml @@ -25,7 +25,7 @@ jobs: runs-on: ubuntu-latest env: ANSIBLE_FORCE_COLOR: '1' - ANSIBLE_STDOUT_CALLBACK: yaml + ANSIBLE_RESULT_FORMAT: yaml CRUN_VER: 1.11.2 REQUIREMENTS_FILE: molecule/ext/molecule-src/requirements.txt GALAXY_REQUIREMENTS_FILE: molecule/ext/molecule-src/requirements.yml diff --git a/README.md b/README.md index 846bac3..ffcfe89 100644 --- a/README.md +++ b/README.md @@ -58,13 +58,13 @@ To run `molecule`: * `pip install -r molecule/ext/molecule-src/requirements.txt` 1. Install the Ansible dependencies: * `ansible-galaxy install -r requirements.yml` -1. Run: `molecule -c molecule/ext/molecule-src/molecule.yml test` +1. Run: `molecule -c molecule/ext/molecule-src/molecule.yml test --all` -This will run the scenario in the `molecule/default` directory. +This will run all scenarios in the `molecule/` directory. To add and run a new scenario, simply: -1. Copy `molecule/default` into `molecule/`. +1. Copy `molecule/playbook-test` into `molecule/`. 1. Make your desired changes. 1. Run: `molecule -c molecule/ext/molecule-src/molecule.yml test -s ` diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml deleted file mode 100644 index 5b04fb0..0000000 --- a/molecule/default/molecule.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -provisioner: - name: ansible - env: - components: - - name: test_component - path: playbook.yml - parameters: - # Add parameters that you expect to be set in the ResearchCloud portal diff --git a/molecule/ext/molecule-src/.github/dependabot.yml b/molecule/ext/molecule-src/.github/dependabot.yml index 9d866e3..65c1d2e 100644 --- a/molecule/ext/molecule-src/.github/dependabot.yml +++ b/molecule/ext/molecule-src/.github/dependabot.yml @@ -9,3 +9,8 @@ updates: directory: "/" # Location of package manifests schedule: interval: "weekly" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + # Check for updates to GitHub Actions every week + interval: "weekly" diff --git a/molecule/ext/molecule-src/.github/workflows/ansible-lint.yml b/molecule/ext/molecule-src/.github/workflows/ansible-lint.yml index 30d0f3a..e29f837 100644 --- a/molecule/ext/molecule-src/.github/workflows/ansible-lint.yml +++ b/molecule/ext/molecule-src/.github/workflows/ansible-lint.yml @@ -12,6 +12,6 @@ jobs: name: Ansible Lint steps: # Important: This sets up your GITHUB_WORKSPACE environment variable - - uses: actions/checkout@v3 + - uses: actions/checkout@v6 - name: Run ansible-lint - uses: ansible/ansible-lint@v6.20.3 + uses: ansible/ansible-lint@v25.11.1 diff --git a/molecule/ext/molecule-src/.github/workflows/molecule.yml b/molecule/ext/molecule-src/.github/workflows/molecule.yml index 47cbdc1..a496fd3 100644 --- a/molecule/ext/molecule-src/.github/workflows/molecule.yml +++ b/molecule/ext/molecule-src/.github/workflows/molecule.yml @@ -16,7 +16,7 @@ jobs: DOCKER_PW: ${{ secrets.GITHUB_TOKEN }} DOCKER_REGISTRY: ghcr.io ANSIBLE_FORCE_COLOR: '1' - ANSIBLE_STDOUT_CALLBACK: yaml + ANSIBLE_RESULT_FORMAT: yaml MOLECULE_CONFIG: molecule/ext/molecule-src/molecule.yml REQUIREMENTS_FILE: requirements.txt PLAYBOOK_DIR: ../../../ # relative to molecule/ext/molecule-src/molecule.yml @@ -37,7 +37,7 @@ jobs: ] EOF - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - run: git clone https://github.com/UtrechtUniversity/SRC-molecule-test.git molecule - run: mkdir molecule/ext && cd molecule/ext && ln -s ../../ molecule-src - run: pip install -r ${{ env.REQUIREMENTS_FILE }} diff --git a/molecule/ext/molecule-src/converge.yml b/molecule/ext/molecule-src/converge.yml index a45d60b..513d9d5 100644 --- a/molecule/ext/molecule-src/converge.yml +++ b/molecule/ext/molecule-src/converge.yml @@ -6,7 +6,7 @@ - name: Debug -- list all components to be executed ansible.builtin.debug: msg: "{{ item.name }}" - with_items: "{{ lookup('env', 'components') }}" + with_items: "{{ lookup('env', 'components') | from_yaml }}" - name: Run components ansible.builtin.include_tasks: _run_component.yml @@ -17,4 +17,4 @@ parameters: "{{ item.parameters | default({}) | to_json }}" script_folder: "{{ item.name }}" path: "{{ item.path }}" - with_items: "{{ lookup('env', 'components') }}" + with_items: "{{ lookup('env', 'components') | from_yaml }}" diff --git a/molecule/ext/molecule-src/default.env.yml b/molecule/ext/molecule-src/default.env.yml index 6f07e00..1a566a9 100644 --- a/molecule/ext/molecule-src/default.env.yml +++ b/molecule/ext/molecule-src/default.env.yml @@ -5,4 +5,4 @@ PLAYBOOK_DIR: ../../../ # Relative to the default molecule.yml (molecule/ext/mol ANSIBLE_VERBOSITY: "2" ANSIBLE_ROLES_PATH: ../../roles # Relative to your scenario (e.g. molecule/role-foo/..) REQUIREMENTS_FILE: requirements.txt -ANSIBLE_STDOUT_CALLBACK: yaml +ANSIBLE_RESULT_FORMAT: yaml diff --git a/molecule/ext/molecule-src/prepare.yml b/molecule/ext/molecule-src/prepare.yml index 351a530..d09f1a3 100644 --- a/molecule/ext/molecule-src/prepare.yml +++ b/molecule/ext/molecule-src/prepare.yml @@ -23,7 +23,7 @@ rsync_opts: - --exclude=".*" ssh_connection_multiplexing: true - with_items: "{{ lookup('env', 'components') }}" + with_items: "{{ lookup('env', 'components') | from_yaml }}" # 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. diff --git a/molecule/ext/molecule-src/requirements.txt b/molecule/ext/molecule-src/requirements.txt index d9a0ad8..0747abd 100644 --- a/molecule/ext/molecule-src/requirements.txt +++ b/molecule/ext/molecule-src/requirements.txt @@ -1,6 +1,6 @@ # Default requirements file for running SRC molecule tests -molecule~=24.8 -molecule-plugins~=23.5 +molecule~=25.11 +molecule-plugins~=25.8 jmespath~=1.0 docker~=7.1 -podman~=5.0 +podman~=5.6 diff --git a/molecule/openwebui/molecule.yml b/molecule/openwebui/molecule.yml new file mode 100644 index 0000000..f638719 --- /dev/null +++ b/molecule/openwebui/molecule.yml @@ -0,0 +1,23 @@ +--- +driver: + name: ${DRIVER-podman} + image_settings: &image_settings + pre_build_image: true + registry: + url: $DOCKER_REGISTRY + credentials: + username: $DOCKER_USER + password: $DOCKER_PW +platforms: # Test on ubuntu jammy by default + - name: workspace-src-ubuntu_jammy + image: ghcr.io/utrechtuniversity/src-test-workspace:ubuntu_jammy + command: /sbin/init + <<: *image_settings +provisioner: + name: ansible + env: + components: + - name: test_component + path: playbook.yml + parameters: + model: smollm:135m diff --git a/molecule/default/verify.yml b/molecule/openwebui/verify.yml similarity index 100% rename from molecule/default/verify.yml rename to molecule/openwebui/verify.yml diff --git a/playbook.yml b/playbook.yml index dc2057b..9531a32 100644 --- a/playbook.yml +++ b/playbook.yml @@ -1,57 +1,12 @@ --- -- name: Example component - hosts: localhost # On ResearchCloud, the target host is always simply 'localhost'. - vars: - # You can define variables here. - # One use for this is to ensure that variables expected to be passed from the SRC portal have sane defaults. - # For example: - _src_component_foo: "{{ src_component_foo | default('fallback value') }}" - _src_component_bar: "Xone,Xtwo,Xthree" - _src_component_boolean: "{{ src_component_boolean | default(true, true) | bool }}" - # But of course you can also define ordinary variables: - testfile: /tmp/test - test_pip_packages: [] - gather_facts: true - +- name: Install and configure ollama serve + hosts: + - all + - localhost + gather_facts: false + vars: {} roles: - - role: uusrc.general.fact_regular_users - - tasks: - # Some example tasks below to introduce Ansible - - - name: Loop over all non-system users and display their names - ansible.builtin.debug: - msg: The user {{ item.user }} exists on the system. - with_items: "{{ fact_regular_users }}" - when: ansible_os_family == 'Debian' # we can use Ansible OS facts because we have set gather_facts to true - - - name: This is a block of tasks that belong together - when: _src_component_boolean # this condition is applied to all tasks in the block - tags: molecule-idempotence-notest # same for tags - block: - - - name: Copy some content to a file - ansible.builtin.copy: - dest: "{{ testfile }}" - mode: "0700" - owner: root - group: root - content: "{{ _src_component_bar | split | map('regex_replace', 'X', '') | join }}" # You can create pipes using filters - # src: foo.txt # instead of 'content', you can also pass the 'src' argument to copy an entire file - - - name: Cat the contents of this file - ansible.builtin.command: - cmd: cat {{ testfile }} - register: cat_testfile # store the results of this module in a new variable - - - name: Debug the results of our cat command - ansible.builtin.debug: - var: cat_testfile.stdout - - - name: Unlike the command module, shell module can use shell features like redirection - ansible.builtin.shell: - cmd: cat {{ testfile }} > /tmp/test2 - - - name: Install a number of pip packages - ansible.builtin.pip: # the pip module has many useful arguments, for instance related to venvs - name: "{{ test_pip_packages }}" + - role: ollama-serve + vars: + ollama_serve_model: "{{ model }}" + ollama_serve_version: "{{ ollama_version | default('0.12.10', true) }}" diff --git a/roles/ollama-serve/README.md b/roles/ollama-serve/README.md new file mode 100644 index 0000000..1ca5045 --- /dev/null +++ b/roles/ollama-serve/README.md @@ -0,0 +1,44 @@ +Role Name +========= + +A brief description of the role goes here. + +Requirements +------------ + +Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. + +Role Variables +-------------- + +A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. + +Dependencies +------------ + +A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. + +Example Playbook +---------------- + +Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: + + - hosts: servers + roles: + - { role: username.rolename, x: 42 } + +Run with + +```shell +ansible-playbook -i localhost, -b -c local ./playbook.yml +``` + +License +------- + +BSD + +Author Information +------------------ + +An optional section for the role authors to include contact information, or a website (HTML is not allowed). diff --git a/roles/ollama-serve/defaults/main.yml b/roles/ollama-serve/defaults/main.yml new file mode 100644 index 0000000..03b4c80 --- /dev/null +++ b/roles/ollama-serve/defaults/main.yml @@ -0,0 +1,9 @@ +#SPDX-License-Identifier: MIT-0 +--- +# defaults file for ollama-serve +ollama_serve_model_dir: /opt/ollama/models +ollama_serve_env: + OLLAMA_FLASH_ATTENTION: "1" + OLLAMA_MODELS: "{{ ollama_serve_model_dir }}" +ollama_serve_model: "" +ollama_serve_version: 12.0.10 diff --git a/roles/ollama-serve/handlers/main.yml b/roles/ollama-serve/handlers/main.yml new file mode 100644 index 0000000..eaa20f5 --- /dev/null +++ b/roles/ollama-serve/handlers/main.yml @@ -0,0 +1,3 @@ +#SPDX-License-Identifier: MIT-0 +--- +# handlers file for ollama-serve diff --git a/roles/ollama-serve/meta/main.yml b/roles/ollama-serve/meta/main.yml new file mode 100644 index 0000000..2db5d03 --- /dev/null +++ b/roles/ollama-serve/meta/main.yml @@ -0,0 +1,6 @@ +#SPDX-License-Identifier: MIT-0 +galaxy_info: + author: Stefan Verhoeven & Dawa Ometto + description: serve ollama + license: MIT + min_ansible_version: 2.1 diff --git a/roles/ollama-serve/tasks/main.yml b/roles/ollama-serve/tasks/main.yml new file mode 100644 index 0000000..eac2c0e --- /dev/null +++ b/roles/ollama-serve/tasks/main.yml @@ -0,0 +1,43 @@ +#SPDX-License-Identifier: MIT-0 +--- +# tasks file for ollama-serve +- name: ollama user + ansible.builtin.user: + name: ollama + system: true + create_home: true + +- name: Create model dir + ansible.builtin.file: + path: "{{ ollama_serve_model_dir }}" + state: directory + owner: ollama + group: ollama + mode: "0755" + +- name: Fetch and unarchive ollama + ansible.builtin.unarchive: + src: "{{ ollama_serve_tarball }}" + remote_src: true + dest: /opt/ollama + creates: /opt/ollama/bin/ollama + +- name: Place systemd config file + ansible.builtin.template: + dest: /etc/systemd/system/ollama-serve.service + src: templates/ollama-serve.service.j2 + mode: "0644" + +- name: Run ollama service + ansible.builtin.systemd: + name: ollama-serve + state: started + daemon_reload: true + enabled: true + +- name: Pull requested model + tags: molecule-idempotence-notest + ansible.builtin.command: + cmd: /opt/ollama/bin/ollama pull "{{ ollama_serve_model }}" + when: ollama_serve_model | length > 0 + delay: 10 diff --git a/roles/ollama-serve/templates/ollama-serve.service.j2 b/roles/ollama-serve/templates/ollama-serve.service.j2 new file mode 100644 index 0000000..9f03d0c --- /dev/null +++ b/roles/ollama-serve/templates/ollama-serve.service.j2 @@ -0,0 +1,16 @@ +[Unit] +Description=Service for Ollama +After=network.target + +[Service] +User=ollama +Group=ollama +StandardOutput=append:/var/log/ollama.log +StandardError=append:/var/log/ollama_err.log +{% for var_name, value in ollama_serve_env.items() %} +Environment="{{ var_name }}={{ value }}" +{% endfor %} +ExecStart=/opt/ollama/bin/ollama serve + +[Install] +WantedBy=multi-user.target diff --git a/roles/ollama-serve/tests/inventory b/roles/ollama-serve/tests/inventory new file mode 100644 index 0000000..03ca42f --- /dev/null +++ b/roles/ollama-serve/tests/inventory @@ -0,0 +1,3 @@ +#SPDX-License-Identifier: MIT-0 +localhost + diff --git a/roles/ollama-serve/tests/test.yml b/roles/ollama-serve/tests/test.yml new file mode 100644 index 0000000..5144190 --- /dev/null +++ b/roles/ollama-serve/tests/test.yml @@ -0,0 +1,6 @@ +#SPDX-License-Identifier: MIT-0 +--- +- hosts: localhost + remote_user: root + roles: + - ollama-serve diff --git a/roles/ollama-serve/vars/main.yml b/roles/ollama-serve/vars/main.yml new file mode 100644 index 0000000..e6822df --- /dev/null +++ b/roles/ollama-serve/vars/main.yml @@ -0,0 +1,4 @@ +#SPDX-License-Identifier: MIT-0 +--- +# vars file for ollama-serve +ollama_serve_tarball: https://github.com/ollama/ollama/releases/download/v{{ ollama_serve_version }}/ollama-linux-amd64.tgz \ No newline at end of file