func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { steps := []multistep.Step{ &communicator.StepConnect{ Config: &b.config.CommConfig, Host: CommHost(b.config.CommConfig.Host()), SSHConfig: SSHConfig( b.config.CommConfig.SSHUsername, b.config.CommConfig.SSHPassword, b.config.CommConfig.SSHPrivateKey), }, &common.StepProvision{}, } // Setup the state bag and initial state for the steps state := new(multistep.BasicStateBag) state.Put("config", b.config) state.Put("hook", hook) state.Put("ui", ui) // Run! b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) b.runner.Run(state) // If there was an error, return that if rawErr, ok := state.GetOk("error"); ok { return nil, rawErr.(error) } // No errors, must've worked artifact := &NullArtifact{} return artifact, nil }
// Run executes a googlecompute Packer build and returns a packer.Artifact // representing a GCE machine image. func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { driver, err := NewDriverGCE( ui, b.config.ProjectId, &b.config.Account) if err != nil { return nil, err } // Set up the state. state := new(multistep.BasicStateBag) state.Put("config", b.config) state.Put("driver", driver) state.Put("hook", hook) state.Put("ui", ui) // Build the steps. steps := []multistep.Step{ new(StepCheckExistingImage), &StepCreateSSHKey{ Debug: b.config.PackerDebug, DebugKeyPath: fmt.Sprintf("gce_%s.pem", b.config.PackerBuildName), }, &StepCreateInstance{ Debug: b.config.PackerDebug, }, &StepInstanceInfo{ Debug: b.config.PackerDebug, }, &communicator.StepConnect{ Config: &b.config.Comm, Host: commHost, SSHConfig: sshConfig, }, new(common.StepProvision), new(StepWaitInstanceStartup), new(StepTeardownInstance), new(StepCreateImage), } // Run the steps. b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) b.runner.Run(state) // Report any errors. if rawErr, ok := state.GetOk("error"); ok { return nil, rawErr.(error) } if _, ok := state.GetOk("image"); !ok { log.Println("Failed to find image in state. Bug?") return nil, nil } artifact := &Artifact{ image: state.Get("image").(*Image), driver: driver, config: b.config, } return artifact, nil }
func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { config, err := b.config.Config() if err != nil { return nil, err } session, err := session.NewSession(config) if err != nil { return nil, err } ec2conn := ec2.New(session) // If the subnet is specified but not the AZ, try to determine the AZ automatically if b.config.SubnetId != "" && b.config.AvailabilityZone == "" { log.Printf("[INFO] Finding AZ for the given subnet '%s'", b.config.SubnetId) resp, err := ec2conn.DescribeSubnets(&ec2.DescribeSubnetsInput{SubnetIds: []*string{&b.config.SubnetId}}) if err != nil { return nil, err } b.config.AvailabilityZone = *resp.Subnets[0].AvailabilityZone log.Printf("[INFO] AZ found: '%s'", b.config.AvailabilityZone) } // Setup the state bag and initial state for the steps state := new(multistep.BasicStateBag) state.Put("config", b.config) state.Put("ec2", ec2conn) state.Put("hook", hook) state.Put("ui", ui) // Build the steps steps := []multistep.Step{ &awscommon.StepPreValidate{ DestAmiName: b.config.AMIName, ForceDeregister: b.config.AMIForceDeregister, }, &awscommon.StepSourceAMIInfo{ SourceAmi: b.config.SourceAmi, EnhancedNetworking: b.config.AMIEnhancedNetworking, AmiFilters: b.config.SourceAmiFilter, }, &awscommon.StepKeyPair{ Debug: b.config.PackerDebug, SSHAgentAuth: b.config.Comm.SSHAgentAuth, DebugKeyPath: fmt.Sprintf("ec2_%s.pem", b.config.PackerBuildName), KeyPairName: b.config.SSHKeyPairName, TemporaryKeyPairName: b.config.TemporaryKeyPairName, PrivateKeyFile: b.config.RunConfig.Comm.SSHPrivateKey, }, &awscommon.StepSecurityGroup{ SecurityGroupIds: b.config.SecurityGroupIds, CommConfig: &b.config.RunConfig.Comm, VpcId: b.config.VpcId, }, &stepCleanupVolumes{ BlockDevices: b.config.BlockDevices, }, &awscommon.StepRunSourceInstance{ Debug: b.config.PackerDebug, ExpectedRootDevice: "ebs", SpotPrice: b.config.SpotPrice, SpotPriceProduct: b.config.SpotPriceAutoProduct, InstanceType: b.config.InstanceType, UserData: b.config.UserData, UserDataFile: b.config.UserDataFile, SourceAMI: b.config.SourceAmi, IamInstanceProfile: b.config.IamInstanceProfile, SubnetId: b.config.SubnetId, AssociatePublicIpAddress: b.config.AssociatePublicIpAddress, EbsOptimized: b.config.EbsOptimized, AvailabilityZone: b.config.AvailabilityZone, BlockDevices: b.config.BlockDevices, Tags: b.config.RunTags, InstanceInitiatedShutdownBehavior: b.config.InstanceInitiatedShutdownBehavior, }, &stepTagEBSVolumes{ VolumeRunTags: b.config.VolumeRunTags, }, &awscommon.StepGetPassword{ Debug: b.config.PackerDebug, Comm: &b.config.RunConfig.Comm, Timeout: b.config.WindowsPasswordTimeout, }, &communicator.StepConnect{ Config: &b.config.RunConfig.Comm, Host: awscommon.SSHHost( ec2conn, b.config.SSHPrivateIp), SSHConfig: awscommon.SSHConfig( b.config.RunConfig.Comm.SSHAgentAuth, b.config.RunConfig.Comm.SSHUsername, b.config.RunConfig.Comm.SSHPassword), }, &common.StepProvision{}, &awscommon.StepStopEBSBackedInstance{ SpotPrice: b.config.SpotPrice, DisableStopInstance: b.config.DisableStopInstance, }, &awscommon.StepModifyEBSBackedInstance{ EnableEnhancedNetworking: b.config.AMIEnhancedNetworking, }, &awscommon.StepDeregisterAMI{ ForceDeregister: b.config.AMIForceDeregister, ForceDeleteSnapshot: b.config.AMIForceDeleteSnapshot, AMIName: b.config.AMIName, }, &stepCreateAMI{}, &stepCreateEncryptedAMICopy{}, &awscommon.StepAMIRegionCopy{ AccessConfig: &b.config.AccessConfig, Regions: b.config.AMIRegions, Name: b.config.AMIName, }, &awscommon.StepModifyAMIAttributes{ Description: b.config.AMIDescription, Users: b.config.AMIUsers, Groups: b.config.AMIGroups, ProductCodes: b.config.AMIProductCodes, }, &awscommon.StepCreateTags{ Tags: b.config.AMITags, SnapshotTags: b.config.SnapshotTags, }, } // Run! b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) b.runner.Run(state) // If there was an error, return that if rawErr, ok := state.GetOk("error"); ok { return nil, rawErr.(error) } // If there are no AMIs, then just return if _, ok := state.GetOk("amis"); !ok { return nil, nil } // Build the artifact and return it artifact := &awscommon.Artifact{ Amis: state.Get("amis").(map[string]string), BuilderIdValue: BuilderId, Conn: ec2conn, } return artifact, nil }
func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { ui.Say("Running builder ...") if err := newConfigRetriever().FillParameters(b.config); err != nil { return nil, err } log.Print(":: Configuration") packerAzureCommon.DumpConfig(b.config, func(s string) { log.Print(s) }) b.stateBag.Put("hook", hook) b.stateBag.Put(constants.Ui, ui) spnCloud, spnKeyVault, err := b.getServicePrincipalTokens(ui.Say) if err != nil { return nil, err } ui.Message("Creating Azure Resource Manager (ARM) client ...") azureClient, err := NewAzureClient( b.config.SubscriptionID, b.config.ResourceGroupName, b.config.StorageAccount, b.config.cloudEnvironment, spnCloud, spnKeyVault) if err != nil { return nil, err } resolver := newResourceResolver(azureClient) if err := resolver.Resolve(b.config); err != nil { return nil, err } b.config.storageAccountBlobEndpoint, err = b.getBlobEndpoint(azureClient, b.config.ResourceGroupName, b.config.StorageAccount) if err != nil { return nil, err } endpointConnectType := PublicEndpoint if b.isPrivateNetworkCommunication() { endpointConnectType = PrivateEndpoint } b.setTemplateParameters(b.stateBag) var steps []multistep.Step if strings.EqualFold(b.config.OSType, constants.Target_Linux) { steps = []multistep.Step{ NewStepCreateResourceGroup(azureClient, ui), NewStepValidateTemplate(azureClient, ui, b.config, GetVirtualMachineDeployment), NewStepDeployTemplate(azureClient, ui, b.config, GetVirtualMachineDeployment), NewStepGetIPAddress(azureClient, ui, endpointConnectType), &communicator.StepConnectSSH{ Config: &b.config.Comm, Host: lin.SSHHost, SSHConfig: lin.SSHConfig(b.config.UserName), }, &packerCommon.StepProvision{}, NewStepGetOSDisk(azureClient, ui), NewStepPowerOffCompute(azureClient, ui), NewStepCaptureImage(azureClient, ui), NewStepDeleteResourceGroup(azureClient, ui), NewStepDeleteOSDisk(azureClient, ui), } } else if strings.EqualFold(b.config.OSType, constants.Target_Windows) { steps = []multistep.Step{ NewStepCreateResourceGroup(azureClient, ui), NewStepValidateTemplate(azureClient, ui, b.config, GetKeyVaultDeployment), NewStepDeployTemplate(azureClient, ui, b.config, GetKeyVaultDeployment), NewStepGetCertificate(azureClient, ui), NewStepSetCertificate(b.config, ui), NewStepValidateTemplate(azureClient, ui, b.config, GetVirtualMachineDeployment), NewStepDeployTemplate(azureClient, ui, b.config, GetVirtualMachineDeployment), NewStepGetIPAddress(azureClient, ui, endpointConnectType), &communicator.StepConnectWinRM{ Config: &b.config.Comm, Host: func(stateBag multistep.StateBag) (string, error) { return stateBag.Get(constants.SSHHost).(string), nil }, WinRMConfig: func(multistep.StateBag) (*communicator.WinRMConfig, error) { return &communicator.WinRMConfig{ Username: b.config.UserName, Password: b.config.tmpAdminPassword, }, nil }, }, &packerCommon.StepProvision{}, NewStepGetOSDisk(azureClient, ui), NewStepPowerOffCompute(azureClient, ui), NewStepCaptureImage(azureClient, ui), NewStepDeleteResourceGroup(azureClient, ui), NewStepDeleteOSDisk(azureClient, ui), } } else { return nil, fmt.Errorf("Builder does not support the os_type '%s'", b.config.OSType) } if b.config.PackerDebug { ui.Message(fmt.Sprintf("temp admin user: '******'", b.config.UserName)) ui.Message(fmt.Sprintf("temp admin password: '******'", b.config.Password)) } b.runner = packerCommon.NewRunner(steps, b.config.PackerConfig, ui) b.runner.Run(b.stateBag) // Report any errors. if rawErr, ok := b.stateBag.GetOk(constants.Error); ok { return nil, rawErr.(error) } // If we were interrupted or cancelled, then just exit. if _, ok := b.stateBag.GetOk(multistep.StateCancelled); ok { return nil, errors.New("Build was cancelled.") } if _, ok := b.stateBag.GetOk(multistep.StateHalted); ok { return nil, errors.New("Build was halted.") } if template, ok := b.stateBag.GetOk(constants.ArmCaptureTemplate); ok { return NewArtifact( template.(*CaptureTemplate), func(name string) string { month := time.Now().AddDate(0, 1, 0).UTC() sasUrl, _ := azureClient.BlobStorageClient.GetBlobSASURI(DefaultSasBlobContainer, name, month, DefaultSasBlobPermission) return sasUrl }) } return &Artifact{}, nil }
func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { if runtime.GOOS != "linux" { return nil, errors.New("The amazon-chroot builder only works on Linux environments.") } config, err := b.config.Config() if err != nil { return nil, err } session, err := session.NewSession(config) if err != nil { return nil, err } ec2conn := ec2.New(session) wrappedCommand := func(command string) (string, error) { ctx := b.config.ctx ctx.Data = &wrappedCommandTemplate{Command: command} return interpolate.Render(b.config.CommandWrapper, &ctx) } // Setup the state bag and initial state for the steps state := new(multistep.BasicStateBag) state.Put("config", &b.config) state.Put("ec2", ec2conn) state.Put("hook", hook) state.Put("ui", ui) state.Put("wrappedCommand", CommandWrapper(wrappedCommand)) // Build the steps steps := []multistep.Step{ &awscommon.StepPreValidate{ DestAmiName: b.config.AMIName, ForceDeregister: b.config.AMIForceDeregister, }, &StepInstanceInfo{}, } if !b.config.FromScratch { steps = append(steps, &awscommon.StepSourceAMIInfo{ SourceAmi: b.config.SourceAmi, EnhancedNetworking: b.config.AMIEnhancedNetworking, AmiFilters: b.config.SourceAmiFilter, }, &StepCheckRootDevice{}, ) } steps = append(steps, &StepFlock{}, &StepPrepareDevice{}, &StepCreateVolume{ RootVolumeSize: b.config.RootVolumeSize, }, &StepAttachVolume{}, &StepEarlyUnflock{}, &StepPreMountCommands{ Commands: b.config.PreMountCommands, }, &StepMountDevice{ MountOptions: b.config.MountOptions, MountPartition: b.config.MountPartition, }, &StepPostMountCommands{ Commands: b.config.PostMountCommands, }, &StepMountExtra{}, &StepCopyFiles{}, &StepChrootProvision{}, &StepEarlyCleanup{}, &StepSnapshot{}, &awscommon.StepDeregisterAMI{ ForceDeregister: b.config.AMIForceDeregister, ForceDeleteSnapshot: b.config.AMIForceDeleteSnapshot, AMIName: b.config.AMIName, }, &StepRegisterAMI{ RootVolumeSize: b.config.RootVolumeSize, }, &awscommon.StepAMIRegionCopy{ AccessConfig: &b.config.AccessConfig, Regions: b.config.AMIRegions, Name: b.config.AMIName, }, &awscommon.StepModifyAMIAttributes{ Description: b.config.AMIDescription, Users: b.config.AMIUsers, Groups: b.config.AMIGroups, ProductCodes: b.config.AMIProductCodes, }, &awscommon.StepCreateTags{ Tags: b.config.AMITags, SnapshotTags: b.config.SnapshotTags, }, ) // Run! b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) b.runner.Run(state) // If there was an error, return that if rawErr, ok := state.GetOk("error"); ok { return nil, rawErr.(error) } // If there are no AMIs, then just return if _, ok := state.GetOk("amis"); !ok { return nil, nil } // Build the artifact and return it artifact := &awscommon.Artifact{ Amis: state.Get("amis").(map[string]string), BuilderIdValue: BuilderId, Conn: ec2conn, } return artifact, nil }
func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { computeClient, err := b.config.computeV2Client() if err != nil { return nil, fmt.Errorf("Error initializing compute client: %s", err) } // Setup the state bag and initial state for the steps state := new(multistep.BasicStateBag) state.Put("config", b.config) state.Put("hook", hook) state.Put("ui", ui) // Build the steps steps := []multistep.Step{ &StepLoadExtensions{}, &StepLoadFlavor{ Flavor: b.config.Flavor, }, &StepKeyPair{ Debug: b.config.PackerDebug, DebugKeyPath: fmt.Sprintf("os_%s.pem", b.config.PackerBuildName), KeyPairName: b.config.SSHKeyPairName, PrivateKeyFile: b.config.RunConfig.Comm.SSHPrivateKey, }, &StepRunSourceServer{ Name: b.config.ImageName, SourceImage: b.config.SourceImage, SourceImageName: b.config.SourceImageName, SecurityGroups: b.config.SecurityGroups, Networks: b.config.Networks, AvailabilityZone: b.config.AvailabilityZone, UserData: b.config.UserData, UserDataFile: b.config.UserDataFile, ConfigDrive: b.config.ConfigDrive, }, &StepGetPassword{ Debug: b.config.PackerDebug, Comm: &b.config.RunConfig.Comm, }, &StepWaitForRackConnect{ Wait: b.config.RackconnectWait, }, &StepAllocateIp{ FloatingIpPool: b.config.FloatingIpPool, FloatingIp: b.config.FloatingIp, }, &communicator.StepConnect{ Config: &b.config.RunConfig.Comm, Host: CommHost( computeClient, b.config.SSHInterface, b.config.SSHIPVersion), SSHConfig: SSHConfig(b.config.RunConfig.Comm.SSHUsername, b.config.RunConfig.Comm.SSHPassword), }, &common.StepProvision{}, &StepStopServer{}, &stepCreateImage{}, } // Run! b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) b.runner.Run(state) // If there was an error, return that if rawErr, ok := state.GetOk("error"); ok { return nil, rawErr.(error) } // If there are no images, then just return if _, ok := state.GetOk("image"); !ok { return nil, nil } // Build the artifact and return it artifact := &Artifact{ ImageId: state.Get("image").(string), BuilderIdValue: BuilderId, Client: computeClient, } return artifact, nil }
func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { client := godo.NewClient(oauth2.NewClient(oauth2.NoContext, &apiTokenSource{ AccessToken: b.config.APIToken, })) if b.config.APIURL != "" { u, err := url.Parse(b.config.APIURL) if err != nil { return nil, fmt.Errorf("DigitalOcean: Invalid API URL, %s.", err) } client.BaseURL = u } // Set up the state state := new(multistep.BasicStateBag) state.Put("config", b.config) state.Put("client", client) state.Put("hook", hook) state.Put("ui", ui) // Build the steps steps := []multistep.Step{ &stepCreateSSHKey{ Debug: b.config.PackerDebug, DebugKeyPath: fmt.Sprintf("do_%s.pem", b.config.PackerBuildName), }, new(stepCreateDroplet), new(stepDropletInfo), &communicator.StepConnect{ Config: &b.config.Comm, Host: commHost, SSHConfig: sshConfig, }, new(common.StepProvision), new(stepShutdown), new(stepPowerOff), new(stepSnapshot), } // Run the steps b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) b.runner.Run(state) // If there was an error, return that if rawErr, ok := state.GetOk("error"); ok { return nil, rawErr.(error) } if _, ok := state.GetOk("snapshot_name"); !ok { log.Println("Failed to find snapshot_name in state. Bug?") return nil, nil } artifact := &Artifact{ snapshotName: state.Get("snapshot_name").(string), snapshotId: state.Get("snapshot_image_id").(int), regionName: state.Get("region").(string), client: client, } return artifact, nil }
func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { config, err := b.config.Config() if err != nil { return nil, err } session, err := session.NewSession(config) if err != nil { return nil, errwrap.Wrapf("Error creating AWS Session: {{err}}", err) } ec2conn := ec2.New(session) // If the subnet is specified but not the AZ, try to determine the AZ automatically if b.config.SubnetId != "" && b.config.AvailabilityZone == "" { log.Printf("[INFO] Finding AZ for the given subnet '%s'", b.config.SubnetId) resp, err := ec2conn.DescribeSubnets(&ec2.DescribeSubnetsInput{SubnetIds: []*string{&b.config.SubnetId}}) if err != nil { return nil, err } b.config.AvailabilityZone = *resp.Subnets[0].AvailabilityZone log.Printf("[INFO] AZ found: '%s'", b.config.AvailabilityZone) } // Setup the state bag and initial state for the steps state := new(multistep.BasicStateBag) state.Put("config", b.config) state.Put("ec2", ec2conn) state.Put("hook", hook) state.Put("ui", ui) launchBlockDevices := commonBlockDevices(b.config.VolumeMappings) var volumeIds *[]string // Build the steps steps := []multistep.Step{ &awscommon.StepSourceAMIInfo{ SourceAmi: b.config.SourceAmi, EnhancedNetworking: b.config.AMIEnhancedNetworking, AmiFilters: b.config.SourceAmiFilter, }, &awscommon.StepKeyPair{ Debug: b.config.PackerDebug, DebugKeyPath: fmt.Sprintf("ec2_%s.pem", b.config.PackerBuildName), KeyPairName: b.config.SSHKeyPairName, TemporaryKeyPairName: b.config.TemporaryKeyPairName, PrivateKeyFile: b.config.RunConfig.Comm.SSHPrivateKey, }, &awscommon.StepSecurityGroup{ SecurityGroupIds: b.config.SecurityGroupIds, CommConfig: &b.config.RunConfig.Comm, VpcId: b.config.VpcId, }, &awscommon.StepRunSourceInstance{ Debug: b.config.PackerDebug, ExpectedRootDevice: "ebs", SpotPrice: b.config.SpotPrice, SpotPriceProduct: b.config.SpotPriceAutoProduct, InstanceType: b.config.InstanceType, UserData: b.config.UserData, UserDataFile: b.config.UserDataFile, SourceAMI: b.config.SourceAmi, IamInstanceProfile: b.config.IamInstanceProfile, SubnetId: b.config.SubnetId, AssociatePublicIpAddress: b.config.AssociatePublicIpAddress, EbsOptimized: b.config.EbsOptimized, AvailabilityZone: b.config.AvailabilityZone, BlockDevices: launchBlockDevices, Tags: b.config.RunTags, InstanceInitiatedShutdownBehavior: b.config.InstanceInitiatedShutdownBehavior, }, &stepTagEBSVolumes{ VolumeMapping: b.config.VolumeMappings, VolumeIDs: &volumeIds, }, &awscommon.StepGetPassword{ Debug: b.config.PackerDebug, Comm: &b.config.RunConfig.Comm, Timeout: b.config.WindowsPasswordTimeout, }, &communicator.StepConnect{ Config: &b.config.RunConfig.Comm, Host: awscommon.SSHHost( ec2conn, b.config.SSHPrivateIp), SSHConfig: awscommon.SSHConfig( b.config.RunConfig.Comm.SSHAgentAuth, b.config.RunConfig.Comm.SSHUsername, b.config.RunConfig.Comm.SSHPassword), }, &common.StepProvision{}, &awscommon.StepStopEBSBackedInstance{ SpotPrice: b.config.SpotPrice, DisableStopInstance: b.config.DisableStopInstance, }, &awscommon.StepModifyEBSBackedInstance{ EnableEnhancedNetworking: b.config.AMIEnhancedNetworking, }, } // Run! b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) b.runner.Run(state) // If there was an error, return that if rawErr, ok := state.GetOk("error"); ok { return nil, rawErr.(error) } ui.Say(fmt.Sprintf("Created Volumes: %s", strings.Join(*volumeIds, ", "))) return nil, nil }
func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { driver := &DockerDriver{Ctx: &b.config.ctx, Ui: ui} if err := driver.Verify(); err != nil { return nil, err } version, err := driver.Version() if err != nil { return nil, err } log.Printf("[DEBUG] Docker version: %s", version.String()) steps := []multistep.Step{ &StepTempDir{}, &StepPull{}, &StepRun{}, &communicator.StepConnect{ Config: &b.config.Comm, Host: commHost, SSHConfig: sshConfig(&b.config.Comm), CustomConnect: map[string]multistep.Step{ "docker": &StepConnectDocker{}, }, }, &common.StepProvision{}, } if b.config.Discard { log.Print("[DEBUG] Container will be discarded") } else if b.config.Commit { log.Print("[DEBUG] Container will be committed") steps = append(steps, new(StepCommit)) } else if b.config.ExportPath != "" { log.Printf("[DEBUG] Container will be exported to %s", b.config.ExportPath) steps = append(steps, new(StepExport)) } else { return nil, errArtifactNotUsed } // Setup the state bag and initial state for the steps state := new(multistep.BasicStateBag) state.Put("config", b.config) state.Put("hook", hook) state.Put("ui", ui) // Setup the driver that will talk to Docker state.Put("driver", driver) // Run! b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) b.runner.Run(state) // If there was an error, return that if rawErr, ok := state.GetOk("error"); ok { return nil, rawErr.(error) } // If it was cancelled, then just return if _, ok := state.GetOk(multistep.StateCancelled); ok { return nil, nil } // No errors, must've worked var artifact packer.Artifact if b.config.Commit { artifact = &ImportArtifact{ IdValue: state.Get("image_id").(string), BuilderIdValue: BuilderIdImport, Driver: driver, } } else { artifact = &ExportArtifact{path: b.config.ExportPath} } return artifact, nil }