go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/client/cmd/swarming/main.go (about) 1 // Copyright 2015 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 //go:build !copybara 16 // +build !copybara 17 18 // Package main is a client to a Swarming server. 19 package main 20 21 import ( 22 "context" 23 "flag" 24 "net/http" 25 "os" 26 27 "github.com/bazelbuild/remote-apis-sdks/go/pkg/client" 28 "github.com/maruel/subcommands" 29 30 "go.chromium.org/luci/auth" 31 "go.chromium.org/luci/auth/client/authcli" 32 "go.chromium.org/luci/client/casclient" 33 "go.chromium.org/luci/client/versioncli" 34 "go.chromium.org/luci/common/cli" 35 "go.chromium.org/luci/common/errors" 36 "go.chromium.org/luci/common/logging/gologger" 37 38 "go.chromium.org/luci/client/cmd/swarming/swarmingimpl" 39 "go.chromium.org/luci/swarming/client/swarming" 40 41 "go.chromium.org/luci/hardcoded/chromeinfra" 42 ) 43 44 type authFlags struct { 45 flags authcli.Flags 46 defaultOpts auth.Options 47 parsedOpts *auth.Options 48 } 49 50 func (af *authFlags) Register(f *flag.FlagSet) { 51 af.flags.Register(f, af.defaultOpts) 52 } 53 54 func (af *authFlags) Parse() error { 55 opts, err := af.flags.Options() 56 if err != nil { 57 return err 58 } 59 af.parsedOpts = &opts 60 return nil 61 } 62 63 func (af *authFlags) NewHTTPClient(ctx context.Context) (*http.Client, error) { 64 if af.parsedOpts == nil { 65 return nil, errors.Reason("AuthFlags.Parse() must be called").Err() 66 } 67 return auth.NewAuthenticator(ctx, auth.OptionalLogin, *af.parsedOpts).Client() 68 } 69 70 func (af *authFlags) NewRBEClient(ctx context.Context, addr string, instance string) (*client.Client, error) { 71 if af.parsedOpts == nil { 72 return nil, errors.Reason("AuthFlags.Parse() must be called").Err() 73 } 74 return casclient.NewLegacy(ctx, addr, instance, *af.parsedOpts, true) 75 } 76 77 func getApplication() *cli.Application { 78 authOpts := chromeinfra.DefaultAuthOptions() 79 af := &authFlags{defaultOpts: authOpts} 80 81 return &cli.Application{ 82 Name: "swarming", 83 Title: "Client tool to access a swarming server.", 84 85 // Note: this decouples logging implementation from subcommands 86 // implementation. Useful when reusing subcommands in g3. 87 Context: func(ctx context.Context) context.Context { 88 return gologger.StdConfig.Use(ctx) 89 }, 90 91 // Keep in alphabetical order of their name. 92 Commands: []*subcommands.Command{ 93 subcommands.Section("Tasks\n"), 94 swarmingimpl.CmdCancelTask(af), 95 swarmingimpl.CmdCancelTasks(af), 96 swarmingimpl.CmdCollect(af), 97 swarmingimpl.CmdReproduce(af), 98 swarmingimpl.CmdRequestShow(af), 99 swarmingimpl.CmdSpawnTasks(af), 100 swarmingimpl.CmdTasks(af), 101 swarmingimpl.CmdTrigger(af), 102 subcommands.Section("Bots\n"), 103 swarmingimpl.CmdBots(af), 104 swarmingimpl.CmdDeleteBots(af), 105 swarmingimpl.CmdTerminateBot(af), 106 swarmingimpl.CmdBotTasks(af), 107 subcommands.Section("Other\n"), 108 subcommands.CmdHelp, 109 authcli.SubcommandInfo(authOpts, "whoami", false), 110 authcli.SubcommandLogin(authOpts, "login", false), 111 authcli.SubcommandLogout(authOpts, "logout", false), 112 versioncli.CmdVersion(swarming.UserAgent), 113 }, 114 115 EnvVars: map[string]subcommands.EnvVarDefinition{ 116 swarming.ServerEnvVar: { 117 ShortDesc: "URL or a hostname of a Swarming server to use by default when omitting -server or -S flag", 118 }, 119 swarming.UserEnvVar: { 120 ShortDesc: "used as \"user\" field in spawned Swarming tasks", 121 }, 122 swarming.TaskIDEnvVar: { 123 Advanced: true, 124 ShortDesc: "set when running within a Swarming task to ID of that task; " + 125 "used as \"parent_task_id\" field in spawned Swarming tasks", 126 }, 127 }, 128 } 129 } 130 131 func main() { 132 os.Exit(subcommands.Run(getApplication(), nil)) 133 }