Skip to content
Draft
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
43 changes: 43 additions & 0 deletions .github/workflows/quick-start-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Quick Start Test

on:
workflow_call:
inputs:
runner:
type: string
default: "ubuntu-latest"
timeout-minutes:
type: number
default: 30

permissions: {}

jobs:
test:
name: Quick Start Test
runs-on: ${{ inputs.runner }}
timeout-minutes: ${{ inputs.timeout-minutes }}

steps:
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0

- name: Install libvirt
run: |
sudo apt-get update
sudo apt-get install -y libvirt-daemon-system qemu-kvm virt-manager libvirt-dev

- name: Run Quick Start Test
# We need a new shell to pick up the new group. That is why we do the sudo -s -u $USER ...
# Remove the pre-installed go version. We install the exact version we need.
run: |
sudo usermod -a -G libvirt $USER
sudo ${{ github.workspace }}/hack/quick-start-test/quick-start-test.sh

- name: Upload artifacts
if: ${{ !cancelled() }}
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: artifacts-${{ inputs.bmc-protocol }}.tar.gz
path: test/quick-start/_artifacts
if-no-files-found: error
overwrite: false
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@
.DS_Store
*.swp

# Quick start test temp files
hack/quick-start-test/disk-images
hack/quick-start-test/bmh-vm-01.xml
hack/quick-start-test/bmo/ironic-username
hack/quick-start-test/bmo/ironic-password
hack/quick-start-test/ironic/ironic-username
hack/quick-start-test/ironic/ironic-password
hack/quick-start-test/irso/ssh_testkey
hack/quick-start-test/irso/ssh_testkey.pub


# Development containers
.devcontainer

Expand Down
8 changes: 8 additions & 0 deletions hack/quick-start-test/bmc-secret.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: v1
kind: Secret
metadata:
name: bml-01
type: Opaque
stringData:
username: replaceme
password: replaceme
17 changes: 17 additions & 0 deletions hack/quick-start-test/bmh-01-provision.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
apiVersion: metal3.io/v1alpha1
kind: BareMetalHost
metadata:
name: bml-vm-01
spec:
online: true
bootMACAddress: 00:60:2f:31:81:01
bootMode: UEFI
hardwareProfile: libvirt
bmc:
address: redfish-virtualmedia+http://192.168.222.1:8000/redfish/v1/Systems/bmh-vm-01
credentialsName: bml-01
image:
checksumType: sha256
checksum: http://192.168.222.1/SHA256SUMS
format: qcow2
url: http://192.168.222.1/noble-server-cloudimg-amd64.img
12 changes: 12 additions & 0 deletions hack/quick-start-test/bmh-01.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: metal3.io/v1alpha1
kind: BareMetalHost
metadata:
name: bml-vm-01
spec:
online: true
bootMACAddress: 00:60:2f:31:81:01
bootMode: UEFI
hardwareProfile: libvirt
bmc:
address: redfish-virtualmedia+http://192.168.222.1:8000/redfish/v1/Systems/bmh-vm-01
credentialsName: bml-01
9 changes: 9 additions & 0 deletions hack/quick-start-test/bmo/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: baremetal-operator-system
# This is the kustomization that we build on. You can download it and change
# the URL to a relative path if you do not want to access it over the network.
# Note that the ref=main specifies the version to use.
# We use main here simply because the integration with IrSO is not included in a release yet.
resources:
- https://github.com/metal3-io/baremetal-operator/config/use-irso?ref=main
33 changes: 33 additions & 0 deletions hack/quick-start-test/capm3-vars.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Baremetal lab image variables
# export IMAGE_URL="http://192.168.0.150/CENTOS_10_NODE_IMAGE_K8S_v1.34.1.qcow2"
# export IMAGE_CHECKSUM="afa7e95ee6fb92b952ab85bae4d01033651e690cf04a626c668041d7b94ddd4a"
# export IMAGE_FORMAT="qcow2"
# Virtualized setup variables
export IMAGE_URL="http://192.168.222.1/CENTOS_10_NODE_IMAGE_K8S_v1.34.1.raw"
export IMAGE_CHECKSUM="20537529c0588e1c3d1929981207ef6fac73df7b2500b84f462d09badcc670ea"
export IMAGE_FORMAT="raw"
# Common variables
export IMAGE_CHECKSUM_TYPE="sha256"
export KUBERNETES_VERSION="v1.34.1"
# Make sure this does not conflict with other networks
export POD_CIDR='["192.168.10.0/24"]'
# These can be used to add user-data
export CTLPLANE_KUBEADM_EXTRA_CONFIG="
preKubeadmCommands:
- systemctl enable --now crio
users:
- name: user
sshAuthorizedKeys:
- ssh-ed25519 ABCD... [email protected]"
export WORKERS_KUBEADM_EXTRA_CONFIG="
preKubeadmCommands:
- systemctl enable --now crio
users:
- name: user
sshAuthorizedKeys:
- ssh-ed25519 ABCD... [email protected]"
# NOTE! You must ensure that this is forwarded or assigned somehow to the
# server(s) that is selected for the control-plane.
# We reserved this address in the net.xml as a basic way to get a fixed IP.
export CLUSTER_APIENDPOINT_HOST="192.168.222.101"
export CLUSTER_APIENDPOINT_PORT="6443"
23 changes: 23 additions & 0 deletions hack/quick-start-test/cleanup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Delete the management cluster.
kind delete cluster

# Stop DHCP and image servers. They are automatically removed when stopped.
docker stop dnsmasq
docker stop image-server

# Cleanup the sushy-tools container and the VM. (For virtual-lab setup)
docker stop sushy-tools

virsh -c qemu:///system destroy --domain bmh-vm-01
virsh -c qemu:///system undefine --domain bmh-vm-01 --remove-all-storage --nvram

virsh -c qemu:///system net-destroy baremetal-e2e
virsh -c qemu:///system net-undefine baremetal-e2e

export QUICK_START_BASE=${QUICK_START_BASE:="$(dirname -- "$(readlink -f "${BASH_SOURCE[0]}")")"}
rm -rf "${QUICK_START_BASE}/bmh-vm-01.xml"

sudo ip link del metalend # delete both ends of veth pair
docker network rm kind
sudo iptables -D FORWARD 1
sudo iptables -D FORWARD 1 # twice because we want to remove the first rule twice
7 changes: 7 additions & 0 deletions hack/quick-start-test/dnsmasq.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
HTTP_PORT=6180
DHCP_HOSTS=00:60:2f:31:81:01
DHCP_IGNORE=tag:!known
# IP of the host from VM perspective
PROVISIONING_IP=192.168.222.2
GATEWAY_IP=192.168.222.2
DHCP_RANGE=192.168.222.100,192.168.222.149
44 changes: 44 additions & 0 deletions hack/quick-start-test/ironic/certificate.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: selfsigned-issuer
namespace: baremetal-operator-system
spec:
selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: ironic-cacert
namespace: baremetal-operator-system
spec:
commonName: ironic-ca
isCA: true
issuerRef:
kind: Issuer
name: selfsigned-issuer
secretName: ironic-cacert
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: ca-issuer
namespace: baremetal-operator-system
spec:
ca:
secretName: ironic-cacert
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: ironic-cert
namespace: baremetal-operator-system
spec:
ipAddresses:
- 192.168.222.2
dnsNames:
- ironic.baremetal-operator-system.svc
issuerRef:
kind: Issuer
name: ca-issuer
secretName: ironic-cert
16 changes: 16 additions & 0 deletions hack/quick-start-test/ironic/ironic.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
apiVersion: ironic.metal3.io/v1alpha1
kind: Ironic
metadata:
name: ironic
namespace: baremetal-operator-system
spec:
networking:
dhcp:
rangeBegin: "192.168.222.100"
rangeEnd: "192.168.222.200"
networkCIDR: "192.168.222.0/24"
interface: "eth0"
ipAddress: "192.168.222.2"
ipAddressManager: "keepalived"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to configure the ironic username/password here: apiCredentialsName: ironic-credentials or whatever the secret name is

tls:
certificateName: ironic-cert
7 changes: 7 additions & 0 deletions hack/quick-start-test/ironic/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: baremetal-operator-system
resources:
- ironic.yaml
- certificate.yaml
- namespace.yaml
4 changes: 4 additions & 0 deletions hack/quick-start-test/ironic/namespace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: baremetal-operator-system
16 changes: 16 additions & 0 deletions hack/quick-start-test/kind.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
apiVersion: kind.x-k8s.io/v1alpha4
kind: Cluster
nodes:
- role: control-plane
# Open ports for Ironic
extraPortMappings:
# Ironic httpd
- containerPort: 6180
hostPort: 6180
listenAddress: "0.0.0.0"
protocol: TCP
# Ironic API
- containerPort: 6385
hostPort: 6385
listenAddress: "0.0.0.0"
protocol: TCP
17 changes: 17 additions & 0 deletions hack/quick-start-test/net.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<network>
<name>baremetal-e2e</name>
<forward mode='nat'>
<nat>
<port start='1024' end='65535'/>
</nat>
</forward>
<bridge name='metal3'/>
<ip address='192.168.222.1' netmask='255.255.255.0'>
<dhcp>
<range start='192.168.222.3' end='192.168.222.99'/>
<!-- Reserve IP for convenience -->
<host mac='00:60:2f:31:81:01' name='bmh-vm-01' ip='192.168.222.101'/>
<bootp file='http://192.168.222.2:6180/boot.ipxe'/>
</dhcp>
</ip>
</network>
66 changes: 66 additions & 0 deletions hack/quick-start-test/quick-start-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/usr/bin/env bash

#------------------------------------------------------------------------------
# This script sets up a quick start test environment for Metal3 by
# configuring a virtual lab, bootstrapping a Kind cluster, setting up
# DHCP and image servers, and deploying Ironic and baremetal operators.
#------------------------------------------------------------------------------
set -eux

export QUICK_START_BASE=${QUICK_START_BASE:="$(dirname -- "$(readlink -f "${BASH_SOURCE[0]}")")"}

setup() {
echo "Disk images directory. If disk images are missing, they will be downloaded and prepared."
setup_disk_images_dir

echo "Setting up virtual lab..."
"${QUICK_START_BASE}/setup-virtual-lab.sh"

echo "Bootstrapping Kind cluster..."
"${QUICK_START_BASE}/setup-bootstrap.sh"

echo "Setting up DHCP and image servers..."
"${QUICK_START_BASE}/start-image-server.sh"
}

create_bmhs() {
kubectl apply -f "${QUICK_START_BASE}/bmc-secret.yaml"
kubectl apply -f "${QUICK_START_BASE}/bmh-01.yaml"
# Wait for BMHs to be provisioned
wait_for_bml_ready
}

setup_disk_images_dir() {
DISK_IMAGE_DIR="${QUICK_START_BASE}/disk-images"
REQUIRED_FILES=(
"noble-server-cloudimg-amd64.img"
"CENTOS_10_NODE_IMAGE_K8S_v1.34.1.qcow2"
"CENTOS_10_NODE_IMAGE_K8S_v1.34.1.raw"
"ipa-centos9-master.tar.gz"
)

missing_files=0
for file in "${REQUIRED_FILES[@]}"; do
if [ ! -f "${DISK_IMAGE_DIR}/${file}" ]; then
missing_files=1
break
fi
done

if [ "$missing_files" -eq 1 ]; then
rm -r ${DISK_IMAGE_DIR} || true
echo "Setting up disk images directory..."
"${QUICK_START_BASE}/setup-image-server-dir.sh"
else
echo "All required disk images are present."
fi
}

wait_for_bml_ready() {
echo "Waiting for BareMetalHosts to be provisioned... This may take up to 12 minutes."
if ! kubectl wait --for=condition=Available --timeout=720s baremetalhosts --all; then
exit 1
fi
}

setup
36 changes: 36 additions & 0 deletions hack/quick-start-test/setup-bootstrap.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/env bash

kind create cluster --config kind.yaml

# (Optional) Initialize CAPM3. This is only needed for scenario 2, but it also installs
# cert-manager, which is needed for pretty much everything else.
# If you skip this, make sure you install cert-manager separately!
clusterctl init --infrastructure=metal3 --ipam=metal3

kubectl apply -f https://github.com/metal3-io/ironic-standalone-operator/releases/latest/download/install.yaml
kubectl -n ironic-standalone-operator-system wait --for=condition=Available deploy/ironic-standalone-operator-controller-manager

# Now we can deploy Ironic and BMO
kubectl create ns baremetal-operator-system
# Apply Ironic with retry logic (up to 5 attempts with 10 second delays).
# The IrSO webhook is not guaranteed to be ready when the IrSO deployment is,
# so some retries may be needed.
MAX_RETRIES=5
RETRY_DELAY=10
RETRY_COUNT=0
echo "Applying Ironic configuration..."
while [[ "${RETRY_COUNT}" -lt "${MAX_RETRIES}" ]]; do
if kubectl apply -k ironic; then
echo "Successfully applied Ironic configuration"
break
else
RETRY_COUNT=$((RETRY_COUNT + 1))
echo "Failed to apply Ironic configuration. Retrying in ${RETRY_DELAY} seconds... (Attempt ${RETRY_COUNT}/${MAX_RETRIES})"
sleep ${RETRY_DELAY}
fi
done
if [[ "${RETRY_COUNT}" -eq "${MAX_RETRIES}" ]]; then
echo "ERROR: Failed to apply Ironic configuration after ${MAX_RETRIES} attempts. Exiting."
exit 1
fi
kubectl apply -k bmo
Loading