Add ppc64le osbuild-workers

Add playbooks, var files and role for setting up osbuild-composer
ppc64le workers. These are needed in order to build Fedora Workstation
ISO on ppc64le.

Related to:
 - https://pagure.io/fedora-infrastructure/issue/11243
 - https://fedoraproject.org/wiki/Changes/FedoraWorkstationImageBuilder

Signed-off-by: Tomáš Hozza <thozza@redhat.com>
This commit is contained in:
Tomáš Hozza 2023-06-21 17:01:50 +02:00 committed by kevin
parent d86babdfe9
commit b74b3a2da8
19 changed files with 1024 additions and 0 deletions

View file

@ -300,3 +300,9 @@ buildvm_stg
buildvm_ppc64le_stg
buildvm_aarch64_stg
buildvm_s390x_stg
[buildvm_osbuild_ppc64le]
buildvm-ppc64le-osbuild01.iad2.fedoraproject.org
[buildvm_osbuild_ppc64le_staging]
buildvm-ppc64le-osbuild02.iad2.fedoraproject.org

View file

@ -0,0 +1,33 @@
# common variables for osbuild workers
csi_primary_contact: Image Builder team - osbuilders@redhat.com
csi_purpose: This group of VMs builds OS images via Koji using image builder for ppc64le architecture.
csi_relationship: |
* Relies on koji-hub and image-builder-api (external).
* Produces automated builds of OS images for the architecture listed. Wokers can be scaled by adding new
virtual instances
datacenter: iad2
dns: 10.3.163.33
eth0_ipv4_gw: 10.3.171.254
ks_repo: http://10.3.163.35/pub/fedora-secondary/releases/38/Server/ppc64le/os/
ks_url: http://10.3.163.35/repo/rhel/ks/kvm-fedora
lvm_size: 102400 # 100 GB
main_bridge: br0
max_mem_size: "{{ mem_size }}"
mem_size: 8192 # 8 GB
num_cpus: 2
virt_install_command: "{{ virt_install_command_ppc64le_one_nic_unsafe }}"
volgroup: /dev/vg_guests
# osbuild worker variables
osbuild_worker_server_hostname: "api.openshift.com"
osbuild_worker_server_api_base_path: "/api/image-builder-worker/v1"
osbuild_worker_authentication_oauth_url: "https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token"
osbuild_worker_authentication_client_id: "ab28d581-164e-42ec-99d9-dff8e2020a51"
# the secret is turned into file in the playbook
osbuild_worker_authentication_client_secret: "{{ osbuild_worker_client_secret }}"
osbuild_worker_koji_instances:
- koji_host: "koji.fedoraproject.org"
krb_principal: "osbuild-automation-bot@FEDORAPROJECT.ORG"
krb_keytab_file: "{{ private }}/files/osbuild/worker_koji.keytab"

View file

@ -0,0 +1,33 @@
# common variables for osbuild workers (staging)
csi_primary_contact: Image Builder team - osbuilders@redhat.com
csi_purpose: This group of VMs builds OS images via Koji (staging) using image builder for ppc64le architecture.
csi_relationship: |
* Relies on koji-hub and image-builder-api (external).
* Produces automated builds of OS images for the architecture listed. Wokers can be scaled by adding new
virtual instances
datacenter: iad2
dns: 10.3.163.33
eth0_ipv4_gw: 10.3.171.254
ks_repo: http://10.3.163.35/pub/fedora-secondary/releases/38/Server/ppc64le/os/
ks_url: http://10.3.163.35/repo/rhel/ks/kvm-fedora
lvm_size: 102400 # 100 GB
main_bridge: br0
max_mem_size: "{{ mem_size }}"
mem_size: 4096 # 4 GB
num_cpus: 2
virt_install_command: "{{ virt_install_command_ppc64le_one_nic_unsafe }}"
volgroup: /dev/vg_guests
# osbuild worker variables
osbuild_worker_server_hostname: "api.stage.openshift.com"
osbuild_worker_server_api_base_path: "/api/image-builder-worker/v1"
osbuild_worker_authentication_oauth_url: "https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token"
osbuild_worker_authentication_client_id: "07120c6c-fd31-4735-bb2f-891439b0bf41"
# the secret is turned into file in the playbook
osbuild_worker_authentication_client_secret: "{{ osbuild_worker_stg_client_secret }}"
osbuild_worker_koji_instances:
- koji_host: "koji.stg.fedoraproject.org"
krb_principal: "osbuild-automation-bot@STG.FEDORAPROJECT.ORG"
krb_keytab_file: "{{ private }}/files/osbuild/worker_stg_koji.keytab"

View file

@ -0,0 +1,4 @@
---
datacenter: iad2
eth0_ipv4_ip: 10.3.171.38
vmhost: bvmhost-p09-05.iad2.fedoraproject.org

View file

@ -0,0 +1,4 @@
~---
datacenter: iad2
eth0_ipv4_ip: 10.3.171.39
vmhost: bvmhost-p09-05.iad2.fedoraproject.org

View file

@ -0,0 +1,56 @@
# create a new osbuild worker
- import_playbook: "/srv/web/infra/ansible/playbooks/include/virt-create.yml"
vars:
myhosts: "buildvm_osbuild_ppc64le:buildvm_osbuild_ppc64le_staging"
- name: make osbuild-worker
hosts: buildvm_osbuild_ppc64le:buildvm_osbuild_ppc64le_staging
user: root
gather_facts: True
vars_files:
- /srv/web/infra/ansible/vars/global.yml
- "{{ private }}/vars.yml"
- /srv/web/infra/ansible/vars/{{ ansible_distribution }}.yml
pre_tasks:
- include_vars: dir=/srv/web/infra/ansible/vars/all/ ignore_files=README
- import_tasks: "{{ tasks_path }}/yumrepos.yml"
roles:
- base
- hosts
- ipa/client
- sudo
tasks:
- name: Set up osbuild worker
block:
- name: Create temporary file for client secret
local_action: ansible.builtin.tempfile state="file" prefix="osbuild_"
# never report this as changed to make the playbook idempotent
changed_when: false
register: client_secret_tempfile
- name: Put secret into the temporary file
local_action: ansible.builtin.copy
content="{{ osbuild_worker_authentication_client_secret }}"
dest="{{ client_secret_tempfile.path }}"
mode="440"
# never report this as changed to make the playbook idempotent
changed_when: false
- name: Import role to configure osbuild-worker
ansible.builtin.import_role:
name: ansible-osbuild-worker
vars:
# rest of the vars are set in the appropriate group_vars
osbuild_worker_authentication_client_secret_file: "{{ client_secret_tempfile.path }}"
always:
- name: Remove temporary file with client secret
local_action: ansible.builtin.file path="{{ client_secret_tempfile.path }}" state=absent
# never report this as changed to make the playbook idempotent
changed_when: false
when: client_secret_tempfile is defined and client_secret_tempfile.path is defined

View file

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View file

@ -0,0 +1,208 @@
# osbuild.osbuild_worker
This roles installs, configures and starts `osbuild-composer` remote worker on the host.
## Role Variables
The role has a few required variables, which must be provided by the user in order for the role to not fail.
**Required variables are:**
* `osbuild_worker_server_hostname`
* `osbuild_worker_authentication_oauth_url`
* `osbuild_worker_authentication_client_id`
* Any of
* `osbuild_worker_authentication_client_secret_file`
* `osbuild_worker_authentication_offline_token_file`
The rest of the variables are not required and if set, they enable optional functionality in the worker.
Variables that the user can set are listed and explained below:
```yaml
#################################
# General configuration options #
#################################
# The hostname of the osbuild-composer API server.
# REQUIRED
osbuild_worker_server_hostname: ""
# The osbuild-composer server API base path. If empty, the default value is used.
osbuild_worker_server_api_base_path: ""
# Worker proxy configuration.
osbuild_worker_proxy_server_hostname: ""
osbuild_worker_proxy_server_port: 443
osbuild_worker_no_proxy_domains: []
################################################
# Worker authentication to the composer server #
################################################
# The OAuth server URL.
# REQUIRED
osbuild_worker_authentication_oauth_url: ""
# The OAuth client ID.
# REQUIRED
osbuild_worker_authentication_client_id: ""
# Local path to the worker OAuth client secret file. If not empty, this file will be
# copied to the worker to {{ osbuild_worker_authentication_client_secret_path }}.
# REQUIRED (if osbuild_worker_authentication_offline_token_file not specified)
osbuild_worker_authentication_client_secret_file: ""
# Path to the worker OAuth client secret file on the worker. If empty,
# defaults to {{ osbuild_worker_authentication_client_secret_path_default }}.
osbuild_worker_authentication_client_secret_path: ""
# Local path to the worker OAuth offline token file. If not empty, this file will be
# copied to the worker to {{ osbuild_worker_authentication_offline_token_path }}.
# REQUIRED (if osbuild_worker_authentication_client_secret_file not specified)
osbuild_worker_authentication_offline_token_file: ""
# Path to the worker OAuth offline token file on the worker. If empty,
# defaults to {{ osbuild_worker_authentication_offline_token_path_default }}.
osbuild_worker_authentication_offline_token_path: ""
##########################
# Configuration for Koji #
##########################
osbuild_worker_koji_instances: []
# example:
# osbuild_worker_koji_instances:
# - koji_host: "koji.example.com"
# krb_principal: "osbuild-automation@EXAMPLE.COM"
# # Local path to the krb keytab file. If not empty, this file will be
# # copied to the worker to {{ krb_keytab_path }}.
# krb_keytab_file: ""
# # Path to the krb keytab file on the worker. If empty, a default path
# # under {{ osbuild_worker_config_dir }} with filename
# # "client_{{ koji_host }}.keytab" will be used.
# krb_keytab_path: ""
# relax_timeout_factor: 5
###########################
# Configuration for Azure #
###########################
# Local path to the Azure credentials file. If not empty, this file will be
# copied to the worker to {{ osbuild_worker_azure_credentials_path }}.
osbuild_worker_azure_credentials_file: ""
# Path to the Azure credentials file on the worker. If empty,
# defaults to {{ osbuild_worker_azure_credentials_path_default }}.
osbuild_worker_azure_credentials_path: ""
# Number of threads to use when uploading image blob to Azure. If 0, no
# explicit value is set in the configuration file and the worker will use
# its internal default. Set to a positive integer to override the default.
osbuild_worker_azure_upload_threads: 0
#########################
# Configuration for AWS #
#########################
# Local path to the AWS credentials file. If not empty, this file will be
# copied to the worker to {{ osbuild_worker_aws_credentials_path }}.
osbuild_worker_aws_credentials_file: ""
# Path to the AWS credentials file on the worker. If empty,
# defaults to {{ osbuild_worker_aws_credentials_path_default }}.
osbuild_worker_aws_credentials_path: ""
osbuild_worker_aws_bucket: ""
#########################
# Configuration for GCP #
#########################
# Local path to the GCP credentials file. If not empty, this file will be
# copied to the worker to {{ osbuild_worker_gcp_credentials_path }}.
osbuild_worker_gcp_credentials_file: ""
# Path to the GCP credentials file on the worker. If empty,
# defaults to {{ osbuild_worker_gcp_credentials_path_default }}.
osbuild_worker_gcp_credentials_path: ""
osbuild_worker_gcp_bucket: ""
```
### Internal variables
The role also uses some internal variables, which usually hold default values used by the role. Although the user can override them when using the role, this is discouraged. Do it only if you know what you are doing. Backward compatibility is not guaranteed when setting those.
```yaml
osbuild_worker_config_dir: /etc/osbuild-worker
osbuild_worker_config_dir_mode: '0755'
osbuild_worker_config_file: "{{ osbuild_worker_config_dir }}/osbuild-worker.toml"
osbuild_worker_config_file_mode: '0644'
osbuild_worker_remote_worker_service_name: osbuild-remote-worker@
osbuild_worker_remote_worker_service_dropin_dir: /etc/systemd/system/{{ osbuild_worker_remote_worker_service_name }}.service.d
osbuild_worker_remote_worker_service_proxy_dropin_file: "{{ osbuild_worker_remote_worker_service_dropin_dir }}/proxy.conf"
osbuild_worker_secrets_owner: root
osbuild_worker_secrets_group: root
osbuild_worker_secrets_mode: '0400'
osbuild_worker_authentication_client_secret_path_default: "{{ osbuild_worker_config_dir }}/client_secret"
osbuild_worker_authentication_offline_token_path_default: "{{ osbuild_worker_config_dir }}/offline_token"
osbuild_worker_azure_credentials_path_default: "{{ osbuild_worker_config_dir }}/azure-credentials"
osbuild_worker_aws_credentials_path_default: "{{ osbuild_worker_config_dir }}/aws-credentials"
osbuild_worker_gcp_credentials_path_default: "{{ osbuild_worker_config_dir }}/gcp-credentials"
```
## Dependencies
The role has no external dependencies.
## Example Playbook
Below is an example minimal playbook using the role with only the requires role variables specified. This playbook will install and configure remote `osbuild-worker` on the host with authentication settings for connecting to the remote `osbuild-composer` job queue server located at `composer.example.com`. The `client_secret` is expected to be a filename of a local file that will be copied to the remote host by the role.
Note that this example is not very useful, because the worker is not configured with any upload target authentication (e.g. AWS, Azure, GCP or Koji), thus it won't be able o upload the built image anywhere.
```yaml
- hosts: osbuild-worker
tasks:
- name: Include osbuild_worker role
ansible.builtin.include_role:
name: "osbuild.osbuild_worker"
vars:
osbuild_worker_server_hostname: "composer.example.com"
osbuild_worker_authentication_oauth_url: "oauth-server.example.com"
osbuild_worker_authentication_client_id: "osbuild-automation"
osbuild_worker_authentication_client_secret_file: "client_secret"
```
More useful example could be an instance of a remote worker configured with the option to upload built images to a Koji instance as well as to AWS. The following things are assumed:
* `client_secret` is a local filename with OAuth client secret
* `aws_credentials` is a local filename with AWS credentials
* `koji.keytab` is a local filename of Kerberos keytab file
```yaml
- hosts: osbuild-worker
tasks:
- name: Include osbuild_worker role
ansible.builtin.include_role:
name: "osbuild.osbuild_worker"
vars:
osbuild_worker_server_hostname: "composer.example.com"
osbuild_worker_authentication_oauth_url: "oauth-server.example.com"
osbuild_worker_authentication_client_id: "osbuild-automation"
osbuild_worker_authentication_client_secret_file: "client_secret"
osbuild_worker_aws_credentials_file: "aws_credentials"
osbuild_worker_aws_bucket: "my-s3-bucket"
osbuild_worker_koji_instances:
- koji_host: "koji.example.com"
krb_principal: "osbuild-automation@EXAMPLE.COM"
krb_keytab_file: "koji.keytab"
```
## What is NOT supported
* Configuring a local osbuild-worker.
* Configuring the "generic S3" upload target authentication.
* Configuring the "container registry" upload target authentication.
* Configuring the path to `dnf-json` binary.
* Configuring the proxy server in the worker configuration.
* Configuring the TLS client certificate authentication.
* Configuring the osbuild-composer server TLS CA certificate.
## License
Apache-2.0

View file

@ -0,0 +1,99 @@
---
# defaults file for osbuild_worker
#################################
# General configuration options #
#################################
# The hostname of the osbuild-composer API server.
# REQUIRED
osbuild_worker_server_hostname: ""
# The osbuild-composer server API base path. If empty, the default value is used.
osbuild_worker_server_api_base_path: ""
# Worker proxy configuration.
osbuild_worker_proxy_server_hostname: ""
osbuild_worker_proxy_server_port: 443
osbuild_worker_no_proxy_domains: []
################################################
# Worker authentication to the composer server #
################################################
# The OAuth server URL.
# REQUIRED
osbuild_worker_authentication_oauth_url: ""
# The OAuth client ID.
# REQUIRED
osbuild_worker_authentication_client_id: ""
# Local path to the worker OAuth client secret file. If not empty, this file will be
# copied to the worker to {{ osbuild_worker_authentication_client_secret_path }}.
# REQUIRED (if osbuild_worker_authentication_offline_token_file not specified)
osbuild_worker_authentication_client_secret_file: ""
# Path to the worker OAuth client secret file on the worker. If empty,
# defaults to {{ osbuild_worker_authentication_client_secret_path_default }}.
osbuild_worker_authentication_client_secret_path: ""
# Local path to the worker OAuth offline token file. If not empty, this file will be
# copied to the worker to {{ osbuild_worker_authentication_offline_token_path }}.
# REQUIRED (if osbuild_worker_authentication_client_secret_file not specified)
osbuild_worker_authentication_offline_token_file: ""
# Path to the worker OAuth offline token file on the worker. If empty,
# defaults to {{ osbuild_worker_authentication_offline_token_path_default }}.
osbuild_worker_authentication_offline_token_path: ""
##########################
# Configuration for Koji #
##########################
osbuild_worker_koji_instances: []
# example:
# osbuild_worker_koji_instances:
# - koji_host: "koji.example.com"
# krb_principal: "osbuild-automation@EXAMPLE.COM"
# # Local path to the krb keytab file. If not empty, this file will be
# # copied to the worker to {{ krb_keytab_path }}.
# krb_keytab_file: ""
# # Path to the krb keytab file on the worker. If empty, a default path
# # under {{ osbuild_worker_config_dir }} with filename
# # "client_{{ koji_host }}.keytab" will be used.
# krb_keytab_path: ""
# relax_timeout_factor: 5
###########################
# Configuration for Azure #
###########################
# Local path to the Azure credentials file. If not empty, this file will be
# copied to the worker to {{ osbuild_worker_azure_credentials_path }}.
osbuild_worker_azure_credentials_file: ""
# Path to the Azure credentials file on the worker. If empty,
# defaults to {{ osbuild_worker_azure_credentials_path_default }}.
osbuild_worker_azure_credentials_path: ""
# Number of threads to use when uploading image blob to Azure. If 0, no
# explicit value is set in the configuration file and the worker will use
# its internal default. Set to a positive integer to override the default.
osbuild_worker_azure_upload_threads: 0
#########################
# Configuration for AWS #
#########################
# Local path to the AWS credentials file. If not empty, this file will be
# copied to the worker to {{ osbuild_worker_aws_credentials_path }}.
osbuild_worker_aws_credentials_file: ""
# Path to the AWS credentials file on the worker. If empty,
# defaults to {{ osbuild_worker_aws_credentials_path_default }}.
osbuild_worker_aws_credentials_path: ""
osbuild_worker_aws_bucket: ""
#########################
# Configuration for GCP #
#########################
# Local path to the GCP credentials file. If not empty, this file will be
# copied to the worker to {{ osbuild_worker_gcp_credentials_path }}.
osbuild_worker_gcp_credentials_file: ""
# Path to the GCP credentials file on the worker. If empty,
# defaults to {{ osbuild_worker_gcp_credentials_path_default }}.
osbuild_worker_gcp_credentials_path: ""
osbuild_worker_gcp_bucket: ""

View file

@ -0,0 +1,7 @@
---
- name: Restart remote worker
become: true
ansible.builtin.systemd:
name: "{{ osbuild_worker_remote_worker_service_name }}{{ osbuild_worker_server_hostname }}"
daemon_reload: true
state: restarted

View file

@ -0,0 +1,2 @@
install_date: "\xDAt\_20.\_\u010Dervna\_2023,\_16:41:07"
version: main

View file

@ -0,0 +1,23 @@
galaxy_info:
role_name: osbuild_worker
namespace: osbuild
author: Tomáš Hozza
description: Ansible role for deploying osbuild-composer worker
company: Red Hat
issue_tracker_url: https://github.com/osbuild/ansible-osbuild-worker/issues
license: Apache-2.0
min_ansible_version: "2.1"
platforms:
- name: Fedora
versions:
- all
- name: EL
versions:
- "8"
- "9"
galaxy_tags:
- "osbuild"
- "composer"
- "worker"
dependencies: []

View file

@ -0,0 +1,97 @@
---
# tasks to deploy osbuild worker
- name: Install osbuild-composer-worker
become: true
ansible.builtin.dnf:
name:
- osbuild-composer-worker
state: installed
update_cache: true
- name: Create worker configuration directory
become: true
ansible.builtin.file:
path: "{{ osbuild_worker_config_dir }}"
state: directory
mode: "{{ osbuild_worker_config_dir_mode }}"
- name: Copy secrets to the worker
become: true
ansible.builtin.copy:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
owner: "{{ osbuild_worker_secrets_owner }}"
group: "{{ osbuild_worker_secrets_group }}"
mode: "{{ osbuild_worker_secrets_mode }}"
loop:
- { src: "{{ osbuild_worker_authentication_client_secret_file }}", dest: "{{ osbuild_worker_authentication_client_secret_path }}" }
- { src: "{{ osbuild_worker_authentication_offline_token_file }}", dest: "{{ osbuild_worker_authentication_offline_token_path }}" }
- { src: "{{ osbuild_worker_azure_credentials_file }}", dest: "{{ osbuild_worker_azure_credentials_path }}" }
- { src: "{{ osbuild_worker_aws_credentials_file }}", dest: "{{ osbuild_worker_aws_credentials_path }}" }
- { src: "{{ osbuild_worker_gcp_credentials_file }}", dest: "{{ osbuild_worker_gcp_credentials_path }}" }
when: item.src | length > 0 and item.dest | length > 0
notify: Restart remote worker
- name: Copy Koji keytabs to the worker
become: true
ansible.builtin.copy:
src: "{{ item.krb_keytab_file }}"
dest: "{{ item.krb_keytab_path }}"
owner: "{{ osbuild_worker_secrets_owner }}"
group: "{{ osbuild_worker_secrets_group }}"
mode: "{{ osbuild_worker_secrets_mode }}"
loop: "{{ _osbuild_worker_koji_instances }}"
when: _osbuild_worker_koji_instances is defined and _osbuild_worker_koji_instances | length > 0
notify: Restart remote worker
- name: Configure osbuild-remote-worker to use proxy
when: osbuild_worker_proxy_server_hostname | length > 0
become: true
block:
- name: Create drop-in directory for osbuild-remote-worker service
ansible.builtin.file:
path: "{{ osbuild_worker_remote_worker_service_dropin_dir }}"
state: directory
mode: '0755'
- name: Configure osbuild-remote-worker to use proxy using drop-in
ansible.builtin.template:
src: templates/osbuild-remote-worker-proxy.conf.j2
dest: "{{ osbuild_worker_remote_worker_service_proxy_dropin_file }}"
mode: '0644'
notify: Restart remote worker
- name: Copy osbuild-worker configuration file
become: true
ansible.builtin.template:
src: templates/osbuild-worker.toml.j2
dest: "{{ osbuild_worker_config_file }}"
mode: "{{ osbuild_worker_config_file_mode }}"
notify: Restart remote worker
- name: Stop any unwanted osbuild-remote-worker services
become: true
block:
- name: Populate service facts
ansible.builtin.service_facts:
- name: Filter any unwanted osbuild-remote-worker services
ansible.builtin.set_fact:
osbuild_remote_worker_services_unwanted: "{{ ansible_facts.services | list | select('regex', '^osbuild-remote-worker@.+.service$')
| difference([_osbuild_remote_worker_service_wanted]) }}"
vars:
_osbuild_remote_worker_service_wanted: "{{ osbuild_worker_remote_worker_service_name }}{{ osbuild_worker_server_hostname }}.service"
- name: Stop and disable any running osbuild-remote-worker service for a different server
ansible.builtin.service:
name: "{{ item }}"
state: stopped
enabled: false
loop: "{{ osbuild_remote_worker_services_unwanted }}"
- name: Start and enable osbuild-remote-worker service
become: true
ansible.builtin.service:
name: "{{ osbuild_worker_remote_worker_service_name }}{{ osbuild_worker_server_hostname }}.service"
state: started
enabled: true

View file

@ -0,0 +1,11 @@
---
# tasks for osbuild_worker role
- name: Validate set role variables
ansible.builtin.include_tasks: tasks/vars_validate.yml
- name: Define unset role variables
ansible.builtin.include_tasks: tasks/vars_define.yml
- name: Install and configure osbuild-composer worker
ansible.builtin.include_tasks: tasks/deploy_worker.yml

View file

@ -0,0 +1,36 @@
---
# tasks to define potentially missing variables
- name: Define worker Oauth client secret path if not defined
ansible.builtin.set_fact:
osbuild_worker_authentication_client_secret_path: "{{ osbuild_worker_authentication_client_secret_path_default }}"
when: osbuild_worker_authentication_client_secret_file | length > 0 and osbuild_worker_authentication_client_secret_path | length == 0
- name: Define worker Oauth offline token path if not defined
ansible.builtin.set_fact:
osbuild_worker_authentication_offline_token_path: "{{ osbuild_worker_authentication_offline_token_path_default }}"
when: osbuild_worker_authentication_offline_token_file | length > 0 and osbuild_worker_authentication_offline_token_path | length == 0
- name: Define Azure credentials path on worker if not defined
ansible.builtin.set_fact:
osbuild_worker_azure_credentials_path: "{{ osbuild_worker_azure_credentials_path_default }}"
when: osbuild_worker_azure_credentials_file | length > 0 and osbuild_worker_azure_credentials_path | length == 0
- name: Define AWS credentials path on worker if not defined
ansible.builtin.set_fact:
osbuild_worker_aws_credentials_path: "{{ osbuild_worker_aws_credentials_path_default }}"
when: osbuild_worker_aws_credentials_file | length > 0 and osbuild_worker_aws_credentials_path | length == 0
- name: Define GCP credentials path on worker if not defined
ansible.builtin.set_fact:
osbuild_worker_gcp_credentials_path: "{{ osbuild_worker_gcp_credentials_path_default }}"
when: osbuild_worker_gcp_credentials_file | length > 0 and osbuild_worker_gcp_credentials_path | length == 0
- name: Ensure that Koji keytab paths on worker are defined
ansible.builtin.set_fact:
_osbuild_worker_koji_instances: "{{ (_osbuild_worker_koji_instances | default([])) + [_item] }}"
vars:
_krb_keytab_path: "{{ (item.krb_keytab_path is not defined or item.krb_keytab_path | length == 0) | \
ternary(osbuild_worker_config_dir + '/client_' + item.koji_host + '.keytab', item.krb_keytab_path) }}"
_item: "{{ item | combine({'krb_keytab_path': _krb_keytab_path}) }}"
loop: "{{ osbuild_worker_koji_instances }}"

View file

@ -0,0 +1,123 @@
---
# tasks to validate variable values
- name: Check that required variables are set
block:
- name: Check that osbuild_worker_server_hostname is set
ansible.builtin.assert:
quiet: true
that:
- osbuild_worker_server_hostname is defined
- osbuild_worker_server_hostname | length > 0
fail_msg: "osbuild_worker_server_hostname must be set"
- name: Check that osbuild_worker_authentication_oauth_url is set
ansible.builtin.assert:
quiet: true
that:
- osbuild_worker_authentication_oauth_url is defined
- osbuild_worker_authentication_oauth_url | length > 0
fail_msg: "osbuild_worker_authentication_oauth_url must be set"
- name: Check that osbuild_worker_authentication_client_id is set
ansible.builtin.assert:
quiet: true
that:
- osbuild_worker_authentication_client_id is defined
- osbuild_worker_authentication_client_id | length > 0
fail_msg: "osbuild_worker_authentication_client_id must be set"
- name: Check that at least one of osbuild_worker_authentication_client_secret_file or osbuild_worker_authentication_offline_token_file is set
ansible.builtin.assert:
quiet: true
that:
- is_client_secret_file_defined or is_offline_token_file_defined
fail_msg: "At least one of osbuild_worker_authentication_client_secret_file and osbuild_worker_authentication_offline_token_file must be set"
vars:
is_client_secret_file_defined:
"{{ osbuild_worker_authentication_client_secret_file is defined and osbuild_worker_authentication_client_secret_file | length > 0 }}"
is_offline_token_file_defined:
"{{ osbuild_worker_authentication_offline_token_file is defined and osbuild_worker_authentication_offline_token_file | length > 0 }}"
- name: Check optional variables
block:
- name: Check that osbuild_worker_authentication_client_secret_file is set if osbuild_worker_authentication_client_secret_path is set
ansible.builtin.assert:
quiet: true
that:
- osbuild_worker_authentication_client_secret_file is defined
- osbuild_worker_authentication_client_secret_file | length > 0
fail_msg: "osbuild_worker_authentication_client_secret_file must be set if osbuild_worker_authentication_client_secret_path is set"
when: osbuild_worker_authentication_client_secret_path | length > 0
- name: Check that osbuild_worker_authentication_offline_token_file is set if osbuild_worker_authentication_offline_token_path is set
ansible.builtin.assert:
quiet: true
that:
- osbuild_worker_authentication_offline_token_file is defined
- osbuild_worker_authentication_offline_token_file | length > 0
fail_msg: "osbuild_worker_authentication_offline_token_file must be set if osbuild_worker_authentication_offline_token_path is set"
when: osbuild_worker_authentication_offline_token_path | length > 0
- name: Check Koji variables
when: osbuild_worker_koji_instances | length > 0
block:
- name: Check that required Koji variables are set
ansible.builtin.assert:
quiet: true
that:
- item.koji_host is defined
- item.koji_host | length > 0
- item.krb_principal is defined
- item.krb_principal | length > 0
- item.krb_keytab_file is defined
- item.krb_keytab_file | length > 0
fail_msg: All of koji_host, krb_principal, and krb_keytab_file must be set for each Koji instance
loop: "{{ osbuild_worker_koji_instances }}"
- name: Check that relax_timeout_factor is a positive integer
ansible.builtin.assert:
quiet: true
that:
- item.relax_timeout_factor | int > 0
fail_msg: relax_timeout_factor must be a positive integer if set
loop: "{{ osbuild_worker_koji_instances }}"
when: item.relax_timeout_factor is defined
- name: Check Azure variables
block:
- name: Check that no Azure variables are set if osbuild_worker_azure_credentials_file is not set
ansible.builtin.assert:
quiet: true
that:
- osbuild_worker_azure_credentials_path | length == 0
- osbuild_worker_azure_upload_threads == 0
fail_msg: "osbuild_worker_azure_credentials_path and osbuild_worker_azure_upload_threads must not be set
if osbuild_worker_azure_credentials_file is not set"
when: osbuild_worker_azure_credentials_file | length == 0
- name: Check that osbuild_worker_azure_upload_threads is a positive integer
ansible.builtin.assert:
quiet: true
that:
- osbuild_worker_azure_upload_threads | int > 0
fail_msg: "osbuild_worker_azure_upload_threads must be a positive integer"
when: osbuild_worker_azure_upload_threads != 0
- name: Check that no AWS variables are set if osbuild_worker_aws_credentials_file is not set
ansible.builtin.assert:
quiet: true
that:
- osbuild_worker_aws_credentials_path | length == 0
- osbuild_worker_aws_bucket | length == 0
fail_msg: "osbuild_worker_aws_credentials_path and osbuild_worker_aws_bucket must not be set if osbuild_worker_aws_credentials_file is not set"
when: osbuild_worker_aws_credentials_file | length == 0
- name: Check that no GCP variables are set if osbuild_worker_gcp_credentials_file is not set
ansible.builtin.assert:
quiet: true
that:
- osbuild_worker_gcp_credentials_path | length == 0
- osbuild_worker_gcp_bucket | length == 0
fail_msg: "osbuild_worker_gcp_credentials_path and osbuild_worker_gcp_bucket must not be set if osbuild_worker_gcp_credentials_file is not set"
when: osbuild_worker_gcp_credentials_file | length == 0

View file

@ -0,0 +1,6 @@
[Service]
Environment="http_proxy={{ osbuild_worker_proxy_server_hostname }}:{{ osbuild_worker_proxy_server_port }}"
Environment="https_proxy={{ osbuild_worker_proxy_server_hostname }}:{{ osbuild_worker_proxy_server_port }}"
{% if osbuild_worker_no_proxy_domains is defined and osbuild_worker_no_proxy_domains | length > 0 %}
Environment="no_proxy={{ osbuild_worker_no_proxy_domains | join(',') }}"
{% endif %}

View file

@ -0,0 +1,52 @@
# {{ ansible_managed }}
{% if osbuild_worker_server_api_base_path %}
base_path = "{{ osbuild_worker_server_api_base_path }}"
{% endif %}
[authentication]
oauth_url = "{{ osbuild_worker_authentication_oauth_url }}"
client_id = "{{ osbuild_worker_authentication_client_id }}"
{% if osbuild_worker_authentication_client_secret_path %}
client_secret = "{{ osbuild_worker_authentication_client_secret_path }}"
{% endif %}
{%if osbuild_worker_authentication_offline_token_path %}
offline_token = "{{ osbuild_worker_authentication_offline_token_path }}"
{% endif %}
{% if _osbuild_worker_koji_instances is defined %}
{% for koji_instance in _osbuild_worker_koji_instances %}
{% if koji_instance.relax_timeout_factor is defined %}
[koji."{{ koji_instance.koji_host }}"]
relax_timeout_factor = {{ koji_instance.relax_timeout_factor }}
{% endif %}
[koji."{{ koji_instance.koji_host }}".kerberos]
principal = "{{ koji_instance.krb_principal }}"
keytab = "{{ koji_instance.krb_keytab_path }}"
{% endfor %}
{% endif %}
{% if osbuild_worker_azure_credentials_path is defined and osbuild_worker_azure_credentials_path %}
[azure]
credentials = "{{ osbuild_worker_azure_credentials_path }}"
{% if osbuild_worker_azure_upload_threads is defined %}
upload_threads = {{ osbuild_worker_azure_upload_threads }}
{% endif %}
{% endif %}
{% if osbuild_worker_aws_credentials_path is defined and osbuild_worker_aws_credentials_path %}
[aws]
credentials = "{{ osbuild_worker_aws_credentials_path }}"
{% if osbuild_worker_aws_bucket is defined %}
bucket = "{{ osbuild_worker_aws_bucket }}"
{% endif %}
{% endif %}
{% if osbuild_worker_gcp_credentials_path is defined and osbuild_worker_gcp_credentials_path %}
[gcp]
credentials = "{{ osbuild_worker_gcp_credentials_path }}"
{% if osbuild_worker_gcp_bucket is defined %}
bucket = "{{ osbuild_worker_gcp_bucket }}"
{% endif %}
{% endif %}

View file

@ -0,0 +1,23 @@
---
# vars file for osbuild_worker
osbuild_worker_config_dir: /etc/osbuild-worker
osbuild_worker_config_dir_mode: '0755'
osbuild_worker_config_file: "{{ osbuild_worker_config_dir }}/osbuild-worker.toml"
osbuild_worker_config_file_mode: '0644'
osbuild_worker_remote_worker_service_name: osbuild-remote-worker@
osbuild_worker_remote_worker_service_dropin_dir: /etc/systemd/system/{{ osbuild_worker_remote_worker_service_name }}.service.d
osbuild_worker_remote_worker_service_proxy_dropin_file: "{{ osbuild_worker_remote_worker_service_dropin_dir }}/proxy.conf"
osbuild_worker_secrets_owner: root
osbuild_worker_secrets_group: root
osbuild_worker_secrets_mode: '0400'
osbuild_worker_authentication_client_secret_path_default: "{{ osbuild_worker_config_dir }}/client_secret"
osbuild_worker_authentication_offline_token_path_default: "{{ osbuild_worker_config_dir }}/offline_token"
osbuild_worker_azure_credentials_path_default: "{{ osbuild_worker_config_dir }}/azure-credentials"
osbuild_worker_aws_credentials_path_default: "{{ osbuild_worker_config_dir }}/aws-credentials"
osbuild_worker_gcp_credentials_path_default: "{{ osbuild_worker_config_dir }}/gcp-credentials"