Skip to content

Instantly share code, notes, and snippets.

@zdtsw
Created October 6, 2025 15:21
Show Gist options
  • Select an option

  • Save zdtsw/0c6cae114abb3506db58432c0e18ae3e to your computer and use it in GitHub Desktop.

Select an option

Save zdtsw/0c6cae114abb3506db58432c0e18ae3e to your computer and use it in GitHub Desktop.
workaround for 35532
#!/bin/bash
# usage: ./inject-hwprofile.sh <profile-name> <profile-namespace> <isvc-name> <isvc-namespace>
# This script manually injects HardwareProfile nodeSelector and tolerations into an InferenceService at the correct path.
set -e
HARDWARE_PROFILE_NAME="${1:-default-profile}"
HARDWARE_PROFILE_NAMESPACE="${2:-opendatahub}"
ISVC_NAME="${3:-isvc}"
ISVC_NAMESPACE="${4:-opendatahub}"
echo "========================================="
echo "Reading HardwareProfile from cluster"
echo "========================================="
echo "Profile: ${HARDWARE_PROFILE_NAME}"
echo "Profile Namespace: ${HARDWARE_PROFILE_NAMESPACE}"
echo ""
# Extract nodeSelector from HardwareProfile
NODE_SELECTOR=$(kubectl get hardwareprofile "${HARDWARE_PROFILE_NAME}" -n "${HARDWARE_PROFILE_NAMESPACE}" \
-o jsonpath='{.spec.schedulingSpec.node.nodeSelector}')
# Extract tolerations from HardwareProfile
TOLERATIONS=$(kubectl get hardwareprofile "${HARDWARE_PROFILE_NAME}" -n "${HARDWARE_PROFILE_NAMESPACE}" \
-o jsonpath='{.spec.schedulingSpec.node.tolerations}')
# Extract identifiers (resources) from HardwareProfile
IDENTIFIERS=$(kubectl get hardwareprofile "${HARDWARE_PROFILE_NAME}" -n "${HARDWARE_PROFILE_NAMESPACE}" \
-o jsonpath='{.spec.identifiers}')
echo "Found nodeSelector: ${NODE_SELECTOR}"
echo "Found tolerations: ${TOLERATIONS}"
echo "Found identifiers: ${IDENTIFIERS}"
echo ""
echo "========================================="
echo "Patching InferenceService"
echo "========================================="
echo "InferenceService: ${ISVC_NAME}"
echo "InferenceService Namespace: ${ISVC_NAMESPACE}"
echo ""
# Build the patch JSON for nodeSelector
if [ -n "${NODE_SELECTOR}" ] && [ "${NODE_SELECTOR}" != "{}" ]; then
echo "Injecting nodeSelector into spec.predictor.nodeSelector..."
kubectl patch inferenceservice "${ISVC_NAME}" -n "${ISVC_NAMESPACE}" --type=merge -p "{\"spec\":{\"predictor\":{\"nodeSelector\":${NODE_SELECTOR}}}}"
echo "✓ nodeSelector injected"
fi
# Build the patch JSON for tolerations
if [ -n "${TOLERATIONS}" ] && [ "${TOLERATIONS}" != "null" ]; then
echo "Injecting tolerations into spec.predictor.tolerations..."
kubectl patch inferenceservice "${ISVC_NAME}" -n "${ISVC_NAMESPACE}" --type=merge -p "{\"spec\":{\"predictor\":{\"tolerations\":${TOLERATIONS}}}}"
echo "✓ tolerations injected"
fi
# Build the patch JSON for resources (from identifiers)
if [ -n "${IDENTIFIERS}" ] && [ "${IDENTIFIERS}" != "null" ]; then
echo "Building resources from identifiers..."
# Parse identifiers and build resources object
RESOURCES=$(kubectl get hardwareprofile "${HARDWARE_PROFILE_NAME}" -n "${HARDWARE_PROFILE_NAMESPACE}" -o jsonpath='{range .spec.identifiers[*]}{"\"resources\":{\"requests\":{\"" + .identifier + "\":\"" + .defaultCount + "\"}"}}{end}')
# For InferenceService, inject into spec.predictor.model.resources
echo "Injecting resources into spec.predictor.model.resources..."
# Build a proper resources patch from identifiers
cat > /tmp/resources-patch.json <<EOF
{
"spec": {
"predictor": {
"model": {
"resources": {
"requests": {
EOF
# Add each identifier as a resource request
kubectl get hardwareprofile "${HARDWARE_PROFILE_NAME}" -n "${HARDWARE_PROFILE_NAMESPACE}" \
-o json | jq -r '.spec.identifiers[] | " \"" + .identifier + "\": \"" + (.defaultCount | tostring) + "\","' >> /tmp/resources-patch.json
# Remove trailing comma and close JSON
sed -i '$ s/,$//' /tmp/resources-patch.json
cat >> /tmp/resources-patch.json <<EOF
},
"limits": {
EOF
# Add limits if maxCount is specified
kubectl get hardwareprofile "${HARDWARE_PROFILE_NAME}" -n "${HARDWARE_PROFILE_NAMESPACE}" \
-o json | jq -r '.spec.identifiers[] | select(.maxCount != null) | " \"" + .identifier + "\": \"" + (.maxCount | tostring) + "\","' >> /tmp/resources-patch.json
# Remove trailing comma and close JSON
sed -i '$ s/,$//' /tmp/resources-patch.json
cat >> /tmp/resources-patch.json <<EOF
}
}
}
}
}
}
EOF
kubectl patch inferenceservice "${ISVC_NAME}" -n "${ISVC_NAMESPACE}" --type=merge -p "$(cat /tmp/resources-patch.json)"
echo "✓ resources injected"
rm /tmp/resources-patch.json
fi
echo ""
echo "========================================="
echo "Verifying injection"
echo "========================================="
echo ""
kubectl get inferenceservice "${ISVC_NAME}" -n "${ISVC_NAMESPACE}" -o yaml
echo ""
echo "========================================="
echo "Summary"
echo "========================================="
echo "Manually injected into InferenceService:"
echo "1. nodeSelector → spec.predictor.nodeSelector"
echo "2. tolerations → spec.predictor.tolerations"
echo "3. resources → spec.predictor.model.resources"
echo ""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment