From: Andrew Bays Date: Fri, 18 Oct 2019 11:29:17 +0000 (-0400) Subject: Version-selection for automated baremetal X-Git-Tag: akraino_r2~16^2 X-Git-Url: https://gerrit.akraino.org/r/gitweb?a=commitdiff_plain;h=c420c494bb8c206c32842d3179a4bde948e4d847;p=kni%2Finstaller.git Version-selection for automated baremetal Change-Id: I1f46fa879a805800916dec97b5cd147593e03332 --- diff --git a/pkg/automation/automation.go b/pkg/automation/automation.go index e5c4304..3a4d655 100644 --- a/pkg/automation/automation.go +++ b/pkg/automation/automation.go @@ -16,10 +16,10 @@ type AutomatedDeploymentParams struct { } type AutomatedDeploymentInterface interface { - PrepareBastion() error // Prepare host for automation - DeployMasters() error // Deploy cluster masters - DeployWorkers() error // Deploy cluster workers - DestroyCluster() error // Destroy the cluster + PrepareBastion(map[string]string) error // Prepare host for automation + DeployMasters() error // Deploy cluster masters + DeployWorkers() error // Deploy cluster workers + DestroyCluster() error // Destroy the cluster } var ( diff --git a/pkg/automation/baremetal.go b/pkg/automation/baremetal.go index 10d5524..94ff23a 100644 --- a/pkg/automation/baremetal.go +++ b/pkg/automation/baremetal.go @@ -8,7 +8,9 @@ import ( "os" "os/exec" "path/filepath" + "strings" + "gerrit.akraino.org/kni/installer/pkg/utils" "github.com/otiai10/copy" getter "github.com/hashicorp/go-getter" @@ -75,7 +77,7 @@ func newBaremetal(params AutomatedDeploymentParams) (AutomatedDeploymentInterfac }, nil } -func (bad baremetalAutomatedDeployment) PrepareBastion() error { +func (bad baremetalAutomatedDeployment) PrepareBastion(requirements map[string]string) error { // Download repo automationDestination := fmt.Sprintf("%s/%s/baremetal_automation", bad.siteBuildPath, bad.siteName) @@ -118,6 +120,56 @@ func (bad baremetalAutomatedDeployment) PrepareBastion() error { return fmt.Errorf("baremetalAutomatedDeployment: PrepareBastion: error writing destination site config file: %s", err) } + // Examine requirements to check for oc or openshift-install version selection. + // If they are found, inject them into the automation's images_and_binaries.sh script + // to override the default + binaryVersionsPath := fmt.Sprintf("%s/images_and_binaries.sh", automationDestination) + + for requirementName, requirementSource := range requirements { + switch requirementName { + case "oc": + err = utils.ReplaceFileText(binaryVersionsPath, "OCP_CLIENT_BINARY_URL=\"\"", fmt.Sprintf("OCP_CLIENT_BINARY_URL=\"%s\"", requirementSource)) + + if err != nil { + return fmt.Errorf("baremetalAutomatedDeployment: PrepareBastion: error injecting oc binary version: %s", err) + } + case "openshift-install": + err = utils.ReplaceFileText(binaryVersionsPath, "OCP_INSTALL_BINARY_URL=\"\"", fmt.Sprintf("OCP_INSTALL_BINARY_URL=\"%s\"", requirementSource)) + + if err != nil { + return fmt.Errorf("baremetalAutomatedDeployment: PrepareBastion: error injecting openshift-install binary version: %s", err) + } + } + } + + // Check site-config.yaml's config block for a releaseImageOverride. If found, extract + // the image's tag to get the requested version for RHCOS images, and inject that into + // automation's common.sh script to override the default + var siteConfig map[string]interface{} + siteConfigFile, err := ioutil.ReadFile(siteConfigDestinationPath) + + err = yaml.Unmarshal(siteConfigFile, &siteConfig) + + if err != nil { + return fmt.Errorf("baremetalAutomatedDeployment: PrepareBastion: error unmarshalling site-config.yaml: %s", err) + } + + if config, ok := siteConfig["config"].(map[interface{}]interface{}); ok { + if releaseImageOverride, ok := config["releaseImageOverride"].(string); ok { + parts := strings.Split(releaseImageOverride, ":") + + if len(parts) == 2 { + rhcosVersionsPath := fmt.Sprintf("%s/common.sh", automationDestination) + + err = utils.ReplaceFileText(rhcosVersionsPath, "OPENSHIFT_RHCOS_MAJOR_REL=\"\"", fmt.Sprintf("OPENSHIFT_RHCOS_MAJOR_REL=\"%s\"", parts[1])) + + if err != nil { + return fmt.Errorf("baremetalAutomatedDeployment: PrepareBastion: error injecting RHCOS image version: %s", err) + } + } + } + } + // Execute automation's prep_bm_host script cmd := exec.Command(fmt.Sprintf("%s/prep_bm_host.sh", automationDestination)) cmd.Dir = automationDestination @@ -165,20 +217,7 @@ func (bad baremetalAutomatedDeployment) DeployMasters() error { _, err = os.Stat(automationRepoPath) if err != nil { - if !os.IsNotExist(err) { - return fmt.Errorf("baremetalAutomatedDeployment: DeployMasters: unable to access local automation repo at %s: %s", automationRepoPath, err) - } - - // Doesn't exist, so clone it? - // NOTE: It should already exist, having been created during the "fetch_requirements" step - log.Printf("baremetalAutomatedDeployment: DeployMasters: downloading missing baremetal automation repo (%s)\n", automationRemoteSource) - - client := &getter.Client{Src: automationRemoteSource, Dst: automationRepoPath, Mode: getter.ClientModeAny} - err := client.Get() - - if err != nil { - return fmt.Errorf("baremetalAutomatedDeployment: DeployMasters: error cloning baremetal automation repository: %s", err) - } + return fmt.Errorf("baremetalAutomatedDeployment: DeployMasters: unable to access local automation repo at %s: %s", automationRepoPath, err) } // Copy final_manifests into the automation repo's ocp directory (the ocp diff --git a/pkg/site/site.go b/pkg/site/site.go index 4a44ad9..7aeb8f8 100644 --- a/pkg/site/site.go +++ b/pkg/site/site.go @@ -161,6 +161,8 @@ func (s Site) FetchRequirements(individualRequirements []string) { } defer file.Close() + parsedRequirements := map[string]string{} + scanner := bufio.NewScanner(file) for scanner.Scan() { requirementsLine := scanner.Text() @@ -168,6 +170,13 @@ func (s Site) FetchRequirements(individualRequirements []string) { // requirements is composed of binary and source requirementsBits := strings.SplitN(strings.TrimSpace(requirementsLine), ":", 2) binaryName := strings.TrimSpace(requirementsBits[0]) + binarySource := strings.TrimSpace(requirementsBits[1]) + + // Store requirement for use in call to prepareHostForAutomation, regardless of + // what happens with the "individualRequirements" check below. If automation is + // in fact used later on, we want to honor the potential "oc" and "openshift-install" + // binary versions set in the blueprint profile's "requirements.yaml" + parsedRequirements[binaryName] = binarySource // if we have individual requirements list, check if we have the requirement on it. Otherwise, skip if len(individualRequirements) > 0 { @@ -184,12 +193,12 @@ func (s Site) FetchRequirements(individualRequirements []string) { continue } } - r := requirements.New(binaryName, strings.TrimSpace(requirementsBits[1]), fmt.Sprintf("%s/requirements", sitePath)) + r := requirements.New(binaryName, binarySource, fmt.Sprintf("%s/requirements", sitePath)) r.FetchRequirement() } // Checks for and executes any required host preparation for this site - err = s.prepareHostForAutomation(profileName) + err = s.prepareHostForAutomation(profileName, parsedRequirements) if err != nil { log.Fatal(err) @@ -663,7 +672,7 @@ func (s Site) getProfileType(profileName string) (string, error) { return "", nil } -func (s Site) prepareHostForAutomation(profileName string) error { +func (s Site) prepareHostForAutomation(profileName string, requirements map[string]string) error { if s.buildPath == "" || s.siteName == "" { return errors.New("Site: prepareHostForAutomation: build path and/or site name missing") } @@ -697,5 +706,5 @@ func (s Site) prepareHostForAutomation(profileName string) error { } // Tell the automated deployment instance to prepare the host for automation - return automatedDeployment.PrepareBastion() + return automatedDeployment.PrepareBastion(requirements) } diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index c12122f..b0b71d0 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -8,6 +8,7 @@ import ( "os" "os/exec" "path/filepath" + "strings" "time" ) @@ -135,3 +136,21 @@ func CopyFile(sourcePath string, destinationPath string) error { return nil } + +func ReplaceFileText(sourcePath string, oldText string, newText string) error { + read, err := ioutil.ReadFile(sourcePath) + + if err != nil { + return err + } + + newContents := strings.Replace(string(read), oldText, newText, -1) + + err = ioutil.WriteFile(sourcePath, []byte(newContents), 0) + + if err != nil { + return err + } + + return nil +}