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  }