Test should run and pass even when run on an environment that does not have Powershel.

This commit is contained in:
Taliesin Sisson 2016-06-30 20:21:57 +01:00
parent 8c3239770d
commit 52c6cd5fc1
4 changed files with 80 additions and 54 deletions

View File

@ -7,6 +7,11 @@ package iso
import (
"errors"
"fmt"
"log"
"os"
"strings"
"time"
"github.com/mitchellh/multistep"
hypervcommon "github.com/mitchellh/packer/builder/hyperv/common"
"github.com/mitchellh/packer/common"
@ -16,10 +21,6 @@ import (
powershell "github.com/mitchellh/packer/powershell"
"github.com/mitchellh/packer/powershell/hyperv"
"github.com/mitchellh/packer/template/interpolate"
"log"
"os"
"strings"
"time"
)
const (
@ -148,13 +149,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
log.Println(fmt.Sprintf("%s: %v", "VMName", b.config.VMName))
if b.config.SwitchName == "" {
// no switch name, try to get one attached to a online network adapter
onlineSwitchName, err := hyperv.GetExternalOnlineVirtualSwitch()
if onlineSwitchName == "" || err != nil {
b.config.SwitchName = fmt.Sprintf("packer-%s", b.config.PackerBuildName)
} else {
b.config.SwitchName = onlineSwitchName
}
b.config.SwitchName = b.detectSwitchName()
}
if b.config.Cpu < 1 {
@ -455,11 +450,29 @@ func (b *Builder) checkRamSize() error {
}
func (b *Builder) checkHostAvailableMemory() string {
freeMB := powershell.GetHostAvailableMemory()
powershellAvailable, _, _ := powershell.IsPowershellAvailable()
if (freeMB - float64(b.config.RamSizeMB)) < LowRam {
return fmt.Sprintf("Hyper-V might fail to create a VM if there is not enough free memory in the system.")
if powershellAvailable {
freeMB := powershell.GetHostAvailableMemory()
if (freeMB - float64(b.config.RamSizeMB)) < LowRam {
return fmt.Sprintf("Hyper-V might fail to create a VM if there is not enough free memory in the system.")
}
}
return ""
}
func (b *Builder) detectSwitchName() string {
powershellAvailable, _, _ := powershell.IsPowershellAvailable()
if powershellAvailable {
// no switch name, try to get one attached to a online network adapter
onlineSwitchName, err := hyperv.GetExternalOnlineVirtualSwitch()
if onlineSwitchName != "" && err == nil {
return onlineSwitchName
}
}
return fmt.Sprintf("packer-%s", b.config.PackerBuildName)
}

View File

@ -1,9 +1,10 @@
package iso
import (
"github.com/mitchellh/packer/packer"
"reflect"
"testing"
"github.com/mitchellh/packer/packer"
)
func testConfig() map[string]interface{} {
@ -31,6 +32,7 @@ func TestBuilder_ImplementsBuilder(t *testing.T) {
func TestBuilderPrepare_Defaults(t *testing.T) {
var b Builder
config := testConfig()
warns, err := b.Prepare(config)
if len(warns) > 0 {
t.Fatalf("bad: %#v", warns)

View File

@ -5,20 +5,20 @@
package powershell
import (
"bytes"
"fmt"
"log"
"io"
"io/ioutil"
"log"
"os"
"os/exec"
"strings"
"bytes"
"io/ioutil"
"strconv"
"strings"
)
const (
powerShellFalse = "False"
powerShellTrue = "True"
powerShellTrue = "True"
)
type PowerShellCmd struct {
@ -31,14 +31,14 @@ func (ps *PowerShellCmd) Run(fileContents string, params ...string) error {
return err
}
// Output runs the PowerShell command and returns its standard output.
// Output runs the PowerShell command and returns its standard output.
func (ps *PowerShellCmd) Output(fileContents string, params ...string) (string, error) {
path, err := ps.getPowerShellPath();
path, err := ps.getPowerShellPath()
if err != nil {
return "", nil
return "", err
}
filename, err := saveScript(fileContents);
filename, err := saveScript(fileContents)
if err != nil {
return "", err
}
@ -49,7 +49,7 @@ func (ps *PowerShellCmd) Output(fileContents string, params ...string) (string,
if !debug {
defer os.Remove(filename)
}
args := createArgs(filename, params...)
if verbose {
@ -93,13 +93,23 @@ func (ps *PowerShellCmd) Output(fileContents string, params ...string) (string,
log.Printf("stderr: %s", stderrString)
}
return stdoutString, err;
return stdoutString, err
}
func IsPowershellAvailable() (bool, string, error) {
path, err := exec.LookPath("powershell")
if err != nil {
return false, "", err
} else {
return false, path, err
}
}
func (ps *PowerShellCmd) getPowerShellPath() (string, error) {
path, err := exec.LookPath("powershell")
if err != nil {
log.Fatal("Cannot find PowerShell in the path", err)
powershellAvailable, path, err := IsPowershellAvailable()
if !powershellAvailable {
log.Fatal("Cannot find PowerShell in the path")
return "", err
}
@ -111,7 +121,7 @@ func saveScript(fileContents string) (string, error) {
if err != nil {
return "", err
}
_, err = file.Write([]byte(fileContents))
if err != nil {
return "", err
@ -132,7 +142,7 @@ func saveScript(fileContents string) (string, error) {
}
func createArgs(filename string, params ...string) []string {
args := make([]string,len(params)+4)
args := make([]string, len(params)+4)
args[0] = "-ExecutionPolicy"
args[1] = "Bypass"
@ -141,9 +151,9 @@ func createArgs(filename string, params ...string) []string {
for key, value := range params {
args[key+4] = value
}
}
return args;
return args
}
func GetHostAvailableMemory() float64 {
@ -158,7 +168,6 @@ func GetHostAvailableMemory() float64 {
return freeMB
}
func GetHostName(ip string) (string, error) {
var script = `
@ -174,7 +183,7 @@ try {
//
var ps PowerShellCmd
cmdOut, err := ps.Output(script, ip);
cmdOut, err := ps.Output(script, ip)
if err != nil {
return "", err
}
@ -190,8 +199,8 @@ $administratorRole = [System.Security.Principal.WindowsBuiltInRole]::Administrat
return $principal.IsInRole($administratorRole)
`
var ps PowerShellCmd
cmdOut, err := ps.Output(script);
var ps PowerShellCmd
cmdOut, err := ps.Output(script)
if err != nil {
return false, err
}
@ -200,14 +209,13 @@ return $principal.IsInRole($administratorRole)
return res == powerShellTrue, nil
}
func ModuleExists(moduleName string) (bool, error) {
var script = `
param([string]$moduleName)
(Get-Module -Name $moduleName) -ne $null
`
var ps PowerShellCmd
var ps PowerShellCmd
cmdOut, err := ps.Output(script)
if err != nil {
return false, err
@ -215,7 +223,7 @@ param([string]$moduleName)
res := strings.TrimSpace(string(cmdOut))
if(res == powerShellFalse){
if res == powerShellFalse {
err := fmt.Errorf("PowerShell %s module is not loaded. Make sure %s feature is on.", moduleName, moduleName)
return false, err
}
@ -249,7 +257,7 @@ $productKeyNode.InnerText = $productKey
$unattend.Save($path)
`
var ps PowerShellCmd
err := ps.Run(script, path, productKey)
return err
var ps PowerShellCmd
err := ps.Run(script, path, productKey)
return err
}

View File

@ -6,11 +6,13 @@ import (
)
func TestOutput(t *testing.T) {
var ps PowerShellCmd
powerShellPath, err := ps.getPowerShellPath()
if err != nil {
t.Skipf("powershell not installed: %s", err)
powershellAvailable, _, _ := IsPowershellAvailable()
if !powershellAvailable {
t.Skipf("powershell not installed")
return
}
@ -43,17 +45,18 @@ func TestOutput(t *testing.T) {
}
func TestRunFile(t *testing.T) {
var ps PowerShellCmd
powershellAvailable, _, _ := IsPowershellAvailable()
if !powershellAvailable {
t.Skipf("powershell not installed")
return
}
var blockBuffer bytes.Buffer
blockBuffer.WriteString(`param([string]$a, [string]$b, [int]$x, [int]$y) if (Test-Path variable:global:ProgressPreference){$ProgressPreference="SilentlyContinue"}; $n = $x + $y; Write-Output "$a $b $n";`)
var ps PowerShellCmd
powerShellPath, err := ps.getPowerShellPath()
if err != nil {
t.Skipf("powershell not installed: %s", err)
return
}
cmdOut, err := ps.Output(blockBuffer.String(), "a", "b", "5", "10")
if err != nil {