blob: fd80e05d3db6c660089cc56bf5c467e48f053175 [file] [log] [blame]
// Copyright 2022 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package manager
import (
"context"
"fmt"
"time"
"chromiumos/tast/errors"
"chromiumos/tast/ssh"
"chromiumos/tast/testing"
)
const (
labProxyHostname = "chromeos1-proxy"
labProxyUser = "access"
labProxyCallboxManagerRemoteAddress = "localhost:5000"
)
type forwardedCallboxManager struct {
host *ssh.Conn
localPortForwarder *ssh.Forwarder
}
type forwardedCallboxManagerConfig struct {
sshKeyDir string
sshKeyFile string
sshUser string
sshHostname string
remoteCallboxManagerAddress string
}
func newForwardedCallboxManager(ctx context.Context, config *forwardedCallboxManagerConfig) (*forwardedCallboxManager, error) {
fcm := &forwardedCallboxManager{}
// Connect to host
sshOptions := &ssh.Options{
KeyFile: config.sshKeyFile,
KeyDir: config.sshKeyDir,
ConnectTimeout: 10 * time.Second,
User: config.sshUser,
Hostname: fmt.Sprintf("%s:%d", config.sshHostname, 22),
}
conn, err := ssh.New(ctx, sshOptions)
if err != nil {
return nil, errors.Wrapf(err, "failed to connect to %s", sshOptions.Hostname)
}
fcm.host = conn
// Forward local port to remote CallboxManager
onFwdError := func(err error) {
testing.ContextLog(ctx, "Ssh forwarding error: ", err)
}
fcm.localPortForwarder, err = conn.ForwardLocalToRemote("tcp", "localhost", config.remoteCallboxManagerAddress, onFwdError)
if err != nil {
return nil, errors.Wrap(err, "failed to forward local port to remote callbox manager")
}
return fcm, nil
}
func newForwardToLabCallboxManager(ctx context.Context, sshKeyDir, sshKeyFile string) (*forwardedCallboxManager, error) {
return newForwardedCallboxManager(ctx, &forwardedCallboxManagerConfig{
sshKeyDir: sshKeyDir,
sshKeyFile: sshKeyFile,
sshUser: labProxyUser,
sshHostname: labProxyHostname,
remoteCallboxManagerAddress: labProxyCallboxManagerRemoteAddress,
})
}
// LocalAddress returns the local address that is forwarded to the remote
// address. This is what should be used to interact with the forwarded
// Callbox Manager.
func (fcm *forwardedCallboxManager) LocalAddress() string {
return fcm.localPortForwarder.ListenAddr().String()
}
// Close closes the local port forward and the connection to the host.
func (fcm *forwardedCallboxManager) Close(ctx context.Context) error {
var firstError error
if err := fcm.Close(ctx); err != nil {
firstError = err
}
if err := fcm.host.Close(ctx); err != nil && firstError != nil {
firstError = err
}
return firstError
}