From 593444b70d6474ebc832768c2621fbf92a4129e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Ferr=C3=A3o?= <2031761+viniciusferrao@users.noreply.github.com> Date: Thu, 20 Aug 2026 13:13:21 -0300 Subject: [PATCH] feat(genesis): add hardware providers --- .../packagegroup-xcat-genesis-hardware.bb | 50 +++ .../files/genesis-hardware | 304 ++++++++++++++++++ .../files/iprutils.json | 11 + .../files/mstflint.json | 9 + .../files/nvme.json | 12 + .../files/provider-iprutils | 47 +++ .../files/provider-mstflint | 57 ++++ .../files/provider-nvme | 63 ++++ .../xcat-genesis-hardware-control_1.0.bb | 63 ++++ ...-configure-avoid-host-ncurses-config.patch | 32 ++ .../iprutils/iprutils_2.4.19.bb | 18 ++ ...001-python-tools-use-libtool-objects.patch | 53 +++ .../mstflint/mstflint_4.36.0.bb | 37 +++ 13 files changed, 756 insertions(+) create mode 100644 xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/packagegroups/packagegroup-xcat-genesis-hardware.bb create mode 100644 xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/files/genesis-hardware create mode 100644 xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/files/iprutils.json create mode 100644 xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/files/mstflint.json create mode 100644 xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/files/nvme.json create mode 100644 xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/files/provider-iprutils create mode 100644 xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/files/provider-mstflint create mode 100644 xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/files/provider-nvme create mode 100644 xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/xcat-genesis-hardware-control_1.0.bb create mode 100644 xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-support/iprutils/files/0001-configure-avoid-host-ncurses-config.patch create mode 100644 xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-support/iprutils/iprutils_2.4.19.bb create mode 100644 xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-support/mstflint/files/0001-python-tools-use-libtool-objects.patch create mode 100644 xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-support/mstflint/mstflint_4.36.0.bb diff --git a/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/packagegroups/packagegroup-xcat-genesis-hardware.bb b/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/packagegroups/packagegroup-xcat-genesis-hardware.bb new file mode 100644 index 000000000..1f53dc4ad --- /dev/null +++ b/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/packagegroups/packagegroup-xcat-genesis-hardware.bb @@ -0,0 +1,50 @@ +SUMMARY = "Open hardware tools for xCAT Genesis" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" + +inherit packagegroup + +PACKAGE_ARCH = "${MACHINE_ARCH}" + +RDEPENDS:${PN} = "\ + curl \ + dosfstools \ + edac-utils \ + e2fsprogs-e2fsck \ + e2fsprogs-mke2fs \ + ethtool \ + hdparm \ + hwloc \ + ipmitool \ + iproute2-rdma \ + jq \ + kexec \ + kernel-modules \ + lldpd \ + lsscsi \ + lvm2 \ + mdadm \ + memtester \ + mstflint \ + nvme-cli \ + parted \ + pciutils \ + rdma-core \ + sg3-utils \ + smartmontools \ + stress-ng \ + usbutils \ + util-linux-blockdev \ + util-linux-lsblk \ + util-linux-sfdisk \ + util-linux-wipefs \ + xcat-genesis-hardware-control \ +" + +RDEPENDS:${PN}:append:xcat-genesis-x86 = " dmidecode lshw" +RDEPENDS:${PN}:append:xcat-genesis-x86-64 = " dmidecode lshw mcelog" +RDEPENDS:${PN}:append:xcat-genesis-armv7hf = " dmidecode lshw" +RDEPENDS:${PN}:append:xcat-genesis-aarch64 = " dmidecode lshw" +RDEPENDS:${PN}:append:xcat-genesis-ppc64 = " dmidecode xcat-genesis-hardware-control-iprutils" +RDEPENDS:${PN}:append:xcat-genesis-ppc64le = " dmidecode xcat-genesis-hardware-control-iprutils" +RDEPENDS:${PN}:append:xcat-genesis-riscv64 = " lshw" diff --git a/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/files/genesis-hardware b/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/files/genesis-hardware new file mode 100644 index 000000000..fe0ac04b0 --- /dev/null +++ b/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/files/genesis-hardware @@ -0,0 +1,304 @@ +#!/bin/bash +set -euo pipefail + +provider_dir=${XCAT_GENESIS_PROVIDER_DIR:-/usr/share/xcat/genesis/providers} +provider_exec_dir=${XCAT_GENESIS_PROVIDER_EXEC_DIR:-/usr/libexec/xcat/genesis/providers} +audit_file=${XCAT_GENESIS_HARDWARE_AUDIT:-/run/xcat/hardware-audit.jsonl} +provider_timeout=${XCAT_GENESIS_PROVIDER_TIMEOUT:-60} + +[[ $provider_timeout =~ ^[1-9][0-9]{0,3}$ ]] \ + || { printf 'genesis-hardware: invalid provider timeout\n' >&2; exit 1; } + +fail() { + printf 'genesis-hardware: %s\n' "$*" >&2 + exit 1 +} + +usage() { + printf '%s\n' \ + 'Usage: genesis-hardware providers' \ + ' genesis-hardware capabilities PROVIDER' \ + ' genesis-hardware probe [PROVIDER]' \ + ' genesis-hardware run PROVIDER CAPABILITY [--device-id ID] [--task-id ID] [--request FILE]' >&2 + exit 2 +} + +validate_provider_name() { + [[ $1 =~ ^[a-z][a-z0-9.-]{0,63}$ ]] || fail "invalid provider name: $1" +} + +manifest_path() { + local provider=$1 path + + validate_provider_name "$provider" + path=$provider_dir/$provider.json + [[ -f $path && ! -L $path ]] || fail "provider manifest not found: $provider" + printf '%s\n' "$path" +} + +validate_manifest() { + local provider=$1 manifest=$2 + + jq -e --arg provider "$provider" ' + type == "object" and + (keys | sort) == (["capabilities", "kind", "name", "schema", "version"] | sort) and + .schema == 1 and + .name == $provider and + (.version | type == "string" and test("^[A-Za-z0-9][A-Za-z0-9._+-]{0,63}$")) and + (.kind | IN("storage", "network", "accelerator", "platform")) and + (.capabilities | type == "array" and length > 0) and + all(.capabilities[]; + type == "object" and + (keys | sort) == (["destructive", "name"] | sort) and + (.name | type == "string" and test("^[a-z][a-z0-9.-]*$")) and + (.destructive | type == "boolean")) and + (([.capabilities[].name] | length) == + ([.capabilities[].name] | unique | length)) + ' "$manifest" >/dev/null || fail "invalid provider manifest: $provider" +} + +provider_executable() { + local provider=$1 executable + + executable=$provider_exec_dir/$provider + [[ -f $executable && ! -L $executable && -x $executable ]] \ + || fail "provider executable not found: $provider" + printf '%s\n' "$executable" +} + +provider_manifest() { + local provider=$1 manifest + + manifest=$(manifest_path "$provider") + validate_manifest "$provider" "$manifest" + printf '%s\n' "$manifest" +} + +invoke_provider() { + local provider=$1 verb=$2 + shift 2 + local executable output error status size message + + executable=$(provider_executable "$provider") + output=$(mktemp) + error=$(mktemp) + + if timeout --signal=TERM --kill-after=5 "$provider_timeout" \ + "$executable" "$verb" "$@" >"$output" 2>"$error"; then + status=0 + else + status=$? + fi + + if ((status != 0)); then + message=$(head -c 4096 "$error") + rm -f -- "$output" "$error" + printf 'genesis-hardware: provider %s failed: %s\n' "$provider" "$message" >&2 + return "$status" + fi + + size=$(wc -c <"$output") + if ((size > 4194304)); then + rm -f -- "$output" "$error" + printf 'genesis-hardware: provider %s returned too much data\n' "$provider" >&2 + return 65 + fi + if ! jq -e 'type == "object"' "$output" >/dev/null; then + rm -f -- "$output" "$error" + printf 'genesis-hardware: provider %s returned invalid JSON\n' "$provider" >&2 + return 65 + fi + + cat "$output" + rm -f -- "$output" "$error" +} + +write_audit() { + local phase=$1 task_id=$2 provider=$3 capability=$4 device_id=$5 request_hash=$6 + local record timestamp audit_dir + + timestamp=$(date -u +%Y-%m-%dT%H:%M:%SZ) + record=$(jq -cn \ + --arg timestamp "$timestamp" \ + --arg phase "$phase" \ + --arg task_id "$task_id" \ + --arg provider "$provider" \ + --arg capability "$capability" \ + --arg device_id "$device_id" \ + --arg request_sha256 "$request_hash" \ + '{schema: 1, timestamp: $timestamp, phase: $phase, task_id: $task_id, + provider: $provider, capability: $capability, device_id: $device_id, + request_sha256: $request_sha256}') + + audit_dir=$(dirname "$audit_file") + install -d -m 0755 "$audit_dir" + [[ ! -e $audit_file || (-f $audit_file && ! -L $audit_file) ]] \ + || fail 'invalid hardware audit file' + [[ ! -e $audit_file.lock || (-f $audit_file.lock && ! -L $audit_file.lock) ]] \ + || fail 'invalid hardware audit lock' + ( + flock -x 9 + printf '%s\n' "$record" >>"$audit_file" + ) 9>"$audit_file.lock" +} + +list_providers() { + local manifest provider output + local -a manifests + + shopt -s nullglob + manifests=("$provider_dir"/*.json) + ((${#manifests[@]} > 0)) || fail 'no hardware providers found' + output=$(mktemp) + for manifest in "${manifests[@]}"; do + provider=${manifest##*/} + provider=${provider%.json} + [[ -f $manifest && ! -L $manifest ]] \ + || fail "invalid provider manifest: $provider" + validate_manifest "$provider" "$manifest" + jq -c . "$manifest" >>"$output" + done + jq -s '{schema: 1, providers: .}' "$output" + rm -f -- "$output" +} + +show_capabilities() { + local manifest + + manifest=$(provider_manifest "$1") + jq '{schema: 1, provider: .name, kind: .kind, version: .version, + capabilities: .capabilities}' "$manifest" +} + +probe_providers() { + local requested=${1:-} manifest provider result output + local -a manifests + + output=$(mktemp) + if [[ -n $requested ]]; then + manifests=("$(provider_manifest "$requested")") + else + shopt -s nullglob + manifests=("$provider_dir"/*.json) + ((${#manifests[@]} > 0)) || fail 'no hardware providers found' + fi + + for manifest in "${manifests[@]}"; do + provider=${manifest##*/} + provider=${provider%.json} + [[ -f $manifest && ! -L $manifest ]] \ + || fail "invalid provider manifest: $provider" + validate_manifest "$provider" "$manifest" + result=$(invoke_provider "$provider" probe) + jq -cn --arg provider "$provider" --argjson result "$result" \ + '{provider: $provider, result: $result}' >>"$output" + done + jq -s '{schema: 1, probes: .}' "$output" + rm -f -- "$output" +} + +validate_request() { + local request=$1 size + + [[ -f $request && ! -L $request ]] || fail "invalid request file: $request" + size=$(wc -c <"$request") + ((size <= 1048576)) || fail 'hardware request is too large' + jq -e 'type == "object"' "$request" >/dev/null \ + || fail 'hardware request must be a JSON object' +} + +run_capability() { + local provider=$1 capability=$2 + shift 2 + local manifest destructive device_id='' task_id='' request_file='' + local request_hash='' result status + + manifest=$(provider_manifest "$provider") + [[ $capability =~ ^[a-z][a-z0-9.-]*$ ]] || fail "invalid capability: $capability" + destructive=$(jq -r --arg capability "$capability" \ + '.capabilities[] | select(.name == $capability) | .destructive | tostring' \ + "$manifest") + [[ $destructive == true || $destructive == false ]] \ + || fail "provider $provider does not support $capability" + + while (($# > 0)); do + case "$1" in + --device-id) + (($# >= 2)) || usage + device_id=$2 + shift 2 + ;; + --task-id) + (($# >= 2)) || usage + task_id=$2 + shift 2 + ;; + --request) + (($# >= 2)) || usage + request_file=$2 + shift 2 + ;; + *) usage ;; + esac + done + + [[ -z $device_id || $device_id =~ ^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$ ]] \ + || fail 'invalid device identity' + [[ -z $task_id || $task_id =~ ^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$ ]] \ + || fail 'invalid task identity' + if [[ -n $request_file ]]; then + validate_request "$request_file" + request_hash=$(sha256sum -- "$request_file" | awk '{print $1}') + fi + + if [[ $destructive == true ]]; then + [[ -n $task_id ]] || fail 'destructive capability requires a task identity' + [[ -n $device_id && $device_id != all ]] \ + || fail 'destructive capability requires an exact device identity' + [[ -n $request_file ]] || fail 'destructive capability requires a request file' + write_audit started "$task_id" "$provider" "$capability" "$device_id" "$request_hash" + fi + + if result=$(invoke_provider "$provider" run "$capability" "$device_id" "${request_file:--}"); then + status=0 + else + status=$? + fi + + if ((status != 0)); then + if [[ $destructive == true ]]; then + write_audit failed "$task_id" "$provider" "$capability" "$device_id" "$request_hash" + fi + fail "provider $provider failed capability $capability" + fi + if [[ $destructive == true ]]; then + write_audit completed "$task_id" "$provider" "$capability" "$device_id" "$request_hash" + fi + + jq -cn \ + --arg provider "$provider" \ + --arg capability "$capability" \ + --arg device_id "$device_id" \ + --arg task_id "$task_id" \ + --argjson result "$result" \ + '{schema: 1, provider: $provider, capability: $capability, + device_id: (if $device_id == "" then null else $device_id end), + task_id: (if $task_id == "" then null else $task_id end), + result: $result}' +} + +[[ $# -ge 1 ]] || usage +command=$1 +shift + +case "$command:$#" in + providers:0) list_providers ;; + capabilities:1) show_capabilities "$1" ;; + probe:0) probe_providers ;; + probe:1) probe_providers "$1" ;; + run:*) + (($# >= 2)) || usage + run_capability "$@" + ;; + *) usage ;; +esac diff --git a/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/files/iprutils.json b/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/files/iprutils.json new file mode 100644 index 000000000..24ee89d7e --- /dev/null +++ b/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/files/iprutils.json @@ -0,0 +1,11 @@ +{ + "capabilities": [ + {"destructive": false, "name": "storage.firmware.inventory"}, + {"destructive": false, "name": "storage.health"}, + {"destructive": false, "name": "storage.inventory"} + ], + "kind": "storage", + "name": "iprutils", + "schema": 1, + "version": "1.0" +} diff --git a/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/files/mstflint.json b/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/files/mstflint.json new file mode 100644 index 000000000..46f0d8e01 --- /dev/null +++ b/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/files/mstflint.json @@ -0,0 +1,9 @@ +{ + "capabilities": [ + {"destructive": false, "name": "network.firmware.inventory"} + ], + "kind": "network", + "name": "mstflint", + "schema": 1, + "version": "1.0" +} diff --git a/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/files/nvme.json b/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/files/nvme.json new file mode 100644 index 000000000..38420c46b --- /dev/null +++ b/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/files/nvme.json @@ -0,0 +1,12 @@ +{ + "capabilities": [ + {"destructive": false, "name": "storage.firmware.inventory"}, + {"destructive": false, "name": "storage.health"}, + {"destructive": false, "name": "storage.inventory"}, + {"destructive": false, "name": "storage.logs"} + ], + "kind": "storage", + "name": "nvme", + "schema": 1, + "version": "1.0" +} diff --git a/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/files/provider-iprutils b/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/files/provider-iprutils new file mode 100644 index 000000000..666300168 --- /dev/null +++ b/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/files/provider-iprutils @@ -0,0 +1,47 @@ +#!/bin/bash +set -euo pipefail + +sys_scsi_hosts=${XCAT_GENESIS_SYS_SCSI_HOSTS:-/sys/class/scsi_host} + +fail() { + printf 'iprutils provider: %s\n' "$*" >&2 + exit 1 +} + +probe() { + local path driver + local -a hosts=() + + shopt -s nullglob + for path in "$sys_scsi_hosts"/host*; do + [[ -f $path/proc_name ]] || continue + read -r driver <"$path/proc_name" + [[ $driver == ipr ]] || continue + hosts+=("${path##*/}") + done + jq -cn --args \ + '{detected: ($ARGS.positional | length > 0), devices: $ARGS.positional}' \ + -- "${hosts[@]}" +} + +run_capability() { + local capability=$1 output + + command -v iprconfig >/dev/null || fail 'iprconfig command is unavailable' + case "$capability" in + storage.inventory) output=$(iprconfig -c show-config) ;; + storage.health) output=$(iprconfig -c show-arrays) ;; + storage.firmware.inventory) output=$(iprconfig -c show-ucode-levels) ;; + *) fail "unsupported capability: $capability" ;; + esac + jq -cn --arg output "$output" '{raw: $output}' +} + +case "${1:-}" in + probe) probe ;; + run) + (($# == 4)) || fail 'invalid provider request' + run_capability "$2" + ;; + *) fail 'invalid provider verb' ;; +esac diff --git a/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/files/provider-mstflint b/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/files/provider-mstflint new file mode 100644 index 000000000..405b571ff --- /dev/null +++ b/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/files/provider-mstflint @@ -0,0 +1,57 @@ +#!/bin/bash +set -euo pipefail + +sys_pci_devices=${XCAT_GENESIS_SYS_PCI_DEVICES:-/sys/bus/pci/devices} + +fail() { + printf 'mstflint provider: %s\n' "$*" >&2 + exit 1 +} + +probe() { + local path vendor + local -a devices=() + + shopt -s nullglob + for path in "$sys_pci_devices"/*; do + [[ -f $path/vendor ]] || continue + read -r vendor <"$path/vendor" + [[ $vendor == 0x15b3 || $vendor == 0X15B3 ]] || continue + devices+=("${path##*/}") + done + jq -cn --args \ + '{detected: ($ARGS.positional | length > 0), devices: $ARGS.positional}' \ + -- "${devices[@]}" +} + +validate_device() { + local vendor + + [[ $1 =~ ^[0-9a-fA-F]{4}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}\.[0-7]$ ]] \ + || fail 'invalid PCI device identity' + [[ -f $sys_pci_devices/$1/vendor ]] || fail "PCI device not found: $1" + read -r vendor <"$sys_pci_devices/$1/vendor" + [[ $vendor == 0x15b3 || $vendor == 0X15B3 ]] \ + || fail "device is not NVIDIA or Mellanox: $1" +} + +run_capability() { + local capability=$1 device=${2:-} output + + [[ $capability == network.firmware.inventory ]] \ + || fail "unsupported capability: $capability" + validate_device "$device" + command -v mstflint >/dev/null || fail 'mstflint command is unavailable' + output=$(mstflint -d "$device" query) + jq -cn --arg device "$device" --arg output "$output" \ + '{device_id: $device, raw: $output}' +} + +case "${1:-}" in + probe) probe ;; + run) + (($# == 4)) || fail 'invalid provider request' + run_capability "$2" "$3" + ;; + *) fail 'invalid provider verb' ;; +esac diff --git a/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/files/provider-nvme b/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/files/provider-nvme new file mode 100644 index 000000000..f640d99d4 --- /dev/null +++ b/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/files/provider-nvme @@ -0,0 +1,63 @@ +#!/bin/bash +set -euo pipefail + +sys_class_nvme=${XCAT_GENESIS_SYS_CLASS_NVME:-/sys/class/nvme} +dev_dir=${XCAT_GENESIS_DEV_DIR:-/dev} + +fail() { + printf 'nvme provider: %s\n' "$*" >&2 + exit 1 +} + +probe() { + local path + local -a devices=() + + shopt -s nullglob + for path in "$sys_class_nvme"/nvme*; do + [[ -d $path ]] || continue + devices+=("${path##*/}") + done + jq -cn --args \ + '{detected: ($ARGS.positional | length > 0), devices: $ARGS.positional}' \ + -- "${devices[@]}" +} + +validate_device() { + [[ $1 =~ ^nvme[0-9]+$ ]] || fail 'invalid NVMe controller identity' + [[ -d $sys_class_nvme/$1 ]] || fail "NVMe controller not found: $1" + [[ -e $dev_dir/$1 && ! -L $dev_dir/$1 ]] || fail "NVMe device not found: $1" +} + +run_capability() { + local capability=$1 device=${2:-} + + command -v nvme >/dev/null || fail 'nvme command is unavailable' + case "$capability" in + storage.inventory) + nvme list -o json + ;; + storage.health) + validate_device "$device" + nvme smart-log "$dev_dir/$device" -o json + ;; + storage.logs) + validate_device "$device" + nvme error-log "$dev_dir/$device" -o json + ;; + storage.firmware.inventory) + validate_device "$device" + nvme id-ctrl "$dev_dir/$device" -o json + ;; + *) fail "unsupported capability: $capability" ;; + esac +} + +case "${1:-}" in + probe) probe ;; + run) + (($# == 4)) || fail 'invalid provider request' + run_capability "$2" "$3" + ;; + *) fail 'invalid provider verb' ;; +esac diff --git a/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/xcat-genesis-hardware-control_1.0.bb b/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/xcat-genesis-hardware-control_1.0.bb new file mode 100644 index 000000000..d2578089d --- /dev/null +++ b/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-core/xcat-genesis-hardware-control/xcat-genesis-hardware-control_1.0.bb @@ -0,0 +1,63 @@ +SUMMARY = "Hardware provider dispatcher for xCAT Genesis" +LICENSE = "EPL-1.0" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/EPL-1.0;md5=57f8d5e2b3e98ac6e088986c12bf94e6" + +SRC_URI = "file://genesis-hardware \ + file://iprutils.json \ + file://mstflint.json \ + file://nvme.json \ + file://provider-iprutils \ + file://provider-mstflint \ + file://provider-nvme \ +" +S = "${UNPACKDIR}" + +RDEPENDS:${PN} = "bash coreutils jq mstflint nvme-cli util-linux-flock" + +PACKAGES:prepend:xcat-genesis-ppc64 = "${PN}-iprutils " +PACKAGES:prepend:xcat-genesis-ppc64le = "${PN}-iprutils " +RDEPENDS:${PN}-iprutils:xcat-genesis-ppc64 = "${PN} bash iprutils" +RDEPENDS:${PN}-iprutils:xcat-genesis-ppc64le = "${PN} bash iprutils" + +do_install() { + install -d ${D}${libexecdir}/xcat/genesis/providers + install -m 0755 ${UNPACKDIR}/genesis-hardware \ + ${D}${libexecdir}/xcat/genesis-hardware + install -m 0755 ${UNPACKDIR}/provider-mstflint \ + ${D}${libexecdir}/xcat/genesis/providers/mstflint + install -m 0755 ${UNPACKDIR}/provider-nvme \ + ${D}${libexecdir}/xcat/genesis/providers/nvme + + install -d ${D}${datadir}/xcat/genesis/providers + install -m 0644 ${UNPACKDIR}/mstflint.json \ + ${D}${datadir}/xcat/genesis/providers/mstflint.json + install -m 0644 ${UNPACKDIR}/nvme.json \ + ${D}${datadir}/xcat/genesis/providers/nvme.json +} + +do_install:append:xcat-genesis-ppc64() { + install -m 0755 ${UNPACKDIR}/provider-iprutils \ + ${D}${libexecdir}/xcat/genesis/providers/iprutils + install -m 0644 ${UNPACKDIR}/iprutils.json \ + ${D}${datadir}/xcat/genesis/providers/iprutils.json +} + +do_install:append:xcat-genesis-ppc64le() { + install -m 0755 ${UNPACKDIR}/provider-iprutils \ + ${D}${libexecdir}/xcat/genesis/providers/iprutils + install -m 0644 ${UNPACKDIR}/iprutils.json \ + ${D}${datadir}/xcat/genesis/providers/iprutils.json +} + +FILES:${PN} = "${libexecdir}/xcat/genesis-hardware \ + ${libexecdir}/xcat/genesis/providers \ + ${datadir}/xcat/genesis/providers \ +" + +FILES:${PN}-iprutils:xcat-genesis-ppc64 = "${libexecdir}/xcat/genesis/providers/iprutils \ + ${datadir}/xcat/genesis/providers/iprutils.json \ +" + +FILES:${PN}-iprutils:xcat-genesis-ppc64le = "${libexecdir}/xcat/genesis/providers/iprutils \ + ${datadir}/xcat/genesis/providers/iprutils.json \ +" diff --git a/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-support/iprutils/files/0001-configure-avoid-host-ncurses-config.patch b/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-support/iprutils/files/0001-configure-avoid-host-ncurses-config.patch new file mode 100644 index 000000000..36f6ebee0 --- /dev/null +++ b/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-support/iprutils/files/0001-configure-avoid-host-ncurses-config.patch @@ -0,0 +1,32 @@ +From 3dd3b6d85ae1ed1cd7e947dd6587fb8d40832875 Mon Sep 17 00:00:00 2001 +From: xCAT Genesis Builder +Date: Wed, 5 Aug 2026 18:46:00 -0300 +Subject: [PATCH] configure: avoid host ncurses-config + +The library and header checks already use the configured compiler and sysroot. +Calling ncurses-config can add flags from the build host to a cross build. + +Upstream-Status: Inappropriate [cross-compile specific] +Signed-off-by: xCAT Genesis Builder +--- + configure.ac | 13 ------------- + 1 file changed, 13 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 56ee054..2095638 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -137,13 +136,0 @@ +-ncurses_config=$(which ncurses5-config 2> /dev/null) +-if ! test -n ${ncurses_config}; then +- ncurses_config=$(which ncurses6-config 2> /dev/null) +-fi +- +-if test -n ${ncurses_config}; then +- ncurses_include="$(${ncurses_config} --cflags)" +- +- if test -n "${ncurses_include}"; then +- CFLAGS="${CFLAGS} ${ncurses_include}" +- fi +-fi +- diff --git a/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-support/iprutils/iprutils_2.4.19.bb b/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-support/iprutils/iprutils_2.4.19.bb new file mode 100644 index 000000000..732360b30 --- /dev/null +++ b/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-support/iprutils/iprutils_2.4.19.bb @@ -0,0 +1,18 @@ +SUMMARY = "IBM Power RAID adapter utilities" +HOMEPAGE = "https://github.com/bjking1/iprutils" +LICENSE = "CPL-1.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=921fff7eff37a36fc62a0242d67fb9b1" + +SRC_URI = "git://github.com/bjking1/iprutils.git;protocol=https;branch=master \ + file://0001-configure-avoid-host-ncurses-config.patch \ + " +SRCREV = "9961e538736a6e81f1072a926c3ad91b8513c8c1" + +DEPENDS = "ncurses zlib" +RDEPENDS:${PN} = "bash" + +inherit autotools + +EXTRA_OECONF = "--without-systemd --without-initscripts --disable-sosreport --disable-iprdumpfmt" + +COMPATIBLE_HOST = "powerpc64.*-linux" diff --git a/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-support/mstflint/files/0001-python-tools-use-libtool-objects.patch b/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-support/mstflint/files/0001-python-tools-use-libtool-objects.patch new file mode 100644 index 000000000..0198f7ab1 --- /dev/null +++ b/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-support/mstflint/files/0001-python-tools-use-libtool-objects.patch @@ -0,0 +1,53 @@ +From 7da676d05cefb7717684942f54cd492cb2c20ab7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Vin=C3=ADcius=20Ferr=C3=A3o?= +Date: Wed, 5 Aug 2026 13:39:00 -0300 +Subject: [PATCH] helper tools: use libtool objects in out-of-tree builds + +Libtool writes position-independent objects under .libs. The current wildcards +only work when another build step happens to leave objects in the build root. + +Upstream-Status: Pending +Signed-off-by: Vinícius Ferrão +--- + cmdif/Makefile.am | 2 +- + dev_mgt/Makefile.am | 2 +- + mvpd/Makefile.am | 2 +- + reg_access/Makefile.am | 2 +- + resourcetools/resourcedump_lib/src/sdk/Makefile.am | 2 +- + 5 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/cmdif/Makefile.am b/cmdif/Makefile.am +index 2cd53813..0bb866b1 100644 +--- a/cmdif/Makefile.am ++++ b/cmdif/Makefile.am +@@ -56 +56 @@ ${CCMDIF_SO}: libcmdif.la +- $(CC) -g -Wall -pthread -shared ${CFLAGS} ${LDFLAGS} *.o -o ${CCMDIF_SO} \ ++ $(CC) -g -Wall -pthread -shared ${CFLAGS} ${LDFLAGS} .libs/*.o -o ${CCMDIF_SO} \ +diff --git a/dev_mgt/Makefile.am b/dev_mgt/Makefile.am +index 9d6c2131..c50b8ee8 100644 +--- a/dev_mgt/Makefile.am ++++ b/dev_mgt/Makefile.am +@@ -55 +55 @@ c_dev_mgt.so: libdev_mgt.la +- $(CC) -g -Wall -pthread -shared ${CFLAGS} ${LDFLAGS} tools_dev_types.o -o c_dev_mgt.so \ ++ $(CC) -g -Wall -pthread -shared ${CFLAGS} ${LDFLAGS} .libs/tools_dev_types.o -o c_dev_mgt.so \ +diff --git a/mvpd/Makefile.am b/mvpd/Makefile.am +index 9c5257d0..4ec19f2c 100644 +--- a/mvpd/Makefile.am ++++ b/mvpd/Makefile.am +@@ -49 +49 @@ ${RMVPD_SO}: libmvpd.la +- $(CC) -g -Wall -pthread -shared ${CFLAGS} *.o -o ${RMVPD_SO} \ ++ $(CC) -g -Wall -pthread -shared ${CFLAGS} .libs/*.o -o ${RMVPD_SO} \ +diff --git a/reg_access/Makefile.am b/reg_access/Makefile.am +index 4e7cd246..990e2b12 100644 +--- a/reg_access/Makefile.am ++++ b/reg_access/Makefile.am +@@ -63 +63 @@ ${RREG_ACCESS_SO}: libreg_access.la +- $(CC) -g -Wall -pthread -shared ${CFLAGS} ${LDFLAGS} *.o -o ${RREG_ACCESS_SO} \ ++ $(CC) -g -Wall -pthread -shared ${CFLAGS} ${LDFLAGS} .libs/*.o -o ${RREG_ACCESS_SO} \ +diff --git a/resourcetools/resourcedump_lib/src/sdk/Makefile.am b/resourcetools/resourcedump_lib/src/sdk/Makefile.am +index 8f34534e..4afe39ad 100644 +--- a/resourcetools/resourcedump_lib/src/sdk/Makefile.am ++++ b/resourcetools/resourcedump_lib/src/sdk/Makefile.am +@@ -89 +89 @@ libresource_dump_sdk.so: libresource_dump_sdk.la +- $(CC) -Wall -pthread -shared ${CFLAGS} ${LDFLAGS} $(COMPILER_FPIC) libresource_dump_sdk_la-resource_dump_sdk.o \ ++ $(CC) -Wall -pthread -shared ${CFLAGS} ${LDFLAGS} $(COMPILER_FPIC) .libs/libresource_dump_sdk_la-resource_dump_sdk.o \ diff --git a/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-support/mstflint/mstflint_4.36.0.bb b/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-support/mstflint/mstflint_4.36.0.bb new file mode 100644 index 000000000..4cf28a60e --- /dev/null +++ b/xCAT-genesis-builder/oe/meta-xcat-genesis/recipes-support/mstflint/mstflint_4.36.0.bb @@ -0,0 +1,37 @@ +SUMMARY = "Firmware tools for NVIDIA and Mellanox network adapters" +HOMEPAGE = "https://github.com/Mellanox/mstflint" +LICENSE = "Linux-OpenIB & MIT & BSD-2-Clause" +LIC_FILES_CHKSUM = "\ + file://LICENSE;md5=79e20039679d6414176a6a04804e40be \ + file://ext_libs/json/LICENSE;md5=b3fc92db0084f98e349b55033958325e \ + file://ext_libs/muparser/muParser.h;beginline=1;endline=27;md5=2d47adf7e1fcdedc5cc8bc4a7292bd09 \ +" + +SRC_URI = "\ + git://github.com/Mellanox/mstflint.git;protocol=https;branch=master \ + file://0001-python-tools-use-libtool-objects.patch \ +" +SRCREV = "b9d9e844a14ae1c85cb90c76ccd4a56a0eccd599" + +inherit autotools pkgconfig + +DEPENDS = "sqlite3" +RDEPENDS:${PN} = "python3-modules" + +PACKAGECONFIG ??= "adb cables dc inband openssl" +PACKAGECONFIG[adb] = "--enable-adb-generic-tools,--disable-adb-generic-tools,expat xz" +PACKAGECONFIG[cables] = "--enable-cables,--disable-cables" +PACKAGECONFIG[dc] = "--enable-dc,--disable-dc,zlib" +PACKAGECONFIG[inband] = "--enable-inband,--disable-inband,rdma-core" +PACKAGECONFIG[openssl] = "--enable-openssl,--disable-openssl,openssl" +PACKAGECONFIG[rdmem] = "--enable-rdmem,--disable-rdmem,rdma-core" + +EXTRA_OECONF = "\ + --disable-dpa \ + --disable-fw-mgr \ + --disable-i2c \ + --disable-nvfwreset \ + --disable-nvml \ + --disable-vfio \ + --disable-xml2 \ +"