Ejemplo n.º 1
0
func loadBrickMetadata(context *pongo2.Context, baseDir *string, brick *string) (*data.BrickMetadata, *string, error) {
	// Check if simple metadata file exists
	brickMetadataFile := filepath.Join(*baseDir, fmt.Sprintf("%s.%s", *brick, brickExt))
	log.Debug("  Search brick metadata file:\n    %s", brickMetadataFile)
	if exists, _ := util.FileExists(brickMetadataFile); !exists {
		// Check if complex module metadata file exists
		brickMetadataFile = filepath.Join(*baseDir, *brick, brickModuleName)
		log.Debug("  Search brick metadata file:\n    %s", brickMetadataFile)
		if exists, _ := util.FileExists(brickMetadataFile); !exists {
			return nil, nil, errors.New(fmt.Sprintf("Could not load brick module:\n  %s\nfrom path:\n  %s", *brick, brickMetadataFile))
		}
	}

	log.Debug("  Loading brick metadata from file:\n    %s", brickMetadataFile)

	brickBaseDir := filepath.Dir(brickMetadataFile)
	log.Debug("  Brick base dir:\n  %s", brickMetadataFile)

	// Compile template
	if compiled, err := compileTemplateFromFile(context, &brickMetadataFile); err == nil {
		var metadata data.BrickMetadata
		if err := util.LoadYAMLFromString(*compiled, &metadata); err != nil {
			return nil, nil, err
		}
		return &metadata, &brickBaseDir, nil
	} else {
		return nil, nil, err
	}
}
Ejemplo n.º 2
0
func processMetadataUnits(context *pongo2.Context, metadata *data.BrickMetadata, brickBaseDir *string) (*data.Unit, error) {
	metaUnit := metadata.Unit

	// Create the initial Unit
	unit := &data.Unit{
		Name:    metaUnit.Name,
		Command: metaUnit.Command,
	}

	// Check if we have a template to process for the unit
	if len(metaUnit.Template) > 0 {
		templateFile := filepath.Join(*brickBaseDir, metaUnit.Template)
		if exists, _ := util.FileExists(templateFile); !exists {
			return nil, errors.New(fmt.Sprintf("Could not find brick module:\n  %s", templateFile))
		}

		// Compile template
		if compiled, err := compileTemplateFromFile(context, &templateFile); err != nil {
			return nil, err
		} else {
			unit.Content = *compiled
		}
	}

	for _, d := range metaUnit.DropIns {
		dropIn := &data.UnitDropIn{
			Name: d.Name,
		}

		// Check if we have a template to process for the drop-in
		if len(d.Template) > 0 {
			templateFile := filepath.Join(*brickBaseDir, d.Template)
			if exists, _ := util.FileExists(templateFile); !exists {
				return nil, errors.New(fmt.Sprintf("Could not find brick module:\n  %s", templateFile))
			}

			// Compile template
			if compiled, err := compileTemplateFromFile(context, &templateFile); err != nil {
				return nil, err
			} else {
				dropIn.Content = *compiled
			}
		}
		unit.AddDropIn(dropIn)
	}

	// Add the unit to the user data
	if len(unit.Name) > 0 {
		return unit, nil
	}
	return nil, nil
}
Ejemplo n.º 3
0
func processMetadataFiles(context *pongo2.Context, metadata *data.BrickMetadata, brickBaseDir *string) ([]data.WriteFile, error) {
	writeFiles := make([]data.WriteFile, 0, 10)
	for _, f := range metadata.Files {
		// Create the initial WriteFile
		writeFile := &data.WriteFile{
			Path:        f.Path,
			Permissions: f.Permissions,
		}

		// Check if we have a template to process
		if len(f.Template) > 0 {
			templateFile := filepath.Join(*brickBaseDir, f.Template)
			if exists, _ := util.FileExists(templateFile); !exists {
				return nil, errors.New(fmt.Sprintf("Could not find brick module:\n  %s", templateFile))
			}

			// Compile template
			if compiled, err := compileTemplateFromFile(context, &templateFile); err != nil {
				return nil, err
			} else {
				writeFile.Content = *compiled
			}
		}
		writeFiles = append(writeFiles, *writeFile)
	}
	return writeFiles, nil
}
Ejemplo n.º 4
0
func compileArtifact(context *pongo2.Context, artifact *data.Artifact, providerName string, baseDir *string, workDir *string) error {
	outputFile := filepath.Join(*workDir, "build", providerName, artifact.Name, "user-data")
	outputDir := filepath.Dir(outputFile)

	// Create output directory if missing
	if exists, _ := util.FileExists(outputDir); !exists {
		if err := os.MkdirAll(outputDir, 0755); err != nil {
			return errors.New(fmt.Sprintf("Could not create output directory:\n  %s\n\nnested error:\n  %s", outputDir, err.Error()))
		}
	}

	log.Notice("▶ Compiling artifact [%s] to:\n  %s", artifact.Name, outputFile)

	log.Debug("  Setting artifact name to the context")
	c := pongo2.Context{
		"env": map[string]interface{}{
			"provider": providerName,
			"artifact": artifact.Name,
		},
	}
	if err := mergo.MergeWithOverwrite(context, c); err != nil {
		return err
	}
	printContextData(context, true)

	// Create the initial user data objects
	buffer := bytes.NewBufferString("#cloud-config\n---\n")
	writeFiles := make([]data.WriteFile, 0, 10)
	units := make([]data.Unit, 0, 10)

	// Process bricks
	bricks := artifact.Bricks
	for _, brick := range bricks {
		log.Info("  Processing brick:\n    %s", brick)

		// Load metadata
		if metadata, brickBaseDir, err := loadBrickMetadata(context, baseDir, &brick); err == nil {
			// Process brick files
			log.Debug("  Processing brick files")
			if brickWriteFiles, err := processMetadataFiles(context, metadata, brickBaseDir); err != nil {
				return err
			} else {
				writeFiles = append(writeFiles, brickWriteFiles...)
			}

			// Process brick units
			log.Debug("  Processing brick unit")
			if brickUnit, err := processMetadataUnits(context, metadata, brickBaseDir); err != nil {
				return err
			} else if brickUnit != nil {
				units = append(units, *brickUnit)
			}
		} else {
			return err
		}
	}

	// Write compiled write-files section
	if len(writeFiles) > 0 {
		writeFilesMap := make(map[string]interface{})
		writeFilesMap["write-files"] = writeFiles
		if output, err := yaml.Marshal(writeFilesMap); err != nil {
			return err
		} else {
			buffer.Write(output)
		}
	}

	// Write rest of config file
	cloudConfig := artifact.CloudConfig

	// Custom CoreOS
	if cloudConfig.CoreOS != nil {
		coreOs := cloudConfig.CoreOS

		// Add units
		//		if coreOs["units"] != nil {
		coreOs["units"] = units
		//		}

		// Write CoreOS section
		coreOsMap := make(map[string]interface{})
		coreOsMap["coreos"] = coreOs
		if output, err := yaml.Marshal(coreOsMap); err != nil {
			return err
		} else {
			buffer.Write(output)
		}
	}

	// Append everything else to the end of the file
	if cloudConfig.Generic != nil {
		if output, err := yaml.Marshal(cloudConfig.Generic); err != nil {
			return err
		} else {
			buffer.Write(output)
		}
	}

	log.Info("  Writing output file to:\n    %s", outputFile)
	if err := ioutil.WriteFile(outputFile, buffer.Bytes(), 0755); err != nil {
		return err
	}

	return nil
}