Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/tools/gopls: failures in kubernetes repository #33551

Closed
stamblerre opened this issue Aug 8, 2019 · 6 comments
Closed

x/tools/gopls: failures in kubernetes repository #33551

stamblerre opened this issue Aug 8, 2019 · 6 comments

Comments

@stamblerre
Copy link
Contributor

@stamblerre stamblerre commented Aug 8, 2019

Forked from #32899.

I tried with master and I couldn't easily reproduce, so I will point to a way I can reproduce 100% with a couple of keystrokes.

If you checkout https://github.com/ereslibre/kubernetes, the ping-on-long-running-commands branch, I do the following:

  • Open /staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go (I do C-c p f with projectile and kubectl logs.go)
  • Navigate to line 380; visit StreamWithPing (M-.)
  • Go back (M-,)
  • Try to visit StreamWithPing again (M-.)

Error: GetAST: unable to check package for...
If I restart gopls with M-x lsp-restart-workspace, same thing, I can visit it once, go back, and when visiting again it will fail again.

Reproducible in VSCode as well.

Logs [Trace - 4:07:56 PM] Received notification 'window/logMessage' in 0ms. Params: {"type":3,"message":"65.454134ms for GOROOT=$GOROOT GOPATH=$GOPATH GO111MODULE=on PWD=$GOPATH/src/kubernetes go \"list\" \"-e\" \"-json\" \"-compiled=true\" \"-test=true\" \"-export=false\" \"-deps=true\" \"-find=false\" \"--\" \"builtin\", stderr: \u003c\u003c\u003e\u003e\n"}

[Trace - 4:07:56 PM] Received response 'initialize - (0)' in 0ms.
Params: {"capabilities":{"textDocumentSync":{"openClose":true,"change":2,"save":{}},"hoverProvider":true,"completionProvider":{"triggerCharacters":["."]},"signatureHelpProvider":{"triggerCharacters":["(",","]},"definitionProvider":true,"referencesProvider":true,"documentHighlightProvider":true,"documentSymbolProvider":true,"codeActionProvider":true,"documentFormattingProvider":true,"renameProvider":true,"documentLinkProvider":{},"typeDefinitionProvider":true,"workspace":{"workspaceFolders":{"supported":true,"changeNotifications":"workspace/didChangeWorkspaceFolders"}}},"custom":null}

[Trace - 4:07:56 PM] Sending notification 'initialize' in 69ms.
Params: {"processId":12011,"rootPath":"$GOPATH/src/kubernetes","rootUri":"file://$GOPATH/src/kubernetes","capabilities":{"workspace":{"applyEdit":true,"workspaceEdit":{"documentChanges":true},"didChangeConfiguration":{"dynamicRegistration":true},"didChangeWatchedFiles":{"dynamicRegistration":true},"symbol":{"dynamicRegistration":true,"symbolKind":{"valueSet":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26]}},"executeCommand":{"dynamicRegistration":true},"configuration":true,"workspaceFolders":true},"textDocument":{"publishDiagnostics":{"relatedInformation":true},"synchronization":{"dynamicRegistration":true,"willSave":true,"willSaveWaitUntil":true,"didSave":true},"completion":{"dynamicRegistration":true,"contextSupport":true,"completionItem":{"snippetSupport":true,"commitCharactersSupport":true,"documentationFormat":["markdown","plaintext"],"deprecatedSupport":true,"preselectSupport":true},"completionItemKind":{"valueSet":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25]}},"hover":{"dynamicRegistration":true,"contentFormat":["markdown","plaintext"]},"signatureHelp":{"dynamicRegistration":true,"signatureInformation":{"documentationFormat":["markdown","plaintext"]}},"definition":{"dynamicRegistration":true},"references":{"dynamicRegistration":true},"documentHighlight":{"dynamicRegistration":true},"documentSymbol":{"dynamicRegistration":true,"symbolKind":{"valueSet":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26]},"hierarchicalDocumentSymbolSupport":true},"codeAction":{"dynamicRegistration":true,"codeActionLiteralSupport":{"codeActionKind":{"valueSet":["","quickfix","refactor","refactor.extract","refactor.inline","refactor.rewrite","source","source.organizeImports"]}}},"codeLens":{"dynamicRegistration":true},"formatting":{"dynamicRegistration":true},"rangeFormatting":{"dynamicRegistration":true},"onTypeFormatting":{"dynamicRegistration":true},"rename":{"dynamicRegistration":true},"documentLink":{"dynamicRegistration":true},"typeDefinition":{"dynamicRegistration":true},"implementation":{"dynamicRegistration":true},"colorProvider":{"dynamicRegistration":true},"foldingRange":{"dynamicRegistration":true,"rangeLimit":5000,"lineFoldingOnly":true}}},"initializationOptions":{"funcSnippetEnabled":false,"gocodeCompletionEnabled":true},"trace":"off","workspaceFolders":[{"uri":"file://$GOPATH/src/kubernetes","name":"kubernetes"}]}

[Info - 4:07:56 PM] 65.454134ms for GOROOT=$GOROOT GOPATH=$GOPATH GO111MODULE=on PWD=$GOPATH/src/kubernetes go "list" "-e" "-json" "-compiled=true" "-test=true" "-export=false" "-deps=true" "-find=false" "--" "builtin", stderr: <<>>

[Trace - 4:07:56 PM] Sending response 'client/registerCapability - (1)' in 0ms.
Params: {}

[Trace - 4:07:56 PM] Received notification 'client/registerCapability' in 4ms.
Params: {"registrations":[{"id":"workspace/didChangeConfiguration","method":"workspace/didChangeConfiguration"},{"id":"workspace/didChangeWorkspaceFolders","method":"workspace/didChangeWorkspaceFolders"}]}

[Trace - 4:07:56 PM] Sending response 'workspace/configuration - (2)' in 0ms.
Params: [{"wantCompletionDocumentation":false,"useDeepCompletions":true,"hoverKind":"FullDocumentation"},null]

[Trace - 4:07:56 PM] Received notification 'workspace/configuration' in 3ms.
Params: {"items":[{"scopeUri":"file://$GOPATH/src/kubernetes","section":"gopls"},{"scopeUri":"file://$GOPATH/src/kubernetes","section":"kubernetes"}]}

[Trace - 4:07:56 PM] Received notification 'window/logMessage' in 0ms.
Params: {"type":3,"message":"141.115224ms for GOROOT=$GOROOT GOPATH=$GOPATH GO111MODULE=on PWD=$GOPATH/src/kubernetes go "list" "-m" "-json" "all", stderr: \u003c\u003c\u003e\u003e\n"}

[Info - 4:07:56 PM] 141.115224ms for GOROOT=$GOROOT GOPATH=$GOPATH GO111MODULE=on PWD=$GOPATH/src/kubernetes go "list" "-m" "-json" "all", stderr: <<>>

[Trace - 4:07:56 PM] Sending notification 'initialized' in 198ms.
Params: {}

[Trace - 4:07:56 PM] Received notification 'window/logMessage' in 0ms.
Params: {"type":3,"message":"Build info\n----------\ngolang.org/x/tools/cmd/gopls v0.1.3-cmd.gopls\n golang.org/x/tools@(devel)\n golang.org/x/sync@v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=\n golang.org/x/xerrors@v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=\n\nGo info\n-------\ngo version go1.12.5 linux/amd64\n\nGOARCH="amd64"\nGOBIN="$GOPATH/bin"\nGOCACHE="$HOME/.cache/go-build"\nGOEXE=""\nGOFLAGS=""\nGOHOSTARCH="amd64"\nGOHOSTOS="linux"\nGOOS="linux"\nGOPATH="$GOPATH"\nGOPROXY="https://proxy.golang.org\"\nGORACE=\"\"\nGOROOT=\"/usr/lib/google-golang\"\nGOTMPDIR=\"\"\nGOTOOLDIR=\"$GOROOTpkg/tool/linux_amd64\"\nGCCGO=\"gccgo\"\nCC=\"clang\"\nCXX=\"clang++\"\nCGO_ENABLED=\"1\"\nGOMOD=\"$GOPATH/src/kubernetes/go.mod\"\nCGO_CFLAGS=\"-g -O2"\nCGO_CPPFLAGS=""\nCGO_CXXFLAGS="-g -O2"\nCGO_FFLAGS="-g -O2"\nCGO_LDFLAGS="-g -O2"\nPKG_CONFIG="pkg-config"\nGOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build030915839=/tmp/go-build -gno-record-gcc-switches"\n"}

[Info - 4:07:56 PM] Build info

golang.org/x/tools/cmd/gopls v0.1.3-cmd.gopls
golang.org/x/tools@(devel)
golang.org/x/sync@v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
golang.org/x/xerrors@v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=

Go info

go version go1.12.5 linux/amd64

GOARCH="amd64"
GOBIN="$GOPATH/bin"
GOCACHE="$HOME/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="$GOPATH"
GOPROXY="https://proxy.golang.org"
GORACE=""
GOROOT="/usr/lib/google-golang"
GOTMPDIR=""
GOTOOLDIR="$GOROOTpkg/tool/linux_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="$GOPATH/src/kubernetes/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build030915839=/tmp/go-build -gno-record-gcc-switches"

[Trace - 4:07:56 PM] Sending notification 'textDocument/didOpen' in 198ms.
Params: {"textDocument":{"uri":"file://$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go","languageId":"go","version":1,"text":"/\nCopyright 2014 The Kubernetes Authors.\n\nLicensed under the Apache License, Version 2.0 (the "License");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an "AS IS" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n/\n\npackage logs\n\nimport (\n\t"bufio"\n\t"context"\n\t"errors"\n\t"fmt"\n\t"io"\n\t"os"\n\t"sync"\n\t"time"\n\n\t"github.com/spf13/cobra"\n\n\tcorev1 "k8s.io/api/core/v1"\n\tmetav1 "k8s.io/apimachinery/pkg/apis/meta/v1"\n\t"k8s.io/apimachinery/pkg/runtime"\n\t"k8s.io/cli-runtime/pkg/genericclioptions"\n\t"k8s.io/client-go/rest"\n\tcmdutil "k8s.io/kubectl/pkg/cmd/util"\n\t"k8s.io/kubectl/pkg/polymorphichelpers"\n\t"k8s.io/kubectl/pkg/scheme"\n\t"k8s.io/kubectl/pkg/util"\n\t"k8s.io/kubectl/pkg/util/i18n"\n\t"k8s.io/kubectl/pkg/util/templates"\n)\n\nconst (\n\tlogsUsageStr = "logs [-f] [-p] (POD | TYPE/NAME) [-c CONTAINER]"\n)\n\nvar (\n\tlogsExample = templates.Examples(i18n.T(\n\t\t# Return snapshot logs from pod nginx with only one container\n\t\tkubectl logs nginx\n\n\t\t# Return snapshot logs from pod nginx with multi containers\n\t\tkubectl logs nginx --all-containers=true\n\n\t\t# Return snapshot logs from all containers in pods defined by label app=nginx\n\t\tkubectl logs -lapp=nginx --all-containers=true\n\n\t\t# Return snapshot of previous terminated ruby container logs from pod web-1\n\t\tkubectl logs -p -c ruby web-1\n\n\t\t# Begin streaming the logs of the ruby container in pod web-1\n\t\tkubectl logs -f -c ruby web-1\n\n\t\t# Begin streaming the logs from all containers in pods defined by label app=nginx\n\t\tkubectl logs -f -lapp=nginx --all-containers=true\n\n\t\t# Display only the most recent 20 lines of output in pod nginx\n\t\tkubectl logs --tail=20 nginx\n\n\t\t# Show all logs from pod nginx written in the last hour\n\t\tkubectl logs --since=1h nginx\n\n\t\t# Return snapshot logs from first container of a job named hello\n\t\tkubectl logs job/hello\n\n\t\t# Return snapshot logs from container nginx-1 of a deployment named nginx\n\t\tkubectl logs deployment/nginx -c nginx-1))\n\n\tselectorTail int64 = 10\n\tlogsUsageErrStr = fmt.Sprintf("expected '%s'.\nPOD or TYPE/NAME is a required argument for the logs command", logsUsageStr)\n)\n\nconst (\n\tdefaultPodLogsTimeout = 20 * time.Second\n)\n\ntype LogsOptions struct {\n\tNamespace string\n\tResourceArg string\n\tAllContainers bool\n\tOptions runtime.Object\n\tResources []string\n\n\tConsumeRequestFn func(rest.ResponseWrapper, io.Writer, time.Duration) error\n\n\t// PodLogOptions\n\tSinceTime string\n\tSinceSeconds time.Duration\n\tFollow bool\n\tPrevious bool\n\tTimestamps bool\n\tIgnoreLogErrors bool\n\tLimitBytes int64\n\tTail int64\n\tContainer string\n\n\t// whether or not a container name was given via --container\n\tContainerNameSpecified bool\n\tSelector string\n\tMaxFollowConcurrency int\n\n\tObject runtime.Object\n\tGetPodTimeout time.Duration\n\tRESTClientGetter genericclioptions.RESTClientGetter\n\tLogsForObject polymorphichelpers.LogsForObjectFunc\n\n\tgenericclioptions.IOStreams\n\tgenericclioptions.StreamFlags\n\n\tTailSpecified bool\n}\n\nfunc NewLogsOptions(streams genericclioptions.IOStreams, allContainers bool) *LogsOptions {\n\n\treturn &LogsOptions{\n\t\tIOStreams: streams,\n\t\tAllContainers: allContainers,\n\t\tTail: -1,\n\t\tMaxFollowConcurrency: 5,\n\t}\n}\n\n// NewCmdLogs creates a new pod logs command\nfunc NewCmdLogs(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {\n\to := NewLogsOptions(streams, false)\n\n\tcmd := &cobra.Command{\n\t\tUse: logsUsageStr,\n\t\tDisableFlagsInUseLine: true,\n\t\tShort: i18n.T("Print the logs for a container in a pod"),\n\t\tLong: "Print the logs for a container in a pod or specified resource. If the pod has only one container, the container name is optional.",\n\t\tExample: logsExample,\n\t\tPreRun: func(cmd *cobra.Command, args []string) {\n\t\t\tif len(os.Args) > 1 && os.Args[1] == "log" {\n\t\t\t\tfmt.Fprintf(o.ErrOut, "%s is DEPRECATED and will be removed in a future version. Use %s instead.\n", "log", "logs")\n\t\t\t}\n\t\t},\n\t\tRun: func(cmd *cobra.Command, args []string) {\n\t\t\tcmdutil.CheckErr(o.Complete(f, cmd, args))\n\t\t\tcmdutil.CheckErr(o.Validate())\n\t\t\tcmdutil.CheckErr(o.RunLogs())\n\t\t},\n\t\tAliases: []string{"log"},\n\t}\n\n\to.StreamFlags.AddFlags(cmd)\n\n\tcmd.Flags().BoolVar(&o.AllContainers, "all-containers", o.AllContainers, "Get all containers' logs in the pod(s).")\n\tcmd.Flags().BoolVarP(&o.Follow, "follow", "f", o.Follow, "Specify if the logs should be streamed.")\n\tcmd.Flags().BoolVar(&o.Timestamps, "timestamps", o.Timestamps, "Include timestamps on each line in the log output")\n\tcmd.Flags().Int64Var(&o.LimitBytes, "limit-bytes", o.LimitBytes, "Maximum bytes of logs to return. Defaults to no limit.")\n\tcmd.Flags().BoolVarP(&o.Previous, "previous", "p", o.Previous, "If true, print the logs for the previous instance of the container in a pod if it exists.")\n\tcmd.Flags().Int64Var(&o.Tail, "tail", o.Tail, "Lines of recent log file to display. Defaults to -1 with no selector, showing all log lines otherwise 10, if a selector is provided.")\n\tcmd.Flags().BoolVar(&o.IgnoreLogErrors, "ignore-errors", o.IgnoreLogErrors, "If watching / following pod logs, allow for any errors that occur to be non-fatal")\n\tcmd.Flags().StringVar(&o.SinceTime, "since-time", o.SinceTime, i18n.T("Only return logs after a specific date (RFC3339). Defaults to all logs. Only one of since-time / since may be used."))\n\tcmd.Flags().DurationVar(&o.SinceSeconds, "since", o.SinceSeconds, "Only return logs newer than a relative duration like 5s, 2m, or 3h. Defaults to all logs. Only one of since-time / since may be used.")\n\tcmd.Flags().StringVarP(&o.Container, "container", "c", o.Container, "Print the logs of this container")\n\tcmdutil.AddPodRunningTimeoutFlag(cmd, defaultPodLogsTimeout)\n\tcmd.Flags().StringVarP(&o.Selector, "selector", "l", o.Selector, "Selector (label query) to filter on.")\n\tcmd.Flags().IntVar(&o.MaxFollowConcurrency, "max-log-requests", o.MaxFollowConcurrency, "Specify maximum number of concurrent logs to follow when using by a selector. Defaults to 5.")\n\treturn cmd\n}\n\nfunc (o *LogsOptions) ToLogOptions() (*corev1.PodLogOptions, error) {\n\tlogOptions := &corev1.PodLogOptions{\n\t\tContainer: o.Container,\n\t\tFollow: o.Follow,\n\t\tPrevious: o.Previous,\n\t\tTimestamps: o.Timestamps,\n\t}\n\n\tif len(o.SinceTime) > 0 {\n\t\tt, err := util.ParseRFC3339(o.SinceTime, metav1.Now)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tlogOptions.SinceTime = &t\n\t}\n\n\tif o.LimitBytes != 0 {\n\t\tlogOptions.LimitBytes = &o.LimitBytes\n\t}\n\n\tif o.SinceSeconds != 0 {\n\t\t// round up to the nearest second\n\t\tsec := int64(o.SinceSeconds.Round(time.Second).Seconds())\n\t\tlogOptions.SinceSeconds = &sec\n\t}\n\n\tif len(o.Selector) > 0 && o.Tail == -1 && !o.TailSpecified {\n\t\tlogOptions.TailLines = &selectorTail\n\t} else if o.Tail != -1 {\n\t\tlogOptions.TailLines = &o.Tail\n\t}\n\n\treturn logOptions, nil\n}\n\nfunc (o *LogsOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {\n\to.ContainerNameSpecified = cmd.Flag("container").Changed\n\to.TailSpecified = cmd.Flag("tail").Changed\n\to.Resources = args\n\n\tswitch len(args) {\n\tcase 0:\n\t\tif len(o.Selector) == 0 {\n\t\t\treturn cmdutil.UsageErrorf(cmd, "%s", logsUsageErrStr)\n\t\t}\n\tcase 1:\n\t\to.ResourceArg = args[0]\n\t\tif len(o.Selector) != 0 {\n\t\t\treturn cmdutil.UsageErrorf(cmd, "only a selector (-l) or a POD name is allowed")\n\t\t}\n\tcase 2:\n\t\to.ResourceArg = args[0]\n\t\to.Container = args[1]\n\tdefault:\n\t\treturn cmdutil.UsageErrorf(cmd, "%s", logsUsageErrStr)\n\t}\n\tvar err error\n\to.Namespace, _, err = f.ToRawKubeConfigLoader().Namespace()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\to.ConsumeRequestFn = DefaultConsumeRequest\n\n\to.GetPodTimeout, err = cmdutil.GetPodRunningTimeoutFlag(cmd)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\to.Options, err = o.ToLogOptions()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\to.RESTClientGetter = f\n\to.LogsForObject = polymorphichelpers.LogsForObjectFn\n\n\tif o.Object == nil {\n\t\tbuilder := f.NewBuilder().\n\t\t\tWithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...).\n\t\t\tNamespaceParam(o.Namespace).DefaultNamespace().\n\t\t\tSingleResourceType()\n\t\tif o.ResourceArg != "" {\n\t\t\tbuilder.ResourceNames("pods", o.ResourceArg)\n\t\t}\n\t\tif o.Selector != "" {\n\t\t\tbuilder.ResourceTypes("pods").LabelSelectorParam(o.Selector)\n\t\t}\n\t\tinfos, err := builder.Do().Infos()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif o.Selector == "" && len(infos) != 1 {\n\t\t\treturn errors.New("expected a resource")\n\t\t}\n\t\to.Object = infos[0].Object\n\t}\n\n\treturn nil\n}\n\nfunc (o LogsOptions) Validate() error {\n\tif len(o.SinceTime) > 0 && o.SinceSeconds != 0 {\n\t\treturn fmt.Errorf("at most one of sinceTime or sinceSeconds may be specified")\n\t}\n\n\tlogsOptions, ok := o.Options.(*corev1.PodLogOptions)\n\tif !ok {\n\t\treturn errors.New("unexpected logs options object")\n\t}\n\tif o.AllContainers && len(logsOptions.Container) > 0 {\n\t\treturn fmt.Errorf("--all-containers=true should not be specified with container name %s", logsOptions.Container)\n\t}\n\n\tif o.ContainerNameSpecified && len(o.Resources) == 2 {\n\t\treturn fmt.Errorf("only one of -c or an inline [CONTAINER] arg is allowed")\n\t}\n\n\tif o.LimitBytes < 0 {\n\t\treturn fmt.Errorf("--limit-bytes must be greater than 0")\n\t}\n\n\tif logsOptions.SinceSeconds != nil && *logsOptions.SinceSeconds < int64(0) {\n\t\treturn fmt.Errorf("--since must be greater than 0")\n\t}\n\n\tif logsOptions.TailLines != nil && *logsOptions.TailLines < -1 {\n\t\treturn fmt.Errorf("--tail must be greater than or equal to -1")\n\t}\n\n\treturn nil\n}\n\n// RunLogs retrieves a pod log\nfunc (o LogsOptions) RunLogs() error {\n\trequests, err := o.LogsForObject(o.RESTClientGetter, o.Object, o.Options, o.GetPodTimeout, o.AllContainers)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif o.Follow && len(requests) > 1 {\n\t\tif len(requests) > o.MaxFollowConcurrency {\n\t\t\treturn fmt.Errorf(\n\t\t\t\t"you are attempting to follow %d log streams, but maximum allowed concurrency is %d, use --max-log-requests to increase the limit",\n\t\t\t\tlen(requests), o.MaxFollowConcurrency,\n\t\t\t)\n\t\t}\n\n\t\treturn o.parallelConsumeRequest(requests)\n\t}\n\n\treturn o.sequentialConsumeRequest(requests)\n}\n\nfunc (o LogsOptions) parallelConsumeRequest(requests []rest.ResponseWrapper) error {\n\treader, writer := io.Pipe()\n\twg := &sync.WaitGroup{}\n\twg.Add(len(requests))\n\tfor , request := range requests {\n\t\tgo func(request rest.ResponseWrapper) {\n\t\t\tdefer wg.Done()\n\t\t\tif err := o.ConsumeRequestFn(request, writer, o.PingInterval); err != nil {\n\t\t\t\tif !o.IgnoreLogErrors {\n\t\t\t\t\twriter.CloseWithError(err)\n\n\t\t\t\t\t// It's important to return here to propagate the error via the pipe\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tfmt.Fprintf(writer, "error: %v\n", err)\n\t\t\t}\n\n\t\t}(request)\n\t}\n\n\tgo func() {\n\t\twg.Wait()\n\t\twriter.Close()\n\t}()\n\n\t, err := io.Copy(o.Out, reader)\n\treturn err\n}\n\nfunc (o LogsOptions) sequentialConsumeRequest(requests []rest.ResponseWrapper) error {\n\tfor _, request := range requests {\n\t\tif err := o.ConsumeRequestFn(request, o.Out, o.PingInterval); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// DefaultConsumeRequest reads the data from request and writes into\n// the out writer. It buffers data from requests until the newline or io.EOF\n// occurs in the data, so it doesn't interleave logs sub-line\n// when running concurrently.\n//\n// A successful read returns err == nil, not err == io.EOF.\n// Because the function is defined to read from request until io.EOF, it does\n// not treat an io.EOF as an error to be reported.\nfunc DefaultConsumeRequest(request rest.ResponseWrapper, out io.Writer, pingInterval time.Duration) error {\n\tctx, cancel := context.WithCancel(context.Background())\n\tdefer cancel()\n\treadCloser, err := request.StreamWithPing(ctx, pingInterval)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer readCloser.Close()\n\n\tr := bufio.NewReader(readCloser)\n\tfor {\n\t\tbytes, err := r.ReadBytes('\n')\n\t\tif _, err := out.Write(bytes); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif err != nil {\n\t\t\tif err != io.EOF {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\t}\n}\n"}}

[Info - 4:07:57 PM] 118.253567ms for GOROOT=$GOROOT GOPATH=$GOPATH GO111MODULE=on PWD=$GOPATH/src/kubernetes go "list" "-m" "-json" "all", stderr: <<>>

[Trace - 4:07:57 PM] Received notification 'window/logMessage' in 0ms.
Params: {"type":3,"message":"118.253567ms for GOROOT=$GOROOT GOPATH=$GOPATH GO111MODULE=on PWD=$GOPATH/src/kubernetes go "list" "-m" "-json" "all", stderr: \u003c\u003c\u003e\u003e\n"}

[Info - 4:07:57 PM] 582.566743ms for GOROOT=$GOROOT GOPATH=$GOPATH GO111MODULE=on PWD=$GOPATH/src/kubernetes go "list" "-e" "-json" "-compiled=true" "-test=true" "-export=false" "-deps=true" "-find=false" "--" "$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs", stderr: <<go: finding k8s.io/kubernetes/staging/src/k8s.io/kubectl latest
go: k8s.io/kubernetes/staging/src/k8s.io/kubectl@v0.0.0-20190808193559-f4e39afea082: parsing go.mod: unexpected module path "k8s.io/kubectl"
go: error loading module requirements

[Trace - 4:07:57 PM] Received notification 'window/logMessage' in 0ms.
Params: {"type":3,"message":"582.566743ms for GOROOT=$GOROOT GOPATH=$GOPATH GO111MODULE=on PWD=$GOPATH/src/kubernetes go "list" "-e" "-json" "-compiled=true" "-test=true" "-export=false" "-deps=true" "-find=false" "--" "$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs", stderr: \u003c\u003cgo: finding k8s.io/kubernetes/staging/src/k8s.io/kubectl latest\ngo: k8s.io/kubernetes/staging/src/k8s.io/kubectl@v0.0.0-20190808193559-f4e39afea082: parsing go.mod: unexpected module path "k8s.io/kubectl"\ngo: error loading module requirements\n\u003e\u003e\n"}

[Info - 4:07:58 PM] 602.142661ms for GOROOT=$GOROOT GOPATH=$GOPATH GO111MODULE=on PWD=$GOPATH/src/kubernetes go "list" "-e" "-json" "-compiled=true" "-test=true" "-export=false" "-deps=true" "-find=false" "--" "$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go", stderr: <<>>

[Trace - 4:07:58 PM] Received notification 'window/logMessage' in 0ms.
Params: {"type":3,"message":"602.142661ms for GOROOT=$GOROOT GOPATH=$GOPATH GO111MODULE=on PWD=$GOPATH/src/kubernetes go "list" "-e" "-json" "-compiled=true" "-test=true" "-export=false" "-deps=true" "-find=false" "--" "$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go", stderr: \u003c\u003c\u003e\u003e\n"}

[Info - 4:07:58 PM] go/packages.Load
package = command-line-arguments
files = [$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go]
[Trace - 4:07:58 PM] Received notification 'window/logMessage' in 0ms.
Params: {"type":3,"message":"go/packages.Load\n\tpackage = command-line-arguments\n\tfiles = [$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go]"}

[Trace - 4:07:58 PM] Received notification 'window/logMessage' in 0ms.
Params: {"type":3,"message":"go/packages.Load\n\tpackages = 1"}

[Info - 4:07:58 PM] go/packages.Load
packages = 1
[Trace - 4:07:59 PM] Received response 'textDocument/documentSymbol - (1)' in 0ms.
Params: [{"name":"logsUsageStr","detail":"untyped string","kind":14,"range":{"start":{"line":43,"character":0},"end":{"line":45,"character":1}},"selectionRange":{"start":{"line":44,"character":1},"end":{"line":44,"character":13}}},{"name":"logsExample","detail":"string","kind":13,"range":{"start":{"line":47,"character":0},"end":{"line":81,"character":1}},"selectionRange":{"start":{"line":48,"character":1},"end":{"line":48,"character":12}}},{"name":"selectorTail","detail":"int64","kind":13,"range":{"start":{"line":47,"character":0},"end":{"line":81,"character":1}},"selectionRange":{"start":{"line":79,"character":1},"end":{"line":79,"character":13}}},{"name":"logsUsageErrStr","detail":"string","kind":13,"range":{"start":{"line":47,"character":0},"end":{"line":81,"character":1}},"selectionRange":{"start":{"line":80,"character":1},"end":{"line":80,"character":16}}},{"name":"defaultPodLogsTimeout","detail":"time.Duration","kind":14,"range":{"start":{"line":83,"character":0},"end":{"line":85,"character":1}},"selectionRange":{"start":{"line":84,"character":1},"end":{"line":84,"character":22}}},{"name":"LogsOptions","detail":"struct{...}","kind":23,"range":{"start":{"line":87,"character":5},"end":{"line":121,"character":1}},"selectionRange":{"start":{"line":87,"character":5},"end":{"line":87,"character":16}},"children":[{"name":"Namespace","detail":"string","kind":8,"range":{"start":{"line":88,"character":1},"end":{"line":88,"character":21}},"selectionRange":{"start":{"line":88,"character":1},"end":{"line":88,"character":10}}},{"name":"ResourceArg","detail":"string","kind":8,"range":{"start":{"line":89,"character":1},"end":{"line":89,"character":21}},"selectionRange":{"start":{"line":89,"character":1},"end":{"line":89,"character":12}}},{"name":"AllContainers","detail":"bool","kind":8,"range":{"start":{"line":90,"character":1},"end":{"line":90,"character":19}},"selectionRange":{"start":{"line":90,"character":1},"end":{"line":90,"character":14}}},{"name":"Options","detail":"interface{...}","kind":8,"range":{"start":{"line":91,"character":1},"end":{"line":91,"character":29}},"selectionRange":{"start":{"line":91,"character":1},"end":{"line":91,"character":8}}},{"name":"Resources","detail":"[]string","kind":8,"range":{"start":{"line":92,"character":1},"end":{"line":92,"character":23}},"selectionRange":{"start":{"line":92,"character":1},"end":{"line":92,"character":10}}},{"name":"ConsumeRequestFn","detail":"func(rest.ResponseWrapper, io.Writer, time.Duration) error","kind":8,"range":{"start":{"line":94,"character":1},"end":{"line":94,"character":76}},"selectionRange":{"start":{"line":94,"character":1},"end":{"line":94,"character":17}}},{"name":"SinceTime","detail":"string","kind":8,"range":{"start":{"line":97,"character":1},"end":{"line":97,"character":23}},"selectionRange":{"start":{"line":97,"character":1},"end":{"line":97,"character":10}}},{"name":"SinceSeconds","detail":"int64","kind":8,"range":{"start":{"line":98,"character":1},"end":{"line":98,"character":30}},"selectionRange":{"start":{"line":98,"character":1},"end":{"line":98,"character":13}}},{"name":"Follow","detail":"bool","kind":8,"range":{"start":{"line":99,"character":1},"end":{"line":99,"character":21}},"selectionRange":{"start":{"line":99,"character":1},"end":{"line":99,"character":7}}},{"name":"Previous","detail":"bool","kind":8,"range":{"start":{"line":100,"character":1},"end":{"line":100,"character":21}},"selectionRange":{"start":{"line":100,"character":1},"end":{"line":100,"character":9}}},{"name":"Timestamps","detail":"bool","kind":8,"range":{"start":{"line":101,"character":1},"end":{"line":101,"character":21}},"selectionRange":{"start":{"line":101,"character":1},"end":{"line":101,"character":11}}},{"name":"IgnoreLogErrors","detail":"bool","kind":8,"range":{"start":{"line":102,"character":1},"end":{"line":102,"character":21}},"selectionRange":{"start":{"line":102,"character":1},"end":{"line":102,"character":16}}},{"name":"LimitBytes","detail":"int64","kind":8,"range":{"start":{"line":103,"character":1},"end":{"line":103,"character":22}},"selectionRange":{"start":{"line":103,"character":1},"end":{"line":103,"character":11}}},{"name":"Tail","detail":"int64","kind":8,"range":{"start":{"line":104,"character":1},"end":{"line":104,"character":22}},"selectionRange":{"start":{"line":104,"character":1},"end":{"line":104,"character":5}}},{"name":"Container","detail":"string","kind":8,"range":{"start":{"line":105,"character":1},"end":{"line":105,"character":23}},"selectionRange":{"start":{"line":105,"character":1},"end":{"line":105,"character":10}}},{"name":"ContainerNameSpecified","detail":"bool","kind":8,"range":{"start":{"line":108,"character":1},"end":{"line":108,"character":28}},"selectionRange":{"start":{"line":108,"character":1},"end":{"line":108,"character":23}}},{"name":"Selector","detail":"string","kind":8,"range":{"start":{"line":109,"character":1},"end":{"line":109,"character":30}},"selectionRange":{"start":{"line":109,"character":1},"end":{"line":109,"character":9}}},{"name":"MaxFollowConcurrency","detail":"int","kind":8,"range":{"start":{"line":110,"character":1},"end":{"line":110,"character":27}},"selectionRange":{"start":{"line":110,"character":1},"end":{"line":110,"character":21}}},{"name":"Object","detail":"interface{...}","kind":8,"range":{"start":{"line":112,"character":1},"end":{"line":112,"character":32}},"selectionRange":{"start":{"line":112,"character":1},"end":{"line":112,"character":7}}},{"name":"GetPodTimeout","detail":"int64","kind":8,"range":{"start":{"line":113,"character":1},"end":{"line":113,"character":31}},"selectionRange":{"start":{"line":113,"character":1},"end":{"line":113,"character":14}}},{"name":"RESTClientGetter","detail":"interface{...}","kind":8,"range":{"start":{"line":114,"character":1},"end":{"line":114,"character":52}},"selectionRange":{"start":{"line":114,"character":1},"end":{"line":114,"character":17}}},{"name":"LogsForObject","detail":"func(restClientGetter genericclioptions.RESTClientGetter, object runtime.Object, options runtime.Object, timeout time.Duration, allContainers bool) ([]rest.ResponseWrapper, error)","kind":8,"range":{"start":{"line":115,"character":1},"end":{"line":115,"character":54}},"selectionRange":{"start":{"line":115,"character":1},"end":{"line":115,"character":14}}},{"name":"IOStreams","detail":"struct{...}","kind":8,"range":{"start":{"line":117,"character":1},"end":{"line":117,"character":28}},"selectionRange":{"start":{"line":117,"character":1},"end":{"line":117,"character":28}}},{"name":"StreamFlags","detail":"struct{...}","kind":8,"range":{"start":{"line":118,"character":1},"end":{"line":118,"character":30}},"selectionRange":{"start":{"line":118,"character":1},"end":{"line":118,"character":30}}},{"name":"TailSpecified","detail":"bool","kind":8,"range":{"start":{"line":120,"character":1},"end":{"line":120,"character":19}},"selectionRange":{"start":{"line":120,"character":1},"end":{"line":120,"character":14}}},{"name":"ToLogOptions","detail":"()","kind":6,"range":{"start":{"line":174,"character":0},"end":{"line":208,"character":1}},"selectionRange":{"start":{"line":174,"character":22},"end":{"line":174,"character":34}}},{"name":"Complete","detail":"(f cmdutil.Factory, cmd *cobra.Command, args []string)","kind":6,"range":{"start":{"line":210,"character":0},"end":{"line":274,"character":1}},"selectionRange":{"start":{"line":210,"character":22},"end":{"line":210,"character":30}}},{"name":"Validate","detail":"()","kind":6,"range":{"start":{"line":276,"character":0},"end":{"line":306,"character":1}},"selectionRange":{"start":{"line":276,"character":21},"end":{"line":276,"character":29}}},{"name":"RunLogs","detail":"()","kind":6,"range":{"start":{"line":309,"character":0},"end":{"line":327,"character":1}},"selectionRange":{"start":{"line":309,"character":21},"end":{"line":309,"character":28}}},{"name":"parallelConsumeRequest","detail":"(requests []rest.ResponseWrapper)","kind":6,"range":{"start":{"line":329,"character":0},"end":{"line":357,"character":1}},"selectionRange":{"start":{"line":329,"character":21},"end":{"line":329,"character":43}}},{"name":"sequentialConsumeRequest","detail":"(requests []rest.ResponseWrapper)","kind":6,"range":{"start":{"line":359,"character":0},"end":{"line":367,"character":1}},"selectionRange":{"start":{"line":359,"character":21},"end":{"line":359,"character":45}}}]},{"name":"NewLogsOptions","detail":"(streams genericclioptions.IOStreams, allContainers bool)","kind":12,"range":{"start":{"line":123,"character":0},"end":{"line":131,"character":1}},"selectionRange":{"start":{"line":123,"character":5},"end":{"line":123,"character":19}}},{"name":"NewCmdLogs","detail":"(f cmdutil.Factory, streams genericclioptions.IOStreams)","kind":12,"range":{"start":{"line":134,"character":0},"end":{"line":172,"character":1}},"selectionRange":{"start":{"line":134,"character":5},"end":{"line":134,"character":15}}},{"name":"DefaultConsumeRequest","detail":"(request rest.ResponseWrapper, out io.Writer, pingInterval time.Duration)","kind":12,"range":{"start":{"line":377,"character":0},"end":{"line":400,"character":1}},"selectionRange":{"start":{"line":377,"character":5},"end":{"line":377,"character":26}}}]

[Trace - 4:07:59 PM] Sending notification 'textDocument/documentSymbol' in 2623ms.
Params: {"textDocument":{"uri":"file://$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go"}}

[Trace - 4:07:59 PM] Received response 'textDocument/codeAction - (2)' in 0ms.
Params: [{"title":"Organize Imports","kind":"source.organizeImports","edit":{"changes":{"file://$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go":[]}}}]

[Trace - 4:07:59 PM] Sending notification 'textDocument/codeAction' in 2723ms.
Params: {"textDocument":{"uri":"file://$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go"},"range":{"start":{"line":384,"character":20},"end":{"line":384,"character":20}},"context":{"diagnostics":[]}}

[Trace - 4:07:59 PM] Received response 'textDocument/documentLink - (3)' in 0ms.
Params: [{"range":{"start":{"line":19,"character":1},"end":{"line":19,"character":8}},"target":"https://godoc.org/bufio"},{"range":{"start":{"line":20,"character":1},"end":{"line":20,"character":10}},"target":"https://godoc.org/context"},{"range":{"start":{"line":21,"character":1},"end":{"line":21,"character":9}},"target":"https://godoc.org/errors"},{"range":{"start":{"line":22,"character":1},"end":{"line":22,"character":6}},"target":"https://godoc.org/fmt"},{"range":{"start":{"line":23,"character":1},"end":{"line":23,"character":5}},"target":"https://godoc.org/io"},{"range":{"start":{"line":24,"character":1},"end":{"line":24,"character":5}},"target":"https://godoc.org/os"},{"range":{"start":{"line":25,"character":1},"end":{"line":25,"character":7}},"target":"https://godoc.org/sync"},{"range":{"start":{"line":26,"character":1},"end":{"line":26,"character":7}},"target":"https://godoc.org/time"},{"range":{"start":{"line":28,"character":1},"end":{"line":28,"character":25}},"target":"https://godoc.org/github.com/spf13/cobra"},{"range":{"start":{"line":30,"character":1},"end":{"line":30,"character":28}},"target":"https://godoc.org/k8s.io/api/core/v1"},{"range":{"start":{"line":31,"character":1},"end":{"line":31,"character":46}},"target":"https://godoc.org/k8s.io/apimachinery/pkg/apis/meta/v1"},{"range":{"start":{"line":32,"character":1},"end":{"line":32,"character":34}},"target":"https://godoc.org/k8s.io/apimachinery/pkg/runtime"},{"range":{"start":{"line":33,"character":1},"end":{"line":33,"character":43}},"target":"https://godoc.org/k8s.io/cli-runtime/pkg/genericclioptions"},{"range":{"start":{"line":34,"character":1},"end":{"line":34,"character":24}},"target":"https://godoc.org/k8s.io/client-go/rest"},{"range":{"start":{"line":35,"character":1},"end":{"line":35,"character":38}},"target":"https://godoc.org/k8s.io/kubectl/pkg/cmd/util"},{"range":{"start":{"line":36,"character":1},"end":{"line":36,"character":40}},"target":"https://godoc.org/k8s.io/kubectl/pkg/polymorphichelpers"},{"range":{"start":{"line":37,"character":1},"end":{"line":37,"character":28}},"target":"https://godoc.org/k8s.io/kubectl/pkg/scheme"},{"range":{"start":{"line":38,"character":1},"end":{"line":38,"character":26}},"target":"https://godoc.org/k8s.io/kubectl/pkg/util"},{"range":{"start":{"line":39,"character":1},"end":{"line":39,"character":31}},"target":"https://godoc.org/k8s.io/kubectl/pkg/util/i18n"},{"range":{"start":{"line":40,"character":1},"end":{"line":40,"character":36}},"target":"https://godoc.org/k8s.io/kubectl/pkg/util/templates"},{"range":{"start":{"line":7,"character":4},"end":{"line":7,"character":46}},"target":"http://www.apache.org/licenses/LICENSE-2.0"}]

[Trace - 4:07:59 PM] Sending notification 'textDocument/documentLink' in 2725ms.
Params: {"textDocument":{"uri":"file://$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go"}}

[Trace - 4:07:59 PM] Received response 'textDocument/hover - (4)' in 0ms.
Params: {"contents":{"kind":"markdown","value":"go\nfunc (rest.ResponseWrapper).StreamWithPing(ctx context.Context, pingInterval time.Duration) (io.ReadCloser, error)\n"},"range":{"start":{"line":380,"character":28},"end":{"line":380,"character":42}}}

[Trace - 4:07:59 PM] Sending notification 'textDocument/hover' in 2057ms.
Params: {"textDocument":{"uri":"file://$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go"},"position":{"line":380,"character":42}}

[Trace - 4:07:59 PM] Sending notification '$/cancelRequest' in 2048ms.
Params: {"id":4}

[Trace - 4:07:59 PM] Received response 'textDocument/hover - (5)' in 0ms.
Params: {"contents":{"kind":"markdown","value":"go\nfunc (rest.ResponseWrapper).StreamWithPing(ctx context.Context, pingInterval time.Duration) (io.ReadCloser, error)\n"},"range":{"start":{"line":380,"character":28},"end":{"line":380,"character":42}}}

[Trace - 4:07:59 PM] Sending notification 'textDocument/hover' in 1797ms.
Params: {"textDocument":{"uri":"file://$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go"},"position":{"line":380,"character":41}}

[Trace - 4:07:59 PM] Received notification 'textDocument/publishDiagnostics' in 0ms.
Params: {"uri":"file://$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go","diagnostics":[]}

[Trace - 4:07:59 PM] Received response 'textDocument/hover - (6)' in 0ms.
Params: {"contents":{"kind":"markdown","value":"go\nfunc (rest.ResponseWrapper).StreamWithPing(ctx context.Context, pingInterval time.Duration) (io.ReadCloser, error)\n"},"range":{"start":{"line":380,"character":28},"end":{"line":380,"character":42}}}

[Trace - 4:07:59 PM] Sending notification 'textDocument/hover' in 1ms.
Params: {"textDocument":{"uri":"file://$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go"},"position":{"line":380,"character":41}}

[Trace - 4:08:01 PM] Received response 'textDocument/codeAction - (7)' in 0ms.
Params: [{"title":"Organize Imports","kind":"source.organizeImports","edit":{"changes":{"file://$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go":[]}}}]

[Trace - 4:08:01 PM] Sending notification 'textDocument/codeAction' in 12ms.
Params: {"textDocument":{"uri":"file://$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go"},"range":{"start":{"line":380,"character":41},"end":{"line":380,"character":41}},"context":{"diagnostics":[]}}

[Trace - 4:08:02 PM] Received response 'textDocument/definition - (8)' in 0ms.
Params: [{"uri":"file://$GOPATH/src/kubernetes/staging/src/k8s.io/client-go/rest/request.go","range":{"start":{"line":66,"character":1},"end":{"line":66,"character":15}}}]

[Trace - 4:08:02 PM] Sending notification 'textDocument/definition' in 20ms.
Params: {"textDocument":{"uri":"file://$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go"},"position":{"line":380,"character":41}}

[Trace - 4:08:02 PM] Sending notification 'textDocument/didOpen' in 3ms.
Params: {"textDocument":{"uri":"file://$GOPATH/src/kubernetes/staging/src/k8s.io/client-go/rest/request.go","languageId":"go","version":1,"text":"/\nCopyright 2014 The Kubernetes Authors.\n\nLicensed under the Apache License, Version 2.0 (the "License");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an "AS IS" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n/\n\npackage rest\n\nimport (\n\t"bytes"\n\t"context"\n\t"encoding/hex"\n\t"fmt"\n\t"io"\n\t"io/ioutil"\n\t"mime"\n\t"net/http"\n\t"net/url"\n\t"path"\n\t"reflect"\n\t"strconv"\n\t"strings"\n\t"time"\n\n\t"golang.org/x/net/http2"\n\t"k8s.io/apimachinery/pkg/api/errors"\n\tmetav1 "k8s.io/apimachinery/pkg/apis/meta/v1"\n\t"k8s.io/apimachinery/pkg/runtime"\n\t"k8s.io/apimachinery/pkg/runtime/schema"\n\t"k8s.io/apimachinery/pkg/runtime/serializer/streaming"\n\t"k8s.io/apimachinery/pkg/util/net"\n\t"k8s.io/apimachinery/pkg/watch"\n\trestclientwatch "k8s.io/client-go/rest/watch"\n\t"k8s.io/client-go/tools/metrics"\n\t"k8s.io/client-go/util/flowcontrol"\n\t"k8s.io/client-go/util/keepalive"\n\tkeepalivehttp "k8s.io/client-go/util/keepalive/http"\n\t"k8s.io/klog"\n)\n\nvar (\n\t// longThrottleLatency defines threshold for logging requests. All requests being\n\t// throttle for more than longThrottleLatency will be logged.\n\tlongThrottleLatency = 50 * time.Millisecond\n)\n\n// HTTPClient is an interface for testing a request object.\ntype HTTPClient interface {\n\tDo(req *http.Request) (*http.Response, error)\n}\n\n// ResponseWrapper is an interface for getting a response.\n// The response may be either accessed as a raw data (the whole output is put into memory) or as a stream.\ntype ResponseWrapper interface {\n\tDoRaw() ([]byte, error)\n\tStream() (io.ReadCloser, error)\n\tStreamWithPing(ctx context.Context, pingInterval time.Duration) (io.ReadCloser, error)\n}\n\n// RequestConstructionError is returned when there's an error assembling a request.\ntype RequestConstructionError struct {\n\tErr error\n}\n\n// Error returns a textual description of 'r'.\nfunc (r *RequestConstructionError) Error() string {\n\treturn fmt.Sprintf("request construction error: '%v'", r.Err)\n}\n\n// Request allows for building up a request to a server in a chained fashion.\n// Any errors are stored until the end of your call, so you only have to\n// check once.\ntype Request struct {\n\t// required\n\tclient HTTPClient\n\tverb string\n\n\tbaseURL *url.URL\n\tcontent ContentConfig\n\tserializers Serializers\n\n\t// generic components accessible via method setters\n\tpathPrefix string\n\tsubpath string\n\tparams url.Values\n\theaders http.Header\n\n\t// structural elements of the request that are part of the Kubernetes API conventions\n\tnamespace string\n\tnamespaceSet bool\n\tresource string\n\tresourceName string\n\tsubresource string\n\ttimeout time.Duration\n\n\t// output\n\terr error\n\tbody io.Reader\n\n\t// This is only used for per-request timeouts, deadlines, and cancellations.\n\tctx context.Context\n\n\tbackoffMgr BackoffManager\n\tthrottle flowcontrol.RateLimiter\n}\n\n// NewRequest creates a new request helper object for accessing runtime.Objects on a server.\nfunc NewRequest(client HTTPClient, verb string, baseURL *url.URL, versionedAPIPath string, content ContentConfig, serializers Serializers, backoff BackoffManager, throttle flowcontrol.RateLimiter, timeout time.Duration) *Request {\n\tif backoff == nil {\n\t\tklog.V(2).Infof("Not implementing request backoff strategy.")\n\t\tbackoff = &NoBackoff{}\n\t}\n\n\tpathPrefix := "/"\n\tif baseURL != nil {\n\t\tpathPrefix = path.Join(pathPrefix, baseURL.Path)\n\t}\n\tr := &Request{\n\t\tclient: client,\n\t\tverb: verb,\n\t\tbaseURL: baseURL,\n\t\tpathPrefix: path.Join(pathPrefix, versionedAPIPath),\n\t\tcontent: content,\n\t\tserializers: serializers,\n\t\tbackoffMgr: backoff,\n\t\tthrottle: throttle,\n\t\ttimeout: timeout,\n\t}\n\tswitch {\n\tcase len(content.AcceptContentTypes) > 0:\n\t\tr.SetHeader("Accept", content.AcceptContentTypes)\n\tcase len(content.ContentType) > 0:\n\t\tr.SetHeader("Accept", content.ContentType+", /")\n\t}\n\treturn r\n}\n\n// Prefix adds segments to the relative beginning to the request path. These\n// items will be placed before the optional Namespace, Resource, or Name sections.\n// Setting AbsPath will clear any previously set Prefix segments\nfunc (r *Request) Prefix(segments ...string) *Request {\n\tif r.err != nil {\n\t\treturn r\n\t}\n\tr.pathPrefix = path.Join(r.pathPrefix, path.Join(segments...))\n\treturn r\n}\n\n// Suffix appends segments to the end of the path. These items will be placed after the prefix and optional\n// Namespace, Resource, or Name sections.\nfunc (r *Request) Suffix(segments ...string) *Request {\n\tif r.err != nil {\n\t\treturn r\n\t}\n\tr.subpath = path.Join(r.subpath, path.Join(segments...))\n\treturn r\n}\n\n// Resource sets the resource to access (/[ns//])\nfunc (r *Request) Resource(resource string) *Request {\n\tif r.err != nil {\n\t\treturn r\n\t}\n\tif len(r.resource) != 0 {\n\t\tr.err = fmt.Errorf("resource already set to %q, cannot change to %q", r.resource, resource)\n\t\treturn r\n\t}\n\tif msgs := IsValidPathSegmentName(resource); len(msgs) != 0 {\n\t\tr.err = fmt.Errorf("invalid resource %q: %v", resource, msgs)\n\t\treturn r\n\t}\n\tr.resource = resource\n\treturn r\n}\n\n// BackOff sets the request's backoff manager to the one specified,\n// or defaults to the stub implementation if nil is provided\nfunc (r *Request) BackOff(manager BackoffManager) *Request {\n\tif manager == nil {\n\t\tr.backoffMgr = &NoBackoff{}\n\t\treturn r\n\t}\n\n\tr.backoffMgr = manager\n\treturn r\n}\n\n// Throttle receives a rate-limiter and sets or replaces an existing request limiter\nfunc (r *Request) Throttle(limiter flowcontrol.RateLimiter) *Request {\n\tr.throttle = limiter\n\treturn r\n}\n\n// SubResource sets a sub-resource path which can be multiple segments after the resource\n// name but before the suffix.\nfunc (r *Request) SubResource(subresources ...string) *Request {\n\tif r.err != nil {\n\t\treturn r\n\t}\n\tsubresource := path.Join(subresources...)\n\tif len(r.subresource) != 0 {\n\t\tr.err = fmt.Errorf("subresource already set to %q, cannot change to %q", r.resource, subresource)\n\t\treturn r\n\t}\n\tfor _, s := range subresources {\n\t\tif msgs := IsValidPathSegmentName(s); len(msgs) != 0 {\n\t\t\tr.err = fmt.Errorf("invalid subresource %q: %v", s, msgs)\n\t\t\treturn r\n\t\t}\n\t}\n\tr.subresource = subresource\n\treturn r\n}\n\n// Name sets the name of a resource to access (/[ns//])\nfunc (r *Request) Name(resourceName string) *Request {\n\tif r.err != nil {\n\t\treturn r\n\t}\n\tif len(resourceName) == 0 {\n\t\tr.err = fmt.Errorf("resource name may not be empty")\n\t\treturn r\n\t}\n\tif len(r.resourceName) != 0 {\n\t\tr.err = fmt.Errorf("resource name already set to %q, cannot change to %q", r.resourceName, resourceName)\n\t\treturn r\n\t}\n\tif msgs := IsValidPathSegmentName(resourceName); len(msgs) != 0 {\n\t\tr.err = fmt.Errorf("invalid resource name %q: %v", resourceName, msgs)\n\t\treturn r\n\t}\n\tr.resourceName = resourceName\n\treturn r\n}\n\n// Namespace applies the namespace scope to a request (/[ns//])\nfunc (r *Request) Namespace(namespace string) *Request {\n\tif r.err != nil {\n\t\treturn r\n\t}\n\tif r.namespaceSet {\n\t\tr.err = fmt.Errorf("namespace already set to %q, cannot change to %q", r.namespace, namespace)\n\t\treturn r\n\t}\n\tif msgs := IsValidPathSegmentName(namespace); len(msgs) != 0 {\n\t\tr.err = fmt.Errorf("invalid namespace %q: %v", namespace, msgs)\n\t\treturn r\n\t}\n\tr.namespaceSet = true\n\tr.namespace = namespace\n\treturn r\n}\n\n// NamespaceIfScoped is a convenience function to set a namespace if scoped is true\nfunc (r *Request) NamespaceIfScoped(namespace string, scoped bool) *Request {\n\tif scoped {\n\t\treturn r.Namespace(namespace)\n\t}\n\treturn r\n}\n\n// AbsPath overwrites an existing path with the segments provided. Trailing slashes are preserved\n// when a single segment is passed.\nfunc (r *Request) AbsPath(segments ...string) *Request {\n\tif r.err != nil {\n\t\treturn r\n\t}\n\tr.pathPrefix = path.Join(r.baseURL.Path, path.Join(segments...))\n\tif len(segments) == 1 && (len(r.baseURL.Path) > 1 || len(segments[0]) > 1) && strings.HasSuffix(segments[0], "/") {\n\t\t// preserve any trailing slashes for legacy behavior\n\t\tr.pathPrefix += "/"\n\t}\n\treturn r\n}\n\n// RequestURI overwrites existing path and parameters with the value of the provided server relative\n// URI.\nfunc (r *Request) RequestURI(uri string) *Request {\n\tif r.err != nil {\n\t\treturn r\n\t}\n\tlocator, err := url.Parse(uri)\n\tif err != nil {\n\t\tr.err = err\n\t\treturn r\n\t}\n\tr.pathPrefix = locator.Path\n\tif len(locator.Query()) > 0 {\n\t\tif r.params == nil {\n\t\t\tr.params = make(url.Values)\n\t\t}\n\t\tfor k, v := range locator.Query() {\n\t\t\tr.params[k] = v\n\t\t}\n\t}\n\treturn r\n}\n\n// Param creates a query parameter with the given string value.\nfunc (r *Request) Param(paramName, s string) *Request {\n\tif r.err != nil {\n\t\treturn r\n\t}\n\treturn r.setParam(paramName, s)\n}\n\n// VersionedParams will take the provided object, serialize it to a map[string][]string using the\n// implicit RESTClient API version and the default parameter codec, and then add those as parameters\n// to the request. Use this to provide versioned query parameters from client libraries.\n// VersionedParams will not write query parameters that have omitempty set and are empty. If a\n// parameter has already been set it is appended to (Params and VersionedParams are additive).\nfunc (r *Request) VersionedParams(obj runtime.Object, codec runtime.ParameterCodec) *Request {\n\treturn r.SpecificallyVersionedParams(obj, codec, *r.content.GroupVersion)\n}\n\nfunc (r *Request) SpecificallyVersionedParams(obj runtime.Object, codec runtime.ParameterCodec, version schema.GroupVersion) *Request {\n\tif r.err != nil {\n\t\treturn r\n\t}\n\tparams, err := codec.EncodeParameters(obj, version)\n\tif err != nil {\n\t\tr.err = err\n\t\treturn r\n\t}\n\tfor k, v := range params {\n\t\tif r.params == nil {\n\t\t\tr.params = make(url.Values)\n\t\t}\n\t\tr.params[k] = append(r.params[k], v...)\n\t}\n\treturn r\n}\n\nfunc (r *Request) setParam(paramName, value string) *Request {\n\tif r.params == nil {\n\t\tr.params = make(url.Values)\n\t}\n\tr.params[paramName] = append(r.params[paramName], value)\n\treturn r\n}\n\nfunc (r *Request) SetHeader(key string, values ...string) *Request {\n\tif r.headers == nil {\n\t\tr.headers = http.Header{}\n\t}\n\tr.headers.Del(key)\n\tfor _, value := range values {\n\t\tr.headers.Add(key, value)\n\t}\n\treturn r\n}\n\n// Timeout makes the request use the given duration as an overall timeout for the\n// request. Additionally, if set passes the value as "timeout" parameter in URL.\nfunc (r *Request) Timeout(d time.Duration) *Request {\n\tif r.err != nil {\n\t\treturn r\n\t}\n\tr.timeout = d\n\treturn r\n}\n\n// Body makes the request use obj as the body. Optional.\n// If obj is a string, try to read a file of that name.\n// If obj is a []byte, send it directly.\n// If obj is an io.Reader, use it directly.\n// If obj is a runtime.Object, marshal it correctly, and set Content-Type header.\n// If obj is a runtime.Object and nil, do nothing.\n// Otherwise, set an error.\nfunc (r *Request) Body(obj interface{}) *Request {\n\tif r.err != nil {\n\t\treturn r\n\t}\n\tswitch t := obj.(type) {\n\tcase string:\n\t\tdata, err := ioutil.ReadFile(t)\n\t\tif err != nil {\n\t\t\tr.err = err\n\t\t\treturn r\n\t\t}\n\t\tglogBody("Request Body", data)\n\t\tr.body = bytes.NewReader(data)\n\tcase []byte:\n\t\tglogBody("Request Body", t)\n\t\tr.body = bytes.NewReader(t)\n\tcase io.Reader:\n\t\tr.body = t\n\tcase runtime.Object:\n\t\t// callers may pass typed interface pointers, therefore we must check nil with reflection\n\t\tif reflect.ValueOf(t).IsNil() {\n\t\t\treturn r\n\t\t}\n\t\tdata, err := runtime.Encode(r.serializers.Encoder, t)\n\t\tif err != nil {\n\t\t\tr.err = err\n\t\t\treturn r\n\t\t}\n\t\tglogBody("Request Body", data)\n\t\tr.body = bytes.NewReader(data)\n\t\tr.SetHeader("Content-Type", r.content.ContentType)\n\tdefault:\n\t\tr.err = fmt.Errorf("unknown type used for body: %+v", obj)\n\t}\n\treturn r\n}\n\n// Context adds a context to the request. Contexts are only used for\n// timeouts, deadlines, and cancellations.\nfunc (r *Request) Context(ctx context.Context) *Request {\n\tr.ctx = ctx\n\treturn r\n}\n\n// URL returns the current working URL.\nfunc (r *Request) URL() url.URL {\n\tp := r.pathPrefix\n\tif r.namespaceSet && len(r.namespace) > 0 {\n\t\tp = path.Join(p, "namespaces", r.namespace)\n\t}\n\tif len(r.resource) != 0 {\n\t\tp = path.Join(p, strings.ToLower(r.resource))\n\t}\n\t// Join trims trailing slashes, so preserve r.pathPrefix's trailing slash for backwards compatibility if nothing was changed\n\tif len(r.resourceName) != 0 || len(r.subpath) != 0 || len(r.subresource) != 0 {\n\t\tp = path.Join(p, r.resourceName, r.subresource, r.subpath)\n\t}\n\n\tfinalURL := &url.URL{}\n\tif r.baseURL != nil {\n\t\tfinalURL = *r.baseURL\n\t}\n\tfinalURL.Path = p\n\n\tquery := url.Values{}\n\tfor key, values := range r.params {\n\t\tfor , value := range values {\n\t\t\tquery.Add(key, value)\n\t\t}\n\t}\n\n\t// timeout is handled specially here.\n\tif r.timeout != 0 {\n\t\tquery.Set("timeout", r.timeout.String())\n\t}\n\tfinalURL.RawQuery = query.Encode()\n\treturn finalURL\n}\n\n// finalURLTemplate is similar to URL(), but will make all specific parameter values equal\n// - instead of name or namespace, "{name}" and "{namespace}" will be used, and all query\n// parameters will be reset. This creates a copy of the url so as not to change the\n// underlying object.\nfunc (r Request) finalURLTemplate() url.URL {\n\tnewParams := url.Values{}\n\tv := []string{"{value}"}\n\tfor k := range r.params {\n\t\tnewParams[k] = v\n\t}\n\tr.params = newParams\n\turl := r.URL()\n\tsegments := strings.Split(r.URL().Path, "/")\n\tgroupIndex := 0\n\tindex := 0\n\tif r.URL() != nil && r.baseURL != nil && strings.Contains(r.URL().Path, r.baseURL.Path) {\n\t\tgroupIndex += len(strings.Split(r.baseURL.Path, "/"))\n\t}\n\tif groupIndex >= len(segments) {\n\t\treturn *url\n\t}\n\n\tconst CoreGroupPrefix = "api"\n\tconst NamedGroupPrefix = "apis"\n\tisCoreGroup := segments[groupIndex] == CoreGroupPrefix\n\tisNamedGroup := segments[groupIndex] == NamedGroupPrefix\n\tif isCoreGroup {\n\t\t// checking the case of core group with /api/v1/... format\n\t\tindex = groupIndex + 2\n\t} else if isNamedGroup {\n\t\t// checking the case of named group with /apis/apps/v1/... format\n\t\tindex = groupIndex + 3\n\t} else {\n\t\t// this should not happen that the only two possibilities are /api... and /apis..., just want to put an\n\t\t// outlet here in case more API groups are added in future if ever possible:\n\t\t// https://kubernetes.io/docs/concepts/overview/kubernetes-api/#api-groups\n\t\t// if a wrong API groups name is encountered, return the {prefix} for url.Path\n\t\turl.Path = "/{prefix}"\n\t\turl.RawQuery = ""\n\t\treturn *url\n\t}\n\t//switch segLength := len(segments) - index; segLength {\n\tswitch {\n\t// case len(segments) - index == 1:\n\t// resource (with no name) do nothing\n\tcase len(segments)-index == 2:\n\t\t// /$RESOURCE/$NAME: replace $NAME with {name}\n\t\tsegments[index+1] = "{name}"\n\tcase len(segments)-index == 3:\n\t\tif segments[index+2] == "finalize" || segments[index+2] == "status" {\n\t\t\t// /$RESOURCE/$NAME/$SUBRESOURCE: replace $NAME with {name}\n\t\t\tsegments[index+1] = "{name}"\n\t\t} else {\n\t\t\t// /namespace/$NAMESPACE/$RESOURCE: replace $NAMESPACE with {namespace}\n\t\t\tsegments[index+1] = "{namespace}"\n\t\t}\n\tcase len(segments)-index >= 4:\n\t\tsegments[index+1] = "{namespace}"\n\t\t// /namespace/$NAMESPACE/$RESOURCE/$NAME: replace $NAMESPACE with {namespace}, $NAME with {name}\n\t\tif segments[index+3] != "finalize" && segments[index+3] != "status" {\n\t\t\t// /$RESOURCE/$NAME/$SUBRESOURCE: replace $NAME with {name}\n\t\t\tsegments[index+3] = "{name}"\n\t\t}\n\t}\n\turl.Path = path.Join(segments...)\n\treturn *url\n}\n\nfunc (r *Request) tryThrottle() error {\n\tif r.throttle == nil {\n\t\treturn nil\n\t}\n\n\tnow := time.Now()\n\tvar err error\n\tif r.ctx != nil {\n\t\terr = r.throttle.Wait(r.ctx)\n\t} else {\n\t\tr.throttle.Accept()\n\t}\n\n\tif latency := time.Since(now); latency > longThrottleLatency {\n\t\tklog.V(4).Infof("Throttling request took %v, request: %s:%s", latency, r.verb, r.URL().String())\n\t}\n\n\treturn err\n}\n\n// Watch attempts to begin watching the requested location.\n// Returns a watch.Interface, or an error.\nfunc (r *Request) Watch() (watch.Interface, error) {\n\treturn r.WatchWithSpecificDecoders(\n\t\tfunc(body io.ReadCloser) streaming.Decoder {\n\t\t\tframer := r.serializers.Framer.NewFrameReader(body)\n\t\t\treturn streaming.NewDecoder(framer, r.serializers.StreamingSerializer)\n\t\t},\n\t\tr.serializers.Decoder,\n\t)\n}\n\n// WatchWithSpecificDecoders attempts to begin watching the requested location with a different decoder.\n// Turns out that you want one "standard" decoder for the watch event and one "personal" decoder for the content\n// Returns a watch.Interface, or an error.\nfunc (r *Request) WatchWithSpecificDecoders(wrapperDecoderFn func(io.ReadCloser) streaming.Decoder, embeddedDecoder runtime.Decoder) (watch.Interface, error) {\n\t// We specifically don't want to rate limit watches, so we\n\t// don't use r.throttle here.\n\tif r.err != nil {\n\t\treturn nil, r.err\n\t}\n\tif r.serializers.Framer == nil {\n\t\treturn nil, fmt.Errorf("watching resources is not possible with this client (content-type: %s)", r.content.ContentType)\n\t}\n\n\turl := r.URL().String()\n\treq, err := http.NewRequest(r.verb, url, r.body)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif r.ctx != nil {\n\t\treq = req.WithContext(r.ctx)\n\t}\n\treq.Header = r.headers\n\tclient := r.client\n\tif client == nil {\n\t\tclient = http.DefaultClient\n\t}\n\tr.backoffMgr.Sleep(r.backoffMgr.CalculateBackoff(r.URL()))\n\tresp, err := client.Do(req)\n\tupdateURLMetrics(r, resp, err)\n\tif r.baseURL != nil {\n\t\tif err != nil {\n\t\t\tr.backoffMgr.UpdateBackoff(r.baseURL, err, 0)\n\t\t} else {\n\t\t\tr.backoffMgr.UpdateBackoff(r.baseURL, err, resp.StatusCode)\n\t\t}\n\t}\n\tif err != nil {\n\t\t// The watch stream mechanism handles many common partial data errors, so closed\n\t\t// connections can be retried in many cases.\n\t\tif net.IsProbableEOF(err) {\n\t\t\treturn watch.NewEmptyWatch(), nil\n\t\t}\n\t\treturn nil, err\n\t}\n\tif resp.StatusCode != http.StatusOK {\n\t\tdefer resp.Body.Close()\n\t\tif result := r.transformResponse(resp, req); result.err != nil {\n\t\t\treturn nil, result.err\n\t\t}\n\t\treturn nil, fmt.Errorf("for request %s, got status: %v", url, resp.StatusCode)\n\t}\n\twrapperDecoder := wrapperDecoderFn(resp.Body)\n\treturn watch.NewStreamWatcher(\n\t\trestclientwatch.NewDecoder(wrapperDecoder, embeddedDecoder),\n\t\t// use 500 to indicate that the cause of the error is unknown - other error codes\n\t\t// are more specific to HTTP interactions, and set a reason\n\t\terrors.NewClientErrorReporter(http.StatusInternalServerError, r.verb, "ClientWatchDecoding"),\n\t), nil\n}\n\n// updateURLMetrics is a convenience function for pushing metrics.\n// It also handles corner cases for incomplete/invalid request data.\nfunc updateURLMetrics(req *Request, resp *http.Response, err error) {\n\turl := "none"\n\tif req.baseURL != nil {\n\t\turl = req.baseURL.Host\n\t}\n\n\t// Errors can be arbitrary strings. Unbound label cardinality is not suitable for a metric\n\t// system so we just report them as <error>.\n\tif err != nil {\n\t\tmetrics.RequestResult.Increment("", req.verb, url)\n\t} else {\n\t\t//Metrics for failure codes\n\t\tmetrics.RequestResult.Increment(strconv.Itoa(resp.StatusCode), req.verb, url)\n\t}\n}\n\n// Stream formats and executes the request, and offers streaming of the response.\n// Returns io.ReadCloser which could be used for streaming of the response, or an error\n// Any non-2xx http status code causes an error. If we get a non-2xx code, we try to convert the body into an APIStatus object.\n// If we can, we return that as an error. Otherwise, we create an error that lists the http status and the content of the response.\nfunc (r *Request) Stream() (io.ReadCloser, error) {\n\tif r.err != nil {\n\t\treturn nil, r.err\n\t}\n\n\tif err := r.tryThrottle(); err != nil {\n\t\treturn nil, err\n\t}\n\n\turl := r.URL().String()\n\treq, err := http.NewRequest(r.verb, url, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif r.body != nil {\n\t\treq.Body = ioutil.NopCloser(r.body)\n\t}\n\tif r.ctx != nil {\n\t\treq = req.WithContext(r.ctx)\n\t}\n\treq.Header = r.headers\n\tclient := r.client\n\tif client == nil {\n\t\tclient = http.DefaultClient\n\t}\n\tr.backoffMgr.Sleep(r.backoffMgr.CalculateBackoff(r.URL()))\n\tresp, err := client.Do(req)\n\tupdateURLMetrics(r, resp, err)\n\tif r.baseURL != nil {\n\t\tif err != nil {\n\t\t\tr.backoffMgr.UpdateBackoff(r.URL(), err, 0)\n\t\t} else {\n\t\t\tr.backoffMgr.UpdateBackoff(r.URL(), err, resp.StatusCode)\n\t\t}\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tswitch {\n\tcase (resp.StatusCode >= 200) && (resp.StatusCode < 300):\n\t\treturn resp.Body, nil\n\n\tdefault:\n\t\t// ensure we close the body before returning the error\n\t\tdefer resp.Body.Close()\n\n\t\tresult := r.transformResponse(resp, req)\n\t\terr := result.Error()\n\t\tif err == nil {\n\t\t\terr = fmt.Errorf("%d while accessing %v: %s", result.statusCode, url, string(result.body))\n\t\t}\n\t\treturn nil, err\n\t}\n}\n\nfunc (r *Request) StreamWithPing(ctx context.Context, pingInterval time.Duration) (io.ReadCloser, error) {\n\tif ctx != nil && pingInterval > 0 {\n\t\tclient := r.client\n\t\tif client == nil {\n\t\t\tclient = http.DefaultClient\n\t\t}\n\t\tkeepalive.KeepAliveWithPinger(ctx, keepalivehttp.NewHttpPinger(client.(*http.Client), r.URL().Scheme, r.URL().Host), pingInterval)\n\t}\n\treturn r.Stream()\n}\n\n// request connects to the server and invokes the provided function when a server response is\n// received. It handles retry behavior and up front validation of requests. It will invoke\n// fn at most once. It will return an error if a problem occurred prior to connecting to the\n// server - the provided function is responsible for handling server errors.\nfunc (r *Request) request(fn func(*http.Request, *http.Response)) error {\n\t//Metrics for total request latency\n\tstart := time.Now()\n\tdefer func() {\n\t\tmetrics.RequestLatency.Observe(r.verb, r.finalURLTemplate(), time.Since(start))\n\t}()\n\n\tif r.err != nil {\n\t\tklog.V(4).Infof("Error in request: %v", r.err)\n\t\treturn r.err\n\t}\n\n\t// TODO: added to catch programmer errors (invoking operations with an object with an empty namespace)\n\tif (r.verb == "GET" || r.verb == "PUT" || r.verb == "DELETE") && r.namespaceSet && len(r.resourceName) > 0 && len(r.namespace) == 0 {\n\t\treturn fmt.Errorf("an empty namespace may not be set when a resource name is provided")\n\t}\n\tif (r.verb == "POST") && r.namespaceSet && len(r.namespace) == 0 {\n\t\treturn fmt.Errorf("an empty namespace may not be set during creation")\n\t}\n\n\tclient := r.client\n\tif client == nil {\n\t\tclient = http.DefaultClient\n\t}\n\n\t// Right now we make about ten retry attempts if we get a Retry-After response.\n\tmaxRetries := 10\n\tretries := 0\n\tfor {\n\t\turl := r.URL().String()\n\t\treq, err := http.NewRequest(r.verb, url, r.body)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif r.timeout > 0 {\n\t\t\tif r.ctx == nil {\n\t\t\t\tr.ctx = context.Background()\n\t\t\t}\n\t\t\tvar cancelFn context.CancelFunc\n\t\t\tr.ctx, cancelFn = context.WithTimeout(r.ctx, r.timeout)\n\t\t\tdefer cancelFn()\n\t\t}\n\t\tif r.ctx != nil {\n\t\t\treq = req.WithContext(r.ctx)\n\t\t}\n\t\treq.Header = r.headers\n\n\t\tr.backoffMgr.Sleep(r.backoffMgr.CalculateBackoff(r.URL()))\n\t\tif retries > 0 {\n\t\t\t// We are retrying the request that we already send to apiserver\n\t\t\t// at least once before.\n\t\t\t// This request should also be throttled with the client-internal throttler.\n\t\t\tif err := r.tryThrottle(); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tresp, err := client.Do(req)\n\t\tupdateURLMetrics(r, resp, err)\n\t\tif err != nil {\n\t\t\tr.backoffMgr.UpdateBackoff(r.URL(), err, 0)\n\t\t} else {\n\t\t\tr.backoffMgr.UpdateBackoff(r.URL(), err, resp.StatusCode)\n\t\t}\n\t\tif err != nil {\n\t\t\t// "Connection reset by peer" is usually a transient error.\n\t\t\t// Thus in case of "GET" operations, we simply retry it.\n\t\t\t// We are not automatically retrying "write" operations, as\n\t\t\t// they are not idempotent.\n\t\t\tif !net.IsConnectionReset(err) || r.verb != "GET" {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\t// For the purpose of retry, we set the artificial "retry-after" response.\n\t\t\t// TODO: Should we clean the original response if it exists?\n\t\t\tresp = &http.Response{\n\t\t\t\tStatusCode: http.StatusInternalServerError,\n\t\t\t\tHeader: http.Header{"Retry-After": []string{"1"}},\n\t\t\t\tBody: ioutil.NopCloser(bytes.NewReader([]byte{})),\n\t\t\t}\n\t\t}\n\n\t\tdone := func() bool {\n\t\t\t// Ensure the response body is fully read and closed\n\t\t\t// before we reconnect, so that we reuse the same TCP\n\t\t\t// connection.\n\t\t\tdefer func() {\n\t\t\t\tconst maxBodySlurpSize = 2 << 10\n\t\t\t\tif resp.ContentLength <= maxBodySlurpSize {\n\t\t\t\t\tio.Copy(ioutil.Discard, &io.LimitedReader{R: resp.Body, N: maxBodySlurpSize})\n\t\t\t\t}\n\t\t\t\tresp.Body.Close()\n\t\t\t}()\n\n\t\t\tretries++\n\t\t\tif seconds, wait := checkWait(resp); wait && retries < maxRetries {\n\t\t\t\tif seeker, ok := r.body.(io.Seeker); ok && r.body != nil {\n\t\t\t\t\t, err := seeker.Seek(0, 0)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tklog.V(4).Infof("Could not retry request, can't Seek() back to beginning of body for %T", r.body)\n\t\t\t\t\t\tfn(req, resp)\n\t\t\t\t\t\treturn true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tklog.V(4).Infof("Got a Retry-After %ds response for attempt %d to %v", seconds, retries, url)\n\t\t\t\tr.backoffMgr.Sleep(time.Duration(seconds) * time.Second)\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tfn(req, resp)\n\t\t\treturn true\n\t\t}()\n\t\tif done {\n\t\t\treturn nil\n\t\t}\n\t}\n}\n\n// Do formats and executes the request. Returns a Result object for easy response\n// processing.\n//\n// Error type:\n// * If the request can't be constructed, or an error happened earlier while building its\n// arguments: *RequestConstructionError\n// * If the server responds with a status: *errors.StatusError or *errors.UnexpectedObjectError\n// * http.Client.Do errors are returned directly.\nfunc (r *Request) Do() Result {\n\tif err := r.tryThrottle(); err != nil {\n\t\treturn Result{err: err}\n\t}\n\n\tvar result Result\n\terr := r.request(func(req *http.Request, resp *http.Response) {\n\t\tresult = r.transformResponse(resp, req)\n\t})\n\tif err != nil {\n\t\treturn Result{err: err}\n\t}\n\treturn result\n}\n\n// DoRaw executes the request but does not process the response body.\nfunc (r *Request) DoRaw() ([]byte, error) {\n\tif err := r.tryThrottle(); err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar result Result\n\terr := r.request(func(req *http.Request, resp *http.Response) {\n\t\tresult.body, result.err = ioutil.ReadAll(resp.Body)\n\t\tglogBody("Response Body", result.body)\n\t\tif resp.StatusCode < http.StatusOK || resp.StatusCode > http.StatusPartialContent {\n\t\t\tresult.err = r.transformUnstructuredResponseError(resp, req, result.body)\n\t\t}\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn result.body, result.err\n}\n\n// transformResponse converts an API response into a structured API object\nfunc (r *Request) transformResponse(resp *http.Response, req *http.Request) Result {\n\tvar body []byte\n\tif resp.Body != nil {\n\t\tdata, err := ioutil.ReadAll(resp.Body)\n\t\tswitch err.(type) {\n\t\tcase nil:\n\t\t\tbody = data\n\t\tcase http2.StreamError:\n\t\t\t// This is trying to catch the scenario that the server may close the connection when sending the\n\t\t\t// response body. This can be caused by server timeout due to a slow network connection.\n\t\t\t// TODO: Add test for this. Steps may be:\n\t\t\t// 1. client-go (or kubectl) sends a GET request.\n\t\t\t// 2. Apiserver sends back the headers and then part of the body\n\t\t\t// 3. Apiserver closes connection.\n\t\t\t// 4. client-go should catch this and return an error.\n\t\t\tklog.V(2).Infof("Stream error %#v when reading response body, may be caused by closed connection.", err)\n\t\t\tstreamErr := fmt.Errorf("stream error when reading response body, may be caused by closed connection. Please retry. Original error: %v", err)\n\t\t\treturn Result{\n\t\t\t\terr: streamErr,\n\t\t\t}\n\t\tdefault:\n\t\t\tklog.Errorf("Unexpected error when reading response body: %v", err)\n\t\t\tunexpectedErr := fmt.Errorf("unexpected error when reading response body. Please retry. Original error: %v", err)\n\t\t\treturn Result{\n\t\t\t\terr: unexpectedErr,\n\t\t\t}\n\t\t}\n\t}\n\n\tglogBody("Response Body", body)\n\n\t// verify the content type is accurate\n\tcontentType := resp.Header.Get("Content-Type")\n\tdecoder := r.serializers.Decoder\n\tif len(contentType) > 0 && (decoder == nil || (len(r.content.ContentType) > 0 && contentType != r.content.ContentType)) {\n\t\tmediaType, params, err := mime.ParseMediaType(contentType)\n\t\tif err != nil {\n\t\t\treturn Result{err: errors.NewInternalError(err)}\n\t\t}\n\t\tdecoder, err = r.serializers.RenegotiatedDecoder(mediaType, params)\n\t\tif err != nil {\n\t\t\t// if we fail to negotiate a decoder, treat this as an unstructured error\n\t\t\tswitch {\n\t\t\tcase resp.StatusCode == http.StatusSwitchingProtocols:\n\t\t\t\t// no-op, we've been upgraded\n\t\t\tcase resp.StatusCode < http.StatusOK || resp.StatusCode > http.StatusPartialContent:\n\t\t\t\treturn Result{err: r.transformUnstructuredResponseError(resp, req, body)}\n\t\t\t}\n\t\t\treturn Result{\n\t\t\t\tbody: body,\n\t\t\t\tcontentType: contentType,\n\t\t\t\tstatusCode: resp.StatusCode,\n\t\t\t}\n\t\t}\n\t}\n\n\tswitch {\n\tcase resp.StatusCode == http.StatusSwitchingProtocols:\n\t\t// no-op, we've been upgraded\n\tcase resp.StatusCode < http.StatusOK || resp.StatusCode > http.StatusPartialContent:\n\t\t// calculate an unstructured error from the response which the Result object may use if the caller\n\t\t// did not return a structured error.\n\t\tretryAfter, _ := retryAfterSeconds(resp)\n\t\terr := r.newUnstructuredResponseError(body, isTextResponse(resp), resp.StatusCode, req.Method, retryAfter)\n\t\treturn Result{\n\t\t\tbody: body,\n\t\t\tcontentType: contentType,\n\t\t\tstatusCode: resp.StatusCode,\n\t\t\tdecoder: decoder,\n\t\t\terr: err,\n\t\t}\n\t}\n\n\treturn Result{\n\t\tbody: body,\n\t\tcontentType: contentType,\n\t\tstatusCode: resp.StatusCode,\n\t\tdecoder: decoder,\n\t}\n}\n\n// truncateBody decides if the body should be truncated, based on the glog Verbosity.\nfunc truncateBody(body string) string {\n\tmax := 0\n\tswitch {\n\tcase bool(klog.V(10)):\n\t\treturn body\n\tcase bool(klog.V(9)):\n\t\tmax = 10240\n\tcase bool(klog.V(8)):\n\t\tmax = 1024\n\t}\n\n\tif len(body) <= max {\n\t\treturn body\n\t}\n\n\treturn body[:max] + fmt.Sprintf(" [truncated %d chars]", len(body)-max)\n}\n\n// glogBody logs a body output that could be either JSON or protobuf. It explicitly guards against\n// allocating a new string for the body output unless necessary. Uses a simple heuristic to determine\n// whether the body is printable.\nfunc glogBody(prefix string, body []byte) {\n\tif klog.V(8) {\n\t\tif bytes.IndexFunc(body, func(r rune) bool {\n\t\t\treturn r < 0x0a\n\t\t}) != -1 {\n\t\t\tklog.Infof("%s:\n%s", prefix, truncateBody(hex.Dump(body)))\n\t\t} else {\n\t\t\tklog.Infof("%s: %s", prefix, truncateBody(string(body)))\n\t\t}\n\t}\n}\n\n// maxUnstructuredResponseTextBytes is an upper bound on how much output to include in the unstructured error.\nconst maxUnstructuredResponseTextBytes = 2048\n\n// transformUnstructuredResponseError handles an error from the server that is not in a structured form.\n// It is expected to transform any response that is not recognizable as a clear server sent error from the\n// K8S API using the information provided with the request. In practice, HTTP proxies and client libraries\n// introduce a level of uncertainty to the responses returned by servers that in common use result in\n// unexpected responses. The rough structure is:\n//\n// 1. Assume the server sends you something sane - JSON + well defined error objects + proper codes\n// - this is the happy path\n// - when you get this output, trust what the server sends\n// 2. Guard against empty fields / bodies in received JSON and attempt to cull sufficient info from them to\n// generate a reasonable facsimile of the original failure.\n// - Be sure to use a distinct error type or flag that allows a client to distinguish between this and error 1 above\n// 3. Handle true disconnect failures / completely malformed data by moving up to a more generic client error\n// 4. Distinguish between various connection failures like SSL certificates, timeouts, proxy errors, unexpected\n// initial contact, the presence of mismatched body contents from posted content types\n// - Give these a separate distinct error type and capture as much as possible of the original message\n//\n// TODO: introduce transformation of generic http.Client.Do() errors that separates 4.\nfunc (r *Request) transformUnstructuredResponseError(resp *http.Response, req *http.Request, body []byte) error {\n\tif body == nil && resp.Body != nil {\n\t\tif data, err := ioutil.ReadAll(&io.LimitedReader{R: resp.Body, N: maxUnstructuredResponseTextBytes}); err == nil {\n\t\t\tbody = data\n\t\t}\n\t}\n\tretryAfter, _ := retryAfterSeconds(resp)\n\treturn r.newUnstructuredResponseError(body, isTextResponse(resp), resp.StatusCode, req.Method, retryAfter)\n}\n\n// newUnstructuredResponseError instantiates the appropriate generic error for the provided input. It also logs the body.\nfunc (r *Request) newUnstructuredResponseError(body []byte, isTextResponse bool, statusCode int, method string, retryAfter int) error {\n\t// cap the amount of output we create\n\tif len(body) > maxUnstructuredResponseTextBytes {\n\t\tbody = body[:maxUnstructuredResponseTextBytes]\n\t}\n\n\tmessage := "unknown"\n\tif isTextResponse {\n\t\tmessage = strings.TrimSpace(string(body))\n\t}\n\tvar groupResource schema.GroupResource\n\tif len(r.resource) > 0 {\n\t\tgroupResource.Group = r.content.GroupVersion.Group\n\t\tgroupResource.Resource = r.resource\n\t}\n\treturn errors.NewGenericServerResponse(\n\t\tstatusCode,\n\t\tmethod,\n\t\tgroupResource,\n\t\tr.resourceName,\n\t\tmessage,\n\t\tretryAfter,\n\t\ttrue,\n\t)\n}\n\n// isTextResponse returns true if the response appears to be a textual media type.\nfunc isTextResponse(resp *http.Response) bool {\n\tcontentType := resp.Header.Get("Content-Type")\n\tif len(contentType) == 0 {\n\t\treturn true\n\t}\n\tmedia, _, err := mime.ParseMediaType(contentType)\n\tif err != nil {\n\t\treturn false\n\t}\n\treturn strings.HasPrefix(media, "text/")\n}\n\n// checkWait returns true along with a number of seconds if the server instructed us to wait\n// before retrying.\nfunc checkWait(resp *http.Response) (int, bool) {\n\tswitch r := resp.StatusCode; {\n\t// any 500 error code and 429 can trigger a wait\n\tcase r == http.StatusTooManyRequests, r >= 500:\n\tdefault:\n\t\treturn 0, false\n\t}\n\ti, ok := retryAfterSeconds(resp)\n\treturn i, ok\n}\n\n// retryAfterSeconds returns the value of the Retry-After header and true, or 0 and false if\n// the header was missing or not a valid number.\nfunc retryAfterSeconds(resp *http.Response) (int, bool) {\n\tif h := resp.Header.Get("Retry-After"); len(h) > 0 {\n\t\tif i, err := strconv.Atoi(h); err == nil {\n\t\t\treturn i, true\n\t\t}\n\t}\n\treturn 0, false\n}\n\n// Result contains the result of calling Request.Do().\ntype Result struct {\n\tbody []byte\n\tcontentType string\n\terr error\n\tstatusCode int\n\n\tdecoder runtime.Decoder\n}\n\n// Raw returns the raw result.\nfunc (r Result) Raw() ([]byte, error) {\n\treturn r.body, r.err\n}\n\n// Get returns the result as an object, which means it passes through the decoder.\n// If the returned object is of type Status and has .Status != StatusSuccess, the\n// additional information in Status will be used to enrich the error.\nfunc (r Result) Get() (runtime.Object, error) {\n\tif r.err != nil {\n\t\t// Check whether the result has a Status object in the body and prefer that.\n\t\treturn nil, r.Error()\n\t}\n\tif r.decoder == nil {\n\t\treturn nil, fmt.Errorf("serializer for %s doesn't exist", r.contentType)\n\t}\n\n\t// decode, but if the result is Status return that as an error instead.\n\tout, _, err := r.decoder.Decode(r.body, nil, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tswitch t := out.(type) {\n\tcase *metav1.Status:\n\t\t// any status besides StatusSuccess is considered an error.\n\t\tif t.Status != metav1.StatusSuccess {\n\t\t\treturn nil, errors.FromObject(t)\n\t\t}\n\t}\n\treturn out, nil\n}\n\n// StatusCode returns the HTTP status code of the request. (Only valid if no\n// error was returned.)\nfunc (r Result) StatusCode(statusCode int) Result {\n\tstatusCode = r.statusCode\n\treturn r\n}\n\n// Into stores the result into obj, if possible. If obj is nil it is ignored.\n// If the returned object is of type Status and has .Status != StatusSuccess, the\n// additional information in Status will be used to enrich the error.\nfunc (r Result) Into(obj runtime.Object) error {\n\tif r.err != nil {\n\t\t// Check whether the result has a Status object in the body and prefer that.\n\t\treturn r.Error()\n\t}\n\tif r.decoder == nil {\n\t\treturn fmt.Errorf("serializer for %s doesn't exist", r.contentType)\n\t}\n\tif len(r.body) == 0 {\n\t\treturn fmt.Errorf("0-length response with status code: %d and content type: %s",\n\t\t\tr.statusCode, r.contentType)\n\t}\n\n\tout, _, err := r.decoder.Decode(r.body, nil, obj)\n\tif err != nil || out == obj {\n\t\treturn err\n\t}\n\t// if a different object is returned, see if it is Status and avoid double decoding\n\t// the object.\n\tswitch t := out.(type) {\n\tcase *metav1.Status:\n\t\t// any status besides StatusSuccess is considered an error.\n\t\tif t.Status != metav1.StatusSuccess {\n\t\t\treturn errors.FromObject(t)\n\t\t}\n\t}\n\treturn nil\n}\n\n// WasCreated updates the provided bool pointer to whether the server returned\n// 201 created or a different response.\nfunc (r Result) WasCreated(wasCreated bool) Result {\n\twasCreated = r.statusCode == http.StatusCreated\n\treturn r\n}\n\n// Error returns the error executing the request, nil if no error occurred.\n// If the returned object is of type Status and has Status != StatusSuccess, the\n// additional information in Status will be used to enrich the error.\n// See the Request.Do() comment for what errors you might get.\nfunc (r Result) Error() error {\n\t// if we have received an unexpected server error, and we have a body and decoder, we can try to extract\n\t// a Status object.\n\tif r.err == nil || !errors.IsUnexpectedServerError(r.err) || len(r.body) == 0 || r.decoder == nil {\n\t\treturn r.err\n\t}\n\n\t// attempt to convert the body into a Status object\n\t// to be backwards compatible with old servers that do not return a version, default to "v1"\n\tout, _, err := r.decoder.Decode(r.body, &schema.GroupVersionKind{Version: "v1"}, nil)\n\tif err != nil {\n\t\tklog.V(5).Infof("body was not decodable (unable to check for Status): %v", err)\n\t\treturn r.err\n\t}\n\tswitch t := out.(type) {\n\tcase *metav1.Status:\n\t\t// because we default the kind, we must check for StatusFailure\n\t\tif t.Status == metav1.StatusFailure {\n\t\t\treturn errors.FromObject(t)\n\t\t}\n\t}\n\treturn r.err\n}\n\n// NameMayNotBe specifies strings that cannot be used as names specified as path segments (like the REST API or etcd store)\nvar NameMayNotBe = []string{".", ".."}\n\n// NameMayNotContain specifies substrings that cannot be used in names specified as path segments (like the REST API or etcd store)\nvar NameMayNotContain = []string{"/", "%"}\n\n// IsValidPathSegmentName validates the name can be safely encoded as a path segment\nfunc IsValidPathSegmentName(name string) []string {\n\tfor _, illegalName := range NameMayNotBe {\n\t\tif name == illegalName {\n\t\t\treturn []string{fmt.Sprintf(may not be '%s', illegalName)}\n\t\t}\n\t}\n\n\tvar errors []string\n\tfor _, illegalContent := range NameMayNotContain {\n\t\tif strings.Contains(name, illegalContent) {\n\t\t\terrors = append(errors, fmt.Sprintf(may not contain '%s', illegalContent))\n\t\t}\n\t}\n\n\treturn errors\n}\n\n// IsValidPathSegmentPrefix validates the name can be used as a prefix for a name which will be encoded as a path segment\n// It does not check for exact matches with disallowed names, since an arbitrary suffix might make the name valid\nfunc IsValidPathSegmentPrefix(name string) []string {\n\tvar errors []string\n\tfor _, illegalContent := range NameMayNotContain {\n\t\tif strings.Contains(name, illegalContent) {\n\t\t\terrors = append(errors, fmt.Sprintf(may not contain '%s', illegalContent))\n\t\t}\n\t}\n\n\treturn errors\n}\n\n// ValidatePathSegmentName validates the name can be safely encoded as a path segment\nfunc ValidatePathSegmentName(name string, prefix bool) []string {\n\tif prefix {\n\t\treturn IsValidPathSegmentPrefix(name)\n\t}\n\treturn IsValidPathSegmentName(name)\n}\n"}}

[Info - 4:08:02 PM] 119.92004ms for GOROOT=$GOROOT GOPATH=$GOPATH GO111MODULE=on PWD=$GOPATH/src/kubernetes go "list" "-m" "-json" "all", stderr: <<>>

[Trace - 4:08:02 PM] Received notification 'window/logMessage' in 0ms.
Params: {"type":3,"message":"119.92004ms for GOROOT=$GOROOT GOPATH=$GOPATH GO111MODULE=on PWD=$GOPATH/src/kubernetes go "list" "-m" "-json" "all", stderr: \u003c\u003c\u003e\u003e\n"}

[Trace - 4:08:02 PM] Received notification 'window/logMessage' in 0ms.
Params: {"type":3,"message":"413.231381ms for GOROOT=$GOROOT GOPATH=$GOPATH GO111MODULE=on PWD=$GOPATH/src/kubernetes go "list" "-e" "-json" "-compiled=true" "-test=true" "-export=false" "-deps=true" "-find=false" "--" "$GOPATH/src/kubernetes/staging/src/k8s.io/client-go/rest", stderr: \u003c\u003cgo: finding k8s.io/kubernetes/staging/src/k8s.io/client-go latest\ngo: k8s.io/kubernetes/staging/src/k8s.io/client-go@v0.0.0-20190808193559-f4e39afea082: parsing go.mod: unexpected module path "k8s.io/client-go"\ngo: error loading module requirements\n\u003e\u003e\n"}

[Info - 4:08:02 PM] 413.231381ms for GOROOT=$GOROOT GOPATH=$GOPATH GO111MODULE=on PWD=$GOPATH/src/kubernetes go "list" "-e" "-json" "-compiled=true" "-test=true" "-export=false" "-deps=true" "-find=false" "--" "$GOPATH/src/kubernetes/staging/src/k8s.io/client-go/rest", stderr: <<go: finding k8s.io/kubernetes/staging/src/k8s.io/client-go latest
go: k8s.io/kubernetes/staging/src/k8s.io/client-go@v0.0.0-20190808193559-f4e39afea082: parsing go.mod: unexpected module path "k8s.io/client-go"
go: error loading module requirements

[Info - 4:08:03 PM] 358.395512ms for GOROOT=$GOROOT GOPATH=$GOPATH GO111MODULE=on PWD=$GOPATH/src/kubernetes go "list" "-e" "-json" "-compiled=true" "-test=true" "-export=false" "-deps=true" "-find=false" "--" "$GOPATH/src/kubernetes/staging/src/k8s.io/client-go/rest/request.go", stderr: <<>>

[Trace - 4:08:03 PM] Received notification 'window/logMessage' in 0ms.
Params: {"type":3,"message":"358.395512ms for GOROOT=$GOROOT GOPATH=$GOPATH GO111MODULE=on PWD=$GOPATH/src/kubernetes go "list" "-e" "-json" "-compiled=true" "-test=true" "-export=false" "-deps=true" "-find=false" "--" "$GOPATH/src/kubernetes/staging/src/k8s.io/client-go/rest/request.go", stderr: \u003c\u003c\u003e\u003e\n"}

[Info - 4:08:03 PM] go/packages.Load
package = command-line-arguments
files = [$GOPATH/src/kubernetes/staging/src/k8s.io/client-go/rest/request.go]
[Trace - 4:08:03 PM] Received notification 'window/logMessage' in 0ms.
Params: {"type":3,"message":"go/packages.Load\n\tpackage = command-line-arguments\n\tfiles = [$GOPATH/src/kubernetes/staging/src/k8s.io/client-go/rest/request.go]"}

[Trace - 4:08:03 PM] Received notification 'window/logMessage' in 0ms.
Params: {"type":3,"message":"go/packages.Load\n\tpackages = 1"}

[Info - 4:08:03 PM] go/packages.Load
packages = 1
[Trace - 4:08:03 PM] Received notification 'textDocument/publishDiagnostics' in 0ms.
Params: {"uri":"file://$GOPATH/src/kubernetes/staging/src/k8s.io/client-go/rest/request.go","diagnostics":[{"range":{"start":{"line":88,"character":13},"end":{"line":88,"character":26}},"severity":1,"source":"LSP","message":"undeclared name: ContentConfig"},{"range":{"start":{"line":89,"character":13},"end":{"line":89,"character":24}},"severity":1,"source":"LSP","message":"undeclared name: Serializers"},{"range":{"start":{"line":112,"character":12},"end":{"line":112,"character":26}},"severity":1,"source":"LSP","message":"undeclared name: BackoffManager"},{"range":{"start":{"line":117,"character":99},"end":{"line":117,"character":112}},"severity":1,"source":"LSP","message":"undeclared name: ContentConfig"},{"range":{"start":{"line":117,"character":126},"end":{"line":117,"character":137}},"severity":1,"source":"LSP","message":"undeclared name: Serializers"},{"range":{"start":{"line":117,"character":147},"end":{"line":117,"character":161}},"severity":1,"source":"LSP","message":"undeclared name: BackoffManager"},{"range":{"start":{"line":187,"character":34},"end":{"line":187,"character":48}},"severity":1,"source":"LSP","message":"undeclared name: BackoffManager"},{"range":{"start":{"line":189,"character":18},"end":{"line":189,"character":29}},"severity":1,"source":"LSP","message":"undeclared name: NoBackoff"},{"range":{"start":{"line":120,"character":13},"end":{"line":120,"character":24}},"severity":1,"source":"LSP","message":"undeclared name: NoBackoff"}]}

[Trace - 4:08:03 PM] Received response 'textDocument/documentLink - (9)' in 0ms.
Params: [{"range":{"start":{"line":19,"character":1},"end":{"line":19,"character":8}},"target":"https://godoc.org/bytes"},{"range":{"start":{"line":20,"character":1},"end":{"line":20,"character":10}},"target":"https://godoc.org/context"},{"range":{"start":{"line":21,"character":1},"end":{"line":21,"character":15}},"target":"https://godoc.org/encoding/hex"},{"range":{"start":{"line":22,"character":1},"end":{"line":22,"character":6}},"target":"https://godoc.org/fmt"},{"range":{"start":{"line":23,"character":1},"end":{"line":23,"character":5}},"target":"https://godoc.org/io"},{"range":{"start":{"line":24,"character":1},"end":{"line":24,"character":12}},"target":"https://godoc.org/io/ioutil"},{"range":{"start":{"line":25,"character":1},"end":{"line":25,"character":7}},"target":"https://godoc.org/mime"},{"range":{"start":{"line":26,"character":1},"end":{"line":26,"character":11}},"target":"https://godoc.org/net/http"},{"range":{"start":{"line":27,"character":1},"end":{"line":27,"character":10}},"target":"https://godoc.org/net/url"},{"range":{"start":{"line":28,"character":1},"end":{"line":28,"character":7}},"target":"https://godoc.org/path"},{"range":{"start":{"line":29,"character":1},"end":{"line":29,"character":10}},"target":"https://godoc.org/reflect"},{"range":{"start":{"line":30,"character":1},"end":{"line":30,"character":10}},"target":"https://godoc.org/strconv"},{"range":{"start":{"line":31,"character":1},"end":{"line":31,"character":10}},"target":"https://godoc.org/strings"},{"range":{"start":{"line":32,"character":1},"end":{"line":32,"character":7}},"target":"https://godoc.org/time"},{"range":{"start":{"line":34,"character":1},"end":{"line":34,"character":25}},"target":"https://godoc.org/golang.org/x/net/http2"},{"range":{"start":{"line":35,"character":1},"end":{"line":35,"character":37}},"target":"https://godoc.org/k8s.io/apimachinery/pkg/api/errors"},{"range":{"start":{"line":36,"character":1},"end":{"line":36,"character":46}},"target":"https://godoc.org/k8s.io/apimachinery/pkg/apis/meta/v1"},{"range":{"start":{"line":37,"character":1},"end":{"line":37,"character":34}},"target":"https://godoc.org/k8s.io/apimachinery/pkg/runtime"},{"range":{"start":{"line":38,"character":1},"end":{"line":38,"character":41}},"target":"https://godoc.org/k8s.io/apimachinery/pkg/runtime/schema"},{"range":{"start":{"line":39,"character":1},"end":{"line":39,"character":55}},"target":"https://godoc.org/k8s.io/apimachinery/pkg/runtime/serializer/streaming"},{"range":{"start":{"line":40,"character":1},"end":{"line":40,"character":35}},"target":"https://godoc.org/k8s.io/apimachinery/pkg/util/net"},{"range":{"start":{"line":41,"character":1},"end":{"line":41,"character":32}},"target":"https://godoc.org/k8s.io/apimachinery/pkg/watch"},{"range":{"start":{"line":42,"character":1},"end":{"line":42,"character":46}},"target":"https://godoc.org/k8s.io/client-go/rest/watch"},{"range":{"start":{"line":43,"character":1},"end":{"line":43,"character":33}},"target":"https://godoc.org/k8s.io/client-go/tools/metrics"},{"range":{"start":{"line":44,"character":1},"end":{"line":44,"character":36}},"target":"https://godoc.org/k8s.io/client-go/util/flowcontrol"},{"range":{"start":{"line":45,"character":1},"end":{"line":45,"character":34}},"target":"https://godoc.org/k8s.io/client-go/util/keepalive"},{"range":{"start":{"line":46,"character":1},"end":{"line":46,"character":53}},"target":"https://godoc.org/k8s.io/client-go/util/keepalive/http"},{"range":{"start":{"line":47,"character":1},"end":{"line":47,"character":14}},"target":"https://godoc.org/k8s.io/klog"},{"range":{"start":{"line":7,"character":4},"end":{"line":7,"character":46}},"target":"http://www.apache.org/licenses/LICENSE-2.0"},{"range":{"start":{"line":493,"character":5},"end":{"line":493,"character":76}},"target":"https://kubernetes.io/docs/concepts/overview/kubernetes-api/#api-groups"}]

[Trace - 4:08:03 PM] Sending notification 'textDocument/documentLink' in 868ms.
Params: {"textDocument":{"uri":"file://$GOPATH/src/kubernetes/staging/src/k8s.io/client-go/rest/request.go"}}

[Trace - 4:08:03 PM] Received response 'textDocument/codeAction - (10)' in 0ms.
Params: [{"title":"Organize Imports","kind":"source.organizeImports","edit":{"changes":{"file://$GOPATH/src/kubernetes/staging/src/k8s.io/client-go/rest/request.go":[]}}}]

[Trace - 4:08:03 PM] Sending notification 'textDocument/codeAction' in 889ms.
Params: {"textDocument":{"uri":"file://$GOPATH/src/kubernetes/staging/src/k8s.io/client-go/rest/request.go"},"range":{"start":{"line":0,"character":0},"end":{"line":0,"character":0}},"context":{"diagnostics":[]}}

[Trace - 4:08:03 PM] Received response 'textDocument/documentSymbol - (11)' in 0ms.
Params: [{"name":"longThrottleLatency","detail":"time.Duration","kind":13,"range":{"start":{"line":50,"character":0},"end":{"line":54,"character":1}},"selectionRange":{"start":{"line":53,"character":1},"end":{"line":53,"character":20}}},{"name":"HTTPClient","detail":"interface{...}","kind":11,"range":{"start":{"line":57,"character":5},"end":{"line":59,"character":1}},"selectionRange":{"start":{"line":57,"character":5},"end":{"line":57,"character":15}},"children":[{"name":"Do","kind":6,"range":{"start":{"line":58,"character":1},"end":{"line":58,"character":46}},"selectionRange":{"start":{"line":58,"character":1},"end":{"line":58,"character":3}}}]},{"name":"ResponseWrapper","detail":"interface{...}","kind":11,"range":{"start":{"line":63,"character":5},"end":{"line":67,"character":1}},"selectionRange":{"start":{"line":63,"character":5},"end":{"line":63,"character":20}},"children":[{"name":"DoRaw","kind":6,"range":{"start":{"line":64,"character":1},"end":{"line":64,"character":24}},"selectionRange":{"start":{"line":64,"character":1},"end":{"line":64,"character":6}}},{"name":"Stream","kind":6,"range":{"start":{"line":65,"character":1},"end":{"line":65,"character":32}},"selectionRange":{"start":{"line":65,"character":1},"end":{"line":65,"character":7}}},{"name":"StreamWithPing","kind":6,"range":{"start":{"line":66,"character":1},"end":{"line":66,"character":87}},"selectionRange":{"start":{"line":66,"character":1},"end":{"line":66,"character":15}}}]},{"name":"RequestConstructionError","detail":"struct{...}","kind":23,"range":{"start":{"line":70,"character":5},"end":{"line":72,"character":1}},"selectionRange":{"start":{"line":70,"character":5},"end":{"line":70,"character":29}},"children":[{"name":"Err","detail":"interface{...}","kind":8,"range":{"start":{"line":71,"character":1},"end":{"line":71,"character":10}},"selectionRange":{"start":{"line":71,"character":1},"end":{"line":71,"character":4}}},{"name":"Error","detail":"()","kind":6,"range":{"start":{"line":75,"character":0},"end":{"line":77,"character":1}},"selectionRange":{"start":{"line":75,"character":35},"end":{"line":75,"character":40}}}]},{"name":"Request","detail":"struct{...}","kind":23,"range":{"start":{"line":82,"character":5},"end":{"line":114,"character":1}},"selectionRange":{"start":{"line":82,"character":5},"end":{"line":82,"character":12}},"children":[{"name":"client","detail":"interface{...}","kind":8,"range":{"start":{"line":84,"character":1},"end":{"line":84,"character":18}},"selectionRange":{"start":{"line":84,"character":1},"end":{"line":84,"character":7}}},{"name":"verb","detail":"string","kind":8,"range":{"start":{"line":85,"character":1},"end":{"line":85,"character":14}},"selectionRange":{"start":{"line":85,"character":1},"end":{"line":85,"character":5}}},{"name":"baseURL","detail":"*url.URL","kind":8,"range":{"start":{"line":87,"character":1},"end":{"line":87,"character":21}},"selectionRange":{"start":{"line":87,"character":1},"end":{"line":87,"character":8}}},{"name":"content","detail":"invalid type","kind":8,"range":{"start":{"line":88,"character":1},"end":{"line":88,"character":26}},"selectionRange":{"start":{"line":88,"character":1},"end":{"line":88,"character":8}}},{"name":"serializers","detail":"invalid type","kind":8,"range":{"start":{"line":89,"character":1},"end":{"line":89,"character":24}},"selectionRange":{"start":{"line":89,"character":1},"end":{"line":89,"character":12}}},{"name":"pathPrefix","detail":"string","kind":8,"range":{"start":{"line":92,"character":1},"end":{"line":92,"character":18}},"selectionRange":{"start":{"line":92,"character":1},"end":{"line":92,"character":11}}},{"name":"subpath","detail":"string","kind":8,"range":{"start":{"line":93,"character":1},"end":{"line":93,"character":18}},"selectionRange":{"start":{"line":93,"character":1},"end":{"line":93,"character":8}}},{"name":"params","detail":"map[string][]string","kind":8,"range":{"start":{"line":94,"character":1},"end":{"line":94,"character":22}},"selectionRange":{"start":{"line":94,"character":1},"end":{"line":94,"character":7}}},{"name":"headers","detail":"map[string][]string","kind":8,"range":{"start":{"line":95,"character":1},"end":{"line":95,"character":23}},"selectionRange":{"start":{"line":95,"character":1},"end":{"line":95,"character":8}}},{"name":"namespace","detail":"string","kind":8,"range":{"start":{"line":98,"character":1},"end":{"line":98,"character":20}},"selectionRange":{"start":{"line":98,"character":1},"end":{"line":98,"character":10}}},{"name":"namespaceSet","detail":"bool","kind":8,"range":{"start":{"line":99,"character":1},"end":{"line":99,"character":18}},"selectionRange":{"start":{"line":99,"character":1},"end":{"line":99,"character":13}}},{"name":"resource","detail":"string","kind":8,"range":{"start":{"line":100,"character":1},"end":{"line":100,"character":20}},"selectionRange":{"start":{"line":100,"character":1},"end":{"line":100,"character":9}}},{"name":"resourceName","detail":"string","kind":8,"range":{"start":{"line":101,"character":1},"end":{"line":101,"character":20}},"selectionRange":{"start":{"line":101,"character":1},"end":{"line":101,"character":13}}},{"name":"subresource","detail":"string","kind":8,"range":{"start":{"line":102,"character":1},"end":{"line":102,"character":20}},"selectionRange":{"start":{"line":102,"character":1},"end":{"line":102,"character":12}}},{"name":"timeout","detail":"int64","kind":8,"range":{"start":{"line":103,"character":1},"end":{"line":103,"character":27}},"selectionRange":{"start":{"line":103,"character":1},"end":{"line":103,"character":8}}},{"name":"err","detail":"interface{...}","kind":8,"range":{"start":{"line":106,"character":1},"end":{"line":106,"character":11}},"selectionRange":{"start":{"line":106,"character":1},"end":{"line":106,"character":4}}},{"name":"body","detail":"interface{...}","kind":8,"range":{"start":{"line":107,"character":1},"end":{"line":107,"character":15}},"selectionRange":{"start":{"line":107,"character":1},"end":{"line":107,"character":5}}},{"name":"ctx","detail":"interface{...}","kind":8,"range":{"start":{"line":110,"character":1},"end":{"line":110,"character":20}},"selectionRange":{"start":{"line":110,"character":1},"end":{"line":110,"character":4}}},{"name":"backoffMgr","detail":"invalid type","kind":8,"range":{"start":{"line":112,"character":1},"end":{"line":112,"character":26}},"selectionRange":{"start":{"line":112,"character":1},"end":{"line":112,"character":11}}},{"name":"throttle","detail":"interface{...}","kind":8,"range":{"start":{"line":113,"character":1},"end":{"line":113,"character":35}},"selectionRange":{"start":{"line":113,"character":1},"end":{"line":113,"character":9}}},{"name":"Context","detail":"(ctx context.Context)","kind":6,"range":{"start":{"line":418,"character":0},"end":{"line":421,"character":1}},"selectionRange":{"start":{"line":418,"character":18},"end":{"line":418,"character":25}}},{"name":"finalURLTemplate","detail":"()","kind":6,"range":{"start":{"line":462,"character":0},"end":{"line":524,"character":1}},"selectionRange":{"start":{"line":462,"character":17},"end":{"line":462,"character":33}}},{"name":"DoRaw","detail":"()","kind":6,"range":{"start":{"line":851,"character":0},"end":{"line":868,"character":1}},"selectionRange":{"start":{"line":851,"character":18},"end":{"line":851,"character":23}}},{"name":"Throttle","detail":"(limiter flowcontrol.RateLimiter)","kind":6,"range":{"start":{"line":198,"character":0},"end":{"line":201,"character":1}},"selectionRange":{"start":{"line":198,"character":18},"end":{"line":198,"character":26}}},{"name":"AbsPath","detail":"(segments []string)","kind":6,"range":{"start":{"line":273,"character":0},"end":{"line":283,"character":1}},"selectionRange":{"start":{"line":273,"character":18},"end":{"line":273,"character":25}}},{"name":"Timeout","detail":"(d time.Duration)","kind":6,"range":{"start":{"line":364,"character":0},"end":{"line":370,"character":1}},"selectionRange":{"start":{"line":364,"character":18},"end":{"line":364,"character":25}}},{"name":"SpecificallyVersionedParams","detail":"(obj runtime.Object, codec runtime.ParameterCodec, version schema.GroupVersion)","kind":6,"range":{"start":{"line":325,"character":0},"end":{"line":341,"character":1}},"selectionRange":{"start":{"line":325,"character":18},"end":{"line":325,"character":45}}},{"name":"Body","detail":"(obj interface{})","kind":6,"range":{"start":{"line":379,"character":0},"end":{"line":414,"character":1}},"selectionRange":{"start":{"line":379,"character":18},"end":{"line":379,"character":22}}},{"name":"RequestURI","detail":"(uri string)","kind":6,"range":{"start":{"line":287,"character":0},"end":{"line":306,"character":1}},"selectionRange":{"start":{"line":287,"character":18},"end":{"line":287,"character":28}}},{"name":"Param","detail":"(paramName string, s string)","kind":6,"range":{"start":{"line":309,"character":0},"end":{"line":314,"character":1}},"selectionRange":{"start":{"line":309,"character":18},"end":{"line":309,"character":23}}},{"name":"NamespaceIfScoped","detail":"(namespace string, scoped bool)","kind":6,"range":{"start":{"line":264,"character":0},"end":{"line":269,"character":1}},"selectionRange":{"start":{"line":264,"character":18},"end":{"line":264,"character":35}}},{"name":"WatchWithSpecificDecoders","detail":"(wrapperDecoderFn func(io.ReadCloser) streaming.Decoder, embeddedDecoder runtime.Decoder)","kind":6,"range":{"start":{"line":561,"character":0},"end":{"line":616,"character":1}},"selectionRange":{"start":{"line":561,"character":18},"end":{"line":561,"character":43}}},{"name":"transformResponse","detail":"(resp *http.Response, req *http.Request)","kind":6,"range":{"start":{"line":871,"character":0},"end":{"line":950,"character":1}},"selectionRange":{"start":{"line":871,"character":18},"end":{"line":871,"character":35}}},{"name":"newUnstructuredResponseError","detail":"(body []byte, isTextResponse bool, statusCode int, method string, retryAfter int)","kind":6,"range":{"start":{"line":1018,"character":0},"end":{"line":1042,"character":1}},"selectionRange":{"start":{"line":1018,"character":18},"end":{"line":1018,"character":46}}},{"name":"Prefix","detail":"(segments []string)","kind":6,"range":{"start":{"line":150,"character":0},"end":{"line":156,"character":1}},"selectionRange":{"start":{"line":150,"character":18},"end":{"line":150,"character":24}}},{"name":"BackOff","detail":"(manager invalid type)","kind":6,"range":{"start":{"line":187,"character":0},"end":{"line":195,"character":1}},"selectionRange":{"start":{"line":187,"character":18},"end":{"line":187,"character":25}}},{"name":"SubResource","detail":"(subresources []string)","kind":6,"range":{"start":{"line":205,"character":0},"end":{"line":222,"character":1}},"selectionRange":{"start":{"line":205,"character":18},"end":{"line":205,"character":29}}},{"name":"SetHeader","detail":"(key string, values []string)","kind":6,"range":{"start":{"line":351,"character":0},"end":{"line":360,"character":1}},"selectionRange":{"start":{"line":351,"character":18},"end":{"line":351,"character":27}}},{"name":"URL","detail":"()","kind":6,"range":{"start":{"line":424,"character":0},"end":{"line":456,"character":1}},"selectionRange":{"start":{"line":424,"character":18},"end":{"line":424,"character":21}}},{"name":"Namespace","detail":"(namespace string)","kind":6,"range":{"start":{"line":246,"character":0},"end":{"line":261,"character":1}},"selectionRange":{"start":{"line":246,"character":18},"end":{"line":246,"character":27}}},{"name":"tryThrottle","detail":"()","kind":6,"range":{"start":{"line":526,"character":0},"end":{"line":544,"character":1}},"selectionRange":{"start":{"line":526,"character":18},"end":{"line":526,"character":29}}},{"name":"Resource","detail":"(resource string)","kind":6,"range":{"start":{"line":169,"character":0},"end":{"line":183,"character":1}},"selectionRange":{"start":{"line":169,"character":18},"end":{"line":169,"character":26}}},{"name":"Name","detail":"(resourceName string)","kind":6,"range":{"start":{"line":225,"character":0},"end":{"line":243,"character":1}},"selectionRange":{"start":{"line":225,"character":18},"end":{"line":225,"character":22}}},{"name":"StreamWithPing","detail":"(ctx context.Context, pingInterval time.Duration)","kind":6,"range":{"start":{"line":696,"character":0},"end":{"line":705,"character":1}},"selectionRange":{"start":{"line":696,"character":18},"end":{"line":696,"character":32}}},{"name":"transformUnstructuredResponseError","detail":"(resp *http.Response, req *http.Request, body []byte)","kind":6,"range":{"start":{"line":1007,"character":0},"end":{"line":1015,"character":1}},"selectionRange":{"start":{"line":1007,"character":18},"end":{"line":1007,"character":52}}},{"name":"setParam","detail":"(paramName string, value string)","kind":6,"range":{"start":{"line":343,"character":0},"end":{"line":349,"character":1}},"selectionRange":{"start":{"line":343,"character":18},"end":{"line":343,"character":26}}},{"name":"Stream","detail":"()","kind":6,"range":{"start":{"line":640,"character":0},"end":{"line":694,"character":1}},"selectionRange":{"start":{"line":640,"character":18},"end":{"line":640,"character":24}}},{"name":"request","detail":"(fn func(*http.Request, *http.Response))","kind":6,"range":{"start":{"line":711,"character":0},"end":{"line":825,"character":1}},"selectionRange":{"start":{"line":711,"character":18},"end":{"line":711,"character":25}}},{"name":"Do","detail":"()","kind":6,"range":{"start":{"line":835,"character":0},"end":{"line":848,"character":1}},"selectionRange":{"start":{"line":835,"character":18},"end":{"line":835,"character":20}}},{"name":"Suffix","detail":"(segments []string)","kind":6,"range":{"start":{"line":160,"character":0},"end":{"line":166,"character":1}},"selectionRange":{"start":{"line":160,"character":18},"end":{"line":160,"character":24}}},{"name":"VersionedParams","detail":"(obj runtime.Object, codec runtime.ParameterCodec)","kind":6,"range":{"start":{"line":321,"character":0},"end":{"line":323,"character":1}},"selectionRange":{"start":{"line":321,"character":18},"end":{"line":321,"character":33}}},{"name":"Watch","detail":"()","kind":6,"range":{"start":{"line":548,"character":0},"end":{"line":556,"character":1}},"selectionRange":{"start":{"line":548,"character":18},"end":{"line":548,"character":23}}}]},{"name":"NewRequest","detail":"(client HTTPClient, verb string, baseURL *url.URL, versionedAPIPath string, content invalid type, serializers invalid type, backoff invalid type, throttle flowcontrol.RateLimiter, timeout time.Duration)","kind":12,"range":{"start":{"line":117,"character":0},"end":{"line":145,"character":1}},"selectionRange":{"start":{"line":117,"character":5},"end":{"line":117,"character":15}}},{"name":"updateURLMetrics","detail":"(req *Request, resp *http.Response, err error)","kind":12,"range":{"start":{"line":620,"character":0},"end":{"line":634,"character":1}},"selectionRange":{"start":{"line":620,"character":5},"end":{"line":620,"character":21}}},{"name":"truncateBody","detail":"(body string)","kind":12,"range":{"start":{"line":953,"character":0},"end":{"line":969,"character":1}},"selectionRange":{"start":{"line":953,"character":5},"end":{"line":953,"character":17}}},{"name":"glogBody","detail":"(prefix string, body []byte)","kind":12,"range":{"start":{"line":974,"character":0},"end":{"line":984,"character":1}},"selectionRange":{"start":{"line":974,"character":5},"end":{"line":974,"character":13}}},{"name":"maxUnstructuredResponseTextBytes","detail":"untyped int","kind":14,"range":{"start":{"line":987,"character":0},"end":{"line":987,"character":45}},"selectionRange":{"start":{"line":987,"character":6},"end":{"line":987,"character":38}}},{"name":"isTextResponse","detail":"(resp *http.Response)","kind":12,"range":{"start":{"line":1045,"character":0},"end":{"line":1055,"character":1}},"selectionRange":{"start":{"line":1045,"character":5},"end":{"line":1045,"character":19}}},{"name":"checkWait","detail":"(resp *http.Response)","kind":12,"range":{"start":{"line":1059,"character":0},"end":{"line":1068,"character":1}},"selectionRange":{"start":{"line":1059,"character":5},"end":{"line":1059,"character":14}}},{"name":"retryAfterSeconds","detail":"(resp *http.Response)","kind":12,"range":{"start":{"line":1072,"character":0},"end":{"line":1079,"character":1}},"selectionRange":{"start":{"line":1072,"character":5},"end":{"line":1072,"character":22}}},{"name":"Result","detail":"struct{...}","kind":23,"range":{"start":{"line":1082,"character":5},"end":{"line":1089,"character":1}},"selectionRange":{"start":{"line":1082,"character":5},"end":{"line":1082,"character":11}},"children":[{"name":"body","detail":"[]byte","kind":8,"range":{"start":{"line":1083,"character":1},"end":{"line":1083,"character":19}},"selectionRange":{"start":{"line":1083,"character":1},"end":{"line":1083,"character":5}}},{"name":"contentType","detail":"string","kind":8,"range":{"start":{"line":1084,"character":1},"end":{"line":1084,"character":19}},"selectionRange":{"start":{"line":1084,"character":1},"end":{"line":1084,"character":12}}},{"name":"err","detail":"interface{...}","kind":8,"range":{"start":{"line":1085,"character":1},"end":{"line":1085,"character":18}},"selectionRange":{"start":{"line":1085,"character":1},"end":{"line":1085,"character":4}}},{"name":"statusCode","detail":"int","kind":8,"range":{"start":{"line":1086,"character":1},"end":{"line":1086,"character":16}},"selectionRange":{"start":{"line":1086,"character":1},"end":{"line":1086,"character":11}}},{"name":"decoder","detail":"interface{...}","kind":8,"range":{"start":{"line":1088,"character":1},"end":{"line":1088,"character":24}},"selectionRange":{"start":{"line":1088,"character":1},"end":{"line":1088,"character":8}}},{"name":"Raw","detail":"()","kind":6,"range":{"start":{"line":1092,"character":0},"end":{"line":1094,"character":1}},"selectionRange":{"start":{"line":1092,"character":16},"end":{"line":1092,"character":19}}},{"name":"Get","detail":"()","kind":6,"range":{"start":{"line":1099,"character":0},"end":{"line":1121,"character":1}},"selectionRange":{"start":{"line":1099,"character":16},"end":{"line":1099,"character":19}}},{"name":"StatusCode","detail":"(statusCode *int)","kind":6,"range":{"start":{"line":1125,"character":0},"end":{"line":1128,"character":1}},"selectionRange":{"start":{"line":1125,"character":16},"end":{"line":1125,"character":26}}},{"name":"Into","detail":"(obj runtime.Object)","kind":6,"range":{"start":{"line":1133,"character":0},"end":{"line":1160,"character":1}},"selectionRange":{"start":{"line":1133,"character":16},"end":{"line":1133,"character":20}}},{"name":"WasCreated","detail":"(wasCreated *bool)","kind":6,"range":{"start":{"line":1164,"character":0},"end":{"line":1167,"character":1}},"selectionRange":{"start":{"line":1164,"character":16},"end":{"line":1164,"character":26}}},{"name":"Error","detail":"()","kind":6,"range":{"start":{"line":1173,"character":0},"end":{"line":1195,"character":1}},"selectionRange":{"start":{"line":1173,"character":16},"end":{"line":1173,"character":21}}}]},{"name":"NameMayNotBe","detail":"[]string","kind":13,"range":{"start":{"line":1198,"character":0},"end":{"line":1198,"character":38}},"selectionRange":{"start":{"line":1198,"character":4},"end":{"line":1198,"character":16}}},{"name":"NameMayNotContain","detail":"[]string","kind":13,"range":{"start":{"line":1201,"character":0},"end":{"line":1201,"character":42}},"selectionRange":{"start":{"line":1201,"character":4},"end":{"line":1201,"character":21}}},{"name":"IsValidPathSegmentName","detail":"(name string)","kind":12,"range":{"start":{"line":1204,"character":0},"end":{"line":1219,"character":1}},"selectionRange":{"start":{"line":1204,"character":5},"end":{"line":1204,"character":27}}},{"name":"IsValidPathSegmentPrefix","detail":"(name string)","kind":12,"range":{"start":{"line":1223,"character":0},"end":{"line":1232,"character":1}},"selectionRange":{"start":{"line":1223,"character":5},"end":{"line":1223,"character":29}}},{"name":"ValidatePathSegmentName","detail":"(name string, prefix bool)","kind":12,"range":{"start":{"line":1235,"character":0},"end":{"line":1240,"character":1}},"selectionRange":{"start":{"line":1235,"character":5},"end":{"line":1235,"character":28}}}]

[Trace - 4:08:03 PM] Sending notification 'textDocument/documentSymbol' in 889ms.
Params: {"textDocument":{"uri":"file://$GOPATH/src/kubernetes/staging/src/k8s.io/client-go/rest/request.go"}}

[Trace - 4:08:03 PM] Received response 'textDocument/codeAction - (12)' in 0ms.
Params: [{"title":"Organize Imports","kind":"source.organizeImports","edit":{"changes":{"file://$GOPATH/src/kubernetes/staging/src/k8s.io/client-go/rest/request.go":[]}}}]

[Trace - 4:08:03 PM] Sending notification 'textDocument/codeAction' in 641ms.
Params: {"textDocument":{"uri":"file://$GOPATH/src/kubernetes/staging/src/k8s.io/client-go/rest/request.go"},"range":{"start":{"line":66,"character":1},"end":{"line":66,"character":1}},"context":{"diagnostics":[]}}

[Trace - 4:08:03 PM] Sending notification '$/cancelRequest' in 641ms.
Params: {"id":10}

[Trace - 4:08:03 PM] Received response 'textDocument/codeAction - (13)' in 0ms.
Params: [{"title":"Organize Imports","kind":"source.organizeImports","edit":{"changes":{"file://$GOPATH/src/kubernetes/staging/src/k8s.io/client-go/rest/request.go":[]}}}]

[Trace - 4:08:03 PM] Sending notification 'textDocument/codeAction' in 20ms.
Params: {"textDocument":{"uri":"file://$GOPATH/src/kubernetes/staging/src/k8s.io/client-go/rest/request.go"},"range":{"start":{"line":66,"character":1},"end":{"line":66,"character":1}},"context":{"diagnostics":[]}}

[Trace - 4:08:04 PM] Received response 'textDocument/hover - (14)' in 0ms.
Params: {"contents":{"kind":"markdown","value":"go\nvar ctx context.Context\n"},"range":{"start":{"line":66,"character":16},"end":{"line":66,"character":19}}}

[Trace - 4:08:04 PM] Sending notification 'textDocument/hover' in 1ms.
Params: {"textDocument":{"uri":"file://$GOPATH/src/kubernetes/staging/src/k8s.io/client-go/rest/request.go"},"position":{"line":66,"character":16}}

[Trace - 4:08:04 PM] Received response 'textDocument/hover - (15)' in 0ms.
Params: {"contents":{"kind":"markdown","value":"go\nfunc (ResponseWrapper).StreamWithPing(ctx context.Context, pingInterval time.Duration) (io.ReadCloser, error)\n"},"range":{"start":{"line":66,"character":1},"end":{"line":66,"character":15}}}

[Trace - 4:08:04 PM] Sending notification 'textDocument/hover' in 1ms.
Params: {"textDocument":{"uri":"file://$GOPATH/src/kubernetes/staging/src/k8s.io/client-go/rest/request.go"},"position":{"line":66,"character":11}}

[Trace - 4:08:09 PM] Received response 'textDocument/documentLink - (16)' in 0ms.
Params: {}

[Trace - 4:08:09 PM] Sending notification 'textDocument/documentLink' in 1ms.
Params: {"textDocument":{"uri":"file://$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go"}}

[Trace - 4:08:09 PM] Received response 'textDocument/codeAction - (17)' in 0ms.
Params: {}

[Trace - 4:08:09 PM] Sending notification 'textDocument/codeAction' in 0ms.
Params: {"textDocument":{"uri":"file://$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go"},"range":{"start":{"line":0,"character":0},"end":{"line":0,"character":0}},"context":{"diagnostics":[]}}

[Error - 4:08:09 PM] Request textDocument/documentLink failed.
Message: GetAST: unable to check package for file://$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go: no packages found for file://$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go
Code: 0
[Error - 4:08:09 PM] Request textDocument/codeAction failed.
Message: GetAST: unable to check package for file://$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go: no packages found for file://$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go
Code: 0
[Trace - 4:08:09 PM] Received response 'textDocument/codeAction - (18)' in 0ms.
Params: {}

[Trace - 4:08:09 PM] Sending notification 'textDocument/codeAction' in 0ms.
Params: {"textDocument":{"uri":"file://$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go"},"range":{"start":{"line":380,"character":41},"end":{"line":380,"character":41}},"context":{"diagnostics":[]}}

[Error - 4:08:09 PM] Request textDocument/codeAction failed.
Message: GetAST: unable to check package for file://$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go: no packages found for file://$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go
Code: 0
[Trace - 4:08:10 PM] Received response 'textDocument/hover - (19)' in 0ms.
Params: {}

[Trace - 4:08:10 PM] Sending notification 'textDocument/hover' in 1ms.
Params: {"textDocument":{"uri":"file://$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go"},"position":{"line":380,"character":33}}

[Error - 4:08:10 PM] Request textDocument/hover failed.
Message: GetAST: unable to check package for file://$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go: no packages found for file://$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go
Code: 0
[Trace - 4:08:11 PM] Received response 'textDocument/documentHighlight - (20)' in 0ms.
Params: {}

[Trace - 4:08:11 PM] Sending notification 'textDocument/documentHighlight' in 0ms.
Params: {"textDocument":{"uri":"file://$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go"},"position":{"line":380,"character":33}}

[Error - 4:08:11 PM] Request textDocument/documentHighlight failed.
Message: GetAST: unable to check package for file://$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go: no packages found for file://$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go
Code: 0
[Trace - 4:08:11 PM] Received response 'textDocument/codeAction - (21)' in 0ms.
Params: {}

[Trace - 4:08:11 PM] Sending notification 'textDocument/codeAction' in 1ms.
Params: {"textDocument":{"uri":"file://$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go"},"range":{"start":{"line":380,"character":33},"end":{"line":380,"character":33}},"context":{"diagnostics":[]}}

[Error - 4:08:11 PM] Request textDocument/codeAction failed.
Message: GetAST: unable to check package for file://$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go: no packages found for file://$GOPATH/src/kubernetes/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go
Code: 0

@ereslibre

This comment has been minimized.

Copy link

@ereslibre ereslibre commented Aug 8, 2019

One last thing, since I will be messing around with that branch, I created another branch called ping-on-long-running-commands-gopls with the reproducer, feel free to update the description of the issue if you think it's better, I won't touch that branch.

@stamblerre

This comment has been minimized.

Copy link
Contributor Author

@stamblerre stamblerre commented Aug 8, 2019

Thanks @ereslibre! I was actually able to understand the issue as I encountered it with VSCode - I hope this will resolve it for you in Emacs as well.

I hadn't noticed that there was a go.mod file inside of kubernetes/staging/src/k8s.io/kubectl in addition to inside of kubernetes. If you set the workspace root to kubernetes/staging/src/k8s.io/kubectl instead of kubernetes, it works correctly. In VSCode, setting the workspace root just means opening VSCode at that directory, though I believe in lsp-mode there is a specific command to set the workspace root?

@ereslibre

This comment has been minimized.

Copy link

@ereslibre ereslibre commented Aug 9, 2019

there is a specific command to set the workspace root?

Yes, this is possible. With the projectile integration it will automatically find the root of the project by default (whatever folder contains the .git directory up the hierarchy); but it can be overriden.

Just to clarify, I assume that this nested go.mod strategy is not going to be supported by gopls? I guess a possible approach could be that I symlink in my GOPATH, like:

$GOPATH/src/k8s.io/kubectl -> $PROJECT/staging/src/k8s.io/kubectl

However, go.mod on the toplevel specifies k8s.io/kubectl => ./staging/src/k8s.io/kubectl, so I'm not sure this approach will work at all.

@stamblerre

This comment has been minimized.

Copy link
Contributor Author

@stamblerre stamblerre commented Aug 9, 2019

We do plan to support multiple modules with gopls (see #32394), but for now the integration isn't seamless. When you open this directory in Emacs, can you try setting the workspace root to the directory that contains the go.mod file and see if it works correctly?

@ereslibre

This comment has been minimized.

Copy link

@ereslibre ereslibre commented Aug 10, 2019

can you try setting the workspace root to the directory that contains the go.mod file and see if it works correctly?

Yes, I cannot reproduce if I explicitly set the workspace root to the subdirectory.

@stamblerre

This comment has been minimized.

Copy link
Contributor Author

@stamblerre stamblerre commented Aug 12, 2019

Ok, glad to hear we were able to get a workaround for this. Since this is essentially the same problem as in #32394, I will close this issue, and you can follow along for updates there. Thanks for bearing with me on this one!

@stamblerre stamblerre closed this Aug 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants
You can’t perform that action at this time.