Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions roles/cnv_instances/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
# If your workload needs customization options provide variables to be used.
#
# Variable names must be prefixed by the role name, e.g. "<role name>_<variable>".
#
# Therefore because this example workload is called "ns_example" the variables
# must be named "ns_example_variable".
#
# You can override the defaults as parameters to the Ansible run that deploys
# your workload via the AgnosticV configuration.

cnv_instances: []

instances: "{{ cnv_instances }}"

openshift_cnv_namespace: "{{ sandbox_openshift_namespace }}"

# Naming of instances
openshift_cnv_instance_numeration: '%d'

# Delete device retry
openshift_cnv_delete_retries: 20
openshift_cnv_delete_delay: 60

# Retries and delay variable
openshift_cnv_retries: 6
openshift_cnv_delay: 10

# Remove X-Frame-Options header (to iframe apps, for example in showroom)
openshift_cnv_route_remove_x_frame_options_header: false

# Use host.guid.domain
openshift_cnv_legacy_routes: false
13 changes: 13 additions & 0 deletions roles/cnv_instances/meta/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
galaxy_info:
role_name: cnv_instances
author: Red Hat, Alberto Gonzalez (josegonz@redhat.com)
description: |
Example workload to be deployed onto OpenShift 4
license: MIT
min_ansible_version: "2.9"
platforms: []
galaxy_tags:
- ocp
- openshift
dependencies: []
37 changes: 37 additions & 0 deletions roles/cnv_instances/readme.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
= cnv_instances - Create instances on CNV cluster

== Role overview

* This is a working no-op role that can be used as a template to develop new workload roles to deploy to a cnv instances config. It consists of the following tasks files:

** Tasks: link:./tasks/workload.yml[workload.yml] - Used to deploy the actual workload, i.e, 3scale, some Demo or OpenShift customization
*** This role only prints the current username for which this role is provisioning.

** Tasks: link:./tasks/remove_workload.yml[remove_workload.yml] - Used to delete the workload
*** This role doesn't do anything here

The provisioning infrastructure will set a variable `ACTION` to be either `provision` or `destroy` depending on the operation.

== The defaults variable file

=== Variable Naming

Since Ansible lacks robust variable scoping you *must* use long-name scope parameters for your workload to avoid variable clashing.

For example, parameters named `ns_example_*` would be recognized as unique to this workload.

* This file link:./defaults/main.yml[./defaults/main.yml] contains all the variables you need to define to control the deployment of your workload.
* The variable *ocp_username* is mandatory to assign the workload to the correct OpenShift user when deploying to a shared cluster. For most workloads the default of `system:admin` is the correct value unless this is a workload to be applied to a shared cluster.
* You can modify any of these default values by adding `-e "variable_name=variable_value"` to the command line
* Your deployer will override any of these variables based on configuration in AgnosticV
* Add long-name scoped workload parameters. Example: `ns_example_machineconfigpool_name: worker`

== The internal variable file

If the workload needs to set some internal variables define them in the file link:./vars/main.yml[./vars/main.yml].

Variables should be named just like external variables with the exception that they should start with an underscore (`_`).

Examples:

* `cnv_instances`
229 changes: 229 additions & 0 deletions roles/cnv_instances/tasks/create_instance.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
---
- name: Empty variable _instance_
ansible.builtin.set_fact:
_instance_interfaces: []
_instance_networks: []
_instance_volumes:
- dataVolume:
name: "INSTANCENAME-{{guid}}"
name: "INSTANCENAME-{{guid}}"
_instance_disks:
- disk:
bus: "{{ _instance.disk_type | default('virtio') }}"
name: "INSTANCENAME-{{guid}}"

- name: Set the instances interfaces
ansible.builtin.set_fact:
_instance_interfaces: >-
{{
_instance_interfaces + [{
'name': _network.split('/')[1] if '/' in _network else _network + guid,
'macAddress': _instance.fixed_macs[_network] | default('2c:c2:60' | random_mac),
'bridge': {},
'model': _instance.interface_model | default('virtio'),
}
if _network != 'default'
else {
'name': 'default',
'model': _instance.interface_model | default('virtio'),
'masquerade': {}
}]
}}
_instance_networks: >-
{{ _instance_networks + [
{
'name': _network.split('/')[1] if '/' in _network else _network + guid,
'multus': {'networkName': _network if '/' in _network else _network + guid}
}
if _network != 'default'
else {
'name': 'default',
'pod': {}
}
] }}
loop: "{{ _instance.networks | default(['default']) | list }}"
loop_control:
loop_var: _network
index_var: _network_idx

- name: Set the instances disks
ansible.builtin.set_fact:
_instance_disks: "{{ _instance_disks | from_yaml + [
{
'name': _disk.metadata.name,
'disk': {'bus': _instance.disk_type | default('virtio')}
}
] }}"
_instance_volumes: "{{ _instance_volumes | from_yaml + [
{
'name': _disk.metadata.name,
'dataVolume': {'name': _disk.metadata.name}
}
] }}"
loop: "{{ _instance.disks | default([]) | list }}"
loop_control:
loop_var: _disk

- name: Set the instances cdroms
ansible.builtin.set_fact:
_instance_disks: "{{ _instance_disks | from_yaml + [
{
'name': _disk.metadata.name,
'cdrom': {'bus': 'sata'}
}
] }}"
_instance_volumes: "{{ _instance_volumes | from_yaml + [
{
'name': _disk.metadata.name,
'dataVolume': {'name': _disk.metadata.name}
}
] }}"
loop: "{{ _instance.cdroms | default([]) | list }}"
loop_control:
loop_var: _disk


- name: Set cloud_config
ansible.builtin.set_fact:
_cloud_config: |-
#cloud-config
ssh_authorized_keys:
{{ _instance.userdata | default('') | replace('#cloud-config','') | replace('INSTANCEGUID', guid) | default('') }}

- name: Set cloud init disk if needed
when: _instance.disable_cloud_init | default(false) == false
set_fact:
_instance_volumes: "{{ _instance_volumes | from_yaml + [
{
'name': 'cloudinitdisk',
'cloudInitNoCloud': {
'userDataBase64': _cloud_config | b64encode,
'networkDataBase64': _instance.networkdata | default('network: 2') | b64encode
}
}
] }}"
_instance_disks: "{{ _instance_disks | from_yaml + [
{
'disk': {'bus': 'virtio'},
'name': 'cloudinitdisk'
}
] }}"

- name: Fail if image (pvc) doesn't exist on namespace cnv-images
when: _instance.image_type | default('pvc') == 'pvc'
kubernetes.core.k8s_info:
api_version: v1
kind: PersistentVolumeClaim
name: "{{ _instance.image }}"
namespace: cnv-images
register: r_pvc_info

- name: Fail if PVC does not exist
ansible.builtin.fail:
msg: "PersistentVolumeClaim {{ _instance.image }} does not exist in namespace cnv-images"
when:
- _instance.image_type | default('pvc') == 'pvc'
- r_pvc_info.resources | default([]) | length == 0


- name: Create instance(s) "{{ _instance.name }}"
vars:
_instance_name: "{{ _instance.name }}{{ _index+1 if _instance.count|d(1)|int > 1 }}"
_datavolume: |
- metadata:
name: "{{ _instance_name }}-{{ guid }}"
spec:
source:
{% if _instance.image_type | default('pvc') == 'pvc' %}
pvc:
namespace: "cnv-images"
name: "{{ _instance.image }}"
{% elif _instance.image_type | default('pvc') == 'registry' %}
registry:
url: "{{ _instance.image }}"
{% elif _instance.image_type | default('pvc') in ['url','http'] %}
http:
url: "{{ _instance.image }}"
{% elif _instance.image_type | default('pvc') == 'blank' %}
blank: {}
{% endif %}
pvc:
accessModes:
- ReadWriteMany
volumeMode: Block
resources:
requests:
storage: "{{ _instance.image_size }}"
_spec: |
hostname: "{{ _instance_name }}"
subdomain: "{{ 'lab' if openshift_cnv_add_lab_subdomain | default(True) else '' }}"
domain:
firmware:
uuid: "{{ 99999999 | random | to_uuid }}"
bootloader:
{% if _instance.bootloader | default('bios') == 'bios' %}
bios: {}
{% elif _instance.bootloader | default('bios') in ['efi', 'uefi'] %}
efi:
secureBoot: false
{% endif %}
cpu:
cores: {{ _instance.cores }}
model: host-passthrough
machine:
type: "{{ _instance.machine_type | default('pc-q35-rhel9.2.0') }}"
memory:
guest: "{{ _instance.memory }}"
memory:
hugepages:
pageSize: "1Gi"
devices:
disks: {{ _instance_disks | replace('INSTANCENAME', _instance_name) }}
interfaces: {{ _instance_interfaces }}
networks: {{ _instance_networks }}
volumes: {{ _instance_volumes | replace('INSTANCENAME', _instance_name) }}
kubernetes.core.k8s:
definition:
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: "{{ _instance_name }}"
namespace: "{{ openshift_cnv_namespace }}"
annotations: >-
{{ _instance.metadata|default({}) | combine(_instance.tags|default({})) | default({}) }}
spec:
dataVolumeTemplates: >-
{{ _datavolume | from_yaml + (_instance.disks | default([]) | to_json | replace('INSTANCENAME',_instance_name) | from_json) + (_instance.cdroms | default([]) | to_json | replace('INSTANCENAME',_instance_name) | from_json) }}
running: true
template:
metadata:
labels:
vm.cnv.io/name: "{{ _instance_name }}"
spec: "{{ _spec | from_yaml }}"
loop: "{{ range(1, _instance.count|default(1)|int+1) | list }}"
loop_control:
index_var: _index
register: r_openshift_cnv_instance
until: r_openshift_cnv_instance is success
retries: "{{ openshift_cnv_retries }}"
delay: "{{ openshift_cnv_delay }}"

- name: Wait till VM is running
vars:
_instance_name: "{{ _instance.name }}{{ _index+1 if _instance.count | default(1) | int > 1 }}"
kubernetes.core.k8s_info:
api_version: kubevirt.io/v1
kind: VirtualMachine
name: "{{ _instance_name }}"
namespace: "{{ openshift_cnv_namespace }}"
register: r_vm_status
until: r_vm_status.resources[0].status.printableStatus | default('') == "Running"
retries: 30
delay: 10
loop: "{{ range(1, _instance.count | default(1) | int+1) | list }}"
loop_control:
index_var: _index

- ansible.builtin.set_fact:
r_openshift_cnv_instances: "{{ r_openshift_cnv_instances + [item] }}"
loop: "{{ r_openshift_cnv_instance.results | list }}"
Loading