plugin/source/multi/multi.go (77 lines of code) (raw):
package multi
/*
	Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
*/
import (
	"io/ioutil"
	"os"
	"github.com/facebookincubator/go2chef"
	"github.com/mitchellh/mapstructure"
	"github.com/otiai10/copy"
)
// TypeName is the name of this source plugin
const TypeName = "go2chef.source.multi"
// Source implements a multi filesystem source plugin that
// copies files from a directory on multi filesystem to temp
// for use. Paths are relative to the current working directory
// of the go2chef process.
type Source struct {
	logger go2chef.Logger
	SourceName string `mapstructure:"name"`
	SourceSpecs []map[string]interface{} `mapstructure:"sources"`
	sources     []go2chef.Source         `mapstructure:","`
}
func (s *Source) String() string {
	return "<" + TypeName + ":" + s.SourceName + ">"
}
// Name returns the name of this source instance
func (s *Source) Name() string {
	return s.SourceName
}
// Type returns the type of this source
func (s *Source) Type() string {
	return TypeName
}
// SetName sets the name of this source instance
func (s *Source) SetName(name string) {
	s.SourceName = name
}
// DownloadToPath fetches multiple source defs in order
func (s *Source) DownloadToPath(dlPath string) error {
	if err := os.MkdirAll(dlPath, 0755); err != nil {
		return err
	}
	for i, src := range s.sources {
		thisDl, err := ioutil.TempDir("", "go2chef-multi-")
		if err != nil {
			return err
		}
		if err := src.DownloadToPath(thisDl); err != nil {
			s.logger.Errorf("failed to download source %d to %s", i, thisDl)
			return err
		}
		if err := copy.Copy(thisDl, dlPath); err != nil {
			s.logger.Errorf("failed to copy directory %s to %s", thisDl, dlPath)
			return err
		}
	}
	return nil
}
// Loader provides an instantiation function for this source
func Loader(config map[string]interface{}) (go2chef.Source, error) {
	s := &Source{
		logger:      go2chef.GetGlobalLogger(),
		SourceName:  "",
		SourceSpecs: []map[string]interface{}{},
	}
	if err := mapstructure.Decode(config, s); err != nil {
		return nil, err
	}
	if s.SourceName == "" {
		s.SourceName = TypeName
	}
	for _, spec := range s.SourceSpecs {
		stype, err := go2chef.GetType(spec)
		if err != nil {
			return nil, err
		}
		src, err := go2chef.GetSource(stype, spec)
		if err != nil {
			return nil, err
		}
		s.sources = append(s.sources, src)
	}
	return s, nil
}
var _ go2chef.Source = &Source{}
var _ go2chef.SourceLoader = Loader
func init() {
	go2chef.RegisterSource(TypeName, Loader)
}