Skip to content

Commit

Permalink
Split the inspection scripts based on their usage
Browse files Browse the repository at this point in the history
It doesn't make sense to try to extract all the values for both
containers and hosts. This commit introduces Inspector objects that are
responsible for generating the inspection script and parsing it into a
structure.

While at it, the extracted values that were not used have been removed.
This gains quite some time at each execution since extracting the
SCC registration status was quite long.

While doing this we could also drop the InspectData proxyHost flag as
SCC credentials are extracted for both server and proxy hosts.
  • Loading branch information
cbosdo committed Jul 12, 2024
1 parent a7ba326 commit bc75baa
Show file tree
Hide file tree
Showing 18 changed files with 491 additions and 243 deletions.
6 changes: 2 additions & 4 deletions mgradm/cmd/install/podman/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,8 @@ func installForPodman(
return utils.Errorf(err, L("failed to compute image URL"))
}
pullArgs := []string{}
_, scc_user_exist := inspectedHostValues["host_scc_username"]
_, scc_user_password := inspectedHostValues["host_scc_password"]
if scc_user_exist && scc_user_password {
pullArgs = append(pullArgs, "--creds", inspectedHostValues["host_scc_username"]+":"+inspectedHostValues["host_scc_password"])
if inspectedHostValues.SccUsername != "" && inspectedHostValues.SccPassword != "" {
pullArgs = append(pullArgs, "--creds", inspectedHostValues.SccUsername+":"+inspectedHostValues.SccPassword)
}

preparedImage, err := shared_podman.PrepareImage(image, flags.Image.PullPolicy, pullArgs...)
Expand Down
2 changes: 1 addition & 1 deletion mgradm/cmd/migrate/kubernetes/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func migrateToKubernetes(
return utils.Errorf(err, L("cannot run migration"))
}

extractedData, err := adm_utils.ReadContainerData(scriptDir)
extractedData, err := utils.ReadInspectData[utils.InspectResult](path.Join(scriptDir, "data"))
if err != nil {
return utils.Errorf(err, L("cannot read data from container"))
}
Expand Down
6 changes: 2 additions & 4 deletions mgradm/cmd/migrate/podman/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,8 @@ func migrateToPodman(globalFlags *types.GlobalFlags, flags *podmanMigrateFlags,
}

pullArgs := []string{}
_, scc_user_exist := inspectedHostValues["host_scc_username"]
_, scc_user_password := inspectedHostValues["host_scc_password"]
if scc_user_exist && scc_user_password {
pullArgs = append(pullArgs, "--creds", inspectedHostValues["host_scc_username"]+":"+inspectedHostValues["host_scc_password"])
if inspectedHostValues.SccUsername != "" && inspectedHostValues.SccPassword != "" {
pullArgs = append(pullArgs, "--creds", inspectedHostValues.SccUsername+":"+inspectedHostValues.SccPassword)
}

preparedImage, err := podman_utils.PrepareImage(serverImage, flags.Image.PullPolicy, pullArgs...)
Expand Down
18 changes: 9 additions & 9 deletions mgradm/shared/kubernetes/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,8 @@ func Upgrade(
return err
}

fqdn, exist := inspectedValues["fqdn"]
if !exist {
fqdn := inspectedValues.Fqdn
if fqdn == "" {
return fmt.Errorf(L("inspect function did non return fqdn value"))
}

Expand Down Expand Up @@ -182,23 +182,23 @@ func Upgrade(
err = kubernetes.ReplicasTo(kubernetes.ServerApp, 1)
}
}()
if inspectedValues["image_pg_version"] > inspectedValues["current_pg_version"] {
if inspectedValues.ImagePgVersion > inspectedValues.CurrentPgVersion {
log.Info().Msgf(L("Previous PostgreSQL is %[1]s, new one is %[2]s. Performing a DB version upgrade…"),
inspectedValues["current_pg_version"], inspectedValues["image_pg_version"])
inspectedValues.CurrentPgVersion, inspectedValues.ImagePgVersion)

if err := RunPgsqlVersionUpgrade(*image, *upgradeImage, nodeName,
inspectedValues["current_pg_version"], inspectedValues["image_pg_version"],
inspectedValues.CurrentPgVersion, inspectedValues.ImagePgVersion,
); err != nil {
return utils.Errorf(err, L("cannot run PostgreSQL version upgrade script"))
}
} else if inspectedValues["image_pg_version"] == inspectedValues["current_pg_version"] {
log.Info().Msgf(L("Upgrading to %s without changing PostgreSQL version"), inspectedValues["uyuni_release"])
} else if inspectedValues.ImagePgVersion == inspectedValues.CurrentPgVersion {
log.Info().Msgf(L("Upgrading to %s without changing PostgreSQL version"), inspectedValues.UyuniRelease)
} else {
return fmt.Errorf(L("trying to downgrade PostgreSQL from %[1]s to %[2]s"),
inspectedValues["current_pg_version"], inspectedValues["image_pg_version"])
inspectedValues.CurrentPgVersion, inspectedValues.ImagePgVersion)
}

schemaUpdateRequired := inspectedValues["current_pg_version"] != inspectedValues["image_pg_version"]
schemaUpdateRequired := inspectedValues.CurrentPgVersion != inspectedValues.ImagePgVersion
if err := RunPgsqlFinalizeScript(serverImage, image.PullPolicy, nodeName, schemaUpdateRequired, false); err != nil {
return utils.Errorf(err, L("cannot run PostgreSQL finalize script"))
}
Expand Down
55 changes: 23 additions & 32 deletions mgradm/shared/podman/podman.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"os/exec"
"path"
"path/filepath"
"strconv"
"strings"

"github.com/rs/zerolog"
Expand Down Expand Up @@ -204,7 +203,7 @@ func RunMigration(preparedImage string, sshAuthSocket string, sshConfigPath stri
[]string{"/var/lib/uyuni-tools/migrate.sh"}); err != nil {
return nil, utils.Errorf(err, L("cannot run uyuni migration container"))
}
extractedData, err := adm_utils.ReadContainerData(scriptDir)
extractedData, err := utils.ReadInspectData[utils.InspectResult](path.Join(scriptDir, "data"))

if err != nil {
return nil, utils.Errorf(err, L("cannot read extracted data"))
Expand Down Expand Up @@ -249,10 +248,8 @@ func RunPgsqlVersionUpgrade(image types.ImageFlags, upgradeImage types.ImageFlag
}

pullArgs := []string{}
_, scc_user_exist := inspectedHostValues["host_scc_username"]
_, scc_user_password := inspectedHostValues["host_scc_password"]
if scc_user_exist && scc_user_password && strings.Contains(upgradeImageUrl, "registry.suse.com") {
pullArgs = append(pullArgs, "--creds", inspectedHostValues["host_scc_username"]+":"+inspectedHostValues["host_scc_password"])
if inspectedHostValues.SccUsername != "" && inspectedHostValues.SccPassword != "" {
pullArgs = append(pullArgs, "--creds", inspectedHostValues.SccUsername+":"+inspectedHostValues.SccPassword)
}

preparedImage, err := podman.PrepareImage(upgradeImageUrl, image.PullPolicy, pullArgs...)
Expand Down Expand Up @@ -344,10 +341,8 @@ func Upgrade(image types.ImageFlags, upgradeImage types.ImageFlags, cocoImage ty
}

pullArgs := []string{}
_, scc_user_exist := inspectedHostValues["host_scc_username"]
_, scc_user_password := inspectedHostValues["host_scc_password"]
if scc_user_exist && scc_user_password && strings.Contains(serverImage, "registry.suse.com") {
pullArgs = append(pullArgs, "--creds", inspectedHostValues["host_scc_username"]+":"+inspectedHostValues["host_scc_password"])
if inspectedHostValues.SccUsername != "" && inspectedHostValues.SccPassword != "" {
pullArgs = append(pullArgs, "--creds", inspectedHostValues.SccUsername+":"+inspectedHostValues.SccPassword)
}

preparedImage, err := podman.PrepareImage(serverImage, image.PullPolicy, pullArgs...)
Expand All @@ -373,18 +368,18 @@ func Upgrade(image types.ImageFlags, upgradeImage types.ImageFlags, cocoImage ty
defer func() {
err = podman.StartService(podman.ServerService)
}()
if inspectedValues["image_pg_version"] > inspectedValues["current_pg_version"] {
log.Info().Msgf(L("Previous postgresql is %[1]s, instead new one is %[2]s. Performing a DB version upgrade…"), inspectedValues["current_pg_version"], inspectedValues["image_pg_version"])
if err := RunPgsqlVersionUpgrade(image, upgradeImage, inspectedValues["current_pg_version"], inspectedValues["image_pg_version"]); err != nil {
if inspectedValues.ImagePgVersion > inspectedValues.CurrentPgVersion {
log.Info().Msgf(L("Previous postgresql is %[1]s, instead new one is %[2]s. Performing a DB version upgrade…"), inspectedValues.CurrentPgVersion, inspectedValues.ImagePgVersion)
if err := RunPgsqlVersionUpgrade(image, upgradeImage, inspectedValues.CurrentPgVersion, inspectedValues.ImagePgVersion); err != nil {
return utils.Errorf(err, L("cannot run PostgreSQL version upgrade script"))
}
} else if inspectedValues["image_pg_version"] == inspectedValues["current_pg_version"] {
log.Info().Msgf(L("Upgrading to %s without changing PostgreSQL version"), inspectedValues["uyuni_release"])
} else if inspectedValues.ImagePgVersion == inspectedValues.CurrentPgVersion {
log.Info().Msgf(L("Upgrading to %s without changing PostgreSQL version"), inspectedValues.UyuniRelease)
} else {
return fmt.Errorf(L("trying to downgrade PostgreSQL from %[1]s to %[2]s"), inspectedValues["current_pg_version"], inspectedValues["image_pg_version"])
return fmt.Errorf(L("trying to downgrade PostgreSQL from %[1]s to %[2]s"), inspectedValues.CurrentPgVersion, inspectedValues.ImagePgVersion)
}

schemaUpdateRequired := inspectedValues["current_pg_version"] != inspectedValues["image_pg_version"]
schemaUpdateRequired := inspectedValues.CurrentPgVersion != inspectedValues.ImagePgVersion
if err := RunPgsqlFinalizeScript(preparedImage, schemaUpdateRequired, false); err != nil {
return utils.Errorf(err, L("cannot run PostgreSQL finalize script"))
}
Expand All @@ -398,13 +393,8 @@ func Upgrade(image types.ImageFlags, upgradeImage types.ImageFlags, cocoImage ty
}
log.Info().Msg(L("Waiting for the server to start…"))

dbPort, err := strconv.Atoi(inspectedValues["db_port"])
if err != nil {
return utils.Errorf(err, L("error %s is not a valid port number."), inspectedValues["db_port"])
}

err = coco.Upgrade(cocoImage, image,
dbPort, inspectedValues["db_name"], inspectedValues["db_user"], inspectedValues["db_password"])
inspectedValues.DbPort, inspectedValues.DbName, inspectedValues.DbUser, inspectedValues.DbPassword)
if err != nil {
return utils.Errorf(err, L("error upgrading confidential computing service."))
}
Expand All @@ -413,31 +403,32 @@ func Upgrade(image types.ImageFlags, upgradeImage types.ImageFlags, cocoImage ty
}

// Inspect check values on a given image and deploy.
func Inspect(preparedImage string) (map[string]string, error) {
func Inspect(preparedImage string) (*utils.ServerInspectData, error) {
scriptDir, err := os.MkdirTemp("", "mgradm-*")
defer os.RemoveAll(scriptDir)
if err != nil {
return map[string]string{}, utils.Errorf(err, L("failed to create temporary directory"))
return nil, utils.Errorf(err, L("failed to create temporary directory"))
}

if err := utils.GenerateInspectContainerScript(scriptDir); err != nil {
return map[string]string{}, err
inspector := utils.NewServerInspector(scriptDir)
if err := inspector.GenerateScript(); err != nil {
return nil, err
}

podmanArgs := []string{
"-v", scriptDir + ":" + utils.InspectOutputFile.Directory,
"-v", scriptDir + ":" + utils.InspectContainerDirectory,
"--security-opt", "label=disable",
}

err = podman.RunContainer("uyuni-inspect", preparedImage, utils.ServerVolumeMounts, podmanArgs,
[]string{utils.InspectOutputFile.Directory + "/" + utils.InspectScriptFilename})
[]string{utils.InspectContainerDirectory + "/" + utils.InspectScriptFilename})
if err != nil {
return map[string]string{}, err
return nil, err
}

inspectResult, err := utils.ReadInspectData(scriptDir)
inspectResult, err := inspector.ReadInspectData()
if err != nil {
return map[string]string{}, utils.Errorf(err, L("cannot inspect data"))
return nil, utils.Errorf(err, L("cannot inspect data"))
}

return inspectResult, err
Expand Down
67 changes: 29 additions & 38 deletions mgradm/shared/utils/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
package utils

import (
"bytes"
"errors"
"fmt"
"os"
Expand All @@ -15,7 +14,6 @@ import (

"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/spf13/viper"
"github.com/uyuni-project/uyuni-tools/mgradm/shared/templates"
"github.com/uyuni-project/uyuni-tools/shared"
"github.com/uyuni-project/uyuni-tools/shared/kubernetes"
Expand Down Expand Up @@ -100,25 +98,6 @@ func GeneratePostUpgradeScript(scriptDir string, cobblerHost string) (string, er
return scriptName, nil
}

// ReadContainerData returns values used to perform migration.
func ReadContainerData(scriptDir string) (*utils.InspectResult, error) {
data, err := os.ReadFile(filepath.Join(scriptDir, "data"))
if err != nil {
return nil, errors.New(L("failed to read data extracted from source host"))
}

viper.SetConfigType("env")
if err := viper.MergeConfig(bytes.NewBuffer(data)); err != nil {
return nil, utils.Errorf(err, L("cannot read config"))
}

var results utils.InspectResult
if err := viper.Unmarshal(&results); err != nil {
return nil, utils.Errorf(err, L("failed to unmarshall data extracted from source host"))
}
return &results, nil
}

// RunMigration execute the migration script.
func RunMigration(cnx *shared.Connection, tmpPath string, scriptName string) error {
log.Info().Msg(L("Migrating server"))
Expand Down Expand Up @@ -183,20 +162,26 @@ func RunningImage(cnx *shared.Connection, containerName string) (string, error)
}

// SanityCheck verifies if an upgrade can be run.
func SanityCheck(cnx *shared.Connection, inspectedValues map[string]string, serverImage string) error {
func SanityCheck(cnx *shared.Connection, inspectedValues *utils.ServerInspectData, serverImage string) error {
isUyuni, err := isUyuni(cnx)
if err != nil {
return utils.Errorf(err, L("cannot check server release"))
}
_, isCurrentUyuni := inspectedValues["uyuni_release"]
_, isCurrentSuma := inspectedValues["suse_manager_release"]
isCurrentUyuni := inspectedValues.UyuniRelease != ""
isCurrentSuma := inspectedValues.SuseManagerRelease != ""

if isUyuni && isCurrentSuma {
return fmt.Errorf(L("currently SUSE Manager %s is installed, instead the image is Uyuni. Upgrade is not supported"), inspectedValues["suse_manager_release"])
return fmt.Errorf(
L("currently SUSE Manager %s is installed, instead the image is Uyuni. Upgrade is not supported"),
inspectedValues.SuseManagerRelease,
)
}

if !isUyuni && isCurrentUyuni {
return fmt.Errorf(L("currently Uyuni %s is installed, instead the image is SUSE Manager. Upgrade is not supported"), inspectedValues["uyuni_release"])
return fmt.Errorf(
L("currently Uyuni %s is installed, instead the image is SUSE Manager. Upgrade is not supported"),
inspectedValues.UyuniRelease,
)
}

if isUyuni {
Expand All @@ -206,12 +191,15 @@ func SanityCheck(cnx *shared.Connection, inspectedValues map[string]string, serv
return utils.Errorf(err, L("failed to read current uyuni release"))
}
log.Debug().Msgf("Current release is %s", string(current_uyuni_release))
if (len(inspectedValues["uyuni_release"])) <= 0 {
if inspectedValues.UyuniRelease != "" {
return fmt.Errorf(L("cannot fetch release from image %s"), serverImage)
}
log.Debug().Msgf("Image %s is %s", serverImage, inspectedValues["uyuni_release"])
if utils.CompareVersion(inspectedValues["uyuni_release"], string(current_uyuni_release)) < 0 {
return fmt.Errorf(L("cannot downgrade from version %[1]s to %[2]s"), string(current_uyuni_release), inspectedValues["uyuni_release"])
log.Debug().Msgf("Image %s is %s", serverImage, inspectedValues.UyuniRelease)
if utils.CompareVersion(inspectedValues.UyuniRelease, string(current_uyuni_release)) < 0 {
return fmt.Errorf(
L("cannot downgrade from version %[1]s to %[2]s"),
string(current_uyuni_release), inspectedValues.UyuniRelease,
)
}
} else {
cnx_args := []string{"s/SUSE Manager release //g", "/etc/susemanager-release"}
Expand All @@ -220,23 +208,26 @@ func SanityCheck(cnx *shared.Connection, inspectedValues map[string]string, serv
return utils.Errorf(err, L("failed to read current susemanager release"))
}
log.Debug().Msgf("Current release is %s", string(current_suse_manager_release))
if (len(inspectedValues["suse_manager_release"])) <= 0 {
if inspectedValues.SuseManagerRelease != "" {
return fmt.Errorf(L("cannot fetch release from image %s"), serverImage)
}
log.Debug().Msgf("Image %s is %s", serverImage, inspectedValues["suse_manager_release"])
if utils.CompareVersion(inspectedValues["suse_manager_release"], string(current_suse_manager_release)) < 0 {
return fmt.Errorf(L("cannot downgrade from version %[1]s to %[2]s"), string(current_suse_manager_release), inspectedValues["suse_manager_release"])
log.Debug().Msgf("Image %s is %s", serverImage, inspectedValues.SuseManagerRelease)
if utils.CompareVersion(inspectedValues.SuseManagerRelease, string(current_suse_manager_release)) < 0 {
return fmt.Errorf(
L("cannot downgrade from version %[1]s to %[2]s"),
string(current_suse_manager_release), inspectedValues.SuseManagerRelease,
)
}
}

if (len(inspectedValues["image_pg_version"])) <= 0 {
if inspectedValues.ImagePgVersion != "" {
return fmt.Errorf(L("cannot fetch postgresql version from %s"), serverImage)
}
log.Debug().Msgf("Image %s has PostgreSQL %s", serverImage, inspectedValues["image_pg_version"])
if (len(inspectedValues["current_pg_version"])) <= 0 {
log.Debug().Msgf("Image %s has PostgreSQL %s", serverImage, inspectedValues.ImagePgVersion)
if inspectedValues.CurrentPgVersion != "" {
return fmt.Errorf(L("posgresql is not installed in the current deployment"))
}
log.Debug().Msgf("Current deployment has PostgreSQL %s", inspectedValues["current_pg_version"])
log.Debug().Msgf("Current deployment has PostgreSQL %s", inspectedValues.CurrentPgVersion)

return nil
}
Expand Down
12 changes: 4 additions & 8 deletions mgrpxy/shared/podman/podman.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,8 @@ func GetContainerImage(flags *utils.ProxyImageFlags, name string) (string, error
}

pullArgs := []string{}
_, scc_user_exist := inspectedHostValues["host_scc_username"]
_, scc_user_password := inspectedHostValues["host_scc_password"]
if scc_user_exist && scc_user_password {
pullArgs = append(pullArgs, "--creds", inspectedHostValues["host_scc_username"]+":"+inspectedHostValues["host_scc_password"])
if inspectedHostValues.SccUsername != "" && inspectedHostValues.SccPassword != "" {
pullArgs = append(pullArgs, "--creds", inspectedHostValues.SccUsername+":"+inspectedHostValues.SccPassword)
}

preparedImage, err := podman.PrepareImage(image, flags.PullPolicy, pullArgs...)
Expand Down Expand Up @@ -259,10 +257,8 @@ func getContainerImage(flags *utils.ProxyImageFlags, name string) (string, error
}

pullArgs := []string{}
_, scc_user_exist := inspectedHostValues["host_scc_username"]
_, scc_user_password := inspectedHostValues["host_scc_password"]
if scc_user_exist && scc_user_password && strings.Contains(image, "registry.suse.com") {
pullArgs = append(pullArgs, "--creds", inspectedHostValues["host_scc_username"]+":"+inspectedHostValues["host_scc_password"])
if inspectedHostValues.SccUsername != "" && inspectedHostValues.SccPassword != "" {
pullArgs = append(pullArgs, "--creds", inspectedHostValues.SccUsername+":"+inspectedHostValues.SccPassword)
}

preparedImage, err := podman.PrepareImage(image, flags.PullPolicy, pullArgs...)
Expand Down
Loading

0 comments on commit bc75baa

Please sign in to comment.