|
| 1 | +# bm_sno |
| 2 | + |
| 3 | +Agent-based bare metal OCP SNO deployment via iDRAC Redfish APIs. |
| 4 | + |
| 5 | +This role is included by the `reproducer` role when |
| 6 | +`cifmw_bm_sno: true`. It performs an agent-based installation on a |
| 7 | +physical bare metal host managed via iDRAC Redfish APIs. The workflow generates |
| 8 | +a self-contained agent ISO on the Zuul controller, pushes it to the target |
| 9 | +host's iDRAC via Redfish VirtualMedia, and waits for the host to self-install. |
| 10 | + |
| 11 | +## Privilege escalation |
| 12 | + |
| 13 | +Bare metal deployment requires privilege escalation for `/etc/hosts` |
| 14 | +management and running the ISO HTTP server via podman. |
| 15 | + |
| 16 | +## Exposed tags |
| 17 | + |
| 18 | +* `bm_ocp_layout`: Agent-based bare metal OCP layout tasks. |
| 19 | + |
| 20 | +## Network architecture |
| 21 | + |
| 22 | +Three routed isolated networks (no shared L2 domain required): |
| 23 | + |
| 24 | +| Network | Purpose | |
| 25 | +| --- | --- | |
| 26 | +| BMC management | iDRAC interfaces; controller reaches iDRAC via routing | |
| 27 | +| BMO provision | Node's 1st NIC, OS interface IP; VirtualMedia boot | |
| 28 | +| Controller | Zuul controller; serves the agent ISO to iDRAC | |
| 29 | + |
| 30 | +A 2nd NIC on the node carries isolated MetalLB networks for RHOSO EDPM |
| 31 | +services (ctlplane, internalapi, storage, tenant) via VLANs. |
| 32 | + |
| 33 | +The `api` and `*.apps` DNS names resolve directly to the node's BMO |
| 34 | +provision IP via `/etc/hosts` entries managed by the role. |
| 35 | + |
| 36 | +## Parameters |
| 37 | + |
| 38 | +### Required (typically set in the scenario's vars.yaml) |
| 39 | + |
| 40 | +| Parameter | Type | Description | |
| 41 | +| --- | --- | --- | |
| 42 | +| `cifmw_bm_agent_cluster_name` | str | OpenShift cluster name | |
| 43 | +| `cifmw_bm_agent_base_domain` | str | Base domain for the cluster | |
| 44 | +| `cifmw_bm_agent_machine_network` | str | BMO provision network CIDR | |
| 45 | +| `cifmw_bm_agent_node_ip` | str | Node IP on the BMO provision network | |
| 46 | +| `cifmw_bm_agent_node_iface` | str | RHCOS interface name on the BMO provision network | |
| 47 | +| `cifmw_bm_agent_bmc_host` | str | iDRAC hostname or IP on the BMC management network | |
| 48 | +| `cifmw_bm_nodes` | list | Single-element list with `mac` and `root_device` keys | |
| 49 | +| `cifmw_bm_agent_openshift_version` | str | OCP version (e.g. `"4.18.3"`); or set `cifmw_bm_agent_release_image` instead | |
| 50 | + |
| 51 | +### Optional (have defaults or are auto-discovered) |
| 52 | + |
| 53 | +| Parameter | Type | Default | Description | |
| 54 | +| --- | --- | --- | --- | |
| 55 | +| `cifmw_bm_agent_release_image` | str | `$OPENSHIFT_RELEASE_IMAGE` | Alternative to version: extract `openshift-install` from a release image | |
| 56 | +| `cifmw_bm_agent_iso_http_port` | int | `80` | Port for the podman HTTP server that serves the agent ISO (only a privileged port may accept external traffic on Zuul controllers) | |
| 57 | +| `cifmw_bm_agent_installer_timeout` | int | `7200` | Total seconds before the installer times out (split between bootstrap and install phases) | |
| 58 | +| `cifmw_manage_secrets_pullsecret_file` | str | `~/pull-secret` | Path to the pull secret JSON file | |
| 59 | +| `cifmw_bmc_credentials_file` | str | `~/secrets/idrac_access.yaml` | Path to a YAML file with `username` and `password` keys for iDRAC | |
| 60 | +| `cifmw_bm_agent_enable_usb_boot` | bool | `false` | Allow the role to automatically enable `GenericUsbBoot` in BIOS (requires a power cycle) | |
| 61 | +| `cifmw_bm_agent_vmedia_uefi_path` | str | auto-discovered | UEFI device path for the Virtual Optical Drive; auto-discovered from UEFI boot options if omitted | |
| 62 | +| `cifmw_bm_agent_core_password` | str | — | Set a `core` user password post-install via MachineConfig | |
| 63 | +| `cifmw_bm_agent_live_debug` | bool | `false` | Patch the agent ISO with password, autologin, and systemd debug shell on `tty6` for discovery-phase console access (requires `cifmw_bm_agent_core_password`) | |
| 64 | + |
| 65 | +## Secrets management |
| 66 | + |
| 67 | +The bare metal path requires two secret files: |
| 68 | + |
| 69 | +### BMC credentials |
| 70 | + |
| 71 | +A YAML file at `cifmw_bmc_credentials_file` (default `~/secrets/idrac_access.yaml`) |
| 72 | +with the following structure: |
| 73 | + |
| 74 | +```yaml |
| 75 | +username: root |
| 76 | +password: <idrac-password> |
| 77 | +``` |
| 78 | +
|
| 79 | +### Pull secret |
| 80 | +
|
| 81 | +The OCP pull secret JSON at `cifmw_manage_secrets_pullsecret_file` |
| 82 | +(default `~/pull-secret`). |
| 83 | + |
| 84 | +## Task files |
| 85 | + |
| 86 | +The agent-based deployment is composed of reusable task files under |
| 87 | +`tasks/`: |
| 88 | + |
| 89 | +| Task file | Description | |
| 90 | +| --- | --- | |
| 91 | +| `main.yml` | Main orchestrator: validates variables, generates ISO, serves it via HTTP, manages VirtualMedia, waits for install completion | |
| 92 | +| `bm_power_on.yml` | Idempotent power-on via Redfish with POST wait (retries 30x at 10s intervals) | |
| 93 | +| `bm_power_off.yml` | Idempotent force power-off via Redfish with confirmation wait | |
| 94 | +| `bm_check_usb_boot.yml` | Reads `GenericUsbBoot` BIOS attribute and fails if disabled | |
| 95 | +| `bm_ensure_usb_boot.yml` | Wraps `bm_check_usb_boot.yml`; if disabled and `cifmw_bm_agent_enable_usb_boot` is true, sets the BIOS attribute, creates a config job, and power-cycles to apply | |
| 96 | +| `bm_eject_vmedia.yml` | Ejects VirtualMedia from the iDRAC Virtual Optical Drive | |
| 97 | +| `bm_discover_vmedia_target.yml` | Discovers or validates the UEFI device path for VirtualMedia, clears pending iDRAC config jobs, and sets a one-time boot override | |
| 98 | +| `bm_patch_agent_iso.yml` | Patches the agent ISO ignition with core password, autologin, and debug shell (used when `cifmw_bm_agent_live_debug` is true) | |
| 99 | +| `bm_core_password_machineconfig.yml` | Generates a MachineConfig manifest to set the core user password hash post-install | |
| 100 | + |
| 101 | +## openshift-install acquisition |
| 102 | + |
| 103 | +The `openshift-install` binary is obtained automatically via one of two |
| 104 | +methods, depending on which variable is set: |
| 105 | + |
| 106 | +* **By version** (`cifmw_bm_agent_openshift_version`): downloads the tarball |
| 107 | + from `https://mirror.openshift.com/pub/openshift-v4/clients/ocp/<version>/openshift-install-linux.tar.gz` |
| 108 | + and extracts it. |
| 109 | +* **By release image** (`cifmw_bm_agent_release_image` or |
| 110 | + `OPENSHIFT_RELEASE_IMAGE` env var): runs |
| 111 | + `oc adm release extract --command=openshift-install` against the image. |
| 112 | + |
| 113 | +If the binary already exists in the working directory it is reused. |
| 114 | + |
| 115 | +## Deployment workflow |
| 116 | + |
| 117 | +1. Validate required variables |
| 118 | +2. Ensure `GenericUsbBoot` is enabled in BIOS (auto-enable with power cycle if allowed) |
| 119 | +3. Power off the host |
| 120 | +4. Generate SSH keys, template `install-config.yaml` and `agent-config.yaml` |
| 121 | +5. Acquire `openshift-install` binary (see above) and run `openshift-install agent create image` to build the agent ISO |
| 122 | +6. Optionally patch the ISO for discovery-phase console access |
| 123 | +7. Serve the ISO via a root podman httpd container (rootless podman cannot use privileged ports) |
| 124 | +8. Eject any existing VirtualMedia, then insert the agent ISO |
| 125 | +9. Discover the Virtual Optical Drive UEFI path and set a one-time boot override |
| 126 | +10. Power on the host |
| 127 | +11. Verify BIOS `GenericUsbBoot` is enabled after POST |
| 128 | +12. Add `/etc/hosts` entries for `api`/`api-int` and `*.apps` domains |
| 129 | +13. Wait for bootstrap and install to complete |
| 130 | +14. Copy kubeconfig and kubeadmin-password to the dev-scripts-compatible auth directory |
| 131 | +15. Eject VirtualMedia and stop the HTTP server |
| 132 | + |
| 133 | +## Molecule tests |
| 134 | + |
| 135 | +### bm_redfish scenario |
| 136 | + |
| 137 | +The `bm_redfish` Molecule scenario validates the bare metal Redfish task files |
| 138 | +(`bm_power_on`, `bm_power_off`, `bm_check_usb_boot`, `bm_ensure_usb_boot`, |
| 139 | +`bm_eject_vmedia`, `bm_discover_vmedia_target`) against a stateful Python |
| 140 | +mock iDRAC server that simulates Redfish API responses over HTTPS. |
| 141 | + |
| 142 | +The mock server (`molecule/bm_redfish/files/mock_idrac.py`) provides: |
| 143 | + |
| 144 | +* Stateful GET/POST/PATCH handlers for power, BIOS, VirtualMedia, boot |
| 145 | + override, and job queue Redfish endpoints |
| 146 | +* A `/test/reset` admin endpoint to set mock state between test cases |
| 147 | +* A `/test/state` endpoint to query current mock state for assertions |
| 148 | +* Self-signed TLS certificates generated during `prepare.yml` |
| 149 | + |
| 150 | +Test coverage: |
| 151 | + |
| 152 | +| Test file | Scenarios | |
| 153 | +| --- | --- | |
| 154 | +| `test_power_off.yml` | Already off (idempotent), On -> Off | |
| 155 | +| `test_power_on.yml` | Already on (idempotent), Off -> On | |
| 156 | +| `test_check_usb_boot.yml` | Enabled (succeeds), Disabled (expected failure) | |
| 157 | +| `test_ensure_usb_boot.yml` | Already enabled (no cycle), Disabled + auto-enable (BIOS change + cycle), Disabled + no auto-enable (expected failure) | |
| 158 | +| `test_eject_vmedia.yml` | Inserted (ejects), Not inserted (idempotent) | |
| 159 | +| `test_discover_vmedia.yml` | Auto-discover, user-provided valid path, user-provided invalid path (expected failure) | |
| 160 | + |
| 161 | +## Examples |
| 162 | + |
| 163 | +Minimal vars.yaml for a bare metal SNO deployment: |
| 164 | + |
| 165 | +```YAML |
| 166 | +cifmw_bm_sno: true |
| 167 | +cifmw_bm_agent_cluster_name: ocp |
| 168 | +cifmw_bm_agent_base_domain: example.com |
| 169 | +cifmw_bm_agent_machine_network: "192.168.10.0/24" |
| 170 | +cifmw_bm_agent_node_ip: "192.168.10.50" |
| 171 | +cifmw_bm_agent_node_iface: eno12399np0 |
| 172 | +cifmw_bm_agent_bmc_host: idrac.mgmt.example.com |
| 173 | +cifmw_bm_agent_openshift_version: "4.18.3" |
| 174 | +cifmw_bm_agent_enable_usb_boot: true |
| 175 | +
|
| 176 | +cifmw_bm_nodes: |
| 177 | + - mac: "b0:7b:25:xx:yy:zz" |
| 178 | + root_device: /dev/sda |
| 179 | +``` |
| 180 | + |
| 181 | +## References |
| 182 | + |
| 183 | +* [ci-framework reproducer documentation](https://ci-framework.readthedocs.io/en/latest/roles/reproducer.html) |
| 184 | +* [Redfish API specification](https://www.dmtf.org/standards/redfish) |
| 185 | +* [Dell iDRAC Redfish API Guide](https://developer.dell.com/apis/2978/versions/6.xx/reference) |
0 commit comments