go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/client/cmd/cas/casimpl/common.go (about) 1 // Copyright 2020 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 package casimpl 16 17 import ( 18 "context" 19 "flag" 20 "fmt" 21 22 "github.com/bazelbuild/remote-apis-sdks/go/pkg/client" 23 "github.com/maruel/subcommands" 24 25 "go.chromium.org/luci/client/casclient" 26 "go.chromium.org/luci/common/cli" 27 "go.chromium.org/luci/common/errors" 28 "go.chromium.org/luci/common/logging" 29 "go.chromium.org/luci/common/runtime/profiling" 30 ) 31 32 // Version is reported by "version" subcommand and put into logs. 33 const Version = "cas 0.2.0" 34 35 // AuthFlags is an interface to register auth flags and create RBE Client. 36 type AuthFlags interface { 37 // Register registers auth flags to the given flag set. e.g. -service-account-json. 38 Register(f *flag.FlagSet) 39 40 // Parse parses auth flags. 41 Parse() error 42 43 // NewRBEClient creates an authorised RBE Client. 44 NewRBEClient(ctx context.Context, addr string, instance string, readOnly bool) (*client.Client, error) 45 } 46 47 var _ cli.ContextModificator = (*commonFlags)(nil) 48 49 type commonFlags struct { 50 subcommands.CommandRunBase 51 casFlags casclient.Flags 52 logConfig logging.Config // for -log-level, used by ModifyContext 53 profiler profiling.Profiler 54 authFlags AuthFlags 55 } 56 57 func (c *commonFlags) Init(authFlags AuthFlags) { 58 c.casFlags.Init(&c.Flags) 59 c.authFlags = authFlags 60 c.authFlags.Register(&c.Flags) 61 c.logConfig.Level = logging.Warning 62 c.logConfig.AddFlags(&c.Flags) 63 c.profiler.AddFlags(&c.Flags) 64 } 65 66 func (c *commonFlags) Parse() error { 67 verbosity := 0 68 switch c.logConfig.Level { 69 case logging.Debug: 70 verbosity = 9 71 case logging.Info: 72 verbosity = 2 73 } 74 if verbosity != 0 { 75 if err := enableGlogVerbosity(verbosity); err != nil { 76 return err 77 } 78 } 79 80 if err := c.profiler.Start(); err != nil { 81 return err 82 } 83 if err := c.authFlags.Parse(); err != nil { 84 return err 85 } 86 87 return c.casFlags.Parse() 88 } 89 90 // ModifyContext implements cli.ContextModificator. 91 func (c *commonFlags) ModifyContext(ctx context.Context) context.Context { 92 return c.logConfig.Set(ctx) 93 } 94 95 func enableGlogVerbosity(level int) error { 96 // extract glog flag used in remote-apis-sdks 97 logtostderr := flag.Lookup("logtostderr") 98 if logtostderr == nil { 99 return errors.Reason("logtostderr flag for glog not found").Err() 100 } 101 if err := logtostderr.Value.Set("true"); err != nil { 102 return errors.Annotate(err, "failed to set logstderr to true").Err() 103 } 104 v := flag.Lookup("v") 105 if v == nil { 106 return errors.Reason("v flag for glog not found").Err() 107 } 108 if err := v.Value.Set(fmt.Sprintf("%d", level)); err != nil { 109 return errors.Annotate(err, "failed to set verbosity level").Err() 110 } 111 return nil 112 }