diff --git a/.github/actions/build-deb/action.yaml b/.github/actions/build-deb/action.yaml index 41376bce..fb5ef5c5 100644 --- a/.github/actions/build-deb/action.yaml +++ b/.github/actions/build-deb/action.yaml @@ -51,7 +51,7 @@ runs: - name: Start the MicroShift service shell: bash run: | - make _topolvm_create + ./src/cluster_manager.sh topolvm-create || exit 1 sudo systemctl start --no-block microshift.service - name: Run a test to verify that MicroShift is functioning properly diff --git a/.github/actions/build/action.yaml b/.github/actions/build/action.yaml index 81c5ed61..70a697f7 100644 --- a/.github/actions/build/action.yaml +++ b/.github/actions/build/action.yaml @@ -30,6 +30,11 @@ inputs: required: false default: 0 type: integer + node-count: + description: Number of nodes in the MicroShift cluster + required: false + default: 1 + type: integer build: type: choice description: Types of artifacts to build @@ -111,11 +116,15 @@ runs: done fi - # Wait until the MicroShift service is ready and healthy + # Start-stop test with readiness check make run-ready make run-healthy - # Stop the MicroShift container + for i in $(seq 2 ${{ inputs.node-count }}); do + make add-node + done + + make run-healthy make stop # Uncomment this to enable tmate-debug on failure diff --git a/.github/actions/quick-start-clean/action.yaml b/.github/actions/quick-start-clean/action.yaml index 49e25237..627e665f 100644 --- a/.github/actions/quick-start-clean/action.yaml +++ b/.github/actions/quick-start-clean/action.yaml @@ -18,8 +18,14 @@ runs: sudo IMAGE_REF=${{ inputs.image-ref }} bash -xeuo pipefail < ./src/quickstart.sh # Wait until the MicroShift service is ready and healthy - make run-ready - make run-healthy + for _ in $(seq 100); do + state=$(sudo podman exec -i microshift-okd systemctl show --property=SubState --value greenboot-healthcheck 2>/dev/null || echo "unknown") + if [ "${state}" = "exited" ]; then + exit 0 + fi + sleep 10 + done + exit 1 - name: Run the quick clean script shell: bash diff --git a/.github/workflows/builders.yaml b/.github/workflows/builders.yaml index 98472be0..ae0660f7 100644 --- a/.github/workflows/builders.yaml +++ b/.github/workflows/builders.yaml @@ -23,6 +23,7 @@ jobs: bootc-image-url: quay.io/centos-bootc/centos-bootc bootc-image-tag: stream9 build: bootc-image + node-count: 2 centos10-bootc: runs-on: ubuntu-24.04 @@ -42,6 +43,7 @@ jobs: bootc-image-url: quay.io/centos-bootc/centos-bootc bootc-image-tag: stream10 build: bootc-image + node-count: 2 fedora-bootc: runs-on: ubuntu-24.04 @@ -61,6 +63,7 @@ jobs: bootc-image-url: registry.fedoraproject.org/fedora-bootc bootc-image-tag: latest build: bootc-image + node-count: 2 ubuntu-rpm2deb: runs-on: ubuntu-24.04 diff --git a/Makefile b/Makefile index cd1952b0..34d3e197 100644 --- a/Makefile +++ b/Makefile @@ -30,19 +30,21 @@ VG_NAME := myvg1 # .PHONY: all all: - @echo "make " + @echo "make " @echo " rpm: build the MicroShift RPMs" @echo " image: build the MicroShift bootc container image" - @echo " run: run the MicroShift bootc container" - @echo " login: login to the MicroShift bootc container" - @echo " stop: stop the MicroShift bootc container" - @echo " clean: clean up the MicroShift container and the LVM backend" + @echo " run: create and run a MicroShift cluster (1 node) in a bootc container" + @echo " add-node: add a new node to the MicroShift cluster in a bootc container" + @echo " start: start the MicroShift cluster that was already created" + @echo " stop: stop the MicroShift cluster" + @echo " clean: clean up the MicroShift cluster and the LVM backend" @echo " check: run the presubmit checks" @echo "" @echo "Sub-targets:" @echo " rpm-to-deb: convert the MicroShift RPMs to Debian packages" - @echo " run-ready: wait until the MicroShift service is ready" - @echo " run-healthy: wait until the MicroShift service is healthy" + @echo " run-ready: wait until the MicroShift service is ready across the cluster" + @echo " run-healthy: wait until the MicroShift service is healthy across the cluster" + @echo " run-status: show the status of the MicroShift cluster" @echo " clean-all: perform a full cleanup, including the container images" @echo "" @@ -105,36 +107,28 @@ image: # which is less efficient than the default driver .PHONY: run run: - @echo "Running the MicroShift container" - sudo modprobe openvswitch - $(MAKE) _topolvm_create - - NETWORK_OPTS="" ; \ - if [ "${ISOLATED_NETWORK}" = "1" ] ; then \ - NETWORK_OPTS="--network none" ; \ - fi ; \ - VOL_OPTS="--tty --volume /dev:/dev" ; \ - for device in input snd dri; do \ - [ -d "/dev/$${device}" ] && VOL_OPTS="$${VOL_OPTS} --tmpfs /dev/$${device}" ; \ - done ; \ - sudo podman run --privileged --rm -d \ - --replace \ - $${NETWORK_OPTS} \ - $${VOL_OPTS} \ - --tmpfs /var/lib/containers \ - --name "${USHIFT_IMAGE}" \ - --hostname 127.0.0.1.nip.io \ - "${USHIFT_IMAGE}" ; \ - $(MAKE) _isolated_network_config + @USHIFT_IMAGE=${USHIFT_IMAGE} ISOLATED_NETWORK=${ISOLATED_NETWORK} LVM_DISK=${LVM_DISK} LVM_VOLSIZE=${LVM_VOLSIZE} VG_NAME=${VG_NAME} ./src/cluster_manager.sh create + +.PHONY: add-node +add-node: + @USHIFT_IMAGE=${USHIFT_IMAGE} ISOLATED_NETWORK=${ISOLATED_NETWORK} LVM_DISK=${LVM_DISK} LVM_VOLSIZE=${LVM_VOLSIZE} VG_NAME=${VG_NAME} ./src/cluster_manager.sh add-node + +.PHONY: start +start: + @USHIFT_IMAGE=${USHIFT_IMAGE} ISOLATED_NETWORK=${ISOLATED_NETWORK} LVM_DISK=${LVM_DISK} LVM_VOLSIZE=${LVM_VOLSIZE} VG_NAME=${VG_NAME} ./src/cluster_manager.sh start + +.PHONY: stop +stop: + @USHIFT_IMAGE=${USHIFT_IMAGE} ISOLATED_NETWORK=${ISOLATED_NETWORK} LVM_DISK=${LVM_DISK} LVM_VOLSIZE=${LVM_VOLSIZE} VG_NAME=${VG_NAME} ./src/cluster_manager.sh stop .PHONY: run-ready run-ready: @echo "Waiting 5m for the MicroShift service to be ready" @for _ in $$(seq 60); do \ - if sudo podman exec -i "${USHIFT_IMAGE}" systemctl -q is-active microshift.service ; then \ + if USHIFT_IMAGE=${USHIFT_IMAGE} ISOLATED_NETWORK=${ISOLATED_NETWORK} LVM_DISK=${LVM_DISK} LVM_VOLSIZE=${LVM_VOLSIZE} VG_NAME=${VG_NAME} ./src/cluster_manager.sh ready ; then \ printf "\nOK\n" && exit 0; \ fi ; \ - echo -n "." && sleep 5 ; \ + sleep 5 ; \ done ; \ printf "\nFAILED\n" && exit 1 @@ -142,31 +136,20 @@ run-ready: run-healthy: @echo "Waiting 15m for the MicroShift service to be healthy" @for _ in $$(seq 60); do \ - state=$$(sudo podman exec -i "${USHIFT_IMAGE}" systemctl show --property=SubState --value greenboot-healthcheck) ; \ - if [ "$${state}" = "exited" ] ; then \ + if USHIFT_IMAGE=${USHIFT_IMAGE} ISOLATED_NETWORK=${ISOLATED_NETWORK} LVM_DISK=${LVM_DISK} LVM_VOLSIZE=${LVM_VOLSIZE} VG_NAME=${VG_NAME} ./src/cluster_manager.sh healthy ; then \ printf "\nOK\n" && exit 0; \ fi ; \ - echo -n "." && sleep 15 ; \ + sleep 5 ; \ done ; \ - printf "\nThe state of the greenboot-healthcheck service is '$${state}'" && \ printf "\nFAILED\n" && exit 1 -.PHONY: login -login: - @echo "Logging into the MicroShift container" - sudo podman exec -it "${USHIFT_IMAGE}" bash -l - -.PHONY: stop -stop: - @echo "Stopping the MicroShift container" - sudo podman stop --time 0 "${USHIFT_IMAGE}" || true +.PHONY: run-status +run-status: + @USHIFT_IMAGE=${USHIFT_IMAGE} ISOLATED_NETWORK=${ISOLATED_NETWORK} LVM_DISK=${LVM_DISK} LVM_VOLSIZE=${LVM_VOLSIZE} VG_NAME=${VG_NAME} ./src/cluster_manager.sh status .PHONY: clean clean: - @echo "Cleaning up the MicroShift container and the TopoLVM CSI backend" - $(MAKE) stop - sudo rmmod openvswitch || true - $(MAKE) _topolvm_delete + @USHIFT_IMAGE=${USHIFT_IMAGE} ISOLATED_NETWORK=${ISOLATED_NETWORK} LVM_DISK=${LVM_DISK} LVM_VOLSIZE=${LVM_VOLSIZE} VG_NAME=${VG_NAME} ./src/cluster_manager.sh delete .PHONY: clean-all clean-all: @@ -181,35 +164,6 @@ check: _hadolint _shellcheck # # Define the private targets # -# The configurations for the isolated network are done inside the container -.PHONY: _isolated_network_config -_isolated_network_config: - if [ "${ISOLATED_NETWORK}" = "1" ] ; then \ - sudo podman cp ./src/config_isolated_net.sh "${USHIFT_IMAGE}:/tmp/config_isolated_net.sh" && \ - sudo podman exec -i "${USHIFT_IMAGE}" /tmp/config_isolated_net.sh && \ - sudo podman exec -i "${USHIFT_IMAGE}" rm -vf /tmp/config_isolated_net.sh ; \ - fi - -.PHONY: _topolvm_create -_topolvm_create: - if [ ! -f "${LVM_DISK}" ] ; then \ - echo "Creating the TopoLVM CSI backend" ; \ - sudo mkdir -p "$$(dirname "${LVM_DISK}")" ; \ - sudo truncate --size="${LVM_VOLSIZE}" "${LVM_DISK}" ; \ - DEVICE_NAME="$$(sudo losetup --find --show --nooverlap "${LVM_DISK}")" && \ - sudo vgcreate -f -y "${VG_NAME}" "$${DEVICE_NAME}" ; \ - fi - -.PHONY: _topolvm_delete -_topolvm_delete: - if [ -f "${LVM_DISK}" ] ; then \ - echo "Deleting the TopoLVM CSI backend" ; \ - sudo lvremove -y "${VG_NAME}" || true ; \ - sudo vgremove -y "${VG_NAME}" || true ; \ - DEVICE_NAME="$$(sudo losetup -j "${LVM_DISK}" | cut -d: -f1)" ; \ - [ -n "$${DEVICE_NAME}" ] && sudo losetup -d $${DEVICE_NAME} || true ; \ - sudo rm -rf "$$(dirname "${LVM_DISK}")" ; \ - fi # When run inside a container, the file contents are redirected via stdin and # the output of errors does not contain the file path. Work around this issue diff --git a/docs/run.md b/docs/run.md index a832d306..26750161 100644 --- a/docs/run.md +++ b/docs/run.md @@ -98,14 +98,17 @@ The following options can be specified in the make command line using the `NAME= | Name | Required | Default | Comments |-------------------|----------|----------|--------- -| LVM_VOLUME_SIZE | no | 1G | TopoLVM CSI backend volume +| LVM_VOLSIZE | no | 1G | TopoLVM CSI backend volume | ISOLATED_NETWORK | no | 0 | Use `--network none` podman option +This step creates a single-node MicroShift cluster. The cluster can be extended using `make add-node` to add one node at a time. + This step includes: * Loading the `openvswitch` module required when OVN-K CNI driver is used when compiled with the non-default `WITH_KINDNET=0` image build option. -* Preparing a 1GB TopoLVM CSI backend on the host to be used by MicroShift when +* Preparing a TopoLVM CSI backend (default 1GB, configurable via `LVM_VOLSIZE`) on the host to be used by MicroShift when compiled with the default `WITH_TOPOLVM=1` image build option. +* Creating a podman network for easier multi-node cluster support with name resolution. ```bash make run @@ -124,20 +127,29 @@ make run ### Container Login -Log into the container by running the following command. +Log into the container by running the following command. The commands for doing so are displayed as +part of the summary from `make run` and `make add-node`. +For example, the first node in a cluster is named `microshift-okd-1`: ```bash -make login +sudo podman exec -it microshift-okd-1 /bin/bash -l ``` Verify that all the MicroShift services are up and running successfully. - ```bash export KUBECONFIG=/var/lib/microshift/resources/kubeadmin/kubeconfig oc get nodes oc get pods -A ``` +### Start the Container + +If you have stopped the MicroShift cluster, you can start it again using the following command. + +```bash +make start +``` + ### Stop the Container Run the following command to stop the MicroShift Bootc container. @@ -146,6 +158,31 @@ Run the following command to stop the MicroShift Bootc container. make stop ``` +### Add Node to Cluster + +To create a multi-node cluster, you can add additional nodes after creating the initial cluster with `make run`. + +```bash +make add-node +``` + +> Note: The `add-node` target requires a non-isolated network (`ISOLATED_NETWORK=0`). Each additional node will be automatically joined to the cluster. + +### Check Cluster Status + +Run the following commands to check the status of your MicroShift cluster. + +```bash +# Wait until the MicroShift service is ready (checks all nodes) +make run-ready + +# Wait until the MicroShift service is healthy (checks all nodes) +make run-healthy + +# Show current cluster status including nodes and pods +make run-status +``` + ## Cleanup ### RPM diff --git a/src/cluster_manager.sh b/src/cluster_manager.sh new file mode 100755 index 00000000..dd28cb18 --- /dev/null +++ b/src/cluster_manager.sh @@ -0,0 +1,397 @@ +#!/bin/bash +# MicroShift Cluster Manager +# Basic functions for managing MicroShift clusters + +set -euo pipefail + +# Configuration - These variables can be overridden by the environment +# They are used throughout the script for single-node and multi-node cluster management +USHIFT_MULTINODE_CLUSTER="${USHIFT_MULTINODE_CLUSTER:-microshift-okd-multinode}" +NODE_BASE_NAME="${NODE_BASE_NAME:-microshift-okd-}" +USHIFT_IMAGE="${USHIFT_IMAGE:-microshift-okd}" +LVM_DISK="${LVM_DISK:-/var/lib/microshift-okd/lvmdisk.image}" +LVM_VOLSIZE="${LVM_VOLSIZE:-1G}" +VG_NAME="${VG_NAME:-myvg1}" +ISOLATED_NETWORK="${ISOLATED_NETWORK:-0}" + +_is_cluster_created() { + if sudo podman container exists "${NODE_BASE_NAME}1"; then + return 0 + fi + return 1 +} + +_is_container_created() { + local -r name="${1}" + if sudo podman container exists "${name}"; then + return 0 + fi + return 1 +} + +create_topolvm_backend() { + if [ -f "${LVM_DISK}" ]; then + echo "INFO: '${LVM_DISK}' exists, reusing" + return 0 + fi + + sudo mkdir -p "$(dirname "${LVM_DISK}")" + sudo truncate --size="${LVM_VOLSIZE}" "${LVM_DISK}" + local -r device_name="$(sudo losetup --find --show --nooverlap "${LVM_DISK}")" + sudo vgcreate -f -y "${VG_NAME}" "${device_name}" +} + +# Delete TopoLVM backend +delete_topolvm_backend() { + if [ -f "${LVM_DISK}" ]; then + echo "Deleting TopoLVM backend: ${LVM_DISK}" + sudo lvremove -y "${VG_NAME}" || true + sudo vgremove -y "${VG_NAME}" || true + local -r device_name="$(sudo losetup -j "${LVM_DISK}" | cut -d: -f1)" + [ -n "${device_name}" ] && sudo losetup -d "${device_name}" || true + sudo rm -rf "$(dirname "${LVM_DISK}")" + fi +} + +_create_podman_network() { + local -r name="${1}" + if ! sudo podman network exists "${name}"; then + echo "Creating podman network: ${name}" + sudo podman network create "${name}" + else + echo "Podman network '${name}' already exists" + fi +} + +_get_subnet() { + local -r network_name="${1}" + local -r subnet_with_mask=$(sudo podman network inspect "${network_name}" --format '{{range .}}{{range .Subnets}}{{.Subnet}}{{end}}{{end}}') + if [ -z "$subnet_with_mask" ]; then + echo "ERROR: Could not determine subnet for network '${network_name}'." >&2 + exit 1 + fi + local -r subnet="${subnet_with_mask%%/*}" + echo "$subnet" +} + +_get_ip_address() { + local -r subnet="${1}" + local -r node_id="${2}" + echo "$subnet" | awk -F. -v new="$node_id" 'NF==4{$4=new+10; printf "%s.%s.%s.%s", $1,$2,$3,$4} NF!=4{print $0}' +} + +_add_node() { + local -r name="${1}" + local -r network_name="${2}" + local -r ip_address="${3}" + + local vol_opts="--tty --volume /dev:/dev" + for device in input snd dri; do + [ -d "/dev/${device}" ] && vol_opts="${vol_opts} --tmpfs /dev/${device}" + done + + local network_opts="--network ${network_name}" + if [ "${ISOLATED_NETWORK}" = "0" ]; then + network_opts="${network_opts} --ip ${ip_address}" + fi + + # shellcheck disable=SC2086 + sudo podman run --privileged -d \ + --ulimit nofile=524288:524288 \ + ${vol_opts} \ + ${network_opts} \ + --tmpfs /var/lib/containers \ + --name "${name}" \ + --hostname "${name}" \ + "${USHIFT_IMAGE}" + + return $? +} + + +_join_node() { + local -r name="${1}" + local -r primary_name="${NODE_BASE_NAME}1" + local -r src_kubeconfig="/var/lib/microshift/resources/kubeadmin/${primary_name}/kubeconfig" + local -r tmp_kubeconfig="/tmp/kubeconfig.${primary_name}" + + sudo podman cp "${primary_name}:${src_kubeconfig}" "${tmp_kubeconfig}" + local -r dest_kubeconfig="kubeconfig" + sudo podman cp "${tmp_kubeconfig}" "${name}:${dest_kubeconfig}" + sudo rm -f "${tmp_kubeconfig}" + + sudo podman exec -i "${name}" bash -c "\ + systemctl stop microshift kubepods.slice crio && \ + microshift add-node --kubeconfig=${dest_kubeconfig} --learner=false > add-node.log 2>&1" + + return $? +} + + +_get_cluster_containers() { + sudo podman ps -a --format '{{.Names}}' | grep -E "^${NODE_BASE_NAME}[0-9]+$" || true +} + + +_get_running_containers() { + sudo podman ps --format '{{.Names}}' | grep -E "^${NODE_BASE_NAME}[0-9]+$" || true +} + + +cluster_create() { + local -r container_name="${NODE_BASE_NAME}1" + echo "Creating cluster: ${container_name}" + + if _is_container_created "${container_name}"; then + echo "ERROR: Container '${container_name}' already exists" >&2 + exit 1 + fi + + sudo modprobe openvswitch || true + create_topolvm_backend + _create_podman_network "${USHIFT_MULTINODE_CLUSTER}" + + local -r subnet=$(_get_subnet "${USHIFT_MULTINODE_CLUSTER}") + local network_name="${USHIFT_MULTINODE_CLUSTER}" + if [ "${ISOLATED_NETWORK}" = "1" ]; then + network_name="none" + fi + + local -r node_name="${NODE_BASE_NAME}1" + local -r ip_address=$(_get_ip_address "$subnet" "1") + if ! _add_node "${node_name}" "${network_name}" "${ip_address}"; then + echo "ERROR: failed to create node: $node_name" >&2 + exit 1 + fi + + if [ "${ISOLATED_NETWORK}" = "1" ] ; then + echo "Configuring isolated network for node: ${node_name}" + sudo podman cp ./src/config_isolated_net.sh "${node_name}:/tmp/config_isolated_net.sh" + sudo podman exec -i "${node_name}" /tmp/config_isolated_net.sh + sudo podman exec -i "${node_name}" rm -vf /tmp/config_isolated_net.sh + fi + + echo "Cluster created successfully. To access the node container, run:" + echo " sudo podman exec -it ${node_name} /bin/bash -l" +} + + +cluster_add_node() { + if ! _is_cluster_created; then + echo "ERROR: Cluster is not created" >&2 + exit 1 + fi + if [ "${ISOLATED_NETWORK}" = "1" ]; then + echo "ERROR: Network type is isolated" >&2 + exit 1 + fi + + local -r last_id=$(_get_cluster_containers | wc -l) + local -r subnet=$(_get_subnet "${USHIFT_MULTINODE_CLUSTER}") + local -r node_id=$((last_id + 1)) + local -r node_name="${NODE_BASE_NAME}${node_id}" + local -r ip_address=$(_get_ip_address "$subnet" "$node_id") + + cluster_healthy + + echo "Creating node: ${node_name}" + if ! _add_node "${node_name}" "${USHIFT_MULTINODE_CLUSTER}" "${ip_address}"; then + echo "ERROR: failed to create node: ${node_name}" >&2 + exit 1 + fi + echo "Joining node to the cluster: ${node_name}" + if ! _join_node "${node_name}"; then + echo "ERROR: failed to join node to the cluster: ${node_name}" >&2 + echo "=== Add-node log content ===" >&2 + if sudo podman exec -i "${node_name}" test -f add-node.log; then + sudo podman exec -i "${node_name}" cat add-node.log >&2 + else + echo "WARNING: add-node.log not found in ${node_name}" >&2 + fi + exit 1 + fi + + echo "Node added successfully. To access the new node container, run:" + echo " sudo podman exec -it ${node_name} /bin/bash -l" + return 0 +} + + +cluster_start() { + local -r containers=$(_get_cluster_containers) + + if [ -z "${containers}" ]; then + echo "ERROR: No cluster containers found" >&2 + exit 1 + fi + + echo "Starting cluster" + for container in ${containers}; do + echo "Starting container: ${container}" + sudo podman start "${container}" || true + done +} + + +cluster_stop() { + local -r containers=$(_get_running_containers) + + if [ -z "${containers}" ]; then + echo "No running cluster containers" + return 0 + fi + + echo "Stopping cluster" + for container in ${containers}; do + echo "Stopping container: ${container}" + sudo podman stop --time 0 "${container}" || true + done +} + + +cluster_destroy() { + local containers + containers=$(_get_cluster_containers) + for container in ${containers}; do + echo "Stopping container: ${container}" + sudo podman stop --time 0 "${container}" || true + echo "Removing container: ${container}" + sudo podman rm -f "${container}" || true + done + + if sudo podman network exists "${USHIFT_MULTINODE_CLUSTER}"; then + echo "Removing podman network: ${USHIFT_MULTINODE_CLUSTER}" + sudo podman network rm "${USHIFT_MULTINODE_CLUSTER}" || true + fi + + sudo rmmod openvswitch || true + delete_topolvm_backend + + echo "Cluster destroyed successfully" +} + + +cluster_ready() { + local -r containers=$(_get_running_containers) + if [ -z "${containers}" ]; then + echo "No running nodes found" + exit 1 + fi + for container in ${containers}; do + echo "Checking readiness of node: ${container}" + state=$(sudo podman exec -i "${container}" systemctl show --property=SubState --value microshift.service 2>/dev/null || echo "unknown") + if [ "${state}" != "running" ]; then + echo "Node ${container} is not ready." + exit 1 + fi + done + echo "All nodes running." +} + +cluster_healthy() { + if ! _is_cluster_created ; then + echo "Cluster is not initialized" + exit 1 + fi + + local -r containers=$(_get_running_containers) + + if [ -z "${containers}" ]; then + echo "Cluster is down. No cluster nodes are running." + exit 1 + fi + + for container in ${containers}; do + echo "Checking health of node: ${container}" + state=$(sudo podman exec -i "${container}" systemctl show --property=SubState --value greenboot-healthcheck 2>/dev/null || echo "unknown") + if [ "${state}" != "exited" ]; then + echo "Node ${container} is not healthy." + exit 1 + fi + done + echo "All nodes healthy." +} + + +cluster_status() { + if ! _is_cluster_created ; then + echo "Cluster is not initialized" + exit 1 + fi + + local -r running_containers=$(_get_running_containers) + + if [ -z "${running_containers}" ]; then + echo "Cluster is down. No cluster nodes are running." + return 0 + fi + + local -r created_containers=$(_get_cluster_containers) + for container in ${created_containers}; do + if ! echo "${running_containers}" | grep -q "${container}"; then + echo "Node ${container} is not running." + fi + done + + local -r first_container=$(echo "${running_containers}" | head -n1) + echo "Cluster is running." + sudo podman exec -i "${first_container}" oc get nodes,pods -A -o wide 2>/dev/null || echo "Unable to retrieve cluster status" + return 0 +} + +main() { + case "${1:-}" in + create) + shift + cluster_create + ;; + add-node) + shift + cluster_add_node + ;; + start) + shift + cluster_start + ;; + stop) + shift + cluster_stop + ;; + delete) + shift + cluster_destroy + ;; + ready) + shift + cluster_ready + ;; + healthy) + shift + cluster_healthy + ;; + status) + shift + cluster_status + ;; + topolvm-create) + shift + create_topolvm_backend + ;; + topolvm-delete) + shift + delete_topolvm_backend + ;; + *) + echo "Usage: $0 {create|add-node|start|stop|delete|ready|healthy|status|topolvm-create|topolvm-delete}" + exit 1 + ;; + esac +} + +# Ensure script is running from project root directory (where Makefile exists) +if [ ! -f "./Makefile" ]; then + echo "ERROR: Please run this script from the project root directory (where Makefile is located)" >&2 + exit 1 +fi + +main "$@" diff --git a/src/rpm/postinstall.sh b/src/rpm/postinstall.sh index 3dbcf0c1..4dbcb0e8 100755 --- a/src/rpm/postinstall.sh +++ b/src/rpm/postinstall.sh @@ -40,6 +40,16 @@ dnf install -y firewalld systemd-resolved \ jq bash-completion firewall-offline-cmd --zone=trusted --add-source=10.42.0.0/16 firewall-offline-cmd --zone=trusted --add-source=169.254.169.1 +# Multinode clusters require connectivity on both apiserver and etcd +firewall-offline-cmd --zone=public --add-port=6443/tcp +firewall-offline-cmd --zone=public --add-port=2379/tcp +firewall-offline-cmd --zone=public --add-port=2380/tcp + +# Configure limits for cAdvisor and kubelet +cat > /etc/sysctl.d/99-microshift.conf <