-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpulp_rpm_repo_from_fileglob.yml
298 lines (271 loc) · 11.1 KB
/
pulp_rpm_repo_from_fileglob.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
---
# This playbook attempts to ensure and populate a RPM repository in Pulp.
# Author: Stefan Joosten <stefan•ɑƬ•atcomputing•ɖɵʈ•nl>
# License: GPLv3
#
# This playbook requires a (valid) repository name to be set (as value of rpm_repository_name).
# For example by running it as follows:
#
# $ ansible-playbook \
# --extra-vars 'rpm_repository_name=my_own_repository' \
# pulp_rpm_repo_from_fileglob.yml
#
# Or by being called from another playbook.
#
# Other optional variables are:
# rpm_repository_description: "a description for the repository"
# rpm_local_upload_path: "local path where to look for .rpm files"
#
- name: Upload a local RPM package(s) to a RPM repository on Pulp
hosts: localhost
connection: local
force_handlers: true
module_defaults: # saves specifying these settings at every task using these modules
pulp.squeezer.status: &pulp_connection_details # & creates YAML anchor
pulp_url: "{{ pulp_url }}" # from group_vars/pulp; example: http://{{ inventory_hostname }}:8080
username: "{{ pulp_username }}" # from group_vars/pulp
password: "{{ pulp_password }}" # from group_vars/pulp
validate_certs: false
pulp.squeezer.artifact:
<<: *pulp_connection_details # alias to content of pulp_connection_details
pulp.squeezer.rpm_repository:
<<: *pulp_connection_details # alias to content of pulp_connection_details
pulp.squeezer.rpm_distribution:
<<: *pulp_connection_details # alias to content of pulp_connection_details
pulp.squeezer.task:
<<: *pulp_connection_details # alias to content of pulp_connection_details
ansible.builtin.uri:
body_format: json
force_basic_auth: true
url_username: "{{ pulp_username }}" # from group_vars/pulp
url_password: "{{ pulp_password }}" # from group_vars/pulp
validate_certs: false
vars:
# Pulp where?
#pulp_url: "http://{{ inventory_hostname }}:8080" # specified in from group_vars/pulp already
# Name and description of repository to put the packages in
#rpm_repository_name: my_very_own_repository # disabled to prevent this from running as-is.
rpm_repository_description: "My repository for Aiur!"
# Local path, on control node, where to look for .rpm files to upload for this repository.
rpm_local_upload_path: "{{ playbook_dir }}/upload/{{ rpm_repository_name }}"
tasks:
- name: Stop when no rpm_repository_name given
ansible.builtin.fail:
msg: "Bailing out. The play requires a repository name set in variable 'rpm_repository_name'."
when: rpm_repository_name is undefined
- name: Acquire details of local file(s)
ansible.builtin.stat:
path: "{{ item }}" # point me to a real file, not a symlink
checksum_algorithm: sha256
get_mime: true
register: file
loop: "{{ query('ansible.builtin.fileglob', rpm_local_upload_path + '/*.rpm') }}"
delegate_to: localhost
- name: Bail out when no matching files are found
ansible.builtin.fail:
msg: |
No matching files have been found in path:
{{ rpm_local_upload_path }}/*.rpm
when: file.results | length < 1
- name: Verify file(s) to upload are readable and RPM package files
ansible.builtin.assert:
that:
- item.stat.readable
- item.stat.mimetype == 'application/x-rpm'
- item.stat.checksum | length > 0
fail_msg: |
Something went wrong during verification of file '{{ item.stat.path }}'.
Please make sure this path is readable, is not a symlink and is an actual RPM package file.
quiet: true
loop: "{{ file.results }}"
loop_control:
label: "{{ item.stat.path }}"
delegate_to: localhost
- name: Refresh and read status from Pulp API # noqa: args[module]
pulp.squeezer.status:
refresh_api_cache: true
- name: Ensure RPM repository # noqa: args[module]
pulp.squeezer.rpm_repository:
name: "{{ rpm_repository_name }}"
description: "{{ rpm_repository_description }}"
state: present
autopublish: true
register: rpm_repository_output
- name: Query Pulp for presence of artifact(s) # noqa: args[module]
pulp.squeezer.artifact:
sha256: "{{ item.stat.checksum }}"
ignore_errors: true
register: artifact_query
# artifact_query.results[i].artifact returns null when artifact is not present
# artifact_query.results[i].artifact returns dict when artifact is present
loop: "{{ file.results }}"
loop_control:
label: "{{ item.stat.path | basename }}"
- name: Copy file(s) to Pulp host
ansible.builtin.copy:
src: "{{ item.item.stat.path }}"
dest: ~/
mode: 0644
register: copy_status
when: item.failed
loop: "{{ artifact_query.results }}"
loop_control:
label: "{{ item.item.stat.path | basename }}"
notify:
- Clean-up copied files
- name: Upload artifact(s) to Pulp # noqa: args[module]
pulp.squeezer.artifact:
file: "{{ item.dest }}"
state: present
register: artifact_upload
when: item.item.failed
loop: "{{ copy_status.results }}"
loop_control:
label: "{{ item.item.item.stat.path | basename }}" # on skip of the copy task item.dest is undefined.
- name: Refresh state of artifact(s) # noqa: args[module]
pulp.squeezer.artifact:
sha256: "{{ item.stat.checksum }}"
register: artifact_state
loop: "{{ file.results }}"
loop_control:
label: "{{ item.stat.path | basename }}"
- name: Debug - Artifact information
ansible.builtin.debug:
msg: "{{ artifact_info }}"
verbosity: 1
loop: "{{ artifact_state.results }}"
loop_control:
label: "{{ item.artifact.sha256 }}"
vars:
artifact_info:
- filename: "{{ item.item.stat.path | basename }}"
sha256sum: "{{ item.item.stat.checksum }}"
artifact: "{{ item.artifact }}"
- name: Verify artifact integrity by comparing checksum of original file
ansible.builtin.assert:
that:
- checksum.file == checksum.artifact
fail_msg: "Checksum of artifact did not match file's. Data corruption occurred?"
quiet: true
loop: "{{ artifact_state.results }}"
loop_control:
label: "{{ filename }}"
vars:
filename: "{{ item.item.stat.path | basename }}"
checksum:
file: "{{ item.item.stat.checksum }}"
artifact: "{{ item.artifact.sha256 }}"
- name: Query Pulp for presence of RPM package
ansible.builtin.uri:
url: "{{ pulp_url }}/pulp/api/v3/content/rpm/packages/\
?sha256={{ item.artifact.sha256 }}\
&fields=name,arch,version,release,epoch,sha256,location_href,pulp_href,artifact"
method: GET
status_code: [200]
loop: "{{ artifact_state.results }}"
loop_control:
label: "{{ item.artifact.sha256 }}"
register: content_query
- name: Create RPM content from uploaded artifact
ansible.builtin.uri:
url: "{{ pulp_url }}/pulp/api/v3/content/rpm/packages/"
method: POST
body:
artifact: "{{ artifact.pulp_href }}"
status_code: [202]
register: rpm_content
when: package_count == 0 or package_count == '0'
loop: "{{ content_query.results }}"
loop_control:
label: "{{ artifact.sha256 }}"
vars:
artifact: "{{ item.item.artifact }}"
package_count: "{{ item.json.count }}"
- name: Wait for content creation to finish # noqa: args[module]
pulp.squeezer.task:
pulp_href: "{{ item.json.task }}"
register: task_status
until: task_status.task.state == 'completed' or task_status.task.state == 'failed'
retries: 30
delay: 2
changed_when:
- task_status.task.created_resources is defined
- task_status.task.created_resources | length > 0
failed_when:
- task_status.task.state == 'failed'
- not 'There is already a package' in task_status.task.error.description
loop: "{{ rpm_content.results | selectattr('skipped', 'undefined') | list }}"
loop_control:
label: "{{ item.json.task | default('') }}"
- name: Query Pulp for presence of RPM package
ansible.builtin.uri:
url: "{{ pulp_url }}/pulp/api/v3/content/rpm/packages/\
?sha256={{ item.artifact.sha256 }}\
&fields=name,arch,version,release,epoch,sha256,location_href,pulp_href,artifact"
method: GET
status_code: [200]
loop: "{{ artifact_state.results }}"
loop_control:
label: "{{ item.artifact.sha256 }}"
register: content_query
- name: Debug - Display per package result(s) of package query
ansible.builtin.debug:
msg: "{{ item.json }}"
verbosity: 1
loop: "{{ content_query.results }}"
loop_control:
label: "{{ item.json.results.0.location_href }}"
- name: Debug - Display generated list of pulp_href's of packages
ansible.builtin.debug:
msg: >
{{ content_query.results
| map(attribute='json.results')
| flatten
| map(attribute='pulp_href')
| list }}
verbosity: 1
- name: Associate content with RPM repository
ansible.builtin.uri:
url: "{{ pulp_url }}{{ rpm_repository_href }}modify/"
method: POST
body:
add_content_units: "{{ package_href_list }}"
status_code: [202]
register: repo_content
vars:
rpm_repository_href: "{{ rpm_repository_output.repository.pulp_href }}"
package_href_list: >
{{ content_query.results
| map(attribute='json.results')
| flatten
| map(attribute='pulp_href')
| list }}
- name: Query for task completion # noqa: args[module]
pulp.squeezer.task:
pulp_href: "{{ repo_content.json.task }}"
register: task_status
until: task_status.task.state == 'completed' or task_status.task.state == 'failed'
retries: 15
delay: 2
failed_when: task_status.task.state == 'failed'
- name: Package already present in publication, done.
ansible.builtin.meta: end_host
when: task_status.task.created_resources | length < 1 # no new resources created
- name: Get publication href
ansible.builtin.set_fact:
publication_href: "{{ task_status.task.created_resources | select('search', '.*/publications/.*') | first }}"
- name: Make new publication of the RPM repository available # noqa: args[module]
pulp.squeezer.rpm_distribution:
name: "{{ rpm_repository_name }}"
base_path: "{{ rpm_repository_name }}"
publication: "{{ publication_href }}"
state: present
handlers:
- name: Clean-up copied files
ansible.builtin.file:
path: "{{ item.dest }}"
state: absent
loop: "{{ copy_status.results }}"
loop_control:
label: "{{ item.item.item.stat.path | basename }}" # on skip of the copy task item.dest is undefined.
when: item.dest is defined # do not try to remove file the copy task skipped