}
type AutomatedDeploymentInterface interface {
- PrepareBastion(map[string]string) error // Prepare host for automation
- DeployMasters() error // Deploy cluster masters
- DeployWorkers() error // Deploy cluster workers
- DestroyCluster() error // Destroy the cluster
+ PrepareAutomation(map[string]string) error // Initial host preparation for automation, before finalizing manifests
+ FinalizeAutomation() error // Final host preparation for automation, after finalizing manifests
+ DeployMasters() error // Deploy cluster masters
+ DeployWorkers() error // Deploy cluster workers
+ DestroyCluster() error // Destroy the cluster
}
var (
}, nil
}
-func (bad baremetalAutomatedDeployment) PrepareBastion(requirements map[string]string) error {
+func (bad baremetalAutomatedDeployment) PrepareAutomation(requirements map[string]string) error {
// Download repo
automationDestination := fmt.Sprintf("%s/%s/baremetal_automation", bad.siteBuildPath, bad.siteName)
// Clear baremetal automation repo if it already exists
os.RemoveAll(automationDestination)
- log.Printf("baremetalAutomatedDeployment: PrepareBastion: downloading baremetal automation repo (%s)\n", automationRemoteSource)
+ log.Printf("baremetalAutomatedDeployment: PrepareAutomation: downloading baremetal automation repo (%s)...\n", automationRemoteSource)
client := &getter.Client{Src: automationRemoteSource, Dst: automationDestination, Mode: getter.ClientModeAny}
err := client.Get()
if err != nil {
- return fmt.Errorf("baremetalAutomatedDeployment: PrepareBastion: error cloning baremetal automation repository: %s", err)
+ return fmt.Errorf("baremetalAutomatedDeployment: PrepareAutomation: error cloning baremetal automation repository: %s", err)
}
// Copy the site's site-config.yaml into the automation repo
siteConfigSource, err := os.Open(fmt.Sprintf("%s/%s/site/00_install-config/site-config.yaml", bad.siteBuildPath, bad.siteName))
if err != nil {
- return fmt.Errorf("baremetalAutomatedDeployment: PrepareBastion: error opening source site config file: %s", err)
+ return fmt.Errorf("baremetalAutomatedDeployment: PrepareAutomation: error opening source site config file: %s", err)
}
defer siteConfigSource.Close()
siteConfigDestination, err := os.OpenFile(siteConfigDestinationPath, os.O_RDWR|os.O_CREATE, 0666)
if err != nil {
- return fmt.Errorf("baremetalAutomatedDeployment: PrepareBastion: error opening destination site config file: %s", err)
+ return fmt.Errorf("baremetalAutomatedDeployment: PrepareAutomation: error opening destination site config file: %s", err)
}
defer siteConfigDestination.Close()
_, err = io.Copy(siteConfigDestination, siteConfigSource)
if err != nil {
- return fmt.Errorf("baremetalAutomatedDeployment: PrepareBastion: error writing destination site config file: %s", err)
+ return fmt.Errorf("baremetalAutomatedDeployment: PrepareAutomation: error writing destination site config file: %s", err)
}
+ log.Printf("baremetalAutomatedDeployment: PrepareAutomation: finished downloading baremetal automation repo (%s)\n", automationRemoteSource)
+
+ log.Printf("baremetalAutomatedDeployment: PrepareAutomation: injecting version selections into automation repo...\n")
+
// 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
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)
+ return fmt.Errorf("baremetalAutomatedDeployment: PrepareAutomation: 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)
+ return fmt.Errorf("baremetalAutomatedDeployment: PrepareAutomation: error injecting openshift-install binary version: %s", err)
}
}
}
err = yaml.Unmarshal(siteConfigFile, &siteConfig)
if err != nil {
- return fmt.Errorf("baremetalAutomatedDeployment: PrepareBastion: error unmarshalling site-config.yaml: %s", err)
+ return fmt.Errorf("baremetalAutomatedDeployment: PrepareAutomation: error unmarshalling site-config.yaml: %s", err)
}
if config, ok := siteConfig["config"].(map[interface{}]interface{}); ok {
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)
+ return fmt.Errorf("baremetalAutomatedDeployment: PrepareAutomation: error injecting RHCOS image version: %s", err)
}
}
}
}
+ log.Printf("baremetalAutomatedDeployment: PrepareAutomation: finished injecting version selections into automation repo\n")
+
+ return nil
+}
+
+func (bad baremetalAutomatedDeployment) FinalizeAutomation() error {
+ automationDestination := fmt.Sprintf("%s/%s/baremetal_automation", bad.siteBuildPath, bad.siteName)
+
// Execute automation's prep_bm_host script
cmd := exec.Command(fmt.Sprintf("%s/prep_bm_host.sh", automationDestination))
cmd.Dir = automationDestination
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
- log.Println("baremetalAutomatedDeployment: PrepareBastion: running baremetal automation host preparation script...")
+ log.Println("baremetalAutomatedDeployment: FinalizeAutomation: running baremetal automation host preparation script...")
- err = cmd.Run()
+ err := cmd.Run()
if err != nil {
- return fmt.Errorf("baremetalAutomatedDeployment: PrepareBastion: error running baremetal automation host preparation script")
+ return fmt.Errorf("baremetalAutomatedDeployment: FinalizeAutomation: error running baremetal automation host preparation script")
}
- log.Println("baremetalAutomatedDeployment: PrepareBastion: finished running automation host preparation script")
+ log.Println("baremetalAutomatedDeployment: FinalizeAutomation: finished running automation host preparation script")
return nil
}
}
// utility to merge manifests
-func MergeManifests(content string, siteBuildPath string) {
+func MergeManifests(content string, siteBuildPath string) string {
manifests := strings.Split(content, "\n---\n")
kustomizeManifests := make(map[string]map[interface{}]interface{})
log.Fatal(fmt.Sprintf("Error moving to final manifests folder: %s", err))
os.Exit(1)
} else {
- log.Println(fmt.Sprintf("*** Manifest generation finished. You can run now: %s/requirements/openshift-install create cluster --dir=%s/final_manifests to create the site cluster ***", siteBuildPath, siteBuildPath))
- log.Println(fmt.Sprintf("If using UPI you can generate ignition files with: %s/requirements/openshift-install create ignition-configs --dir=%s/final_manifests", siteBuildPath, siteBuildPath))
- log.Println(fmt.Sprintf("A profile.env file has been generated inside %s/profile.env, you can source it before starting the openshift-install command", siteBuildPath))
- log.Println(fmt.Sprintf("In order to destroy the cluster you can run: %s/requirements/openshift-install destroy cluster --dir %s/final_manifests", siteBuildPath, siteBuildPath))
+ var builder strings.Builder
+
+ fmt.Fprintf(&builder, "*** Manifest generation finished. You can run now: %s/requirements/openshift-install create cluster --dir=%s/final_manifests to create the site cluster ***\n", siteBuildPath, siteBuildPath)
+ fmt.Fprintf(&builder, "If using UPI you can generate ignition files with: %s/requirements/openshift-install create ignition-configs --dir=%s/final_manifests", siteBuildPath, siteBuildPath)
+ fmt.Fprintf(&builder, "A profile.env file has been generated inside %s/profile.env, you can source it before starting the openshift-install command", siteBuildPath)
+ fmt.Fprintf(&builder, "In order to destroy the cluster you can run: %s/requirements/openshift-install destroy cluster --dir %s/final_manifests", siteBuildPath, siteBuildPath)
+
+ return builder.String()
}
+ // Should never get here
+ return ""
}
}
// using the downloaded site content, fetches (and builds) the specified requirements,
-// and also runs any required host preparation scripts for the site's profile type
+// and also prepares the host for running scripts for the site's profile type
func (s Site) FetchRequirements(individualRequirements []string) {
log.Println(fmt.Sprintf("Downloading requirements for %s", s.siteName))
sitePath := fmt.Sprintf("%s/%s", s.buildPath, s.siteName)
r.FetchRequirement()
}
- // Checks for and executes any required host preparation for this site
+ // Prepares host automation for post-'prepare_manifests' execution (if any)
err = s.prepareHostForAutomation(profileName, parsedRequirements)
if err != nil {
})
}
-// using the downloaded site content, prepares the manifests for it
+// using the downloaded site content, prepares the manifests for it, and also runs
+// host preparation finalization scripts for site automation (if any)
func (s Site) PrepareManifests() {
sitePath := fmt.Sprintf("%s/%s", s.buildPath, s.siteName)
log.Println(fmt.Sprintf("Preparing manifests for %s", s.siteName))
utils.ValidateRequirements(s.buildPath, s.siteName)
binariesPath := fmt.Sprintf("%s/requirements", sitePath)
- // retrieve profile path and clone the repo
- _, profileLayerPath, profileRef := s.GetProfileFromSite()
+ // retrieve profile name/path and clone the repo
+ profileName, profileLayerPath, profileRef := s.GetProfileFromSite()
s.DownloadRepo(sitePath, profileLayerPath, profileRef)
// create automation sub-directory to store a copy of anything that might be
- // needed if automation is later requested
+ // needed in the case of potential automation
automationPath := fmt.Sprintf("%s/automation", sitePath)
+ automationRepoPath := fmt.Sprintf("%s/baremetal_automation", sitePath)
os.Mkdir(automationPath, 0755)
// copy 00_install-config directory contents (minus kustomization.yaml)
os.Exit(1)
}
- // create a copy of final install-config.yaml in site automation sub-directory
- // in case automation is later requested
+ // create a copy of final install-config.yaml in any site automation sub-directories
+ // in case automation is later needed
err = ioutil.WriteFile(fmt.Sprintf("%s/install-config.yaml", automationPath), out, 0644)
if err != nil {
log.Fatal(fmt.Sprintf("Error writing final install-config file to automation assets directory: %s", err))
os.Exit(1)
}
+
+ automationRepoClusterPath := fmt.Sprintf("%s/cluster", automationRepoPath)
+ if _, err = os.Stat(automationRepoClusterPath); err == nil {
+ err = ioutil.WriteFile(fmt.Sprintf("%s/install-config.yaml", automationRepoClusterPath), out, 0644)
+ if err != nil {
+ log.Fatal(fmt.Sprintf("Error writing final install-config file to automation repo directory: %s", err))
+ os.Exit(1)
+ }
+ }
} else {
log.Fatal("Error, kustomize did not return any content")
os.Exit(1)
out = utils.ApplyKustomize(fmt.Sprintf("%s/kustomize", binariesPath), fmt.Sprintf("%s/blueprint/sites/site/01_cluster-mods", sitePath))
if len(out) > 0 {
// now apply modifications on the manifests
- manifests.MergeManifests(string(out), sitePath)
+ resultStr := manifests.MergeManifests(string(out), sitePath)
+
+ // Now that we have finalized our manifests, call automation finalization (if any)
+ err = s.finalizeHostForAutomation(profileName)
+ if err != nil {
+ log.Fatal(err)
+ os.Exit(1)
+ }
+
+ // Finally, print manifest merge output
+ fmt.Println(resultStr)
} else {
log.Fatal("Error, kustomize did not return any content")
os.Exit(1)
}
// Tell the automated deployment instance to prepare the host for automation
- return automatedDeployment.PrepareBastion(requirements)
+ return automatedDeployment.PrepareAutomation(requirements)
+}
+
+func (s Site) finalizeHostForAutomation(profileName string) error {
+ if s.buildPath == "" || s.siteName == "" {
+ return errors.New("Site: finalizeHostForAutomation: build path and/or site name missing")
+ }
+
+ // Get an automated deployment object
+ automatedDeployment, err := s.getAutomatedDeployment()
+
+ if err != nil {
+ // If automation isn't supported for this profile type, it's not a fatal error in
+ // this context, since this function is just trying to finalize the host for potential
+ // automation (and is not called in the context of an explicit automation request)
+ if strings.Contains(err.Error(), "automation not supported") || strings.Contains(err.Error(), "automated deployment not supported") {
+ return nil
+ }
+
+ // Anything else should be treated as an error
+ return err
+ }
+
+ // If automatedDeployment is nil, then automation isn't required/supported
+ // for this particular site, which isn't an error in this context
+ if automatedDeployment == nil {
+ return nil
+ }
+
+ // Tell the automated deployment instance to prepare the host for automation
+ return automatedDeployment.FinalizeAutomation()
}