Skip to content

Commit f032ed9

Browse files
authored
Merge pull request #490 from stackhpc/feat/pulp-builds
Support site Pulp server for image builds
2 parents 32cc0c6 + a3e1258 commit f032ed9

File tree

33 files changed

+390
-45
lines changed

33 files changed

+390
-45
lines changed

.github/workflows/fatimage.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ jobs:
3333
OS_CLOUD: openstack
3434
CI_CLOUD: ${{ github.event.inputs.ci_cloud }}
3535
ARK_PASSWORD: ${{ secrets.ARK_PASSWORD }}
36+
LEAFCLOUD_PULP_PASSWORD: ${{ secrets.LEAFCLOUD_PULP_PASSWORD }}
3637

3738
steps:
3839
- uses: actions/checkout@v2

.github/workflows/nightlybuild.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ jobs:
3535
OS_CLOUD: openstack
3636
CI_CLOUD: ${{ github.event.inputs.ci_cloud || vars.CI_CLOUD }}
3737
ARK_PASSWORD: ${{ secrets.ARK_PASSWORD }}
38+
LEAFCLOUD_PULP_PASSWORD: ${{ secrets.LEAFCLOUD_PULP_PASSWORD }}
3839

3940
steps:
4041
- uses: actions/checkout@v2

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ It requires an OpenStack cloud, and an Ansible "deploy host" with access to that
3232
Before starting ensure that:
3333
- You have root access on the deploy host.
3434
- You can create instances using a Rocky 9 GenericCloud image (or an image based on that).
35-
- **NB**: In general it is recommended to use the [latest released image](https://github.com/stackhpc/ansible-slurm-appliance/releases) which already contains the required packages. This is built and tested in StackHPC's CI. However the appliance will install the necessary packages if a GenericCloud image is used.
35+
- **NB**: In general it is recommended to use the [latest released image](https://github.com/stackhpc/ansible-slurm-appliance/releases) which already contains the required packages. This is built and tested in StackHPC's CI.
3636
- You have a SSH keypair defined in OpenStack, with the private key available on the deploy host.
3737
- Created instances have access to internet (note proxies can be setup through the appliance if necessary).
3838
- Created instances have accurate/synchronised time (for VM instances this is usually provided by the hypervisor; if not or for bare metal instances it may be necessary to configure a time service via the appliance).

ansible/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,5 +66,7 @@ roles/*
6666
!roles/lustre/**
6767
!roles/dnf_repos/
6868
!roles/dnf_repos/**
69+
!roles/pulp_site/
70+
!roles/pulp_site/**
6971
!roles/doca/
7072
!roles/doca/**

ansible/adhoc/deploy-pulp.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Usage: ansible-playbook ansible/adhoc/deploy-pulp.yml -e "pulp_server=<pulp server hostname>"
2+
3+
- name: Add temporary pulp server host
4+
hosts: localhost
5+
tasks:
6+
- ansible.builtin.add_host:
7+
name: "{{ pulp_server }}"
8+
group: "_pulp_host"
9+
10+
- name: Install pulp on server and add to config
11+
become: yes
12+
hosts: _pulp_host
13+
tasks:
14+
- name: Install pulp
15+
ansible.builtin.include_role:
16+
name: pulp_site
17+
tasks_from: install.yml
18+
public: true
19+
20+
- name: Print Pulp endpoint
21+
become: no
22+
debug:
23+
msg: |
24+
Server configured, override 'appliances_pulp_url' with
25+
appliances_pulp_url: "http://{{ pulp_server }}:{{ pulp_site_port }}"
26+
in your environments

ansible/adhoc/sync-pulp.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
- hosts: localhost
2+
tasks:
3+
- ansible.builtin.include_role:
4+
name: pulp_site
5+
tasks_from: sync.yml
6+
vars:
7+
pulp_site_target_arch: "x86_64"
8+
pulp_site_target_distribution: "rocky"
9+
pulp_site_target_distribution_version: "9.4"
10+
pulp_site_target_distribution_version_major: "9"

ansible/bootstrap.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,20 @@
110110
policy: "{{ selinux_policy }}"
111111
register: sestatus
112112

113+
- hosts: dnf_repos
114+
become: yes
115+
tasks:
116+
- name: Check that creds won't be leaked to users
117+
ansible.builtin.assert:
118+
that: dnf_repos_password is undefined
119+
fail_msg: Passwords should not be templated into repofiles during configure, unset 'dnf_repos_password'
120+
when: appliances_mode == 'configure'
121+
- name: Replace system repos with pulp repos
122+
ansible.builtin.include_role:
123+
name: dnf_repos
124+
tasks_from: set_repos.yml
125+
when: ansible_distribution_major_version == "9" #TODO update role once RL8 config decided
126+
113127
# --- tasks after here require access to package repos ---
114128
- hosts: squid
115129
tags: squid

ansible/disable-repos.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
- hosts: dnf_repos
2+
become: yes
3+
tasks:
4+
- name: Disable pulp repos
5+
ansible.builtin.include_role:
6+
name: dnf_repos
7+
tasks_from: disable_repos.yml
8+
when: ansible_distribution_major_version == "9" #TODO update role once RL8 config decided

ansible/fatimage.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,16 @@
1717
import_playbook: "{{ hook_path if hook_path | exists else 'noop.yml' }}"
1818
when: hook_path | exists
1919

20+
- name: Sync pulp repos with upstream
21+
hosts: pulp
22+
tasks:
23+
- ansible.builtin.include_role:
24+
name: pulp_site
25+
tasks_from: sync.yml
26+
apply:
27+
delegate_to: localhost
28+
when: appliances_mode != 'configure'
29+
2030
- import_playbook: bootstrap.yml
2131

2232
- name: Run post-bootstrap.yml hook
@@ -210,6 +220,8 @@
210220
import_role:
211221
name: doca
212222

223+
- import_playbook: disable-repos.yml
224+
213225
- name: Run post.yml hook
214226
vars:
215227
appliances_environment_root: "{{ lookup('env', 'APPLIANCES_ENVIRONMENT_ROOT') }}"
Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,23 @@
1-
dnf_repos_rocky_ark_prefix: https://ark.stackhpc.com/pulp/content/{{ ansible_distribution | lower }}/{{ ansible_distribution_version }}
2-
dnf_repos_rocky_ark_suffix: "{{ ansible_architecture }}/os/{{ dnf_repos_rocky_ark_timestamp }}/"
3-
# most stable from https://github.com/stackhpc/stackhpc-kayobe-config/blob/stackhpc/2024.1/etc/kayobe/pulp-repo-versions.yml
4-
# note that some timestamps can't be used because not all repos have snapshots for them
5-
dnf_repos_rocky_ark_timestamp: 20240816T002610
6-
dnf_repos_username: slurm-app-ci
7-
dnf_repos_password: "{{ lookup('ansible.builtin.env', 'ARK_PASSWORD') }}"
1+
dnf_repos_pulp_content_url: "{{ appliances_pulp_url }}/pulp/content"
2+
dnf_repos_rocky_prefix: "{{ ansible_distribution | lower }}/{{ ansible_distribution_version }}"
3+
dnf_repos_epel_prefix: "epel/{{ ansible_distribution_major_version }}"
4+
dnf_repos_username: "{{ omit }}"
5+
dnf_repos_password: "{{ omit }}"
86

97
# epel installed separately
108
dnf_repos_repolist:
119
- file: rocky
1210
name: baseos
13-
base_url: "{{ dnf_repos_rocky_ark_prefix }}/BaseOS/{{ dnf_repos_rocky_ark_suffix }}"
11+
base_url: "{{ dnf_repos_pulp_content_url }}/{{ dnf_repos_rocky_prefix }}/BaseOS/{{ ansible_architecture }}/os/{{ appliances_repo_timestamps.baseos[ansible_distribution_version] }}"
1412
- file: rocky
1513
name: appstream
16-
base_url: "{{ dnf_repos_rocky_ark_prefix }}/AppStream/{{ dnf_repos_rocky_ark_suffix }}"
14+
base_url: "{{ dnf_repos_pulp_content_url }}/{{ dnf_repos_rocky_prefix }}/AppStream/{{ ansible_architecture }}/os/{{ appliances_repo_timestamps.appstream[ansible_distribution_version] }}"
1715
- file: rocky
1816
name: crb
19-
base_url: "{{ dnf_repos_rocky_ark_prefix }}/CRB/{{ dnf_repos_rocky_ark_suffix }}"
17+
base_url: "{{ dnf_repos_pulp_content_url }}/{{ dnf_repos_rocky_prefix }}/CRB/{{ ansible_architecture }}/os/{{ appliances_repo_timestamps.crb[ansible_distribution_version] }}"
2018
- file: rocky-extras
2119
name: extras
22-
base_url: "{{ dnf_repos_rocky_ark_prefix }}/extras/{{ dnf_repos_rocky_ark_suffix }}"
20+
base_url: "{{ dnf_repos_pulp_content_url }}/{{ dnf_repos_rocky_prefix }}/extras/{{ ansible_architecture }}/os/{{ appliances_repo_timestamps.extras[ansible_distribution_version] }}"
2321

24-
dnf_repos_epel_timestamp: 20240902T080424
25-
dnf_repos_epel_baseurl: "https://ark.stackhpc.com/pulp/content/epel/{{ ansible_distribution_major_version }}/Everything/{{ ansible_architecture }}/{{ dnf_repos_epel_timestamp }}"
22+
dnf_repos_epel_baseurl: "{{ dnf_repos_pulp_content_url }}/epel/{{ ansible_distribution_major_version }}/Everything/{{ ansible_architecture }}/{{ appliances_repo_timestamps.epel[ansible_distribution_major_version] }}"
23+
dnf_repos_epel_description: "epel"
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
- name: Disable Pulp repos and remove creds
2+
- name: Disable Pulp repos
33
ansible.builtin.yum_repository:
44
file: "{{ item.file }}"
55
name: "{{ item.name }}"
@@ -8,11 +8,11 @@
88
enabled: false
99
loop: "{{ dnf_repos_repolist }}"
1010

11-
- name: Disable EPEL repo and remove creds
11+
- name: Disable EPEL repo
1212
ansible.builtin.yum_repository:
1313
name: epel
1414
file: epel
15-
description: epel
15+
description: "{{ dnf_repos_epel_description }}"
1616
baseurl: "{{ dnf_repos_epel_baseurl }}"
1717
gpgcheck: false
1818
enabled: false

ansible/roles/dnf_repos/tasks/set_repos.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
ansible.builtin.yum_repository:
2020
name: epel
2121
file: epel
22-
description: epel
22+
description: "{{ dnf_repos_epel_description }}"
2323
gpgcheck: false
24+
baseurl: "{{ dnf_repos_epel_baseurl }}"
2425
username: "{{ dnf_repos_username }}"
2526
password: "{{ dnf_repos_password }}"
26-
baseurl: "{{ dnf_repos_epel_baseurl }}"

ansible/roles/passwords/defaults/main.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ slurm_appliance_secrets:
99
vault_freeipa_ds_password: "{{ vault_freeipa_ds_password | default(lookup('password', '/dev/null')) }}"
1010
vault_freeipa_admin_password: "{{ vault_freeipa_admin_password | default(lookup('password', '/dev/null')) }}"
1111
vault_k3s_token: "{{ vault_k3s_token | default(lookup('ansible.builtin.password', '/dev/null', length=64)) }}"
12+
vault_pulp_admin_password: "{{ vault_pulp_admin_password | default(lookup('password', '/dev/null', chars=['ascii_letters', 'digits'])) }}"
1213

1314
secrets_openhpc_mungekey_default:
1415
content: "{{ lookup('pipe', 'dd if=/dev/urandom bs=1 count=1024 2>/dev/null | base64') }}"

ansible/roles/pulp_site/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
filter_plugins/__pycache__
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
pulp_site_url: "{{ appliances_pulp_url }}"
2+
pulp_site_port: 8080
3+
pulp_site_username: admin # shouldn't be changed
4+
pulp_site_password: "{{ vault_pulp_admin_password }}"
5+
pulp_site_upstream_content_url: https://ark.stackhpc.com/pulp/content
6+
_pulp_site_rocky_prefix: "{{ pulp_site_target_distribution }}/{{ pulp_site_target_distribution_version }}"
7+
pulp_site_default_upstream_suffix: "{{ pulp_site_target_arch }}/os"
8+
pulp_site_validate_certs: false
9+
pulp_site_install_dir: '/home/rocky/pulp'
10+
pulp_site_selinux_suffix: "{{ ':Z' if ansible_selinux.status == 'enabled' else '' }}"
11+
pulp_site_target_facts: "{{ hostvars[groups['builder'][0]]['ansible_facts'] }}"
12+
pulp_site_target_arch: "{{ pulp_site_target_facts['architecture'] }}"
13+
pulp_site_target_distribution: "{{ pulp_site_target_facts['distribution'] | lower }}"
14+
pulp_site_target_distribution_version: "{{ pulp_site_target_facts['distribution_version'] }}"
15+
pulp_site_target_distribution_version_major: "{{ pulp_site_target_facts['distribution_major_version'] }}"
16+
17+
pulp_site_rpm_info:
18+
- name: "baseos-{{ pulp_site_target_distribution_version }}-{{ appliances_repo_timestamps.baseos[pulp_site_target_distribution_version] }}"
19+
subpath: "{{ _pulp_site_rocky_prefix }}/BaseOS/{{ pulp_site_default_upstream_suffix }}/{{ appliances_repo_timestamps.baseos[pulp_site_target_distribution_version] }}"
20+
- name: "appstream-{{ pulp_site_target_distribution_version }}-{{ appliances_repo_timestamps.appstream[pulp_site_target_distribution_version] }}"
21+
subpath: "{{ _pulp_site_rocky_prefix }}/AppStream/{{ pulp_site_default_upstream_suffix }}/{{ appliances_repo_timestamps.appstream[pulp_site_target_distribution_version] }}"
22+
- name: "crb-{{ pulp_site_target_distribution_version }}-{{ appliances_repo_timestamps.crb[pulp_site_target_distribution_version] }}"
23+
subpath: "{{ _pulp_site_rocky_prefix }}/{{ 'PowerTools' if pulp_site_target_distribution_version_major == '8' else 'CRB' }}/{{ pulp_site_default_upstream_suffix }}/{{ appliances_repo_timestamps.crb[pulp_site_target_distribution_version] }}"
24+
- name: "extras-{{ pulp_site_target_distribution_version }}-{{ appliances_repo_timestamps.extras[pulp_site_target_distribution_version] }}"
25+
subpath: "{{ _pulp_site_rocky_prefix }}/extras/{{ pulp_site_default_upstream_suffix }}/{{ appliances_repo_timestamps.extras[pulp_site_target_distribution_version] }}"
26+
- name: "epel-{{ pulp_site_target_distribution_version_major }}-{{ appliances_repo_timestamps.epel[pulp_site_target_distribution_version_major] }}"
27+
subpath: "epel/{{ pulp_site_target_distribution_version_major }}/Everything/{{ pulp_site_target_arch }}/{{ appliances_repo_timestamps.epel[pulp_site_target_distribution_version_major] }}"
28+
29+
pulp_site_rpm_repo_defaults:
30+
remote_username: "{{ pulp_site_upstream_username }}"
31+
remote_password: "{{ pulp_site_upstream_password }}"
32+
policy: on_demand
33+
state: present
34+
35+
_pulp_site_rpm_info_all: "{{ pulp_site_rpm_info | map('combine', pulp_site_rpm_repo_defaults) }}"
36+
37+
pulp_site_rpm_repos: "{{ _pulp_site_rpm_info_all | to_rpm_repos(pulp_site_upstream_content_url) }}"
38+
pulp_site_rpm_publications: "{{ _pulp_site_rpm_info_all | to_rpm_pubs }}"
39+
pulp_site_rpm_distributions: "{{ _pulp_site_rpm_info_all | to_rpm_distros }}"
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
class FilterModule(object):
2+
def filters(self):
3+
return {
4+
'to_rpm_repos': self.to_rpm_repos,
5+
'to_rpm_pubs': self.to_rpm_pubs,
6+
'to_rpm_distros': self.to_rpm_distros
7+
}
8+
9+
def to_rpm_repos(self, list, pulp_url):
10+
repo_list = map(lambda x: {
11+
'name': x['name'],
12+
'url': pulp_url+'/'+x['subpath'],
13+
'remote_username': x['remote_username'],
14+
'remote_password': x['remote_password'],
15+
'policy': x['policy'],
16+
'state': x['state'] }, list)
17+
return repo_list
18+
19+
def to_rpm_pubs(self, list):
20+
pub_list = map(lambda x: {
21+
'repository': x['name'],
22+
'state': x['state'] }, list)
23+
return pub_list
24+
25+
def to_rpm_distros(self, list):
26+
distro_list = map(lambda x: {
27+
'name': x['name'],
28+
'repository': x['name'],
29+
'base_path': x['subpath'],
30+
'state': x['state'] }, list)
31+
return distro_list
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
---
2+
3+
- name: Install packages
4+
dnf:
5+
name:
6+
- podman
7+
8+
- name: Create install directories
9+
ansible.builtin.file:
10+
state: directory
11+
path: "{{ pulp_site_install_dir }}/{{ item }}"
12+
loop:
13+
- settings/certs
14+
- pulp_storage
15+
- pgsql
16+
- containers
17+
18+
- name: Template settings file
19+
ansible.builtin.template:
20+
src: settings.py.j2
21+
dest: "{{ pulp_site_install_dir }}/settings/settings.py"
22+
23+
- name: Install pulp podman container
24+
containers.podman.podman_container:
25+
name: pulp
26+
publish:
27+
- "{{ pulp_site_port }}:80"
28+
volume:
29+
- "{{ pulp_site_install_dir }}/settings:/etc/pulp{{ pulp_site_selinux_suffix }}"
30+
- "{{ pulp_site_install_dir }}/pulp_storage:/var/lib/pulp{{ pulp_site_selinux_suffix }}"
31+
- "{{ pulp_site_install_dir }}/pgsql:/var/lib/pgsql{{ pulp_site_selinux_suffix }}"
32+
- "{{ pulp_site_install_dir }}/containers:/var/lib/containers{{ pulp_site_selinux_suffix }}"
33+
device: /dev/fuse
34+
image: docker.io/pulp/pulp:3.68.1
35+
36+
- name: Reset admin password once container has initialised
37+
no_log: true
38+
ansible.builtin.shell:
39+
cmd: "podman exec pulp bash -c 'pulpcore-manager reset-admin-password -p {{ pulp_site_password }}'"
40+
register: _admin_reset_output
41+
until: 0 == _admin_reset_output.rc
42+
retries: 6
43+
delay: 30

0 commit comments

Comments
 (0)