From 2c7797df7373b9211f0887d17e4547fdff44a3c7 Mon Sep 17 00:00:00 2001 From: Balazs Nadasdi Date: Thu, 11 Nov 2021 15:42:47 +0100 Subject: [PATCH] chore(fmt): Enable disabled linters in global scope (#238) * chore(fmt): Enable disabled linters in global scope Global options: * An explanation for all nolint annotations is required. Please do not just ignore it, tell us why is it ignored. == wsl * Fixed everywhere. == lll * Fix everywhere. * Added exception on `https://` links. == gochecknoglobals * Fixed everywhere. == gci * Fixed everywhere (with `golangci-lint run --fix`) == godox No TODO comments should live in the code without filed issues to track them. The reason is simple: if we have a comment with "todo", it has the same value as not having that comment at all, because no one will care about it. * No TODO, BUG, and FIXME comments in the code. * Except if it has a filed github issue reference. * Update golangci-lint and fix new issues Disabled linters: golint: The linter 'golint' is deprecated (since v1.41.0) due to: The repository of the linter has been archived by the owner. Replaced by revive. interfacer: The linter 'interfacer' is deprecated (since v1.38.0) due to: The repository of the linter has been archived by the owner. scopelint: The linter 'scopelint' is deprecated (since v1.39.0) due to: The repository of the linter has been deprecated by the owner. Replaced by exportloopref. maligned: fieldalignment tagliatelle: We have a yaml structure already and it uses snake_case keys, this linter wants us to replace with camelCase. That would require a design document and update all yaml outputs. ireturn: Question? nilnil: We are using nil, nil returns in case it was not an error, but the resource does not exist. Later we might want to return an error and check for error type on the caller side. exhaustivestruct: We don't want to specify all fields with nil and empty string. I see the point, if you specify and the default behavior is changed, it does not break the code. * Use go 1.17 in the lint workflow --- .github/workflows/lint.yml | 5 +- .golangci.yml | 116 ++--- cmd/dev-helper/main.go | 2 +- core/application/commands.go | 4 +- core/application/reconcile.go | 3 +- core/models/network.go | 4 +- core/models/vmid.go | 2 + core/models/volumes.go | 2 - core/plans/microvm_create_update.go | 16 +- core/plans/microvm_delete.go | 6 +- core/plans/types.go | 1 + core/steps/microvm/create.go | 1 + core/steps/microvm/delete.go | 1 + core/steps/network/interface_create.go | 14 +- core/steps/network/interface_delete.go | 6 +- core/steps/runtime/dir_create.go | 6 +- core/steps/runtime/dir_delete.go | 2 + core/steps/runtime/initrd_mount.go | 2 + core/steps/runtime/kernel_mount.go | 2 + core/steps/runtime/volume_mount.go | 8 +- docs/adr/0005-network-device-name.md | 2 +- docs/adr/0246-linters.md | 208 +++++++++ hack/tools/go.mod | 99 ++-- hack/tools/go.sum | 430 +++++++++++++----- infrastructure/containerd/content.go | 35 +- infrastructure/containerd/convert.go | 11 +- infrastructure/containerd/event_service.go | 23 +- infrastructure/containerd/image_service.go | 34 +- infrastructure/containerd/lease.go | 3 +- infrastructure/containerd/repo.go | 61 ++- infrastructure/containerd/snapshot.go | 1 + .../controllers/microvm_controller.go | 24 +- infrastructure/firecracker/config.go | 30 +- infrastructure/firecracker/create.go | 22 +- infrastructure/firecracker/provider.go | 19 +- infrastructure/firecracker/state.go | 7 +- infrastructure/firecracker/types.go | 53 +-- infrastructure/grpc/convert.go | 7 + infrastructure/grpc/server.go | 45 +- infrastructure/network/network_service.go | 35 +- infrastructure/network/utils.go | 5 +- infrastructure/ulid/ulid.go | 8 +- internal/command/flags/flags.go | 2 + internal/command/gw/gw.go | 35 +- internal/command/root.go | 7 +- internal/command/run/run.go | 25 +- pkg/flags/flags.go | 6 +- pkg/log/log.go | 4 + pkg/planner/actuator.go | 20 +- pkg/queue/queue.go | 3 +- pkg/validation/validate.go | 38 +- pkg/wait/wait.go | 6 +- test/e2e/utils/runner.go | 32 +- 53 files changed, 1072 insertions(+), 471 deletions(-) create mode 100644 docs/adr/0246-linters.md diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index feeeb036..31a5deaf 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -8,5 +8,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + - uses: actions/setup-go@v2 + with: + go-version: '1.17' - name: Lint - run: make lint \ No newline at end of file + run: make lint diff --git a/.golangci.yml b/.golangci.yml index eb85a856..65aab7e7 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -6,6 +6,22 @@ run: - "./*/mock" linters-settings: + funlen: + lines: 110 + statements: 60 + staticcheck: + go: "1.17" + stylecheck: + go: "1.17" + cyclop: + max-complexity: 15 + skip-tests: true + gosec: + exclude-generated: true + lll: + line-length: 120 + misspell: + locale: GB goimports: local-prefixes: github.com/weaveworks/flintlock govet: @@ -17,6 +33,14 @@ linters-settings: allow-unused: false require-explanation: true require-specific: false + varnamelen: + ignore-names: + - err + - wg + - fs + - id + - vm + - ns issues: max-same-issues: 0 @@ -28,6 +52,12 @@ issues: - text: "local replacement are not allowed: github.com/weaveworks/flintlock/" linters: - gomoddirectives + - text: "sig: func github.com/weaveworks/flintlock/" + linters: + - wrapcheck + - source: "https://" + linters: + - lll - path: _test\.go linters: - goerr113 @@ -45,73 +75,23 @@ issues: linters: - exhaustivestruct - lll - -linters-settings: - funlen: - lines: 110 - statements: 60 - staticcheck: - go: "1.17" - stylecheck: - go: "1.17" - cyclop: - max-complexity: 12 - skip-tests: true + - wrapcheck + - source: "// .* #\\d+" + linters: + - godox + - path: test/e2e/ + linters: + - goerr113 + - gomnd linters: - disable-all: true - enable: - - deadcode - - errcheck - - gosimple - - govet - - ineffassign - - staticcheck - - structcheck - - typecheck - - unused - - varcheck - - bodyclose - - depguard - - dogsled - - dupl - - exhaustive - - exportloopref - - funlen - - gochecknoinits - - gocognit - - goconst - - gocritic - - gocyclo - - godot - - goerr113 - - gofmt - - gofumpt - - goheader - - goimports - - revive - - gomnd - - gomodguard - - goprintffuncname - - gosec - - misspell - - nakedret - - nestif - - nlreturn - - noctx - - nolintlint - - prealloc - - rowserrcheck - - exportloopref - - sqlclosecheck - - stylecheck - - testpackage - - unconvert - - unparam - - whitespace - disabled: - - gci - - godox - - gochecknoglobals - - lll - - wsl + enable-all: true + disable: + - exhaustivestruct + - golint + - interfacer + - ireturn + - maligned + - nilnil + - scopelint + - tagliatelle diff --git a/cmd/dev-helper/main.go b/cmd/dev-helper/main.go index 40642f00..114cd925 100644 --- a/cmd/dev-helper/main.go +++ b/cmd/dev-helper/main.go @@ -1,4 +1,4 @@ -//nolint +//nolint // We don't care about this, it will be deleted. package main import ( diff --git a/core/application/commands.go b/core/application/commands.go index e13d5b23..227a2c00 100644 --- a/core/application/commands.go +++ b/core/application/commands.go @@ -25,10 +25,12 @@ func (a *app) CreateMicroVM(ctx context.Context, mvm *models.MicroVM) (*models.M if err != nil { return nil, fmt.Errorf("generating random name for microvm: %w", err) } + vmid, err := models.NewVMID(name, defaults.MicroVMNamespace) if err != nil { return nil, fmt.Errorf("creating vmid: %w", err) } + mvm.ID = *vmid } @@ -49,8 +51,6 @@ func (a *app) CreateMicroVM(ctx context.Context, mvm *models.MicroVM) (*models.M } } - // TODO: validate the spec - // Set the timestamp when the VMspec was created. mvm.Spec.CreatedAt = a.ports.Clock().Unix() mvm.Status.State = models.PendingState diff --git a/core/application/reconcile.go b/core/application/reconcile.go index cebf89e0..5a475616 100644 --- a/core/application/reconcile.go +++ b/core/application/reconcile.go @@ -18,6 +18,7 @@ func (a *app) ReconcileMicroVM(ctx context.Context, id, namespace string) error logger := log.GetLogger(ctx).WithField("action", "reconcile") logger.Debugf("Getting spec for %s/%s", namespace, id) + spec, err := a.ports.Repo.Get(ctx, ports.RepositoryGetOptions{ Name: id, Namespace: namespace, @@ -35,8 +36,8 @@ func (a *app) ResyncMicroVMs(ctx context.Context, namespace string) error { "namespace": "ns", }) logger.Info("Resyncing specs") - logger.Debug("Getting all specs") + specs, err := a.ports.Repo.GetAll(ctx, namespace) if err != nil { return fmt.Errorf("getting all microvm specs for resync: %w", err) diff --git a/core/models/network.go b/core/models/network.go index a204f6f1..697b9dfe 100644 --- a/core/models/network.go +++ b/core/models/network.go @@ -5,7 +5,7 @@ type NetworkInterface struct { // GuestDeviceName is the name of the network interface to create in the microvm. GuestDeviceName string `json:"guest_device_name" validate:"required,excludesall=/@,guestDeviceName"` // AllowMetadataRequests indicates that this interface can be used for metadata requests. - // TODO: we may hide this within the firecracker plugin. + // TODO: we may hide this within the firecracker plugin. #179 AllowMetadataRequests bool `json:"allow_mmds,omitempty"` // GuestMAC allows the specifying of a specifi MAC address to use for the interface. If // not supplied a autogenerated MAC address will be used. @@ -14,8 +14,6 @@ type NetworkInterface struct { Type IfaceType `json:"type" validate:"oneof=tap macvtap unsupported"` // Address is an optional IP address to assign to this interface. If not supplied then DHCP will be used. Address string `json:"address,omitempty" validate:"omitempty,cidr"` - // TODO: add rate limiting. - // TODO: add CNI. } type NetworkInterfaceStatus struct { diff --git a/core/models/vmid.go b/core/models/vmid.go index da861418..895ef21f 100644 --- a/core/models/vmid.go +++ b/core/models/vmid.go @@ -29,6 +29,7 @@ func NewVMID(name, namespace string) (*VMID, error) { if name == "" { return nil, coreerrs.ErrNameRequired } + if namespace == "" { return nil, coreerrs.ErrNamespaceRequired } @@ -98,6 +99,7 @@ func splitVMIDFromString(id string) (namespace string, name string, err error) { if parts[0] == "" { return "", "", coreerrs.ErrNamespaceRequired } + if parts[1] == "" { return "", "", coreerrs.ErrNameRequired } diff --git a/core/models/volumes.go b/core/models/volumes.go index 328eb291..9ea0a6c4 100644 --- a/core/models/volumes.go +++ b/core/models/volumes.go @@ -17,7 +17,6 @@ type Volume struct { PartitionID string `json:"partition_id,omitempty"` // Size is the size to resize this volume to. Size int32 `json:"size,omitempty"` - // TODO: add rate limiting. } // Volumes represents a collection of volumes. @@ -38,7 +37,6 @@ func (v Volumes) GetByID(id string) *Volume { type VolumeSource struct { // Container is used to specify a source of a volume as a OCI container. Container *ContainerVolumeSource `json:"container,omitempty"` - // TODO: add CSI. } // ContainerDriveSource represents the details of a volume coming from a OCI image. diff --git a/core/plans/microvm_create_update.go b/core/plans/microvm_create_update.go index 1fc2f0fe..238c5d77 100644 --- a/core/plans/microvm_create_update.go +++ b/core/plans/microvm_create_update.go @@ -107,25 +107,32 @@ func (p *microvmCreateOrUpdatePlan) addStep(ctx context.Context, step planner.Pr return nil } -func (p *microvmCreateOrUpdatePlan) addImageSteps(ctx context.Context, vm *models.MicroVM, imageSvc ports.ImageService) error { +func (p *microvmCreateOrUpdatePlan) addImageSteps(ctx context.Context, + vm *models.MicroVM, + imageSvc ports.ImageService, +) error { for i := range vm.Spec.Volumes { vol := vm.Spec.Volumes[i] + status, ok := vm.Status.Volumes[vol.ID] if !ok { status = &models.VolumeStatus{} vm.Status.Volumes[vol.ID] = status } + if vol.Source.Container != nil { if err := p.addStep(ctx, runtime.NewVolumeMount(&vm.ID, &vol, status, imageSvc)); err != nil { return fmt.Errorf("adding volume mount step: %w", err) } } } + if string(vm.Spec.Kernel.Image) != "" { if err := p.addStep(ctx, runtime.NewKernelMount(vm, imageSvc)); err != nil { return fmt.Errorf("adding kernel mount step: %w", err) } } + if vm.Spec.Initrd != nil { if err := p.addStep(ctx, runtime.NewInitrdMount(vm, imageSvc)); err != nil { return fmt.Errorf("adding initrd mount step: %w", err) @@ -135,14 +142,19 @@ func (p *microvmCreateOrUpdatePlan) addImageSteps(ctx context.Context, vm *model return nil } -func (p *microvmCreateOrUpdatePlan) addNetworkSteps(ctx context.Context, vm *models.MicroVM, networkSvc ports.NetworkService) error { +func (p *microvmCreateOrUpdatePlan) addNetworkSteps(ctx context.Context, + vm *models.MicroVM, + networkSvc ports.NetworkService, +) error { for i := range vm.Spec.NetworkInterfaces { iface := vm.Spec.NetworkInterfaces[i] + status, ok := vm.Status.NetworkInterfaces[iface.GuestDeviceName] if !ok { status = &models.NetworkInterfaceStatus{} vm.Status.NetworkInterfaces[iface.GuestDeviceName] = status } + if err := p.addStep(ctx, network.NewNetworkInterface(&vm.ID, &iface, status, networkSvc)); err != nil { return fmt.Errorf("adding create network interface step: %w", err) } diff --git a/core/plans/microvm_delete.go b/core/plans/microvm_delete.go index 774eced5..667fdc77 100644 --- a/core/plans/microvm_delete.go +++ b/core/plans/microvm_delete.go @@ -119,7 +119,11 @@ func (p *microvmDeletePlan) addStep(ctx context.Context, step planner.Procedure) return nil } -func (p *microvmDeletePlan) addNetworkSteps(ctx context.Context, vm *models.MicroVM, networkSvc ports.NetworkService) error { +func (p *microvmDeletePlan) addNetworkSteps( + ctx context.Context, + vm *models.MicroVM, + networkSvc ports.NetworkService, +) error { for i := range vm.Spec.NetworkInterfaces { iface := vm.Spec.NetworkInterfaces[i] ifaceStats := vm.Status.NetworkInterfaces[iface.GuestDeviceName] diff --git a/core/plans/types.go b/core/plans/types.go index 2fe3e436..8693f593 100644 --- a/core/plans/types.go +++ b/core/plans/types.go @@ -2,6 +2,7 @@ package plans import ( "github.com/spf13/afero" + "github.com/weaveworks/flintlock/core/ports" ) diff --git a/core/steps/microvm/create.go b/core/steps/microvm/create.go index a1ea91da..a12fadcd 100644 --- a/core/steps/microvm/create.go +++ b/core/steps/microvm/create.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/sirupsen/logrus" + "github.com/weaveworks/flintlock/core/errors" "github.com/weaveworks/flintlock/core/models" "github.com/weaveworks/flintlock/core/ports" diff --git a/core/steps/microvm/delete.go b/core/steps/microvm/delete.go index 7fa26bac..25c70156 100644 --- a/core/steps/microvm/delete.go +++ b/core/steps/microvm/delete.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/sirupsen/logrus" + "github.com/weaveworks/flintlock/core/errors" "github.com/weaveworks/flintlock/core/models" "github.com/weaveworks/flintlock/core/ports" diff --git a/core/steps/network/interface_create.go b/core/steps/network/interface_create.go index 30339ef1..f12830c7 100644 --- a/core/steps/network/interface_create.go +++ b/core/steps/network/interface_create.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/sirupsen/logrus" + "github.com/weaveworks/flintlock/core/errors" "github.com/weaveworks/flintlock/core/models" "github.com/weaveworks/flintlock/core/ports" @@ -13,7 +14,11 @@ import ( "github.com/weaveworks/flintlock/pkg/planner" ) -func NewNetworkInterface(vmid *models.VMID, iface *models.NetworkInterface, status *models.NetworkInterfaceStatus, svc ports.NetworkService) planner.Procedure { +func NewNetworkInterface(vmid *models.VMID, + iface *models.NetworkInterface, + status *models.NetworkInterfaceStatus, + svc ports.NetworkService, +) planner.Procedure { return &createInterface{ vmid: vmid, iface: iface, @@ -87,10 +92,11 @@ func (s *createInterface) Do(ctx context.Context) ([]planner.Procedure, error) { if err != nil { return nil, fmt.Errorf("checking if networking interface exists: %w", err) } + if exists { - details, err := s.svc.IfaceDetails(ctx, deviceName) - if err != nil { - return nil, fmt.Errorf("getting interface details: %w", err) + details, detailsErr := s.svc.IfaceDetails(ctx, deviceName) + if detailsErr != nil { + return nil, fmt.Errorf("getting interface details: %w", detailsErr) } s.status.HostDeviceName = deviceName diff --git a/core/steps/network/interface_delete.go b/core/steps/network/interface_delete.go index 0584e0e7..5840756a 100644 --- a/core/steps/network/interface_delete.go +++ b/core/steps/network/interface_delete.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/sirupsen/logrus" + "github.com/weaveworks/flintlock/core/errors" "github.com/weaveworks/flintlock/core/models" "github.com/weaveworks/flintlock/core/ports" @@ -12,7 +13,10 @@ import ( "github.com/weaveworks/flintlock/pkg/planner" ) -func DeleteNetworkInterface(vmid *models.VMID, iface *models.NetworkInterfaceStatus, svc ports.NetworkService) planner.Procedure { +func DeleteNetworkInterface(vmid *models.VMID, + iface *models.NetworkInterfaceStatus, + svc ports.NetworkService, +) planner.Procedure { return deleteInterface{ vmid: vmid, iface: iface, diff --git a/core/steps/runtime/dir_create.go b/core/steps/runtime/dir_create.go index 70affbc4..e3012142 100644 --- a/core/steps/runtime/dir_create.go +++ b/core/steps/runtime/dir_create.go @@ -38,8 +38,8 @@ func (s *createDirectory) ShouldDo(ctx context.Context) (bool, error) { "mode": s.mode.String(), }) logger.Debug("checking if procedure should be run") - logger.Trace("checking if directory exists") + exists, err := s.directoryExists() if err != nil { return false, err @@ -50,6 +50,7 @@ func (s *createDirectory) ShouldDo(ctx context.Context) (bool, error) { } logger.Trace("checking directory permissions") + info, err := s.fs.Stat(s.dir) if err != nil { return false, fmt.Errorf("doing stat on %s: %w", s.dir, err) @@ -78,14 +79,17 @@ func (s *createDirectory) Do(ctx context.Context) ([]planner.Procedure, error) { if err != nil { return nil, err } + if !exists { logger.Trace("creating directory") + if err := s.fs.Mkdir(s.dir, s.mode); err != nil { return nil, fmt.Errorf("creating directory %s: %w", s.dir, err) } } logger.Trace("setting permissions for directory") + if err := s.fs.Chmod(s.dir, s.mode); err != nil { return nil, fmt.Errorf("changing directory permissions for %s: %w", s.dir, err) } diff --git a/core/steps/runtime/dir_delete.go b/core/steps/runtime/dir_delete.go index 3e7ff387..a550da44 100644 --- a/core/steps/runtime/dir_delete.go +++ b/core/steps/runtime/dir_delete.go @@ -52,8 +52,10 @@ func (s *deleteDirectory) Do(ctx context.Context) ([]planner.Procedure, error) { if err != nil { return nil, err } + if exists { logger.Trace("deleting directory") + if err := s.fs.RemoveAll(s.dir); err != nil { return nil, fmt.Errorf("deleting directory %s: %w", s.dir, err) } diff --git a/core/steps/runtime/initrd_mount.go b/core/steps/runtime/initrd_mount.go index 464fd553..689dd820 100644 --- a/core/steps/runtime/initrd_mount.go +++ b/core/steps/runtime/initrd_mount.go @@ -50,6 +50,7 @@ func (s *initrdMount) ShouldDo(ctx context.Context) (bool, error) { } input := s.getMountSpec() + mounted, err := s.imageSvc.IsMounted(ctx, input) if err != nil { return false, fmt.Errorf("checking if image %s is mounted: %w", input.ImageName, err) @@ -76,6 +77,7 @@ func (s *initrdMount) Do(ctx context.Context) ([]planner.Procedure, error) { if err != nil { return nil, fmt.Errorf("mount images %s for initrd use: %w", input.ImageName, err) } + if len(mounts) == 0 { return nil, cerrs.ErrNoMount } diff --git a/core/steps/runtime/kernel_mount.go b/core/steps/runtime/kernel_mount.go index d7a7cbd1..28faaaf1 100644 --- a/core/steps/runtime/kernel_mount.go +++ b/core/steps/runtime/kernel_mount.go @@ -46,6 +46,7 @@ func (s *kernelMount) ShouldDo(ctx context.Context) (bool, error) { } input := s.getMountSpec() + mounted, err := s.imageSvc.IsMounted(ctx, input) if err != nil { return false, fmt.Errorf("checking if image %s is mounted: %w", input.ImageName, err) @@ -76,6 +77,7 @@ func (s *kernelMount) Do(ctx context.Context) ([]planner.Procedure, error) { if err != nil { return nil, fmt.Errorf("mount images %s for kernel use: %w", input.ImageName, err) } + if len(mounts) == 0 { return nil, cerrs.ErrNoMount } diff --git a/core/steps/runtime/volume_mount.go b/core/steps/runtime/volume_mount.go index 71b0ed22..54e4c9bc 100644 --- a/core/steps/runtime/volume_mount.go +++ b/core/steps/runtime/volume_mount.go @@ -13,7 +13,11 @@ import ( "github.com/weaveworks/flintlock/pkg/planner" ) -func NewVolumeMount(vmid *models.VMID, volume *models.Volume, status *models.VolumeStatus, imageService ports.ImageService) planner.Procedure { +func NewVolumeMount(vmid *models.VMID, + volume *models.Volume, + status *models.VolumeStatus, + imageService ports.ImageService, +) planner.Procedure { return &volumeMount{ vmid: vmid, volume: volume, @@ -46,6 +50,7 @@ func (s *volumeMount) ShouldDo(ctx context.Context) (bool, error) { } input := s.getMountSpec() + mounted, err := s.imageSvc.IsMounted(ctx, input) if err != nil { return false, fmt.Errorf("checking if image %s is mounted: %w", input.ImageName, err) @@ -72,6 +77,7 @@ func (s *volumeMount) Do(ctx context.Context) ([]planner.Procedure, error) { if err != nil { return nil, fmt.Errorf("mount images %s for volume use: %w", input.ImageName, err) } + if len(mounts) == 0 { return nil, cerrs.ErrNoVolumeMount } diff --git a/docs/adr/0005-network-device-name.md b/docs/adr/0005-network-device-name.md index 2344a7ef..f1a6f313 100644 --- a/docs/adr/0005-network-device-name.md +++ b/docs/adr/0005-network-device-name.md @@ -1,6 +1,6 @@ # 5. Network Device Name on Host -* Status: pending // will be updated after PR review +* Status: accepted * Date: 2021-11-08 * Authors: @yitsushi * Deciders: @Callisto13 @jmickey @richardcase @yitsushi diff --git a/docs/adr/0246-linters.md b/docs/adr/0246-linters.md new file mode 100644 index 00000000..b8f0fa8c --- /dev/null +++ b/docs/adr/0246-linters.md @@ -0,0 +1,208 @@ +# 246. Linters + +Status: accepted +Date: 2021-11-10 +Authors: @yitsushi +Deciders: @Callisto13 @jmickey @richardcase @yitsushi + +# Context + +A few linters are disabled and they can improve the code, and the linter tool +(golangci-lint) was misconfigured and a lot of `linters-settings` options were +simply ignored. + +# Scope + +Enable all linters and set reasonable exception list and linter settings. + +# Decision + +## gci + +> Gci control golang package import order and make it always deterministic. + +This makes the import list easier to read and see what imports are from external, +built-in, or internal packages. + +### Example + +```go +import ( + "context" + "fmt" + + "github.com/sirupsen/logrus" + + "github.com/weaveworks/flintlock/core/errors" + "github.com/weaveworks/flintlock/core/models" + "github.com/weaveworks/flintlock/core/ports" + "github.com/weaveworks/flintlock/pkg/log" +) +``` + +## godox + +> Tool for detection of FIXME, TODO and other comment keywords. + +No `TODO`, `FIXME`, or `BUG` comments should live in the code without filed +issues to track them. The reason is simple: if we have a comment with "todo", +it has the same value as not having that comment at all, because no one will +care about it. + +We can mark block with `TODO`, `FIXME`, or `BUG` if we have a GitHub issues to +fix it. We can annotate these comments with an GitHub reference at the end of +the line. + +### Example + +```go +// TODO: we may hide this within the firecracker plugin. #179 +``` + +## gochecknoglobals + +> A global variable is a variable declared in package scope and that can be +> read and written to by any function within the package. Global variables can +> cause side effects which are difficult to keep track of. A code in one +> function may change the variables state while another unrelated chunk of code +> may be effected by it. + +The official description has all the information. + +## lll + +> Reports long lines + +Long lines are hard to read and hard to edit. Most of the time if a line is too +long, it can be reduced with a different pattern (for example Options pattern +for functions), or can be re-formatted into multiple lines. + +**Exception:** + +If a line contains the `https://` substring, it will be ignored automatically. + +## wsl + +> Whitespace Linter - Forces you to use empty lines! + +This linter has a lot of rules and they make the code easier to read. + +### Example + +**One big block of code** + +
+ Without empty lines + +```go +stdOutFile, err := p.fs.OpenFile(vmState.StdoutPath(), os.O_WRONLY|os.O_CREATE|os.O_APPEND, defaults.DataFilePerm) +if err != nil { + return nil, fmt.Errorf("opening stdout file %s: %w", vmState.StdoutPath(), err) +} +stdErrFile, err := p.fs.OpenFile(vmState.StderrPath(), os.O_WRONLY|os.O_CREATE|os.O_APPEND, defaults.DataFilePerm) +if err != nil { + return nil, fmt.Errorf("opening sterr file %s: %w", vmState.StderrPath(), err) +} +cmd.Stderr = stdErrFile +cmd.Stdout = stdOutFile +cmd.Stdin = &bytes.Buffer{} +if !exists { + if err = p.fs.MkdirAll(vmState.Root(), defaults.DataDirPerm); err != nil { + return fmt.Errorf("creating state directory %s: %w", vmState.Root(), err) + } +} +``` +
+ +
+ With empty lines + +```go +stdOutFile, err := p.fs.OpenFile(vmState.StdoutPath(), os.O_WRONLY|os.O_CREATE|os.O_APPEND, defaults.DataFilePerm) +if err != nil { + return nil, fmt.Errorf("opening stdout file %s: %w", vmState.StdoutPath(), err) +} + +stdErrFile, err := p.fs.OpenFile(vmState.StderrPath(), os.O_WRONLY|os.O_CREATE|os.O_APPEND, defaults.DataFilePerm) +if err != nil { + return nil, fmt.Errorf("opening sterr file %s: %w", vmState.StderrPath(), err) +} + +cmd.Stderr = stdErrFile +cmd.Stdout = stdOutFile +cmd.Stdin = &bytes.Buffer{} + +if !exists { + if err = p.fs.MkdirAll(vmState.Root(), defaults.DataDirPerm); err != nil { + return fmt.Errorf("creating state directory %s: %w", vmState.Root(), err) + } +} +``` +
+ +**Error check** + +
+ With empty lines + +```go +vmState := NewState(*vmid, p.config.StateRoot, p.fs) +pidPath := vmState.PIDPath() +exists, err := afero.Exists(p.fs, pidPath) +if err != nil { + return ports.MicroVMStateUnknown, fmt.Errorf("checking pid file exists: %w", err) +} +if !exists { + return ports.MicroVMStatePending, nil +} +``` +
+ +
+ With empty lines + +```go +vmState := NewState(*vmid, p.config.StateRoot, p.fs) +pidPath := vmState.PIDPath() + +exists, err := afero.Exists(p.fs, pidPath) +if err != nil { + return ports.MicroVMStateUnknown, fmt.Errorf("checking pid file exists: %w", err) +} + +if !exists { + return ports.MicroVMStatePending, nil +} +``` +
+ +## Description on ignored linters + +It is possible to add a `//nolint` command for a specific file, block, or line, +but it's not recommended. If it has a reason why we need that `//nolint`, tell +us a why. + + +### Example + +```go +return rand.New(rand.NewSource(time.Now().UnixNano())) //nolint: gosec // It's not a security context. + + +//nolint:exhaustivestruct // I don't want to specify all values with nil. +root.AddCommand(&cobra.Command{...}) + +//nolint:gosec // The purpose of this call is to execute whatever the caller wants. +process := exec.Command(options.Command, options.Args...) +``` + +# Consequences + +* All `todo` comments have a GitHub reference. +* Code will be easier to read and update. +* If a linter rule is ignored, the code itself documents why. +* No unnecessary global variables, less painful debugging what changed that value. +* Spell checker in comments with GB locale. No more `maintanence` or `color`. +* Some of the rules are hard to keep in mind first. + +Discussion: https://github.com/weaveworks/flintlock/discussions/246 diff --git a/hack/tools/go.mod b/hack/tools/go.mod index f5c24421..b7b6be00 100644 --- a/hack/tools/go.mod +++ b/hack/tools/go.mod @@ -4,7 +4,7 @@ go 1.17 require ( github.com/golang/mock v1.6.0 - github.com/golangci/golangci-lint v1.41.1 + github.com/golangci/golangci-lint v1.43.0 github.com/google/wire v0.5.0 github.com/grpc-ecosystem/grpc-gateway/v2 v2.5.0 github.com/onsi/ginkgo v1.16.4 @@ -14,8 +14,10 @@ require ( ) require ( - 4d63.com/gochecknoglobals v0.0.0-20201008074935-acfc0b28355a // indirect - github.com/BurntSushi/toml v0.3.1 // indirect + 4d63.com/gochecknoglobals v0.1.0 // indirect + github.com/Antonboom/errname v0.1.5 // indirect + github.com/Antonboom/nilnil v0.1.0 // indirect + github.com/BurntSushi/toml v0.4.1 // indirect github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect github.com/Masterminds/goutils v1.1.0 // indirect github.com/Masterminds/semver v1.5.0 // indirect @@ -26,34 +28,37 @@ require ( github.com/ashanbrown/makezero v0.0.0-20210520155254-b6261585ddde // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bkielbasa/cyclop v1.2.0 // indirect + github.com/blizzy78/varnamelen v0.3.0 // indirect github.com/bombsimon/wsl/v3 v3.3.0 // indirect + github.com/breml/bidichk v0.1.1 // indirect + github.com/butuzov/ireturn v0.1.1 // indirect github.com/cespare/xxhash/v2 v2.1.1 // indirect - github.com/charithe/durationcheck v0.0.8 // indirect + github.com/charithe/durationcheck v0.0.9 // indirect github.com/chavacava/garif v0.0.0-20210405164556-e8a0a408d6af // indirect - github.com/daixiang0/gci v0.2.8 // indirect + github.com/daixiang0/gci v0.2.9 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/denis-tingajkin/go-header v0.4.2 // indirect github.com/envoyproxy/protoc-gen-validate v0.3.0-java // indirect - github.com/esimonov/ifshort v1.0.2 // indirect + github.com/esimonov/ifshort v1.0.3 // indirect github.com/ettle/strcase v0.1.1 // indirect - github.com/fatih/color v1.12.0 // indirect + github.com/fatih/color v1.13.0 // indirect github.com/fatih/structtag v1.2.0 // indirect - github.com/fsnotify/fsnotify v1.4.9 // indirect + github.com/fsnotify/fsnotify v1.5.1 // indirect github.com/fzipp/gocyclo v0.3.1 // indirect github.com/ghodss/yaml v1.0.0 // indirect - github.com/go-critic/go-critic v0.5.6 // indirect + github.com/go-critic/go-critic v0.6.1 // indirect github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect github.com/go-toolsmith/astcast v1.0.0 // indirect github.com/go-toolsmith/astcopy v1.0.0 // indirect - github.com/go-toolsmith/astequal v1.0.0 // indirect + github.com/go-toolsmith/astequal v1.0.1 // indirect github.com/go-toolsmith/astfmt v1.0.0 // indirect github.com/go-toolsmith/astp v1.0.0 // indirect github.com/go-toolsmith/strparse v1.0.0 // indirect github.com/go-toolsmith/typep v1.0.2 // indirect github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b // indirect github.com/gobwas/glob v0.2.3 // indirect - github.com/gofrs/flock v0.8.0 // indirect - github.com/gogo/protobuf v1.3.1 // indirect + github.com/gofrs/flock v0.8.1 // indirect + github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/glog v0.0.0-20210429001901-424d2337a529 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 // indirect @@ -63,14 +68,14 @@ require ( github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 // indirect github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca // indirect github.com/golangci/misspell v0.3.5 // indirect - github.com/golangci/revgrep v0.0.0-20210208091834-cd28932614b5 // indirect + github.com/golangci/revgrep v0.0.0-20210930125155-c22e5001d4f2 // indirect github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect github.com/google/go-cmp v0.5.6 // indirect github.com/google/subcommands v1.0.1 // indirect - github.com/google/uuid v1.1.2 // indirect + github.com/google/uuid v1.3.0 // indirect github.com/gordonklaus/ineffassign v0.0.0-20210225214923-2e10b2664254 // indirect - github.com/gostaticanalysis/analysisutil v0.4.1 // indirect - github.com/gostaticanalysis/comment v1.4.1 // indirect + github.com/gostaticanalysis/analysisutil v0.7.1 // indirect + github.com/gostaticanalysis/comment v1.4.2 // indirect github.com/gostaticanalysis/forcetypeassert v0.0.0-20200621232751-01d4955beaa5 // indirect github.com/gostaticanalysis/nilerr v0.1.1 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect @@ -80,90 +85,92 @@ require ( github.com/imdario/mergo v0.3.8 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/jgautheron/goconst v1.5.1 // indirect - github.com/jingyugao/rowserrcheck v1.1.0 // indirect + github.com/jingyugao/rowserrcheck v1.1.1 // indirect github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect github.com/julz/importas v0.0.0-20210419104244-841f0c0fe66d // indirect github.com/kisielk/errcheck v1.6.0 // indirect github.com/kisielk/gotool v1.0.0 // indirect github.com/kulti/thelper v0.4.0 // indirect - github.com/kunwardeep/paralleltest v1.0.2 // indirect + github.com/kunwardeep/paralleltest v1.0.3 // indirect github.com/kyoh86/exportloopref v0.1.8 // indirect - github.com/ldez/gomoddirectives v0.2.1 // indirect + github.com/ldez/gomoddirectives v0.2.2 // indirect github.com/ldez/tagliatelle v0.2.0 // indirect - github.com/magiconair/properties v1.8.1 // indirect + github.com/magiconair/properties v1.8.5 // indirect github.com/maratori/testpackage v1.0.1 // indirect github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 // indirect - github.com/mattn/go-colorable v0.1.8 // indirect - github.com/mattn/go-isatty v0.0.12 // indirect + github.com/mattn/go-colorable v0.1.11 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect github.com/mbilski/exhaustivestruct v1.2.0 // indirect - github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81 // indirect - github.com/mgechev/revive v1.0.7 // indirect + github.com/mgechev/dots v0.0.0-20210922191527-e955255bf517 // indirect + github.com/mgechev/revive v1.1.2 // indirect github.com/mitchellh/copystructure v1.0.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/mitchellh/mapstructure v1.1.2 // indirect + github.com/mitchellh/mapstructure v1.4.2 // indirect github.com/mitchellh/reflectwalk v1.0.1 // indirect github.com/moricho/tparallel v0.2.1 // indirect github.com/mwitkow/go-proto-validators v0.2.0 // indirect - github.com/nakabonne/nestif v0.3.0 // indirect + github.com/nakabonne/nestif v0.3.1 // indirect github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 // indirect - github.com/nishanths/exhaustive v0.1.0 // indirect + github.com/nishanths/exhaustive v0.2.3 // indirect github.com/nishanths/predeclared v0.2.1 // indirect github.com/nxadm/tail v1.4.8 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/pelletier/go-toml v1.2.0 // indirect + github.com/pelletier/go-toml v1.9.4 // indirect github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/polyfloyd/go-errorlint v0.0.0-20210510181950-ab96adb96fea // indirect + github.com/polyfloyd/go-errorlint v0.0.0-20210722154253-910bb7978349 // indirect github.com/prometheus/client_golang v1.7.1 // indirect github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.10.0 // indirect - github.com/prometheus/procfs v0.1.3 // indirect + github.com/prometheus/procfs v0.6.0 // indirect github.com/pseudomuto/protokit v0.2.0 // indirect - github.com/quasilyte/go-ruleguard v0.3.4 // indirect + github.com/quasilyte/go-ruleguard v0.3.13 // indirect github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 // indirect - github.com/ryancurrah/gomodguard v1.2.2 // indirect + github.com/ryancurrah/gomodguard v1.2.3 // indirect github.com/ryanrolds/sqlclosecheck v0.3.0 // indirect github.com/sanposhiho/wastedassign/v2 v2.0.6 // indirect - github.com/securego/gosec/v2 v2.8.0 // indirect + github.com/securego/gosec/v2 v2.9.1 // indirect github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect github.com/sirupsen/logrus v1.8.1 // indirect + github.com/sivchari/tenv v1.4.7 // indirect github.com/sonatard/noctx v0.0.1 // indirect github.com/sourcegraph/go-diff v0.6.1 // indirect github.com/spf13/afero v1.6.0 // indirect - github.com/spf13/cast v1.3.0 // indirect - github.com/spf13/cobra v1.1.3 // indirect - github.com/spf13/jwalterweatherman v1.0.0 // indirect + github.com/spf13/cast v1.4.1 // indirect + github.com/spf13/cobra v1.2.1 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.7.1 // indirect - github.com/ssgreg/nlreturn/v2 v2.1.0 // indirect + github.com/spf13/viper v1.9.0 // indirect + github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect github.com/stretchr/objx v0.2.0 // indirect github.com/stretchr/testify v1.7.0 // indirect github.com/subosito/gotenv v1.2.0 // indirect + github.com/sylvia7788/contextcheck v1.0.4 // indirect github.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b // indirect - github.com/tetafro/godot v1.4.7 // indirect + github.com/tetafro/godot v1.4.11 // indirect github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94 // indirect - github.com/tomarrell/wrapcheck/v2 v2.1.0 // indirect + github.com/tomarrell/wrapcheck/v2 v2.4.0 // indirect github.com/tommy-muehle/go-mnd/v2 v2.4.0 // indirect github.com/ultraware/funlen v0.0.3 // indirect github.com/ultraware/whitespace v0.0.4 // indirect - github.com/uudashr/gocognit v1.0.1 // indirect + github.com/uudashr/gocognit v1.0.5 // indirect github.com/yeya24/promlinter v0.1.0 // indirect - golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad // indirect + golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect golang.org/x/mod v0.5.0 // indirect golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d // indirect - golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912 // indirect + golang.org/x/sys v0.0.0-20211013075003-97ac67df715c // indirect golang.org/x/text v0.3.7 // indirect - golang.org/x/tools v0.1.5 // indirect + golang.org/x/tools v0.1.7 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/genproto v0.0.0-20211101144312-62acf1d99145 // indirect - gopkg.in/ini.v1 v1.51.0 // indirect + gopkg.in/ini.v1 v1.63.2 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect - honnef.co/go/tools v0.2.0 // indirect + honnef.co/go/tools v0.2.1 // indirect mvdan.cc/gofumpt v0.1.1 // indirect mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect diff --git a/hack/tools/go.sum b/hack/tools/go.sum index 8c5b45aa..16159bfd 100644 --- a/hack/tools/go.sum +++ b/hack/tools/go.sum @@ -1,5 +1,5 @@ -4d63.com/gochecknoglobals v0.0.0-20201008074935-acfc0b28355a h1:wFEQiK85fRsEVF0CRrPAos5LoAryUsIX1kPW/WrIqFw= -4d63.com/gochecknoglobals v0.0.0-20201008074935-acfc0b28355a/go.mod h1:wfdC5ZjKSPr7CybKEcgJhUOgeAQW1+7WcyK8OvUilfo= +4d63.com/gochecknoglobals v0.1.0 h1:zeZSRqj5yCg28tCkIV/z/lWbwvNm5qnKVS15PI8nhD0= +4d63.com/gochecknoglobals v0.1.0/go.mod h1:wfdC5ZjKSPr7CybKEcgJhUOgeAQW1+7WcyK8OvUilfo= bitbucket.org/creachadair/shell v0.0.6/go.mod h1:8Qqi/cYk7vPnsOePHroKXDJYmb5x7ENhtiFtfZq8K+M= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= @@ -17,6 +17,16 @@ cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZ cloud.google.com/go v0.60.0/go.mod h1:yw2G51M9IfRboUH61Us8GqCeF1PzPblB823Mn2q2eAU= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= @@ -26,6 +36,7 @@ cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM7 cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/firestore v1.6.0/go.mod h1:afJwI0vaXwAG54kI7A//lP/lSPDkQORQuMkv56TxEPU= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -39,8 +50,13 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/Antonboom/errname v0.1.5 h1:IM+A/gz0pDhKmlt5KSNTVAvfLMb+65RxavBXpRtCUEg= +github.com/Antonboom/errname v0.1.5/go.mod h1:DugbBstvPFQbv/5uLcRRzfrNqKE9tVdVCqWCLp6Cifo= +github.com/Antonboom/nilnil v0.1.0 h1:DLDavmg0a6G/F4Lt9t7Enrbgb3Oph6LnDE6YVsmTt74= +github.com/Antonboom/nilnil v0.1.0/go.mod h1:PhHLvRPSghY5Y7mX4TW+BHZQYo1A8flE5H20D3IPZBo= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw= +github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM= github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= @@ -55,14 +71,15 @@ github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuN github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OpenPeeDeeP/depguard v1.0.1 h1:VlW4R6jmBIv3/u1JNlawEvJMM4J+dPORPaZasQee8Us= github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM= -github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pOcUuw= github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE= -github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= +github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= +github.com/andybalholm/brotli v1.0.3/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/aokoli/goutils v1.0.1/go.mod h1:SijmP0QR8LtwsmDs8Yii5Z/S4trXFGFC2oO5g9DP+DQ= @@ -70,6 +87,7 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/ashanbrown/forbidigo v1.2.0 h1:RMlEFupPCxQ1IogYOQUnIQwGEUGK8g5vAPMRyJoSxbc= github.com/ashanbrown/forbidigo v1.2.0/go.mod h1:vVW7PEdqEFqapJe95xHkTfB1+XvZXBFg8t0sG2FIxmI= github.com/ashanbrown/makezero v0.0.0-20210520155254-b6261585ddde h1:YOsoVXsZQPA9aOTy1g0lAJv5VzZUvwQuZqug8XPeqfM= @@ -82,18 +100,24 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/bkielbasa/cyclop v1.2.0 h1:7Jmnh0yL2DjKfw28p86YTd/B4lRGcNuu12sKE35sM7A= github.com/bkielbasa/cyclop v1.2.0/go.mod h1:qOI0yy6A7dYC4Zgsa72Ppm9kONl0RoIlPbzot9mhmeI= +github.com/blizzy78/varnamelen v0.3.0 h1:80mYO7Y5ppeEefg1Jzu+NBg16iwToOQVnDnNIoWSShs= +github.com/blizzy78/varnamelen v0.3.0/go.mod h1:hbwRdBvoBqxk34XyQ6HA0UH3G0/1TKuv5AC4eaBT0Ec= github.com/bombsimon/wsl/v3 v3.3.0 h1:Mka/+kRLoQJq7g2rggtgQsjuI/K5Efd87WX96EWFxjM= github.com/bombsimon/wsl/v3 v3.3.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc= +github.com/breml/bidichk v0.1.1 h1:Qpy8Rmgos9qdJxhka0K7ADEE5bQZX9PQUthkgggHpFM= +github.com/breml/bidichk v0.1.1/go.mod h1:zbfeitpevDUGI7V91Uzzuwrn4Vls8MoBMrwtt78jmso= +github.com/butuzov/ireturn v0.1.1 h1:QvrO2QF2+/Cx1WA/vETCIYBKtRjc30vesdoPUNo1EbY= +github.com/butuzov/ireturn v0.1.1/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/charithe/durationcheck v0.0.8 h1:cnZrThioNW9gSV5JsRIXmkyHUbcDH7Y9hkzFDVc9/j0= -github.com/charithe/durationcheck v0.0.8/go.mod h1:SSbRIBVfMjCi/kEB6K65XEA83D6prSM8ap1UCpNKtgg= +github.com/charithe/durationcheck v0.0.9 h1:mPP4ucLrf/rKZiIG/a9IPXHGlh8p4CzgpyTy6EEutYk= +github.com/charithe/durationcheck v0.0.9/go.mod h1:SSbRIBVfMjCi/kEB6K65XEA83D6prSM8ap1UCpNKtgg= github.com/chavacava/garif v0.0.0-20210405164556-e8a0a408d6af h1:spmv8nSH9h5oCQf40jt/ufBCt9j0/58u4G+rkeMqXGI= github.com/chavacava/garif v0.0.0-20210405164556-e8a0a408d6af/go.mod h1:Qjyv4H3//PWVzTeCezG2b9IRn6myJxJSr4TD/xo6ojU= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -101,18 +125,17 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= @@ -120,8 +143,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/daixiang0/gci v0.2.8 h1:1mrIGMBQsBu0P7j7m1M8Lb+ZeZxsZL+jyGX4YoMJJpg= -github.com/daixiang0/gci v0.2.8/go.mod h1:+4dZ7TISfSmqfAGv59ePaHfNzgGtIkHAhhdKggP1JAc= +github.com/daixiang0/gci v0.2.9 h1:iwJvwQpBZmMg31w+QQ6jsyZ54KEATn6/nfARbBNW294= +github.com/daixiang0/gci v0.2.9/go.mod h1:+4dZ7TISfSmqfAGv59ePaHfNzgGtIkHAhhdKggP1JAc= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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= @@ -129,12 +152,12 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/denis-tingajkin/go-header v0.4.2 h1:jEeSF4sdv8/3cT/WY8AgDHUoItNSoEZ7qg9dX7pc218= github.com/denis-tingajkin/go-header v0.4.2/go.mod h1:eLRHAVXzE5atsKAnNRDB90WHCFFnBUn4RN0nRcs1LJA= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= @@ -142,27 +165,28 @@ github.com/envoyproxy/protoc-gen-validate v0.0.14/go.mod h1:iSmxcyjqTsJpI2R4NaDN github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.3.0-java h1:bV5JGEB1ouEzZa0hgVDFFiClrUEuGWRaAc/3mxR2QK0= github.com/envoyproxy/protoc-gen-validate v0.3.0-java/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/esimonov/ifshort v1.0.2 h1:K5s1W2fGfkoWXsFlxBNqT6J0ZCncPaKrGM5qe0bni68= -github.com/esimonov/ifshort v1.0.2/go.mod h1:yZqNJUrNn20K8Q9n2CrjTKYyVEmX209Hgu+M1LBpeZE= +github.com/esimonov/ifshort v1.0.3 h1:JD6x035opqGec5fZ0TLjXeROD2p5H7oLGn8MKfy9HTM= +github.com/esimonov/ifshort v1.0.3/go.mod h1:yZqNJUrNn20K8Q9n2CrjTKYyVEmX209Hgu+M1LBpeZE= github.com/ettle/strcase v0.1.1 h1:htFueZyVeE1XNnMEfbqp5r67qAN/4r6ya1ysq8Q+Zcw= github.com/ettle/strcase v0.1.1/go.mod h1:hzDLsPC7/lwKyBOywSHEP89nt2pDgdy+No1NBA9o9VY= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= -github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc= -github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= +github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/fullstorydev/grpcurl v1.6.0/go.mod h1:ZQ+ayqbKMJNhzLmbpCiurTVlaK2M/3nqZCxaQ2Ze/sM= github.com/fzipp/gocyclo v0.3.1 h1:A9UeX3HJSXTBzvHzhqoYVuE0eAhe+aM8XBCCwsPMZOc= github.com/fzipp/gocyclo v0.3.1/go.mod h1:DJHO6AUmbdqj2ET4Z9iArSuwWgYDRryYt2wASxc7x3E= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-critic/go-critic v0.5.6 h1:siUR1+322iVikWXoV75I1YRfNaC/yaLzhdF9Zwd8Tus= -github.com/go-critic/go-critic v0.5.6/go.mod h1:cVjj0DfqewQVIlIAGexPCaGaZDAqGE29PYDDADIVNEo= +github.com/go-critic/go-critic v0.6.1 h1:lS8B9LH/VVsvQQP7Ao5TJyQqteVKVs3E4dXiHMyubtI= +github.com/go-critic/go-critic v0.6.1/go.mod h1:SdNCfU0yF3UBjtaZGw6586/WocupMOJuiqgom5DsQxM= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -170,7 +194,8 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2 github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= +github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-redis/redis v6.15.8+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= @@ -181,8 +206,9 @@ github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= github.com/go-toolsmith/astcopy v1.0.0 h1:OMgl1b1MEpjFQ1m5ztEO06rz5CUd3oBv9RF7+DyvdG8= github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= -github.com/go-toolsmith/astequal v1.0.0 h1:4zxD8j3JRFNyLN46lodQuqz3xdKSrur7U/sr0SDS/gQ= github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= +github.com/go-toolsmith/astequal v1.0.1 h1:JbSszi42Jiqu36Gnf363HWS9MTEAz67vTQLponh3Moc= +github.com/go-toolsmith/astequal v1.0.1/go.mod h1:4oGA3EZXTVItV/ipGiOx7NWkY5veFfcsOJVS2YxltLw= github.com/go-toolsmith/astfmt v1.0.0 h1:A0vDDXt+vsvLEdbMFJAUBI/uTbRw1ffOPnxsILnFL6k= github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw= github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU= @@ -199,18 +225,19 @@ github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b h1:khEcpUM4yFcxg4 github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/gofrs/flock v0.8.0 h1:MSdYClljsF3PbENUUEx85nkWfJSGfzYI9yEBZOJz6CY= -github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20210429001901-424d2337a529 h1:2voWjNECnrZRbfwXxHB1/j8wa6xdKn85B5NzgVL/pTU= github.com/golang/glog v0.0.0-20210429001901-424d2337a529/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -221,6 +248,7 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -239,8 +267,10 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0= github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM= @@ -249,16 +279,16 @@ github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613 h1:9kfjN3AdxcbsZB github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8= github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a h1:iR3fYXUjHCR97qWS8ch1y9zPNsgXThGwjKPrYfqMPks= github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= -github.com/golangci/golangci-lint v1.41.1 h1:KH28pTSqRu6DTXIAANl1sPXNCmqg4VEH21z6G9Wj4SM= -github.com/golangci/golangci-lint v1.41.1/go.mod h1:LPtcY3aAAU8wydHrKpnanx9Og8K/cblZSyGmI5CJZUk= +github.com/golangci/golangci-lint v1.43.0 h1:SLwZFEmDgopqZpfP495zCtV9REUf551JJlJ51Ql7NZA= +github.com/golangci/golangci-lint v1.43.0/go.mod h1:VIFlUqidx5ggxDfQagdvd9E67UjMXtTHBkBQ7sHoC5Q= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA= github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o= github.com/golangci/misspell v0.3.5 h1:pLzmVdl3VxTOncgzHcvLOKirdvcx/TydsClUQXTehjo= github.com/golangci/misspell v0.3.5/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= -github.com/golangci/revgrep v0.0.0-20210208091834-cd28932614b5 h1:c9Mqqrm/Clj5biNaG7rABrmwUq88nHh0uABo2b/WYmc= -github.com/golangci/revgrep v0.0.0-20210208091834-cd28932614b5/go.mod h1:LK+zW4MpyytAWQRz0M4xnzEk50lSvqDQKfx304apFkY= +github.com/golangci/revgrep v0.0.0-20210930125155-c22e5001d4f2 h1:SgM7GDZTxtTTQPU84heOxy34iG5Du7F2jcoZnvp+fXI= +github.com/golangci/revgrep v0.0.0-20210930125155-c22e5001d4f2/go.mod h1:LK+zW4MpyytAWQRz0M4xnzEk50lSvqDQKfx304apFkY= github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 h1:zwtduBRr5SSWhqsYNgcuWO2kFlpdOZbP0+yRjmvPGys= github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -273,6 +303,7 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= @@ -280,6 +311,8 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -288,6 +321,13 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200507031123-427632fa3b1c/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/subcommands v1.0.1 h1:/eqq+otEXm5vhfBrbREPCSVQbvofip6kIz+mX5TUH7k= github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= @@ -295,14 +335,15 @@ github.com/google/trillian v1.3.11/go.mod h1:0tPraVHrSDkA3BO6vKX67zgLXs6SsOAbHEi github.com/google/uuid v0.0.0-20161128191214-064e2069ce9c/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/wire v0.5.0 h1:I7ELFeVBr3yfPIcc8+MWvrjk+3VjbcSzoXm3JVa+jD8= github.com/google/wire v0.5.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= github.com/gordonklaus/ineffassign v0.0.0-20210225214923-2e10b2664254 h1:Nb2aRlC404yz7gQIfRZxX9/MLvQiqXyiBTJtgAy6yrI= @@ -311,25 +352,27 @@ github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75/go.mod h1:g2644b0 github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= github.com/gostaticanalysis/analysisutil v0.1.0/go.mod h1:dMhHRU9KTiDcuLGdy87/2gTR8WruwYZrKdRq9m1O6uw= -github.com/gostaticanalysis/analysisutil v0.4.1 h1:/7clKqrVfiVwiBQLM0Uke4KvXnO6JcCTS7HwF2D6wG8= github.com/gostaticanalysis/analysisutil v0.4.1/go.mod h1:18U/DLpRgIUd459wGxVHE0fRgmo1UgHDcbw7F5idXu0= +github.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk= +github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc= github.com/gostaticanalysis/comment v1.3.0/go.mod h1:xMicKDx7XRXYdVwY9f9wQpDJVnqWxw9wCauCMKp+IBI= -github.com/gostaticanalysis/comment v1.4.1 h1:xHopR5L2lRz6OsjH4R2HG5wRhW9ySl3FsHIvi5pcXwc= github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado= +github.com/gostaticanalysis/comment v1.4.2 h1:hlnx5+S2fY9Zo9ePo4AhgYsYHbM2+eAv8m/s1JiCd6Q= +github.com/gostaticanalysis/comment v1.4.2/go.mod h1:KLUTGDv6HOCotCH8h2erHKmpci2ZoR8VPu34YA2uzdM= github.com/gostaticanalysis/forcetypeassert v0.0.0-20200621232751-01d4955beaa5 h1:rx8127mFPqXXsfPSo8BwnIU97MKFZc89WHAHt8PwDVY= github.com/gostaticanalysis/forcetypeassert v0.0.0-20200621232751-01d4955beaa5/go.mod h1:qZEedyP/sY1lTGV1uJ3VhWZ2mqag3IkWsDHVbplHXak= github.com/gostaticanalysis/nilerr v0.1.1 h1:ThE+hJP0fEp4zWLkWHWcRyI2Od0p7DlgYG3Uqrmrcpk= github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A= +github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M= +github.com/gostaticanalysis/testutil v0.4.0 h1:nhdCmubdmDF6VEatUNjgUZBJKWRqugoISdUv3PPQgHY= +github.com/gostaticanalysis/testutil v0.4.0/go.mod h1:bLIoPefWXrRi/ssLFWX1dx7Repi5x3CuviD3dgAZaBU= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= @@ -337,20 +380,27 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFb github.com/grpc-ecosystem/grpc-gateway/v2 v2.5.0 h1:ajue7SzQMywqRjg2fK7dcpc0QhFGpTR2plWfV4EZWR4= github.com/grpc-ecosystem/grpc-gateway/v2 v2.5.0/go.mod h1:r1hZAcvfFXuYmcKyCJI9wlyOPIZUJl6FCB8Cpca/NLE= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/api v1.10.1/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= +github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -359,13 +409,17 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo= github.com/huandu/xstrings v1.2.0 h1:yPeWdRnmynF7p+lLYz0H2tthW9lqhMJrQV/U7yy4wX0= github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.4/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= @@ -374,8 +428,8 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/jgautheron/goconst v1.5.1 h1:HxVbL1MhydKs8R8n/HE5NPvzfaYmQJA3o879lE4+WcM= github.com/jgautheron/goconst v1.5.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= github.com/jhump/protoreflect v1.6.1/go.mod h1:RZQ/lnuN+zqeRVpQigTwO6o0AJUkxbnSnpuG7toUTG4= -github.com/jingyugao/rowserrcheck v1.1.0 h1:u6h4eiNuCLqk73Ic5TXQq9yZS+uEXTdusn7c3w1Mr6A= -github.com/jingyugao/rowserrcheck v1.1.0/go.mod h1:TOQpc2SLx6huPfoFGK3UOnEG+u02D3C1GeosjupAKCA= +github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs= +github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= @@ -384,12 +438,13 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfC github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.2.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= +github.com/josharian/txtarfs v0.0.0-20210218200122-0702f000015a/go.mod h1:izVPOvVRsHiKkeGCT6tYBNWyDVuzj9wAaBb5R9qamfw= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/juju/ratelimit v1.0.1/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= @@ -398,56 +453,66 @@ github.com/julz/importas v0.0.0-20210419104244-841f0c0fe66d/go.mod h1:oSFU2R4XK/ github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/errcheck v1.6.0 h1:YTDO4pNy7AUN/021p+JGHycQyYNIyMoenM1YDVK6RlY= github.com/kisielk/errcheck v1.6.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 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/kulti/thelper v0.4.0 h1:2Nx7XbdbE/BYZeoip2mURKUdtHQRuy6Ug+wR7K9ywNM= github.com/kulti/thelper v0.4.0/go.mod h1:vMu2Cizjy/grP+jmsvOFDx1kYP6+PD1lqg4Yu5exl2U= -github.com/kunwardeep/paralleltest v1.0.2 h1:/jJRv0TiqPoEy/Y8dQxCFJhD56uS/pnvtatgTZBHokU= -github.com/kunwardeep/paralleltest v1.0.2/go.mod h1:ZPqNm1fVHPllh5LPVujzbVz1JN2GhLxSfY+oqUsvG30= +github.com/kunwardeep/paralleltest v1.0.3 h1:UdKIkImEAXjR1chUWLn+PNXqWUGs//7tzMeWuP7NhmI= +github.com/kunwardeep/paralleltest v1.0.3/go.mod h1:vLydzomDFpk7yu5UX02RmP0H8QfRPOV/oFhWN85Mjb4= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/kyoh86/exportloopref v0.1.8 h1:5Ry/at+eFdkX9Vsdw3qU4YkvGtzuVfzT4X7S77LoN/M= github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg= -github.com/ldez/gomoddirectives v0.2.1 h1:9pAcW9KRZW7HQjFwbozNvFMcNVwdCBufU7os5QUwLIY= -github.com/ldez/gomoddirectives v0.2.1/go.mod h1:sGicqkRgBOg//JfpXwkB9Hj0X5RyJ7mlACM5B9f6Me4= +github.com/ldez/gomoddirectives v0.2.2 h1:p9/sXuNFArS2RLc+UpYZSI4KQwGMEDWC/LbtF5OPFVg= +github.com/ldez/gomoddirectives v0.2.2/go.mod h1:cpgBogWITnCfRq2qGoDkKMEVSaarhdBr6g8G04uz6d0= github.com/ldez/tagliatelle v0.2.0 h1:693V8Bf1NdShJ8eu/s84QySA0J2VWBanVBa2WwXD/Wk= github.com/ldez/tagliatelle v0.2.0/go.mod h1:8s6WJQwEYHbKZDsp/LjArytKOG8qaMrKQQ3mFukHs88= github.com/letsencrypt/pkcs11key/v4 v4.0.0/go.mod h1:EFUvBDay26dErnNb70Nd0/VW3tJiIbETBPTl9ATXQag= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.10.3/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= +github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/maratori/testpackage v1.0.1 h1:QtJ5ZjqapShm0w5DosRjg0PRlSdAdlx+W6cCKoALdbQ= github.com/maratori/testpackage v1.0.1/go.mod h1:ddKdw+XG0Phzhx8BFDTKgpWP4i7MpApTE5fXSKAqwDU= github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 h1:pWxk9e//NbPwfxat7RXkts09K+dEBJWakUWwICVqYbA= github.com/matoous/godox v0.0.0-20210227103229-6504466cf951/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= +github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= +github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs= +github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= @@ -459,15 +524,17 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0j github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mbilski/exhaustivestruct v1.2.0 h1:wCBmUnSYufAHO6J4AVWY6ff+oxWxsVFrwgOdMUQePUo= github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= -github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81 h1:QASJXOGm2RZ5Ardbc86qNFvby9AqkLDibfChMtAg5QM= -github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg= -github.com/mgechev/revive v1.0.7 h1:5kEWTY/W5a0Eiqnkn2BAWsRZpxbs1ft15PsyNC7Rml8= -github.com/mgechev/revive v1.0.7/go.mod h1:vuE5ox/4L/HDd63MCcCk3H6wTLQ6XXezRphJ8cJJOxY= +github.com/mgechev/dots v0.0.0-20210922191527-e955255bf517 h1:zpIH83+oKzcpryru8ceC6BxnoG8TBrhgAvRg8obzup0= +github.com/mgechev/dots v0.0.0-20210922191527-e955255bf517/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg= +github.com/mgechev/revive v1.1.2 h1:MiYA/o9M7REjvOF20QN43U8OtXDDHQFKLCtJnxLGLog= +github.com/mgechev/revive v1.1.2/go.mod h1:bnXsMr+ZTH09V5rssEI+jHAZ4z+ZdyhgO/zsy3EhK+0= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -478,8 +545,10 @@ github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eI github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.2 h1:6h7AQ0yhTcIsmFmnAwQls75jp2Gzs4iB8W7pjMO+rqo= +github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.1 h1:FVzMWA5RllMAKIdUSC8mdWo3XtwoecrH79BY70sEEpE= github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= @@ -491,26 +560,25 @@ github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwd github.com/moricho/tparallel v0.2.1 h1:95FytivzT6rYzdJLdtfn6m1bfFJylOJK41+lgv/EHf4= github.com/moricho/tparallel v0.2.1/go.mod h1:fXEIZxG2vdfl0ZF8b42f5a78EhjjD5mX8qUplsoSU4k= github.com/mozilla/scribe v0.0.0-20180711195314-fb71baf557c1/go.mod h1:FIczTrinKo8VaLxe6PWTPEXRXDIHz2QAwiaBaP5/4a8= -github.com/mozilla/tls-observatory v0.0.0-20210209181001-cf43108d6880/go.mod h1:FUqVoUPHSEdDR0MnFM3Dh8AU0pZHLXUD127SAJGER/s= +github.com/mozilla/tls-observatory v0.0.0-20210609171429-7bc42856d2e5/go.mod h1:FUqVoUPHSEdDR0MnFM3Dh8AU0pZHLXUD127SAJGER/s= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-proto-validators v0.0.0-20180403085117-0950a7990007/go.mod h1:m2XC9Qq0AlmmVksL6FktJCdTYyLk7V3fKyp0sl1yWQo= github.com/mwitkow/go-proto-validators v0.2.0 h1:F6LFfmgVnfULfaRsQWBbe7F7ocuHCr9+7m+GAeDzNbQ= github.com/mwitkow/go-proto-validators v0.2.0/go.mod h1:ZfA1hW+UH/2ZHOWvQ3HnQaU0DtnpXu850MZiy+YUgcc= -github.com/nakabonne/nestif v0.3.0 h1:+yOViDGhg8ygGrmII72nV9B/zGxY188TYpfolntsaPw= -github.com/nakabonne/nestif v0.3.0/go.mod h1:dI314BppzXjJ4HsCnbo7XzrJHPszZsjnk5wEBSYHI2c= +github.com/nakabonne/nestif v0.3.1 h1:wm28nZjhQY5HyYPx+weN3Q65k6ilSBxDb8v5S81B81U= +github.com/nakabonne/nestif v0.3.1/go.mod h1:9EtoZochLn5iUprVDmDjqGKPofoUEBL8U4Ngq6aY7OE= github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 h1:4kuARK6Y6FxaNu/BnU2OAaLF86eTVhP2hjTB6iMvItA= github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nishanths/exhaustive v0.1.0 h1:kVlMw8h2LHPMGUVqUj6230oQjjTMFjwcZrnkhXzFfl8= -github.com/nishanths/exhaustive v0.1.0/go.mod h1:S1j9110vxV1ECdCudXRkeMnFQ/DQk9ajLT0Uf2MYZQQ= +github.com/nishanths/exhaustive v0.2.3 h1:+ANTMqRNrqwInnP9aszg/0jDo+zbXa4x66U19Bx/oTk= +github.com/nishanths/exhaustive v0.2.3/go.mod h1:bhIX678Nx8inLM9PbpvK1yv6oGtoP8BfaIeMzgBNKvc= github.com/nishanths/predeclared v0.0.0-20190419143655-18a43bb90ffc/go.mod h1:62PewwiQTlm/7Rj+cxVYqZvDIUc+JjZq6GHAC1fsObQ= github.com/nishanths/predeclared v0.2.1 h1:1TXtjmy4f3YCFjTxRd8zcFHOmoUir+gp0ESzjFzG2sw= github.com/nishanths/predeclared v0.2.1/go.mod h1:HvkGJcA3naj4lOwnFXFDkFxVtSqQMB9sbB1usJ+xjQE= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ= @@ -519,18 +587,25 @@ github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.16.1/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.11.0 h1:+CqWgvj0OZycCaqclBD1pxKHAU+tOkHmQIWvDHq2aug= -github.com/onsi/gomega v1.11.0/go.mod h1:azGKhqFUon9Vuj0YmTfLSmx0FUwqXYSTl5re8lQLTUg= +github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c= +github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/otiai10/copy v1.2.0 h1:HvG945u96iNadPoG2/Ja2+AUJeW5YuFQMixq9yirC+k= +github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= +github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= +github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= +github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= +github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM= +github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d h1:CdDQnGF8Nq9ocOS/xlSptM1N3BbrA6/kmaep5ggwaIA= github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= @@ -542,11 +617,11 @@ github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZ github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/polyfloyd/go-errorlint v0.0.0-20210510181950-ab96adb96fea h1:Sk6Xawg57ZkjXmFYD1xCHSKN6FtYM+km51MM7Lveyyc= -github.com/polyfloyd/go-errorlint v0.0.0-20210510181950-ab96adb96fea/go.mod h1:wi9BfjxjF/bwiZ701TzmfKu6UKC357IOAtNr0Td0Lvw= +github.com/polyfloyd/go-errorlint v0.0.0-20210722154253-910bb7978349 h1:Kq/3kL0k033ds3tyez5lFPrfQ74fNJ+OqCclRipubwA= +github.com/polyfloyd/go-errorlint v0.0.0-20210722154253-910bb7978349/go.mod h1:wi9BfjxjF/bwiZ701TzmfKu6UKC357IOAtNr0Td0Lvw= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.7.1 h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= @@ -555,17 +630,14 @@ github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1: github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/pseudomuto/protoc-gen-doc v1.3.2/go.mod h1:y5+P6n3iGrbKG+9O04V5ld71in3v/bX88wUwgt+U8EA= github.com/pseudomuto/protoc-gen-doc v1.5.0 h1:pHZp0MEiT68jrZV8js8BS7E9ZEnlSLegoQbbtXj5lfo= github.com/pseudomuto/protoc-gen-doc v1.5.0/go.mod h1:exDTOVwqpp30eV/EDPFLZy3Pwr2sn6hBC1WIYH/UbIg= @@ -573,12 +645,12 @@ github.com/pseudomuto/protokit v0.2.0 h1:hlnBDcy3YEDXH7kc9gV+NLaN0cDzhDvD1s7Y6FZ github.com/pseudomuto/protokit v0.2.0/go.mod h1:2PdH30hxVHsup8KpBTOXTBeMVhJZVio3Q8ViKSAXT0Q= github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= github.com/quasilyte/go-ruleguard v0.3.1-0.20210203134552-1b5a410e1cc8/go.mod h1:KsAh3x0e7Fkpgs+Q9pNLS5XpFSvYCEVl5gP9Pp1xp30= -github.com/quasilyte/go-ruleguard v0.3.4 h1:F6l5p6+7WBcTKS7foNQ4wqA39zjn2+RbdbyzGxIq1B0= -github.com/quasilyte/go-ruleguard v0.3.4/go.mod h1:57FZgMnoo6jqxkYKmVj5Fc8vOt0rVzoE/UNAmFFIPqA= +github.com/quasilyte/go-ruleguard v0.3.13 h1:O1G41cq1jUr3cJmqp7vOUT0SokqjzmS9aESWJuIDRaY= +github.com/quasilyte/go-ruleguard v0.3.13/go.mod h1:Ul8wwdqR6kBVOCt2dipDBkE+T6vAV/iixkrKuRTN1oQ= github.com/quasilyte/go-ruleguard/dsl v0.3.0/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= -github.com/quasilyte/go-ruleguard/dsl v0.3.2/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= +github.com/quasilyte/go-ruleguard/dsl v0.3.10/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= github.com/quasilyte/go-ruleguard/rules v0.0.0-20201231183845-9e62ed36efe1/go.mod h1:7JTjp89EGyU1d6XfBiXihJNG37wB2VRkd125Q1u7Plc= -github.com/quasilyte/go-ruleguard/rules v0.0.0-20210203162857-b223e0831f88/go.mod h1:4cgAphtvu7Ftv7vOT2ZOYhC6CvBxZixcasr8qIOTA50= +github.com/quasilyte/go-ruleguard/rules v0.0.0-20210428214800-545e0d2e0bf7/go.mod h1:4cgAphtvu7Ftv7vOT2ZOYhC6CvBxZixcasr8qIOTA50= github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 h1:L8QM9bvf68pVdQ3bCFZMDmnt9yqcMBro1pC7F+IPYMY= github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= @@ -588,20 +660,21 @@ github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryancurrah/gomodguard v1.2.2 h1:ZJQeYHZ2kaJpojoQBaGqpsn5g7GMcePY36uUGW1umbs= -github.com/ryancurrah/gomodguard v1.2.2/go.mod h1:tpI+C/nzvfUR3bF28b5QHpTn/jM/zlGniI++6ZlIWeE= +github.com/ryancurrah/gomodguard v1.2.3 h1:ww2fsjqocGCAFamzvv/b8IsRduuHHeK2MHTcTxZTQX8= +github.com/ryancurrah/gomodguard v1.2.3/go.mod h1:rYbA/4Tg5c54mV1sv4sQTP5WOPBcoLtnBZ7/TEhXAbg= github.com/ryanrolds/sqlclosecheck v0.3.0 h1:AZx+Bixh8zdUBxUA1NxbxVAS78vTPq4rCb8OUZI9xFw= github.com/ryanrolds/sqlclosecheck v0.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0KCtEdgEkHwDbigdA= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sagikazarmark/crypt v0.1.0/go.mod h1:B/mN0msZuINBtQ1zZLEQcegFJJf9vnYIR88KRMEuODE= github.com/sanposhiho/wastedassign/v2 v2.0.6 h1:+6/hQIHKNJAUixEj6EmOngGIisyeI+T3335lYTyxRoA= github.com/sanposhiho/wastedassign/v2 v2.0.6/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/securego/gosec/v2 v2.8.0 h1:iHg9cVmHWf5n6/ijUJ4F10h5bKlNtvXmcWzRw0lxiKE= -github.com/securego/gosec/v2 v2.8.0/go.mod h1:hJZ6NT5TqoY+jmOsaxAV4cXoEdrMRLVaNPnSpUCvCZs= +github.com/securego/gosec/v2 v2.9.1 h1:anHKLS/ApTYU6NZkKa/5cQqqcbKZURjvc+MtR++S4EQ= +github.com/securego/gosec/v2 v2.9.1/go.mod h1:oDcDLcatOJxkCGaCaq8lua1jTnYf6Sou4wdiJ1n4iHc= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= -github.com/shirou/gopsutil/v3 v3.21.5/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw= +github.com/shirou/gopsutil/v3 v3.21.10/go.mod h1:t75NhzCZ/dYyPQjyQmrAYP6c8+LCdFANeBMdLPCNnew= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= @@ -611,9 +684,9 @@ github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrf github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/sivchari/tenv v1.4.7 h1:FdTpgRlTue5eb5nXIYgS/lyVXSjugU8UUVDwhP1NLU8= +github.com/sivchari/tenv v1.4.7/go.mod h1:5nF+bITvkebQVanjU6IuMbvIot/7ReNsUV7I5NbprB0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sonatard/noctx v0.0.1 h1:VC1Qhl6Oxx9vvWo3UDgrGXYCeKCe3Wbw7qAWL6FrmTY= @@ -624,24 +697,27 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= -github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA= +github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M= -github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= -github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= +github.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw= +github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk= -github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/ssgreg/nlreturn/v2 v2.1.0 h1:6/s4Rc49L6Uo6RLjhWZGBpWWjfzk2yrf1nIW8m4wgVA= -github.com/ssgreg/nlreturn/v2 v2.1.0/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= +github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= +github.com/spf13/viper v1.9.0 h1:yR6EXjTp0y0cLN8OZg1CRZmOBdI88UcGkhgyJhu6nZk= +github.com/spf13/viper v1.9.0/go.mod h1:+i6ajR7OX2XaiBkrcZJFK21htRk7eDeLg7+O6bhUPP4= +github.com/ssgreg/nlreturn/v2 v2.2.1 h1:X4XDI7jstt3ySqGU86YGAURbxw3oTDPK9sPEi6YEwQ0= +github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= @@ -657,19 +733,25 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/sylvia7788/contextcheck v1.0.4 h1:MsiVqROAdr0efZc/fOCt0c235qm9XJqHtWwM+2h2B04= +github.com/sylvia7788/contextcheck v1.0.4/go.mod h1:vuPKJMQ7MQ91ZTqfdyreNKwZjyUg6KO+IebVyQDedZQ= github.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b h1:HxLVTlqcHhFAz3nWUcuvpH7WuOMv8LQoCWmruLfFH2U= github.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= -github.com/tetafro/godot v1.4.7 h1:zBaoSY4JRVVz33y/qnODsdaKj2yAaMr91HCbqHCifVc= -github.com/tetafro/godot v1.4.7/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaEohUpn8= +github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA= +github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0= +github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpRQGxTSkNYKJ51yaw6ChIqO+Je8UqsTKN/cDag= +github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY= +github.com/tetafro/godot v1.4.11 h1:BVoBIqAf/2QdbFmSwAWnaIqDivZdOV0ZRwEm6jivLKw= +github.com/tetafro/godot v1.4.11/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaEohUpn8= github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94 h1:ig99OeTyDwQWhPe2iw9lwfQVF1KB3Q4fpP3X7/2VBG8= github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= -github.com/tklauser/go-sysconf v0.3.4/go.mod h1:Cl2c8ZRWfHD5IrfHo9VN+FX9kCFjIOyVklgXycLB6ek= -github.com/tklauser/numcpus v0.2.1/go.mod h1:9aU+wOc6WjUIZEwWMP62PL/41d65P+iks1gBkr4QyP8= +github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs= +github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tomarrell/wrapcheck/v2 v2.1.0 h1:LTzwrYlgBUwi9JldazhbJN84fN9nS2UNGrZIo2syqxE= -github.com/tomarrell/wrapcheck/v2 v2.1.0/go.mod h1:crK5eI4RGSUrb9duDTQ5GqcukbKZvi85vX6nbhsBAeI= +github.com/tomarrell/wrapcheck/v2 v2.4.0 h1:mU4H9KsqqPZUALOUbVOpjy8qNQbWLoLI9fV68/1tq30= +github.com/tomarrell/wrapcheck/v2 v2.4.0/go.mod h1:68bQ/eJg55BROaRTbMjC7vuhL2OgfoG8bLp9ZyoBfyY= github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4= github.com/tommy-muehle/go-mnd/v2 v2.4.0 h1:1t0f8Uiaq+fqKteUR4N9Umr6E99R+lDnLnq7PwX2PPE= github.com/tommy-muehle/go-mnd/v2 v2.4.0/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= @@ -680,12 +762,12 @@ github.com/ultraware/whitespace v0.0.4 h1:If7Va4cM03mpgrNH9k49/VOicWpGoG70XPBFFO github.com/ultraware/whitespace v0.0.4/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/uudashr/gocognit v1.0.1 h1:MoG2fZ0b/Eo7NXoIwCVFLG5JED3qgQz5/NEE+rOsjPs= -github.com/uudashr/gocognit v1.0.1/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM= +github.com/uudashr/gocognit v1.0.5 h1:rrSex7oHr3/pPLQ0xoWq108XMU8s678FJcQ+aSfOHa4= +github.com/uudashr/gocognit v1.0.5/go.mod h1:wgYz0mitoKOTysqxTDMOUXg+Jb5SvtihkfmugIZYpEA= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.16.0/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl6TwOBhHCA= -github.com/valyala/quicktemplate v1.6.3/go.mod h1:fwPzK2fHuYEODzJ9pkw0ipCPNHZ2tD5KW4lOuSdPKzY= -github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/valyala/fasthttp v1.30.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus= +github.com/valyala/quicktemplate v1.7.0/go.mod h1:sqKJnoaOF88V07vkO+9FL8fb9uZg/VPSJnLYn+LmLk8= +github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= github.com/viki-org/dnscache v0.0.0-20130720023526-c70c1f23c5d8/go.mod h1:dniwbG03GafCjFohMDmz6Zc6oCuiqgH6tGNyXTkHzXE= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= @@ -700,26 +782,34 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/etcd v0.0.0-20200513171258-e048e166ab9c/go.mod h1:xCI7ZzBfRuGgBXyXO6yfWfDmlWd35khcWpUa4L0xI/k= +go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= +go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= go.mozilla.org/mozlog v0.0.0-20170222151521-4bb13139d403/go.mod h1:jHoPAGnDrCy6kaI2tAze5Prf0Nr0w/oNkROt2lw3n3o= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= golang.org/x/crypto v0.0.0-20180501155221-613d6eafa307/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -728,10 +818,14 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -755,6 +849,7 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= @@ -803,15 +898,21 @@ golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d h1:LO7XpTYMwTqxjLcGWPijK3vRXg1aWdlNOVOHRq45d7c= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -819,7 +920,18 @@ golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210615190721-d04028783cf1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -830,6 +942,7 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -851,6 +964,8 @@ golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -863,6 +978,7 @@ golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -874,19 +990,38 @@ golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912 h1:uCLL3g5wH2xjxVREVuAbP9JM5PPKjRbXKRa6IBjkzmU= -golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210915083310-ed5796bab164/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211013075003-97ac67df715c h1:taxlMj0D/1sOAuv/CbSD+MMDof2vbyPTqz5FNYKpXt8= +golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -894,6 +1029,7 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= @@ -926,6 +1062,7 @@ golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190916130336-e45ffcd953cc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -978,23 +1115,33 @@ golang.org/x/tools v0.0.0-20200812195022-5ae4c3c160a0/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200831203904-5a2aa26beb65/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201002184944-ecd9fd270d5d/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= -golang.org/x/tools v0.0.0-20201011145850-ed2f50202694/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201028025901-8cd080b735b3/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201114224030-61ea331ec02b/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201118003311-bd56c0adb394/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201230224404-63754364767c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210101214203-2dba1e4ea05c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210104081019-d8d6ddbec6ee/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1-0.20210205202024-ef80cdb6ec6d/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= +golang.org/x/tools v0.1.1-0.20210302220138-2ac05c832e1a/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.6/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= +golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ= +golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1017,6 +1164,18 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1024,6 +1183,7 @@ google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20181107211654-5fc9ac540362/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= @@ -1060,7 +1220,29 @@ google.golang.org/genproto v0.0.0-20200707001353-8e8330bf89df/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210617175327-b9e0b3197ced/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20211101144312-62acf1d99145 h1:vum3nDKdleYb+aePXKFEDT2+ghuH00EgYp9B7Q7EZZE= google.golang.org/genproto v0.0.0-20211101144312-62acf1d99145/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= @@ -1079,9 +1261,18 @@ google.golang.org/grpc v1.29.0/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE= @@ -1111,8 +1302,9 @@ gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qS gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= -gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= -gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.63.2 h1:tGK/CyBg7SMzb60vP1M03vNZ3VDu3wGQJwn7Sxi9r3c= +gopkg.in/ini.v1 v1.63.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= @@ -1138,8 +1330,8 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.2.0 h1:ws8AfbgTX3oIczLPNPCu5166oBg9ST2vNs0rcht+mDE= -honnef.co/go/tools v0.2.0/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY= +honnef.co/go/tools v0.2.1 h1:/EPr//+UMMXwMTkXvCCoaJDq8cpjMO80Ou+L4PDo2mY= +honnef.co/go/tools v0.2.1/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY= mvdan.cc/gofumpt v0.1.1 h1:bi/1aS/5W00E2ny5q65w9SnKpWEF/UIOqDYBILpo9rA= mvdan.cc/gofumpt v0.1.1/go.mod h1:yXG1r1WqZVKWbVRtBWKWX9+CxGYfA51nSomhM0woR48= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= diff --git a/infrastructure/containerd/content.go b/infrastructure/containerd/content.go index 503705d2..1c2fd259 100644 --- a/infrastructure/containerd/content.go +++ b/infrastructure/containerd/content.go @@ -7,17 +7,14 @@ import ( "github.com/weaveworks/flintlock/pkg/defaults" ) -var ( - // NameLabel is the name of the containerd content store label used for the microvm name. - NameLabel = fmt.Sprintf("%s/name", defaults.Domain) - // NamespaceLabel is the name of the containerd content store label used for the microvm namespace. - NamespaceLabel = fmt.Sprintf("%s/ns", defaults.Domain) - // TypeLabel is the name of the containerd content store label used to denote the type of content. - TypeLabel = fmt.Sprintf("%s/type", defaults.Domain) - // VersionLabel is the name of the containerd content store label to hold version of the content. - VersionLabel = fmt.Sprintf("%s/version", defaults.Domain) +const ( // MicroVMSpecType is the type name for a microvm spec. MicroVMSpecType = "microvm" + + nameLabelFormat = "%s/name" + namespaceLabelFormat = "%s/ns" + typeLabelFormat = "%s/type" + versionLabelFormat = "%s/version" ) func contentRefName(microvm *models.MicroVM) string { @@ -27,3 +24,23 @@ func contentRefName(microvm *models.MicroVM) string { func labelFilter(name, value string) string { return fmt.Sprintf("labels.\"%s\"==\"%s\"", name, value) } + +// NameLabel is the name of the containerd content store label used for the microvm name. +func NameLabel() string { + return fmt.Sprintf(nameLabelFormat, defaults.Domain) +} + +// NamespaceLabel is the name of the containerd content store label used for the microvm namespace. +func NamespaceLabel() string { + return fmt.Sprintf(namespaceLabelFormat, defaults.Domain) +} + +// TypeLabel is the name of the containerd content store label used to denote the type of content. +func TypeLabel() string { + return fmt.Sprintf(typeLabelFormat, defaults.Domain) +} + +// VersionLabel is the name of the containerd content store label to hold version of the content. +func VersionLabel() string { + return fmt.Sprintf(versionLabelFormat, defaults.Domain) +} diff --git a/infrastructure/containerd/convert.go b/infrastructure/containerd/convert.go index 98eebf40..9342f343 100644 --- a/infrastructure/containerd/convert.go +++ b/infrastructure/containerd/convert.go @@ -11,22 +11,22 @@ import ( "github.com/weaveworks/flintlock/core/ports" ) -func convertMountToModel(m mount.Mount, snapshotter string) (models.Mount, error) { +func convertMountToModel(mountPoint mount.Mount, snapshotter string) (models.Mount, error) { switch snapshotter { case "overlayfs": return models.Mount{ Type: models.MountTypeHostPath, - Source: getOverlayMountPath(m), + Source: getOverlayMountPath(mountPoint), }, nil case "native": return models.Mount{ Type: models.MountTypeHostPath, - Source: m.Source, + Source: mountPoint.Source, }, nil case "devmapper": return models.Mount{ Type: models.MountTypeDev, - Source: m.Source, + Source: mountPoint.Source, }, nil default: return models.Mount{}, unsupportedSnapshotterError{name: snapshotter} @@ -39,11 +39,13 @@ func getOverlayMountPath(m mount.Mount) string { func convertMountsToModel(mounts []mount.Mount, snapshotter string) ([]models.Mount, error) { convertedMounts := []models.Mount{} + for _, m := range mounts { counvertedMount, err := convertMountToModel(m, snapshotter) if err != nil { return nil, fmt.Errorf("converting mount: %w", err) } + convertedMounts = append(convertedMounts, counvertedMount) } @@ -65,6 +67,7 @@ func convertCtrEventEnvelope(evt *events.Envelope) (*ports.EventEnvelope, error) if err != nil { return nil, fmt.Errorf("unmarshalling event: %w", err) } + converted.Event = v return converted, nil diff --git a/infrastructure/containerd/event_service.go b/infrastructure/containerd/event_service.go index 2f2d0c59..8b29d0ea 100644 --- a/infrastructure/containerd/event_service.go +++ b/infrastructure/containerd/event_service.go @@ -37,6 +37,7 @@ type eventService struct { func (es *eventService) Publish(ctx context.Context, topic string, eventToPublish interface{}) error { namespaceCtx := namespaces.WithNamespace(ctx, es.cfg.Namespace) ctrEventSrv := es.client.EventService() + if err := ctrEventSrv.Publish(namespaceCtx, topic, eventToPublish); err != nil { return fmt.Errorf("publishing event: %w", err) } @@ -45,14 +46,18 @@ func (es *eventService) Publish(ctx context.Context, topic string, eventToPublis } // SubscribeTopic will subscribe to events on a named topic. -func (es *eventService) SubscribeTopic(ctx context.Context, topic string) (ch <-chan *ports.EventEnvelope, errs <-chan error) { +func (es *eventService) SubscribeTopic(ctx context.Context, + topic string, +) (ch <-chan *ports.EventEnvelope, errs <-chan error) { topicFilter := topicFilter(topic) return es.subscribe(ctx, topicFilter) } // SubscribeTopics will subscribe to events on a set of named topics. -func (es *eventService) SubscribeTopics(ctx context.Context, topics []string) (ch <-chan *ports.EventEnvelope, errs <-chan error) { +func (es *eventService) SubscribeTopics(ctx context.Context, + topics []string, +) (ch <-chan *ports.EventEnvelope, errs <-chan error) { topicFilters := []string{} for _, topic := range topics { @@ -67,18 +72,20 @@ func (es *eventService) Subscribe(ctx context.Context) (ch <-chan *ports.EventEn return es.subscribe(ctx) } -func (es *eventService) subscribe(ctx context.Context, filters ...string) (ch <-chan *ports.EventEnvelope, errs <-chan error) { +func (es *eventService) subscribe(ctx context.Context, + filters ...string, +) (ch <-chan *ports.EventEnvelope, errs <-chan error) { var ( - evtCh = make(chan *ports.EventEnvelope) - evtErrCh = make(chan error, 1) + evtCh = make(chan *ports.EventEnvelope) + evtErrCh = make(chan error, 1) + ctrEvents <-chan *events.Envelope + ctrErrs <-chan error ) + errs = evtErrCh ch = evtCh - namespaceCtx := namespaces.WithNamespace(ctx, es.cfg.Namespace) - var ctrEvents <-chan *events.Envelope - var ctrErrs <-chan error if len(filters) == 0 { ctrEvents, ctrErrs = es.client.Subscribe(namespaceCtx) } else { diff --git a/infrastructure/containerd/image_service.go b/infrastructure/containerd/image_service.go index 27734112..ab81b5f5 100644 --- a/infrastructure/containerd/image_service.go +++ b/infrastructure/containerd/image_service.go @@ -4,12 +4,11 @@ import ( "context" "fmt" - "github.com/containerd/containerd/snapshots" - "github.com/containerd/containerd" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/mount" "github.com/containerd/containerd/namespaces" + "github.com/containerd/containerd/snapshots" "github.com/sirupsen/logrus" "github.com/weaveworks/flintlock/core/models" @@ -62,12 +61,14 @@ func (im *imageService) PullAndMount(ctx context.Context, input *ports.ImageMoun logger.Debugf("getting and mounting image %s for owner %s", input.ImageName, input.Owner) nsCtx := namespaces.WithNamespace(ctx, im.config.Namespace) + leaseCtx, err := withOwnerLease(nsCtx, input.Owner, im.client) if err != nil { return nil, fmt.Errorf("getting lease for image pulling and mounting: %w", err) } var image containerd.Image + exists, image, err := im.imageExists(leaseCtx, input.ImageName, input.Owner) if err != nil { return nil, fmt.Errorf("checking if image %s exists for owner %s: %w", input.ImageName, input.Owner, err) @@ -79,6 +80,7 @@ func (im *imageService) PullAndMount(ctx context.Context, input *ports.ImageMoun return nil, fmt.Errorf("getting image %s for owner %s: %w", input.ImageName, input.Owner, err) } } + ss := im.getSnapshotter(input.Use) return im.snapshotAndMount(leaseCtx, image, input.Owner, input.OwnerUsageID, ss, logger) @@ -110,6 +112,7 @@ func (im *imageService) IsMounted(ctx context.Context, input *ports.ImageMountSp if err != nil { return false, fmt.Errorf("checking image exists: %w", err) } + if !exists { return false, nil } @@ -126,7 +129,7 @@ func (im *imageService) IsMounted(ctx context.Context, input *ports.ImageMountSp return snapshotExists, nil } -func (im *imageService) imageExists(ctx context.Context, imageName string, owner string) (bool, containerd.Image, error) { +func (im *imageService) imageExists(ctx context.Context, imageName, owner string) (bool, containerd.Image, error) { leaseCtx, err := withOwnerLease(ctx, owner, im.client) if err != nil { return false, nil, fmt.Errorf("getting lease for owner: %w", err) @@ -158,13 +161,23 @@ func (im *imageService) pullImage(ctx context.Context, imageName string, owner s return image, nil } -func (im *imageService) snapshotAndMount(ctx context.Context, image containerd.Image, owner, ownerUsageID, snapshotter string, logger *logrus.Entry) ([]models.Mount, error) { +func (im *imageService) snapshotAndMount(ctx context.Context, + image containerd.Image, + owner, ownerUsageID, snapshotter string, + logger *logrus.Entry, +) ([]models.Mount, error) { unpacked, err := image.IsUnpacked(ctx, snapshotter) if err != nil { - return nil, fmt.Errorf("checking if image %s has been unpacked with snapshotter %s: %w", image.Name(), snapshotter, err) + return nil, fmt.Errorf("checking if image %s has been unpacked with snapshotter %s: %w", + image.Name(), + snapshotter, + err, + ) } + if !unpacked { logger.Debugf("image %s isn't unpacked, unpacking using %s snapshotter", image.Name(), snapshotter) + if unpackErr := image.Unpack(ctx, snapshotter); unpackErr != nil { return nil, fmt.Errorf("unpacking %s with snapshotter %s: %w", image.Name(), snapshotter, err) } @@ -174,29 +187,32 @@ func (im *imageService) snapshotAndMount(ctx context.Context, image containerd.I if err != nil { return nil, fmt.Errorf("getting rootfs content for %s: %w", image.Name(), err) } + parent := imageContent[0].String() snapshotKey := snapshotKey(owner, ownerUsageID) logger.Debugf("creating snapshot %s for image %s with snapshotter %s", snapshotKey, image.Name(), snapshotter) - ss := im.client.SnapshotService(snapshotter) + snapService := im.client.SnapshotService(snapshotter) - snapshotExists, err := snapshotExists(ctx, snapshotKey, ss) + snapshotExists, err := snapshotExists(ctx, snapshotKey, snapService) if err != nil { return nil, fmt.Errorf("checking for existence of snapshot %s: %w", snapshotKey, err) } var mounts []mount.Mount + if !snapshotExists { labels := map[string]string{ "flintlock/owner": owner, "flintlock/owner-usage": ownerUsageID, } - mounts, err = ss.Prepare(ctx, snapshotKey, parent, snapshots.WithLabels(labels)) + + mounts, err = snapService.Prepare(ctx, snapshotKey, parent, snapshots.WithLabels(labels)) if err != nil { return nil, fmt.Errorf("preparing snapshot of %s: %w", image.Name(), err) } } else { - mounts, err = ss.Mounts(ctx, snapshotKey) + mounts, err = snapService.Mounts(ctx, snapshotKey) if err != nil { return nil, fmt.Errorf("getting mounts of %s: %w", image.Name(), err) } diff --git a/infrastructure/containerd/lease.go b/infrastructure/containerd/lease.go index 18fb6915..4f872918 100644 --- a/infrastructure/containerd/lease.go +++ b/infrastructure/containerd/lease.go @@ -5,7 +5,6 @@ import ( "fmt" "github.com/containerd/containerd" - "github.com/containerd/containerd/leases" ) @@ -22,6 +21,7 @@ func withOwnerLease(ctx context.Context, owner string, client *containerd.Client func getExistingOrCreateLease(ctx context.Context, name string, manager leases.Manager) (*leases.Lease, error) { filter := fmt.Sprintf("id==%s", name) + existingLeases, err := manager.List(ctx, filter) if err != nil { return nil, fmt.Errorf("listing existing containerd leases: %w", err) @@ -44,6 +44,7 @@ func getExistingOrCreateLease(ctx context.Context, name string, manager leases.M func deleteLease(ctx context.Context, owner string, client *containerd.Client) error { leaseName := getLeaseNameForOwner(owner) lease := leases.Lease{ID: leaseName} + err := client.LeasesService().Delete(ctx, lease, leases.SynchronousDelete) if err != nil { return fmt.Errorf("delete lease %s: %w", leaseName, err) diff --git a/infrastructure/containerd/repo.go b/infrastructure/containerd/repo.go index 36dd035c..a0535bfd 100644 --- a/infrastructure/containerd/repo.go +++ b/infrastructure/containerd/repo.go @@ -64,9 +64,11 @@ func (r *containerdRepo) Save(ctx context.Context, microvm *models.MicroVM) (*mo if err != nil { return nil, fmt.Errorf("getting vm spec from store: %w", err) } + if existingSpec != nil { specDiff := cmp.Diff(existingSpec.Spec, microvm.Spec) statusDiff := cmp.Diff(existingSpec.Status, microvm.Status) + if specDiff == "" && statusDiff == "" { logger.Debug("microvm specs have no diff, skipping save") @@ -75,15 +77,18 @@ func (r *containerdRepo) Save(ctx context.Context, microvm *models.MicroVM) (*mo } namespaceCtx := namespaces.WithNamespace(ctx, r.config.Namespace) + leaseCtx, err := withOwnerLease(namespaceCtx, microvm.ID.String(), r.client) if err != nil { return nil, fmt.Errorf("getting lease for owner: %w", err) } + store := r.client.ContentStore() microvm.Version++ refName := contentRefName(microvm) + writer, err := store.Writer(leaseCtx, content.WithRef(refName)) if err != nil { return nil, fmt.Errorf("getting containerd writer: %w", err) @@ -100,6 +105,7 @@ func (r *containerdRepo) Save(ctx context.Context, microvm *models.MicroVM) (*mo } labels := getVMLabels(microvm) + err = writer.Commit(namespaceCtx, 0, "", content.WithLabels(labels)) if err != nil { return nil, fmt.Errorf("committing content to store: %w", err) @@ -119,6 +125,7 @@ func (r *containerdRepo) Get(ctx context.Context, options ports.RepositoryGetOpt if err != nil { return nil, fmt.Errorf("getting vm spec from store: %w", err) } + if spec == nil { return nil, errors.NewSpecNotFound(options.Name, options.Namespace, options.Version) } @@ -131,17 +138,17 @@ func (r *containerdRepo) Get(ctx context.Context, options ports.RepositoryGetOpt func (r *containerdRepo) GetAll(ctx context.Context, namespace string) ([]*models.MicroVM, error) { namespaceCtx := namespaces.WithNamespace(ctx, r.config.Namespace) store := r.client.ContentStore() + filters := []string{labelFilter(TypeLabel(), MicroVMSpecType)} + versions := map[string]int{} + digests := map[string]*digest.Digest{} - filters := []string{labelFilter(TypeLabel, MicroVMSpecType)} if namespace != "" { - filters = append(filters, labelFilter(NamespaceLabel, namespace)) + filters = append(filters, labelFilter(NamespaceLabel(), namespace)) } - versions := map[string]int{} - digests := map[string]*digest.Digest{} - err := store.Walk(namespaceCtx, func(i content.Info) error { - name := i.Labels[NameLabel] - version, err := strconv.Atoi(i.Labels[VersionLabel]) + err := store.Walk(namespaceCtx, func(info content.Info) error { + name := info.Labels[NameLabel()] + version, err := strconv.Atoi(info.Labels[VersionLabel()]) if err != nil { return fmt.Errorf("parsing version number: %w", err) } @@ -153,7 +160,7 @@ func (r *containerdRepo) GetAll(ctx context.Context, namespace string) ([]*model if version > high { versions[name] = version - digests[name] = &i.Digest + digests[name] = &info.Digest } return nil @@ -163,6 +170,7 @@ func (r *containerdRepo) GetAll(ctx context.Context, namespace string) ([]*model } items := []*models.MicroVM{} + for _, d := range digests { vm, getErr := r.getWithDigest(namespaceCtx, d) if getErr != nil { @@ -200,6 +208,7 @@ func (r *containerdRepo) Delete(ctx context.Context, microvm *models.MicroVM) er if err != nil { return fmt.Errorf("finding digests for %s: %w", microvm.ID, err) } + if len(digests) == 0 { // Ignore not found return nil @@ -244,6 +253,7 @@ func (r *containerdRepo) get(ctx context.Context, options ports.RepositoryGetOpt if err != nil { return nil, fmt.Errorf("finding content in store: %w", err) } + if digest == nil { return nil, nil } @@ -260,6 +270,7 @@ func (r *containerdRepo) getWithDigest(ctx context.Context, metadigest *digest.D } microvm := &models.MicroVM{} + err = json.Unmarshal(readData, microvm) if err != nil { return nil, fmt.Errorf("unmarshalling json content to microvm: %w", err) @@ -268,10 +279,14 @@ func (r *containerdRepo) getWithDigest(ctx context.Context, metadigest *digest.D return microvm, nil } -func (r *containerdRepo) findDigestForSpec(ctx context.Context, options ports.RepositoryGetOptions) (*digest.Digest, error) { - idLabelFilter := labelFilter(NameLabel, options.Name) - nsFilter := labelFilter(NamespaceLabel, options.Namespace) - versionFilter := labelFilter(VersionLabel, options.Version) +func (r *containerdRepo) findDigestForSpec(ctx context.Context, + options ports.RepositoryGetOptions, +) (*digest.Digest, error) { + var digest *digest.Digest + + idLabelFilter := labelFilter(NameLabel(), options.Name) + nsFilter := labelFilter(NamespaceLabel(), options.Namespace) + versionFilter := labelFilter(VersionLabel(), options.Version) combinedFilters := []string{idLabelFilter, nsFilter} @@ -281,20 +296,18 @@ func (r *containerdRepo) findDigestForSpec(ctx context.Context, options ports.Re allFilters := strings.Join(combinedFilters, ",") store := r.client.ContentStore() - - var digest *digest.Digest highestVersion := 0 err := store.Walk( ctx, - func(i content.Info) error { - version, err := strconv.Atoi(i.Labels[VersionLabel]) + func(info content.Info) error { + version, err := strconv.Atoi(info.Labels[VersionLabel()]) if err != nil { return fmt.Errorf("parsing version number: %w", err) } if version > highestVersion { - digest = &i.Digest + digest = &info.Digest highestVersion = version } @@ -311,12 +324,12 @@ func (r *containerdRepo) findDigestForSpec(ctx context.Context, options ports.Re func (r *containerdRepo) findAllDigestForSpec(ctx context.Context, name, namespace string) ([]*digest.Digest, error) { store := r.client.ContentStore() - idLabelFilter := labelFilter(NameLabel, name) - nsLabelFilter := labelFilter(NamespaceLabel, namespace) + idLabelFilter := labelFilter(NameLabel(), name) + nsLabelFilter := labelFilter(NamespaceLabel(), namespace) combinedFilters := []string{idLabelFilter, nsLabelFilter} allFilters := strings.Join(combinedFilters, ",") - digests := []*digest.Digest{} + err := store.Walk( ctx, func(i content.Info) error { @@ -350,10 +363,10 @@ func (r *containerdRepo) getMutex(name string) *sync.RWMutex { func getVMLabels(microvm *models.MicroVM) map[string]string { labels := map[string]string{ - NameLabel: microvm.ID.Name(), - NamespaceLabel: microvm.ID.Namespace(), - TypeLabel: MicroVMSpecType, - VersionLabel: strconv.Itoa(microvm.Version), + NameLabel(): microvm.ID.Name(), + NamespaceLabel(): microvm.ID.Namespace(), + TypeLabel(): MicroVMSpecType, + VersionLabel(): strconv.Itoa(microvm.Version), } return labels diff --git a/infrastructure/containerd/snapshot.go b/infrastructure/containerd/snapshot.go index 80d11550..6db0de7a 100644 --- a/infrastructure/containerd/snapshot.go +++ b/infrastructure/containerd/snapshot.go @@ -13,6 +13,7 @@ func snapshotKey(owner, ownerUsageID string) string { func snapshotExists(ctx context.Context, key string, ss snapshots.Snapshotter) (bool, error) { snapshotExists := false + err := ss.Walk(ctx, func(walkCtx context.Context, info snapshots.Info) error { if info.Name == key { snapshotExists = true diff --git a/infrastructure/controllers/microvm_controller.go b/infrastructure/controllers/microvm_controller.go index f8fd874b..2aca33fc 100644 --- a/infrastructure/controllers/microvm_controller.go +++ b/infrastructure/controllers/microvm_controller.go @@ -32,7 +32,11 @@ type MicroVMController struct { queue queue.Queue } -func (r *MicroVMController) Run(ctx context.Context, numWorkers int, resyncPeriod time.Duration, resyncOnStart bool) error { +func (r *MicroVMController) Run(ctx context.Context, + numWorkers int, + resyncPeriod time.Duration, + resyncOnStart bool, +) error { logger := log.GetLogger(ctx).WithField("controller", "microvm") ctx = log.WithLogger(ctx, logger) logger.Infof("starting microvm controller with %d workers", numWorkers) @@ -44,14 +48,15 @@ func (r *MicroVMController) Run(ctx context.Context, numWorkers int, resyncPerio if resyncOnStart { if err := r.resyncSpecs(ctx, logger); err != nil { - // TODO: should we just log here? return fmt.Errorf("resyncing specs on start: %w", err) } } wg := &sync.WaitGroup{} + logger.Info("starting event listener") wg.Add(1) + go func() { defer wg.Done() r.runEventListener(ctx, resyncPeriod) @@ -59,9 +64,11 @@ func (r *MicroVMController) Run(ctx context.Context, numWorkers int, resyncPerio logger.Info("Starting workers", "num_workers", numWorkers) wg.Add(numWorkers) + for i := 0; i < numWorkers; i++ { go func() { defer wg.Done() + for r.processQueueItem(ctx) { } }() @@ -90,23 +97,24 @@ func (r *MicroVMController) runEventListener(ctx context.Context, resyncPeriod t return case evt := <-evtCh: if err := r.handleEvent(evt, logger); err != nil { + // TODO: should we exit here? #233 logger.Errorf("handling events: %s", err) - // TODO: should we exit here } case <-ticker.C: if err := r.resyncSpecs(ctx, logger); err != nil { + // TODO: should we exit here? #233 logger.Errorf("resyncing specs: %s", err) - // TODO: should we exit here } case evtErr := <-errCh: + // TODO: should we exit here? #233 logger.Errorf("error from event service: %s", evtErr) - // TODO: should we exit here? } } } func (r *MicroVMController) processQueueItem(ctx context.Context) bool { logger := log.GetLogger(ctx) + item, shutdown := r.queue.Dequeue() if shutdown { return false @@ -118,6 +126,7 @@ func (r *MicroVMController) processQueueItem(ctx context.Context) bool { return true } + vmid, err := models.NewVMIDFromString(id) if err != nil { logger.Errorf("failed to parse id into vmid %s, skipping: %s", id, err) @@ -138,7 +147,8 @@ func (r *MicroVMController) processQueueItem(ctx context.Context) bool { func (r *MicroVMController) handleEvent(envelope *ports.EventEnvelope, logger *logrus.Entry) error { var name, namespace string - switch v := envelope.Event.(type) { + + switch eventType := envelope.Event.(type) { case *events.MicroVMSpecCreated: created, _ := envelope.Event.(*events.MicroVMSpecCreated) name = created.ID @@ -153,7 +163,7 @@ func (r *MicroVMController) handleEvent(envelope *ports.EventEnvelope, logger *l name = updated.ID namespace = updated.Namespace default: - logger.Debugf("unhandled event type (%T) received", v) + logger.Debugf("unhandled event type (%T) received", eventType) return nil } diff --git a/infrastructure/firecracker/config.go b/infrastructure/firecracker/config.go index 524bac54..3c70224e 100644 --- a/infrastructure/firecracker/config.go +++ b/infrastructure/firecracker/config.go @@ -5,8 +5,6 @@ import ( "encoding/base64" "fmt" - "github.com/weaveworks/flintlock/pkg/ptr" - "github.com/firecracker-microvm/firecracker-go-sdk" fcmodels "github.com/firecracker-microvm/firecracker-go-sdk/client/models" "gopkg.in/yaml.v3" @@ -14,6 +12,7 @@ import ( "github.com/weaveworks/flintlock/core/errors" "github.com/weaveworks/flintlock/core/models" "github.com/weaveworks/flintlock/pkg/cloudinit" + "github.com/weaveworks/flintlock/pkg/ptr" ) const ( @@ -31,8 +30,6 @@ func CreateConfig(opts ...ConfigOption) (*VmmConfig, error) { } } - // TODO: do we need to add validation? - return cfg, nil } @@ -49,6 +46,7 @@ func WithMicroVM(vm *models.MicroVM) ConfigOption { } cfg.NetDevices = []NetworkInterfaceConfig{} + for i := range vm.Spec.NetworkInterfaces { iface := vm.Spec.NetworkInterfaces[i] @@ -62,6 +60,7 @@ func WithMicroVM(vm *models.MicroVM) ConfigOption { } cfg.BlockDevices = []BlockDeviceConfig{} + for _, vol := range vm.Spec.Volumes { status, ok := vm.Status.Volumes[vol.ID] if !ok { @@ -80,11 +79,13 @@ func WithMicroVM(vm *models.MicroVM) ConfigOption { } kernelArgs := vm.Spec.Kernel.CmdLine + if vm.Spec.Kernel.AddNetworkConfig { networkConfig, err := generateNetworkConfig(vm) if err != nil { return fmt.Errorf("generating kernel network-config: %w", err) } + kernelArgs = fmt.Sprintf("%s network-config=%s", kernelArgs, networkConfig) } @@ -132,29 +133,31 @@ func ApplyConfig(ctx context.Context, cfg *VmmConfig, client *firecracker.Client if err != nil { return fmt.Errorf("failed to put machine configuration: %w", err) } + for _, drive := range cfg.BlockDevices { - _, err := client.PutGuestDriveByID(ctx, drive.ID, &fcmodels.Drive{ + _, requestErr := client.PutGuestDriveByID(ctx, drive.ID, &fcmodels.Drive{ DriveID: &drive.ID, IsReadOnly: &drive.IsReadOnly, IsRootDevice: &drive.IsRootDevice, Partuuid: drive.PartUUID, PathOnHost: &drive.PathOnHost, - // RateLimiter: , }) - if err != nil { - return fmt.Errorf("putting drive configuration: %w", err) + if requestErr != nil { + return fmt.Errorf("putting drive configuration: %w", requestErr) } } + for i, netInt := range cfg.NetDevices { guestIfaceName := fmt.Sprintf("eth%d", i) - _, err := client.PutGuestNetworkInterfaceByID(ctx, guestIfaceName, &fcmodels.NetworkInterface{ + + _, requestErr := client.PutGuestNetworkInterfaceByID(ctx, guestIfaceName, &fcmodels.NetworkInterface{ IfaceID: &guestIfaceName, GuestMac: netInt.GuestMAC, HostDevName: &netInt.HostDevName, AllowMmdsRequests: netInt.AllowMMDSRequests, }) - if err != nil { - return fmt.Errorf("putting %s network configuration: %w", guestIfaceName, err) + if requestErr != nil { + return fmt.Errorf("putting %s network configuration: %w", guestIfaceName, requestErr) } } @@ -188,6 +191,7 @@ func ApplyConfig(ctx context.Context, cfg *VmmConfig, client *firecracker.Client return fmt.Errorf("failed to put logging configuration: %w", err) } } + if cfg.Metrics != nil { _, err = client.PutMetrics(ctx, &fcmodels.Metrics{ MetricsPath: &cfg.Metrics.Path, @@ -210,6 +214,7 @@ func ApplyMetadata(ctx context.Context, metadata map[string]string, client *fire meta := &Metadata{ Latest: map[string]string{}, } + for metadataKey, metadataVal := range metadata { encodedVal, err := base64.StdEncoding.DecodeString(metadataVal) if err != nil { @@ -232,6 +237,7 @@ func createNetworkIface(iface *models.NetworkInterface, status *models.NetworkIn if iface.Type == models.IfaceTypeMacvtap { hostDevName = fmt.Sprintf("/dev/tap%d", status.Index) + if macAddr == "" { macAddr = status.MACAddress } @@ -255,10 +261,12 @@ func generateNetworkConfig(vm *models.MicroVM) (string, error) { for i := range vm.Spec.NetworkInterfaces { iface := vm.Spec.NetworkInterfaces[i] + status, ok := vm.Status.NetworkInterfaces[iface.GuestDeviceName] if !ok { return "", errors.NewNetworkInterfaceStatusMissing(iface.GuestDeviceName) } + macAdress := getMacAddress(&iface, status) eth := &cloudinit.Ethernet{ diff --git a/infrastructure/firecracker/create.go b/infrastructure/firecracker/create.go index 5084462d..c6f4f9ff 100644 --- a/infrastructure/firecracker/create.go +++ b/infrastructure/firecracker/create.go @@ -34,6 +34,7 @@ func (p *fcProvider) Create(ctx context.Context, vm *models.MicroVM) error { logger.Debugf("creating microvm") vmState := NewState(vm.ID, p.config.StateRoot, p.fs) + if err := p.ensureState(vmState); err != nil { return fmt.Errorf("ensuring state dir: %w", err) } @@ -42,12 +43,14 @@ func (p *fcProvider) Create(ctx context.Context, vm *models.MicroVM) error { if err != nil { return fmt.Errorf("creating firecracker config: %w", err) } - if err := vmState.SetConfig(config); err != nil { + + if err = vmState.SetConfig(config); err != nil { return fmt.Errorf("saving firecracker config: %w", err) } id := strings.ReplaceAll(vm.ID.String(), "/", "-") args := []string{"--id", id, "--boot-timer"} + if !p.config.APIConfig { args = append(args, "--config-file", vmState.ConfigPath()) } @@ -56,18 +59,22 @@ func (p *fcProvider) Create(ctx context.Context, vm *models.MicroVM) error { WithBin(p.config.FirecrackerBin). WithSocketPath(vmState.SockPath()). WithArgs(args). - Build(context.TODO()) + Build(context.TODO()) //nolint: contextcheck // Intentional. proc, err := p.startFirecracker(cmd, vmState, p.config.RunDetached) if err != nil { return fmt.Errorf("starting firecracker process: %w", err) } - if err := vmState.SetPid(proc.Pid); err != nil { + if err = vmState.SetPid(proc.Pid); err != nil { return fmt.Errorf("saving pid %d to file: %w", proc.Pid, err) } - err = wait.ForCondition(wait.FileExistsCondition(vmState.SockPath(), p.fs), socketTimeoutInSec*time.Second, socketPollInMs*time.Millisecond) + err = wait.ForCondition( + wait.FileExistsCondition(vmState.SockPath(), p.fs), + socketTimeoutInSec*time.Second, + socketPollInMs*time.Millisecond, + ) if err != nil { return fmt.Errorf("waiting for sock file to exist: %w", err) } @@ -77,6 +84,7 @@ func (p *fcProvider) Create(ctx context.Context, vm *models.MicroVM) error { if err := ApplyConfig(ctx, config, client); err != nil { return fmt.Errorf("applying firecracker configuration: %w", err) } + if err := ApplyMetadata(ctx, vm.Spec.Metadata, client); err != nil { return fmt.Errorf("applying metadata to mmds: %w", err) } @@ -95,6 +103,7 @@ func (p *fcProvider) startFirecracker(cmd *exec.Cmd, vmState State, detached boo if err != nil { return nil, fmt.Errorf("opening sterr file %s: %w", vmState.StderrPath(), err) } + cmd.Stderr = stdErrFile cmd.Stdout = stdOutFile cmd.Stdin = &bytes.Buffer{} @@ -121,7 +130,7 @@ func (p *fcProvider) ensureState(vmState State) error { } if !exists { - if err := p.fs.MkdirAll(vmState.Root(), defaults.DataDirPerm); err != nil { + if err = p.fs.MkdirAll(vmState.Root(), defaults.DataDirPerm); err != nil { return fmt.Errorf("creating state directory %s: %w", vmState.Root(), err) } } @@ -130,6 +139,7 @@ func (p *fcProvider) ensureState(vmState State) error { if err != nil { return fmt.Errorf("checking if sock dir exists: %w", err) } + if sockExists { if delErr := p.fs.Remove(vmState.SockPath()); delErr != nil { return fmt.Errorf("deleting existing sock file: %w", err) @@ -140,12 +150,14 @@ func (p *fcProvider) ensureState(vmState State) error { if err != nil { return fmt.Errorf("opening log file %s: %w", vmState.LogPath(), err) } + logFile.Close() metricsFile, err := p.fs.OpenFile(vmState.MetricsPath(), os.O_WRONLY|os.O_CREATE|os.O_APPEND, defaults.DataFilePerm) if err != nil { return fmt.Errorf("opening metrics file %s: %w", vmState.MetricsPath(), err) } + metricsFile.Close() return nil diff --git a/infrastructure/firecracker/provider.go b/infrastructure/firecracker/provider.go index 884b6863..9fd58d44 100644 --- a/infrastructure/firecracker/provider.go +++ b/infrastructure/firecracker/provider.go @@ -7,14 +7,13 @@ import ( "net/url" "os" - "github.com/go-openapi/strfmt" - "github.com/sirupsen/logrus" - "github.com/spf13/afero" - "github.com/firecracker-microvm/firecracker-go-sdk" "github.com/firecracker-microvm/firecracker-go-sdk/client" fcmodels "github.com/firecracker-microvm/firecracker-go-sdk/client/models" "github.com/firecracker-microvm/firecracker-go-sdk/client/operations" + "github.com/go-openapi/strfmt" + "github.com/sirupsen/logrus" + "github.com/spf13/afero" "github.com/weaveworks/flintlock/core/models" "github.com/weaveworks/flintlock/core/ports" @@ -78,6 +77,7 @@ func (p *fcProvider) Start(ctx context.Context, id string) error { if err != nil { return fmt.Errorf("checking if instance is running: %w", err) } + if state == ports.MicroVMStateRunning { logger.Debug("instance is already running, not starting") @@ -88,15 +88,17 @@ func (p *fcProvider) Start(ctx context.Context, id string) error { if err != nil { return fmt.Errorf("parsing vmid: %w", err) } - vmState := NewState(*vmid, p.config.StateRoot, p.fs) + vmState := NewState(*vmid, p.config.StateRoot, p.fs) socketPath := vmState.SockPath() logger.Tracef("using socket %s", socketPath) client := firecracker.NewClient(socketPath, logger, true) + _, err = client.CreateSyncAction(ctx, &fcmodels.InstanceActionInfo{ ActionType: firecracker.String("InstanceStart"), }) + if err != nil { return fmt.Errorf("failed to create start action: %w", err) } @@ -139,8 +141,8 @@ func (p *fcProvider) Delete(ctx context.Context, id string) error { if err != nil { return fmt.Errorf("parsing vmid: %w", err) } - vmState := NewState(*vmid, p.config.StateRoot, p.fs) + vmState := NewState(*vmid, p.config.StateRoot, p.fs) socketPath := vmState.SockPath() logger.Tracef("using socket %s", socketPath) @@ -193,13 +195,15 @@ func (p *fcProvider) State(ctx context.Context, id string) (ports.MicroVMState, if err != nil { return ports.MicroVMStateUnknown, fmt.Errorf("parsing vmid: %w", err) } - vmState := NewState(*vmid, p.config.StateRoot, p.fs) + vmState := NewState(*vmid, p.config.StateRoot, p.fs) pidPath := vmState.PIDPath() + exists, err := afero.Exists(p.fs, pidPath) if err != nil { return ports.MicroVMStateUnknown, fmt.Errorf("checking pid file exists: %w", err) } + if !exists { return ports.MicroVMStatePending, nil } @@ -213,6 +217,7 @@ func (p *fcProvider) State(ctx context.Context, id string) (ports.MicroVMState, if err != nil { return ports.MicroVMStateUnknown, fmt.Errorf("checking if firecracker process is running: %w", err) } + if !processExists { return ports.MicroVMStatePending, nil } diff --git a/infrastructure/firecracker/state.go b/infrastructure/firecracker/state.go index 7981e50f..b0b7ed4d 100644 --- a/infrastructure/firecracker/state.go +++ b/infrastructure/firecracker/state.go @@ -113,11 +113,12 @@ func (s *fsState) pidReadFromFile(pidFile string) (int, error) { func (s *fsState) pidWriteToFile(pid int, pidFile string) error { file, err := s.fs.OpenFile(pidFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, defaults.DataFilePerm) - defer file.Close() //nolint: staticcheck if err != nil { return fmt.Errorf("opening pid file %s: %w", pidFile, err) } + defer file.Close() + _, err = fmt.Fprintf(file, "%d", pid) if err != nil { return fmt.Errorf("writing pid %d to file %s: %w", pid, pidFile, err) @@ -138,6 +139,7 @@ func (s *fsState) cfgReadFromFile(cfgFile string) (*VmmConfig, error) { } cfg := &VmmConfig{} + err = json.Unmarshal(data, cfg) if err != nil { return nil, fmt.Errorf("unmarshalling firecracker config: %w", err) @@ -153,11 +155,12 @@ func (s *fsState) cfgWriteToFile(cfg *VmmConfig, cfgFile string) error { } file, err := s.fs.OpenFile(cfgFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, defaults.DataFilePerm) - defer file.Close() //nolint: staticcheck if err != nil { return fmt.Errorf("opening firecracker config file %s: %w", cfgFile, err) } + defer file.Close() + _, err = file.Write(data) if err != nil { return fmt.Errorf("writing firecracker cfg to file %s: %w", cfgFile, err) diff --git a/infrastructure/firecracker/types.go b/infrastructure/firecracker/types.go index 7169bea0..f70abde8 100644 --- a/infrastructure/firecracker/types.go +++ b/infrastructure/firecracker/types.go @@ -1,7 +1,30 @@ package firecracker -// VmmConfig contains the configuration of the microvm. Based on the rust structure -// from here https://github.com/firecracker-microvm/firecracker/blob/0690010524001b606f67c1a65c67f3c27883183f/src/vmm/src/resources.rs#L51. +const ( + // CacheTypeUnsafe indovates the flushing mechanic will be advertised to + // the guest driver, but the operation will be a noop. + CacheTypeUnsafe CacheType = "Unsafe" + // CacheTypeWriteBack indicates the flushing mechanic will be advertised + // to the guest driver and flush requests coming from the guest will be + // performed using `fsync`. + CacheTypeWriteBack CacheType = "WriteBack" + + LogLevelError LogLevel = "Error" + LogLevelWarning LogLevel = "Warning" + LogLevelInfo LogLevel = "Info" + LogLevelDebug LogLevel = "Debug" + + // InstanceStateNotStarted the instance hasn't started running yet. + InstanceStateNotStarted InstanceState = "Not started" + // InstanceStateRunning the instance is running. + InstanceStateRunning InstanceState = "Running" + // InstanceStatePaused the instance is currently paused. + InstanceStatePaused InstanceState = "Paused" +) + +// VmmConfig contains the configuration of the microvm. +// Based on the rust structure from firecracker: +// https://github.com/firecracker-microvm/firecracker/blob/0690010524001b606f67c1a65c67f3c27883183f/src/vmm/src/resources.rs#L51. type VmmConfig struct { // Balloon hols the balloon device configuration. Balloon *BalloonDeviceConfig `json:"balloon,omitempty"` @@ -38,16 +61,6 @@ type VMConfig struct { type CacheType string -var ( - // CacheTypeUnsafe indovates the flushing mechanic will be advertised to - // the guest driver, but the operation will be a noop. - CacheTypeUnsafe CacheType = "Unsafe" - // CacheTypeWriteBack indicates the flushing mechanic will be advertised - // to the guest driver and flush requests coming from the guest will be - // performed using `fsync`. - CacheTypeWriteBack CacheType = "WriteBack" -) - // BlockDeviceConfig contains the configuration for a microvm block device. type BlockDeviceConfig struct { // ID is the unique identifier of the drive. @@ -104,13 +117,6 @@ type NetworkInterfaceConfig struct { type LogLevel string -var ( - LogLevelError LogLevel = "Error" - LogLevelWarning LogLevel = "Warning" - LogLevelInfo LogLevel = "Info" - LogLevelDebug LogLevel = "Debug" -) - // LoggerConfig holds the configuration for the logger. type LoggerConfig struct { // LogPath is the named pipe or file used as output for logs. @@ -161,12 +167,3 @@ type Metadata struct { // InstanceState is a type that represents the running state of a Firecracker instance. type InstanceState string - -var ( - // InstanceStateNotStarted the instance hasn't started running yet. - InstanceStateNotStarted InstanceState = "Not started" - // InstanceStateRunning the instance is running. - InstanceStateRunning InstanceState = "Running" - // InstanceStatePaused the instance is currently paused. - InstanceStatePaused InstanceState = "Paused" -) diff --git a/infrastructure/grpc/convert.go b/infrastructure/grpc/convert.go index 00b09411..62609c9c 100644 --- a/infrastructure/grpc/convert.go +++ b/infrastructure/grpc/convert.go @@ -12,6 +12,7 @@ func convertMicroVMToModel(spec *types.MicroVMSpec) (*models.MicroVM, error) { if err != nil { return nil, fmt.Errorf("creating vmid from spec: %w", err) } + convertedModel := &models.MicroVM{ ID: *vmid, // Labels @@ -28,6 +29,7 @@ func convertMicroVMToModel(spec *types.MicroVMSpec) (*models.MicroVM, error) { if spec.Kernel.Filename != nil { convertedModel.Spec.Kernel.Filename = *spec.Kernel.Filename } + if spec.Initrd != nil { convertedModel.Spec.Initrd = &models.Initrd{ Image: models.ContainerImage(spec.Initrd.Image), @@ -60,9 +62,11 @@ func convertNetworkInterfaceToModel(netInt *types.NetworkInterface) *models.Netw AllowMetadataRequests: netInt.AllowMetadataReq, GuestDeviceName: netInt.GuestDeviceName, } + if netInt.GuestMac != nil { converted.GuestMAC = *netInt.GuestMac } + if netInt.Address != nil { converted.Address = *netInt.Address } @@ -84,9 +88,11 @@ func convertVolumeToModel(volume *types.Volume) *models.Volume { IsRoot: volume.IsRoot, IsReadOnly: volume.IsReadOnly, } + if volume.PartitionId != nil { convertedVol.PartitionID = *volume.PartitionId } + if volume.SizeInMb != nil { convertedVol.Size = *volume.SizeInMb } @@ -135,6 +141,7 @@ func convertModelToMicroVM(mvm *models.MicroVM) *types.MicroVMSpec { } converted.Metadata = map[string]string{} + for metadataKey, metadataValue := range mvm.Spec.Metadata { converted.Metadata[metadataKey] = metadataValue } diff --git a/infrastructure/grpc/server.go b/infrastructure/grpc/server.go index b5038ad0..0516fa2e 100644 --- a/infrastructure/grpc/server.go +++ b/infrastructure/grpc/server.go @@ -5,11 +5,11 @@ import ( "errors" "fmt" + "github.com/go-playground/validator/v10" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/emptypb" - "github.com/go-playground/validator/v10" mvmv1 "github.com/weaveworks/flintlock/api/services/microvm/v1alpha1" "github.com/weaveworks/flintlock/api/types" "github.com/weaveworks/flintlock/core/ports" @@ -33,27 +33,36 @@ type server struct { validator validation.Validator } -func (s *server) CreateMicroVM(ctx context.Context, req *mvmv1.CreateMicroVMRequest) (*mvmv1.CreateMicroVMResponse, error) { +func (s *server) CreateMicroVM(ctx context.Context, + req *mvmv1.CreateMicroVMRequest, +) (*mvmv1.CreateMicroVMResponse, error) { logger := log.GetLogger(ctx) logger.Trace("converting request to model") + modelSpec, err := convertMicroVMToModel(req.Microvm) if err != nil { return nil, fmt.Errorf("converting request: %w", err) } logger.Trace("validating model") - err = s.validator.ValidateStruct(modelSpec) + var valErrors validator.ValidationErrors - if err != nil { + + if err = s.validator.ValidateStruct(modelSpec); err != nil { if errors.As(err, &valErrors) { - return nil, status.Errorf(codes.InvalidArgument, "an error occurred when attempting to validate the request: %v", err) + return nil, status.Errorf( + codes.InvalidArgument, + "an error occurred when attempting to validate the request: %v", + err, + ) } return nil, status.Errorf(codes.Internal, "an error occurred: %v", err) } logger.Infof("creating microvm %s", modelSpec.ID) + createdModel, err := s.commandUC.CreateMicroVM(ctx, modelSpec) if err != nil { logger.Errorf("failed to create microvm: %s", err) @@ -62,6 +71,7 @@ func (s *server) CreateMicroVM(ctx context.Context, req *mvmv1.CreateMicroVMRequ } logger.Trace("converting model to response") + resp := &mvmv1.CreateMicroVMResponse{ Microvm: convertModelToMicroVM(createdModel), } @@ -73,8 +83,8 @@ func (s *server) DeleteMicroVM(ctx context.Context, req *mvmv1.DeleteMicroVMRequ logger := log.GetLogger(ctx) logger.Infof("deleting microvm %s/%s", req.Id, req.Namespace) - err := s.commandUC.DeleteMicroVM(ctx, req.Id, req.Namespace) - if err != nil { + + if err := s.commandUC.DeleteMicroVM(ctx, req.Id, req.Namespace); err != nil { logger.Errorf("failed to delete microvm: %s", err) return nil, fmt.Errorf("deleting microvm: %w", err) @@ -85,8 +95,8 @@ func (s *server) DeleteMicroVM(ctx context.Context, req *mvmv1.DeleteMicroVMRequ func (s *server) GetMicroVM(ctx context.Context, req *mvmv1.GetMicroVMRequest) (*mvmv1.GetMicroVMResponse, error) { logger := log.GetLogger(ctx) - logger.Infof("getting microvm %s/%s", req.Namespace, req.Id) + foundMicrovm, err := s.queryUC.GetMicroVM(ctx, req.Id, req.Namespace) if err != nil { logger.Errorf("failed to get microvm: %s", err) @@ -95,6 +105,7 @@ func (s *server) GetMicroVM(ctx context.Context, req *mvmv1.GetMicroVMRequest) ( } logger.Trace("converting model to response") + resp := &mvmv1.GetMicroVMResponse{ Microvm: &types.MicroVM{ Version: int32(foundMicrovm.Version), @@ -106,10 +117,12 @@ func (s *server) GetMicroVM(ctx context.Context, req *mvmv1.GetMicroVMRequest) ( return resp, nil } -func (s *server) ListMicroVMs(ctx context.Context, req *mvmv1.ListMicroVMsRequest) (*mvmv1.ListMicroVMsResponse, error) { +func (s *server) ListMicroVMs(ctx context.Context, + req *mvmv1.ListMicroVMsRequest, +) (*mvmv1.ListMicroVMsResponse, error) { logger := log.GetLogger(ctx) - logger.Infof("getting all microvms in %s", req.Namespace) + foundMicrovms, err := s.queryUC.GetAllMicroVM(ctx, req.Namespace) if err != nil { logger.Errorf("failed to getting all microvm: %s", err) @@ -118,6 +131,7 @@ func (s *server) ListMicroVMs(ctx context.Context, req *mvmv1.ListMicroVMsReques } logger.Trace("converting model to response") + resp := &mvmv1.ListMicroVMsResponse{ Microvm: []*types.MicroVM{}, } @@ -134,11 +148,15 @@ func (s *server) ListMicroVMs(ctx context.Context, req *mvmv1.ListMicroVMsReques return resp, nil } -func (s *server) ListMicroVMsStream(req *mvmv1.ListMicroVMsRequest, ss mvmv1.MicroVM_ListMicroVMsStreamServer) error { - ctx := ss.Context() +func (s *server) ListMicroVMsStream( + req *mvmv1.ListMicroVMsRequest, + streamServer mvmv1.MicroVM_ListMicroVMsStreamServer, +) error { + ctx := streamServer.Context() logger := log.GetLogger(ctx) logger.Infof("getting all microvms in %s", req.Namespace) + foundMicrovms, err := s.queryUC.GetAllMicroVM(ctx, req.Namespace) if err != nil { logger.Errorf("failed to getting all microvm: %s", err) @@ -147,12 +165,13 @@ func (s *server) ListMicroVMsStream(req *mvmv1.ListMicroVMsRequest, ss mvmv1.Mic } logger.Info("streaming found microvm results") + for _, mvm := range foundMicrovms { resp := &mvmv1.ListMessage{ Microvm: convertModelToMicroVM(mvm), } - if err := ss.Send(resp); err != nil { + if err := streamServer.Send(resp); err != nil { logger.Errorf("failed to stream response to client: %s", err) return fmt.Errorf("streaming response to client: %w", err) diff --git a/infrastructure/network/network_service.go b/infrastructure/network/network_service.go index db006874..42bf58ef 100644 --- a/infrastructure/network/network_service.go +++ b/infrastructure/network/network_service.go @@ -2,6 +2,7 @@ package network import ( "context" + ierror "errors" "fmt" "net" "strings" @@ -35,10 +36,18 @@ func (n *networkService) IfaceCreate(ctx context.Context, input ports.IfaceCreat "service": "netlink_network", "iface": input.DeviceName, }) - logger.Debugf("creating network interface with type %s and MAC %s using parent %s", input.Type, input.MAC, n.parentDeviceName) + logger.Debugf( + "creating network interface with type %s and MAC %s using parent %s", + input.Type, + input.MAC, + n.parentDeviceName, + ) + + var ( + parentLink netlink.Link + err error + ) - var parentLink netlink.Link - var err error if input.Type == models.IfaceTypeMacvtap { if n.parentDeviceName == "" { return nil, errors.ErrParentIfaceRequired @@ -51,12 +60,13 @@ func (n *networkService) IfaceCreate(ctx context.Context, input ports.IfaceCreat } var link netlink.Link + switch input.Type { case models.IfaceTypeTap: link = &netlink.Tuntap{ LinkAttrs: netlink.LinkAttrs{ Name: input.DeviceName, - // TODO: add Namespace + // TODO: add Namespace #206 }, Mode: netlink.TUNTAP_MODE_TAP, } @@ -67,7 +77,7 @@ func (n *networkService) IfaceCreate(ctx context.Context, input ports.IfaceCreat Name: input.DeviceName, MTU: parentLink.Attrs().MTU, ParentIndex: parentLink.Attrs().Index, - Namespace: parentLink.Attrs().Namespace, // TODO: add namespace specific to vm + Namespace: parentLink.Attrs().Namespace, // TODO: add namespace specific to vm #206 TxQLen: parentLink.Attrs().TxQLen, }, Mode: netlink.MACVLAN_MODE_BRIDGE, @@ -75,10 +85,11 @@ func (n *networkService) IfaceCreate(ctx context.Context, input ports.IfaceCreat } if input.MAC != "" { - addr, err := net.ParseMAC(input.MAC) + addr, parseErr := net.ParseMAC(input.MAC) if err != nil { - return nil, fmt.Errorf("parsing mac address %s: %w", input.MAC, err) + return nil, fmt.Errorf("parsing mac address %s: %w", input.MAC, parseErr) } + link.Attrs().HardwareAddr = addr logger.Tracef("added mac address %s to interface", addr) } @@ -88,7 +99,7 @@ func (n *networkService) IfaceCreate(ctx context.Context, input ports.IfaceCreat return nil, errors.NewErrUnsupportedInterface(string(input.Type)) } - if err := netlink.LinkAdd(link); err != nil { + if err = netlink.LinkAdd(link); err != nil { return nil, fmt.Errorf("creating interface %s using netlink: %w", link.Attrs().Name, err) } @@ -100,6 +111,7 @@ func (n *networkService) IfaceCreate(ctx context.Context, input ports.IfaceCreat if err := netlink.LinkSetUp(macIf); err != nil { return nil, fmt.Errorf("enabling device %s: %w", macIf.Attrs().Name, err) } + logger.Debugf("created interface with mac %s", macIf.Attrs().HardwareAddr.String()) return &ports.IfaceDetails{ @@ -120,8 +132,7 @@ func (n *networkService) IfaceDelete(ctx context.Context, input ports.DeleteIfac link, err := netlink.LinkByName(input.DeviceName) if err != nil { - _, ok := err.(netlink.LinkNotFoundError) //nolint: errorlint - if !ok { + if ierror.Is(err, netlink.LinkNotFoundError{}) { return fmt.Errorf("failed to lookup network interface %s: %w", input.DeviceName, err) } @@ -164,6 +175,7 @@ func (n *networkService) IfaceDetails(ctx context.Context, name string) (*ports. if err != nil { return nil, fmt.Errorf("getting interface %s: %w", name, err) } + if !found { return nil, errors.ErrIfaceNotFound } @@ -189,8 +201,7 @@ func (n *networkService) IfaceDetails(ctx context.Context, name string) (*ports. func (n *networkService) getIface(name string) (bool, netlink.Link, error) { link, err := netlink.LinkByName(name) if err != nil { - _, ok := err.(netlink.LinkNotFoundError) //nolint: errorlint - if !ok { + if ierror.Is(err, netlink.LinkNotFoundError{}) { return false, nil, fmt.Errorf("failed to lookup network interface %s: %w", name, err) } diff --git a/infrastructure/network/utils.go b/infrastructure/network/utils.go index 366bb2e9..fe512fa3 100644 --- a/infrastructure/network/utils.go +++ b/infrastructure/network/utils.go @@ -8,6 +8,7 @@ import ( "strings" "github.com/vishvananda/netlink" + "github.com/weaveworks/flintlock/core/models" ) @@ -22,7 +23,7 @@ const ( ) func NewIfaceName(ifaceType models.IfaceType) (string, error) { - devPrefix := "" + var devPrefix string switch ifaceType { case models.IfaceTypeTap: @@ -57,7 +58,7 @@ func NewIfaceName(ifaceType models.IfaceType) (string, error) { func generateRandomName(prefix string) (string, error) { id := make([]byte, randomBytesLength) if _, err := io.ReadFull(rand.Reader, id); err != nil { - return "", err + return "", interfaceErrorf("random generator error: %s", err.Error()) } return prefix + hex.EncodeToString(id)[:ifaceLength], nil diff --git a/infrastructure/ulid/ulid.go b/infrastructure/ulid/ulid.go index 13b58250..cbad3d4f 100644 --- a/infrastructure/ulid/ulid.go +++ b/infrastructure/ulid/ulid.go @@ -10,13 +10,14 @@ import ( "github.com/weaveworks/flintlock/core/ports" ) -// DefaultRand is a random source based on the unix time not. -var DefaultRand = rand.New(rand.NewSource(time.Now().UnixNano())) //nolint:gosec +func randomSource() *rand.Rand { + return rand.New(rand.NewSource(time.Now().UnixNano())) //nolint: gosec // It's not a security context +} // New will create a new ulid based ID service using the default random source. func New() ports.IDService { return &ulidIDService{ - rnd: DefaultRand, + rnd: randomSource(), } } @@ -34,6 +35,7 @@ type ulidIDService struct { // GenerateRandom will generate a random identifier using ulid. func (u *ulidIDService) GenerateRandom() (string, error) { entropy := ulid.Monotonic(u.rnd, 0) + newID, err := ulid.New(ulid.Now(), entropy) if err != nil { return "", fmt.Errorf("generating microvm id: %w", err) diff --git a/internal/command/flags/flags.go b/internal/command/flags/flags.go index 26cd9d34..73087193 100644 --- a/internal/command/flags/flags.go +++ b/internal/command/flags/flags.go @@ -78,9 +78,11 @@ func AddHiddenFlagsToCommand(cmd *cobra.Command, cfg *config.Config) error { if err := cmd.Flags().MarkHidden(disableReconcileFlag); err != nil { return fmt.Errorf("setting %s as hidden: %w", disableReconcileFlag, err) } + if err := cmd.Flags().MarkHidden(maximumRetryFlag); err != nil { return fmt.Errorf("setting %s as hidden: %w", maximumRetryFlag, err) } + if err := cmd.Flags().MarkHidden(disableAPIFlag); err != nil { return fmt.Errorf("setting %s as hidden: %w", disableAPIFlag, err) } diff --git a/internal/command/gw/gw.go b/internal/command/gw/gw.go index cc5a70da..fe86ccb3 100644 --- a/internal/command/gw/gw.go +++ b/internal/command/gw/gw.go @@ -59,8 +59,10 @@ func runGWServer(ctx context.Context, cfg *config.Config) error { ctx, cancel := context.WithCancel(log.WithLogger(ctx, logger)) wg.Add(1) + go func() { defer wg.Done() + if err := serveAPI(ctx, cfg); err != nil { logger.Errorf("failed serving api: %v", err) } @@ -81,16 +83,6 @@ func serveAPI(ctx context.Context, cfg *config.Config) error { logger := log.GetLogger(ctx) mux := runtime.NewServeMux() - // TODO: create the dependencies for the server - - // grpcServer := grpc.NewServer( - // grpc.StreamInterceptor(grpc_prometheus.StreamServerInterceptor), - // grpc.UnaryInterceptor(grpc_prometheus.UnaryServerInterceptor), - // ) - // mvmv1.RegisterMicroVMServer(grpcServer, server.NewServer()) - // grpc_prometheus.Register(grpcServer) - // http.Handle("/metrics", promhttp.Handler()) - opts := []grpc.DialOption{ grpc.WithInsecure(), } @@ -99,7 +91,7 @@ func serveAPI(ctx context.Context, cfg *config.Config) error { return fmt.Errorf("could not register microvm server: %w", err) } - s := &http.Server{ + server := &http.Server{ Addr: cfg.HTTPAPIEndpoint, Handler: mux, } @@ -107,27 +99,16 @@ func serveAPI(ctx context.Context, cfg *config.Config) error { go func() { <-ctx.Done() logger.Infof("shutting down the http gateway server") - if err := s.Shutdown(context.Background()); err != nil { + + //nolint: contextcheck // Intentional. + if err := server.Shutdown(context.Background()); err != nil { logger.Errorf("failed to shutdown http gateway server: %v", err) } - // logger.Infof("shutting down grpc server") - // grpcServer.GracefulStop() }() - // logger.Debugf("starting grpc server listening on endpoint %s", cfg.GRPCAPIEndpoint) - // l, err := net.Listen("tcp", cfg.GRPCAPIEndpoint) - // if err != nil { - // return fmt.Errorf("setting up gRPC api listener: %w", err) - // } - // defer l.Close() - // go func() { - // if err := grpcServer.Serve(l); err != nil { - // logger.Fatalf("serving grpc api: %v", err) // TODO: remove this fatal - // } - // }() - logger.Debugf("starting http server listening on endpoint %s", cfg.HTTPAPIEndpoint) - if err := s.ListenAndServe(); err != nil { + + if err := server.ListenAndServe(); err != nil { return fmt.Errorf("listening and serving http api: %w", err) } diff --git a/internal/command/root.go b/internal/command/root.go index 40bfbe20..9ca62a3e 100644 --- a/internal/command/root.go +++ b/internal/command/root.go @@ -32,11 +32,12 @@ func NewRootCommand() (*cobra.Command, error) { return nil }, RunE: func(c *cobra.Command, _ []string) error { - return c.Help() //nolint: wrapcheck + return c.Help() }, } log.AddFlagsToCommand(cmd, &cfg.Logging) + if err := addRootSubCommands(cmd, cfg); err != nil { return nil, fmt.Errorf("adding subcommands: %w", err) } @@ -89,11 +90,11 @@ func versionCommand() *cobra.Command { ) if long, err = cmd.Flags().GetBool("long"); err != nil { - return nil + return err } if short, err = cmd.Flags().GetBool("short"); err != nil { - return nil + return err } if short { diff --git a/internal/command/run/run.go b/internal/command/run/run.go index 0ff3cca7..e93520b2 100644 --- a/internal/command/run/run.go +++ b/internal/command/run/run.go @@ -49,18 +49,23 @@ func NewCommand(cfg *config.Config) (*cobra.Command, error) { } cmdflags.AddGRPCServerFlagsToCommand(cmd, cfg) + if err := cmdflags.AddContainerDFlagsToCommand(cmd, cfg); err != nil { return nil, fmt.Errorf("adding containerd flags to run command: %w", err) } + if err := cmdflags.AddFirecrackerFlagsToCommand(cmd, cfg); err != nil { return nil, fmt.Errorf("adding firecracker flags to run command: %w", err) } + if err := cmdflags.AddNetworkFlagsToCommand(cmd, cfg); err != nil { return nil, fmt.Errorf("adding network flags to run command: %w", err) } + if err := cmdflags.AddHiddenFlagsToCommand(cmd, cfg); err != nil { return nil, fmt.Errorf("adding hidden flags to run command: %w", err) } + cmd.Flags().StringVar(&cfg.StateRootDir, "state-dir", defaults.StateRootDir, "The directory to use for the as the root for runtime state.") cmd.Flags().DurationVar(&cfg.ResyncPeriod, "resync-period", defaults.ResyncPeriod, "Reconcile the specs to resynchronise them based on this period.") @@ -79,8 +84,10 @@ func runServer(ctx context.Context, cfg *config.Config) error { if !cfg.DisableAPI { wg.Add(1) + go func() { defer wg.Done() + if err := serveAPI(ctx, cfg); err != nil { logger.Errorf("failed serving api: %v", err) } @@ -89,8 +96,10 @@ func runServer(ctx context.Context, cfg *config.Config) error { if !cfg.DisableReconcile { wg.Add(1) + go func() { defer wg.Done() + if err := runControllers(ctx, cfg); err != nil { logger.Errorf("failed running controllers: %v", err) } @@ -113,8 +122,9 @@ func serveAPI(ctx context.Context, cfg *config.Config) error { ports, err := inject.InitializePorts(cfg) if err != nil { - return fmt.Errorf("initializing ports for application: %w", err) + return fmt.Errorf("initialising ports for application: %w", err) } + app := inject.InitializeApp(cfg, ports) server := inject.InitializeGRPCServer(app) @@ -133,16 +143,17 @@ func serveAPI(ctx context.Context, cfg *config.Config) error { }() logger.Debugf("starting grpc server listening on endpoint %s", cfg.GRPCAPIEndpoint) - l, err := net.Listen("tcp", cfg.GRPCAPIEndpoint) + + listener, err := net.Listen("tcp", cfg.GRPCAPIEndpoint) if err != nil { return fmt.Errorf("setting up gRPC api listener: %w", err) } - defer l.Close() + defer listener.Close() reflection.Register(grpcServer) - if err := grpcServer.Serve(l); err != nil { - logger.Fatalf("serving grpc api: %v", err) // TODO: remove this fatal + if err := grpcServer.Serve(listener); err != nil { + logger.Fatalf("serving grpc api: %v", err) // TODO: remove this fatal #235 } return nil @@ -153,12 +164,14 @@ func runControllers(ctx context.Context, cfg *config.Config) error { ports, err := inject.InitializePorts(cfg) if err != nil { - return fmt.Errorf("initializing ports for controller: %w", err) + return fmt.Errorf("initialising ports for controller: %w", err) } + app := inject.InitializeApp(cfg, ports) mvmControllers := inject.InializeController(app, ports) logger.Info("starting microvm controller") + if err := mvmControllers.Run(ctx, 1, cfg.ResyncPeriod, true); err != nil { logger.Fatalf("starting microvm controller: %v", err) } diff --git a/pkg/flags/flags.go b/pkg/flags/flags.go index 2b21861c..ad43f480 100644 --- a/pkg/flags/flags.go +++ b/pkg/flags/flags.go @@ -16,12 +16,12 @@ func BindCommandToViper(cmd *cobra.Command) { func bindFlagsToViper(fs *pflag.FlagSet) { fs.VisitAll(func(flag *pflag.Flag) { - viper.BindPFlag(flag.Name, flag) //nolint: errcheck - viper.BindEnv(flag.Name) //nolint: errcheck + _ = viper.BindPFlag(flag.Name, flag) + _ = viper.BindEnv(flag.Name) if !flag.Changed && viper.IsSet(flag.Name) { val := viper.Get(flag.Name) - fs.Set(flag.Name, fmt.Sprintf("%v", val)) //nolint: errcheck + _ = fs.Set(flag.Name, fmt.Sprintf("%v", val)) } }) } diff --git a/pkg/log/log.go b/pkg/log/log.go index 643504da..ba3a84eb 100644 --- a/pkg/log/log.go +++ b/pkg/log/log.go @@ -44,9 +44,11 @@ type Config struct { // Configure will configure the logger from the supplied config. func Configure(logConfig *Config) error { configureVerbosity(logConfig) + if err := configureFormatter(logConfig); err != nil { return fmt.Errorf("configuring log formatter: %w", err) } + if err := configureOutput(logConfig); err != nil { return fmt.Errorf("configuring log output: %w", err) } @@ -69,6 +71,7 @@ func configureFormatter(logConfig *Config) error { func configureVerbosity(logConfig *Config) { logrus.SetLevel(logrus.InfoLevel) + if logConfig.Verbosity >= LogVerbosityDebug && logConfig.Verbosity < LogVerbosityTrace { logrus.SetLevel(logrus.DebugLevel) } else if logConfig.Verbosity >= LogVerbosityTrace { @@ -90,6 +93,7 @@ func configureOutput(logConfig *Config) error { if err != nil { return fmt.Errorf("opening log file %s: %w", output, err) } + logrus.SetOutput(file) } diff --git a/pkg/planner/actuator.go b/pkg/planner/actuator.go index 20aafd0b..f9275740 100644 --- a/pkg/planner/actuator.go +++ b/pkg/planner/actuator.go @@ -24,17 +24,17 @@ func NewActuator() Actuator { type actuatorImpl struct{} // Execute will execute the plan. -func (e *actuatorImpl) Execute(ctx context.Context, p Plan, executionID string) (int, error) { +func (e *actuatorImpl) Execute(ctx context.Context, plan Plan, executionID string) (int, error) { logger := log.GetLogger(ctx).WithFields(logrus.Fields{ "execution_id": executionID, - "plan_name": p.Name(), + "plan_name": plan.Name(), }) start := time.Now().UTC() logger.Infof("started executing plan") - numStepsExecuted, err := e.executePlan(ctx, p, logger) + numStepsExecuted, err := e.executePlan(ctx, plan, logger) if err != nil { logger.WithFields(logrus.Fields{ "execution_time": time.Since(start), @@ -52,12 +52,13 @@ func (e *actuatorImpl) Execute(ctx context.Context, p Plan, executionID string) return numStepsExecuted, nil } -func (e *actuatorImpl) executePlan(ctx context.Context, p Plan, logger *logrus.Entry) (int, error) { +func (e *actuatorImpl) executePlan(ctx context.Context, plan Plan, logger *logrus.Entry) (int, error) { numStepsExecuted := 0 + for { - steps, err := p.Create(ctx) + steps, err := plan.Create(ctx) if err != nil { - return numStepsExecuted, fmt.Errorf("creating plan for %s: %w", p.Name(), err) + return numStepsExecuted, fmt.Errorf("creating plan for %s: %w", plan.Name(), err) } if len(steps) == 0 { @@ -68,6 +69,7 @@ func (e *actuatorImpl) executePlan(ctx context.Context, p Plan, logger *logrus.E executed, err := e.react(ctx, steps, logger) numStepsExecuted += executed + if err != nil { return numStepsExecuted, fmt.Errorf("executing steps: %w", err) } @@ -76,6 +78,7 @@ func (e *actuatorImpl) executePlan(ctx context.Context, p Plan, logger *logrus.E func (e *actuatorImpl) react(ctx context.Context, steps []Procedure, logger *logrus.Entry) (int, error) { var childSteps []Procedure + numStepsExecuted := 0 for _, step := range steps { @@ -83,12 +86,13 @@ func (e *actuatorImpl) react(ctx context.Context, steps []Procedure, logger *log case <-ctx.Done(): logger.WithField("step_name", step.Name()).Info("step not executed due to context done") - return numStepsExecuted, ctx.Err() //nolint:wrapcheck + return numStepsExecuted, ctx.Err() //nolint:wrapcheck // It's ok ;) default: shouldDo, err := step.ShouldDo(ctx) if err != nil { return numStepsExecuted, fmt.Errorf("checking if step %s should be executed: %w", step.Name(), err) } + if shouldDo { logger.WithField("step", step.Name()).Debug("execute step") @@ -100,9 +104,11 @@ func (e *actuatorImpl) react(ctx context.Context, steps []Procedure, logger *log } } } + if len(childSteps) > 0 { executed, err := e.react(ctx, childSteps, logger) numStepsExecuted += executed + if err != nil { return numStepsExecuted, err } diff --git a/pkg/queue/queue.go b/pkg/queue/queue.go index 44b58f05..66900f28 100644 --- a/pkg/queue/queue.go +++ b/pkg/queue/queue.go @@ -6,7 +6,8 @@ import ( "github.com/google/go-cmp/cmp" ) -// NOTE: this is heavily based on the workerqueue from client-go: https://github.com/kubernetes/client-go/blob/master/util/workqueue/queue.go +// NOTE: this is heavily based on the workerqueue from client-go: +// https://github.com/kubernetes/client-go/blob/master/util/workqueue/queue.go // Queue is the interface for a queue. type Queue interface { diff --git a/pkg/validation/validate.go b/pkg/validation/validate.go index cc815c68..3cf27fa8 100644 --- a/pkg/validation/validate.go +++ b/pkg/validation/validate.go @@ -6,7 +6,8 @@ import ( "time" "github.com/containerd/containerd/reference" - "github.com/go-playground/validator/v10" + playgroundValidator "github.com/go-playground/validator/v10" + "github.com/weaveworks/flintlock/core/models" ) @@ -15,20 +16,20 @@ type Validator interface { } type validate struct { - validator *validator.Validate + validator *playgroundValidator.Validate } func NewValidator() Validator { - v := validator.New() + validator := playgroundValidator.New() - // TODO(@jmickey): Do something with this error maybe? - _ = v.RegisterValidation("imageURI", customImageURIValidator, false) - _ = v.RegisterValidation("datetimeInPast", customTimestampValidator, false) - _ = v.RegisterValidation("guestDeviceName", customNetworkGuestDeviceNameValidator, false) - v.RegisterStructValidation(customMicroVMSpecStructLevelValidation, models.MicroVMSpec{}) + // TODO(@jmickey): Do something with this error maybe? #236 + _ = validator.RegisterValidation("imageURI", customImageURIValidator, false) + _ = validator.RegisterValidation("datetimeInPast", customTimestampValidator, false) + _ = validator.RegisterValidation("guestDeviceName", customNetworkGuestDeviceNameValidator, false) + validator.RegisterStructValidation(customMicroVMSpecStructLevelValidation, models.MicroVMSpec{}) return &validate{ - validator: v, + validator: validator, } } @@ -40,7 +41,7 @@ func (v *validate) ValidateStruct(obj interface{}) error { return nil } -func customImageURIValidator(fl validator.FieldLevel) bool { +func customImageURIValidator(fl playgroundValidator.FieldLevel) bool { uri := fl.Field().String() _, err := reference.Parse(uri) @@ -49,24 +50,24 @@ func customImageURIValidator(fl validator.FieldLevel) bool { } // Ensure that the timestamp is in the past and greater than 0. -func customTimestampValidator(fl validator.FieldLevel) bool { +func customTimestampValidator(fl playgroundValidator.FieldLevel) bool { tm := fl.Field().Int() return tm <= time.Now().Unix() && tm > 0 } -func customNetworkGuestDeviceNameValidator(fl validator.FieldLevel) bool { - name := fl.Field().String() +func customNetworkGuestDeviceNameValidator(fieldLevel playgroundValidator.FieldLevel) bool { + name := fieldLevel.Field().String() re := regexp.MustCompile("^[a-z][a-z0-9_]*$") return re.MatchString(name) } -func customMicroVMSpecStructLevelValidation(sl validator.StructLevel) { - spec, _ := sl.Current().Interface().(models.MicroVMSpec) +func customMicroVMSpecStructLevelValidation(structLevel playgroundValidator.StructLevel) { + spec, _ := structLevel.Current().Interface().(models.MicroVMSpec) if spec.Initrd == nil && len(spec.Volumes) == 0 { - sl.ReportError(spec.Volumes, "volumes", "Volumes", "volumeOrInitrdRequired", "") + structLevel.ReportError(spec.Volumes, "volumes", "Volumes", "volumeOrInitrdRequired", "") return } @@ -79,12 +80,13 @@ func customMicroVMSpecStructLevelValidation(sl validator.StructLevel) { // that a root device has been configured. var found bool + for _, vol := range spec.Volumes { if vol.IsRoot { if found { // Only one volume can be specified as the root volume. If a root volume is found twice then // report an error. - sl.ReportError(spec.Volumes, "volumes", "Volumes", "onlyOneRootVolume", "") + structLevel.ReportError(spec.Volumes, "volumes", "Volumes", "onlyOneRootVolume", "") } found = true @@ -92,7 +94,7 @@ func customMicroVMSpecStructLevelValidation(sl validator.StructLevel) { } if spec.Initrd == nil && !found { - sl.ReportError(spec.Volumes, "volumes", "Volumes", "oneVolumeMustBeRoot", "") + structLevel.ReportError(spec.Volumes, "volumes", "Volumes", "oneVolumeMustBeRoot", "") return } diff --git a/pkg/wait/wait.go b/pkg/wait/wait.go index f07c4ad3..c3ebf815 100644 --- a/pkg/wait/wait.go +++ b/pkg/wait/wait.go @@ -17,15 +17,17 @@ type ConditionFunc func() (bool, error) // ForCondition will wait for the specified condition to be true until the max duration. func ForCondition(conditionFn ConditionFunc, maxWait time.Duration, checkInternal time.Duration) error { timeout := time.NewTimer(maxWait) + defer timeout.Stop() + checkTicker := time.NewTicker(checkInternal) defer checkTicker.Stop() - defer timeout.Stop() for { conditionMet, err := conditionFn() if err != nil { return fmt.Errorf("checking if condition met: %w", err) } + if conditionMet { return nil } @@ -42,6 +44,6 @@ func ForCondition(conditionFn ConditionFunc, maxWait time.Duration, checkInterna // FileExistsCondition creates a condition check on the existence of a file. func FileExistsCondition(filepath string, fs afero.Fs) ConditionFunc { return func() (bool, error) { - return afero.Exists(fs, filepath) //nolint: wrapcheck + return afero.Exists(fs, filepath) //nolint: wrapcheck // It's ok ;) } } diff --git a/test/e2e/utils/runner.go b/test/e2e/utils/runner.go index ecc15556..ad76f391 100644 --- a/test/e2e/utils/runner.go +++ b/test/e2e/utils/runner.go @@ -14,8 +14,9 @@ import ( gm "github.com/onsi/gomega" "github.com/onsi/gomega/gexec" "github.com/pelletier/go-toml" - "github.com/weaveworks/flintlock/api/services/microvm/v1alpha1" "google.golang.org/grpc" + + "github.com/weaveworks/flintlock/api/services/microvm/v1alpha1" ) const ( @@ -109,6 +110,7 @@ func createThinPools() { scriptPath := filepath.Join(baseDir(), "hack", "scripts", "devpool.sh") command := exec.Command(scriptPath, thinpoolName, loopDeviceTag) session, err := gexec.Start(command, gk.GinkgoWriter, gk.GinkgoWriter) + gm.Expect(err).NotTo(gm.HaveOccurred()) gm.Eventually(session).Should(gexec.Exit(0)) } @@ -118,6 +120,7 @@ func cleanupThinPools() { cmd := exec.Command("losetup") loopDevices := grep(cmd, loopDeviceTag, 0) + for _, dev := range loopDevices { command := exec.Command("losetup", "-d", dev) session, err := gexec.Start(command, gk.GinkgoWriter, gk.GinkgoWriter) @@ -135,8 +138,9 @@ func writeContainerdConfig() { } pluginTree, err := toml.TreeFromMap(dmplug) gm.Expect(err).NotTo(gm.HaveOccurred()) + cfg := ccfg.Config{ - Version: 2, //nolint:gomnd + Version: 2, Root: containerdRootDir, State: containerdStateDir, GRPC: ccfg.GRPCConfig{ @@ -155,13 +159,16 @@ func writeContainerdConfig() { f, err := os.Create(containerdCfg) gm.Expect(err).NotTo(gm.HaveOccurred()) + defer f.Close() + gm.Expect(toml.NewEncoder(f).Encode(cfg)).To(gm.Succeed()) } func (r *Runner) buildFLBinary() { flBin, err := gexec.Build(flintlockCmdDir) gm.Expect(err).NotTo(gm.HaveOccurred()) + r.flintlockdBin = flBin } @@ -169,29 +176,42 @@ func (r *Runner) startContainerd() { ctrdCmd := exec.Command(containerdBin, "--config", containerdCfg) ctrdSess, err := gexec.Start(ctrdCmd, gk.GinkgoWriter, gk.GinkgoWriter) gm.Expect(err).NotTo(gm.HaveOccurred()) + r.containerdSession = ctrdSess } func (r *Runner) startFlintlockd() { parentIface, err := getParentInterface() gm.Expect(err).NotTo(gm.HaveOccurred()) - flCmd := exec.Command(r.flintlockdBin, "run", "--containerd-socket", containerdSocket, "--parent-iface", parentIface) //nolint:gosec + + //nolint: gosec // We know what we're doing. + flCmd := exec.Command( + r.flintlockdBin, + "run", + "--containerd-socket", + containerdSocket, + "--parent-iface", + parentIface, + ) flSess, err := gexec.Start(flCmd, gk.GinkgoWriter, gk.GinkgoWriter) gm.Expect(err).NotTo(gm.HaveOccurred()) + r.flintlockdSession = flSess } func (r *Runner) dialGRPCServer() { conn, err := grpc.Dial(grpcDialTarget, grpc.WithInsecure(), grpc.WithBlock()) gm.Expect(err).NotTo(gm.HaveOccurred()) + r.flintlockdConn = conn } func getParentInterface() (string, error) { cmd := exec.Command("ip", "route", "show") - iface := grep(cmd, "default", 4) //nolint:gomnd + iface := grep(cmd, "default", 4) + if len(iface) == 0 { - return "", errors.New("parent interface not found") //nolint:goerr113 + return "", errors.New("parent interface not found") } return iface[0], nil @@ -200,8 +220,10 @@ func getParentInterface() (string, error) { func grep(cmd *exec.Cmd, match string, loc int) []string { output, err := cmd.Output() gm.Expect(err).NotTo(gm.HaveOccurred()) + scanner := bufio.NewScanner(strings.NewReader(string(output))) out := []string{} + for scanner.Scan() { line := scanner.Text() if strings.Contains(line, match) {