func (p *Provisioner) ProvisionUpload(ui packer.Ui, comm packer.Communicator) error { ui.Say(fmt.Sprintf("Uploading %s => %s", p.config.Source, p.config.Destination)) info, err := os.Stat(p.config.Source) if err != nil { return err } // If we're uploading a directory, short circuit and do that if info.IsDir() { return comm.UploadDir(p.config.Destination, p.config.Source, nil) } // We're uploading a file... f, err := os.Open(p.config.Source) if err != nil { return err } defer f.Close() fi, err := f.Stat() if err != nil { return err } err = comm.Upload(p.config.Destination, f, &fi) if err != nil { ui.Error(fmt.Sprintf("Upload failed: %s", err)) } return err }
func (p *Provisioner) ProvisionDownload(ui packer.Ui, comm packer.Communicator) error { for _, src := range p.config.Sources { ui.Say(fmt.Sprintf("Downloading %s => %s", src, p.config.Destination)) if strings.HasSuffix(p.config.Destination, "/") { err := os.MkdirAll(p.config.Destination, os.FileMode(0755)) if err != nil { return err } return comm.DownloadDir(src, p.config.Destination, nil) } f, err := os.OpenFile(p.config.Destination, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644) if err != nil { return err } defer f.Close() err = comm.Download(src, f) if err != nil { ui.Error(fmt.Sprintf("Download failed: %s", err)) return err } } return nil }
func (p *Provisioner) ProvisionDownload(ui packer.Ui, comm packer.Communicator) error { for _, src := range p.config.Sources { ui.Say(fmt.Sprintf("Downloading %s => %s", src, p.config.Destination)) // ensure destination dir exists. p.config.Destination may either be a file or a dir. dir := p.config.Destination // if it doesn't end with a /, set dir as the parent dir if !strings.HasSuffix(p.config.Destination, "/") { dir = filepath.Dir(dir) } if dir != "" { err := os.MkdirAll(dir, os.FileMode(0755)) if err != nil { return err } } // if the config.Destination was a dir, download the dir if strings.HasSuffix(p.config.Destination, "/") { return comm.DownloadDir(src, p.config.Destination, nil) } f, err := os.OpenFile(p.config.Destination, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644) if err != nil { return err } defer f.Close() err = comm.Download(src, f) if err != nil { ui.Error(fmt.Sprintf("Download failed: %s", err)) return err } } return nil }
func (t *tunnel) Provision(ui packer.Ui, comm packer.Communicator) error { ui.Say("Starting tunnel") t.server.comm = comm errc := make(chan error, 1) go func() { errc <- t.server.serveOne() }() stdout := &lineWriter{output: ui.Say} stderr := &lineWriter{output: ui.Error} cmd := exec.Command(t.Exec, t.Args...) cmd.Env = append(os.Environ(), "PACKER_TUNNEL_USERNAME="******"PACKER_TUNNEL_PASSWORD="******"PACKER_TUNNEL_PORT="+strconv.Itoa(t.server.port), ) cmd.Stdout = stdout cmd.Stderr = stderr log.Println("Command", cmd.Args, "env", cmd.Env) ui.Say("Running command " + strings.Join(cmd.Args, " ")) err := cmd.Run() stdout.Flush() stderr.Flush() if err != nil { ui.Error(fmt.Sprintf("Error running command %s", err)) return err } return <-errc }
func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, error) { if artifact.BuilderId() != dockerimport.BuilderId { err := fmt.Errorf( "Unknown artifact type: %s\nCan only tag from Docker builder artifacts.", artifact.BuilderId()) return nil, false, err } dockerfile, template_err := p.render_template(trim_artifact_id(artifact.Id())) if template_err != nil { // could not render template return nil, false, template_err } log.Printf("[DEBUG] Dockerfile: %s\n", dockerfile.String()) if image_id, err := p.docker_build_fn(dockerfile); err != nil { // docker build command failed ui.Error("docker build command failed: " + err.Error()) return nil, false, err } else { ui.Message("Built image: " + image_id) new_artifact := &docker.ImportArtifact{ BuilderIdValue: dockerimport.BuilderId, Driver: &docker.DockerDriver{Ui: ui, Tpl: nil}, IdValue: image_id, } log.Printf("[DEBUG] artifact: %#v\n", new_artifact) return new_artifact, true, nil } }
// Prepares the signal handlers so that we handle interrupts properly. // The signal handler exists in a goroutine. func setupSignalHandlers(ui packer.Ui) { ch := make(chan os.Signal, 1) signal.Notify(ch, os.Interrupt) signal.Notify(ch, syscall.SIGTERM) go func() { // First interrupt. We mostly ignore this because it allows the // plugins time to cleanup. <-ch log.Println("First interrupt. Ignoring to allow plugins to clean up.") ui.Error("Interrupt signal received. Cleaning up...") // Second interrupt. Go down hard. <-ch log.Println("Second interrupt. Exiting now.") ui.Error("Interrupt signal received twice. Forcefully exiting now.") // Force kill all the plugins, but mark that we're killing them // first so that we don't get panics everywhere. plugin.CleanupClients() os.Exit(1) }() }
func (p *Provisioner) executeAnsible(ui packer.Ui, comm packer.Communicator, privKeyFile string, checkHostKey bool) error { playbook, _ := filepath.Abs(p.config.PlaybookFile) inventory := p.config.inventoryFile var envvars []string args := []string{playbook, "-i", inventory} if len(privKeyFile) > 0 { args = append(args, "--private-key", privKeyFile) } args = append(args, p.config.ExtraArguments...) if len(p.config.AnsibleEnvVars) > 0 { envvars = append(envvars, p.config.AnsibleEnvVars...) } cmd := exec.Command(p.config.Command, args...) cmd.Env = os.Environ() if len(envvars) > 0 { cmd.Env = append(cmd.Env, envvars...) } if !checkHostKey { cmd.Env = append(cmd.Env, "ANSIBLE_HOST_KEY_CHECKING=False") } stdout, err := cmd.StdoutPipe() if err != nil { return err } stderr, err := cmd.StderrPipe() if err != nil { return err } wg := sync.WaitGroup{} repeat := func(r io.ReadCloser) { scanner := bufio.NewScanner(r) for scanner.Scan() { ui.Message(scanner.Text()) } if err := scanner.Err(); err != nil { ui.Error(err.Error()) } wg.Done() } wg.Add(2) go repeat(stdout) go repeat(stderr) ui.Say(fmt.Sprintf("Executing Ansible: %s", strings.Join(cmd.Args, " "))) cmd.Start() wg.Wait() err = cmd.Wait() if err != nil { return fmt.Errorf("Non-zero exit status: %s", err) } return nil }
func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, error) { if artifact.BuilderId() != dockerimport.BuilderId && artifact.BuilderId() != dockertag.BuilderId { err := fmt.Errorf( "Unknown artifact type: %s\nCan only import from docker-import and docker-tag artifacts.", artifact.BuilderId()) return nil, false, err } driver := p.Driver if driver == nil { // If no driver is set, then we use the real driver driver = &docker.DockerDriver{Ctx: &p.config.ctx, Ui: ui} } if p.config.EcrLogin { ui.Message("Fetching ECR credentials...") username, password, err := p.config.EcrGetLogin(p.config.LoginServer) if err != nil { return nil, false, err } p.config.LoginUsername = username p.config.LoginPassword = password } if p.config.Login || p.config.EcrLogin { ui.Message("Logging in...") err := driver.Login( p.config.LoginServer, p.config.LoginEmail, p.config.LoginUsername, p.config.LoginPassword) if err != nil { return nil, false, fmt.Errorf( "Error logging in to Docker: %s", err) } defer func() { ui.Message("Logging out...") if err := driver.Logout(p.config.LoginServer); err != nil { ui.Error(fmt.Sprintf("Error logging out: %s", err)) } }() } // Get the name. name := artifact.Id() ui.Message("Pushing: " + name) if err := driver.Push(name); err != nil { return nil, false, err } return nil, false, nil }
func NewStepSetCertificate(config *Config, ui packer.Ui) *StepSetCertificate { var step = &StepSetCertificate{ config: config, say: func(message string) { ui.Say(message) }, error: func(e error) { ui.Error(e.Error()) }, } return step }
func NewStepGetIPAddress(client *AzureClient, ui packer.Ui) *StepGetIPAddress { var step = &StepGetIPAddress{ client: client, say: func(message string) { ui.Say(message) }, error: func(e error) { ui.Error(e.Error()) }, } step.get = step.getIPAddress return step }
func NewStepPowerOffCompute(client *AzureClient, ui packer.Ui) *StepPowerOffCompute { var step = &StepPowerOffCompute{ client: client, say: func(message string) { ui.Say(message) }, error: func(e error) { ui.Error(e.Error()) }, } step.powerOff = step.powerOffCompute return step }
func NewStepDeleteOSDisk(client *AzureClient, ui packer.Ui) *StepDeleteOSDisk { var step = &StepDeleteOSDisk{ client: client, say: func(message string) { ui.Say(message) }, error: func(e error) { ui.Error(e.Error()) }, } step.delete = step.deleteBlob return step }
func NewStepGetOSDisk(client *AzureClient, ui packer.Ui) *StepGetOSDisk { var step = &StepGetOSDisk{ client: client, say: func(message string) { ui.Say(message) }, error: func(e error) { ui.Error(e.Error()) }, } step.query = step.queryCompute return step }
func NewStepCreateResourceGroup(client *AzureClient, ui packer.Ui) *StepCreateResourceGroup { var step = &StepCreateResourceGroup{ client: client, say: func(message string) { ui.Say(message) }, error: func(e error) { ui.Error(e.Error()) }, } step.create = step.createResourceGroup return step }
func NewStepCaptureImage(client *AzureClient, ui packer.Ui) *StepCaptureImage { var step = &StepCaptureImage{ client: client, say: func(message string) { ui.Say(message) }, error: func(e error) { ui.Error(e.Error()) }, } step.capture = step.captureImage return step }
func NewStepDeployTemplate(client *AzureClient, ui packer.Ui) *StepDeployTemplate { var step = &StepDeployTemplate{ client: client, say: func(message string) { ui.Say(message) }, error: func(e error) { ui.Error(e.Error()) }, } step.deploy = step.deployTemplate return step }
func (p *Provisioner) ProvisionUpload(ui packer.Ui, comm packer.Communicator) error { ui.Say(fmt.Sprintf("Uploading %s => %s", p.config.Source, p.config.Destination)) info, _ := os.Stat(p.config.Source) if info != nil { // If we're uploading a directory, short circuit and do that if info.IsDir() { return comm.UploadDir(p.config.Destination, p.config.Source, nil) } } pwd, err := os.Getwd() if err != nil { return fmt.Errorf("Couldn't get the current working directory") } det, err := gg.Detect(p.config.Source, pwd, gg.Detectors) if err != nil { return fmt.Errorf("Couldn't detect file source type: %v", err) } if len(det) == 0 { return errors.New("Don't recognise the source type") } dir, err := ioutil.TempDir("", "packer") if err != nil { return errors.New("Unable to create temp dir") } defer os.RemoveAll(dir) source := filepath.Join(dir, filepath.Base(p.config.Source)) if err := gg.GetFile(source, p.config.Source); err != nil { return fmt.Errorf("There was a problem getting the file: %v", err) } // We're uploading a file... f, err := os.Open(source) if err != nil { return err } defer f.Close() fi, err := f.Stat() if err != nil { return err } err = comm.Upload(p.config.Destination, f, &fi) if err != nil { ui.Error(fmt.Sprintf("Upload failed: %s", err)) } return err }
func NewStepValidateTemplate(client *AzureClient, ui packer.Ui, template string) *StepValidateTemplate { var step = &StepValidateTemplate{ client: client, template: template, say: func(message string) { ui.Say(message) }, error: func(e error) { ui.Error(e.Error()) }, } step.validate = step.validateTemplate return step }
func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, error) { if artifact.BuilderId() != dockerimport.BuilderId && artifact.BuilderId() != dockertag.BuilderId { err := fmt.Errorf( "Unknown artifact type: %s\nCan only import from docker-import and docker-tag artifacts.", artifact.BuilderId()) return nil, false, err } driver := p.Driver if driver == nil { // If no driver is set, then we use the real driver driver = &docker.DockerDriver{Ctx: &p.config.ctx, Ui: ui} } if p.config.Login { ui.Message("Logging in...") err := driver.Login( p.config.LoginServer, p.config.LoginEmail, p.config.LoginUsername, p.config.LoginPassword) if err != nil { return nil, false, fmt.Errorf( "Error logging in to Docker: %s", err) } defer func() { ui.Message("Logging out...") if err := driver.Logout(p.config.LoginServer); err != nil { ui.Error(fmt.Sprintf("Error logging out: %s", err)) } }() } // Get the name. We strip off any tags from the name because the // push doesn't use those. name := artifact.Id() if i := strings.Index(name, "/"); i >= 0 { // This should always be true because the / is required. But we have // to get the index to this so we don't accidentally strip off the port if j := strings.Index(name[i:], ":"); j >= 0 { name = name[:i+j] } } ui.Message("Pushing: " + name) if err := driver.Push(name); err != nil { return nil, false, err } return nil, false, nil }
func NewStepGetCertificate(client *AzureClient, ui packer.Ui) *StepGetCertificate { var step = &StepGetCertificate{ client: client, say: func(message string) { ui.Say(message) }, error: func(e error) { ui.Error(e.Error()) }, pause: func() { time.Sleep(30 * time.Second) }, } step.get = step.getCertificateUrl return step }
func NewStepValidateTemplate(client *AzureClient, ui packer.Ui, config *Config, factory templateFactoryFunc) *StepValidateTemplate { var step = &StepValidateTemplate{ client: client, say: func(message string) { ui.Say(message) }, error: func(e error) { ui.Error(e.Error()) }, config: config, factory: factory, } step.validate = step.validateTemplate return step }
func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { ui.Say(fmt.Sprintf("Uploading %s => %s", p.config.Source, p.config.Destination)) f, err := os.Open(p.config.Source) if err != nil { return err } defer f.Close() err = comm.Upload(p.config.Destination, f) if err != nil { ui.Error(fmt.Sprintf("Upload failed: %s", err)) } return err }
func (p *Provisioner) ProvisionDownload(ui packer.Ui, comm packer.Communicator) error { ui.Say(fmt.Sprintf("Downloading %s => %s", p.config.Source, p.config.Destination)) f, err := os.OpenFile(p.config.Destination, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644) if err != nil { return err } defer f.Close() err = comm.Download(p.config.Source, f) if err != nil { ui.Error(fmt.Sprintf("Download failed: %s", err)) } return err }
func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { ui.Say("Preparing builder ...") b.stateBag.Put("hook", hook) b.stateBag.Put(constants.Ui, ui) servicePrincipalToken, err := b.createServicePrincipalToken() 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, servicePrincipalToken) if err != nil { return nil, err } steps := []multistep.Step{ NewStepCreateResourceGroup(azureClient, ui), NewStepValidateTemplate(azureClient, ui), NewStepDeployTemplate(azureClient, ui), NewStepGetIPAddress(azureClient, ui), &communicator.StepConnectSSH{ Config: &b.config.Comm, Host: lin.SSHHost, SSHConfig: lin.SSHConfig(b.config.UserName), }, &common.StepProvision{}, &lin.StepGeneralizeOS{ Command: "sudo /usr/sbin/waagent -force -deprovision+user && export HISTSIZE=0 && sync", }, NewStepGetOSDisk(azureClient, ui), NewStepPowerOffCompute(azureClient, ui), NewStepCaptureImage(azureClient, ui), NewStepDeleteResourceGroup(azureClient, ui), NewStepDeleteOSDisk(azureClient, ui), } b.runner = b.createRunner(&steps, ui) b.runner.Run(b.stateBag) if e, ok := b.stateBag.GetOk(constants.Error); ok { ui.Error(e.(string)) } return &artifact{}, nil }
func NewStepGetIPAddress(client *AzureClient, ui packer.Ui, endpoint EndpointType) *StepGetIPAddress { var step = &StepGetIPAddress{ client: client, endpoint: endpoint, say: func(message string) { ui.Say(message) }, error: func(e error) { ui.Error(e.Error()) }, } switch endpoint { case PrivateEndpoint: step.get = step.getPrivateIP case PublicEndpoint: step.get = step.getPublicIP } return step }
func (p *Provisioner) executeAnsible(ui packer.Ui, comm packer.Communicator) error { playbook, _ := filepath.Abs(p.config.PlaybookFile) inventory := p.config.inventoryFile args := []string{playbook, "-i", inventory} args = append(args, p.config.ExtraArguments...) cmd := exec.Command(p.config.Command, args...) stdout, err := cmd.StdoutPipe() if err != nil { return err } stderr, err := cmd.StderrPipe() if err != nil { return err } wg := sync.WaitGroup{} repeat := func(r io.ReadCloser) { scanner := bufio.NewScanner(r) for scanner.Scan() { ui.Message(scanner.Text()) } if err := scanner.Err(); err != nil { ui.Error(err.Error()) } wg.Done() } wg.Add(2) go repeat(stdout) go repeat(stderr) ui.Say(fmt.Sprintf("Executing Ansible: %s", strings.Join(cmd.Args, " "))) cmd.Start() wg.Wait() err = cmd.Wait() if err != nil { return fmt.Errorf("Non-zero exit status: %s", err) } return nil }
func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { ui.Say(fmt.Sprintf("Provisioning with windows-shell...")) scripts := make([]string, len(p.config.Scripts)) copy(scripts, p.config.Scripts) // Build our variables up by adding in the build name and builder type envVars := make([]string, len(p.config.Vars)+2) envVars[0] = "PACKER_BUILD_NAME=" + p.config.PackerBuildName envVars[1] = "PACKER_BUILDER_TYPE=" + p.config.PackerBuilderType copy(envVars, p.config.Vars) if p.config.Inline != nil { temp, err := extractScript(p) if err != nil { ui.Error(fmt.Sprintf("Unable to extract inline scripts into a file: %s", err)) } scripts = append(scripts, temp) } for _, path := range scripts { ui.Say(fmt.Sprintf("Provisioning with shell script: %s", path)) log.Printf("Opening %s for reading", path) f, err := os.Open(path) if err != nil { return fmt.Errorf("Error opening shell script: %s", err) } defer f.Close() // Create environment variables to set before executing the command flattendVars, err := p.createFlattenedEnvVars() if err != nil { return err } // Compile the command p.config.ctx.Data = &ExecuteCommandTemplate{ Vars: flattendVars, Path: p.config.RemotePath, } command, err := interpolate.Render(p.config.ExecuteCommand, &p.config.ctx) if err != nil { return fmt.Errorf("Error processing command: %s", err) } // Upload the file and run the command. Do this in the context of // a single retryable function so that we don't end up with // the case that the upload succeeded, a restart is initiated, // and then the command is executed but the file doesn't exist // any longer. var cmd *packer.RemoteCmd err = p.retryable(func() error { if _, err := f.Seek(0, 0); err != nil { return err } if err := comm.Upload(p.config.RemotePath, f, nil); err != nil { return fmt.Errorf("Error uploading script: %s", err) } cmd = &packer.RemoteCmd{Command: command} return cmd.StartWithUi(comm, ui) }) if err != nil { return err } // Close the original file since we copied it f.Close() if cmd.ExitStatus != 0 { return fmt.Errorf("Script exited with non-zero exit status: %d", cmd.ExitStatus) } } return nil }
func (p *Provisioner) executeAnsible(ui packer.Ui, comm packer.Communicator, privKeyFile string) error { playbook, _ := filepath.Abs(p.config.PlaybookFile) inventory := p.config.inventoryFile var envvars []string args := []string{playbook, "-i", inventory} if len(privKeyFile) > 0 { args = append(args, "--private-key", privKeyFile) } args = append(args, p.config.ExtraArguments...) if len(p.config.AnsibleEnvVars) > 0 { envvars = append(envvars, p.config.AnsibleEnvVars...) } cmd := exec.Command(p.config.Command, args...) cmd.Env = os.Environ() if len(envvars) > 0 { cmd.Env = append(cmd.Env, envvars...) } stdout, err := cmd.StdoutPipe() if err != nil { return err } stderr, err := cmd.StderrPipe() if err != nil { return err } wg := sync.WaitGroup{} repeat := func(r io.ReadCloser) { reader := bufio.NewReader(r) for { line, err := reader.ReadString('\n') if line != "" { line = strings.TrimRightFunc(line, unicode.IsSpace) ui.Message(line) } if err != nil { if err == io.EOF { break } else { ui.Error(err.Error()) break } } } wg.Done() } wg.Add(2) go repeat(stdout) go repeat(stderr) log.Printf("Executing Ansible: %s", strings.Join(cmd.Args, " ")) cmd.Start() wg.Wait() err = cmd.Wait() if err != nil { return fmt.Errorf("Non-zero exit status: %s", err) } return nil }
func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { ui.Say(fmt.Sprintf("Provisioning with Powershell...")) p.communicator = comm scripts := make([]string, len(p.config.Scripts)) copy(scripts, p.config.Scripts) // Build our variables up by adding in the build name and builder type envVars := make([]string, len(p.config.Vars)+2) envVars[0] = "PACKER_BUILD_NAME=" + p.config.PackerBuildName envVars[1] = "PACKER_BUILDER_TYPE=" + p.config.PackerBuilderType copy(envVars, p.config.Vars) if p.config.Inline != nil { temp, err := extractScript(p) if err != nil { ui.Error(fmt.Sprintf("Unable to extract inline scripts into a file: %s", err)) } scripts = append(scripts, temp) } for _, path := range scripts { ui.Say(fmt.Sprintf("Provisioning with shell script: %s", path)) log.Printf("Opening %s for reading", path) f, err := os.Open(path) if err != nil { return fmt.Errorf("Error opening shell script: %s", err) } defer f.Close() command, err := p.createCommandText() if err != nil { return fmt.Errorf("Error processing command: %s", err) } // Upload the file and run the command. Do this in the context of // a single retryable function so that we don't end up with // the case that the upload succeeded, a restart is initiated, // and then the command is executed but the file doesn't exist // any longer. var cmd *packer.RemoteCmd err = p.retryable(func() error { if _, err := f.Seek(0, 0); err != nil { return err } if err := comm.Upload(p.config.RemotePath, f, nil); err != nil { return fmt.Errorf("Error uploading script: %s", err) } cmd = &packer.RemoteCmd{Command: command} return cmd.StartWithUi(comm, ui) }) if err != nil { return err } // Close the original file since we copied it f.Close() // Check exit code against allowed codes (likely just 0) validExitCode := false for _, v := range p.config.ValidExitCodes { if cmd.ExitStatus == v { validExitCode = true } } if !validExitCode { return fmt.Errorf( "Script exited with non-zero exit status: %d. Allowed exit codes are: %v", cmd.ExitStatus, p.config.ValidExitCodes) } } return nil }