github.phpd.cn/hashicorp/packer@v1.3.2/post-processor/googlecompute-export/post-processor.go (about)

     1  package googlecomputeexport
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"github.com/hashicorp/packer/builder/googlecompute"
     8  	"github.com/hashicorp/packer/common"
     9  	"github.com/hashicorp/packer/helper/config"
    10  	"github.com/hashicorp/packer/helper/multistep"
    11  	"github.com/hashicorp/packer/packer"
    12  	"github.com/hashicorp/packer/template/interpolate"
    13  )
    14  
    15  type Config struct {
    16  	common.PackerConfig `mapstructure:",squash"`
    17  
    18  	Paths             []string `mapstructure:"paths"`
    19  	KeepOriginalImage bool     `mapstructure:"keep_input_artifact"`
    20  
    21  	ctx interpolate.Context
    22  }
    23  
    24  type PostProcessor struct {
    25  	config Config
    26  	runner multistep.Runner
    27  }
    28  
    29  func (p *PostProcessor) Configure(raws ...interface{}) error {
    30  	err := config.Decode(&p.config, &config.DecodeOpts{
    31  		Interpolate:        true,
    32  		InterpolateContext: &p.config.ctx,
    33  	}, raws...)
    34  	if err != nil {
    35  		return err
    36  	}
    37  
    38  	return nil
    39  }
    40  
    41  func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, error) {
    42  	ui.Say("Starting googlecompute-export...")
    43  	ui.Say(fmt.Sprintf("Exporting image to destinations: %v", p.config.Paths))
    44  	if artifact.BuilderId() != googlecompute.BuilderId {
    45  		err := fmt.Errorf(
    46  			"Unknown artifact type: %s\nCan only export from Google Compute Engine builder artifacts.",
    47  			artifact.BuilderId())
    48  		return nil, p.config.KeepOriginalImage, err
    49  	}
    50  
    51  	result := &Artifact{paths: p.config.Paths}
    52  
    53  	if len(p.config.Paths) > 0 {
    54  		accountKeyFilePath := artifact.State("AccountFilePath").(string)
    55  		imageName := artifact.State("ImageName").(string)
    56  		imageSizeGb := artifact.State("ImageSizeGb").(int64)
    57  		projectId := artifact.State("ProjectId").(string)
    58  		zone := artifact.State("BuildZone").(string)
    59  
    60  		// Set up instance configuration.
    61  		instanceName := fmt.Sprintf("%s-exporter", artifact.Id())
    62  		metadata := map[string]string{
    63  			"image_name":     imageName,
    64  			"name":           instanceName,
    65  			"paths":          strings.Join(p.config.Paths, " "),
    66  			"startup-script": StartupScript,
    67  			"zone":           zone,
    68  		}
    69  		exporterConfig := googlecompute.Config{
    70  			InstanceName:         instanceName,
    71  			SourceImageProjectId: "debian-cloud",
    72  			SourceImage:          "debian-8-jessie-v20160629",
    73  			DiskName:             instanceName,
    74  			DiskSizeGb:           imageSizeGb + 10,
    75  			DiskType:             "pd-standard",
    76  			Metadata:             metadata,
    77  			MachineType:          "n1-standard-4",
    78  			Zone:                 zone,
    79  			Network:              "default",
    80  			RawStateTimeout:      "5m",
    81  			Scopes: []string{
    82  				"https://www.googleapis.com/auth/userinfo.email",
    83  				"https://www.googleapis.com/auth/compute",
    84  				"https://www.googleapis.com/auth/devstorage.full_control",
    85  			},
    86  		}
    87  		exporterConfig.CalcTimeout()
    88  
    89  		// Set up credentials and GCE driver.
    90  		if accountKeyFilePath != "" {
    91  			err := googlecompute.ProcessAccountFile(&exporterConfig.Account, accountKeyFilePath)
    92  			if err != nil {
    93  				return nil, p.config.KeepOriginalImage, err
    94  			}
    95  		}
    96  		driver, err := googlecompute.NewDriverGCE(ui, projectId, &exporterConfig.Account)
    97  		if err != nil {
    98  			return nil, p.config.KeepOriginalImage, err
    99  		}
   100  
   101  		// Set up the state.
   102  		state := new(multistep.BasicStateBag)
   103  		state.Put("config", &exporterConfig)
   104  		state.Put("driver", driver)
   105  		state.Put("ui", ui)
   106  
   107  		// Build the steps.
   108  		steps := []multistep.Step{
   109  			&googlecompute.StepCreateSSHKey{
   110  				Debug:        p.config.PackerDebug,
   111  				DebugKeyPath: fmt.Sprintf("gce_%s.pem", p.config.PackerBuildName),
   112  			},
   113  			&googlecompute.StepCreateInstance{
   114  				Debug: p.config.PackerDebug,
   115  			},
   116  			new(googlecompute.StepWaitStartupScript),
   117  			new(googlecompute.StepTeardownInstance),
   118  		}
   119  
   120  		// Run the steps.
   121  		p.runner = common.NewRunner(steps, p.config.PackerConfig, ui)
   122  		p.runner.Run(state)
   123  	}
   124  
   125  	return result, p.config.KeepOriginalImage, nil
   126  }