Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move arch validation logic outside of OS upgrade script #55

Merged
merged 5 commits into from
Aug 21, 2024
Merged
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
35 changes: 29 additions & 6 deletions api/v1alpha1/releasemanifest_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,16 @@ limitations under the License.
package v1alpha1

import (
"fmt"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

const (
ArchTypeX86 Arch = "x86_64"
ArchTypeARM Arch = "aarch64"
)

// ReleaseManifestSpec defines the desired state of ReleaseManifest
type ReleaseManifestSpec struct {
ReleaseVersion string `json:"releaseVersion"`
Expand Down Expand Up @@ -65,12 +72,28 @@ type KubernetesDistribution struct {
}

type OperatingSystem struct {
Version string `json:"version"`
ZypperID string `json:"zypperID"`
CPEScheme string `json:"cpeScheme"`
RepoGPGPath string `json:"repoGPGPath"`
SupportedArchs []string `json:"supportedArchs"`
PrettyName string `json:"prettyName"`
Version string `json:"version"`
ZypperID string `json:"zypperID"`
CPEScheme string `json:"cpeScheme"`
RepoGPGPath string `json:"repoGPGPath"`
// +kubebuilder:validation:MinItems=1
SupportedArchs []Arch `json:"supportedArchs"`
PrettyName string `json:"prettyName"`
}

// +kubebuilder:validation:Enum=x86_64;aarch64
type Arch string

func (a Arch) Short() string {
switch a {
case ArchTypeX86:
return "amd64"
case ArchTypeARM:
return "arm64"
default:
message := fmt.Sprintf("unknown arch: %s", a)
panic(message)
}
}

// +kubebuilder:object:root=true
Expand Down
2 changes: 1 addition & 1 deletion api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions config/crd/bases/lifecycle.suse.com_releasemanifests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,11 @@ spec:
type: string
supportedArchs:
items:
enum:
- x86_64
- aarch64
type: string
minItems: 1
type: array
version:
type: string
Expand Down
35 changes: 30 additions & 5 deletions internal/controller/reconcile_os.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ import (
func (r *UpgradePlanReconciler) reconcileOS(ctx context.Context, upgradePlan *lifecyclev1alpha1.UpgradePlan, releaseVersion string, releaseOS *lifecyclev1alpha1.OperatingSystem) (ctrl.Result, error) {
identifierAnnotations := upgrade.PlanIdentifierAnnotations(upgradePlan.Name, upgradePlan.Namespace)

nodeList := &corev1.NodeList{}
if err := r.List(ctx, nodeList); err != nil {
return ctrl.Result{}, fmt.Errorf("listing nodes: %w", err)
}

if err := validateOSArch(nodeList, releaseOS.SupportedArchs); err != nil {
setFailedCondition(upgradePlan, lifecyclev1alpha1.OperatingSystemUpgradedCondition, "Cluster nodes are running unsupported architectures")
return ctrl.Result{}, fmt.Errorf("validating cluster node OS architecture: %w", err)
}

secret, err := upgrade.OSUpgradeSecret(releaseOS, identifierAnnotations)
if err != nil {
return ctrl.Result{}, fmt.Errorf("generating OS upgrade secret: %w", err)
Expand Down Expand Up @@ -47,11 +57,6 @@ func (r *UpgradePlanReconciler) reconcileOS(ctx context.Context, upgradePlan *li
return ctrl.Result{}, fmt.Errorf("parsing node selector: %w", err)
}

nodeList := &corev1.NodeList{}
if err := r.List(ctx, nodeList); err != nil {
return ctrl.Result{}, fmt.Errorf("listing nodes: %w", err)
}

if !isOSUpgraded(nodeList, selector, releaseOS.PrettyName) {
setInProgressCondition(upgradePlan, lifecyclev1alpha1.OperatingSystemUpgradedCondition, "Control plane nodes are being upgraded")
return ctrl.Result{RequeueAfter: 1 * time.Minute}, nil
Expand Down Expand Up @@ -109,3 +114,23 @@ func isOSUpgraded(nodeList *corev1.NodeList, selector labels.Selector, osPrettyN

return true
}

func validateOSArch(nodeList *corev1.NodeList, supportedArchs []lifecyclev1alpha1.Arch) error {
supportedArchMap := map[string]bool{}
for _, arch := range supportedArchs {
// add both the long and short architecture name
// to avoid any future problems related to changing
// what 'node.Status.NodeInfo.Architecture' outputs
supportedArchMap[string(arch)] = true
supportedArchMap[arch.Short()] = true
}

for _, node := range nodeList.Items {
nodeArch := node.Status.NodeInfo.Architecture
if _, ok := supportedArchMap[nodeArch]; !ok {
return fmt.Errorf("unsuported arch '%s' for '%s' node. Supported archs: %s", nodeArch, node.Name, supportedArchs)
ipetrov117 marked this conversation as resolved.
Show resolved Hide resolved
}
}

return nil
}
18 changes: 8 additions & 10 deletions internal/upgrade/os.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,15 @@ func OSUpgradeSecret(releaseOS *lifecyclev1alpha1.OperatingSystem, annotations m
}

values := struct {
CPEScheme string
RepoGPGKey string
ZypperID string
Version string
SupportedArchs []string
CPEScheme string
RepoGPGKey string
ZypperID string
Version string
}{
CPEScheme: releaseOS.CPEScheme,
RepoGPGKey: releaseOS.RepoGPGPath,
ZypperID: releaseOS.ZypperID,
Version: releaseOS.Version,
SupportedArchs: releaseOS.SupportedArchs,
CPEScheme: releaseOS.CPEScheme,
RepoGPGKey: releaseOS.RepoGPGPath,
ZypperID: releaseOS.ZypperID,
Version: releaseOS.Version,
}

var buff bytes.Buffer
Expand Down
16 changes: 0 additions & 16 deletions internal/upgrade/templates/os-upgrade.sh.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,7 @@ executeUpgrade(){
# Common Platform Enumeration (CPE) that the system is currently running with
CURRENT_CPE=`cat /etc/os-release | grep -w CPE_NAME | cut -d "=" -f 2 | tr -d '"'`

# Determine whether architecture is supported
SYSTEM_ARCH=`arch`
IFS=' ' read -r -a SUPPORTED_ARCH_ARRAY <<< $(echo "{{.SupportedArchs}}" | tr -d '[]')

found=false
for arch in "${SUPPORTED_ARCH_ARRAY[@]}"; do
if [ "${SYSTEM_ARCH}" == ${arch} ]; then
found=true
break
fi
done

if [ ${found} == false ]; then
echo "Operating system is running an unsupported architecture. System arch: ${SYSTEM_ARCH}. Supported archs: ${SUPPORTED_ARCH_ARRAY[*]}"
exit 1
fi

# Lines that will be appended to the systemd.service 'ExecStartPre' configuration
EXEC_START_PRE_LINES=""

Expand Down