Skip to content

Commit 5c32f5b

Browse files
committed
WIP - Add MicroShift support
Introduces disk image building elements, Ansible roles, Heat templates, and bootstrap/setup playbooks for deploying MicroShift as an alternative to OCP. Assisted-By: Claude (claude-4.5-sonnet) Signed-off-by: Harald Jensås <hjensas@redhat.com>
1 parent d6b1e4b commit 5c32f5b

16 files changed

Lines changed: 1849 additions & 9 deletions

03-setup_microshift.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
---
2+
# Copyright Red Hat, Inc.
3+
# All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
6+
# not use this file except in compliance with the License. You may obtain
7+
# a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
# License for the specific language governing permissions and limitations
15+
# under the License.
16+
17+
- name: Setup MicroShift
18+
hosts: localhost
19+
gather_facts: true
20+
strategy: linear
21+
pre_tasks:
22+
- name: Load stack output vars from file
23+
ansible.builtin.include_vars:
24+
file: "{{ hotstack_work_dir | default(playbook_dir) }}/{{ stack_name }}-outputs.yaml"
25+
name: stack_outputs
26+
27+
- name: Add controller-0 to the Ansible inventory
28+
ansible.builtin.add_host: "{{ stack_outputs.controller_ansible_host }}"
29+
30+
- name: Add microshift-0 to the Ansible inventory
31+
when: stack_outputs.microshift_ansible_host is defined
32+
ansible.builtin.add_host: "{{ stack_outputs.microshift_ansible_host }}"
33+
34+
- name: Slurp the pull-secret file
35+
register: slurp_pull_secret
36+
ansible.builtin.slurp:
37+
src: "{{ pull_secret_file }}"
38+
39+
roles:
40+
- role: microshift_setup
41+
delegate_to: controller-0
42+
vars:
43+
ocp_installer_type: "{{ stack_outputs.ocp_installer_type | default('agent') }}"
44+
pull_secret: "{{ slurp_pull_secret.content }}"

bootstrap.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
- name: Install Openshift Container Platform
2424
ansible.builtin.import_playbook: 03-install_ocp.yml
2525

26+
- name: Setup MicroShift
27+
ansible.builtin.import_playbook: 03-setup_microshift.yml
28+
2629
- name: Deploy RedFish Virtual BMC
2730
ansible.builtin.import_playbook: 04-redfish_virtual_bmc.yml
2831

images/.gitignore

Lines changed: 0 additions & 9 deletions
This file was deleted.

scenarios/microshift/README.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# microshift Scenario
2+
3+
## Overview
4+
5+
A MicroShift-based scenario designed to run the OpenStack control plane on a
6+
lightweight single-node Kubernetes cluster. This scenario uses a pre-built
7+
MicroShift image (built with `images/dib/microshift-image.yaml`) instead of
8+
a full Single Node OpenShift (SNO) installation.
9+
10+
## Architecture
11+
12+
### Component Details
13+
14+
- **Controller**: Hotstack controller providing DNS, load balancing (HAProxy),
15+
and orchestration services
16+
- **MicroShift**: Single-node MicroShift cluster running the OpenStack control
17+
plane. Boots from a pre-built image with MicroShift packages installed;
18+
runtime configuration (firewall, LVM, services) is applied via cloud-init.
19+
20+
## Features
21+
22+
- Pre-built MicroShift image for fast boot (no OCP agent-based installation)
23+
- Complete OpenStack service stack (Nova, Neutron, Glance, Swift, Ironic, etc.)
24+
- OpenStack Ironic bare metal provisioning service (no ironic nodes in the stack)
25+
- TopoLVM for local storage management
26+
- Cinder LVM-iSCSI backend
27+
- Multi-network setup for OpenStack services including Ironic provisioning network
28+
- Cloud-init based MicroShift runtime configuration
29+
30+
## Networks
31+
32+
- **machine-net**: 192.168.32.0/24 (MicroShift cluster network)
33+
- **ctlplane-net**: 192.168.122.0/24 (OpenStack control plane)
34+
- **internal-api-net**: 172.17.0.0/24 (OpenStack internal services)
35+
- **storage-net**: 172.18.0.0/24 (Storage backend communication)
36+
- **tenant-net**: 172.19.0.0/24 (Tenant network traffic)
37+
- **ironic-net**: 172.20.1.0/24 (Bare metal provisioning network)
38+
39+
## OpenStack Services
40+
41+
### Core Services
42+
43+
- **Keystone**: Identity service with LoadBalancer on Internal API
44+
- **Nova**: Compute service with Ironic driver for bare metal
45+
- **Neutron**: Networking service with OVN backend
46+
- **Glance**: Image service with Swift backend
47+
- **Swift**: Object storage service
48+
- **Placement**: Resource placement service
49+
- **Cinder**: Block storage with LVM-iSCSI backend
50+
51+
### Bare Metal Services
52+
53+
- **Ironic**: Bare metal provisioning service
54+
- **Ironic Inspector**: Hardware inspection service
55+
- **Ironic Neutron Agent**: Network management for bare metal
56+
57+
## MicroShift Image
58+
59+
The MicroShift image is built using `images/dib/microshift-image.yaml` and
60+
includes:
61+
62+
- CentOS 9 Stream base
63+
- MicroShift packages (core, networking, TopoLVM, OLM)
64+
- UEFI boot support
65+
66+
Upload the image to your cloud:
67+
68+
```bash
69+
openstack image create hotstack-microshift \
70+
--disk-format raw \
71+
--file microshift.qcow2 \
72+
--property hw_firmware_type=uefi \
73+
--property hw_machine_type=q35
74+
```
75+
76+
## Usage
77+
78+
```bash
79+
# Deploy the scenario
80+
ansible-playbook -i inventory.yml bootstrap.yml \
81+
-e @scenarios/microshift/bootstrap_vars.yml \
82+
-e @~/cloud-secrets.yaml
83+
```
84+
85+
## Configuration Files
86+
87+
- `bootstrap_vars.yml`: Infrastructure and MicroShift configuration
88+
- `automation-vars.yml`: Hotloop deployment stages
89+
- `heat_template.yaml`: OpenStack infrastructure template
90+
- `manifests/control-plane/control-plane.yaml.j2`: OpenStack service configuration
91+
- `manifests/control-plane/networking/nncp.yaml.j2`: Node network configuration
92+
- `manifests/control-plane/networking/nad.yaml`: Network attachment definitions
93+
- `manifests/control-plane/networking/metallb.yaml`: MetalLB load balancer pools
94+
- `manifests/control-plane/dnsmasq-dns-ironic.yaml`: DNS LoadBalancer on Ironic network
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
---
2+
stages:
3+
4+
- name: Dependencies
5+
stages: >-
6+
{{
7+
lookup("ansible.builtin.template",
8+
"common/stages/deps-stages.yaml.j2")
9+
}}
10+
11+
- name: Cinder LVM
12+
stages: >-
13+
{{
14+
lookup("ansible.builtin.file",
15+
"common/stages/cinder-lvm-label-stages.yaml")
16+
}}
17+
18+
- name: OLM Openstack
19+
stages: >-
20+
{{
21+
lookup("ansible.builtin.template",
22+
"common/stages/olm-openstack-stages.yaml.j2")
23+
}}
24+
25+
- name: NodeNetworkConfigurationPolicy (nncp)
26+
documentation: |
27+
Apply node network configuration policies to configure host networking.
28+
Waits for all policies to be successfully configured.
29+
j2_manifest: manifests/control-plane/networking/nncp.yaml.j2
30+
wait_conditions:
31+
- >-
32+
oc wait -n openstack nncp -l osp/nncm-config-type=standard
33+
--for jsonpath='{.status.conditions[0].reason}'=SuccessfullyConfigured
34+
--timeout=180s
35+
36+
- name: NetworkAttchmentDefinition (NAD)
37+
documentation: |
38+
Create network attachment definitions for OpenStack services.
39+
Defines additional network interfaces for pods.
40+
manifest: manifests/control-plane/networking/nad.yaml
41+
42+
- name: MetalLB - L2Advertisement and IPAddressPool
43+
documentation: |
44+
Configure MetalLB load balancer with IP address pools and L2 advertisements.
45+
Enables external access to OpenStack services.
46+
manifest: manifests/control-plane/networking/metallb.yaml
47+
48+
- name: OpenstackControlPlane
49+
documentation: |
50+
Deploy the OpenStack control plane with all core services.
51+
Waits for the control plane to be fully ready before proceeding.
52+
j2_manifest: manifests/control-plane/control-plane.yaml.j2
53+
wait_conditions:
54+
- >-
55+
oc -n openstack wait openstackcontrolplanes.core.openstack.org controlplane
56+
--for condition=OpenStackControlPlaneDNSReadyCondition --timeout=600s
57+
58+
- name: Extra DNS LoadBalancer on Ironic network
59+
documentation: |
60+
Deploy additional DNS service on the Ironic network for bare metal provisioning.
61+
Provides DNS resolution for ironic nodes during deployment and inspection.
62+
manifest: manifests/control-plane/dnsmasq-dns-ironic.yaml
63+
wait_conditions:
64+
- >-
65+
oc wait -n openstack service dnsmasq-dns-ironic
66+
--for jsonpath='.status.loadBalancer' --timeout=60s
67+
68+
- name: Wait for OpenstackControlPlane
69+
documentation: |
70+
Wait for the OpenStack control plane to be fully ready and operational.
71+
Ensures all services are running before proceeding with additional configurations.
72+
wait_conditions:
73+
- >-
74+
oc wait -n openstack openstackcontrolplane controlplane
75+
--for condition=Ready --timeout=30m
76+
77+
- name: Update openstack-operators OLM
78+
stages: >-
79+
{{
80+
lookup('ansible.builtin.template',
81+
'common/stages/openstack-olm-update.yaml.j2')
82+
}}
83+
run_conditions:
84+
- >-
85+
{{
86+
openstack_operators_update is defined and
87+
openstack_operators_update | bool
88+
}}
89+
90+
- name: Wait for condition MinorUpdateAvailable True
91+
documentation: |
92+
Wait for OpenStack version to indicate a minor update is available.
93+
Required before proceeding with version updates.
94+
wait_conditions:
95+
- >-
96+
oc -n openstack wait openstackversions.core.openstack.org controlplane
97+
--for=condition=MinorUpdateAvailable=True --timeout=10m
98+
run_conditions:
99+
- "{{ openstack_update is defined and openstack_update | bool }}"
100+
101+
- name: "Minor update :: Create OpenStackVersion patch"
102+
documentation: |
103+
This creates a patch file `{{ manifests_dir }}/patches/openstack_version_patch.yaml`
104+
If `openstack_update_custom_images` is defined it will populate the customContainerImages
105+
in the OpenstackVersion YAML patch.
106+
shell: >-
107+
{{
108+
lookup('ansible.builtin.template',
109+
'common/scripts/create_openstack_version_patch.sh.j2')
110+
}}
111+
run_conditions:
112+
- "{{ openstack_update is defined and openstack_update | bool }}"
113+
114+
- name: "Minor update :: Update the target version in the OpenStackVersion custom resource (CR)"
115+
documentation: |
116+
The `hotstack-openstack-version-patch` script will get the `availableVersion`
117+
and us it to replace the string `__TARGET_VERSION__` in the patch file and
118+
apply the patch using `oc patch` command.
119+
command: >-
120+
hotstack-openstack-version-patch --namespace openstack --name controlplane
121+
--file {{ manifests_dir }}/patches/openstack_version_patch.yaml
122+
wait_conditions:
123+
- oc -n openstack wait openstackversions.core.openstack.org controlplane
124+
--for=condition=Ready --timeout=10m
125+
run_conditions:
126+
- "{{ openstack_update is defined and openstack_update | bool }}"
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
---
2+
os_cloud: default
3+
os_floating_network: public
4+
os_router_external_network: public
5+
6+
scenario: microshift
7+
scenario_dir: scenarios
8+
stack_template_path: "{{ scenario_dir }}/{{ scenario }}/heat_template.yaml"
9+
automation_vars_file: "{{ scenario_dir }}/{{ scenario }}/automation-vars.yml"
10+
11+
openstack_operators_image: quay.io/openstack-k8s-operators/openstack-operator-index:latest
12+
openstack_operator_channel: alpha
13+
openstack_operator_starting_csv: null
14+
15+
ntp_servers: []
16+
dns_servers:
17+
- 172.31.0.129
18+
19+
pull_secret_file: ~/pull-secret.txt
20+
21+
ovn_k8s_gateway_config_host_routing: true
22+
enable_iscsi: true
23+
enable_multipath: true
24+
25+
cinder_volume_pvs:
26+
- /dev/vdc
27+
- /dev/vdd
28+
- /dev/vde
29+
30+
# Nova console recorder NFS settings
31+
nova_console_recorder_nfs_server: controller-0.openstack.lab
32+
nova_console_recorder_nfs_path: /export/nova-console-recordings
33+
34+
stack_name: "hs-{{ scenario }}-{{ zuul.build[:8] | default('no-zuul') }}"
35+
stack_parameters:
36+
# On misconfigured clouds, uncomment these to avoid issues.
37+
# Ref: https://access.redhat.com/solutions/7059376
38+
# net_value_specs:
39+
# mtu: 1442
40+
dns_servers: "{{ dns_servers }}"
41+
ntp_servers: "{{ ntp_servers }}"
42+
controller_ssh_pub_key: "{{ controller_ssh_pub_key | default('') }}"
43+
router_external_network: "{{ os_router_external_network | default('public') }}"
44+
floating_ip_network: "{{ os_floating_network | default('public') }}"
45+
controller_params:
46+
image: hotstack-controller
47+
flavor: hotstack.small
48+
microshift_params:
49+
image: hotstack-microshift
50+
flavor: hotstack.xlarge
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
---
2+
dns:
3+
baseDomain: shift.openstack.lab
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
apiVersion: v1
3+
kind: ConfigMap
4+
metadata:
5+
name: topolvm-lvmd-0
6+
namespace: topolvm-system
7+
data:
8+
lvmd.yaml: |
9+
socket-name: /run/topolvm/lvmd.sock
10+
device-classes:
11+
- name: default
12+
volume-group: microshift
13+
spare-gb: 0
14+
default: true
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
apiVersion: kustomize.config.k8s.io/v1beta1
3+
kind: Kustomization
4+
resources:
5+
- configmap.yaml
6+
- storageclass.yaml
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
apiVersion: storage.k8s.io/v1
3+
kind: StorageClass
4+
metadata:
5+
name: lvms-local-storage
6+
provisioner: topolvm.io
7+
parameters:
8+
topolvm.io/device-class: default
9+
volumeBindingMode: WaitForFirstConsumer
10+
allowVolumeExpansion: true

0 commit comments

Comments
 (0)