func getAmiMap(artifact packer.Artifact) map[string]string { meta := artifact.State("atlas.artifact.metadata") if meta == nil { log.Println("Artifact has no AWS info: artifact.State(atlas.artifact.metadata)") return nil } regionMap, ok := meta.(map[interface{}]interface{}) if !ok { return nil } amiMap := make(map[string]string) for reg, ami := range regionMap { r, ok := reg.(string) if !ok { log.Printf("Couldnt convert Region to string: %#v \n", reg) } a, ok := ami.(string) if !ok { log.Printf("Couldnt convert Ami to string: %#v \n", ami) } r = strings.TrimPrefix(r, "region.") amiMap[r] = a } return amiMap }
func (p *PostProcessor) artifactType(artifact packer.Artifact) string { if !p.config.TypeOverride { if v := artifact.State(ArtifactStateType); v != nil { return v.(string) } } return p.config.Type }
func (p *PostProcessor) metadata(artifact packer.Artifact) map[string]string { var metadata map[string]string metadataRaw := artifact.State(ArtifactStateMetadata) if metadataRaw != nil { if err := mapstructure.Decode(metadataRaw, &metadata); err != nil { panic(err) } } if p.config.Metadata != nil { // If we have no extra metadata, just return as-is if metadata == nil { return p.config.Metadata } // Merge the metadata for k, v := range p.config.Metadata { metadata[k] = v } } return metadata }
func (p *LibVirtProvider) Process(ui packer.Ui, artifact packer.Artifact, dir string) (vagrantfile string, metadata map[string]interface{}, err error) { diskName := artifact.State("diskName").(string) // Copy the disk image into the temporary directory (as box.img) for _, path := range artifact.Files() { if strings.HasSuffix(path, "/"+diskName) { ui.Message(fmt.Sprintf("Copying from artifact: %s", path)) dstPath := filepath.Join(dir, "box.img") if err = CopyContents(dstPath, path); err != nil { return } } } format := artifact.State("diskType").(string) origSize := artifact.State("diskSize").(uint64) size := origSize / 1024 // In MB, want GB if origSize%1024 > 0 { // Make sure we don't make the size smaller size++ } domainType := artifact.State("domainType").(string) // Convert domain type to libvirt driver var driver string switch domainType { case "none", "tcg": driver = "qemu" case "kvm": driver = domainType default: return "", nil, fmt.Errorf("Unknown libvirt domain type: %s", domainType) } // Create the metadata metadata = map[string]interface{}{ "provider": "libvirt", "format": format, "virtual_size": size, } vagrantfile = fmt.Sprintf(libvirtVagrantfile, driver) return }
func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, error) { ui.Say("Starting googlecompute-export...") ui.Say(fmt.Sprintf("Exporting image to destinations: %v", p.config.Paths)) if artifact.BuilderId() != googlecompute.BuilderId { err := fmt.Errorf( "Unknown artifact type: %s\nCan only export from Google Compute Engine builder artifacts.", artifact.BuilderId()) return nil, p.config.KeepOriginalImage, err } result := &Artifact{paths: p.config.Paths} if len(p.config.Paths) > 0 { accountKeyFilePath := artifact.State("AccountFilePath").(string) imageName := artifact.State("ImageName").(string) imageSizeGb := artifact.State("ImageSizeGb").(int64) projectId := artifact.State("ProjectId").(string) zone := artifact.State("BuildZone").(string) // Set up instance configuration. instanceName := fmt.Sprintf("%s-exporter", artifact.Id()) metadata := map[string]string{ "image_name": imageName, "name": instanceName, "paths": strings.Join(p.config.Paths, " "), "startup-script": StartupScript, "zone": zone, } exporterConfig := googlecompute.Config{ InstanceName: instanceName, SourceImageProjectId: "debian-cloud", SourceImage: "debian-8-jessie-v20160629", DiskName: instanceName, DiskSizeGb: imageSizeGb + 10, DiskType: "pd-standard", Metadata: metadata, MachineType: "n1-standard-4", Zone: zone, Network: "default", RawStateTimeout: "5m", } exporterConfig.CalcTimeout() // Set up credentials and GCE driver. b, err := ioutil.ReadFile(accountKeyFilePath) if err != nil { err = fmt.Errorf("Error fetching account credentials: %s", err) return nil, p.config.KeepOriginalImage, err } accountKeyContents := string(b) googlecompute.ProcessAccountFile(&exporterConfig.Account, accountKeyContents) driver, err := googlecompute.NewDriverGCE(ui, projectId, &exporterConfig.Account) if err != nil { return nil, p.config.KeepOriginalImage, err } // Set up the state. state := new(multistep.BasicStateBag) state.Put("config", &exporterConfig) state.Put("driver", driver) state.Put("ui", ui) // Build the steps. steps := []multistep.Step{ &googlecompute.StepCreateSSHKey{ Debug: p.config.PackerDebug, DebugKeyPath: fmt.Sprintf("gce_%s.pem", p.config.PackerBuildName), }, &googlecompute.StepCreateInstance{ Debug: p.config.PackerDebug, }, new(googlecompute.StepWaitInstanceStartup), new(googlecompute.StepTeardownInstance), } // Run the steps. if p.config.PackerDebug { p.runner = &multistep.DebugRunner{ Steps: steps, PauseFn: common.MultistepDebugFn(ui), } } else { p.runner = &multistep.BasicRunner{Steps: steps} } p.runner.Run(state) } return result, p.config.KeepOriginalImage, nil }
func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, error) { if _, ok := builtins[artifact.BuilderId()]; !ok { return nil, false, fmt.Errorf("Unknown artifact type, can't process artifact: %s", artifact.BuilderId()) } vhd := "" for _, path := range artifact.Files() { if strings.HasSuffix(path, ".vhd") { vhd = path break } } if vhd == "" { return nil, false, fmt.Errorf("No VHD artifact file found") } vmType := artifact.State("virtualizationType") if vhd == "" { return nil, false, fmt.Errorf("Virtualization type wasn't specified") } requiresHVM := "false" if strings.ToLower(vmType.(string)) == "hvm" { requiresHVM = "true" } dir, file := path.Split(vhd) copyFromUrl := "" uploadFile := vhd if p.config.CompressVhd { uploadFile = dir + "template.vhd.gzip" os.Remove(uploadFile) // remove any existing file to ensure no corruption ui.Message(fmt.Sprintf("Compressing '%s' to '%s'", vhd, uploadFile)) err := compressVhd(vhd, uploadFile) if err != nil { return nil, false, fmt.Errorf("Error compressing template '%s': %s", vhd, err) } if strings.HasSuffix(p.config.DownloadUrl, "/") { copyFromUrl = p.config.DownloadUrl + "template.vhd.gzip" } else { copyFromUrl = fmt.Sprintf("%s/%s", p.config.DownloadUrl, "template.vhd.gzip") } } else { if strings.HasSuffix(p.config.DownloadUrl, "/") { copyFromUrl = p.config.DownloadUrl + file } else { copyFromUrl = fmt.Sprintf("%s/%s", p.config.DownloadUrl, file) } } ui.Message(fmt.Sprintf("Uploading %s to CloudStack", uploadFile)) // Create a new caching client acs, err := gocs.NewCachingClient(p.config.ApiUrl, p.config.ApiKey, p.config.Secret, 0, false) if err != nil { return nil, false, fmt.Errorf("Connection error: %s", err) } ostypeid, err := acs.Request("listOsTypes", fmt.Sprintf("description:%s", p.config.OsType)) if err != nil { return nil, false, fmt.Errorf("Error locating OS type '%s': %s", p.config.OsType, err) } ui.Say(fmt.Sprintf("OS '%s' has id '%s'", p.config.OsType, ostypeid)) zoneid, err := acs.Request("listZones", fmt.Sprintf("name:%s", p.config.Zone)) if err != nil { return nil, false, fmt.Errorf("Error locating Zone '%s': %s", p.config.Zone, err) } ui.Say(fmt.Sprintf("Zone '%s' has id '%s'", p.config.Zone, zoneid)) templateid, err := acs.Request("registerTemplate", fmt.Sprintf("displaytext:%s, ostypeid:%s, format:vhd, hypervisor:xenserver, name:%s, zoneid:%s, url:%s, requireshvm:%t, passwordenabled:%t, sshkeyenabled:%t, isdynamicallyscalable:%t", p.config.DisplayText, ostypeid, p.config.TemplateName, zoneid, copyFromUrl, requiresHVM, p.config.PwdEnabled, p.config.SshEnabled, p.config.HasTools)) if err != nil { return nil, false, fmt.Errorf("Error registering template '%s': %s", p.config.TemplateName, err) } ui.Say(fmt.Sprintf("Template registered as '%s'", templateid)) lastStatus := "" downloadStarted := false iterations := int(p.config.UploadTimer) / 5 for i := 0; i < iterations; i++ { templateDetails, err := acs.RawRequest("listTemplates", fmt.Sprintf("id:%s, templatefilter:all", templateid)) if err != nil { return nil, false, fmt.Errorf("Error locating template '%s': %s", templateid, err) } jsonResponse, err := gocs.UnmarshalResponse("template", templateDetails) if err != nil { return nil, false, fmt.Errorf("Error unmarshalling template repsonse: %s", err) } // a normal download will see the "status" start blank, then become non-blank in a few seconds, ending with isready:true // anything else is an error var status []TemplateResponse if err := json.Unmarshal(jsonResponse, &status); err != nil { return nil, false, fmt.Errorf("Error unmarshalling template repsonse: %s", err) } if status[0].Status != lastStatus { ui.Say(fmt.Sprintf("Template processing status '%s'", status[0].Status)) lastStatus = status[0].Status if strings.TrimSpace(lastStatus) != "" && !downloadStarted { if strings.Contains(lastStatus, "%") { downloadStarted = true } else if strings.HasPrefix(lastStatus, "Failed") { return nil, false, fmt.Errorf("Template '%s' processing aborted due to error: '%s'", p.config.TemplateName, strings.TrimSpace(lastStatus)) } else { return nil, false, fmt.Errorf("Template '%s' download aborted due to error: '%s'", p.config.TemplateName, strings.TrimSpace(lastStatus)) } } } if status[0].IsReady { ui.Say(fmt.Sprintf("Template '%s' is ready ", p.config.TemplateName)) break } time.Sleep(time.Duration(5) * time.Second) } return artifact, false, nil }
func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact /*keep*/, bool, error) { ui.Say("Validating artifact") if artifact.BuilderId() != azure.BuilderId { return nil, false, fmt.Errorf( "Unknown artifact type: %s\nCan only import from Azure builder artifacts (%s).", artifact.BuilderId(), azure.BuilderId) } publishSettingsPath, ok := artifact.State("publishSettingsPath").(string) if !ok || publishSettingsPath == "" { return nil, false, fmt.Errorf(stateError, "publishSettingsPath") } subscriptionID, ok := artifact.State("subscriptionID").(string) if !ok || subscriptionID == "" { return nil, false, fmt.Errorf(stateError, "subscriptionID") } name := artifact.Id() ui.Message("Creating Azure Service Management client...") client, err := management.ClientFromPublishSettingsFile(publishSettingsPath, subscriptionID) if err != nil { return nil, false, fmt.Errorf("Error creating new Azure client: %v", err) } client = azure.GetLoggedClient(client) vmic := virtualmachineimage.NewClient(client) ui.Message("Retrieving VM image...") var image virtualmachineimage.VMImage if err = retry.ExecuteOperation(func() error { imageList, err := vmic.ListVirtualMachineImages( virtualmachineimage.ListParameters{ Category: virtualmachineimage.CategoryUser, }) if err != nil { return err } for _, i := range imageList.VMImages { if i.Name == name { image = i break } } return nil }); err != nil { log.Printf("VM image client returned error: %s", err) return nil, false, err } if image.Name != name { return nil, false, fmt.Errorf("Could not find image: %s", name) } ui.Message(fmt.Sprintf("Deleting VM image (keeping VHDs) %s: %s...", image.Name, image.Label)) err = retry.ExecuteOperation(func() error { return vmic.DeleteVirtualMachineImage(image.Name, false) }) if err != nil { log.Printf("Error deleting VM image: %s", err) return nil, false, err } blobs := VMBlobListArtifact{ OSDisk: image.OSDiskConfiguration.MediaLink, DataDisks: make([]string, len(image.DataDiskConfigurations))} for i, ddc := range image.DataDiskConfigurations { blobs.DataDisks[i] = ddc.MediaLink } return blobs, false, nil }