예제 #1
0
func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, error) {
	ppName, ok := builtins[artifact.BuilderId()]
	if !ok {
		return nil, false, fmt.Errorf("Unknown artifact type, can't build box: %s", artifact.BuilderId())
	}

	// Use the premade PostProcessor if we have one. Otherwise, we
	// create it and configure it here.
	pp, ok := p.premade[ppName]
	if !ok {
		log.Printf("Premade post-processor for '%s' not found. Creating.", ppName)

		var err error
		pp, err = p.subPostProcessor(ppName, nil, p.extraConfig)
		if err != nil {
			return nil, false, err
		}

		if pp == nil {
			return nil, false, fmt.Errorf("Vagrant box post-processor not found: %s", ppName)
		}
	}

	ui.Say(fmt.Sprintf("Creating Vagrant box for '%s' provider", ppName))
	return pp.PostProcess(ui, artifact)
}
예제 #2
0
func RunLocalCommands(commands []string, wrappedCommand CommandWrapper, ctx interpolate.Context, ui packer.Ui) error {
	for _, rawCmd := range commands {
		intCmd, err := interpolate.Render(rawCmd, &ctx)
		if err != nil {
			return fmt.Errorf("Error interpolating: %s", err)
		}

		command, err := wrappedCommand(intCmd)
		if err != nil {
			return fmt.Errorf("Error wrapping command: %s", err)
		}

		ui.Say(fmt.Sprintf("Executing command: %s", command))
		comm := &shell_local.Communicator{}
		cmd := &packer.RemoteCmd{Command: command}
		if err := cmd.StartWithUi(comm, ui); err != nil {
			return fmt.Errorf("Error executing command: %s", err)
		}
		if cmd.ExitStatus != 0 {
			return fmt.Errorf(
				"Received non-zero exit code %d from command: %s",
				cmd.ExitStatus,
				command)
		}
	}
	return nil
}
예제 #3
0
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
}
예제 #4
0
func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, error) {
	ppName, ok := builtins[artifact.BuilderId()]
	if !ok {
		return nil, fmt.Errorf("Unknown artifact type, can't build box: %s", artifact.BuilderId())
	}

	// Use the premade PostProcessor if we have one. Otherwise, we
	// create it and configure it here.
	pp, ok := p.premade[ppName]
	if !ok {
		log.Printf("Premade post-processor for '%s' not found. Creating.", ppName)
		pp = keyToPostProcessor(ppName)
		if pp == nil {
			return nil, fmt.Errorf("Vagrant box post-processor not found: %s", ppName)
		}

		config := map[string]string{"output": p.config.OutputPath}
		if err := pp.Configure(config); err != nil {
			return nil, err
		}
	}

	ui.Say(fmt.Sprintf("Creating Vagrant box for '%s' provider", ppName))
	return pp.PostProcess(ui, artifact)
}
예제 #5
0
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
}
예제 #6
0
func delVNIC(ui packer.Ui, f *find.Finder, ctx context.Context, vm *object.VirtualMachine) error {
	ui.Say("Deleting NIC ")
	devicelst, err := vm.Device(ctx)
	if err != nil {
		return err
	}

	for _, device := range devicelst {

		switch device.(type) {
		case *types.VirtualVmxnet3:
			ui.Message(fmt.Sprintf("Removing NIC %s\n", device.GetVirtualDevice().DeviceInfo))
			err := vm.RemoveDevice(ctx, device)
			if err != nil {
				return err
			}
			return nil

		case *types.VirtualE1000:
			ui.Message(fmt.Sprintf("Removing NIC %s\n", device.GetVirtualDevice().DeviceInfo))
			err := vm.RemoveDevice(ctx, device)
			if err != nil {
				return err
			}
			return nil
		default:
			fmt.Printf("Type %s\n", reflect.TypeOf(device).Elem())
			fmt.Printf("Device info %s\n", device.GetVirtualDevice().DeviceInfo)

		}

	}

	return nil
} //
예제 #7
0
func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
	p.cancelLock.Lock()
	p.cancel = make(chan struct{})
	p.cancelLock.Unlock()

	ui.Say("Restarting Machine")
	p.comm = comm
	p.ui = ui

	var cmd *packer.RemoteCmd
	command := p.config.RestartCommand
	err := p.retryable(func() error {
		cmd = &packer.RemoteCmd{Command: command}
		return cmd.StartWithUi(comm, ui)
	})

	if err != nil {
		return err
	}

	if cmd.ExitStatus != 0 {
		return fmt.Errorf("Restart script exited with non-zero exit status: %d", cmd.ExitStatus)
	}

	return waitForRestart(p, comm)
}
예제 #8
0
func (p *Provisioner) Provision(ui packer.Ui, _ packer.Communicator) error {
	// Make another communicator for local
	comm := &Communicator{
		Ctx:            p.config.ctx,
		ExecuteCommand: p.config.ExecuteCommand,
	}

	// Build the remote command
	cmd := &packer.RemoteCmd{Command: p.config.Command}

	ui.Say(fmt.Sprintf(
		"Executing local command: %s",
		p.config.Command))
	if err := cmd.StartWithUi(comm, ui); err != nil {
		return fmt.Errorf(
			"Error executing command: %s\n\n"+
				"Please see output above for more information.",
			p.config.Command)
	}
	if cmd.ExitStatus != 0 {
		return fmt.Errorf(
			"Erroneous exit code %d while executing command: %s\n\n"+
				"Please see output above for more information.",
			cmd.ExitStatus,
			p.config.Command)
	}

	return nil
}
예제 #9
0
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
}
예제 #10
0
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
}
예제 #11
0
func (p *Provisioner) uploadDeploymentManifest(ui packer.Ui, comm packer.Communicator) error {
	ui.Say(fmt.Sprintf("Uploading manifest: %s", p.config.Manifest))

	err := runCmd("mkdir ~/deployments", ui, comm)
	if err != nil {
		return err
	}

	f, err := os.Open(p.config.Manifest)
	if err != nil {
		return err
	}
	defer f.Close()

	fi, err := f.Stat()
	if err != nil {
		return err
	}

	err = comm.Upload(fmt.Sprintf("~/deployments/%s", p.config.Manifest), f, &fi)
	if err != nil {
		return err
	}

	cmd := fmt.Sprintf("sed -i \"s/director_uuid: .*/director_uuid: $(bosh status --uuid)/\" ~/deployments/%s", p.config.Manifest)
	return runCmd(cmd, ui, comm)
}
예제 #12
0
func addVNIC(ui packer.Ui, f *find.Finder, ctx context.Context, c *govmomi.Client, vm *object.VirtualMachine, network string, nwType string) error {

	ui.Say("Adding NIC")

	nets, err := f.NetworkList(ctx, network)
	if err != nil {
		return err
	}
	// TODO expose param for DVS
	net := nets[1]

	backing, err := net.EthernetCardBackingInfo(ctx)
	if err != nil {
		return err
	}
	device, err := object.EthernetCardTypes().CreateEthernetCard(nwType, backing)
	if err != nil {
		return err
	}
	err = vm.AddDevice(ctx, device)
	if err != nil {
		return err
	}
	ui.Say("Adding NIC Success")

	return nil
} //
예제 #13
0
func (p *Provisioner) uploadManifests(ui packer.Ui, comm packer.Communicator) (string, error) {
	// Create the remote manifests directory...
	ui.Message("Uploading manifests...")
	remoteManifestsPath := fmt.Sprintf("%s/manifests", p.config.StagingDir)
	if err := p.createDir(ui, comm, remoteManifestsPath); err != nil {
		return "", fmt.Errorf("Error creating manifests directory: %s", err)
	}

	// Upload the main manifest
	f, err := os.Open(p.config.ManifestFile)
	if err != nil {
		return "", err
	}
	defer f.Close()

	manifestFilename := p.config.ManifestFile
	if fi, err := os.Stat(p.config.ManifestFile); err != nil {
		return "", fmt.Errorf("Error inspecting manifest file: %s", err)
	} else if !fi.IsDir() {
		manifestFilename = filepath.Base(manifestFilename)
	} else {
		ui.Say("WARNING: manifest_file should be a file. Use manifest_dir for directories")
	}

	remoteManifestFile := fmt.Sprintf("%s/%s", remoteManifestsPath, manifestFilename)
	if err := comm.Upload(remoteManifestFile, f, nil); err != nil {
		return "", err
	}

	return remoteManifestFile, nil
}
예제 #14
0
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{},
		NewStepGetOSDisk(azureClient, ui),
		NewStepPowerOffCompute(azureClient, ui),
		NewStepCaptureImage(azureClient, ui),
		NewStepDeleteResourceGroup(azureClient, ui),
		NewStepDeleteOSDisk(azureClient, ui),
	}

	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 = b.createRunner(&steps, 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.")
	}

	return &artifact{}, nil
}
예제 #15
0
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
}
예제 #16
0
func (p *Provisioner) cleanNode(ui packer.Ui, comm packer.Communicator, node string) error {
	ui.Say("Cleaning up chef node...")
	args := []string{"node", "delete", node}
	if err := p.knifeExec(ui, comm, node, args); err != nil {
		return fmt.Errorf("Failed to cleanup node: %s", err)
	}

	return nil
}
예제 #17
0
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
}
예제 #18
0
func (p *Provisioner) cleanClient(ui packer.Ui, comm packer.Communicator, node string, knifeConfigPath string) error {
	ui.Say("Cleaning up chef client...")
	args := []string{"client", "delete", node}
	if err := p.knifeExec(ui, comm, node, knifeConfigPath, args); err != nil {
		return fmt.Errorf("Failed to cleanup client: %s", err)
	}

	return nil
}
예제 #19
0
func (self *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, error) {
	ui.Say(fmt.Sprintf("Creating archive for '%s'", artifact.BuilderId()))

	// Create the compressed archive file at the appropriate OutputPath.
	fw, err := os.Create(self.config.OutputPath)
	if err != nil {
		return nil, false, fmt.Errorf(
			"Failed creating file for compressed archive: %s", self.config.OutputPath)
	}
	defer fw.Close()

	gw := gzip.NewWriter(fw)
	defer gw.Close()

	// Iterate through all of the artifact's files and put them into the
	// compressed archive using the tar/gzip writers.
	for _, path := range artifact.Files() {
		fi, err := os.Stat(path)
		if err != nil {
			return nil, false, fmt.Errorf(
				"Failed stating file: %s", path)
		}

		target, _ := os.Readlink(path)
		header, err := tar.FileInfoHeader(fi, target)
		if err != nil {
			return nil, false, fmt.Errorf(
				"Failed creating archive header: %s", path)
		}

		tw := tar.NewWriter(gw)
		defer tw.Close()

		// Write the header first to the archive. This takes partial data
		// from the FileInfo that is grabbed by running the stat command.
		if err := tw.WriteHeader(header); err != nil {
			return nil, false, fmt.Errorf(
				"Failed writing archive header: %s", path)
		}

		// Open the target file for archiving and compressing.
		fr, err := os.Open(path)
		if err != nil {
			return nil, false, fmt.Errorf(
				"Failed opening file '%s' to write compressed archive.", path)
		}
		defer fr.Close()

		if _, err = io.Copy(tw, fr); err != nil {
			return nil, false, fmt.Errorf(
				"Failed copying file to archive: %s", path)
		}
	}

	return NewArtifact(artifact.BuilderId(), self.config.OutputPath), false, nil
}
예제 #20
0
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()

	return comm.Upload(p.config.Destination, f)
}
예제 #21
0
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
}
예제 #22
0
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
}
예제 #23
0
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
}
예제 #24
0
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
}
예제 #25
0
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
}
예제 #26
0
func (p *Provisioner) uploadBoshRelease(ui packer.Ui, comm packer.Communicator) error {
	ui.Say(fmt.Sprintf("Uploading release %s", p.config.Release))

	cmd := fmt.Sprintf("bosh upload release --skip-if-exists https://bosh.io/d/github.com/%s", p.config.Release)
	if p.config.ReleaseVersion != "" {
		cmd += fmt.Sprintf("?v=%s", p.config.ReleaseVersion)
	}

	return runCmd(cmd, ui, comm)
}
예제 #27
0
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
}
예제 #28
0
func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, error) {
	if len(artifact.Files()) > 0 {
		ui.Say(fmt.Sprintf("Discarding artifact files: %s", strings.Join(artifact.Files(), ", ")))
	}

	artifact, err := NewArtifact(p.config.Files)
	ui.Say(fmt.Sprintf("Using these artifact files: %s", strings.Join(artifact.Files(), ", ")))

	return artifact, true, err
}
예제 #29
0
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
}
예제 #30
0
func (p *Provisioner) uploadStemcell(ui packer.Ui, comm packer.Communicator) error {
	ui.Say(fmt.Sprintf("Uploading stemcell %s", p.config.Stemcell))

	cmd := fmt.Sprintf("bosh upload stemcell --skip-if-exists https://bosh.io/d/stemcells/%s", p.config.Stemcell)
	if p.config.StemcellVersion != "" {
		cmd += fmt.Sprintf("?v=%s", p.config.StemcellVersion)
	}

	return runCmd(cmd, ui, comm)
}