Allow user to connect to vnc

This commit is contained in:
flx5 2021-09-30 17:10:45 +02:00
parent 991ced778f
commit f049f32908
5 changed files with 41 additions and 41 deletions

View File

@ -7,6 +7,7 @@ import (
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
"golang.org/x/net/proxy" "golang.org/x/net/proxy"
"io" "io"
"log"
"net" "net"
"time" "time"
) )
@ -110,8 +111,7 @@ func CreateCustomPortForwarding(connectTarget func() (net.Conn, error)) (net.Lis
for { for {
accept, err := listener.Accept() accept, err := listener.Accept()
if err != nil { if err != nil {
fmt.Printf("error accepting: %v", err) return
continue
} }
go handleConnection(accept, connectTarget) go handleConnection(accept, connectTarget)
@ -128,12 +128,14 @@ func serviceForwardedConnection(clientConn net.Conn, targetConn net.Conn) {
go func() { go func() {
_, err := io.Copy(targetConn, clientConn) _, err := io.Copy(targetConn, clientConn)
log.Printf("[FORWARD] proxy client closed connection")
// Close conn so that other copy operation unblocks // Close conn so that other copy operation unblocks
targetConn.Close() targetConn.Close()
close(txDone) close(txDone)
if err != nil { if err != nil {
fmt.Printf("[FORWARD] Error conn <- accept: %v", err) log.Printf("[FORWARD] Error conn <- accept: %v", err)
return return
} }
}() }()
@ -141,12 +143,14 @@ func serviceForwardedConnection(clientConn net.Conn, targetConn net.Conn) {
go func() { go func() {
_, err := io.Copy(clientConn, targetConn) _, err := io.Copy(clientConn, targetConn)
log.Printf("[FORWARD] proxy target closed connection")
// Close accept so that other copy operation unblocks // Close accept so that other copy operation unblocks
clientConn.Close() clientConn.Close()
close(rxDone) close(rxDone)
if err != nil { if err != nil {
fmt.Printf("[FORWARD] Error accept <- conn: %v", err) log.Printf("[FORWARD] Error accept <- conn: %v", err)
return return
} }
}() }()
@ -160,7 +164,7 @@ func handleConnection(clientConn net.Conn, connectTarget func() (net.Conn, error
targetConn, err := connectTarget() targetConn, err := connectTarget()
if err != nil { if err != nil {
fmt.Printf("[FORWARD] Connect proxy Error: %v", err) log.Printf("[FORWARD] Connect proxy Error: %v", err)
return return
} }

View File

@ -1,51 +1,46 @@
package common package common
import ( import (
"context"
"fmt" "fmt"
"strconv"
"github.com/hashicorp/packer-plugin-sdk/multistep" "github.com/hashicorp/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer-plugin-sdk/packer" "github.com/hashicorp/packer-plugin-sdk/packer"
"net"
) )
type StepGetVNCPort struct{} type StepGetVNCPort struct {
listener net.Listener
}
func (self *StepGetVNCPort) Run(state multistep.StateBag) multistep.StepAction { func (self *StepGetVNCPort) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
ui.Say("Step: forward the instances VNC port over SSH") ui.Say("Step: forward the instances VNC")
domid := state.Get("domid").(int) location, err := GetVNCConsoleLocation(state)
cmd := fmt.Sprintf("xenstore-read /local/domain/%d/console/vnc-port", domid)
remote_vncport, err := ExecuteHostSSHCmd(state, cmd)
if err != nil { if err != nil {
ui.Error(fmt.Sprintf("Unable to get VNC port (is the VM running?): %s", err.Error())) state.Put("error", err)
return multistep.ActionHalt
}
remote_port, err := strconv.ParseUint(remote_vncport, 10, 16)
if err != nil {
ui.Error(fmt.Sprintf("Unable to convert '%s' to an int", remote_vncport))
ui.Error(err.Error()) ui.Error(err.Error())
return multistep.ActionHalt return multistep.ActionHalt
} }
state.Put("instance_vnc_port", uint(remote_port)) forwardingListener, err := CreateCustomPortForwarding(func() (net.Conn, error) {
return CreateVNCConnection(state, location)
})
if err != nil {
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
self.listener = forwardingListener
ui.Say(fmt.Sprintf("VNC available on vnc://%s", self.listener.Addr().String()))
return multistep.ActionContinue return multistep.ActionContinue
} }
func (self *StepGetVNCPort) Cleanup(state multistep.StateBag) { func (self *StepGetVNCPort) Cleanup(state multistep.StateBag) {
} self.listener.Close()
func InstanceVNCPort(state multistep.StateBag) (uint, error) {
vncPort := state.Get("instance_vnc_port").(uint)
return vncPort, nil
}
func InstanceVNCIP(state multistep.StateBag) (string, error) {
// The port is in Dom0, so we want to forward from localhost
return "127.0.0.1", nil
} }

View File

@ -78,7 +78,7 @@ func CreateVNCClient(state multistep.StateBag, location string) (*vnc.ClientConn
} }
client, err := vnc.Client(connection, &vnc.ClientConfig{ client, err := vnc.Client(connection, &vnc.ClientConfig{
Exclusive: false, Exclusive: true,
}) })
if err != nil { if err != nil {
connection.Close() connection.Close()

View File

@ -253,17 +253,14 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p
new(xscommon.StepHTTPIPDiscover), new(xscommon.StepHTTPIPDiscover),
&xscommon.StepCreateProxy{}, &xscommon.StepCreateProxy{},
commonsteps.HTTPServerFromHTTPConfig(&self.config.HTTPConfig), commonsteps.HTTPServerFromHTTPConfig(&self.config.HTTPConfig),
// &xscommon.StepForwardPortOverSSH{
// RemotePort: xscommon.InstanceVNCPort,
// RemoteDest: xscommon.InstanceVNCIP,
// HostPortMin: self.config.HostPortMin,
// HostPortMax: self.config.HostPortMax,
// ResultKey: "local_vnc_port",
// },
new(xscommon.StepBootWait), new(xscommon.StepBootWait),
&xscommon.StepTypeBootCommand{ &xscommon.StepTypeBootCommand{
Ctx: *self.config.GetInterpContext(), Ctx: *self.config.GetInterpContext(),
}, },
/*
VNC is only available after boot command because xenserver doesn't seem to support two vnc connections at the same time
*/
&xscommon.StepGetVNCPort{},
&xscommon.StepWaitForIP{ &xscommon.StepWaitForIP{
Chan: httpReqChan, Chan: httpReqChan,
Timeout: self.config.InstallTimeout, // @todo change this Timeout: self.config.InstallTimeout, // @todo change this

View File

@ -151,6 +151,10 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p
&xscommon.StepTypeBootCommand{ &xscommon.StepTypeBootCommand{
Ctx: *self.config.GetInterpContext(), Ctx: *self.config.GetInterpContext(),
}, },
/*
VNC is only available after boot command because xenserver doesn't seem to support two vnc connections at the same time
*/
&xscommon.StepGetVNCPort{},
&xscommon.StepWaitForIP{ &xscommon.StepWaitForIP{
Chan: httpReqChan, Chan: httpReqChan,
Timeout: 300 * time.Minute, /*self.config.InstallTimeout*/ // @todo change this Timeout: 300 * time.Minute, /*self.config.InstallTimeout*/ // @todo change this