diff --git a/ansible/adhoc/deploy-pulp.yml b/ansible/adhoc/deploy-pulp.yml index 2858d032b..f7bafc3e0 100644 --- a/ansible/adhoc/deploy-pulp.yml +++ b/ansible/adhoc/deploy-pulp.yml @@ -1,15 +1,6 @@ -# Usage: ansible-playbook ansible/adhoc/deploy-pulp.yml -e "pulp_server=" - -- name: Add temporary pulp server host - hosts: localhost - tasks: - - ansible.builtin.add_host: - name: "{{ pulp_server }}" - group: "_pulp_host" - -- name: Install pulp on server and add to config +- name: Install pulp on server become: yes - hosts: _pulp_host + hosts: pulp_server tasks: - name: Install pulp ansible.builtin.include_role: @@ -22,5 +13,5 @@ debug: msg: | Server configured, override 'appliances_pulp_url' with - appliances_pulp_url: "http://{{ pulp_server }}:{{ pulp_site_port }}" - in your environments + appliances_pulp_url: "http://{{ hostvars[groups['pulp_server'] | first].ansible_host }}:{{ pulp_site_port }}" + (or the correct IP if multi-homed) in your environments diff --git a/ansible/adhoc/sync-pulp.yml b/ansible/adhoc/sync-pulp.yml index b2cd9a8c4..373f3abb8 100644 --- a/ansible/adhoc/sync-pulp.yml +++ b/ansible/adhoc/sync-pulp.yml @@ -6,5 +6,5 @@ vars: pulp_site_target_arch: "x86_64" pulp_site_target_distribution: "rocky" - pulp_site_target_distribution_version: "9.5" - pulp_site_target_distribution_version_major: "9" + # default distribution to *latest* specified for baseos repo: + pulp_site_target_distribution_version: "{{ dnf_repos_repos['baseos'].keys() | map('float') | sort | last }}" diff --git a/ansible/ci/update_timestamps.yml b/ansible/ci/update_timestamps.yml index e9a455a1e..8db475706 100644 --- a/ansible/ci/update_timestamps.yml +++ b/ansible/ci/update_timestamps.yml @@ -2,15 +2,15 @@ tasks: - name: Get latest timestamps from sources latest_timestamps: - repos_dict: "{{ appliances_pulp_repos }}" + repos_dict: "{{ dnf_repos_default }}" content_url: "https://ark.stackhpc.com/pulp/content" register: _result - name: Overwrite repo timestamps with latest ansible.builtin.copy: - dest: "{{ appliances_repository_root }}/environments/common/inventory/group_vars/all/timestamps.yml" + dest: "{{ appliances_repository_root }}/environments/common/inventory/group_vars/all/dnf_repo_timestamps.yml" content: "{{ repo_template | to_nice_yaml(indent=2) }}" backup: true vars: repo_template: - appliances_pulp_repos: "{{ _result.timestamps }}" + dnf_repos_default: "{{ _result.timestamps }}" diff --git a/ansible/fatimage.yml b/ansible/fatimage.yml index 839c8dc4a..46a99bc03 100644 --- a/ansible/fatimage.yml +++ b/ansible/fatimage.yml @@ -18,7 +18,7 @@ when: hook_path | exists - name: Sync pulp repos with upstream - hosts: pulp + hosts: pulp_site tasks: - ansible.builtin.include_role: name: pulp_site diff --git a/ansible/filter_plugins/utils.py b/ansible/filter_plugins/utils.py index b5b92ed7e..42b7107ee 100644 --- a/ansible/filter_plugins/utils.py +++ b/ansible/filter_plugins/utils.py @@ -61,11 +61,6 @@ def to_ood_regex(items): r = ['(%s)' % v for v in r] return '|'.join(r) -def appliances_repo_to_subpath(repo_entry): - """ Take an element from appliances_pulp_repos and convert it to a pulp path. This assumes that the remote and local pulp structures are the same - """ - return repo_entry['path'] + '/' + repo_entry['timestamp'] - class FilterModule(object): ''' Ansible core jinja2 filters ''' @@ -81,5 +76,4 @@ def filters(self): 'exists': exists, 'warn': self.warn, 'to_ood_regex': to_ood_regex, - 'appliances_repo_to_subpath': appliances_repo_to_subpath } diff --git a/ansible/library/latest_timestamps.py b/ansible/library/latest_timestamps.py index 6407ef049..0de388326 100644 --- a/ansible/library/latest_timestamps.py +++ b/ansible/library/latest_timestamps.py @@ -56,13 +56,12 @@ def run_module(): for version in timestamps[repo]: html_txt = requests.get( - url= module.params['content_url'] + '/' + timestamps[repo][version]['path'] + url= module.params['content_url'] + '/' + timestamps[repo][version]['pulp_path'] ).text timestamp_link_list = BeautifulSoup(html_txt,features="html.parser").body.find('pre').find_all() # getting raw list of timestamps from html timestamp_link_list = map(lambda x: x.string,timestamp_link_list) # stripping xml tags latest_timestamp = list(timestamp_link_list)[-1][:-1] # last timestamp in list with trailing / removed - timestamps[repo][version]['timestamp'] = latest_timestamp - + timestamps[repo][version]['pulp_timestamp'] = latest_timestamp result['timestamps'] = dict(sorted(timestamps.items())) module.exit_json(**result) diff --git a/ansible/roles/dnf_repos/README.md b/ansible/roles/dnf_repos/README.md new file mode 100644 index 000000000..ff22c79fc --- /dev/null +++ b/ansible/roles/dnf_repos/README.md @@ -0,0 +1,40 @@ +dnf_repos +========= + +Modifies repo definitions for repofiles in `/etc/yum.repos.d` to point to snapshots in StackHPC's Ark Pulp server or mirrors of them +on a local Pulp server. + +Requirements +------------ + +Requires Ark credentials if using StackHPC's upstream Ark server. + +Role Variables +-------------- + +Variables in this role are also required by `pulp_site` so set in +`environments/common/inventory/groups_vars/all/dnf_repos.yml`. See that file for detailed default values. + +- `dnf_repos_repos`: Dict of dicts containing information to construct URLs for Ark snapshots from the target Pulp server for each Rocky version. For example: + ``` + dnf_repos_repos: + appstream: # ansible.builtin.yum_repository:name + '8.10': # ansible_distribution_version or ansible_distribution_major_version + repo_file: Rocky-AppStream # yum_repository: file + # repo_name: # optional, override yum_repository:name + pulp_path: rocky/8.10/AppStream/x86_64/os # The subpath of the the upstream Ark server's content endpoint URL for the repo's snapshots, see https://ark.stackhpc.com/pulp/content/ + pulp_timestamp: 20250614T013846 + # pulp_content_url: # optional, dnf_repos_pulp_content_url + '9.6': + ... + ``` +- `dnf_repos_default`: Appliance default repos to use Ark snapshots for. Following same format as `dnf_repos_repos`. + See for appliance default repo list `environments/common/inventory/group_vars/all/dnf_repo_timestamps.yml`. +- `dnf_repos_extra`: Additional repos to use Ark snapshots for. Follows same format as + `dnf_repos_repos`. Defaults to `{}` +- `dnf_repos_pulp_content_url`: Optional str. Content URL of Pulp server to use Ark snapshots from. + Defaults to `{{ appliances_pulp_url }}/pulp/content` +- `dnf_repos_username`: Optional str. Username for Ark. Should be set if using upstream StackHPC Ark + Pulp server, but omitted if using local Pulp server (see `ansible/roles/pulp_site`) +- `dnf_repos_password`: Optional str. Password for Ark. Should be set if using upstream StackHPC Ark + Pulp server, but omitted if using local Pulp server (see `ansible/roles/pulp_site`) diff --git a/ansible/roles/dnf_repos/defaults/main.yml b/ansible/roles/dnf_repos/defaults/main.yml index 9302eff84..fe3c44e4f 100644 --- a/ansible/roles/dnf_repos/defaults/main.yml +++ b/ansible/roles/dnf_repos/defaults/main.yml @@ -1,54 +1,4 @@ +dnf_repos_repos: {} # see environments/common/inventory/group_vars/all/{dnf_repos,timestamps}.yml dnf_repos_pulp_content_url: "{{ appliances_pulp_url }}/pulp/content" dnf_repos_username: "{{ omit }}" dnf_repos_password: "{{ omit }}" - -dnf_repos_filenames: - '8': - baseos: 'Rocky-BaseOS' - appstream: 'Rocky-AppStream' - crb: 'Rocky-PowerTools' - extras: 'Rocky-Extras' - grafana: 'grafana' - '9': - baseos: 'rocky' - appstream: 'rocky' - crb: 'rocky' - extras: 'rocky-extras' - grafana: 'grafana' - -dnf_repos_version_filenames: "{{ dnf_repos_filenames[ansible_distribution_major_version] }}" - -# epel installed separately -dnf_repos_default_repolist: -- file: "{{ dnf_repos_version_filenames.baseos }}" - name: baseos - base_url: "{{ dnf_repos_pulp_content_url }}/{{ appliances_pulp_repos.baseos[ansible_distribution_version] | appliances_repo_to_subpath }}" -- file: "{{ dnf_repos_version_filenames.appstream }}" - name: appstream - base_url: "{{ dnf_repos_pulp_content_url }}/{{ appliances_pulp_repos.appstream[ansible_distribution_version] | appliances_repo_to_subpath }}" -- file: "{{ dnf_repos_version_filenames.crb }}" - name: "{{ 'powertools' if ansible_distribution_major_version == '8' else 'crb' }}" - base_url: "{{ dnf_repos_pulp_content_url }}/{{ appliances_pulp_repos.crb[ansible_distribution_version] | appliances_repo_to_subpath }}" -- file: "{{ dnf_repos_version_filenames.extras }}" - name: extras - base_url: "{{ dnf_repos_pulp_content_url }}/{{ appliances_pulp_repos.extras[ansible_distribution_version] | appliances_repo_to_subpath }}" -- file: ceph - name: Ceph - base_url: "{{ dnf_repos_pulp_content_url }}/{{ appliances_pulp_repos.ceph[ansible_distribution_major_version] | appliances_repo_to_subpath }}" -- file: "{{ dnf_repos_version_filenames.grafana }}" - name: grafana - base_url: "{{ dnf_repos_pulp_content_url }}/{{ appliances_pulp_repos.grafana[ansible_distribution_major_version] | appliances_repo_to_subpath }}" - -dnf_repos_openhpc_repolist: -- name: OpenHPC - file: OpenHPC - base_url: "{{ dnf_repos_pulp_content_url }}/{{ appliances_pulp_repos.openhpc_base[ansible_distribution_major_version] | appliances_repo_to_subpath }}" -- name: OpenHPC-updates - file: OpenHPC - base_url: "{{ dnf_repos_pulp_content_url }}/{{ appliances_pulp_repos.openhpc_updates[ansible_distribution_major_version] | appliances_repo_to_subpath }}" - -dnf_repos_extra_repolist: [] -dnf_repos_repolist: "{{ dnf_repos_default_repolist + (dnf_repos_openhpc_repolist if (openhpc_install_type | default('ohpc')) == 'ohpc' else []) + dnf_repos_extra_repolist }}" - -dnf_repos_epel_baseurl: "{{ dnf_repos_pulp_content_url }}/{{ appliances_pulp_repos.epel[ansible_distribution_major_version] | appliances_repo_to_subpath }}" -dnf_repos_epel_description: "epel" diff --git a/ansible/roles/dnf_repos/tasks/disable_repos.yml b/ansible/roles/dnf_repos/tasks/disable_repos.yml index 9f8abe6d9..4db073bc1 100644 --- a/ansible/roles/dnf_repos/tasks/disable_repos.yml +++ b/ansible/roles/dnf_repos/tasks/disable_repos.yml @@ -1,21 +1,20 @@ --- - name: Remove password and disable Pulp repos ansible.builtin.yum_repository: - file: "{{ item.file }}" - name: "{{ item.name }}" - baseurl: "{{ item.base_url }}" - description: "{{ item.name }}" + file: "{{ repo_values.repo_file }}" + name: "{{ repo_name }}" + baseurl: "{{ repo_content_url }}/{{ repo_values.pulp_path }}/{{ repo_values.pulp_timestamp }}" + description: "{{ repo_name }}" enabled: false - loop: "{{ dnf_repos_repolist }}" - -- name: Remove password and disable EPEL repo - ansible.builtin.yum_repository: - name: epel - file: epel - description: "{{ dnf_repos_epel_description }}" - baseurl: "{{ dnf_repos_epel_baseurl }}" gpgcheck: false - enabled: false + loop: "{{ dnf_repos_repos | dict2items }}" + loop_control: + label: "{{ repo_name }}[{{ repo_os }}]: {{ repo_values }}" + vars: + repo_os: "{{ ansible_distribution_version if ansible_distribution_version in item.value else ansible_distribution_major_version }}" + repo_values: "{{ item.value[repo_os] }}" + repo_name: "{{ repo_values.repo_name | default(item.key) }}" + repo_content_url: "{{ repo_values.pulp_content_url | default(dnf_repos_pulp_content_url) }}" - name: Get all repo files ansible.builtin.find: diff --git a/ansible/roles/dnf_repos/tasks/set_repos.yml b/ansible/roles/dnf_repos/tasks/set_repos.yml index c9fcb0c07..2db4de91b 100644 --- a/ansible/roles/dnf_repos/tasks/set_repos.yml +++ b/ansible/roles/dnf_repos/tasks/set_repos.yml @@ -1,27 +1,44 @@ --- -- name: Replace system repos with Pulp repos +- name: Replace non-epel repos with Pulp repos ansible.builtin.yum_repository: - file: "{{ item.file }}" - name: "{{ item.name }}" - baseurl: "{{ item.base_url }}" - description: "{{ item.name }}" + file: "{{ repo_values.repo_file }}" + name: "{{ repo_name }}" + baseurl: "{{ repo_content_url }}/{{ repo_values.pulp_path }}/{{ repo_values.pulp_timestamp }}" + description: "{{ repo_name }}" username: "{{ dnf_repos_username }}" password: "{{ dnf_repos_password }}" gpgcheck: false - loop: "{{ dnf_repos_repolist }}" + loop: "{{ dnf_repos_repos | dict2items }}" + loop_control: + label: "{{ repo_name }}[{{ repo_os }}]: {{ repo_values }}" + when: repo_name != 'epel' + vars: + repo_os: "{{ ansible_distribution_version if ansible_distribution_version in item.value else ansible_distribution_major_version }}" + repo_values: "{{ item.value[repo_os] }}" + repo_name: "{{ repo_values.repo_name | default(item.key) }}" + repo_content_url: "{{ repo_values.pulp_content_url | default(dnf_repos_pulp_content_url) }}" - name: Install epel-release - # done so that roles installing epel via epel-release don't over-write our changes to the epel repo + # So roles installing epel via epel-release don't overwrite changes to the epel repo below ansible.builtin.dnf: name: epel-release -- name: Use Pulp EPEL repo +- name: Replace epel repo with Pulp repo ansible.builtin.yum_repository: - name: epel - file: epel - description: "{{ dnf_repos_epel_description }}" - gpgcheck: false - baseurl: "{{ dnf_repos_epel_baseurl }}" + file: "{{ repo_values.repo_file }}" + name: "{{ repo_name }}" + baseurl: "{{ repo_content_url }}/{{ repo_values.pulp_path }}/{{ repo_values.pulp_timestamp }}" + description: "{{ repo_name }}" username: "{{ dnf_repos_username }}" password: "{{ dnf_repos_password }}" + gpgcheck: false + loop: "{{ dnf_repos_repos | dict2items }}" + loop_control: + label: "{{ repo_name }}[{{ repo_os }}]: {{ repo_values }}" + when: repo_name == 'epel' + vars: + repo_os: "{{ ansible_distribution_version if ansible_distribution_version in item.value else ansible_distribution_major_version }}" + repo_values: "{{ item.value[repo_os] }}" + repo_name: "{{ repo_values.repo_name | default(item.key) }}" + repo_content_url: "{{ repo_values.pulp_content_url | default(dnf_repos_pulp_content_url) }}" diff --git a/ansible/roles/pulp_site/README.md b/ansible/roles/pulp_site/README.md new file mode 100644 index 000000000..3af801cd2 --- /dev/null +++ b/ansible/roles/pulp_site/README.md @@ -0,0 +1,36 @@ +pulp_site +========= + +Contains playbooks to deploy a Pulp server and sync its content with repo snapshots in +StackHPC's Ark Pulp server + +Requirements +------------ + +Requires Ark credentials. The VM you are deploying Pulp on must allow ingress on `pulp_site_port` +and not be externally accessible (as the Pulp server's content is unauthenticated). Rocky Linux 9 has been +tested as the target VM for deploying Pulp. + +Role Variables +-------------- + +- `pulp_site_url`: Required str. The base url from which Pulp content will be hosted. Defaults to `{{ appliances_pulp_url }}`. + Value to set for ``appliances_pulp_url` will be generated and output by the deploy.yml playbook. +- `pulp_site_port`: Optional str. Port to serve Pulp server on. Defaults to `8080`. +- `pulp_site_username`: Optional str. Admin username for the Pulp server. Defaults to `admin`. +- `pulp_site_password`: Required str. Admin password for the Pulp server. Defaults to `{{ vault_pulp_admin_password }}`. +- `pulp_site_upstream_username`: Required str. Username for accessing content from the upstream Ark Pulp server. +- `pulp_site_upstream_password`: Required str. Password for upstream Ark Pulp server. +- `pulp_site_upstream_content_url`: Optional str. Content URL of upstream Ark Pulp. Defaults to `https://ark.stackhpc.com/pulp/content`. +- `pulp_site_install_dir`: Optional str. Directory on Pulp host to install config and persistent state to be mounted into Pulp container. Defaults to `/home/rocky/pulp`. +- `pulp_site_target_facts`: Optional str. The `ansible_facts` of a host which will be pulling from your Pulp server, allowing the role to auto-discover the necessary repos to pull. + defaults to `{{ hostvars[groups['pulp'][0]]['ansible_facts'] }}`. +- `pulp_site_target_distribution_version`: Optional str. The Rocky Linux minor release to sync repos from Ark for. Defaults to `{{ pulp_site_target_facts['distribution_version'] }}`. +- `pulp_site_rpm_repo_defaults`: Optional dict. Contains key value pairs for fields which are common to all repo definition in `pulp_site_rpm_repos`. Includes values for `remote_username`, + `remote_password` and `policy` by default. +- `pulp_site_rpm_repos`: Optional list of dicts. List of repo definitions in format required by the `stackhpc.pulp.pulp_repository`. Defaults to modified versions of repos defined in + `dnf_repos_all`. +- `pulp_site_rpm_publications`: Optional list of dicts. List of repo definitions in format required by the `stackhpc.pulp.pulp_publication`. Defaults to list of publications for repos defined in + `dnf_repos_all`. +- `pulp_site_rpm_distributions`: Optional list of dicts. List of repo definitions in format required by the `stackhpc.pulp.pulp_distribution`. Defaults to list of distributions for repos defined in + `dnf_repos_all`. diff --git a/ansible/roles/pulp_site/defaults/main.yml b/ansible/roles/pulp_site/defaults/main.yml index d30d1bdff..3d2bce7ec 100644 --- a/ansible/roles/pulp_site/defaults/main.yml +++ b/ansible/roles/pulp_site/defaults/main.yml @@ -2,43 +2,30 @@ pulp_site_url: "{{ appliances_pulp_url }}" pulp_site_port: 8080 pulp_site_username: admin # shouldn't be changed pulp_site_password: "{{ vault_pulp_admin_password }}" +# See environments/common/inventory/groups_vars/all/pulp.yml +# pulp_site_upstream_username: +# pulp_site_upstream_password: pulp_site_upstream_content_url: https://ark.stackhpc.com/pulp/content -pulp_site_default_upstream_suffix: "{{ pulp_site_target_arch }}/os" -pulp_site_validate_certs: false pulp_site_install_dir: '/home/rocky/pulp' -pulp_site_selinux_suffix: "{{ ':Z' if ansible_selinux.status == 'enabled' else '' }}" +_pulp_site_selinux_suffix: "{{ ':Z' if ansible_selinux.status == 'enabled' else '' }}" pulp_site_target_facts: "{{ hostvars[groups['pulp'][0]]['ansible_facts'] }}" -pulp_site_target_distribution_version: "{{ pulp_site_target_facts['distribution_version'] }}" -pulp_site_target_distribution_version_major: "{{ pulp_site_target_facts['distribution_major_version'] }}" - -pulp_site_rpm_info: -- name: "baseos-{{ pulp_site_target_distribution_version }}-{{ appliances_pulp_repos.baseos[pulp_site_target_distribution_version].timestamp }}" - subpath: "{{ appliances_pulp_repos.baseos[pulp_site_target_distribution_version] | appliances_repo_to_subpath }}" -- name: "appstream-{{ pulp_site_target_distribution_version }}-{{ appliances_pulp_repos.appstream[pulp_site_target_distribution_version].timestamp }}" - subpath: "{{ appliances_pulp_repos.appstream[pulp_site_target_distribution_version] | appliances_repo_to_subpath }}" -- name: "crb-{{ pulp_site_target_distribution_version }}-{{ appliances_pulp_repos.crb[pulp_site_target_distribution_version].timestamp }}" - subpath: "{{ appliances_pulp_repos.crb[pulp_site_target_distribution_version] | appliances_repo_to_subpath }}" -- name: "extras-{{ pulp_site_target_distribution_version }}-{{ appliances_pulp_repos.extras[pulp_site_target_distribution_version].timestamp }}" - subpath: "{{ appliances_pulp_repos.extras[pulp_site_target_distribution_version] | appliances_repo_to_subpath }}" -- name: "epel-{{ pulp_site_target_distribution_version_major }}-{{ appliances_pulp_repos.epel[pulp_site_target_distribution_version_major].timestamp }}" - subpath: "{{ appliances_pulp_repos.epel[pulp_site_target_distribution_version_major] | appliances_repo_to_subpath }}" -- name: "ohpc-{{ pulp_site_target_distribution_version_major }}-{{ appliances_pulp_repos.openhpc_base[pulp_site_target_distribution_version_major].timestamp }}" - subpath: "{{ appliances_pulp_repos.openhpc_base[pulp_site_target_distribution_version_major] | appliances_repo_to_subpath }}" -- name: "ohpc-updates-{{ pulp_site_target_distribution_version_major }}-{{ appliances_pulp_repos.openhpc_updates[pulp_site_target_distribution_version_major].timestamp }}" - subpath: "{{ appliances_pulp_repos.openhpc_updates[pulp_site_target_distribution_version_major] | appliances_repo_to_subpath }}" -- name: "ceph-{{ pulp_site_target_distribution_version_major }}-{{ appliances_pulp_repos.ceph[pulp_site_target_distribution_version_major].timestamp }}" - subpath: "{{ appliances_pulp_repos.ceph[pulp_site_target_distribution_version_major] | appliances_repo_to_subpath }}" -- name: "grafana-{{ pulp_site_target_distribution_version_major }}-{{ appliances_pulp_repos.grafana.timestamp[pulp_site_target_distribution_version_major].timestamp }} - subpath: "{{ appliances_pulp_repos.grafana[pulp_site_target_distribution_version_major] | appliances_repo_to_subpath }}" +pulp_site_target_distribution_version: "{{ pulp_site_target_facts['distribution_version'] }}" # TODO: how to set automatically? pulp_site_rpm_repo_defaults: remote_username: "{{ pulp_site_upstream_username }}" remote_password: "{{ pulp_site_upstream_password }}" policy: on_demand - state: present -_pulp_site_rpm_info_all: "{{ pulp_site_rpm_info | map('combine', pulp_site_rpm_repo_defaults) }}" +_pulp_site_rpm_info: | + {{ + dnf_repos_repos | + select_repos(pulp_site_target_distribution_version) + }} +pulp_site_rpm_repos: | + {{ + _pulp_site_rpm_info | + to_rpm_repos(pulp_site_upstream_content_url, pulp_site_rpm_repo_defaults) + }} -pulp_site_rpm_repos: "{{ _pulp_site_rpm_info_all | to_rpm_repos(pulp_site_upstream_content_url) }}" -pulp_site_rpm_publications: "{{ _pulp_site_rpm_info_all | to_rpm_pubs }}" -pulp_site_rpm_distributions: "{{ _pulp_site_rpm_info_all | to_rpm_distros }}" +pulp_site_rpm_publications: "{{ _pulp_site_rpm_info | to_rpm_pubs }}" +pulp_site_rpm_distributions: "{{ _pulp_site_rpm_info | to_rpm_distros }}" diff --git a/ansible/roles/pulp_site/files/pulp.service b/ansible/roles/pulp_site/files/pulp.service new file mode 100644 index 000000000..464961d23 --- /dev/null +++ b/ansible/roles/pulp_site/files/pulp.service @@ -0,0 +1,12 @@ +# Adapted from https://grimoire.carcano.ch/blog/installing-pulp3-as-a-container/ +[Unit] +Description=Pulp +Wants=syslog.service + +[Service] +Restart=always +ExecStart=/usr/bin/podman start -a pulp +ExecStop=/usr/bin/podman stop -t 15 pulp + +[Install] +WantedBy=multi-user.target diff --git a/ansible/roles/pulp_site/filter_plugins/pulp-list-filters.py b/ansible/roles/pulp_site/filter_plugins/pulp-list-filters.py index 50e912685..41e995c82 100644 --- a/ansible/roles/pulp_site/filter_plugins/pulp-list-filters.py +++ b/ansible/roles/pulp_site/filter_plugins/pulp-list-filters.py @@ -3,29 +3,61 @@ def filters(self): return { 'to_rpm_repos': self.to_rpm_repos, 'to_rpm_pubs': self.to_rpm_pubs, - 'to_rpm_distros': self.to_rpm_distros + 'to_rpm_distros': self.to_rpm_distros, + 'select_repos': self.select_repos, } - - def to_rpm_repos(self, list, pulp_url): - repo_list = map(lambda x: { - 'name': x['name'], - 'url': pulp_url+'/'+x['subpath'], - 'remote_username': x['remote_username'], - 'remote_password': x['remote_password'], - 'policy': x['policy'], - 'state': x['state'] }, list) - return repo_list + def select_repos(self, dnf_repos, target_distro_ver): + """ Filter dnf_repos to only those for a relevant distribution version (M.m or M). Returns a list of dicts. + Also adds pulp_repo_name field to give the repository a unique name in Pulp to be referenced by subsequent + filters + """ + + target_distro_ver_major = target_distro_ver.split('.')[0] + + rpm_repos = [] + for repokey in dnf_repos: + # select either the matching major.minor or major version: + if target_distro_ver in dnf_repos[repokey]: + selected_ver = target_distro_ver + elif target_distro_ver_major in dnf_repos[repokey]: + selected_ver = target_distro_ver_major + else: + raise ValueError(f'No key matching {target_distro_ver_major} or {target_distro_ver} found in f{repokey}') + repo_data = dnf_repos[repokey][selected_ver] + repo_data['pulp_repo_name'] = f"{repokey}-{selected_ver}-{dnf_repos[repokey][selected_ver]['pulp_timestamp']}" + rpm_repos.append(repo_data) + return rpm_repos + + def to_rpm_repos(self, rpm_info, content_url, repo_defaults): + """ Filter repo object list given by select_repos into dict required by the pulp_repository_rpm_repos variable + from stackhpc.pulp.pulp_repository role + """ + rpm_repos = [] + for repo_data in rpm_info: + rpm_data = repo_defaults.copy() # NB: this changes behaviour vs before, so now defaults can correctly be overriden + rpm_data['name'] = repo_data['pulp_repo_name'] + rpm_data['url'] = '/'.join([content_url, repo_data['pulp_path'], repo_data['pulp_timestamp']]) + rpm_data['state'] = 'present' + rpm_repos.append(rpm_data) + return rpm_repos + def to_rpm_pubs(self, list): + """ Filter repo object list given by select_repos into dict required by the pulp_publication_rpm variable + from stackhpc.pulp.pulp_publication role + """ pub_list = map(lambda x: { - 'repository': x['name'], - 'state': x['state'] }, list) + 'repository': x['pulp_repo_name'], + 'state': 'present' }, list) return pub_list def to_rpm_distros(self, list): + """ Filter repo object list given by select_repos into dict required by the pulp_distirubtion_rpm variable + from stackhpc.pulp.pulp_distribution role + """ distro_list = map(lambda x: { - 'name': x['name'], - 'repository': x['name'], - 'base_path': x['subpath'], - 'state': x['state'] }, list) - return distro_list \ No newline at end of file + 'name': x['pulp_repo_name'], + 'repository': x['pulp_repo_name'], + 'base_path': '/'.join([x['pulp_path'],x['pulp_timestamp']]), + 'state': 'present' }, list) + return distro_list diff --git a/ansible/roles/pulp_site/tasks/install.yml b/ansible/roles/pulp_site/tasks/install.yml index 39b4fcd97..75b0f66cb 100644 --- a/ansible/roles/pulp_site/tasks/install.yml +++ b/ansible/roles/pulp_site/tasks/install.yml @@ -26,13 +26,27 @@ publish: - "{{ pulp_site_port }}:80" volume: - - "{{ pulp_site_install_dir }}/settings:/etc/pulp{{ pulp_site_selinux_suffix }}" - - "{{ pulp_site_install_dir }}/pulp_storage:/var/lib/pulp{{ pulp_site_selinux_suffix }}" - - "{{ pulp_site_install_dir }}/pgsql:/var/lib/pgsql{{ pulp_site_selinux_suffix }}" - - "{{ pulp_site_install_dir }}/containers:/var/lib/containers{{ pulp_site_selinux_suffix }}" + - "{{ pulp_site_install_dir }}/settings:/etc/pulp{{ _pulp_site_selinux_suffix }}" + - "{{ pulp_site_install_dir }}/pulp_storage:/var/lib/pulp{{ _pulp_site_selinux_suffix }}" + - "{{ pulp_site_install_dir }}/pgsql:/var/lib/pgsql{{ _pulp_site_selinux_suffix }}" + - "{{ pulp_site_install_dir }}/containers:/var/lib/containers{{ _pulp_site_selinux_suffix }}" device: /dev/fuse image: docker.io/pulp/pulp:3.68.1 + state: present +- name: Create systemd file + copy: + src: pulp.service + dest: /etc/systemd/system/pulp.service + register: _pulp_service + +- name: Start Pulp service + systemd: + name: pulp + state: "{{ 'started' if _pulp_service.changed else 'restarted' }}" + daemon_reload: "{{ _pulp_service.changed }}" + enabled: true + - name: Reset admin password once container has initialised no_log: true ansible.builtin.shell: diff --git a/ansible/roles/pulp_site/tasks/sync.yml b/ansible/roles/pulp_site/tasks/sync.yml index 5ef2bc5f1..9a2a93210 100644 --- a/ansible/roles/pulp_site/tasks/sync.yml +++ b/ansible/roles/pulp_site/tasks/sync.yml @@ -3,17 +3,7 @@ - ansible.builtin.assert: that: pulp_site_upstream_password != '' quiet: true - fail_msg: "Upstream password not set. Either set env var ARK_PASSWORD or override pulp_site_upstream_password." - -- name: Wait for Pulp server - pulp.squeezer.status: - pulp_url: "{{ pulp_site_url }}" - username: "{{ pulp_site_username }}" - password: "{{ pulp_site_password }}" - register: _pulp_status - until: _pulp_status.failed == false - retries: 30 - delay: 20 + fail_msg: "Upstream password not set. Ensure `pulp_site_upstream_username` and `pulp_site_upstream_password` are overriden to your Ark credentials." - name: Ensure Pulp CLI config directory exists ansible.builtin.file: @@ -27,6 +17,16 @@ dest: ~/.config/pulp/cli.toml mode: '0644' +- name: Wait for Pulp server + pulp.squeezer.status: + pulp_url: "{{ pulp_site_url }}" + username: "{{ pulp_site_username }}" + password: "{{ pulp_site_password }}" + register: _pulp_status + until: _pulp_status.failed == false + retries: 30 + delay: 20 + - block: - name: Ensure squeezer cache exists ansible.builtin.file: diff --git a/ansible/roles/pulp_site/templates/cli.toml.j2 b/ansible/roles/pulp_site/templates/cli.toml.j2 index 06867902f..c67dcf393 100644 --- a/ansible/roles/pulp_site/templates/cli.toml.j2 +++ b/ansible/roles/pulp_site/templates/cli.toml.j2 @@ -4,7 +4,6 @@ username = "{{ pulp_site_username }}" password = "{{ pulp_site_password }}" api_root = "/pulp/" domain = "default" -headers = [] cert = "" key = "" verify_ssl = true diff --git a/docs/environments.md b/docs/environments.md index d1c492312..183b775ee 100644 --- a/docs/environments.md +++ b/docs/environments.md @@ -14,7 +14,10 @@ All environments load the inventory from the `common` environment first, with th The ansible inventory for the environment is in `environments//inventory/`. It should generally contain: - A `hosts` file. This defines the hosts in the appliance. Generally it should be templated out by the deployment automation so it is also a convenient place to define variables which depend on the deployed hosts such as connection variables, IP addresses, ssh proxy arguments etc. -- A `groups` file defining ansible groups, which essentially controls which features of the appliance are enabled and where they are deployed. This repository generally follows a convention where functionality is defined using ansible roles applied to a group of the same name, e.g. `openhpc` or `grafana`. The meaning and use of each group is described in comments in `environments/common/inventory/groups`. As the groups defined there for the common environment are empty, functionality is disabled by default and must be enabled in a specific environment's `groups` file. Two template examples are provided in `environments/commmon/layouts/` demonstrating a minimal appliance with only the Slurm cluster itself, and an appliance with all functionality. +- A `groups` file defining ansible groups, which essentially controls which features of the appliance are enabled and where they are deployed. This repository generally follows a convention where functionality is defined using ansible roles applied to a group +of the same name, e.g. `openhpc` or `grafana`. The meaning and use of each group is described in comments in `environments/common/inventory/groups`. As the groups defined there for the common environment are empty, functionality is disabled by default and must be +enabled in a specific environment's `groups` file. The `site` environment contains an ini file at `environments/site/inventory/groups` which enables groups for default appliance functionality across all environments. Additional groups should generally also be +enabled in this file to avoid divergence between staging and production environments. Note that enabling some groups may require a site-specific image build and Ark credentials (see [operations guide](operations.md)). - Optionally, group variable files in `group_vars//overrides.yml`, where the group names match the functional groups described above. These can be used to override the default configuration for each functionality, which are defined in `environments/common/inventory/group_vars/all/.yml` (the use of `all` here is due to ansible's precedence rules). Although most of the inventory uses the group convention described above there are a few special cases: diff --git a/docs/experimental/pulp.md b/docs/experimental/pulp.md index c6b437d20..582eec9d7 100644 --- a/docs/experimental/pulp.md +++ b/docs/experimental/pulp.md @@ -5,13 +5,47 @@ In order to ensure reproducible builds, the appliance can build images using rep ## Deploying/configuring Pulp Server ### Deploying a Pulp server -A playbook is provided to install and configure a Pulp server on a given host. Admin credentials for this server are automatically generated through the `ansible/adhoc/generate-passwords.yml` playbook. This can be run with -`ansible-playbook ansible/adhoc/deploy-pulp.yml -e "pulp_server="` -where `target_host` is any resolvable host. This will print a Pulp URL which can be copied to your environments as appropriate. Ensure that the server is accessible on the specified port. Note access to this server's content isn't authenticated so assumes the server is deployed behind a secure network. +A playbook is provided to install and configure a Pulp server on a given host. Admin credentials for this server are automatically generated through the `ansible/adhoc/generate-passwords.yml` playbook. To use this, create an inventory file +defining a group `pulp_server` containing a single host, which requires at least 2 vCPUs and 4GB RAM. The group should be defined in your `site` environment's inventory so that a single Pulp server is shared between all environments and +the same snapshots are tested in staging and production. +Deploying and syncing Pulp has been tested on an RL9 host. The hostvar `ansible_host` should be defined, giving the IP address Ansible should use for ssh. For example, you can create an ini file at `environments/site/inventory/pulp` with the contents: + +``` +[pulp_server] +pulp_host ansible_host= +``` + +> [!WARNING] +> The inventory hostname cannot conflict with group names i.e can't be called `pulp_site` or `pulp_server`. + +Once complete, it will print a message giving a value to set for `appliances_pulp_url` (see example config below), assuming the `ansible_host` address is also the address the cluster +should use to reach the Pulp server. + +Note access to this server's content isn't authenticated so this assumes the `pulp_server` host is not externally reachable. ### Using an existing Pulp server An existing Pulp server can be used to host Ark repos by overriding `pulp_site_password` and `appliances_pulp_url` in the target environment. Note that this assumes the same configuration as the appliance deployed Pulp i.e no content authentication. ## Syncing Pulp content with Ark -If the `pulp` group is added to the Packer build groups, the local Pulp server will be synced with Ark on build. You must authenticate with Ark by overriding `pulp_site_upstream_username` and `pulp_site_upstream_password` with your vault encrypted Ark dev credentials. `dnf_repos_username` and `dnf_repos_password` must remain unset to access content from the local Pulp. Content can also be synced by running `ansible/adhoc/sync-pulp.yml`. By default this syncs repositories for Rocky 9.5 with x86_64 architecture, but can be overridden by setting extra variables for `pulp_site_target_arch`, `pulp_site_target_distribution`, `pulp_site_target_distribution_version` and `pulp_site_target_distribution_version_major`. +If the `pulp_site` group is added to the Packer build groups, the local Pulp server will be synced with Ark on build. You must authenticate with Ark by overriding `pulp_site_upstream_username` and `pulp_site_upstream_password` with your vault encrypted Ark dev credentials. `dnf_repos_username` and `dnf_repos_password` must remain unset to access content from the local Pulp. + +Content can also be synced by running `ansible/adhoc/sync-pulp.yml`. By default this syncs repositories for the latest version of Rocky supported by the appliance but this can be overridden by setting extra variables for `pulp_site_target_arch`, `pulp_site_target_distribution` and `pulp_site_target_distribution_version`. + +## Example config in site variables + +``` +# environments/site/inventory/group_vars/all/pulp_site.yml: +appliances_pulp_url: "http://:8080" +pulp_site_upstream_username: +pulp_site_upstream_password: +``` + +## Installing packages from Pulp at runtime +By default, system repos are overwritten to point at Pulp repos during [image builds,](../image-build.md) so using a site Pulp server will require a new fatimage. If you instead wish to install packages at runtime, +you will need to add all host groups on which you will be installing packages to the `dnf_repos` group in `environments/site/inventory/groups` e.g: + +``` +[dnf_repos:children] +cluster +``` diff --git a/docs/operations.md b/docs/operations.md index 4f7bc5cfb..4c5c640c5 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -9,7 +9,7 @@ All subsequent sections assume that: - Appropriate OpenStack credentials are available. - Any non-appliance controlled infrastructure is available (e.g. networks, volumes, etc.). - `$ENV` is your current, activated environment, as defined by e.g. `environments/production/`. -- `$SITE_ENV` is the base site-specific environment, as defined by e.g. `environments/mysite/`. +- `$SITE_ENV` is the base site-specific environment, as defined by `environments/site/`. - A string `some/path/to/file.yml:myvar` defines a path relative to the repository root and an Ansible variable in that file. - Configuration is generally common to all environments at a site, i.e. is made in `environments/$SITE_ENV` not `environments/$ENV`. @@ -62,6 +62,24 @@ This is a usually a two-step process: Deploying the additional nodes and applying these changes requires rerunning both OpenTofu and the Ansible site.yml playbook - follow [Deploying a Cluster](#Deploying-a-Cluster). +# Enabling additional functionality +Roles in the appliance which are disabled by default can be enabled by adding the appropriate groups as children of the role's corresponding group in `environments/site/inventory/groups`. For example, +to install a Squid proxy on nodes in the login group, you would modify the `squid` group definition in `environments/site/inventory/groups` to: + +``` +[squid:children] +# Hosts to run squid proxy +login +``` + +Note that many non-default roles include package installations from repositories which the appliance overwrites to point at snapshotted mirrors on a Pulp server (by default StackHPC's Ark server), which are +disabled during runtime to prevent Ark credentials from being leaked. To enable this functionality, you must therefore either: + +- Create a site-specific fatimage (see [image build docs](image-build.md)) with the appropriate group added to the `inventory_groups` Packer variables. +- If you instead wish roles to perform their installations during runtime, deploy a site Pulp server and sync it with with mirrors of the snapshots from the upstream Ark server (see [Pulp docs](experimental/pulp.md)). + +In both cases, Ark credentials will be required. + # Adding Additional Packages By default, the following utility packages are installed during the StackHPC image build: - htop diff --git a/environments/.stackhpc/tofu/cluster_image.auto.tfvars.json b/environments/.stackhpc/tofu/cluster_image.auto.tfvars.json index af148393a..88cdb4264 100644 --- a/environments/.stackhpc/tofu/cluster_image.auto.tfvars.json +++ b/environments/.stackhpc/tofu/cluster_image.auto.tfvars.json @@ -1,6 +1,6 @@ { "cluster_image": { - "RL8": "openhpc-RL8-250808-1727-faa44755", - "RL9": "openhpc-RL9-250808-1727-faa44755" + "RL8": "openhpc-RL8-250820-0800-767addd8", + "RL9": "openhpc-RL9-250820-0800-767addd8" } } diff --git a/environments/common/files/grafana/grafana.repo.j2 b/environments/common/files/grafana/grafana.repo.j2 index 8f1aef5a7..6ce2581f6 100644 --- a/environments/common/files/grafana/grafana.repo.j2 +++ b/environments/common/files/grafana/grafana.repo.j2 @@ -1,6 +1,6 @@ {{ ansible_managed | comment }} [grafana] -baseurl = {{ appliances_pulp_url }}/pulp/content/{{ appliances_pulp_repos.grafana[ansible_distribution_major_version] | appliances_repo_to_subpath }} +baseurl = {{ appliances_pulp_url }}/pulp/content/{{ dnf_repos_repos['grafana'][ansible_distribution_major_version]['pulp_path'] }}/{{ dnf_repos_repos['grafana'][ansible_distribution_major_version]['pulp_timestamp'] }} enabled = 0 name = grafana async = 1 diff --git a/environments/common/inventory/group_vars/all/dnf_repo_timestamps.yml b/environments/common/inventory/group_vars/all/dnf_repo_timestamps.yml new file mode 100644 index 000000000..d2df041b4 --- /dev/null +++ b/environments/common/inventory/group_vars/all/dnf_repo_timestamps.yml @@ -0,0 +1,116 @@ +dnf_repos_default: + Ceph: + '8': + pulp_path: centos/8-stream/storage/x86_64/ceph-quincy + pulp_timestamp: 20231104T015751 + repo_file: ceph + '9': + pulp_path: centos/9-stream/storage/x86_64/ceph-reef + pulp_timestamp: 20250617T023108 + repo_file: ceph + appstream: + '8.10': + pulp_path: rocky/8.10/AppStream/x86_64/os + pulp_timestamp: 20250614T013846 + repo_file: Rocky-AppStream + '9.4': + pulp_path: rocky/9.4/AppStream/x86_64/os + pulp_timestamp: 20241112T003151 + repo_file: rocky + '9.5': + pulp_path: rocky/9.5/AppStream/x86_64/os + pulp_timestamp: 20250514T014704 + repo_file: rocky + '9.6': + pulp_path: rocky/9.6/AppStream/x86_64/os + pulp_timestamp: 20250816T020215 + repo_file: rocky + baseos: + '8.10': + pulp_path: rocky/8.10/BaseOS/x86_64/os + pulp_timestamp: 20250614T013846 + repo_file: Rocky-BaseOS + '9.4': + pulp_path: rocky/9.4/BaseOS/x86_64/os + pulp_timestamp: 20241115T011711 + repo_file: rocky + '9.5': + pulp_path: rocky/9.5/BaseOS/x86_64/os + pulp_timestamp: 20250513T031844 + repo_file: rocky + '9.6': + pulp_path: rocky/9.6/BaseOS/x86_64/os + pulp_timestamp: 20250815T050653 + repo_file: rocky + crb: + '8.10': + pulp_path: rocky/8.10/PowerTools/x86_64/os + pulp_timestamp: 20250614T013846 + repo_file: Rocky-PowerTools + repo_name: powertools + '9.4': + pulp_path: rocky/9.4/CRB/x86_64/os + pulp_timestamp: 20241115T003133 + repo_file: rocky + '9.5': + pulp_path: rocky/9.5/CRB/x86_64/os + pulp_timestamp: 20250514T014704 + repo_file: rocky + '9.6': + pulp_path: rocky/9.6/CRB/x86_64/os + pulp_timestamp: 20250815T034418 + repo_file: rocky + extras: + '8.10': + pulp_path: rocky/8.10/extras/x86_64/os + pulp_timestamp: 20250510T032327 + repo_file: Rocky-Extras + '9.4': + pulp_path: rocky/9.4/extras/x86_64/os + pulp_timestamp: 20241118T002802 + repo_file: rocky-extras + '9.5': + pulp_path: rocky/9.5/extras/x86_64/os + pulp_timestamp: 20250506T032818 + repo_file: rocky-extras + '9.6': + pulp_path: rocky/9.6/extras/x86_64/os + pulp_timestamp: 20250726T040613 + repo_file: rocky-extras + grafana: + '8': + pulp_path: grafana/oss/rpm + pulp_timestamp: 20250730T011314 + repo_file: grafana + timestamp: 20250615T005738 + '9': + pulp_path: grafana/oss/rpm + pulp_timestamp: 20250730T011314 + repo_file: grafana + epel: + '8': + pulp_path: epel/8/Everything/x86_64 + pulp_timestamp: 20250615T234151 + repo_file: epel + '9': + pulp_path: epel/9/Everything/x86_64 + pulp_timestamp: 20250817T000753 + repo_file: epel + OpenHPC: + '8': + pulp_path: OpenHPC/2/EL_8 + pulp_timestamp: 20241218T154614 + repo_file: OpenHPC + '9': + pulp_path: OpenHPC/3/EL_9 + pulp_timestamp: 20241218T154614 + repo_file: OpenHPC + OpenHPC-updates: + '8': + pulp_path: OpenHPC/2/updates/EL_8 + pulp_timestamp: 20250512T003315 + repo_file: OpenHPC + '9': + pulp_path: OpenHPC/3/updates/EL_9 + pulp_timestamp: 20250510T003301 + repo_file: OpenHPC diff --git a/environments/common/inventory/group_vars/all/dnf_repos.yml b/environments/common/inventory/group_vars/all/dnf_repos.yml new file mode 100644 index 000000000..e7a8ace33 --- /dev/null +++ b/environments/common/inventory/group_vars/all/dnf_repos.yml @@ -0,0 +1,8 @@ +# dnf_repos_default: see role ansible/roles/dnf_repos/README.md for format and dnf_repo_timestamps.yml for default definition + +# override this in environments/site/inventory/group_vars/dnf_repos.yml to add repos: +dnf_repos_extra: {} + +# indirection to skip openhpc repos if using alternative slurm: +dnf_repos_skip: "{{ [] if ((openhpc_install_type | default('ohpc') == 'ohpc')) else ['OpenHPC', 'OpenHPC-updates'] }}" +dnf_repos_repos: "{{ dnf_repos_default | combine(dnf_repos_extra) | dict2items | rejectattr('key', 'in', dnf_repos_skip) | items2dict }}" diff --git a/environments/common/inventory/group_vars/all/timestamps.yml b/environments/common/inventory/group_vars/all/timestamps.yml deleted file mode 100644 index 455c26005..000000000 --- a/environments/common/inventory/group_vars/all/timestamps.yml +++ /dev/null @@ -1,88 +0,0 @@ -appliances_pulp_repos: - appstream: - '8.10': - path: rocky/8.10/AppStream/x86_64/os - timestamp: 20250614T013846 - '9.4': - path: rocky/9.4/AppStream/x86_64/os - timestamp: 20241112T003151 - '9.5': - path: rocky/9.5/AppStream/x86_64/os - timestamp: 20250514T014704 - '9.6': - path: rocky/9.6/AppStream/x86_64/os - timestamp: 20250726T040613 - baseos: - '8.10': - path: rocky/8.10/BaseOS/x86_64/os - timestamp: 20250614T013846 - '9.4': - path: rocky/9.4/BaseOS/x86_64/os - timestamp: 20241115T011711 - '9.5': - path: rocky/9.5/BaseOS/x86_64/os - timestamp: 20250513T031844 - '9.6': - path: rocky/9.6/BaseOS/x86_64/os - timestamp: 20250726T052250 - ceph: - '8': - path: centos/8-stream/storage/x86_64/ceph-quincy - timestamp: 20231104T015751 - '9': - path: centos/9-stream/storage/x86_64/ceph-reef - timestamp: 20250617T023108 - crb: - '8.10': - path: rocky/8.10/PowerTools/x86_64/os - timestamp: 20250614T013846 - '9.4': - path: rocky/9.4/CRB/x86_64/os - timestamp: 20241115T003133 - '9.5': - path: rocky/9.5/CRB/x86_64/os - timestamp: 20250514T014704 - '9.6': - path: rocky/9.6/CRB/x86_64/os - timestamp: 20250726T040613 - epel: - '8': - path: epel/8/Everything/x86_64 - timestamp: 20250615T234151 - '9': - path: epel/9/Everything/x86_64 - timestamp: 20250729T235750 - extras: - '8.10': - path: rocky/8.10/extras/x86_64/os - timestamp: 20250510T032327 - '9.4': - path: rocky/9.4/extras/x86_64/os - timestamp: 20241118T002802 - '9.5': - path: rocky/9.5/extras/x86_64/os - timestamp: 20250506T032818 - '9.6': - path: rocky/9.6/extras/x86_64/os - timestamp: 20250726T040613 - grafana: - '8': - path: grafana/oss/rpm - timestamp: 20250615T005738 - '9': - path: grafana/oss/rpm - timestamp: 20250730T011314 - openhpc_base: - '8': - path: OpenHPC/2/EL_8 - timestamp: 20241218T154614 - '9': - path: OpenHPC/3/EL_9 - timestamp: 20241218T154614 - openhpc_updates: - '8': - path: OpenHPC/2/updates/EL_8 - timestamp: 20250512T003315 - '9': - path: OpenHPC/3/updates/EL_9 - timestamp: 20250510T003301 diff --git a/environments/common/inventory/groups b/environments/common/inventory/groups index 57b644152..6926355ed 100644 --- a/environments/common/inventory/groups +++ b/environments/common/inventory/groups @@ -197,8 +197,8 @@ k3s_agent builder extra_packages -[pulp] -# Add builder to this group to enable automatically syncing of pulp during image build +[pulp_site] +# Add builder to this group to automatically sync pulp during image build [cacerts] # Hosts to configure CA certificates and trusts on @@ -211,3 +211,10 @@ extra_packages [nhc] # Hosts to configure for node health checks - either entire 'compute' group or empty + +[pulp_server] +# Host to deploy a Pulp server on and sync with mirrors of upstream Ark repositories. Should be a group containing a single VM provisioned +# separately from the appliance. e.g +# pulp_host ansible_host= +# Note the host name can't conflict with group names i.e can't be called `pulp` or `pulp_server` + diff --git a/environments/site/inventory/groups b/environments/site/inventory/groups index 9df61dc13..b78197df0 100644 --- a/environments/site/inventory/groups +++ b/environments/site/inventory/groups @@ -157,3 +157,12 @@ compute # Should be set to `compute` if enabled # Note that this feature currently assumes all compute nodes are VMs, enabling # when the cluster contains baremetal compute nodes may lead to unexpected scheduling behaviour + +[pulp_site] +# Add builder to this group to automatically sync pulp during image build + +[pulp_server] +# Host to deploy a Pulp server on and sync with mirrors of upstream Ark repositories. Should be a group containing a single VM provisioned +# separately from the appliance. e.g +# pulp_host ansible_host= +# Note inventory host name cannot conflict with group names i.e can't be called `pulp` or `pulp_server`.