Skip to content

Commit

Permalink
Allow creating devices without build api credentials
Browse files Browse the repository at this point in the history
  • Loading branch information
jemoreira committed Nov 17, 2023
1 parent c07508d commit 33b575f
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 17 deletions.
6 changes: 6 additions & 0 deletions build/package/host/etc/cvdr.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@
# files forever.
# KeepLogFilesDays = 30

# Source for the Build API credentials to be used on cvd create operations.
# Possible values are:
# - "injected": Use credentials stored in the server.
# - "none": Don't use Build API credentials.
# CredentialsSource = "injected"

# The host.GCP section provides default configuration values for hosts created
# using the GCP Cloud Provider. Other providers will have their own
# host.<Provider> sections when added.
Expand Down
3 changes: 1 addition & 2 deletions pkg/app/secrets/empty.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ package secrets
const EmptySMType = ""

// A secret manager that always returns empty string.
type EmptySecretManager struct {}
type EmptySecretManager struct{}

func NewEmptySecretManager() *EmptySecretManager {
return &EmptySecretManager{}
Expand All @@ -30,4 +30,3 @@ func (sm *EmptySecretManager) OAuth2ClientID() string {
func (sm *EmptySecretManager) OAuth2ClientSecret() string {
return ""
}

3 changes: 3 additions & 0 deletions pkg/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ const (
systemImgBuildTargetFlag = "system_build_target"
numInstancesFlag = "num_instances"
autoConnectFlag = "auto_connect"
credentialsSourceFlag = "credentials_source"
)

const (
Expand Down Expand Up @@ -488,6 +489,8 @@ func cvdCommands(opts *subCommandOpts) []*cobra.Command {
"Creates multiple instances with the same artifacts. Only relevant if given a single build source")
create.Flags().BoolVar(&createFlags.AutoConnect, autoConnectFlag, true,
"Automatically connect through ADB after device is created.")
create.Flags().StringVar(&createFlags.CredentialsSource, credentialsSourceFlag, opts.InitialConfig.CredentialsSource,
"Source for the Build API OAuth2 credentials")
// Host flags
createHostFlags := []struct {
ValueRef *string
Expand Down
1 change: 1 addition & 0 deletions pkg/cli/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ func TestCommandSucceeds(t *testing.T) {
Args: append(test.Args, "--service_url="+serviceURL),
InitialConfig: Config{
ConnectionControlDir: t.TempDir(),
CredentialsSource: "none",
},
ServiceBuilder: func(opts *client.ServiceOptions) (client.Service, error) {
return &fakeService{}, nil
Expand Down
4 changes: 3 additions & 1 deletion pkg/cli/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ type Config struct {
HTTPProxy string
ConnectionControlDir string
KeepLogFilesDays int
CredentialsSource string
Host HostConfig
}

Expand All @@ -55,7 +56,8 @@ func (c *Config) LogFilesDeleteThreshold() time.Duration {
func BaseConfig() *Config {
return &Config{
ConnectionControlDir: "~/.cvdr/connections",
KeepLogFilesDays: 30, // A default is needed to not keep forever
KeepLogFilesDays: 30, // A default is needed to not keep forever
CredentialsSource: NoneCredentialsSource, // Default needed because empty string is invalid
}
}

Expand Down
1 change: 1 addition & 0 deletions pkg/cli/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ MachineType = "machine-type-bar"
Zone: "zone-bar",
KeepLogFilesDays: 0,
ConnectionControlDir: "~/.cvdr/connections",
CredentialsSource: NoneCredentialsSource,
Host: HostConfig{
GCP: GCPHostConfig{
MachineType: "machine-type-bar",
Expand Down
56 changes: 42 additions & 14 deletions pkg/cli/cvd.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ func NewRemoteCVD(url, host string, cvd *hoapi.CVD) *RemoteCVD {
}
}

const (
NoneCredentialsSource = "none"
InjectedCredentialsSource = "injected"
)

type CreateCVDOpts struct {
Host string
MainBuild hoapi.AndroidCIBuild
Expand All @@ -75,7 +80,8 @@ type CreateCVDOpts struct {
// Example: https://cs.android.com/android/platform/superproject/main/+/main:device/google/cuttlefish/host/cvd_test_configs/main_phone-main_watch.json;drc=b2e8f4f014abb7f9cb56c0ae199334aacb04542d
EnvConfig map[string]interface{}
// If true, perform the ADB connection automatically.
AutoConnect bool
AutoConnect bool
CredentialsSource string
}

func (o *CreateCVDOpts) AdditionalInstancesNum() uint32 {
Expand All @@ -86,7 +92,10 @@ func (o *CreateCVDOpts) AdditionalInstancesNum() uint32 {
}

func createCVD(service client.Service, createOpts CreateCVDOpts, statePrinter *statePrinter) ([]*RemoteCVD, error) {
creator := newCVDCreator(service, createOpts, statePrinter)
creator, err := newCVDCreator(service, createOpts, statePrinter)
if err != nil {
return nil, fmt.Errorf("failed to create cvd: %w", err)
}
cvds, err := creator.Create()
if err != nil {
return nil, fmt.Errorf("failed to create cvd: %w", err)
Expand All @@ -98,18 +107,26 @@ func createCVD(service client.Service, createOpts CreateCVDOpts, statePrinter *s
return result, nil
}

type CredentialsFactory func() string

type cvdCreator struct {
service client.Service
opts CreateCVDOpts
statePrinter *statePrinter
service client.Service
opts CreateCVDOpts
statePrinter *statePrinter
credentialsFactory CredentialsFactory
}

func newCVDCreator(service client.Service, opts CreateCVDOpts, statePrinter *statePrinter) *cvdCreator {
return &cvdCreator{
service: service,
opts: opts,
statePrinter: statePrinter,
func newCVDCreator(service client.Service, opts CreateCVDOpts, statePrinter *statePrinter) (*cvdCreator, error) {
cf, err := credentialsFactoryFromSource(opts.CredentialsSource)
if err != nil {
return nil, err
}
return &cvdCreator{
service: service,
opts: opts,
statePrinter: statePrinter,
credentialsFactory: cf,
}, nil
}

func (c *cvdCreator) Create() ([]*hoapi.CVD, error) {
Expand Down Expand Up @@ -150,7 +167,7 @@ func (c *cvdCreator) createCVDFromLocalBuild() ([]*hoapi.CVD, error) {
},
AdditionalInstancesNum: c.opts.AdditionalInstancesNum(),
}
res, err := c.service.HostService(c.opts.Host).CreateCVD(&req, client.InjectedCredentials)
res, err := c.service.HostService(c.opts.Host).CreateCVD(&req, c.credentialsFactory())
if err != nil {
return nil, err
}
Expand All @@ -175,7 +192,7 @@ func (c *cvdCreator) createWithCanonicalConfig() ([]*hoapi.CVD, error) {
EnvConfig: c.opts.EnvConfig,
}
c.statePrinter.Print(stateMsgFetchAndStart)
res, err := c.service.HostService(c.opts.Host).CreateCVD(createReq, client.InjectedCredentials)
res, err := c.service.HostService(c.opts.Host).CreateCVD(createReq, c.credentialsFactory())
c.statePrinter.PrintDone(stateMsgFetchAndStart, err)
if err != nil {
return nil, err
Expand All @@ -199,7 +216,7 @@ func (c *cvdCreator) createWithOpts() ([]*hoapi.CVD, error) {
AndroidCIBundle: &hoapi.AndroidCIBundle{Build: mainBuild, Type: hoapi.MainBundleType},
}
c.statePrinter.Print(stateMsgFetchMainBundle)
fetchMainBuildRes, err := c.service.HostService(c.opts.Host).FetchArtifacts(fetchReq, client.InjectedCredentials)
fetchMainBuildRes, err := c.service.HostService(c.opts.Host).FetchArtifacts(fetchReq, c.credentialsFactory())
c.statePrinter.PrintDone(stateMsgFetchMainBundle, err)
if err != nil {
return nil, err
Expand All @@ -218,14 +235,25 @@ func (c *cvdCreator) createWithOpts() ([]*hoapi.CVD, error) {
AdditionalInstancesNum: c.opts.AdditionalInstancesNum(),
}
c.statePrinter.Print(stateMsgStartCVD)
res, err := c.service.HostService(c.opts.Host).CreateCVD(createReq, client.InjectedCredentials)
res, err := c.service.HostService(c.opts.Host).CreateCVD(createReq, c.credentialsFactory())
c.statePrinter.PrintDone(stateMsgStartCVD, err)
if err != nil {
return nil, err
}
return res.CVDs, nil
}

func credentialsFactoryFromSource(source string) (CredentialsFactory, error) {
switch source {
case NoneCredentialsSource:
return func() string { return "" }, nil
case InjectedCredentialsSource:
return func() string { return client.InjectedCredentials }, nil
default:
return nil, fmt.Errorf("unknown credentials source: %s", source)
}
}

type cvdListResult struct {
Result []*RemoteCVD
Error error
Expand Down

0 comments on commit 33b575f

Please sign in to comment.