github.phpd.cn/hashicorp/packer@v1.3.2/builder/docker/config.go (about)

     1  package docker
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  
     7  	"github.com/hashicorp/packer/common"
     8  	"github.com/hashicorp/packer/helper/communicator"
     9  	"github.com/hashicorp/packer/helper/config"
    10  	"github.com/hashicorp/packer/packer"
    11  	"github.com/hashicorp/packer/template/interpolate"
    12  	"github.com/mitchellh/mapstructure"
    13  )
    14  
    15  var (
    16  	errArtifactNotUsed     = fmt.Errorf("No instructions given for handling the artifact; expected commit, discard, or export_path")
    17  	errArtifactUseConflict = fmt.Errorf("Cannot specify more than one of commit, discard, and export_path")
    18  	errExportPathNotFile   = fmt.Errorf("export_path must be a file, not a directory")
    19  	errImageNotSpecified   = fmt.Errorf("Image must be specified")
    20  )
    21  
    22  type Config struct {
    23  	common.PackerConfig `mapstructure:",squash"`
    24  	Comm                communicator.Config `mapstructure:",squash"`
    25  
    26  	Author         string
    27  	Changes        []string
    28  	Commit         bool
    29  	ContainerDir   string `mapstructure:"container_dir"`
    30  	Discard        bool
    31  	ExecUser       string `mapstructure:"exec_user"`
    32  	ExportPath     string `mapstructure:"export_path"`
    33  	Image          string
    34  	Message        string
    35  	Privileged     bool `mapstructure:"privileged"`
    36  	Pty            bool
    37  	Pull           bool
    38  	RunCommand     []string `mapstructure:"run_command"`
    39  	Volumes        map[string]string
    40  	FixUploadOwner bool `mapstructure:"fix_upload_owner"`
    41  
    42  	// This is used to login to dockerhub to pull a private base container. For
    43  	// pushing to dockerhub, see the docker post-processors
    44  	Login           bool
    45  	LoginPassword   string `mapstructure:"login_password"`
    46  	LoginServer     string `mapstructure:"login_server"`
    47  	LoginUsername   string `mapstructure:"login_username"`
    48  	EcrLogin        bool   `mapstructure:"ecr_login"`
    49  	AwsAccessConfig `mapstructure:",squash"`
    50  
    51  	ctx interpolate.Context
    52  }
    53  
    54  func NewConfig(raws ...interface{}) (*Config, []string, error) {
    55  	c := new(Config)
    56  
    57  	c.FixUploadOwner = true
    58  
    59  	var md mapstructure.Metadata
    60  	err := config.Decode(c, &config.DecodeOpts{
    61  		Metadata:           &md,
    62  		Interpolate:        true,
    63  		InterpolateContext: &c.ctx,
    64  		InterpolateFilter: &interpolate.RenderFilter{
    65  			Exclude: []string{
    66  				"run_command",
    67  			},
    68  		},
    69  	}, raws...)
    70  	if err != nil {
    71  		return nil, nil, err
    72  	}
    73  
    74  	// Defaults
    75  	if len(c.RunCommand) == 0 {
    76  		c.RunCommand = []string{"-d", "-i", "-t", "{{.Image}}", "/bin/bash"}
    77  	}
    78  
    79  	// Default Pull if it wasn't set
    80  	hasPull := false
    81  	for _, k := range md.Keys {
    82  		if k == "Pull" {
    83  			hasPull = true
    84  			break
    85  		}
    86  	}
    87  
    88  	if !hasPull {
    89  		c.Pull = true
    90  	}
    91  
    92  	// Default to the normal Docker type
    93  	if c.Comm.Type == "" {
    94  		c.Comm.Type = "docker"
    95  	}
    96  
    97  	var errs *packer.MultiError
    98  	if es := c.Comm.Prepare(&c.ctx); len(es) > 0 {
    99  		errs = packer.MultiErrorAppend(errs, es...)
   100  	}
   101  	if c.Image == "" {
   102  		errs = packer.MultiErrorAppend(errs, errImageNotSpecified)
   103  	}
   104  
   105  	if (c.ExportPath != "" && c.Commit) || (c.ExportPath != "" && c.Discard) || (c.Commit && c.Discard) {
   106  		errs = packer.MultiErrorAppend(errs, errArtifactUseConflict)
   107  	}
   108  
   109  	if c.ExportPath == "" && !c.Commit && !c.Discard {
   110  		errs = packer.MultiErrorAppend(errs, errArtifactNotUsed)
   111  	}
   112  
   113  	if c.ExportPath != "" {
   114  		if fi, err := os.Stat(c.ExportPath); err == nil && fi.IsDir() {
   115  			errs = packer.MultiErrorAppend(errs, errExportPathNotFile)
   116  		}
   117  	}
   118  
   119  	if c.ContainerDir == "" {
   120  		c.ContainerDir = "/packer-files"
   121  	}
   122  
   123  	if c.EcrLogin && c.LoginServer == "" {
   124  		errs = packer.MultiErrorAppend(errs, fmt.Errorf("ECR login requires login server to be provided."))
   125  	}
   126  
   127  	if errs != nil && len(errs.Errors) > 0 {
   128  		return nil, nil, errs
   129  	}
   130  
   131  	return c, nil, nil
   132  }