1
0
Fork 0

ssh dial with retry

master
dump_stack() 2023-05-08 14:54:28 +00:00
parent 2e5c386c42
commit c1c5afc0e0
Signed by: dump_stack
GPG Key ID: BE44DA8C062D87DC
1 changed files with 25 additions and 17 deletions

View File

@ -68,9 +68,10 @@ type System struct {
KernelPanic bool KernelPanic bool
Died bool Died bool
sshAddrPort string
SCP struct { SSH struct {
AddrPort string
Retries int Retries int
RetryTimeout time.Duration RetryTimeout time.Duration
} }
@ -117,15 +118,15 @@ func NewSystem(arch arch, kernel Kernel, drivePath string) (q *System, err error
// Default values // Default values
q.Cpus = 1 q.Cpus = 1
q.Memory = 512 // megabytes q.Memory = 512 // megabytes
q.SCP.Retries = 16 q.SSH.Retries = 16
q.SCP.RetryTimeout = time.Second q.SSH.RetryTimeout = time.Second / 4
return return
} }
func (q *System) SetSSHAddrPort(addr string, port int) (err error) { func (q *System) SetSSHAddrPort(addr string, port int) (err error) {
// TODO validate // TODO validate
q.sshAddrPort = fmt.Sprintf("%s:%d", addr, port) q.SSH.AddrPort = fmt.Sprintf("%s:%d", addr, port)
return return
} }
@ -220,10 +221,10 @@ func (q System) Executable() string {
} }
func (q *System) Args() (qemuArgs []string) { func (q *System) Args() (qemuArgs []string) {
if q.sshAddrPort == "" { if q.SSH.AddrPort == "" {
q.sshAddrPort = getFreeAddrPort() q.SSH.AddrPort = getFreeAddrPort()
} }
hostfwd := fmt.Sprintf("hostfwd=tcp:%s-:22", q.sshAddrPort) hostfwd := fmt.Sprintf("hostfwd=tcp:%s-:22", q.SSH.AddrPort)
qemuArgs = []string{"-nographic", qemuArgs = []string{"-nographic",
"-hda", q.drivePath, "-hda", q.drivePath,
"-kernel", q.kernel.KernelPath, "-kernel", q.kernel.KernelPath,
@ -370,7 +371,13 @@ func (q System) ssh(user string) (client *ssh.Client, err error) {
HostKeyCallback: ssh.InsecureIgnoreHostKey(), HostKeyCallback: ssh.InsecureIgnoreHostKey(),
} }
client, err = ssh.Dial("tcp", q.sshAddrPort, cfg) for retries := q.SSH.Retries; retries > 0; retries-- {
client, err = ssh.Dial("tcp", q.SSH.AddrPort, cfg)
if err == nil {
break
}
time.Sleep(q.SSH.RetryTimeout)
}
return return
} }
@ -459,12 +466,13 @@ func (q System) AsyncCommand(user, cmd string) (err error) {
func (q System) scp(user, localPath, remotePath string, recursive bool) (err error) { func (q System) scp(user, localPath, remotePath string, recursive bool) (err error) {
q.Log.Debug().Msgf("scp[%s] %s -> %s", user, localPath, remotePath) q.Log.Debug().Msgf("scp[%s] %s -> %s", user, localPath, remotePath)
cfg := &ssh.ClientConfig{ sshClient, err := q.ssh(user)
User: user, if err != nil {
HostKeyCallback: ssh.InsecureIgnoreHostKey(), return
} }
defer sshClient.Close()
client, err := scp.NewClient(q.sshAddrPort, cfg, &scp.ClientOption{}) client, err := scp.NewClientFromExistingSSH(sshClient, &scp.ClientOption{})
if err != nil { if err != nil {
return return
} }
@ -486,14 +494,14 @@ func (q System) scp(user, localPath, remotePath string, recursive bool) (err err
} }
func (q System) scpWithRetry(user, localPath, remotePath string, recursive bool) (err error) { func (q System) scpWithRetry(user, localPath, remotePath string, recursive bool) (err error) {
for retries := q.SCP.Retries; retries > 0; retries-- { for retries := q.SSH.Retries; retries > 0; retries-- {
err = q.scp(user, localPath, remotePath, recursive) err = q.scp(user, localPath, remotePath, recursive)
if err == nil { if err == nil {
break break
} }
q.Log.Warn().Err(err).Msg("scp: failed") q.Log.Warn().Err(err).Msg("scp: failed")
time.Sleep(q.SCP.RetryTimeout) time.Sleep(q.SSH.RetryTimeout)
q.Log.Warn().Msgf("scp: %d retries left", retries) q.Log.Warn().Msgf("scp: %d retries left", retries)
} }
return return
@ -579,7 +587,7 @@ func (q *System) GetKPTI() bool {
// GetSSHCommand returns command for connect to qemu machine over ssh // GetSSHCommand returns command for connect to qemu machine over ssh
func (q System) GetSSHCommand() (cmd string) { func (q System) GetSSHCommand() (cmd string) {
addrPort := strings.Split(q.sshAddrPort, ":") addrPort := strings.Split(q.SSH.AddrPort, ":")
addr := addrPort[0] addr := addrPort[0]
port := addrPort[1] port := addrPort[1]