'fetch_reqs' integration with bm automation 88/1588/4
authorAndrew Bays <abays@redhat.com>
Mon, 16 Sep 2019 17:10:57 +0000 (13:10 -0400)
committerAndrew Bays <abays@redhat.com>
Wed, 18 Sep 2019 15:23:40 +0000 (11:23 -0400)
Change-Id: I8ec51432cf9f50e5793209932d72e76aa2d2e4c2

pkg/site/site.go

index c5b9e87..e337875 100644 (file)
@@ -8,6 +8,7 @@ import (
        "io/ioutil"
        "log"
        "os"
+       "os/exec"
        "path"
        "path/filepath"
        "strings"
@@ -125,7 +126,8 @@ func (s Site) GetProfileFromSite() (string, string, string) {
        return "", "", ""
 }
 
-// using the downloaded site content, fetches (and builds) the specified requirements
+// 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
 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)
@@ -185,6 +187,14 @@ func (s Site) FetchRequirements(individualRequirements []string) {
                r.FetchRequirement()
        }
 
+       // Checks for and executes any required host preparation for this site
+       err = s.prepareHostForAutomation(profileName)
+
+       if err != nil {
+               log.Fatal(err)
+               os.Exit(1)
+       }
+
        // remove profile folder
        os.RemoveAll(profileBuildPath)
 
@@ -530,3 +540,115 @@ func (s Site) getProfileType(profileName string) (string, error) {
 
        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
+}