blob: 8f4295487e2fcc0b76a3066102b00f53f0c055cf [file] [log] [blame]
// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Provides service implementations and management
package services
import (
"fmt"
"os/exec"
"go.chromium.org/chromiumos/config/go/test/api"
"go.chromium.org/chromiumos/test/local-cft/internal/utils"
)
type crosDutServiceCommands struct {
}
func CROS_DUT_SERVICE_COMMANDS() crosDutServiceCommands {
return crosDutServiceCommands{}
}
// Service implementation for cros-dut
type CrosDutService struct {
Service
ServiceBase
client api.DutServiceClient
}
func (c *CrosDutService) Start() error {
c.EnsurePort()
c.LocalLogger.Printf("Starting %s on port %d", c.Name, c.Port)
starter := &SetupCrosDut{
cd: c,
}
return c.executor.Start(starter)
}
func (c *CrosDutService) Execute(commandName ServiceCommand_, args ...interface{}) error {
switch commandName {
default:
return fmt.Errorf("Command %s not found", commandName)
}
}
func (c *CrosDutService) Stop() error {
stopper := &StopCrosDut{
cd: c,
}
return c.executor.Stop(stopper)
}
// Setup
type SetupCrosDut struct {
ServiceSetup
cd *CrosDutService
}
func (starter *SetupCrosDut) Setup() error {
if err := utils.EnsureContainerAvailable(starter.cd.Name); err != nil {
err = fmt.Errorf("Failed to ensure container %s was available, %s", starter.cd.Name, err)
starter.cd.LocalLogger.Println(err)
return err
}
containerImage := fmt.Sprintf(
"us-docker.pkg.dev/cros-registry/test-services/%s:%s",
starter.cd.Name,
starter.cd.manager.images[starter.cd.Name].Tags[0],
)
if _, ok := starter.cd.manager.LocalServices[starter.cd.Name]; ok {
err := utils.UpdateContainerService(starter.cd.LocalLogger, starter.cd.manager.Chroot, containerImage, starter.cd.Name)
if err != nil {
starter.cd.LocalLogger.Println(err)
return err
}
containerImage = containerImage + "_localchange"
}
request := &api.StartContainerRequest{
Name: starter.cd.Name,
ContainerImage: containerImage,
AdditionalOptions: &api.StartContainerRequest_Options{
Expose: []string{fmt.Sprint(starter.cd.Port)},
Volume: []string{fmt.Sprintf("%s/cros-dut:/tmp/cros-dut", starter.cd.BaseDir)},
Network: "host",
},
StartCommand: []string{
"cros-dut",
"-dut_address",
fmt.Sprintf("localhost:%d", starter.cd.manager.ports[SERVICES().SSHTunnel]),
"-cache_address",
fmt.Sprintf("%s:%d", "localhost", starter.cd.manager.ports[SERVICES().SSHReverseTunnel]),
"-port",
fmt.Sprint(starter.cd.Port),
},
}
starter.cd.manager.Execute(
SERVICES().CrosToolRunner,
CTR_SERVICE_COMMANDS().StartContainer,
request,
)
go BuildServiceListener(
&starter.cd.ServiceBase,
false,
exec.Command("docker", "logs", "-f", starter.cd.Name),
)()
if err := <-starter.cd.ReadyChan; err != nil {
starter.cd.LocalLogger.Println(err)
return err
}
if err := BuildConnection(&starter.cd.ServiceBase); err != nil {
return err
}
starter.cd.client = api.NewDutServiceClient(starter.cd.conn)
return nil
}
// Stopper
type StopCrosDut struct {
ServiceStopper
cd *CrosDutService
}
func (stopper *StopCrosDut) Stop() error {
if stopper.cd.conn != nil {
stopper.cd.conn.Close()
}
if stopper.cd.Started {
stopper.cd.CloseChan <- struct{}{}
<-stopper.cd.CloseFinishedChan
}
WriteLogs(&stopper.cd.ServiceBase)
return nil
}
// Commands