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 }