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
44 changes: 44 additions & 0 deletions 03-setup_microshift.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
# Copyright Red Hat, Inc.
# All Rights Reserved.
#
# 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.

- name: Setup MicroShift
hosts: localhost
gather_facts: true
strategy: linear
pre_tasks:
- name: Load stack output vars from file
ansible.builtin.include_vars:
file: "{{ hotstack_work_dir | default(playbook_dir) }}/{{ stack_name }}-outputs.yaml"
name: stack_outputs

- name: Add controller-0 to the Ansible inventory
ansible.builtin.add_host: "{{ stack_outputs.controller_ansible_host }}"

- name: Add microshift-0 to the Ansible inventory
when: stack_outputs.microshift_ansible_host is defined
ansible.builtin.add_host: "{{ stack_outputs.microshift_ansible_host }}"

- name: Slurp the pull-secret file
register: slurp_pull_secret
ansible.builtin.slurp:
src: "{{ pull_secret_file }}"

roles:
- role: microshift_setup
delegate_to: controller-0
vars:
ocp_installer_type: "{{ stack_outputs.ocp_installer_type | default('agent') }}"
pull_secret: "{{ slurp_pull_secret.content }}"
3 changes: 3 additions & 0 deletions bootstrap.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
- name: Install Openshift Container Platform
ansible.builtin.import_playbook: 03-install_ocp.yml

- name: Setup MicroShift
ansible.builtin.import_playbook: 03-setup_microshift.yml

- name: Deploy RedFish Virtual BMC
ansible.builtin.import_playbook: 04-redfish_virtual_bmc.yml

Expand Down
9 changes: 0 additions & 9 deletions images/.gitignore

This file was deleted.

94 changes: 94 additions & 0 deletions scenarios/microshift/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# microshift Scenario

## Overview

A MicroShift-based scenario designed to run the OpenStack control plane on a
lightweight single-node Kubernetes cluster. This scenario uses a pre-built
MicroShift image (built with `images/dib/microshift-image.yaml`) instead of
a full Single Node OpenShift (SNO) installation.

## Architecture

### Component Details

- **Controller**: Hotstack controller providing DNS, load balancing (HAProxy),
and orchestration services
- **MicroShift**: Single-node MicroShift cluster running the OpenStack control
plane. Boots from a pre-built image with MicroShift packages installed;
runtime configuration (firewall, LVM, services) is applied via cloud-init.

## Features

- Pre-built MicroShift image for fast boot (no OCP agent-based installation)
- Complete OpenStack service stack (Nova, Neutron, Glance, Swift, Ironic, etc.)
- OpenStack Ironic bare metal provisioning service (no ironic nodes in the stack)
- TopoLVM for local storage management
- Cinder LVM-iSCSI backend
- Multi-network setup for OpenStack services including Ironic provisioning network
- Cloud-init based MicroShift runtime configuration

## Networks

- **machine-net**: 192.168.32.0/24 (MicroShift cluster network)
- **ctlplane-net**: 192.168.122.0/24 (OpenStack control plane)
- **internal-api-net**: 172.17.0.0/24 (OpenStack internal services)
- **storage-net**: 172.18.0.0/24 (Storage backend communication)
- **tenant-net**: 172.19.0.0/24 (Tenant network traffic)
- **ironic-net**: 172.20.1.0/24 (Bare metal provisioning network)

## OpenStack Services

### Core Services

- **Keystone**: Identity service with LoadBalancer on Internal API
- **Nova**: Compute service with Ironic driver for bare metal
- **Neutron**: Networking service with OVN backend
- **Glance**: Image service with Swift backend
- **Swift**: Object storage service
- **Placement**: Resource placement service
- **Cinder**: Block storage with LVM-iSCSI backend

### Bare Metal Services

- **Ironic**: Bare metal provisioning service
- **Ironic Inspector**: Hardware inspection service
- **Ironic Neutron Agent**: Network management for bare metal

## MicroShift Image

The MicroShift image is built using `images/dib/microshift-image.yaml` and
includes:

- CentOS 9 Stream base
- MicroShift packages (core, networking, TopoLVM, OLM)
- UEFI boot support

Upload the image to your cloud:

```bash
openstack image create hotstack-microshift \
--disk-format raw \
--file microshift.qcow2 \
--property hw_firmware_type=uefi \
--property hw_machine_type=q35
```

## Usage

```bash
# Deploy the scenario
ansible-playbook -i inventory.yml bootstrap.yml \
-e @scenarios/microshift/bootstrap_vars.yml \
-e @~/cloud-secrets.yaml
```

## Configuration Files

- `bootstrap_vars.yml`: Infrastructure and MicroShift configuration
- `automation-vars.yml`: Hotloop deployment stages
- `heat_template.yaml`: OpenStack infrastructure template
- `manifests/control-plane/control-plane.yaml.j2`: OpenStack service configuration
- `manifests/control-plane/networking/nncp.yaml.j2`: Node network configuration
- `manifests/control-plane/networking/nad.yaml`: Network attachment definitions
- `manifests/control-plane/networking/metallb.yaml`: MetalLB load balancer pools
- `manifests/control-plane/dnsmasq-dns-ironic.yaml`: DNS LoadBalancer on Ironic network
126 changes: 126 additions & 0 deletions scenarios/microshift/automation-vars.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
---
stages:

- name: Dependencies
stages: >-
{{
lookup("ansible.builtin.template",
"common/stages/deps-stages.yaml.j2")
}}

- name: Cinder LVM
stages: >-
{{
lookup("ansible.builtin.file",
"common/stages/cinder-lvm-label-stages.yaml")
}}

- name: OLM Openstack
stages: >-
{{
lookup("ansible.builtin.template",
"common/stages/olm-openstack-stages.yaml.j2")
}}

- name: NodeNetworkConfigurationPolicy (nncp)
documentation: |
Apply node network configuration policies to configure host networking.
Waits for all policies to be successfully configured.
j2_manifest: manifests/control-plane/networking/nncp.yaml.j2
wait_conditions:
- >-
oc wait -n openstack nncp -l osp/nncm-config-type=standard
--for jsonpath='{.status.conditions[0].reason}'=SuccessfullyConfigured
--timeout=180s

- name: NetworkAttchmentDefinition (NAD)
documentation: |
Create network attachment definitions for OpenStack services.
Defines additional network interfaces for pods.
manifest: manifests/control-plane/networking/nad.yaml

- name: MetalLB - L2Advertisement and IPAddressPool
documentation: |
Configure MetalLB load balancer with IP address pools and L2 advertisements.
Enables external access to OpenStack services.
manifest: manifests/control-plane/networking/metallb.yaml

- name: OpenstackControlPlane
documentation: |
Deploy the OpenStack control plane with all core services.
Waits for the control plane to be fully ready before proceeding.
j2_manifest: manifests/control-plane/control-plane.yaml.j2
wait_conditions:
- >-
oc -n openstack wait openstackcontrolplanes.core.openstack.org controlplane
--for condition=OpenStackControlPlaneDNSReadyCondition --timeout=600s

- name: Extra DNS LoadBalancer on Ironic network
documentation: |
Deploy additional DNS service on the Ironic network for bare metal provisioning.
Provides DNS resolution for ironic nodes during deployment and inspection.
manifest: manifests/control-plane/dnsmasq-dns-ironic.yaml
wait_conditions:
- >-
oc wait -n openstack service dnsmasq-dns-ironic
--for jsonpath='.status.loadBalancer' --timeout=60s

- name: Wait for OpenstackControlPlane
documentation: |
Wait for the OpenStack control plane to be fully ready and operational.
Ensures all services are running before proceeding with additional configurations.
wait_conditions:
- >-
oc wait -n openstack openstackcontrolplane controlplane
--for condition=Ready --timeout=30m

- name: Update openstack-operators OLM
stages: >-
{{
lookup('ansible.builtin.template',
'common/stages/openstack-olm-update.yaml.j2')
}}
run_conditions:
- >-
{{
openstack_operators_update is defined and
openstack_operators_update | bool
}}

- name: Wait for condition MinorUpdateAvailable True
documentation: |
Wait for OpenStack version to indicate a minor update is available.
Required before proceeding with version updates.
wait_conditions:
- >-
oc -n openstack wait openstackversions.core.openstack.org controlplane
--for=condition=MinorUpdateAvailable=True --timeout=10m
run_conditions:
- "{{ openstack_update is defined and openstack_update | bool }}"

- name: "Minor update :: Create OpenStackVersion patch"
documentation: |
This creates a patch file `{{ manifests_dir }}/patches/openstack_version_patch.yaml`
If `openstack_update_custom_images` is defined it will populate the customContainerImages
in the OpenstackVersion YAML patch.
shell: >-
{{
lookup('ansible.builtin.template',
'common/scripts/create_openstack_version_patch.sh.j2')
}}
run_conditions:
- "{{ openstack_update is defined and openstack_update | bool }}"

- name: "Minor update :: Update the target version in the OpenStackVersion custom resource (CR)"
documentation: |
The `hotstack-openstack-version-patch` script will get the `availableVersion`
and us it to replace the string `__TARGET_VERSION__` in the patch file and
apply the patch using `oc patch` command.
command: >-
hotstack-openstack-version-patch --namespace openstack --name controlplane
--file {{ manifests_dir }}/patches/openstack_version_patch.yaml
wait_conditions:
- oc -n openstack wait openstackversions.core.openstack.org controlplane
--for=condition=Ready --timeout=10m
run_conditions:
- "{{ openstack_update is defined and openstack_update | bool }}"
50 changes: 50 additions & 0 deletions scenarios/microshift/bootstrap_vars.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
os_cloud: default
os_floating_network: public
os_router_external_network: public

scenario: microshift
scenario_dir: scenarios
stack_template_path: "{{ scenario_dir }}/{{ scenario }}/heat_template.yaml"
automation_vars_file: "{{ scenario_dir }}/{{ scenario }}/automation-vars.yml"

openstack_operators_image: quay.io/openstack-k8s-operators/openstack-operator-index:latest
openstack_operator_channel: alpha
openstack_operator_starting_csv: null

ntp_servers: []
dns_servers:
- 172.31.0.129

pull_secret_file: ~/pull-secret.txt

ovn_k8s_gateway_config_host_routing: true
enable_iscsi: true
enable_multipath: true

cinder_volume_pvs:
- /dev/vdc
- /dev/vdd
- /dev/vde

# Nova console recorder NFS settings
nova_console_recorder_nfs_server: controller-0.openstack.lab
nova_console_recorder_nfs_path: /export/nova-console-recordings

stack_name: "hs-{{ scenario }}-{{ zuul.build[:8] | default('no-zuul') }}"
stack_parameters:
# On misconfigured clouds, uncomment these to avoid issues.
# Ref: https://access.redhat.com/solutions/7059376
# net_value_specs:
# mtu: 1442
dns_servers: "{{ dns_servers }}"
ntp_servers: "{{ ntp_servers }}"
controller_ssh_pub_key: "{{ controller_ssh_pub_key | default('') }}"
router_external_network: "{{ os_router_external_network | default('public') }}"
floating_ip_network: "{{ os_floating_network | default('public') }}"
controller_params:
image: hotstack-controller
flavor: hotstack.small
microshift_params:
image: hotstack-microshift
flavor: hotstack.xlarge
3 changes: 3 additions & 0 deletions scenarios/microshift/files/microshift-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
dns:
baseDomain: shift.openstack.lab
14 changes: 14 additions & 0 deletions scenarios/microshift/files/topolvm-configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
apiVersion: v1
kind: ConfigMap
metadata:
name: topolvm-lvmd-0
namespace: topolvm-system
data:
lvmd.yaml: |
socket-name: /run/topolvm/lvmd.sock
device-classes:
- name: default
volume-group: microshift
spare-gb: 0
default: true
6 changes: 6 additions & 0 deletions scenarios/microshift/files/topolvm-kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- configmap.yaml
- storageclass.yaml
10 changes: 10 additions & 0 deletions scenarios/microshift/files/topolvm-storageclass.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: lvms-local-storage
provisioner: topolvm.io
parameters:
topolvm.io/device-class: default
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
Loading