Skip to content

Commit 1fe546e

Browse files
committed
Fix container image promotion (hopefully)
This change modifies the way in which we promote container image tags. Previously, the stackhpc-dev container repository was configured as a remote, and the stackhpc repository synced with it, using include_tags to limit to a specific tag. Now, we use the "Add content" [1] API to add container tags from stackhpc-dev to stackhpc. Currently we're still promoting a single tag across all repositories, so a non-existent tag is not an error. This will change in future. [1] https://docs.pulpproject.org/pulp_container/restapi.html#tag/Repositories:-Container/operation/repositories_container_container_add
1 parent 5566c06 commit 1fe546e

File tree

6 files changed

+154
-8
lines changed

6 files changed

+154
-8
lines changed

ansible/dev-pulp-container-promote.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,24 @@
3333
pulp_username: "{{ dev_pulp_username }}"
3434
pulp_password: "{{ dev_pulp_password }}"
3535
pulp_distribution_container: "{{ dev_pulp_distribution_container_release }}"
36+
37+
# Copy tags from stackhpc-dev to stackhpc repositories.
38+
- import_role:
39+
name: pulp-container-content
40+
vars:
41+
pulp_url: "{{ dev_pulp_url }}"
42+
pulp_username: "{{ dev_pulp_username }}"
43+
pulp_password: "{{ dev_pulp_password }}"
44+
pulp_container_content: >-
45+
{%- set contents = [] -%}
46+
{%- for base_distro in kolla_base_distros -%}
47+
{%- for image in kolla_container_images_filtered -%}
48+
{%- if image not in kolla_unbuildable_images[base_distro]-%}
49+
{%- set src_image_repo = "stackhpc-dev/" ~ base_distro ~ "-source-" ~ image -%}
50+
{%- set dest_image_repo = "stackhpc/" ~ base_distro ~ "-source-" ~ image -%}
51+
{%- set content = {"src_repo": src_image_repo, "src_is_push": true, "dest_repo": dest_image_repo, "tags": [dev_pulp_repository_container_promotion_tag]} -%}
52+
{%- set _ = contents.append(content) -%}
53+
{%- endif -%}
54+
{%- endfor -%}
55+
{%- endfor -%}
56+
{{ contents }}

ansible/inventory/group_vars/all/dev-pulp-containers

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,6 @@ dev_release_pulp_registry_url: "{{ dev_pulp_url }}"
88

99
# Common parameters for release image repositories.
1010
dev_pulp_repository_container_repo_release_common:
11-
url: "{{ dev_release_pulp_registry_url }}"
12-
include_tags:
13-
- "{{ dev_pulp_repository_container_promotion_tag.strip() | mandatory }}"
14-
policy: on_demand
15-
remote_username: "{{ dev_pulp_username }}"
16-
remote_password: "{{ dev_pulp_password }}"
1711
state: present
1812

1913
# List of release container image repositories.
@@ -23,8 +17,7 @@ dev_pulp_repository_container_repos_release: >-
2317
{%- for image in kolla_container_images_filtered -%}
2418
{%- if image not in kolla_unbuildable_images[base_distro]-%}
2519
{%- set image_repo = "stackhpc/" ~ base_distro ~ "-source-" ~ image -%}
26-
{%- set upstream_repo = "stackhpc-dev/" ~ base_distro ~ "-source-" ~ image -%}
27-
{%- set repo = {"name": image_repo, "upstream_name": upstream_repo} -%}
20+
{%- set repo = {"name": image_repo} -%}
2821
{%- set _ = repos.append(dev_pulp_repository_container_repo_release_common | combine(repo)) -%}
2922
{%- endif -%}
3023
{%- endfor -%}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
pulp_container_content
2+
======================
3+
4+
This role adds and removes content in Pulp container repositories.
5+
6+
Currently only supports tags.
7+
8+
Role variables
9+
--------------
10+
11+
* `pulp_url`: URL of Pulp server. Default is `https://localhost:8080`
12+
* `pulp_username`: Username used to access Pulp server. Default is `admin`
13+
* `pulp_password`: Password used to access Pulp server. Default is unset
14+
* `pulp_container_content`: List of content to add or remove. Each item is a dict with the following keys:
15+
16+
* `src_repo`: Name of the repository to copy from when `state` is `present`,
17+
or the repository to remove from when `state` is `absent`.
18+
* `src_is_push`: Whether `src_repo` is a push repository. Default is `false`.
19+
* `dest_repo`: Name of the repository to copy to when `state is `present`.
20+
* `tags`: List of names of tags to add or remove.
21+
* `state`: Whether to add (`present`) or remove (`absent`) content.
22+
23+
Example playbook
24+
----------------
25+
26+
```yaml
27+
---
28+
- name: Add or remove container content
29+
any_errors_fatal: True
30+
gather_facts: True
31+
hosts: all
32+
roles:
33+
- role: pulp-container-content
34+
pulp_username: admin
35+
pulp_password: "{{ secrets_pulp_admin_password }}"
36+
pulp_container_content:
37+
# Copy tag1 and tag2 from repo1 to repo2
38+
- src_repo: repo1
39+
src_is_push: true
40+
dest_repo: repo2
41+
tags:
42+
- tag1
43+
- tag2
44+
# Remove tag3 from repo3
45+
- src_repo: repo3
46+
tags:
47+
- tag3
48+
state: absent
49+
```
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
pulp_url: https://localhost:8080
3+
pulp_username: admin
4+
pulp_password:
5+
6+
pulp_container_content: []
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
---
2+
- name: Query source repository
3+
uri:
4+
url: "{{ pulp_url }}/pulp/api/v3/repositories/container/container{% if item.src_is_push | default(false) | bool %}-push{% endif %}/?name={{ item.src_repo | urlencode | regex_replace('/','%2F') }}"
5+
user: "{{ pulp_username }}"
6+
password: "{{ pulp_password }}"
7+
method: GET
8+
status_code: 200
9+
force_basic_auth: true
10+
register: src_repo
11+
when: item.state | default != 'absent'
12+
13+
- name: Assert that source repository exists
14+
assert:
15+
that:
16+
src_repo.json.results | length > 0
17+
when: item.state | default != 'absent'
18+
19+
- name: Query destination repository
20+
uri:
21+
url: "{{ pulp_url }}/pulp/api/v3/repositories/container/container/?name={{ item.dest_repo | urlencode | regex_replace('/','%2F') }}"
22+
user: "{{ pulp_username }}"
23+
password: "{{ pulp_password }}"
24+
method: GET
25+
status_code: 200
26+
force_basic_auth: true
27+
register: dest_repo
28+
29+
- name: Assert that destination repository exists
30+
assert:
31+
that:
32+
dest_repo.json.results | length > 0
33+
34+
- name: Query tags
35+
uri:
36+
url: "{{ pulp_url }}/pulp/api/v3/content/container/tags/?name__in={{ item.tags | join(',') | urlencode | regex_replace('/','%2F') }}&repository_version={{ repo.json.results[0].latest_version_href | urlencode | regex_replace('/','%2F') }}"
37+
user: "{{ pulp_username }}"
38+
password: "{{ pulp_password }}"
39+
method: GET
40+
status_code: 200
41+
force_basic_auth: true
42+
register: tags
43+
vars:
44+
repo: "{{ src_repo if item.state | default != 'absent' else dest_repo }}"
45+
46+
# NOTE: Currently we don't verify that all tags exist. This can be fixed when we specify a different tag for each repo.
47+
48+
- name: Add or remove content units
49+
uri:
50+
url: "{{ pulp_url }}{{ dest_repo.json.results[0].pulp_href }}{% if item.state | default != 'absent' %}add{% else %}remove{% endif %}/"
51+
user: "{{ pulp_username }}"
52+
password: "{{ pulp_password }}"
53+
method: POST
54+
status_code: 202
55+
force_basic_auth: true
56+
body:
57+
content_units: "{{ tags.json.results | map(attribute='pulp_href') | list }}"
58+
body_format: json
59+
register: task
60+
61+
- name: Wait for task to complete
62+
uri:
63+
url: "{{ pulp_url }}{{ task.json.task }}"
64+
user: "{{ pulp_username }}"
65+
password: "{{ pulp_password }}"
66+
method: GET
67+
status_code: 200
68+
force_basic_auth: true
69+
register: result
70+
until: result.json.state not in ['waiting', 'running']
71+
retries: 30
72+
delay: 2
73+
failed_when: result.json.state != 'completed'
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
- name: Include content.yml
3+
include_tasks: content.yml
4+
loop: "{{ pulp_container_content }}"

0 commit comments

Comments
 (0)