예제 #1
0
파일: builder.go 프로젝트: vvchik/packer
// Run executes a Packer build and returns a packer.Artifact representing
// a Hyperv appliance.
func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) {
	// Create the driver that we'll use to communicate with Hyperv
	driver, err := hypervcommon.NewHypervPS4Driver()
	if err != nil {
		return nil, fmt.Errorf("Failed creating Hyper-V driver: %s", 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)

	steps := []multistep.Step{
		&hypervcommon.StepCreateTempDir{},
		&hypervcommon.StepOutputDir{
			Force: b.config.PackerForce,
			Path:  b.config.OutputDir,
		},
		&common.StepCreateFloppy{
			Files: b.config.FloppyFiles,
		},
		&hypervcommon.StepHTTPServer{
			HTTPDir:     b.config.HTTPDir,
			HTTPPortMin: b.config.HTTPPortMin,
			HTTPPortMax: b.config.HTTPPortMax,
		},
		&hypervcommon.StepCreateSwitch{
			SwitchName: b.config.SwitchName,
		},
		&hypervcommon.StepCreateVM{
			VMName:          b.config.VMName,
			SwitchName:      b.config.SwitchName,
			RamSizeMB:       b.config.RamSizeMB,
			DiskSize:        b.config.DiskSize,
			Generation:      b.config.Generation,
			Cpu:             b.config.Cpu,
			EnabeSecureBoot: b.config.EnableSecureBoot,
		},
		&hypervcommon.StepConfigureVlan{
			VlanId: b.config.VlanId,
		},
		&hypervcommon.StepEnableIntegrationService{},

		&hypervcommon.StepMountDvdDrive{
			RawSingleISOUrl: b.config.RawSingleISOUrl,
		},
		&hypervcommon.StepMountFloppydrive{},

		&hypervcommon.StepMountSecondaryDvdImages{
			Files:      b.config.SecondaryDvdImages,
			Generation: b.config.Generation,
		},

		&hypervcommon.StepRun{
			BootWait: b.config.BootWait,
			Headless: b.config.Headless,
		},

		&hypervcommon.StepTypeBootCommand{
			BootCommand: b.config.BootCommand,
			SwitchName:  b.config.SwitchName,
			Ctx:         b.config.ctx,
		},

		// configure the communicator ssh, winrm
		&communicator.StepConnect{
			Config:    &b.config.SSHConfig.Comm,
			Host:      hypervcommon.CommHost,
			SSHConfig: hypervcommon.SSHConfigFunc(&b.config.SSHConfig),
		},

		// provision requires communicator to be setup
		&common.StepProvision{},

		&hypervcommon.StepShutdown{
			Command: b.config.ShutdownCommand,
			Timeout: b.config.ShutdownTimeout,
		},

		// wait for the vm to be powered off
		&hypervcommon.StepWaitForPowerOff{},

		// remove the integration services dvd drive
		// after we power down
		&hypervcommon.StepUnmountSecondaryDvdImages{},
		&hypervcommon.StepUnmountFloppyDrive{
			Generation: b.config.Generation,
		},
		&hypervcommon.StepUnmountDvdDrive{},

		&hypervcommon.StepExportVm{
			OutputDir:      b.config.OutputDir,
			SkipCompaction: b.config.SkipCompaction,
		},

		// the clean up actions for each step will be executed reverse order
	}

	// Run the steps.
	if b.config.PackerDebug {
		b.runner = &multistep.DebugRunner{
			Steps:   steps,
			PauseFn: common.MultistepDebugFn(ui),
		}
	} else {
		b.runner = &multistep.BasicRunner{Steps: steps}
	}
	b.runner.Run(state)

	// Report any errors.
	if rawErr, ok := state.GetOk("error"); ok {
		return nil, rawErr.(error)
	}

	// If we were interrupted or cancelled, then just exit.
	if _, ok := state.GetOk(multistep.StateCancelled); ok {
		return nil, errors.New("Build was cancelled.")
	}

	if _, ok := state.GetOk(multistep.StateHalted); ok {
		return nil, errors.New("Build was halted.")
	}

	return hypervcommon.NewArtifact(b.config.OutputDir)
}
예제 #2
0
func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) {
	// Create the driver that we'll use to communicate with Hyperv
	driver, err := hypervcommon.NewHypervPS4Driver()
	if err != nil {
		return nil, fmt.Errorf("Failed creating Hyper-V driver: %s", 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)

	steps := []multistep.Step{

		new(hypervcommon.StepCreateTempDir),

		&hypervcommon.StepOutputDir{
			Force: b.config.PackerForce,
			Path:  b.config.OutputDir,
		},

		//		&hypervcommon.StepSetUnattendedProductKey{
		//			Files: b.config.FloppyFiles,
		//			ProductKey: b.config.ProductKey,
		//		},

		&common.StepCreateFloppy{
			Files: b.config.FloppyFiles,
		},

		&hypervcommon.StepCreateSwitch{
			SwitchName: b.config.SwitchName,
		},

		new(StepCreateVM),

		new(hypervcommon.StepEnableIntegrationService),

		new(StepMountDvdDrive),

		new(StepMountFloppydrive),

		//TODO: new(StepMountSecondaryDvdImages),

		new(hypervcommon.StepStartVm),

		// wait for the vm to be powered off
		&hypervcommon.StepWaitForPowerOff{},

		//TODO: &hypervcommon.StepUnmountSecondaryDvdImages{},

		new(hypervcommon.StepConfigureIp),

		new(hypervcommon.StepSetRemoting),

		new(common.StepProvision),

		new(StepExportVm),

		//		new(hypervcommon.StepConfigureIp),
		//		new(hypervcommon.StepSetRemoting),
		//		new(hypervcommon.StepCheckRemoting),
		//		new(msbldcommon.StepSysprep),
	}

	// Run the steps.
	if b.config.PackerDebug {
		b.runner = &multistep.DebugRunner{
			Steps:   steps,
			PauseFn: common.MultistepDebugFn(ui),
		}
	} else {
		b.runner = &multistep.BasicRunner{Steps: steps}
	}
	b.runner.Run(state)

	// Report any errors.
	if rawErr, ok := state.GetOk("error"); ok {
		return nil, rawErr.(error)
	}

	// If we were interrupted or cancelled, then just exit.
	if _, ok := state.GetOk(multistep.StateCancelled); ok {
		return nil, errors.New("Build was cancelled.")
	}

	if _, ok := state.GetOk(multistep.StateHalted); ok {
		return nil, errors.New("Build was halted.")
	}

	return hypervcommon.NewArtifact(b.config.OutputDir)
}