github.com/rahart/packer@v0.12.2-0.20161229105310-282bb6ad370f/builder/hyperv/common/step_polling_installation.go (about)

     1  package common
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"github.com/mitchellh/multistep"
     7  	"github.com/mitchellh/packer/packer"
     8  	"log"
     9  	"os/exec"
    10  	"strings"
    11  	"time"
    12  )
    13  
    14  const port string = "13000"
    15  
    16  type StepPollingInstalation struct {
    17  	step int
    18  }
    19  
    20  func (s *StepPollingInstalation) Run(state multistep.StateBag) multistep.StepAction {
    21  	ui := state.Get("ui").(packer.Ui)
    22  
    23  	errorMsg := "Error polling VM: %s"
    24  	vmIp := state.Get("ip").(string)
    25  
    26  	ui.Say("Start polling VM to check the installation is complete...")
    27  	host := "'" + vmIp + "'," + port
    28  
    29  	var blockBuffer bytes.Buffer
    30  	blockBuffer.WriteString("Invoke-Command -scriptblock {function foo(){try{$client=New-Object System.Net.Sockets.TcpClient(")
    31  	blockBuffer.WriteString(host)
    32  	blockBuffer.WriteString(") -ErrorAction SilentlyContinue;if($client -eq $null){return $false}}catch{return $false}return $true} foo}")
    33  
    34  	count := 60
    35  	var duration time.Duration = 20
    36  	sleepTime := time.Second * duration
    37  
    38  	var res string
    39  
    40  	for count > 0 {
    41  		log.Println(fmt.Sprintf("Connecting vm (%s)...", host))
    42  		cmd := exec.Command("powershell", blockBuffer.String())
    43  		cmdOut, err := cmd.Output()
    44  		if err != nil {
    45  			err := fmt.Errorf(errorMsg, err)
    46  			state.Put("error", err)
    47  			ui.Error(err.Error())
    48  			return multistep.ActionHalt
    49  		}
    50  
    51  		res = strings.TrimSpace(string(cmdOut))
    52  
    53  		if res != "False" {
    54  			ui.Say("Signal was received from the VM")
    55  			// Sleep before starting provision
    56  			time.Sleep(time.Second * 30)
    57  			break
    58  		}
    59  
    60  		log.Println(fmt.Sprintf("Slipping for more %v seconds...", uint(duration)))
    61  		time.Sleep(sleepTime)
    62  		count--
    63  	}
    64  
    65  	if count == 0 {
    66  		err := fmt.Errorf(errorMsg, "a signal from vm was not received in a given time period ")
    67  		state.Put("error", err)
    68  		ui.Error(err.Error())
    69  		return multistep.ActionHalt
    70  	}
    71  
    72  	ui.Say("The installation complete")
    73  
    74  	return multistep.ActionContinue
    75  }
    76  
    77  func (s *StepPollingInstalation) Cleanup(state multistep.StateBag) {
    78  
    79  }