Browse Source

fix a bug with the start_compose module

ca-cert-and-multi-ks
Nicolas Massé 2 years ago
parent
commit
7cb7d78d2d
  1. 5
      ansible/ansible.cfg
  2. 25
      ansible/build.yaml
  3. 5
      ansible/plugins/modules/README.md
  4. 339
      ansible/plugins/modules/start_compose2.py
  5. 28
      ansible/templates/kiosk.ks.j2
  6. 21
      imagebuilder/kiosk.ks

5
ansible/ansible.cfg

@ -2,6 +2,5 @@
# Use the provided inventory # Use the provided inventory
inventory = inventory.yaml inventory = inventory.yaml
# To get the vault password from the KDE Wallet # Use a forked copy of the infra.osbuild plugins
vault_identity_list = itix@/home/nmasse/local/bin/get-vault-password library = plugins/modules

25
ansible/build.yaml

@ -9,6 +9,11 @@
update: yes update: yes
clone: yes clone: yes
- ansible.builtin.tempfile:
state: directory
suffix: -build
register: tmp
## ##
## RPM construction ## RPM construction
## ##
@ -127,7 +132,7 @@
blueprint: "{{ lookup('ansible.builtin.template', 'kiosk.toml.j2') }}" blueprint: "{{ lookup('ansible.builtin.template', 'kiosk.toml.j2') }}"
- name: Start ostree compose - name: Start ostree compose
infra.osbuild.start_compose: start_compose2:
blueprint: "{{ blueprint_name }}" blueprint: "{{ blueprint_name }}"
allow_duplicate: true allow_duplicate: true
compose_type: edge-commit compose_type: edge-commit
@ -145,11 +150,6 @@
compose_id: "{{ compose_id }}" compose_id: "{{ compose_id }}"
timeout: 3600 timeout: 3600
- ansible.builtin.tempfile:
state: directory
suffix: build
register: tmp
- name: Export the compose artifact - name: Export the compose artifact
infra.osbuild.export_compose: # noqa only-builtins infra.osbuild.export_compose: # noqa only-builtins
compose_id: "{{ compose_id }}" compose_id: "{{ compose_id }}"
@ -204,7 +204,7 @@
blueprint: "{{ lookup('ansible.builtin.file', playbook_dir ~ '/files/edge-installer.toml') }}" blueprint: "{{ lookup('ansible.builtin.file', playbook_dir ~ '/files/edge-installer.toml') }}"
- name: Start ostree compose - name: Start ostree compose
infra.osbuild.start_compose: start_compose2:
blueprint: "{{ blueprint_name }}" blueprint: "{{ blueprint_name }}"
allow_duplicate: true allow_duplicate: true
compose_type: edge-installer compose_type: edge-installer
@ -221,11 +221,6 @@
compose_id: "{{ compose_id }}" compose_id: "{{ compose_id }}"
timeout: 3600 timeout: 3600
- ansible.builtin.tempfile:
state: directory
suffix: build
register: tmp
- name: Export the compose artifact - name: Export the compose artifact
infra.osbuild.export_compose: # noqa only-builtins infra.osbuild.export_compose: # noqa only-builtins
compose_id: "{{ compose_id }}" compose_id: "{{ compose_id }}"
@ -250,3 +245,9 @@
dest: "{{ www_location }}/kiosk.iso" dest: "{{ www_location }}/kiosk.iso"
remote_src: true remote_src: true
become: true become: true
post_tasks:
- ansible.builtin.file:
path: "{{ tmp.path }}.iso"
state: absent
when: tmp is defined

5
ansible/plugins/modules/README.md

@ -0,0 +1,5 @@
# README
This is a modified version of the start_compose module from the repo https://github.com/redhat-cop/infra.osbuild, commit 6e3416233c84623b2edd503a4b50d15c61d6c155.
The module has been patched to specify the ostree ref when starting a compose of type "ostree-commit".

339
ansible/plugins/modules/start_compose2.py

@ -0,0 +1,339 @@
#!/usr/bin/python
# Copyright: Red Hat Inc.
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
ANSIBLE_METADATA = {
"metadata_version": "1.1",
"status": ["preview"],
"supported_by": "community",
}
DOCUMENTATION = """
---
module: start_compose2
short_description: Start an ostree compose
description:
- Start an ostree compose
author:
- Adam Miller (@maxamillion)
- Chris Santiago (@resoluteCoder)
options:
blueprint:
description:
- Name of blueprint to iniate a build for
type: str
required: true
size:
description:
- Image size expressed in MiB
type: int
default: 0
required: false
profile:
description:
- Path to profile toml file
type: str
default: ""
required: false
image_name:
description:
- Image name
type: str
default: ""
required: false
allow_duplicate:
description:
- Allow a duplicate version'd compose.
- (Default osbuild composer functionality is to allow duplicate composes)
type: bool
default: True
required: false
compose_type:
description:
- type of compose
type: str
default: "edge-commit"
required: false
choices:
- ami
- edge-commit
- edge-container
- edge-installer
- edge-raw-image
- edge-simplified-installer
- image-installer
- oci
- openstack
- qcow2
- tar
- vhd
- vmdk
- iot-commit
- iot-container
- iot-installer
- iot-raw-image
- container
ostree_ref:
description:
- ostree ref
type: str
default: ""
required: false
ostree_parent:
description:
- ostree parent
type: str
default: ""
required: false
ostree_url:
description:
- ostree URL
type: str
default: ""
required: false
timeout:
description:
- timeout for osbuild-compose requests, in seconds
type: int
default: 120
required: false
notes:
- THIS MODULE IS NOT IDEMPOTENT UNLESS C(allow_duplicate) is set to C(false)
- The params C(profile) and C(image_name) are required together.
- The C(profile) option is not fully implemented at this time.
"""
EXAMPLES = """
- name: Start ostree compose size 4096
start_compose2:
blueprint: rhel-for-edge-demo
image_name: testimage
size: 4096
- name: Start ostree compose with idempotent transaction
start_compose2:
blueprint: rhel-for-edge-demo
allow_duplicate: false
"""
import json # noqa E402
import socket
from typing import Any # noqa E402
from ansible.module_utils.basic import AnsibleModule # noqa E402
from ansible_collections.infra.osbuild.plugins.module_utils.weldr import Weldr # noqa E402
argument_spec = dict(
blueprint=dict(type="str", required=True),
size=dict(type="int", required=False, default=0),
profile=dict(type="str", required=False, default=""),
image_name=dict(type="str", required=False, default=""),
allow_duplicate=dict(type="bool", required=False, default=True),
compose_type=dict(
type="str",
required=False,
default="edge-commit",
choices=[
"ami",
"edge-commit",
"edge-container",
"edge-installer",
"edge-raw-image",
"edge-simplified-installer",
"image-installer",
"oci",
"openstack",
"qcow2",
"tar",
"vhd",
"vmdk",
"iot-commit",
"iot-container",
"iot-installer",
"iot-raw-image",
"container",
],
),
ostree_ref=dict(type="str", required=False, default=""),
ostree_parent=dict(type="str", required=False, default=""),
ostree_url=dict(type="str", required=False, default=""),
timeout=dict(type="int", required=False, default=120),
)
def start_compose(module, weldr):
changed: bool = False
dupe_compose: list = []
blueprint_info: dict = weldr.api.get_blueprints_info(module.params["blueprint"])
blueprint_version: int = blueprint_info["blueprints"][0]["version"]
# Add check if compose_type is supported
supported_compose_type: dict = weldr.api.get_compose_types()
is_supported: dict = next((item for item in supported_compose_type["types"] if item["name"] == module.params["compose_type"]), {})
if not is_supported:
module.fail_json(
msg="%s is not a valid image type, valid types are: %s"
% (module.params["compose_type"], [[v for k, v in t.items() if k == "name"] for t in supported_compose_type["types"]]),
changed=changed
)
else:
if not is_supported["enabled"]:
module.fail_json(
msg="%s is not a supported image type, supported image types are: %s"
% (module.params["compose_type"], [[v for k, v in t.items() if k == "enabled" and v is True] for t in supported_compose_type["types"]]),
changed=changed
)
if not module.params["allow_duplicate"]:
# only do all this query and filtering if needed
compose_queue: dict = weldr.api.get_compose_queue()
# {"new":[],"run":[{"id":"930a1584-8737-4b61-ba77-582780f0ff2d","blueprint":"base-image-with-tmux","version":"0.0.5","compose_type":"edge-commit","image_size":0,"queue_status":"RUNNING","job_created":1654620015.4107578,"job_started":1654620015.415151}]}
compose_queue_run_dupe: list = [
compose for compose in compose_queue["run"] if (compose["blueprint"] == module.params["blueprint"]) and (compose["version"] == blueprint_version)
]
compose_queue_new_dupe: list = [
compose for compose in compose_queue["new"] if (compose["blueprint"] == module.params["blueprint"]) and (compose["version"] == blueprint_version)
]
compose_finished: dict = weldr.api.get_compose_finished()
# {"finished":[{"id":"930a1584-8737-4b61-ba77-582780f0ff2d","blueprint":"base-image-with-tmux","version":"0.0.5","compose_type":"edge-commit","image_size":8192,"queue_status":"FINISHED","job_created":1654620015.4107578,"job_started":1654620015.415151,"job_finished":1654620302.9069786}]}
compose_finished_dupe: list = [
compose
for compose in compose_finished["finished"]
if (compose["blueprint"] == module.params["blueprint"]) and (compose["version"] == blueprint_version)
]
compose_failed: dict = weldr.api.get_compose_failed()
# {"failed":[]}
compose_failed_dupe: list = [
compose
for compose in compose_failed["failed"]
if (compose["blueprint"] == module.params["blueprint"]) and (compose["version"] == blueprint_version)
]
dupe_compose: list = compose_queue_run_dupe + compose_queue_new_dupe + compose_failed_dupe + compose_finished_dupe
if module.params["allow_duplicate"] or (len(dupe_compose) == 0):
# FIXME - build to POST payload and POST that ish
compose_settings: dict[str, Any] = {
"blueprint_name": module.params["blueprint"],
"compose_type": module.params["compose_type"],
"branch": "master",
"size": module.params["size"],
}
if "edge-commit" in module.params["compose_type"] or "installer" in module.params["compose_type"] or "raw" in module.params["compose_type"]:
compose_settings["ostree"] = {
"ref": module.params["ostree_ref"],
"parent": module.params["ostree_parent"],
"url": module.params["ostree_url"],
}
try:
result: dict = weldr.api.post_compose(json.dumps(compose_settings), timeout=module.params["timeout"])
except socket.timeout:
# it's possible we don't get a response back from weldr because on the
# very first run including a new content source composer will build a repo cache
# and when that happens we get an empty JSON response
compose_queue: dict = weldr.api.get_compose_queue()
# {"new":[],"run":[{"id":"930a1584-8737-4b61-ba77-582780f0ff2d","blueprint":"base-image-with-tmux","version":"0.0.5","compose_type":"edge-commit","image_size":0,"queue_status":"RUNNING","job_created":1654620015.4107578,"job_started":1654620015.415151}]}
submitted_compose_uuid: str = ""
submitted_compose_found_run: list[dict[str, str]] = [
compose
for compose in compose_queue["run"]
if (compose["blueprint"] == module.params["blueprint"]) and (compose["version"] == blueprint_version)
]
if submitted_compose_found_run:
# we expect it to be RUNNING, so check that first
submitted_compose_uuid: str = submitted_compose_found_run[0]["id"]
else:
# didn't find it running, check for NEW queue status
submitted_compose_found_new: list = [
compose
for compose in compose_queue["new"]
if (compose["blueprint"] == module.params["blueprint"]) and (compose["version"] == blueprint_version)
]
if submitted_compose_found_new:
submitted_compose_uuid: str = submitted_compose_found_new[0]["id"]
else:
# it's not RUNNING and not NEW, so check for FAILURE state
compose_failed: dict = weldr.api.get_compose_failed()
# {"failed":[]}
submitted_compose_found_failed: list = [
compose
for compose in compose_failed["failed"]
if (compose["blueprint"] == module.params["blueprint"]) and (compose["version"] == blueprint_version)
]
if submitted_compose_found_failed:
submitted_compose_uuid: str = submitted_compose_found_failed[0]["id"]
else:
module.fail_json(
msg="Unable to determine state of build, check osbuild-composer system logs. Also, consider increasing the request timeout",
changed=changed
)
if submitted_compose_uuid:
result: dict = weldr.api.get_compose_status(submitted_compose_uuid)
result['body'] = {
'build_id': submitted_compose_uuid
}
if "status_code" in result.keys():
if result["status_code"] >= 400:
module.fail_json(
msg="Compose returned body: {0}, msg {1}, and status_code {2}".format(result["body"], result["error_msg"], result["status_code"]),
changed=changed
)
# Having received a non-400+ response, we know a compose has started
changed: bool = True
compose_output_types: dict[str, list[str]] = {
"tar": ["tar", "edge-commit", "iot-commit", "edge-container", "iot-container", "container"],
"iso": ["edge-installer", "edge-simplified-installer", "iot-installer", "image-installer"],
"qcow2": ["qcow2", "openstack", "oci"],
"vmdk": ["vmdk"],
"vhd": ["vhd"],
"raw.xz": ["edge-raw-image", "iot-raw-image"],
"ami": ["ami"],
}
output_type: str = ""
for compose_type, compose_type_list in compose_output_types.items():
if module.params["compose_type"] in compose_type_list:
output_type: str = compose_type
result["output_type"] = output_type
module.exit_json(msg="Compose submitted to queue", result=result, changed=changed)
else:
changed: bool = False
module.exit_json(
msg="Not queuing a duplicate versioned compose without allow_duplicate set to true",
changed=changed,
)
def main() -> None:
module: AnsibleModule = AnsibleModule(
argument_spec=argument_spec,
required_together=[["image_name", "profile"]],
required_if=[
["compose_type", "edge-installer", ["ostree_url"]],
["compose_type", "iot-installer", ["ostree_url"]],
],
)
weldr: Weldr = Weldr(module)
start_compose(module, weldr)
if __name__ == "__main__":
main()

28
ansible/templates/kiosk.ks.j2

@ -21,32 +21,15 @@ reboot
text text
## ##
## Storage configuration ## Storage configuration for only one disk
##
# Clear the target disk
zerombr
# Remove existing partitions
clearpart --all --initlabel
# Automatically create partitions required by hardware platform
# and add a separate /boot partition
reqpart --add-boot
##
## Alternative partitioning on only one disk
## /dev/disk/by-path/pci-0000:00:12.0-ata-1 instead of sda when sda is taken by the usb stick ## /dev/disk/by-path/pci-0000:00:12.0-ata-1 instead of sda when sda is taken by the usb stick
## ##
zerombr zerombr
clearpart --all --initlabel clearpart --all --initlabel
reqpart --add-boot reqpart --add-boot
part pv.01 --size=10240 --ondisk=/dev/disk/by-path/pci-0000:00:12.0-ata-1 part pv.01 --size=1024 --grow --ondisk=/dev/disk/by-path/pci-0000:00:12.0-ata-1
volgroup system pv.01 volgroup rhel pv.01
logvol / --fstype="xfs" --size=1 --grow --name=root --vgname=system logvol / --fstype="xfs" --size=10240 --name=root --vgname=rhel
part pv.02 --size=1 --grow --ondisk=/dev/disk/by-path/pci-0000:00:12.0-ata-1
volgroup data pv.02
## ##
## Network configuration ## Network configuration
@ -62,9 +45,6 @@ network --hostname=kiosk.localdomain
## Ostree installation ## Ostree installation
## ##
# Use this line if creating an Edge Installer ISO that includes a local ostree commit
#ostreesetup --nogpg --osname=rhel --remote=edge --url=file:///run/install/repo/ostree/repo --ref=rhel/9/x86_64/edge
# Use this to fetch from a remote URL # Use this to fetch from a remote URL
ostreesetup --nogpg --osname=rhel --remote=edge --url=http://{{ ansible_default_ipv4.address }}/repo --ref=rhel/9/x86_64/edge-kiosk ostreesetup --nogpg --osname=rhel --remote=edge --url=http://{{ ansible_default_ipv4.address }}/repo --ref=rhel/9/x86_64/edge-kiosk

21
imagebuilder/kiosk.ks

@ -21,32 +21,15 @@ reboot
text text
## ##
## Storage configuration ## Storage configuration for only one disk
##
# Clear the target disk
zerombr
# Remove existing partitions
clearpart --all --initlabel
# Automatically create partitions required by hardware platform
# and add a separate /boot partition
reqpart --add-boot
##
## Alternative partitioning on only one disk
## /dev/disk/by-path/pci-0000:00:12.0-ata-1 instead of sda when sda is taken by the usb stick ## /dev/disk/by-path/pci-0000:00:12.0-ata-1 instead of sda when sda is taken by the usb stick
## ##
zerombr zerombr
clearpart --all --initlabel clearpart --all --initlabel
reqpart --add-boot reqpart --add-boot
part pv.01 --size=10240 --ondisk=/dev/disk/by-path/pci-0000:00:12.0-ata-1 part pv.01 --size=10240 --ondisk=/dev/disk/by-path/pci-0000:00:12.0-ata-1
volgroup system pv.01 volgroup rhel pv.01
logvol / --fstype="xfs" --size=1 --grow --name=root --vgname=system logvol / --fstype="xfs" --size=1 --grow --name=root --vgname=system
part pv.02 --size=1 --grow --ondisk=/dev/disk/by-path/pci-0000:00:12.0-ata-1
volgroup data pv.02
## ##
## Network configuration ## Network configuration

Loading…
Cancel
Save