#!/bin/sh # This is run by the administrator from outside the cluster to install # or uninstall the overrides. # # Note: The administrator may run this on a system without bash, or on # OS X, so it needs to be portable. set -e function usage() { exec 1>&2 echo "Usage: $0 [--workers-only] [--no-reboot] OVERRIDE-IMAGE" echo "" echo "This will install or uninstall the overrides from OVERRIDE-IMAGE." echo "" echo "If --workers-only is passed, then the master nodes will not be touched." echo "If --no-reboot is passed, the machines will not be rebooted (and thus" echo "the installation will not be complete)." } while [ -n "$*" ]; do case "$1" in install|uninstall) action=$1 shift ;; --workers-only|--worker-only) workers_only=true # "workers-only" really means "not masters". (eg, it includes infra nodes) node_affinity="affinity: { nodeAffinity: { requiredDuringSchedulingIgnoredDuringExecution: { nodeSelectorTerms: [ { matchExpressions: [ { key: node-role.kubernetes.io/master, operator: DoesNotExist } ] } ] } } }" node_filter="-l node-role.kubernetes.io/master!=" shift ;; --no-reboot) no_reboot=true shift ;; */*:*) image=$1 tag=$(echo "${image}" | sed -e 's/.*://') shift ;; *) usage exit 1 ;; esac done if [ -z "${action}" ] || [ -z "${image}" ]; then usage exit 1 fi clustername=$(oc get infrastructure cluster -o jsonpath='{.status.infrastructureName}' 2>/dev/null || /bin/true) version=$(oc get clusterversion version -o jsonpath='{.status.desired.version}' 2>/dev/null || /bin/true) if [ -z "${clustername}" ] || [ -z "${version}" ]; then exec 1>&2 echo "Unable to fetch cluster information. Do you need to set KUBECONFIG?" echo "" echo "$ oc get clusterversion" oc get clusterversion # not expected to be reached due to "set -e", but... exit 1 fi # FIXME: double-check version against the override... echo "${action}ing overrides from '${image}' in cluster '${clustername}' at version '${version}'" echo "" namespace="openshift-overrides-${tag}" oc create namespace "${namespace}" oc create serviceaccount -n "${namespace}" overrides oc adm policy add-scc-to-user privileged -n "${namespace}" -z overrides oc create -f - <&2 echo "Pod ${pod} failed:" echo "" oc logs -n "${namespace}" "${pod}" exit 1 ;; esac done if [ "${num_success}" = "${num_nodes}" ]; then break fi echo "${num_success} of ${num_nodes} nodes have staged the changes... Waiting..." done if [ "${num_success}" != "${num_nodes}" ]; then exec 1>&2 echo "Timed out waiting for all nodes to stage changes." exit 1 fi echo "All nodes have staged the changes." echo "" oc delete daemonset -n "${namespace}" overrides oc delete namespace "${namespace}" function reboot_nodes() { role="$1" old_generation=$(oc get machineconfigpool "${role}" -o jsonpath="{.status.observedGeneration}") echo "" if [ "${action}" = "install" ]; then echo "Creating override MachineConfig for ${role} nodes" # The base64-encoded message is: # # The presence of this file indicates that RPM overrides have been applied # to this host. Note that removing the MachineConfig that created this # file will not cause the RPM overrides to be removed. oc create -f - <&2 echo "MachineConfigPool '${role}' is not updating" exit 1 fi num=$(oc get machineconfigpool "${role}" -o jsonpath="{.status.machineCount}") echo "Waiting for the ${role} MachineConfigPool to update all nodes. (This will take several minutes per node.)" while :; do sleep 10 updated=$(oc get machineconfigpool "${role}" -o jsonpath="{.status.updatedMachineCount}") echo "${updated}/${num} nodes updated..." if [ "${updated}" = "${num}" ]; then break fi done } if [ "{no_reboot}" = "true" ]; then echo "(Skipping reboot)" else # Install dummy MachineConfig(s) to force reboots. reboot_nodes worker if [ "${workers_only}" != "true" ]; then reboot_nodes master fi fi echo "" echo "Overrides installed."