github.com/daniellockard/packer@v0.7.6-0.20141210173435-5a9390934716/builder/googlecompute/config.go (about)

     1  package googlecompute
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"time"
     7  
     8  	"github.com/mitchellh/packer/common"
     9  	"github.com/mitchellh/packer/common/uuid"
    10  	"github.com/mitchellh/packer/packer"
    11  )
    12  
    13  // Config is the configuration structure for the GCE builder. It stores
    14  // both the publicly settable state as well as the privately generated
    15  // state of the config object.
    16  type Config struct {
    17  	common.PackerConfig `mapstructure:",squash"`
    18  
    19  	AccountFile string `mapstructure:"account_file"`
    20  	ProjectId   string `mapstructure:"project_id"`
    21  
    22  	DiskName             string            `mapstructure:"disk_name"`
    23  	DiskSizeGb           int64             `mapstructure:"disk_size"`
    24  	ImageName            string            `mapstructure:"image_name"`
    25  	ImageDescription     string            `mapstructure:"image_description"`
    26  	InstanceName         string            `mapstructure:"instance_name"`
    27  	MachineType          string            `mapstructure:"machine_type"`
    28  	Metadata             map[string]string `mapstructure:"metadata"`
    29  	Network              string            `mapstructure:"network"`
    30  	SourceImage          string            `mapstructure:"source_image"`
    31  	SourceImageProjectId string            `mapstructure:"source_image_project_id"`
    32  	SSHUsername          string            `mapstructure:"ssh_username"`
    33  	SSHPort              uint              `mapstructure:"ssh_port"`
    34  	RawSSHTimeout        string            `mapstructure:"ssh_timeout"`
    35  	RawStateTimeout      string            `mapstructure:"state_timeout"`
    36  	Tags                 []string          `mapstructure:"tags"`
    37  	Zone                 string            `mapstructure:"zone"`
    38  
    39  	account         accountFile
    40  	privateKeyBytes []byte
    41  	sshTimeout      time.Duration
    42  	stateTimeout    time.Duration
    43  	tpl             *packer.ConfigTemplate
    44  }
    45  
    46  func NewConfig(raws ...interface{}) (*Config, []string, error) {
    47  	c := new(Config)
    48  	md, err := common.DecodeConfig(c, raws...)
    49  	if err != nil {
    50  		return nil, nil, err
    51  	}
    52  
    53  	c.tpl, err = packer.NewConfigTemplate()
    54  	if err != nil {
    55  		return nil, nil, err
    56  	}
    57  	c.tpl.UserVars = c.PackerUserVars
    58  
    59  	// Prepare the errors
    60  	errs := common.CheckUnusedConfig(md)
    61  
    62  	// Set defaults.
    63  	if c.Network == "" {
    64  		c.Network = "default"
    65  	}
    66  
    67  	if c.DiskSizeGb == 0 {
    68  		c.DiskSizeGb = 10
    69  	}
    70  
    71  	if c.ImageDescription == "" {
    72  		c.ImageDescription = "Created by Packer"
    73  	}
    74  
    75  	if c.ImageName == "" {
    76  		c.ImageName = "packer-{{timestamp}}"
    77  	}
    78  
    79  	if c.InstanceName == "" {
    80  		c.InstanceName = fmt.Sprintf("packer-%s", uuid.TimeOrderedUUID())
    81  	}
    82  
    83  	if c.DiskName == "" {
    84  		c.DiskName = c.InstanceName
    85  	}
    86  
    87  	if c.MachineType == "" {
    88  		c.MachineType = "n1-standard-1"
    89  	}
    90  
    91  	if c.RawSSHTimeout == "" {
    92  		c.RawSSHTimeout = "5m"
    93  	}
    94  
    95  	if c.RawStateTimeout == "" {
    96  		c.RawStateTimeout = "5m"
    97  	}
    98  
    99  	if c.SSHUsername == "" {
   100  		c.SSHUsername = "root"
   101  	}
   102  
   103  	if c.SSHPort == 0 {
   104  		c.SSHPort = 22
   105  	}
   106  
   107  	// Process Templates
   108  	templates := map[string]*string{
   109  		"account_file": &c.AccountFile,
   110  
   111  		"disk_name":               &c.DiskName,
   112  		"image_name":              &c.ImageName,
   113  		"image_description":       &c.ImageDescription,
   114  		"instance_name":           &c.InstanceName,
   115  		"machine_type":            &c.MachineType,
   116  		"network":                 &c.Network,
   117  		"project_id":              &c.ProjectId,
   118  		"source_image":            &c.SourceImage,
   119  		"source_image_project_id": &c.SourceImageProjectId,
   120  		"ssh_username":            &c.SSHUsername,
   121  		"ssh_timeout":             &c.RawSSHTimeout,
   122  		"state_timeout":           &c.RawStateTimeout,
   123  		"zone":                    &c.Zone,
   124  	}
   125  
   126  	for n, ptr := range templates {
   127  		var err error
   128  		*ptr, err = c.tpl.Process(*ptr, nil)
   129  		if err != nil {
   130  			errs = packer.MultiErrorAppend(
   131  				errs, fmt.Errorf("Error processing %s: %s", n, err))
   132  		}
   133  	}
   134  
   135  	// Process required parameters.
   136  	if c.ProjectId == "" {
   137  		errs = packer.MultiErrorAppend(
   138  			errs, errors.New("a project_id must be specified"))
   139  	}
   140  
   141  	if c.SourceImage == "" {
   142  		errs = packer.MultiErrorAppend(
   143  			errs, errors.New("a source_image must be specified"))
   144  	}
   145  
   146  	if c.Zone == "" {
   147  		errs = packer.MultiErrorAppend(
   148  			errs, errors.New("a zone must be specified"))
   149  	}
   150  
   151  	// Process timeout settings.
   152  	sshTimeout, err := time.ParseDuration(c.RawSSHTimeout)
   153  	if err != nil {
   154  		errs = packer.MultiErrorAppend(
   155  			errs, fmt.Errorf("Failed parsing ssh_timeout: %s", err))
   156  	}
   157  	c.sshTimeout = sshTimeout
   158  
   159  	stateTimeout, err := time.ParseDuration(c.RawStateTimeout)
   160  	if err != nil {
   161  		errs = packer.MultiErrorAppend(
   162  			errs, fmt.Errorf("Failed parsing state_timeout: %s", err))
   163  	}
   164  	c.stateTimeout = stateTimeout
   165  
   166  	if c.AccountFile != "" {
   167  		if err := loadJSON(&c.account, c.AccountFile); err != nil {
   168  			errs = packer.MultiErrorAppend(
   169  				errs, fmt.Errorf("Failed parsing account file: %s", err))
   170  		}
   171  	}
   172  
   173  	// Check for any errors.
   174  	if errs != nil && len(errs.Errors) > 0 {
   175  		return nil, nil, errs
   176  	}
   177  
   178  	return c, nil, nil
   179  }