github.phpd.cn/hashicorp/packer@v1.3.2/builder/hyperv/common/step_polling_installation.go (about)

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