ConnectToInstanceSerialPort uses SSH to connect to the serial port of the instance
(instance, zone string)
| 389 | |
| 390 | // ConnectToInstanceSerialPort uses SSH to connect to the serial port of the instance |
| 391 | func (g GCPClient) ConnectToInstanceSerialPort(instance, zone string) error { |
| 392 | log.Infof("Connecting to serial port of instance %s", instance) |
| 393 | gPubKeyURL := "https://cloud-certs.storage.googleapis.com/google-cloud-serialport-host-key.pub" |
| 394 | resp, err := http.Get(gPubKeyURL) |
| 395 | if err != nil { |
| 396 | return err |
| 397 | } |
| 398 | defer func() { _ = resp.Body.Close() }() |
| 399 | body, err := io.ReadAll(resp.Body) |
| 400 | if err != nil { |
| 401 | return err |
| 402 | } |
| 403 | gPubKey, _, _, _, err := ssh.ParseAuthorizedKey(body) |
| 404 | if err != nil { |
| 405 | return err |
| 406 | } |
| 407 | |
| 408 | signer, err := ssh.NewSignerFromKey(g.privKey) |
| 409 | if err != nil { |
| 410 | return err |
| 411 | } |
| 412 | config := &ssh.ClientConfig{ |
| 413 | User: fmt.Sprintf("%s.%s.%s.moby", g.projectName, zone, instance), |
| 414 | Auth: []ssh.AuthMethod{ |
| 415 | ssh.PublicKeys(signer), |
| 416 | }, |
| 417 | HostKeyCallback: ssh.FixedHostKey(gPubKey), |
| 418 | Timeout: 5 * time.Second, |
| 419 | } |
| 420 | |
| 421 | var conn *ssh.Client |
| 422 | // Retry connection as VM may not be ready yet |
| 423 | for i := 0; i < timeout; i++ { |
| 424 | conn, err = ssh.Dial("tcp", "ssh-serialport.googleapis.com:9600", config) |
| 425 | if err != nil { |
| 426 | time.Sleep(pollingInterval) |
| 427 | continue |
| 428 | } |
| 429 | break |
| 430 | } |
| 431 | if conn == nil { |
| 432 | return err |
| 433 | } |
| 434 | defer func() { _ = conn.Close() }() |
| 435 | |
| 436 | session, err := conn.NewSession() |
| 437 | if err != nil { |
| 438 | return err |
| 439 | } |
| 440 | defer func() { _ = session.Close() }() |
| 441 | |
| 442 | stdin, err := session.StdinPipe() |
| 443 | if err != nil { |
| 444 | return fmt.Errorf("unable to setup stdin for session: %v", err) |
| 445 | } |
| 446 | go func() { |
| 447 | _, _ = io.Copy(stdin, os.Stdin) |
| 448 | }() |