diff --git a/go.sum b/go.sum index a3bfdfb5847..331897a8a75 100644 --- a/go.sum +++ b/go.sum @@ -200,16 +200,12 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A= github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= -github.com/lestrrat-go/blackmagic v1.0.1 h1:lS5Zts+5HIC/8og6cGHb0uCcNCa3OUt1ygh3Qz2Fe80= -github.com/lestrrat-go/blackmagic v1.0.1/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k= github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI= github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= -github.com/lestrrat-go/jwx v1.2.26 h1:4iFo8FPRZGDYe1t19mQP0zTRqA7n8HnJ5lkIiDvJcB0= -github.com/lestrrat-go/jwx v1.2.26/go.mod h1:MaiCdGbn3/cckbOFSCluJlJMmp9dmZm5hDuIkx8ftpQ= github.com/lestrrat-go/jwx v1.2.27 h1:cvnTnda/YzdyFuWdEAMkI6BsLtItSrASEVCI3C/IUEQ= github.com/lestrrat-go/jwx v1.2.27/go.mod h1:Stob9LjSqR3lOmNdxF0/TvZo60V3hUGv8Fr7Bwzla3k= github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= @@ -442,7 +438,6 @@ golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= diff --git a/kubectl-minio/cmd/helpers/helpers.go b/kubectl-minio/cmd/helpers/helpers.go index 28cc76b5deb..fb3b1dc7b71 100644 --- a/kubectl-minio/cmd/helpers/helpers.go +++ b/kubectl-minio/cmd/helpers/helpers.go @@ -184,7 +184,11 @@ func CapacityPerVolume(capacity string, volumes int32) (*resource.Quantity, erro if err != nil { return nil, err } - return resource.NewQuantity(totalQuantity.Value()/int64(volumes), totalQuantity.Format), nil + quantity := resource.NewQuantity(totalQuantity.Value()/int64(volumes), totalQuantity.Format) + if quantity.Sign() <= 0 { + return nil, errors.New("capacity per volume needs to be greater than zero") + } + return quantity, nil } // TotalCapacity returns total capacity of a given tenant diff --git a/kubectl-minio/cmd/resources/tenant.go b/kubectl-minio/cmd/resources/tenant.go index 0bce6b6c74e..9779b994f6e 100644 --- a/kubectl-minio/cmd/resources/tenant.go +++ b/kubectl-minio/cmd/resources/tenant.go @@ -17,7 +17,6 @@ package resources import ( "errors" - "github.com/minio/kubectl-minio/cmd/helpers" operator "github.com/minio/operator/pkg/apis/minio.min.io" miniov2 "github.com/minio/operator/pkg/apis/minio.min.io/v2" @@ -33,6 +32,7 @@ type TenantOptions struct { ConfigurationSecretName string Servers int32 Volumes int32 + VolumesPerServer int32 Capacity string NS string Image string @@ -55,22 +55,35 @@ func (t TenantOptions) Validate() error { if t.Servers <= 0 { return errors.New("--servers is required. Specify a value greater than or equal to 1") } - if t.Volumes <= 0 { - return errors.New("--volumes is required. Specify a positive value") + if t.Volumes <= 0 && t.VolumesPerServer <= 0 { + return errors.New("--volumes or --volumes-per-server is required. Specify either with a value greater than or equal to 1") + } + if t.Volumes > 0 && t.VolumesPerServer > 0 { + return errors.New("only either --volumes or --volumes-per-server may be specified") + } + if t.VolumesPerServer > 0 { + t.Volumes = t.VolumesPerServer * t.Servers } if t.Capacity == "" { return errors.New("--capacity flag is required") } - _, err := resource.ParseQuantity(t.Capacity) + capacity, err := resource.ParseQuantity(t.Capacity) if err != nil { if err == resource.ErrFormatWrong { - return errors.New("--capacity flag is incorrectly formatted. Please use suffix like 'T' or 'Ti' only") + return errors.New("--capacity flag is incorrectly formatted. Use a suffix like 'T' or 'Ti' only") } return err } + if capacity.Sign() <= 0 { + return errors.New("--capacity needs to be greater than zero") + } if t.Volumes%t.Servers != 0 { return errors.New("--volumes should be a multiple of --servers") } + _, err = helpers.CapacityPerVolume(t.Capacity, t.Volumes) + if err != nil { + return err + } return nil } @@ -104,7 +117,13 @@ func storageClass(sc string) *string { // NewTenant will return a new Tenant for a MinIO Operator func NewTenant(opts *TenantOptions, userSecret *v1.Secret) (*miniov2.Tenant, error) { autoCert := !opts.DisableTLS - volumesPerServer := helpers.VolumesPerServer(opts.Volumes, opts.Servers) + // Derive Volumes or VolumesPerServer in the absence of the other + // Exclusively either variable is guaranteed to exist + if opts.Volumes == 0 { + opts.Volumes = opts.VolumesPerServer * opts.Servers + } else { + opts.VolumesPerServer = helpers.VolumesPerServer(opts.Volumes, opts.Servers) + } capacityPerVolume, err := helpers.CapacityPerVolume(opts.Capacity, opts.Volumes) if err != nil { return nil, err @@ -128,7 +147,7 @@ func NewTenant(opts *TenantOptions, userSecret *v1.Secret) (*miniov2.Tenant, err Console: opts.ExposeConsoleService, MinIO: opts.ExposeMinioService, }, - Pools: []miniov2.Pool{Pool(opts, volumesPerServer, *capacityPerVolume)}, + Pools: []miniov2.Pool{Pool(opts, opts.VolumesPerServer, *capacityPerVolume)}, RequestAutoCert: &autoCert, Mountpath: helpers.MinIOMountPath, KES: tenantKESConfig(opts.Name, opts.KmsSecret, opts.KesImage), diff --git a/kubectl-minio/cmd/tenant-create.go b/kubectl-minio/cmd/tenant-create.go index 1679a8c0503..d2b60d8f484 100644 --- a/kubectl-minio/cmd/tenant-create.go +++ b/kubectl-minio/cmd/tenant-create.go @@ -55,12 +55,12 @@ func newTenantCreateCmd(out io.Writer, errOut io.Writer) *cobra.Command { c := &createCmd{out: out, errOut: errOut} cmd := &cobra.Command{ - Use: "create --pool --servers --volumes --capacity --namespace ", + Use: "create --pool --servers ( --volumes | --volumes-per-server ) --capacity --namespace ", Short: "Create a MinIO tenant", Long: createDesc, Example: createExample, Args: func(cmd *cobra.Command, args []string) error { - // The disable-tls parameter default value is false, we cannot rely on the default value binded to the tenantOpts.DisableTLS variable + // The disable-tls parameter default value is false, we cannot rely on the default value bound to the tenantOpts.DisableTLS variable // to identify if the parameter --disable-tls was actually set on the command line. // regardless of which value is being set to the flag, if the flag and ONLY if the flag is present, then we disable TLS c.tenantOpts.DisableTLS = cmd.Flags().Lookup("disable-tls").Changed @@ -80,6 +80,7 @@ func newTenantCreateCmd(out io.Writer, errOut io.Writer) *cobra.Command { f.StringVarP(&c.tenantOpts.PoolName, "pool", "p", "", "name for this pool") f.Int32Var(&c.tenantOpts.Servers, "servers", 0, "total number of pods in MinIO tenant") f.Int32Var(&c.tenantOpts.Volumes, "volumes", 0, "total number of volumes in the MinIO tenant") + f.Int32Var(&c.tenantOpts.VolumesPerServer, "volumes-per-server", 0, "number of volumes in each server in the MinIO tenant") f.StringVar(&c.tenantOpts.Capacity, "capacity", "", "total raw capacity of MinIO tenant in this pool, e.g. 16Ti") f.StringVarP(&c.tenantOpts.NS, "namespace", "n", "", "k8s namespace for this MinIO tenant") f.StringVarP(&c.tenantOpts.StorageClass, "storage-class", "s", helpers.DefaultStorageclass, "storage class for this MinIO tenant") @@ -182,7 +183,11 @@ func (c *createCmd) populateInteractiveTenant() error { c.tenantOpts.Name = helpers.AskQuestion("Tenant name", helpers.CheckValidTenantName) c.tenantOpts.ConfigurationSecretName = fmt.Sprintf("%s-env-configuration", c.tenantOpts.Name) c.tenantOpts.Servers = int32(helpers.AskNumber("Total of servers", greaterThanZero)) - c.tenantOpts.Volumes = int32(helpers.AskNumber("Total of volumes", greaterThanZero)) + if helpers.Ask("Define 'Total of volumes'") { + c.tenantOpts.Volumes = int32(helpers.AskNumber("Total of volumes", greaterThanZero)) + } else { + c.tenantOpts.VolumesPerServer = int32(helpers.AskNumber("Volumes per server", greaterThanZero)) + } c.tenantOpts.NS = helpers.AskQuestion("Namespace", validateEmptyInput) c.tenantOpts.Capacity = helpers.AskQuestion("Capacity", validateCapacity) if err := c.tenantOpts.Validate(); err != nil { @@ -192,6 +197,7 @@ func (c *createCmd) populateInteractiveTenant() error { c.tenantOpts.ExposeMinioService = helpers.Ask("Expose Minio Service") c.tenantOpts.ExposeConsoleService = helpers.Ask("Expose Console Service") c.tenantOpts.EnableSFTP = helpers.Ask("Enable SFTP") + c.tenantOpts.DisableAntiAffinity = helpers.Ask("Disable Anti-Affinity (unsupported in production environment)") return nil } @@ -206,7 +212,16 @@ func validateCapacity(value string) error { if err := validateEmptyInput(value); err != nil { return err } - _, err := resource.ParseQuantity(value) + capacity, err := resource.ParseQuantity(value) + if err != nil { + if err == resource.ErrFormatWrong { + return errors.New("capacity flag is incorrectly formatted. Use a suffix like 'T' or 'Ti' only") + } + return err + } + if capacity.Sign() <= 0 { + return errors.New("capacity needs to be greater than zero") + } return err } diff --git a/kubectl-minio/cmd/tenant-expand.go b/kubectl-minio/cmd/tenant-expand.go index 8894f27a97e..b92d8348b08 100644 --- a/kubectl-minio/cmd/tenant-expand.go +++ b/kubectl-minio/cmd/tenant-expand.go @@ -20,10 +20,9 @@ import ( "encoding/json" "errors" "fmt" - "io" - "github.com/minio/kubectl-minio/cmd/helpers" "github.com/minio/kubectl-minio/cmd/resources" + "io" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/klog/v2" @@ -51,7 +50,7 @@ func newTenantExpandCmd(out io.Writer, errOut io.Writer) *cobra.Command { v := &expandCmd{out: out, errOut: errOut} cmd := &cobra.Command{ - Use: "expand --pool --servers --volumes --capacity --namespace ", + Use: "expand --pool --servers ( --volumes | --volumes-per-server ) --capacity --namespace ", Short: "Add capacity to existing tenant", Long: expandDesc, Example: expandExample, @@ -73,12 +72,13 @@ func newTenantExpandCmd(out io.Writer, errOut io.Writer) *cobra.Command { f.StringVarP(&v.tenantOpts.PoolName, "pool", "p", "", "name for this pool expansion") f.Int32Var(&v.tenantOpts.Servers, "servers", 0, "total number of pods to add to tenant") f.Int32Var(&v.tenantOpts.Volumes, "volumes", 0, "total number of volumes to add to tenant") + f.Int32Var(&v.tenantOpts.VolumesPerServer, "volumes-per-server", 0, "number of volumes in each server in the MinIO tenant") f.StringVar(&v.tenantOpts.Capacity, "capacity", "", "total raw capacity to add to tenant, e.g. 16Ti") f.StringVarP(&v.tenantOpts.StorageClass, "storage-class", "s", helpers.DefaultStorageclass, "storage class for the expanded MinIO tenant pool (can be different than original pool)") + f.BoolVar(&v.tenantOpts.DisableAntiAffinity, "enable-host-sharing", false, "[TESTING-ONLY] disable anti-affinity to allow pods to be co-located on a single node (unsupported in production environment)") f.BoolVarP(&v.output, "output", "o", false, "generate MinIO tenant yaml with expansion details") cmd.MarkFlagRequired("servers") - cmd.MarkFlagRequired("volumes") cmd.MarkFlagRequired("capacity") return cmd } @@ -123,7 +123,13 @@ func (v *expandCmd) run() error { return err } currentCapacity := helpers.TotalCapacity(*t) - volumesPerServer := helpers.VolumesPerServer(v.tenantOpts.Volumes, v.tenantOpts.Servers) + // Derive Volumes or VolumesPerServer in the absence of the other + // Exclusively either variable is guaranteed to exist + if v.tenantOpts.Volumes == 0 { + v.tenantOpts.Volumes = v.tenantOpts.VolumesPerServer * v.tenantOpts.Servers + } else { + v.tenantOpts.VolumesPerServer = helpers.VolumesPerServer(v.tenantOpts.Volumes, v.tenantOpts.Servers) + } capacityPerVolume, err := helpers.CapacityPerVolume(v.tenantOpts.Capacity, v.tenantOpts.Volumes) if err != nil { return err @@ -134,7 +140,7 @@ func (v *expandCmd) run() error { v.tenantOpts.PoolName = resources.GeneratePoolName(len(t.Spec.Pools)) } - t.Spec.Pools = append(t.Spec.Pools, resources.Pool(&v.tenantOpts, volumesPerServer, *capacityPerVolume)) + t.Spec.Pools = append(t.Spec.Pools, resources.Pool(&v.tenantOpts, v.tenantOpts.VolumesPerServer, *capacityPerVolume)) expandedCapacity := helpers.TotalCapacity(*t) if !v.output { fmt.Printf(Bold(fmt.Sprintf("\nExpanding Tenant '%s/%s' from %s to %s\n\n", t.ObjectMeta.Name, t.ObjectMeta.Namespace, currentCapacity, expandedCapacity))) diff --git a/kubectl-minio/cmd/tenant-info.go b/kubectl-minio/cmd/tenant-info.go index a1e16943436..a3d9e55be11 100644 --- a/kubectl-minio/cmd/tenant-info.go +++ b/kubectl-minio/cmd/tenant-info.go @@ -162,13 +162,15 @@ func printTenantInfo(tenant miniov2.Tenant) { } t := helpers.GetTable() - t.SetHeader([]string{"Pool", "Servers", "Volumes(server)", "Capacity(volume)"}) + t.SetHeader([]string{"Pool", "Servers", "Volumes per server", "Volumes", "Capacity per volume", "Capacity"}) for i, z := range tenant.Spec.Pools { t.Append([]string{ strconv.Itoa(i), strconv.Itoa(int(z.Servers)), strconv.Itoa(int(z.VolumesPerServer)), + strconv.Itoa(int(z.VolumesPerServer) * int(z.Servers)), humanize.IBytes(uint64(z.VolumeClaimTemplate.Spec.Resources.Requests.Storage().Value())), + humanize.IBytes(uint64(z.VolumeClaimTemplate.Spec.Resources.Requests.Storage().Value()) * uint64(z.VolumesPerServer) * uint64(z.Servers)), }) } t.Render() diff --git a/kubectl-minio/go.mod b/kubectl-minio/go.mod index 1752983be1f..5b45f452ac5 100644 --- a/kubectl-minio/go.mod +++ b/kubectl-minio/go.mod @@ -38,7 +38,6 @@ require ( github.com/go-openapi/jsonpointer v0.20.0 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.22.4 // indirect - github.com/goccy/go-json v0.10.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect @@ -55,8 +54,6 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.17.4 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect - github.com/lestrrat-go/jwx v1.2.27 // indirect - github.com/lestrrat-go/option v1.0.1 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a // indirect github.com/mailru/easyjson v0.7.7 // indirect diff --git a/kubectl-minio/go.sum b/kubectl-minio/go.sum index 8438b40ca53..9503bf19066 100644 --- a/kubectl-minio/go.sum +++ b/kubectl-minio/go.sum @@ -20,8 +20,6 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= @@ -55,8 +53,6 @@ github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogB github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= @@ -126,15 +122,6 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= -github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= -github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= -github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= -github.com/lestrrat-go/jwx v1.2.27 h1:cvnTnda/YzdyFuWdEAMkI6BsLtItSrASEVCI3C/IUEQ= -github.com/lestrrat-go/jwx v1.2.27/go.mod h1:Stob9LjSqR3lOmNdxF0/TvZo60V3hUGv8Fr7Bwzla3k= -github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= -github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= -github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= @@ -234,7 +221,6 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= @@ -277,7 +263,6 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -291,8 +276,6 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -335,8 +318,6 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -344,8 +325,6 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= @@ -360,7 +339,6 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=