// now we can apply it
utils.ApplyOc(fmt.Sprintf("%s/oc", binariesPath), out, kubeconfigFile)
} else {
- log.Println(fmt.Sprintf("No manifests found for %s", addonsPath))
+ log.Println(fmt.Sprintf("No manifests found for %s/blueprint/sites/site/02_cluster-addons", siteBuildPath))
}
- servicesPath := fmt.Sprintf("%s/blueprint/sites/site/03_services", siteBuildPath)
- log.Println(fmt.Sprintf("Applying workloads from %s", servicesPath))
- utils.PrepareKustomize(ocPath, servicesPath, kubeconfigFile)
- out = utils.ApplyKustomize(kustomizePath, servicesPath)
+ log.Println(fmt.Sprintf("Applying workloads from %s/blueprint/sites/site/03_services", siteBuildPath))
+ out = utils.ApplyKustomize(fmt.Sprintf("%s/kustomize", binariesPath), fmt.Sprintf("%s/blueprint/sites/site/03_services", siteBuildPath))
if string(out) != "" {
// now we can apply it
- utils.ApplyOc(ocPath, out, kubeconfigFile)
+ utils.ApplyOc(fmt.Sprintf("%s/oc", binariesPath), out, kubeconfigFile)
} else {
- log.Println(fmt.Sprintf("No manifests found for %s", servicesPath))
+ log.Println(fmt.Sprintf("No manifests found for %s/blueprint/sites/site/03_services", siteBuildPath))
}
}
+
+// Determines site profile type based on blueprint profile contents
+func (s Site) getProfileType(profileName string) (string, error) {
+ if profileName == "" || s.buildPath == "" || s.siteName == "" {
+ return "", errors.New("Site: getProfileType: profile name, build path and/or site name missing")
+ }
+
+ sitePath := fmt.Sprintf("%s/%s", s.buildPath, s.siteName)
+ installConfigDirPath := fmt.Sprintf("%s/%s/00_install-config/", sitePath, profileName)
+
+ // Check that blueprint profile install config directory is available
+ _, err := os.Stat(installConfigDirPath)
+
+ if err != nil {
+ return "", errors.New("Site: getProfileType: blueprint profile install config directory not found")
+ }
+
+ var profileType string
+
+ // Try to find an install-config yaml file of some sort
+ err = filepath.Walk(installConfigDirPath, func(path string, info os.FileInfo, err error) error {
+ if err != nil {
+ return err
+ }
+
+ // Not interested in directories, so just keep walking
+ if info.IsDir() {
+ return nil
+ }
+
+ if strings.Contains(info.Name(), "install-config") {
+ filename, _ := filepath.Abs(path)
+ installConfigFile, err := ioutil.ReadFile(filename)
+
+ if err != nil {
+ return err
+ }
+
+ // Empty file is useless, so just keep walking
+ if len(installConfigFile) == 0 {
+ return nil
+ }
+
+ var installConfig map[string]interface{}
+
+ err = yaml.Unmarshal(installConfigFile, &installConfig)
+
+ if err != nil {
+ return err
+ }
+
+ // Check unmarshalled YAML for a "platform" map
+ if platformIntf, ok := installConfig["platform"].(map[interface{}]interface{}); ok {
+ // "platform" map found, so check for certain keys
+ for key := range platformIntf {
+ switch key.(string) {
+ case "aws":
+ profileType = "aws"
+ break
+ case "libvirt":
+ profileType = "libvirt"
+ break
+ case "none":
+ profileType = "baremetal"
+ break
+ }
+ }
+ }
+
+ // If we found a profile type, return io.EOF error to force walk to break
+ // (we'll catch this below and treat it as a non-error)
+ if profileType != "" {
+ return io.EOF
+ }
+ }
+
+ return nil
+ })
+
+ // io.EOF error indicates success, but anything else is an actual error
+ if err != nil && err != io.EOF {
+ return "", fmt.Errorf("Site: getProfileType: error walking blueprint profile install-config directory: %s", err)
+ }
+
+ // If we found a profile type, return it
+ if profileType != "" {
+ return profileType, nil
+ }
+
+ // Warn that we were unable to find a profile type
+ log.Println("WARNING: Site: getProfileType: unable to determine site profile type")
+
+ return "", nil
+}
+
+func (s Site) prepareHostForAutomation(profileName string) error {
+ if s.buildPath == "" || s.siteName == "" {
+ return errors.New("Site: prepareHostForAutomation: build path and/or site name missing")
+ }
+
+ // Examine site's site-config and determine if any preparation in fact
+ // needs to be done
+ siteConfigSourcePath := fmt.Sprintf("%s/%s/site/00_install-config/site-config.yaml", s.buildPath, s.siteName)
+ filename, _ := filepath.Abs(siteConfigSourcePath)
+ siteConfigFile, err := ioutil.ReadFile(filename)
+
+ if err != nil {
+ return fmt.Errorf("Site: prepareHostForAutomation: error reading site-config.yaml: %s", err)
+ }
+
+ // Empty file is useless, so just abort
+ if len(siteConfigFile) == 0 {
+ return nil
+ }
+
+ var siteConfig map[string]interface{}
+
+ err = yaml.Unmarshal(siteConfigFile, &siteConfig)
+
+ if err != nil {
+ return fmt.Errorf("Site: prepareHostForAutomation: error unmarshalling site-config.yaml: %s", err)
+ }
+
+ // Check unmarshalled YAML for a "provisioningInfrastructure" map. If it has one, this indicates
+ // that this site requires host preparation, and we have to continue. Otherwise, we're done.
+ if _, ok := siteConfig["provisioningInfrastructure"].(map[interface{}]interface{}); !ok {
+ // Nothing to do, so just abort
+ return nil
+ }
+
+ // We DO require host preparation, so determine profile type
+ profileType, err := s.getProfileType(profileName)
+
+ if err != nil {
+ return err
+ }
+
+ // Now we know site profile type (if any), so call automation for that profile type (if any)
+ switch profileType {
+ case "baremetal":
+ // Download kni-upi-lab repo
+ // TODO: parameterize upi lab repo?
+ automationSource := "github.com/redhat-nfvpe/kni-upi-lab.git"
+ automationDestination := fmt.Sprintf("%s/%s/baremetal_automation", s.buildPath, s.siteName)
+
+ log.Printf("Site: prepareHostForAutomation: downloading baremetal automation repo (%s)\n", automationSource)
+
+ client := &getter.Client{Src: automationSource, Dst: automationDestination, Mode: getter.ClientModeAny}
+ err := client.Get()
+
+ if err != nil {
+ return fmt.Errorf("Site: prepareHostForAutomation: error cloning baremetal automation repository: %s", err)
+ }
+
+ // Defer clean-up
+ defer func() {
+ log.Printf("Site: prepareHostForAutomation: removing baremetal automation repo (%s)\n", automationDestination)
+ os.RemoveAll(automationDestination)
+ }()
+
+ // Copy the site's site-config.yaml into the automation repo
+ siteConfigSource, err := os.Open(siteConfigSourcePath)
+
+ if err != nil {
+ return fmt.Errorf("Site: prepareHostForAutomation: error opening source site config file: %s", err)
+ }
+
+ defer siteConfigSource.Close()
+
+ // Remove the existing automation site config, if any
+ siteConfigDestinationPath := fmt.Sprintf("%s/cluster/site-config.yaml", automationDestination)
+ os.RemoveAll(siteConfigDestinationPath)
+
+ siteConfigDestination, err := os.OpenFile(siteConfigDestinationPath, os.O_RDWR|os.O_CREATE, 0666)
+
+ if err != nil {
+ return fmt.Errorf("Site: prepareHostForAutomation: error opening destination site config file: %s", err)
+ }
+
+ defer siteConfigDestination.Close()
+
+ _, err = io.Copy(siteConfigDestination, siteConfigSource)
+
+ if err != nil {
+ return fmt.Errorf("Site: prepareHostForAutomation: error writing destination site config file: %s", err)
+ }
+
+ // 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("Site: prepareHostForAutomation: running automation host preparation script...")
+
+ err = cmd.Run()
+
+ if err != nil {
+ return fmt.Errorf("Site: prepareHostForAutomation: error running automation host preparation script")
+ }
+
+ log.Println("Site: prepareHostForAutomation: finished running automation host preparation script")
+ }
+
+ return nil
+}