diff --git a/Makefile b/Makefile index 0a1099a3..e2c97b20 100644 --- a/Makefile +++ b/Makefile @@ -68,10 +68,11 @@ UPGRADE=upgrade # Specify the name of the docker repo for amd64 UPGRADE_REPO_NAME_AMD64="upgrade-amd64" -M_MIGRATE_REPO_NAME?=migrate +MIGRATE_REPO_NAME_AMD64="migrate-amd64" # Specify the name of the docker repo for arm64 UPGRADE_REPO_NAME_ARM64="upgrade-arm64" +MIGRATE_REPO_NAME_ARM64="migrate-arm64" # build upgrade binary .PHONY: upgrade diff --git a/build/migrate/Dockerfile b/build/migrate/Dockerfile index 04254c9c..848a42d1 100644 --- a/build/migrate/Dockerfile +++ b/build/migrate/Dockerfile @@ -3,18 +3,20 @@ # its latest binary # -FROM alpine:3.9 +FROM alpine:3.11.5 # copy the latest binary COPY migrate /usr/local/bin/migrate -ARG BUILD_DATE - +ARG ARCH +ARG DBUILD_DATE +ARG DBUILD_REPO_URL +ARG DBUILD_SITE_URL LABEL org.label-schema.name="migrate" LABEL org.label-schema.description="migrates openebs components" -LABEL org.label-schema.url="https://openebs.io/" -LABEL org.label-schema.vcs-url="https://github.com/openebs/upgrade" LABEL org.label-schema.schema-version="1.0" -LABEL org.label-schema.build-date=$BUILD_DATE +LABEL org.label-schema.build-date=$DBUILD_DATE +LABEL org.label-schema.vcs-url=$DBUILD_REPO_URL +LABEL org.label-schema.url=$DBUILD_SITE_URL ENTRYPOINT ["migrate"] diff --git a/build/migrate/Makefile.mk b/build/migrate/Makefile.mk index 30683c99..e9062f31 100644 --- a/build/migrate/Makefile.mk +++ b/build/migrate/Makefile.mk @@ -15,15 +15,27 @@ migrate: @PNAME=${MIGRATE} CTLNAME=${MIGRATE} CGO_ENABLED=0 sh -c "'$(PWD)/build/build.sh'" # build migrate image -.PHONY: migrate-image -migrate-image: migrate +.PHONY: migrate-image.amd64 +migrate-image.amd64: migrate @echo "-----------------------------------------------" @echo "--> ${MIGRATE} image " - @echo "${HUB_USER}/${M_MIGRATE_REPO_NAME}:${IMAGE_TAG}" + @echo "${HUB_USER}/${MIGRATE_REPO_NAME_AMD64}:${IMAGE_TAG}" @echo "-----------------------------------------------" @cp bin/${MIGRATE}/${MIGRATE} build/${MIGRATE}/ @cd build/${MIGRATE} && \ - sudo docker build -t "${HUB_USER}/${M_MIGRATE_REPO_NAME}:${IMAGE_TAG}" --build-arg BUILD_DATE=${BUILD_DATE} . + sudo docker build -t "${HUB_USER}/${MIGRATE_REPO_NAME_AMD64}:${IMAGE_TAG}" ${DBUILD_ARGS} . + @rm build/${MIGRATE}/${MIGRATE} + +# build migrate image +.PHONY: migrate-image.arm64 +migrate-image.arm64: migrate + @echo "-----------------------------------------------" + @echo "--> ${MIGRATE} image " + @echo "${HUB_USER}/${MIGRATE_REPO_NAME_ARM64}:${IMAGE_TAG}" + @echo "-----------------------------------------------" + @cp bin/${MIGRATE}/${MIGRATE} build/${MIGRATE}/ + @cd build/${MIGRATE} && \ + sudo docker build -t "${HUB_USER}/${MIGRATE_REPO_NAME_ARM64}:${IMAGE_TAG}" ${DBUILD_ARGS} . @rm build/${MIGRATE}/${MIGRATE} # cleanup migrate build diff --git a/cmd/migrate/executor/options.go b/cmd/migrate/executor/options.go index a5ebdd74..5d90663d 100644 --- a/cmd/migrate/executor/options.go +++ b/cmd/migrate/executor/options.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The OpenEBS Authors. +Copyright 2020 The OpenEBS Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -20,11 +20,10 @@ import ( "strings" errors "github.com/pkg/errors" - - "github.com/spf13/cobra" ) -// MigrateOptions stores information required for migrate +// MigrateOptions stores information required for migration of +// OpenEBS resources type MigrateOptions struct { openebsNamespace string spcName string @@ -37,9 +36,9 @@ var ( ) // RunPreFlightChecks will ensure the sanity of the common migrate options -func (u *MigrateOptions) RunPreFlightChecks(cmd *cobra.Command) error { - if len(strings.TrimSpace(u.openebsNamespace)) == 0 { - return errors.Errorf("Cannot execute migrate job: namespace is missing") +func (m *MigrateOptions) RunPreFlightChecks() error { + if len(strings.TrimSpace(m.openebsNamespace)) == 0 { + return errors.Errorf("Cannot execute migrate job: openebs namespace is missing") } return nil } diff --git a/cmd/migrate/executor/pool.go b/cmd/migrate/executor/pool.go index 4cf0aee8..874e8442 100644 --- a/cmd/migrate/executor/pool.go +++ b/cmd/migrate/executor/pool.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The OpenEBS Authors. +Copyright 2020 The OpenEBS Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -44,9 +44,9 @@ func NewMigratePoolJob() *cobra.Command { Long: cstorSPCMigrateCmdHelpText, Example: `migrate cstor-spc --spc-name `, Run: func(cmd *cobra.Command, args []string) { - util.CheckErr(options.RunPreFlightChecks(cmd), util.Fatal) - util.CheckErr(options.RunCStorSPCMigrateChecks(cmd), util.Fatal) - util.CheckErr(options.RunCStorSPCMigrate(cmd), util.Fatal) + util.CheckErr(options.RunPreFlightChecks(), util.Fatal) + util.CheckErr(options.RunCStorSPCMigrateChecks(), util.Fatal) + util.CheckErr(options.RunCStorSPCMigrate(), util.Fatal) }, } @@ -59,8 +59,8 @@ func NewMigratePoolJob() *cobra.Command { } // RunCStorSPCMigrateChecks will ensure the sanity of the cstor SPC migrate options -func (u *MigrateOptions) RunCStorSPCMigrateChecks(cmd *cobra.Command) error { - if len(strings.TrimSpace(u.spcName)) == 0 { +func (m *MigrateOptions) RunCStorSPCMigrateChecks() error { + if len(strings.TrimSpace(m.spcName)) == 0 { return errors.Errorf("Cannot execute migrate job: cstor spc name is missing") } @@ -68,16 +68,16 @@ func (u *MigrateOptions) RunCStorSPCMigrateChecks(cmd *cobra.Command) error { } // RunCStorSPCMigrate migrates the given spc. -func (u *MigrateOptions) RunCStorSPCMigrate(cmd *cobra.Command) error { +func (m *MigrateOptions) RunCStorSPCMigrate() error { - klog.Infof("Migrating spc %s to cspc", u.spcName) + klog.Infof("Migrating spc %s to cspc", m.spcName) migrator := cstor.CSPCMigrator{} - err := migrator.Migrate(u.spcName, u.openebsNamespace) + err := migrator.Migrate(m.spcName, m.openebsNamespace) if err != nil { klog.Error(err) - return errors.Errorf("Failed to migrate cStor SPC : %s", u.spcName) + return errors.Errorf("Failed to migrate cStor SPC : %s", m.spcName) } - klog.Infof("Successfully migrated spc %s to cspc", u.spcName) + klog.Infof("Successfully migrated spc %s to cspc", m.spcName) return nil } diff --git a/cmd/migrate/executor/setup_job.go b/cmd/migrate/executor/setup_job.go index 9891d27d..4e94691d 100644 --- a/cmd/migrate/executor/setup_job.go +++ b/cmd/migrate/executor/setup_job.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The OpenEBS Authors. +Copyright 2020 The OpenEBS Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/cmd/migrate/main.go b/cmd/migrate/main.go index 978884aa..d4ec9690 100644 --- a/cmd/migrate/main.go +++ b/cmd/migrate/main.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The OpenEBS Authors. +Copyright 2020 The OpenEBS Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/cmd/util/env.go b/cmd/util/env.go index 68a37c98..822005df 100644 --- a/cmd/util/env.go +++ b/cmd/util/env.go @@ -17,14 +17,15 @@ limitations under the License. package util import ( - menv "github.com/openebs/maya/pkg/env/v1alpha1" + "os" ) -//This file defines the environement variable names that are specific -// to this provisioner. In addition to the variables defined in this file, -// provisioner also uses the following: -// OPENEBS_NAMESPACE +const ( + openebsNamespaceEnv = "OPENEBS_NAMESPACE" +) +// GetOpenEBSNamespace gets the openebs namespace set to +// the OPENEBS_NAMESPACE env func GetOpenEBSNamespace() string { - return menv.Get(menv.OpenEBSNamespace) + return os.Getenv(openebsNamespaceEnv) } diff --git a/pkg/migrate/cstor/cspc_generator.go b/pkg/migrate/cstor/cspc_generator.go index 0c14a487..a4cb92b1 100644 --- a/pkg/migrate/cstor/cspc_generator.go +++ b/pkg/migrate/cstor/cspc_generator.go @@ -41,9 +41,21 @@ var ( } ) -func getBDList(cspObj apis.CStorPool) []cstor.CStorPoolInstanceBlockDevice { +func getDataRaidGroups(cspObj apis.CStorPool) []cstor.RaidGroup { + dataRaidGroups := []cstor.RaidGroup{} + for _, rg := range cspObj.Spec.Group { + dataRaidGroups = append(dataRaidGroups, + cstor.RaidGroup{ + CStorPoolInstanceBlockDevices: getBDList(rg), + }, + ) + } + return dataRaidGroups +} + +func getBDList(rg apis.BlockDeviceGroup) []cstor.CStorPoolInstanceBlockDevice { list := []cstor.CStorPoolInstanceBlockDevice{} - for _, bdcObj := range cspObj.Spec.Group[0].Item { + for _, bdcObj := range rg.Item { list = append(list, cstor.CStorPoolInstanceBlockDevice{ BlockDeviceName: bdcObj.Name, @@ -83,11 +95,7 @@ func (c *CSPCMigrator) getCSPCSpecForSPC() (*cstor.CStorPoolCluster, error) { NodeSelector: map[string]string{ types.HostNameLabelKey: cspObj.Labels[string(apis.HostNameCPK)], }, - DataRaidGroups: []cstor.RaidGroup{ - { - CStorPoolInstanceBlockDevices: getBDList(cspObj), - }, - }, + DataRaidGroups: getDataRaidGroups(cspObj), PoolConfig: cstor.PoolConfig{ DataRaidGroupType: typeMap[cspObj.Spec.PoolSpec.PoolType], ThickProvision: cspObj.Spec.PoolSpec.ThickProvisioning, diff --git a/pkg/migrate/cstor/pool.go b/pkg/migrate/cstor/pool.go index c954da56..691bcdb2 100644 --- a/pkg/migrate/cstor/pool.go +++ b/pkg/migrate/cstor/pool.go @@ -18,6 +18,7 @@ package migrate import ( "fmt" + "strings" "time" "k8s.io/client-go/kubernetes" @@ -80,10 +81,36 @@ func (c *CSPCMigrator) Migrate(name, namespace string) error { if err != nil { return errors.Wrap(err, "error building openebs clientset") } + err = c.validateCSPCOperator() + if err != nil { + return err + } err = c.migrate(name) return err } +func (c *CSPCMigrator) validateCSPCOperator() error { + operatorPods, err := c.KubeClientset.CoreV1(). + Pods(c.OpenebsNamespace). + List(metav1.ListOptions{ + LabelSelector: "openebs.io/component-name=cspc-operator", + }) + if err != nil { + return err + } + if len(operatorPods.Items) == 0 { + return fmt.Errorf("cspc operator pod missing") + } + for _, pod := range operatorPods.Items { + operatorVersion := strings.Split(pod.Labels["openebs.io/version"], "-")[0] + if operatorVersion != "1.11.0" { + return fmt.Errorf("cspc operator is in %s version, please upgrade it to 1.11.0 or above version", + pod.Labels["openebs.io/version"]) + } + } + return nil +} + // Pool migrates the pool from SPC schema to CSPC schema func (c *CSPCMigrator) migrate(spcName string) error { var err error @@ -98,11 +125,11 @@ func (c *CSPCMigrator) migrate(spcName string) error { } err = c.validateSPC() if err != nil { - return err + return errors.Wrapf(err, "failed to validate spc %s", spcName) } err = c.updateBDCLabels(spcName) if err != nil { - return err + return errors.Wrapf(err, "failed to update bdc labels for spc %s", spcName) } klog.Infof("Creating equivalent cspc for spc %s", spcName) c.CSPCObj, err = c.generateCSPC() @@ -130,11 +157,9 @@ func (c *CSPCMigrator) migrate(spcName string) error { // which implies the migration is done and makes it idempotent cspiItem := cspiItem // pin it cspiObj := &cspiItem - if cspiObj.Status.Phase != "ONLINE" { - err = c.csptocspi(cspiObj) - if err != nil { - return err - } + err = c.cspTocspi(cspiObj) + if err != nil { + return err } } // Clean up old SPC resources after the migration is complete @@ -172,8 +197,10 @@ func (c *CSPCMigrator) validateSPC() error { bdMap[bdName]++ } for _, cspObj := range cspList.Items { - for _, bdObj := range cspObj.Spec.Group[0].Item { - bdMap[bdObj.Name]++ + for _, rg := range cspObj.Spec.Group { + for _, bdObj := range rg.Item { + bdMap[bdObj.Name]++ + } } } for bdName, count := range bdMap { @@ -210,34 +237,37 @@ func (c *CSPCMigrator) getSPCWithMigrationStatus(spcName string) (*apis.StorageP } // csptocspi migrates a CSP to CSPI based on hostname -func (c *CSPCMigrator) csptocspi(cspiObj *cstor.CStorPoolInstance) error { +func (c *CSPCMigrator) cspTocspi(cspiObj *cstor.CStorPoolInstance) error { + var err1 error hostnameLabel := types.HostNameLabelKey + "=" + cspiObj.Labels[types.HostNameLabelKey] spcLabel := string(apis.StoragePoolClaimCPK) + "=" + c.CSPCObj.Name cspLabel := hostnameLabel + "," + spcLabel - var err1 error cspObj, err := getCSP(cspLabel) if err != nil { return err } - klog.Infof("Migrating csp %s to cspi %s", cspiObj.Name, cspObj.Name) - err = c.scaleDownDeployment(cspObj, c.OpenebsNamespace) - if err != nil { - return err - } - // once the old pool pod is scaled down and bdcs are patched - // bring up the cspi pod so that the old pool can be renamed and imported. - cspiObj.Annotations[types.OldPoolName] = "cstor-" + string(cspObj.UID) - delete(cspiObj.Annotations, types.OpenEBSDisableReconcileLabelKey) - cspiObj, err = c.OpenebsClientset.CstorV1(). - CStorPoolInstances(c.OpenebsNamespace). - Update(cspiObj) - if err != nil { - return err + if cspiObj.Annotations[types.OpenEBSDisableReconcileLabelKey] != "" { + klog.Infof("Migrating csp %s to cspi %s", cspObj.Name, cspiObj.Name) + err = c.scaleDownDeployment(cspObj, c.OpenebsNamespace) + if err != nil { + return err + } + // once the old pool pod is scaled down and bdcs are patched + // bring up the cspi pod so that the old pool can be renamed and imported. + cspiObj.Annotations[types.ExistingPoolName] = "cstor-" + string(cspObj.UID) + delete(cspiObj.Annotations, types.OpenEBSDisableReconcileLabelKey) + cspiObj, err = c.OpenebsClientset.CstorV1(). + CStorPoolInstances(c.OpenebsNamespace). + Update(cspiObj) + if err != nil { + return err + } } err = retry. Times(60). Wait(5 * time.Second). Try(func(attempt uint) error { + klog.Infof("waiting for cspi %s to come to ONLINE state", cspiObj.Name) cspiObj, err1 = c.OpenebsClientset.CstorV1(). CStorPoolInstances(c.OpenebsNamespace). Get(cspiObj.Name, metav1.GetOptions{}) @@ -323,6 +353,7 @@ func (c *CSPCMigrator) scaleDownDeployment(cspObj *apis.CStorPool, openebsNamesp Times(60). Wait(5 * time.Second). Try(func(attempt uint) error { + klog.Infof("waiting for csp %s deployment to scale down", cspObj.Name) cspPods, err1 := c.KubeClientset.CoreV1(). Pods(openebsNamespace). List(metav1.ListOptions{