-
Notifications
You must be signed in to change notification settings - Fork 169
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 default openshift version #3094
Changes from all commits
d058b35
9a94353
cc1c8ea
b9e928e
7e24288
38c6b31
ad5abb9
837f5fb
b021c32
d89b290
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,8 +22,13 @@ import ( | |
"github.com/Azure/ARO-RP/pkg/util/version" | ||
) | ||
|
||
func getInstallerImageDigests(envKey string) (map[string]string, error) { | ||
var installerImageDigests map[string]string | ||
// Corresponds to configuration.openShiftVersions in RP-Config | ||
type OpenShiftVersions struct { | ||
DefaultStream map[string]string | ||
InstallStreams map[string]string | ||
} | ||
|
||
func getEnvironmentData(envKey string, envData any) error { | ||
var err error | ||
|
||
jsonData := []byte(os.Getenv(envKey)) | ||
|
@@ -34,57 +39,111 @@ func getInstallerImageDigests(envKey string) (map[string]string, error) { | |
if !env.IsLocalDevelopmentMode() { | ||
jsonData, err = base64.StdEncoding.DecodeString(string(jsonData)) | ||
if err != nil { | ||
return nil, fmt.Errorf("%s: Failed to decode base64: %v", envKey, err) | ||
return fmt.Errorf("%s: Failed to decode base64: %w", envKey, err) | ||
} | ||
} | ||
|
||
if err = json.Unmarshal(jsonData, &installerImageDigests); err != nil { | ||
return nil, fmt.Errorf("%s: Failed to parse JSON: %v", envKey, err) | ||
if err = json.Unmarshal(jsonData, envData); err != nil { | ||
SudoBrendan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return fmt.Errorf("%s: Failed to parse JSON: %w", envKey, err) | ||
} | ||
|
||
return installerImageDigests, nil | ||
return nil | ||
} | ||
|
||
func getLatestOCPVersions(ctx context.Context, log *logrus.Entry) ([]api.OpenShiftVersion, error) { | ||
env, err := env.NewCoreForCI(ctx, log) | ||
if err != nil { | ||
func getOpenShiftVersions() (*OpenShiftVersions, error) { | ||
const envKey = envOpenShiftVersions | ||
var openShiftVersions OpenShiftVersions | ||
|
||
if err := getEnvironmentData(envKey, &openShiftVersions); err != nil { | ||
return nil, err | ||
} | ||
dstAcr := os.Getenv("DST_ACR_NAME") | ||
acrDomainSuffix := "." + env.Environment().ContainerRegistryDNSSuffix | ||
|
||
dstRepo := dstAcr + acrDomainSuffix | ||
ocpVersions := []api.OpenShiftVersion{} | ||
// The DefaultStream map must have exactly one entry. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Small question to help with my understanding of how we do things: This comment tells me the "What" but not the "Why" and in the past this has been the rule I've used to determine if we need a comment. So:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Always good to get feedback on this. Basically we have only one default version for install - the latest Y version. Instead of having a default version per Y stream. |
||
numDefaultStreams := len(openShiftVersions.DefaultStream) | ||
if numDefaultStreams != 1 { | ||
return nil, fmt.Errorf("%s: DefaultStream must have exactly 1 entry, found %d", envKey, numDefaultStreams) | ||
} | ||
|
||
return &openShiftVersions, nil | ||
} | ||
|
||
func getInstallerImageDigests() (map[string]string, error) { | ||
// INSTALLER_IMAGE_DIGESTS is the mapping of a minor version to | ||
// the aro-installer wrapper digest. This allows us to utilize | ||
// Azure Safe Deployment Practices (SDP) instead of pushing the | ||
// version tag and deploying to all regions at once. | ||
installerImageDigests, err := getInstallerImageDigests("INSTALLER_IMAGE_DIGESTS") | ||
if err != nil { | ||
const envKey = envInstallerImageDigests | ||
var installerImageDigests map[string]string | ||
|
||
if err := getEnvironmentData(envKey, &installerImageDigests); err != nil { | ||
return nil, err | ||
} | ||
|
||
for _, vers := range version.AvailableInstallStreams { | ||
installerPullSpec := fmt.Sprintf("%s/aro-installer:%s", dstRepo, vers.Version.MinorVersion()) | ||
digest, ok := installerImageDigests[vers.Version.MinorVersion()] | ||
return installerImageDigests, nil | ||
} | ||
|
||
func appendOpenShiftVersions(ocpVersions []api.OpenShiftVersion, installStreams map[string]string, installerImageName string, installerImageDigests map[string]string, isDefault bool) ([]api.OpenShiftVersion, error) { | ||
for fullVersion, openShiftPullspec := range installStreams { | ||
openShiftVersion, err := version.ParseVersion(fullVersion) | ||
if err != nil { | ||
return nil, err | ||
} | ||
fullVersion = openShiftVersion.String() // trimmed of whitespace | ||
minorVersion := openShiftVersion.MinorVersion() | ||
installerDigest, ok := installerImageDigests[minorVersion] | ||
if !ok { | ||
return nil, fmt.Errorf("no digest found for version %s", vers.Version.String()) | ||
return nil, fmt.Errorf("no installer digest for version %s", minorVersion) | ||
} | ||
installerPullspec := fmt.Sprintf("%s:%s@%s", installerImageName, minorVersion, installerDigest) | ||
|
||
ocpVersions = append(ocpVersions, api.OpenShiftVersion{ | ||
Properties: api.OpenShiftVersionProperties{ | ||
Version: vers.Version.String(), | ||
OpenShiftPullspec: vers.PullSpec, | ||
InstallerPullspec: installerPullSpec + "@" + digest, | ||
Version: fullVersion, | ||
OpenShiftPullspec: openShiftPullspec, | ||
InstallerPullspec: installerPullspec, | ||
Enabled: true, | ||
Default: isDefault, | ||
}, | ||
}) | ||
} | ||
|
||
return ocpVersions, nil | ||
} | ||
|
||
func getLatestOCPVersions(ctx context.Context, log *logrus.Entry) ([]api.OpenShiftVersion, error) { | ||
env, err := env.NewCoreForCI(ctx, log) | ||
if err != nil { | ||
return nil, err | ||
} | ||
dstAcr := os.Getenv("DST_ACR_NAME") | ||
acrDomainSuffix := "." + env.Environment().ContainerRegistryDNSSuffix | ||
installerImageName := dstAcr + acrDomainSuffix + "/aro-installer" | ||
|
||
openShiftVersions, err := getOpenShiftVersions() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
installerImageDigests, err := getInstallerImageDigests() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
ocpVersions := make([]api.OpenShiftVersion, 0, len(openShiftVersions.DefaultStream)+len(openShiftVersions.InstallStreams)) | ||
|
||
ocpVersions, err = appendOpenShiftVersions(ocpVersions, openShiftVersions.DefaultStream, installerImageName, installerImageDigests, true) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
ocpVersions, err = appendOpenShiftVersions(ocpVersions, openShiftVersions.InstallStreams, installerImageName, installerImageDigests, false) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return ocpVersions, nil | ||
} | ||
|
||
func getVersionsDatabase(ctx context.Context, log *logrus.Entry) (database.OpenShiftVersions, error) { | ||
_env, err := env.NewCore(ctx, log) | ||
if err != nil { | ||
|
@@ -113,10 +172,10 @@ func getVersionsDatabase(ctx context.Context, log *logrus.Entry) (database.OpenS | |
|
||
m := statsd.New(ctx, log.WithField("component", "update-ocp-versions"), _env, os.Getenv("MDM_ACCOUNT"), os.Getenv("MDM_NAMESPACE"), os.Getenv("MDM_STATSD_SOCKET")) | ||
|
||
if err := env.ValidateVars(KeyVaultPrefix); err != nil { | ||
if err := env.ValidateVars(envKeyVaultPrefix); err != nil { | ||
return nil, err | ||
} | ||
keyVaultPrefix := os.Getenv(KeyVaultPrefix) | ||
keyVaultPrefix := os.Getenv(envKeyVaultPrefix) | ||
serviceKeyvaultURI := keyvault.URI(_env, env.ServiceKeyvaultSuffix, keyVaultPrefix) | ||
serviceKeyvault := keyvault.NewManager(msiKVAuthorizer, serviceKeyvaultURI) | ||
|
||
|
@@ -125,11 +184,11 @@ func getVersionsDatabase(ctx context.Context, log *logrus.Entry) (database.OpenS | |
return nil, err | ||
} | ||
|
||
if err := env.ValidateVars(DatabaseAccountName); err != nil { | ||
if err := env.ValidateVars(envDatabaseAccountName); err != nil { | ||
return nil, err | ||
} | ||
|
||
dbAccountName := os.Getenv(DatabaseAccountName) | ||
dbAccountName := os.Getenv(envDatabaseAccountName) | ||
clientOptions := &policy.ClientOptions{ | ||
ClientOptions: _env.Environment().ManagedIdentityCredentialOptions().ClientOptions, | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems odd to me (someone who is new to the team and GO) that we don't have some large struct to validate the contents of the RP-config already. Do we always just query part of the config piecemeal like this? Wouldn't it be more typical to load the config at start time and then access some object as needed? (Assuming that we don't have any dynamic components to the config). What am I missing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The main goal of this work was to move the hardcoded configuration of the versioning into the database. Historically this configuration has been hardcoded so there was not a need to call it other than using
pkg/util/version/
What you suggest is a good idea but we haven't gotten to a something like a general
pkg/util/config
at a team. In time this will probably make sense to consolidate the configuration of the RP in one package. But it was out of scope for this effort. Mainly when this was talked about there was some worry about not knowing what all the configuration was, so we decided to move one by one instead. With the idea that we would consolidate later. This is what I remember anyways.While I wasn't the main person working on this. Matt has been moved to other priorities at the moment so the rest of Loki team is trying to push this one over the finish line for him.
+1 for a follow up discussion and effort on this for sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, ARO.Pipelines has the full struct and parser you're looking for. What's happening in this context is the parser is extracting the OpenShift version bits we need from RP-Config and passing it to the RP as a JSON blob by way of an environment variable. All we're parsing here is the environment variable, not RP-Config directly.