Commit 1d4adb03 authored by Brad Davidson's avatar Brad Davidson Committed by Brad Davidson

Update Kubernetes to v1.20.2-k3s1

parent 26d45287
...@@ -21,7 +21,7 @@ replace ( ...@@ -21,7 +21,7 @@ replace (
github.com/docker/libnetwork => github.com/docker/libnetwork v0.8.0-dev.2.0.20190624125649-f0e46a78ea34 github.com/docker/libnetwork => github.com/docker/libnetwork v0.8.0-dev.2.0.20190624125649-f0e46a78ea34
github.com/golang/protobuf => github.com/golang/protobuf v1.3.5 github.com/golang/protobuf => github.com/golang/protobuf v1.3.5
github.com/juju/errors => github.com/k3s-io/nocode v0.0.0-20200630202308-cb097102c09f github.com/juju/errors => github.com/k3s-io/nocode v0.0.0-20200630202308-cb097102c09f
github.com/kubernetes-sigs/cri-tools => github.com/k3s-io/cri-tools v1.19.0-k3s1 github.com/kubernetes-sigs/cri-tools => github.com/k3s-io/cri-tools v1.20.0-k3s1
github.com/matryer/moq => github.com/rancher/moq v0.0.0-20190404221404-ee5226d43009 github.com/matryer/moq => github.com/rancher/moq v0.0.0-20190404221404-ee5226d43009
github.com/opencontainers/runc => github.com/opencontainers/runc v1.0.0-rc92 github.com/opencontainers/runc => github.com/opencontainers/runc v1.0.0-rc92
github.com/opencontainers/runtime-spec => github.com/opencontainers/runtime-spec v1.0.3-0.20200728170252-4d89ac9fbff6 github.com/opencontainers/runtime-spec => github.com/opencontainers/runtime-spec v1.0.3-0.20200728170252-4d89ac9fbff6
...@@ -32,34 +32,34 @@ replace ( ...@@ -32,34 +32,34 @@ replace (
google.golang.org/genproto => google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63 google.golang.org/genproto => google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63
google.golang.org/grpc => google.golang.org/grpc v1.27.1 google.golang.org/grpc => google.golang.org/grpc v1.27.1
gopkg.in/square/go-jose.v2 => gopkg.in/square/go-jose.v2 v2.2.2 gopkg.in/square/go-jose.v2 => gopkg.in/square/go-jose.v2 v2.2.2
k8s.io/api => github.com/k3s-io/kubernetes/staging/src/k8s.io/api v1.20.0-k3s1 k8s.io/api => github.com/k3s-io/kubernetes/staging/src/k8s.io/api v1.20.2-k3s1
k8s.io/apiextensions-apiserver => github.com/k3s-io/kubernetes/staging/src/k8s.io/apiextensions-apiserver v1.20.0-k3s1 k8s.io/apiextensions-apiserver => github.com/k3s-io/kubernetes/staging/src/k8s.io/apiextensions-apiserver v1.20.2-k3s1
k8s.io/apimachinery => github.com/k3s-io/kubernetes/staging/src/k8s.io/apimachinery v1.20.0-k3s1 k8s.io/apimachinery => github.com/k3s-io/kubernetes/staging/src/k8s.io/apimachinery v1.20.2-k3s1
k8s.io/apiserver => github.com/k3s-io/kubernetes/staging/src/k8s.io/apiserver v1.20.0-k3s1 k8s.io/apiserver => github.com/k3s-io/kubernetes/staging/src/k8s.io/apiserver v1.20.2-k3s1
k8s.io/cli-runtime => github.com/k3s-io/kubernetes/staging/src/k8s.io/cli-runtime v1.20.0-k3s1 k8s.io/cli-runtime => github.com/k3s-io/kubernetes/staging/src/k8s.io/cli-runtime v1.20.2-k3s1
k8s.io/client-go => github.com/k3s-io/kubernetes/staging/src/k8s.io/client-go v1.20.0-k3s1 k8s.io/client-go => github.com/k3s-io/kubernetes/staging/src/k8s.io/client-go v1.20.2-k3s1
k8s.io/cloud-provider => github.com/k3s-io/kubernetes/staging/src/k8s.io/cloud-provider v1.20.0-k3s1 k8s.io/cloud-provider => github.com/k3s-io/kubernetes/staging/src/k8s.io/cloud-provider v1.20.2-k3s1
k8s.io/cluster-bootstrap => github.com/k3s-io/kubernetes/staging/src/k8s.io/cluster-bootstrap v1.20.0-k3s1 k8s.io/cluster-bootstrap => github.com/k3s-io/kubernetes/staging/src/k8s.io/cluster-bootstrap v1.20.2-k3s1
k8s.io/code-generator => github.com/k3s-io/kubernetes/staging/src/k8s.io/code-generator v1.20.0-k3s1 k8s.io/code-generator => github.com/k3s-io/kubernetes/staging/src/k8s.io/code-generator v1.20.2-k3s1
k8s.io/component-base => github.com/k3s-io/kubernetes/staging/src/k8s.io/component-base v1.20.0-k3s1 k8s.io/component-base => github.com/k3s-io/kubernetes/staging/src/k8s.io/component-base v1.20.2-k3s1
k8s.io/component-helpers => github.com/k3s-io/kubernetes/staging/src/k8s.io/component-helpers v1.20.0-k3s1 k8s.io/component-helpers => github.com/k3s-io/kubernetes/staging/src/k8s.io/component-helpers v1.20.2-k3s1
k8s.io/controller-manager => github.com/k3s-io/kubernetes/staging/src/k8s.io/controller-manager v1.20.0-k3s1 k8s.io/controller-manager => github.com/k3s-io/kubernetes/staging/src/k8s.io/controller-manager v1.20.2-k3s1
k8s.io/cri-api => github.com/k3s-io/kubernetes/staging/src/k8s.io/cri-api v1.20.0-k3s1 k8s.io/cri-api => github.com/k3s-io/kubernetes/staging/src/k8s.io/cri-api v1.20.2-k3s1
k8s.io/csi-translation-lib => github.com/k3s-io/kubernetes/staging/src/k8s.io/csi-translation-lib v1.20.0-k3s1 k8s.io/csi-translation-lib => github.com/k3s-io/kubernetes/staging/src/k8s.io/csi-translation-lib v1.20.2-k3s1
k8s.io/kube-aggregator => github.com/k3s-io/kubernetes/staging/src/k8s.io/kube-aggregator v1.20.0-k3s1 k8s.io/kube-aggregator => github.com/k3s-io/kubernetes/staging/src/k8s.io/kube-aggregator v1.20.2-k3s1
k8s.io/kube-controller-manager => github.com/k3s-io/kubernetes/staging/src/k8s.io/kube-controller-manager v1.20.0-k3s1 k8s.io/kube-controller-manager => github.com/k3s-io/kubernetes/staging/src/k8s.io/kube-controller-manager v1.20.2-k3s1
k8s.io/kube-proxy => github.com/k3s-io/kubernetes/staging/src/k8s.io/kube-proxy v1.20.0-k3s1 k8s.io/kube-proxy => github.com/k3s-io/kubernetes/staging/src/k8s.io/kube-proxy v1.20.2-k3s1
k8s.io/kube-scheduler => github.com/k3s-io/kubernetes/staging/src/k8s.io/kube-scheduler v1.20.0-k3s1 k8s.io/kube-scheduler => github.com/k3s-io/kubernetes/staging/src/k8s.io/kube-scheduler v1.20.2-k3s1
k8s.io/kubectl => github.com/k3s-io/kubernetes/staging/src/k8s.io/kubectl v1.20.0-k3s1 k8s.io/kubectl => github.com/k3s-io/kubernetes/staging/src/k8s.io/kubectl v1.20.2-k3s1
k8s.io/kubelet => github.com/k3s-io/kubernetes/staging/src/k8s.io/kubelet v1.20.0-k3s1 k8s.io/kubelet => github.com/k3s-io/kubernetes/staging/src/k8s.io/kubelet v1.20.2-k3s1
k8s.io/kubernetes => github.com/k3s-io/kubernetes v1.20.0-k3s1 k8s.io/kubernetes => github.com/k3s-io/kubernetes v1.20.2-k3s1
k8s.io/legacy-cloud-providers => github.com/k3s-io/kubernetes/staging/src/k8s.io/legacy-cloud-providers v1.20.0-k3s1 k8s.io/legacy-cloud-providers => github.com/k3s-io/kubernetes/staging/src/k8s.io/legacy-cloud-providers v1.20.2-k3s1
k8s.io/metrics => github.com/k3s-io/kubernetes/staging/src/k8s.io/metrics v1.20.0-k3s1 k8s.io/metrics => github.com/k3s-io/kubernetes/staging/src/k8s.io/metrics v1.20.2-k3s1
k8s.io/mount-utils => github.com/k3s-io/kubernetes/staging/src/k8s.io/mount-utils v1.20.0-k3s1 k8s.io/mount-utils => github.com/k3s-io/kubernetes/staging/src/k8s.io/mount-utils v1.20.2-k3s1
k8s.io/node-api => github.com/k3s-io/kubernetes/staging/src/k8s.io/node-api v1.20.0-k3s1 k8s.io/node-api => github.com/k3s-io/kubernetes/staging/src/k8s.io/node-api v1.20.2-k3s1
k8s.io/sample-apiserver => github.com/k3s-io/kubernetes/staging/src/k8s.io/sample-apiserver v1.20.0-k3s1 k8s.io/sample-apiserver => github.com/k3s-io/kubernetes/staging/src/k8s.io/sample-apiserver v1.20.2-k3s1
k8s.io/sample-cli-plugin => github.com/k3s-io/kubernetes/staging/src/k8s.io/sample-cli-plugin v1.20.0-k3s1 k8s.io/sample-cli-plugin => github.com/k3s-io/kubernetes/staging/src/k8s.io/sample-cli-plugin v1.20.2-k3s1
k8s.io/sample-controller => github.com/k3s-io/kubernetes/staging/src/k8s.io/sample-controller v1.20.0-k3s1 k8s.io/sample-controller => github.com/k3s-io/kubernetes/staging/src/k8s.io/sample-controller v1.20.2-k3s1
mvdan.cc/unparam => mvdan.cc/unparam v0.0.0-20190209190245-fbb59629db34 mvdan.cc/unparam => mvdan.cc/unparam v0.0.0-20190209190245-fbb59629db34
) )
...@@ -73,7 +73,7 @@ require ( ...@@ -73,7 +73,7 @@ require (
github.com/coreos/flannel v0.12.0 github.com/coreos/flannel v0.12.0
github.com/coreos/go-iptables v0.4.5 github.com/coreos/go-iptables v0.4.5
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f
github.com/docker/docker v17.12.0-ce-rc1.0.20200916142827-bd33bbf0497b+incompatible github.com/docker/docker v20.10.0-beta1.0.20201108103107-c7109494fe65+incompatible
github.com/erikdubbelboer/gspt v0.0.0-20190125194910-e68493906b83 github.com/erikdubbelboer/gspt v0.0.0-20190125194910-e68493906b83
github.com/frankban/quicktest v1.10.2 // indirect github.com/frankban/quicktest v1.10.2 // indirect
github.com/go-bindata/go-bindata v3.1.2+incompatible github.com/go-bindata/go-bindata v3.1.2+incompatible
...@@ -98,7 +98,7 @@ require ( ...@@ -98,7 +98,7 @@ require (
github.com/rancher/wrangler-api v0.6.0 github.com/rancher/wrangler-api v0.6.0
github.com/robfig/cron/v3 v3.0.1 github.com/robfig/cron/v3 v3.0.1
github.com/rootless-containers/rootlesskit v0.10.0 github.com/rootless-containers/rootlesskit v0.10.0
github.com/sirupsen/logrus v1.6.0 github.com/sirupsen/logrus v1.7.0
github.com/spf13/pflag v1.0.5 github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.6.1 github.com/stretchr/testify v1.6.1
github.com/tchap/go-patricia v2.3.0+incompatible // indirect github.com/tchap/go-patricia v2.3.0+incompatible // indirect
...@@ -107,7 +107,7 @@ require ( ...@@ -107,7 +107,7 @@ require (
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b golang.org/x/net v0.0.0-20201110031124-69a78807bb2b
golang.org/x/sys v0.0.0-20201112073958-5cba982894dd golang.org/x/sys v0.0.0-20201112073958-5cba982894dd
google.golang.org/grpc v1.31.1 google.golang.org/grpc v1.33.2
gopkg.in/yaml.v2 v2.3.0 gopkg.in/yaml.v2 v2.3.0
k8s.io/api v0.19.0 k8s.io/api v0.19.0
k8s.io/apimachinery v0.19.0 k8s.io/apimachinery v0.19.0
...@@ -119,6 +119,6 @@ require ( ...@@ -119,6 +119,6 @@ require (
k8s.io/cri-api v0.19.0 k8s.io/cri-api v0.19.0
k8s.io/klog v1.0.0 k8s.io/klog v1.0.0
k8s.io/kubectl v0.0.0 k8s.io/kubectl v0.0.0
k8s.io/kubernetes v1.20.0 k8s.io/kubernetes v1.20.2
sigs.k8s.io/yaml v1.2.0 sigs.k8s.io/yaml v1.2.0
) )
...@@ -65,11 +65,10 @@ func Client(address, namespace string) (ContainerdClient, error) { ...@@ -65,11 +65,10 @@ func Client(address, namespace string) (ContainerdClient, error) {
tryConn.Close() tryConn.Close()
connParams := grpc.ConnectParams{ connParams := grpc.ConnectParams{
Backoff: backoff.Config{ Backoff: backoff.DefaultConfig,
BaseDelay: baseBackoffDelay,
MaxDelay: maxBackoffDelay,
},
} }
connParams.Backoff.BaseDelay = baseBackoffDelay
connParams.Backoff.MaxDelay = maxBackoffDelay
gopts := []grpc.DialOption{ gopts := []grpc.DialOption{
grpc.WithInsecure(), grpc.WithInsecure(),
grpc.WithContextDialer(dialer.ContextDialer), grpc.WithContextDialer(dialer.ContextDialer),
......
(The MIT License)
Copyright (c) 2017 marvin + konsorten GmbH (open-source@konsorten.de)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# Windows Terminal Sequences
This library allow for enabling Windows terminal color support for Go.
See [Console Virtual Terminal Sequences](https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences) for details.
## Usage
```go
import (
"syscall"
sequences "github.com/konsorten/go-windows-terminal-sequences"
)
func main() {
sequences.EnableVirtualTerminalProcessing(syscall.Stdout, true)
}
```
## Authors
The tool is sponsored by the [marvin + konsorten GmbH](http://www.konsorten.de).
We thank all the authors who provided code to this library:
* Felix Kollmann
* Nicolas Perraut
* @dirty49374
## License
(The MIT License)
Copyright (c) 2018 marvin + konsorten GmbH (open-source@konsorten.de)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
module github.com/konsorten/go-windows-terminal-sequences
// +build windows
package sequences
import (
"syscall"
)
var (
kernel32Dll *syscall.LazyDLL = syscall.NewLazyDLL("Kernel32.dll")
setConsoleMode *syscall.LazyProc = kernel32Dll.NewProc("SetConsoleMode")
)
func EnableVirtualTerminalProcessing(stream syscall.Handle, enable bool) error {
const ENABLE_VIRTUAL_TERMINAL_PROCESSING uint32 = 0x4
var mode uint32
err := syscall.GetConsoleMode(syscall.Stdout, &mode)
if err != nil {
return err
}
if enable {
mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING
} else {
mode &^= ENABLE_VIRTUAL_TERMINAL_PROCESSING
}
ret, _, err := setConsoleMode.Call(uintptr(stream), uintptr(mode))
if ret == 0 {
return err
}
return nil
}
// +build linux darwin
package sequences
import (
"fmt"
)
func EnableVirtualTerminalProcessing(stream uintptr, enable bool) error {
return fmt.Errorf("windows only package")
}
...@@ -57,6 +57,9 @@ type runOptions struct { ...@@ -57,6 +57,9 @@ type runOptions struct {
// podConfig is path to the config for sandbox // podConfig is path to the config for sandbox
podConfig string podConfig string
// the create timeout
timeout time.Duration
// the image pull options // the image pull options
*pullOptions *pullOptions
} }
...@@ -120,7 +123,11 @@ var createContainerCommand = &cli.Command{ ...@@ -120,7 +123,11 @@ var createContainerCommand = &cli.Command{
Name: "create", Name: "create",
Usage: "Create a new container", Usage: "Create a new container",
ArgsUsage: "POD container-config.[json|yaml] pod-config.[json|yaml]", ArgsUsage: "POD container-config.[json|yaml] pod-config.[json|yaml]",
Flags: createPullFlags, Flags: append(createPullFlags, &cli.DurationFlag{
Name: "cancel-timeout",
Aliases: []string{"T"},
Usage: "Seconds to wait for a container create request to complete before cancelling the request",
}),
Action: func(context *cli.Context) error { Action: func(context *cli.Context) error {
if context.Args().Len() != 3 { if context.Args().Len() != 3 {
...@@ -159,6 +166,7 @@ var createContainerCommand = &cli.Command{ ...@@ -159,6 +166,7 @@ var createContainerCommand = &cli.Command{
creds: context.String("creds"), creds: context.String("creds"),
auth: context.String("auth"), auth: context.String("auth"),
}, },
timeout: context.Duration("cancel-timeout"),
}, },
} }
...@@ -265,7 +273,6 @@ var stopContainerCommand = &cli.Command{ ...@@ -265,7 +273,6 @@ var stopContainerCommand = &cli.Command{
&cli.Int64Flag{ &cli.Int64Flag{
Name: "timeout", Name: "timeout",
Aliases: []string{"t"}, Aliases: []string{"t"},
Value: 10,
Usage: "Seconds to wait to kill the container after a graceful stop is requested", Usage: "Seconds to wait to kill the container after a graceful stop is requested",
}, },
}, },
...@@ -530,6 +537,10 @@ var runContainerCommand = &cli.Command{ ...@@ -530,6 +537,10 @@ var runContainerCommand = &cli.Command{
Name: "runtime", Name: "runtime",
Aliases: []string{"r"}, Aliases: []string{"r"},
Usage: "Runtime handler to use. Available options are defined by the container runtime.", Usage: "Runtime handler to use. Available options are defined by the container runtime.",
}, &cli.DurationFlag{
Name: "timeout",
Aliases: []string{"t"},
Usage: "Seconds to wait for a container create request before cancelling the request",
}), }),
Action: func(context *cli.Context) error { Action: func(context *cli.Context) error {
...@@ -569,6 +580,7 @@ var runContainerCommand = &cli.Command{ ...@@ -569,6 +580,7 @@ var runContainerCommand = &cli.Command{
creds: context.String("creds"), creds: context.String("creds"),
auth: context.String("auth"), auth: context.String("auth"),
}, },
timeout: context.Duration("timeout"),
} }
err = RunContainer(imageClient, runtimeClient, opts, context.String("runtime")) err = RunContainer(imageClient, runtimeClient, opts, context.String("runtime"))
...@@ -591,7 +603,9 @@ func RunContainer( ...@@ -591,7 +603,9 @@ func RunContainer(
if err != nil { if err != nil {
return errors.Wrap(err, "load podSandboxConfig") return errors.Wrap(err, "load podSandboxConfig")
} }
podID, err := RunPodSandbox(rClient, podSandboxConfig, runtime) // set the timeout for the RunPodSandbox request to 0, because the
// timeout option is documented as being for container creation.
podID, err := RunPodSandbox(rClient, podSandboxConfig, runtime, 0)
if err != nil { if err != nil {
return errors.Wrap(err, "run pod sandbox") return errors.Wrap(err, "run pod sandbox")
} }
...@@ -655,7 +669,9 @@ func CreateContainer( ...@@ -655,7 +669,9 @@ func CreateContainer(
SandboxConfig: podConfig, SandboxConfig: podConfig,
} }
logrus.Debugf("CreateContainerRequest: %v", request) logrus.Debugf("CreateContainerRequest: %v", request)
r, err := rClient.CreateContainer(context.Background(), request) ctx, cancel := ctxWithTimeout(opts.timeout)
defer cancel()
r, err := rClient.CreateContainer(ctx, request)
logrus.Debugf("CreateContainerResponse: %v", r) logrus.Debugf("CreateContainerResponse: %v", r)
if err != nil { if err != nil {
return "", err return "", err
......
...@@ -52,6 +52,12 @@ var runPodCommand = &cli.Command{ ...@@ -52,6 +52,12 @@ var runPodCommand = &cli.Command{
Aliases: []string{"r"}, Aliases: []string{"r"},
Usage: "Runtime handler to use. Available options are defined by the container runtime.", Usage: "Runtime handler to use. Available options are defined by the container runtime.",
}, },
&cli.DurationFlag{
Name: "cancel-timeout",
Aliases: []string{"T"},
Value: 0,
Usage: "Seconds to wait for a run pod sandbox request to complete before cancelling the request",
},
}, },
Action: func(context *cli.Context) error { Action: func(context *cli.Context) error {
...@@ -72,7 +78,7 @@ var runPodCommand = &cli.Command{ ...@@ -72,7 +78,7 @@ var runPodCommand = &cli.Command{
} }
// Test RuntimeServiceClient.RunPodSandbox // Test RuntimeServiceClient.RunPodSandbox
podID, err := RunPodSandbox(runtimeClient, podSandboxConfig, context.String("runtime")) podID, err := RunPodSandbox(runtimeClient, podSandboxConfig, context.String("runtime"), context.Duration("cancel-timeout"))
if err != nil { if err != nil {
return errors.Wrap(err, "run pod sandbox") return errors.Wrap(err, "run pod sandbox")
} }
...@@ -149,25 +155,26 @@ var removePodCommand = &cli.Command{ ...@@ -149,25 +155,26 @@ var removePodCommand = &cli.Command{
funcs := []func() error{} funcs := []func() error{}
for _, id := range ids { for _, id := range ids {
podId := id
funcs = append(funcs, func() error { funcs = append(funcs, func() error {
resp, err := runtimeClient.PodSandboxStatus(context.Background(), resp, err := runtimeClient.PodSandboxStatus(context.Background(),
&pb.PodSandboxStatusRequest{PodSandboxId: id}) &pb.PodSandboxStatusRequest{PodSandboxId: podId})
if err != nil { if err != nil {
return errors.Wrapf(err, "getting sandbox status of pod %q", id) return errors.Wrapf(err, "getting sandbox status of pod %q", podId)
} }
if resp.Status.State == pb.PodSandboxState_SANDBOX_READY { if resp.Status.State == pb.PodSandboxState_SANDBOX_READY {
if ctx.Bool("force") { if ctx.Bool("force") {
if err := StopPodSandbox(runtimeClient, id); err != nil { if err := StopPodSandbox(runtimeClient, podId); err != nil {
return errors.Wrapf(err, "stopping the pod sandbox %q failed", id) return errors.Wrapf(err, "stopping the pod sandbox %q failed", podId)
} }
} else { } else {
return errors.Errorf("pod sandbox %q is running, please stop it first", id) return errors.Errorf("pod sandbox %q is running, please stop it first", podId)
} }
} }
err = RemovePodSandbox(runtimeClient, id) err = RemovePodSandbox(runtimeClient, podId)
if err != nil { if err != nil {
return errors.Wrapf(err, "removing the pod sandbox %q", id) return errors.Wrapf(err, "removing the pod sandbox %q", podId)
} }
return nil return nil
...@@ -314,13 +321,15 @@ var listPodCommand = &cli.Command{ ...@@ -314,13 +321,15 @@ var listPodCommand = &cli.Command{
// RunPodSandbox sends a RunPodSandboxRequest to the server, and parses // RunPodSandbox sends a RunPodSandboxRequest to the server, and parses
// the returned RunPodSandboxResponse. // the returned RunPodSandboxResponse.
func RunPodSandbox(client pb.RuntimeServiceClient, config *pb.PodSandboxConfig, runtime string) (string, error) { func RunPodSandbox(client pb.RuntimeServiceClient, config *pb.PodSandboxConfig, runtime string, timeout time.Duration) (string, error) {
request := &pb.RunPodSandboxRequest{ request := &pb.RunPodSandboxRequest{
Config: config, Config: config,
RuntimeHandler: runtime, RuntimeHandler: runtime,
} }
logrus.Debugf("RunPodSandboxRequest: %v", request) logrus.Debugf("RunPodSandboxRequest: %v", request)
r, err := client.RunPodSandbox(context.Background(), request) ctx, cancel := ctxWithTimeout(timeout)
defer cancel()
r, err := client.RunPodSandbox(ctx, request)
logrus.Debugf("RunPodSandboxResponse: %v", r) logrus.Debugf("RunPodSandboxResponse: %v", r)
if err != nil { if err != nil {
return "", err return "", err
......
...@@ -18,6 +18,7 @@ package crictl ...@@ -18,6 +18,7 @@ package crictl
import ( import (
"bytes" "bytes"
"context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"os" "os"
...@@ -25,6 +26,7 @@ import ( ...@@ -25,6 +26,7 @@ import (
"regexp" "regexp"
"sort" "sort"
"strings" "strings"
"time"
"github.com/golang/protobuf/jsonpb" "github.com/golang/protobuf/jsonpb"
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
...@@ -342,3 +344,10 @@ func matchesImage(imageClient pb.ImageServiceClient, image string, containerImag ...@@ -342,3 +344,10 @@ func matchesImage(imageClient pb.ImageServiceClient, image string, containerImag
} }
return r1.Image.Id == r2.Image.Id, nil return r1.Image.Id == r2.Image.Id, nil
} }
func ctxWithTimeout(timeout time.Duration) (context.Context, context.CancelFunc) {
if timeout == 0 {
return context.Background(), func() {}
}
return context.WithTimeout(context.Background(), timeout)
}
package logrus
import (
"bytes"
"sync"
)
var (
bufferPool BufferPool
)
type BufferPool interface {
Put(*bytes.Buffer)
Get() *bytes.Buffer
}
type defaultPool struct {
pool *sync.Pool
}
func (p *defaultPool) Put(buf *bytes.Buffer) {
p.pool.Put(buf)
}
func (p *defaultPool) Get() *bytes.Buffer {
return p.pool.Get().(*bytes.Buffer)
}
func getBuffer() *bytes.Buffer {
return bufferPool.Get()
}
func putBuffer(buf *bytes.Buffer) {
buf.Reset()
bufferPool.Put(buf)
}
// SetBufferPool allows to replace the default logrus buffer pool
// to better meets the specific needs of an application.
func SetBufferPool(bp BufferPool) {
bufferPool = bp
}
func init() {
SetBufferPool(&defaultPool{
pool: &sync.Pool{
New: func() interface{} {
return new(bytes.Buffer)
},
},
})
}
...@@ -13,7 +13,6 @@ import ( ...@@ -13,7 +13,6 @@ import (
) )
var ( var (
bufferPool *sync.Pool
// qualified package name, cached at first use // qualified package name, cached at first use
logrusPackage string logrusPackage string
...@@ -31,12 +30,6 @@ const ( ...@@ -31,12 +30,6 @@ const (
) )
func init() { func init() {
bufferPool = &sync.Pool{
New: func() interface{} {
return new(bytes.Buffer)
},
}
// start at the bottom of the stack before the package-name cache is primed // start at the bottom of the stack before the package-name cache is primed
minimumCallerDepth = 1 minimumCallerDepth = 1
} }
...@@ -243,9 +236,12 @@ func (entry Entry) log(level Level, msg string) { ...@@ -243,9 +236,12 @@ func (entry Entry) log(level Level, msg string) {
entry.fireHooks() entry.fireHooks()
buffer = bufferPool.Get().(*bytes.Buffer) buffer = getBuffer()
defer func() {
entry.Buffer = nil
putBuffer(buffer)
}()
buffer.Reset() buffer.Reset()
defer bufferPool.Put(buffer)
entry.Buffer = buffer entry.Buffer = buffer
entry.write() entry.write()
......
...@@ -134,6 +134,51 @@ func Fatal(args ...interface{}) { ...@@ -134,6 +134,51 @@ func Fatal(args ...interface{}) {
std.Fatal(args...) std.Fatal(args...)
} }
// TraceFn logs a message from a func at level Trace on the standard logger.
func TraceFn(fn LogFunction) {
std.TraceFn(fn)
}
// DebugFn logs a message from a func at level Debug on the standard logger.
func DebugFn(fn LogFunction) {
std.DebugFn(fn)
}
// PrintFn logs a message from a func at level Info on the standard logger.
func PrintFn(fn LogFunction) {
std.PrintFn(fn)
}
// InfoFn logs a message from a func at level Info on the standard logger.
func InfoFn(fn LogFunction) {
std.InfoFn(fn)
}
// WarnFn logs a message from a func at level Warn on the standard logger.
func WarnFn(fn LogFunction) {
std.WarnFn(fn)
}
// WarningFn logs a message from a func at level Warn on the standard logger.
func WarningFn(fn LogFunction) {
std.WarningFn(fn)
}
// ErrorFn logs a message from a func at level Error on the standard logger.
func ErrorFn(fn LogFunction) {
std.ErrorFn(fn)
}
// PanicFn logs a message from a func at level Panic on the standard logger.
func PanicFn(fn LogFunction) {
std.PanicFn(fn)
}
// FatalFn logs a message from a func at level Fatal on the standard logger then the process will exit with status set to 1.
func FatalFn(fn LogFunction) {
std.FatalFn(fn)
}
// Tracef logs a message at level Trace on the standard logger. // Tracef logs a message at level Trace on the standard logger.
func Tracef(format string, args ...interface{}) { func Tracef(format string, args ...interface{}) {
std.Tracef(format, args...) std.Tracef(format, args...)
......
...@@ -2,10 +2,9 @@ module github.com/sirupsen/logrus ...@@ -2,10 +2,9 @@ module github.com/sirupsen/logrus
require ( require (
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/konsorten/go-windows-terminal-sequences v1.0.3
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/testify v1.2.2 github.com/stretchr/testify v1.2.2
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 golang.org/x/sys v0.0.0-20191026070338-33540a1f6037
) )
go 1.13 go 1.13
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
...@@ -9,6 +9,11 @@ import ( ...@@ -9,6 +9,11 @@ import (
"time" "time"
) )
// LogFunction For big messages, it can be more efficient to pass a function
// and only call it if the log level is actually enables rather than
// generating the log message and then checking if the level is enabled
type LogFunction func()[]interface{}
type Logger struct { type Logger struct {
// The logs are `io.Copy`'d to this in a mutex. It's common to set this to a // The logs are `io.Copy`'d to this in a mutex. It's common to set this to a
// file, or leave it default which is `os.Stderr`. You can also set this to // file, or leave it default which is `os.Stderr`. You can also set this to
...@@ -70,7 +75,7 @@ func (mw *MutexWrap) Disable() { ...@@ -70,7 +75,7 @@ func (mw *MutexWrap) Disable() {
// //
// var log = &logrus.Logger{ // var log = &logrus.Logger{
// Out: os.Stderr, // Out: os.Stderr,
// Formatter: new(logrus.JSONFormatter), // Formatter: new(logrus.TextFormatter),
// Hooks: make(logrus.LevelHooks), // Hooks: make(logrus.LevelHooks),
// Level: logrus.DebugLevel, // Level: logrus.DebugLevel,
// } // }
...@@ -195,6 +200,14 @@ func (logger *Logger) Log(level Level, args ...interface{}) { ...@@ -195,6 +200,14 @@ func (logger *Logger) Log(level Level, args ...interface{}) {
} }
} }
func (logger *Logger) LogFn(level Level, fn LogFunction) {
if logger.IsLevelEnabled(level) {
entry := logger.newEntry()
entry.Log(level, fn()...)
logger.releaseEntry(entry)
}
}
func (logger *Logger) Trace(args ...interface{}) { func (logger *Logger) Trace(args ...interface{}) {
logger.Log(TraceLevel, args...) logger.Log(TraceLevel, args...)
} }
...@@ -234,6 +247,45 @@ func (logger *Logger) Panic(args ...interface{}) { ...@@ -234,6 +247,45 @@ func (logger *Logger) Panic(args ...interface{}) {
logger.Log(PanicLevel, args...) logger.Log(PanicLevel, args...)
} }
func (logger *Logger) TraceFn(fn LogFunction) {
logger.LogFn(TraceLevel, fn)
}
func (logger *Logger) DebugFn(fn LogFunction) {
logger.LogFn(DebugLevel, fn)
}
func (logger *Logger) InfoFn(fn LogFunction) {
logger.LogFn(InfoLevel, fn)
}
func (logger *Logger) PrintFn(fn LogFunction) {
entry := logger.newEntry()
entry.Print(fn()...)
logger.releaseEntry(entry)
}
func (logger *Logger) WarnFn(fn LogFunction) {
logger.LogFn(WarnLevel, fn)
}
func (logger *Logger) WarningFn(fn LogFunction) {
logger.WarnFn(fn)
}
func (logger *Logger) ErrorFn(fn LogFunction) {
logger.LogFn(ErrorLevel, fn)
}
func (logger *Logger) FatalFn(fn LogFunction) {
logger.LogFn(FatalLevel, fn)
logger.Exit(1)
}
func (logger *Logger) PanicFn(fn LogFunction) {
logger.LogFn(PanicLevel, fn)
}
func (logger *Logger) Logln(level Level, args ...interface{}) { func (logger *Logger) Logln(level Level, args ...interface{}) {
if logger.IsLevelEnabled(level) { if logger.IsLevelEnabled(level) {
entry := logger.newEntry() entry := logger.newEntry()
......
...@@ -5,30 +5,23 @@ package logrus ...@@ -5,30 +5,23 @@ package logrus
import ( import (
"io" "io"
"os" "os"
"syscall"
sequences "github.com/konsorten/go-windows-terminal-sequences" "golang.org/x/sys/windows"
) )
func initTerminal(w io.Writer) {
switch v := w.(type) {
case *os.File:
sequences.EnableVirtualTerminalProcessing(syscall.Handle(v.Fd()), true)
}
}
func checkIfTerminal(w io.Writer) bool { func checkIfTerminal(w io.Writer) bool {
var ret bool
switch v := w.(type) { switch v := w.(type) {
case *os.File: case *os.File:
handle := windows.Handle(v.Fd())
var mode uint32 var mode uint32
err := syscall.GetConsoleMode(syscall.Handle(v.Fd()), &mode) if err := windows.GetConsoleMode(handle, &mode); err != nil {
ret = (err == nil) return false
default: }
ret = false mode |= windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING
} if err := windows.SetConsoleMode(handle, mode); err != nil {
if ret { return false
initTerminal(w) }
return true
} }
return ret return false
} }
...@@ -17,11 +17,15 @@ Usage documentation exists for each major version. Don't know what version you'r ...@@ -17,11 +17,15 @@ Usage documentation exists for each major version. Don't know what version you'r
- `v2` - [./docs/v2/manual.md](./docs/v2/manual.md) - `v2` - [./docs/v2/manual.md](./docs/v2/manual.md)
- `v1` - [./docs/v1/manual.md](./docs/v1/manual.md) - `v1` - [./docs/v1/manual.md](./docs/v1/manual.md)
Guides for migrating to newer versions:
- `v1-to-v2` - [./docs/migrate-v1-to-v2.md](./docs/migrate-v1-to-v2.md)
## Installation ## Installation
Make sure you have a working Go environment. Go version 1.11+ is supported. [See the install instructions for Go](http://golang.org/doc/install.html). Using this package requires a working Go environment. [See the install instructions for Go](http://golang.org/doc/install.html).
Go Modules are strongly recommended when using this package. [See the go blog guide on using Go Modules](https://blog.golang.org/using-go-modules). Go Modules are required when using this package. [See the go blog guide on using Go Modules](https://blog.golang.org/using-go-modules).
### Using `v2` releases ### Using `v2` releases
...@@ -63,4 +67,4 @@ export PATH=$PATH:$GOPATH/bin ...@@ -63,4 +67,4 @@ export PATH=$PATH:$GOPATH/bin
cli is tested against multiple versions of Go on Linux, and against the latest cli is tested against multiple versions of Go on Linux, and against the latest
released version of Go on OS X and Windows. This project uses Github Actions for released version of Go on OS X and Windows. This project uses Github Actions for
builds. For more build info, please look at the [./.github/workflows/cli.yml](https://github.com/urfave/cli/blob/master/.github/workflows/cli.yml). builds. To see our currently supported go versions and platforms, look at the [./.github/workflows/cli.yml](https://github.com/urfave/cli/blob/master/.github/workflows/cli.yml).
...@@ -64,7 +64,7 @@ type App struct { ...@@ -64,7 +64,7 @@ type App struct {
Action ActionFunc Action ActionFunc
// Execute this function if the proper command cannot be found // Execute this function if the proper command cannot be found
CommandNotFound CommandNotFoundFunc CommandNotFound CommandNotFoundFunc
// Execute this function if an usage error occurs // Execute this function if a usage error occurs
OnUsageError OnUsageErrorFunc OnUsageError OnUsageErrorFunc
// Compilation date // Compilation date
Compiled time.Time Compiled time.Time
...@@ -72,12 +72,15 @@ type App struct { ...@@ -72,12 +72,15 @@ type App struct {
Authors []*Author Authors []*Author
// Copyright of the binary if any // Copyright of the binary if any
Copyright string Copyright string
// Reader reader to write input to (useful for tests)
Reader io.Reader
// Writer writer to write output to // Writer writer to write output to
Writer io.Writer Writer io.Writer
// ErrWriter writes error output // ErrWriter writes error output
ErrWriter io.Writer ErrWriter io.Writer
// Execute this function to handle ExitErrors. If not provided, HandleExitCoder is provided to // ExitErrHandler processes any error encountered while running an App before
// function as a default, so this is optional. // it is returned to the caller. If no function is provided, HandleExitCoder
// is used as the default behavior.
ExitErrHandler ExitErrHandlerFunc ExitErrHandler ExitErrHandlerFunc
// Other custom info // Other custom info
Metadata map[string]interface{} Metadata map[string]interface{}
...@@ -116,7 +119,9 @@ func NewApp() *App { ...@@ -116,7 +119,9 @@ func NewApp() *App {
BashComplete: DefaultAppComplete, BashComplete: DefaultAppComplete,
Action: helpCommand.Action, Action: helpCommand.Action,
Compiled: compileTime(), Compiled: compileTime(),
Reader: os.Stdin,
Writer: os.Stdout, Writer: os.Stdout,
ErrWriter: os.Stderr,
} }
} }
...@@ -158,10 +163,18 @@ func (a *App) Setup() { ...@@ -158,10 +163,18 @@ func (a *App) Setup() {
a.Compiled = compileTime() a.Compiled = compileTime()
} }
if a.Reader == nil {
a.Reader = os.Stdin
}
if a.Writer == nil { if a.Writer == nil {
a.Writer = os.Stdout a.Writer = os.Stdout
} }
if a.ErrWriter == nil {
a.ErrWriter = os.Stderr
}
var newCommands []*Command var newCommands []*Command
for _, c := range a.Commands { for _, c := range a.Commands {
...@@ -195,10 +208,6 @@ func (a *App) Setup() { ...@@ -195,10 +208,6 @@ func (a *App) Setup() {
if a.Metadata == nil { if a.Metadata == nil {
a.Metadata = make(map[string]interface{}) a.Metadata = make(map[string]interface{})
} }
if a.Writer == nil {
a.Writer = os.Stdout
}
} }
func (a *App) newFlagSet() (*flag.FlagSet, error) { func (a *App) newFlagSet() (*flag.FlagSet, error) {
...@@ -290,8 +299,6 @@ func (a *App) RunContext(ctx context.Context, arguments []string) (err error) { ...@@ -290,8 +299,6 @@ func (a *App) RunContext(ctx context.Context, arguments []string) (err error) {
if a.Before != nil { if a.Before != nil {
beforeErr := a.Before(context) beforeErr := a.Before(context)
if beforeErr != nil { if beforeErr != nil {
_, _ = fmt.Fprintf(a.Writer, "%v\n\n", beforeErr)
_ = ShowAppHelp(context)
a.handleExitCoder(context, beforeErr) a.handleExitCoder(context, beforeErr)
err = beforeErr err = beforeErr
return err return err
...@@ -325,7 +332,7 @@ func (a *App) RunContext(ctx context.Context, arguments []string) (err error) { ...@@ -325,7 +332,7 @@ func (a *App) RunContext(ctx context.Context, arguments []string) (err error) {
// code in the cli.ExitCoder // code in the cli.ExitCoder
func (a *App) RunAndExitOnError() { func (a *App) RunAndExitOnError() {
if err := a.Run(os.Args); err != nil { if err := a.Run(os.Args); err != nil {
_, _ = fmt.Fprintln(a.errWriter(), err) _, _ = fmt.Fprintln(a.ErrWriter, err)
OsExiter(1) OsExiter(1)
} }
} }
...@@ -479,15 +486,6 @@ func (a *App) VisibleFlags() []Flag { ...@@ -479,15 +486,6 @@ func (a *App) VisibleFlags() []Flag {
return visibleFlags(a.Flags) return visibleFlags(a.Flags)
} }
func (a *App) errWriter() io.Writer {
// When the app ErrWriter is nil use the package level one.
if a.ErrWriter == nil {
return ErrWriter
}
return a.ErrWriter
}
func (a *App) appendFlag(fl Flag) { func (a *App) appendFlag(fl Flag) {
if !hasFlag(a.Flags, fl) { if !hasFlag(a.Flags, fl) {
a.Flags = append(a.Flags, fl) a.Flags = append(a.Flags, fl)
......
...@@ -150,7 +150,6 @@ func (c *Command) Run(ctx *Context) (err error) { ...@@ -150,7 +150,6 @@ func (c *Command) Run(ctx *Context) (err error) {
if c.Before != nil { if c.Before != nil {
err = c.Before(context) err = c.Before(context)
if err != nil { if err != nil {
_ = ShowCommandHelp(context, c.Name)
context.App.handleExitCoder(context, err) context.App.handleExitCoder(context, err)
return err return err
} }
...@@ -242,7 +241,7 @@ func (c *Command) startApp(ctx *Context) error { ...@@ -242,7 +241,7 @@ func (c *Command) startApp(ctx *Context) error {
app.HideHelpCommand = c.HideHelpCommand app.HideHelpCommand = c.HideHelpCommand
app.Version = ctx.App.Version app.Version = ctx.App.Version
app.HideVersion = ctx.App.HideVersion app.HideVersion = true
app.Compiled = ctx.App.Compiled app.Compiled = ctx.App.Compiled
app.Writer = ctx.App.Writer app.Writer = ctx.App.Writer
app.ErrWriter = ctx.App.ErrWriter app.ErrWriter = ctx.App.ErrWriter
......
...@@ -17,11 +17,10 @@ var ErrWriter io.Writer = os.Stderr ...@@ -17,11 +17,10 @@ var ErrWriter io.Writer = os.Stderr
// MultiError is an error that wraps multiple errors. // MultiError is an error that wraps multiple errors.
type MultiError interface { type MultiError interface {
error error
// Errors returns a copy of the errors slice
Errors() []error Errors() []error
} }
// NewMultiError creates a new MultiError. Pass in one or more errors. // newMultiError creates a new MultiError. Pass in one or more errors.
func newMultiError(err ...error) MultiError { func newMultiError(err ...error) MultiError {
ret := multiError(err) ret := multiError(err)
return &ret return &ret
...@@ -65,13 +64,20 @@ type exitError struct { ...@@ -65,13 +64,20 @@ type exitError struct {
message interface{} message interface{}
} }
// NewExitError makes a new *exitError // NewExitError calls Exit to create a new ExitCoder.
//
// Deprecated: This function is a duplicate of Exit and will eventually be removed.
func NewExitError(message interface{}, exitCode int) ExitCoder { func NewExitError(message interface{}, exitCode int) ExitCoder {
return Exit(message, exitCode) return Exit(message, exitCode)
} }
// Exit wraps a message and exit code into an ExitCoder suitable for handling by // Exit wraps a message and exit code into an error, which by default is
// HandleExitCoder // handled with a call to os.Exit during default error handling.
//
// This is the simplest way to trigger a non-zero exit code for an App without
// having to call os.Exit manually. During testing, this behavior can be avoided
// by overiding the ExitErrHandler function on an App or the package-global
// OsExiter function.
func Exit(message interface{}, exitCode int) ExitCoder { func Exit(message interface{}, exitCode int) ExitCoder {
return &exitError{ return &exitError{
message: message, message: message,
...@@ -87,10 +93,14 @@ func (ee *exitError) ExitCode() int { ...@@ -87,10 +93,14 @@ func (ee *exitError) ExitCode() int {
return ee.exitCode return ee.exitCode
} }
// HandleExitCoder checks if the error fulfills the ExitCoder interface, and if // HandleExitCoder handles errors implementing ExitCoder by printing their
// so prints the error to stderr (if it is non-empty) and calls OsExiter with the // message and calling OsExiter with the given exit code.
// given exit code. If the given error is a MultiError, then this func is //
// called on all members of the Errors slice and calls OsExiter with the last exit code. // If the given error instead implements MultiError, each error will be checked
// for the ExitCoder interface, and OsExiter will be called with the last exit
// code found, or exit code 1 if no ExitCoder is found.
//
// This function is the default error-handling behavior for an App.
func HandleExitCoder(err error) { func HandleExitCoder(err error) {
if err == nil { if err == nil {
return return
......
...@@ -171,6 +171,10 @@ func fishAddFileFlag(flag Flag, completion *strings.Builder) { ...@@ -171,6 +171,10 @@ func fishAddFileFlag(flag Flag, completion *strings.Builder) {
if f.TakesFile { if f.TakesFile {
return return
} }
case *PathFlag:
if f.TakesFile {
return
}
} }
completion.WriteString(" -f") completion.WriteString(" -f")
} }
......
...@@ -116,8 +116,17 @@ func (f *StringSliceFlag) GetValue() string { ...@@ -116,8 +116,17 @@ func (f *StringSliceFlag) GetValue() string {
// Apply populates the flag given the flag set and environment // Apply populates the flag given the flag set and environment
func (f *StringSliceFlag) Apply(set *flag.FlagSet) error { func (f *StringSliceFlag) Apply(set *flag.FlagSet) error {
if f.Destination != nil && f.Value != nil {
f.Destination.slice = make([]string, len(f.Value.slice))
copy(f.Destination.slice, f.Value.slice)
}
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok { if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
f.Value = &StringSlice{} if f.Value == nil {
f.Value = &StringSlice{}
}
destination := f.Value destination := f.Value
if f.Destination != nil { if f.Destination != nil {
destination = f.Destination destination = f.Destination
......
...@@ -118,7 +118,9 @@ func (f *TimestampFlag) Apply(set *flag.FlagSet) error { ...@@ -118,7 +118,9 @@ func (f *TimestampFlag) Apply(set *flag.FlagSet) error {
if f.Layout == "" { if f.Layout == "" {
return fmt.Errorf("timestamp Layout is required") return fmt.Errorf("timestamp Layout is required")
} }
f.Value = &Timestamp{} if f.Value == nil {
f.Value = &Timestamp{}
}
f.Value.SetLayout(f.Layout) f.Value.SetLayout(f.Layout)
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok { if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
......
...@@ -5,5 +5,5 @@ go 1.11 ...@@ -5,5 +5,5 @@ go 1.11
require ( require (
github.com/BurntSushi/toml v0.3.1 github.com/BurntSushi/toml v0.3.1
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d
gopkg.in/yaml.v2 v2.2.2 gopkg.in/yaml.v2 v2.2.3
) )
...@@ -10,5 +10,5 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5I ...@@ -10,5 +10,5 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5I
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.3 h1:fvjTMHxHEw/mxHbtzPi3JCcKXQRAnQTBRo6YCJSVHKI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
...@@ -72,13 +72,13 @@ func ShowAppHelpAndExit(c *Context, exitCode int) { ...@@ -72,13 +72,13 @@ func ShowAppHelpAndExit(c *Context, exitCode int) {
// ShowAppHelp is an action that displays the help. // ShowAppHelp is an action that displays the help.
func ShowAppHelp(c *Context) error { func ShowAppHelp(c *Context) error {
template := c.App.CustomAppHelpTemplate tpl := c.App.CustomAppHelpTemplate
if template == "" { if tpl == "" {
template = AppHelpTemplate tpl = AppHelpTemplate
} }
if c.App.ExtraInfo == nil { if c.App.ExtraInfo == nil {
HelpPrinter(c.App.Writer, template, c.App) HelpPrinter(c.App.Writer, tpl, c.App)
return nil return nil
} }
...@@ -87,7 +87,7 @@ func ShowAppHelp(c *Context) error { ...@@ -87,7 +87,7 @@ func ShowAppHelp(c *Context) error {
"ExtraInfo": c.App.ExtraInfo, "ExtraInfo": c.App.ExtraInfo,
} }
} }
HelpPrinterCustom(c.App.Writer, template, c.App, customAppData()) HelpPrinterCustom(c.App.Writer, tpl, c.App, customAppData())
return nil return nil
} }
...@@ -214,6 +214,12 @@ func ShowCommandHelp(ctx *Context, command string) error { ...@@ -214,6 +214,12 @@ func ShowCommandHelp(ctx *Context, command string) error {
return nil return nil
} }
// ShowSubcommandHelpAndExit - Prints help for the given subcommand and exits with exit code.
func ShowSubcommandHelpAndExit(c *Context, exitCode int) {
_ = ShowSubcommandHelp(c)
os.Exit(exitCode)
}
// ShowSubcommandHelp prints help for the given subcommand // ShowSubcommandHelp prints help for the given subcommand
func ShowSubcommandHelp(c *Context) error { func ShowSubcommandHelp(c *Context) error {
if c == nil { if c == nil {
...@@ -263,7 +269,10 @@ func ShowCommandCompletions(ctx *Context, command string) { ...@@ -263,7 +269,10 @@ func ShowCommandCompletions(ctx *Context, command string) {
// allow using arbitrary functions in template rendering. // allow using arbitrary functions in template rendering.
func printHelpCustom(out io.Writer, templ string, data interface{}, customFuncs map[string]interface{}) { func printHelpCustom(out io.Writer, templ string, data interface{}, customFuncs map[string]interface{}) {
funcMap := template.FuncMap{ funcMap := template.FuncMap{
"join": strings.Join, "join": strings.Join,
"indent": indent,
"nindent": nindent,
"trim": strings.TrimSpace,
} }
for key, value := range customFuncs { for key, value := range customFuncs {
funcMap[key] = value funcMap[key] = value
...@@ -366,3 +375,12 @@ func checkCommandCompletions(c *Context, name string) bool { ...@@ -366,3 +375,12 @@ func checkCommandCompletions(c *Context, name string) bool {
ShowCommandCompletions(c, name) ShowCommandCompletions(c, name)
return true return true
} }
func indent(spaces int, v string) string {
pad := strings.Repeat(" ", spaces)
return pad + strings.Replace(v, "\n", "\n"+pad, -1)
}
func nindent(spaces int, v string) string {
return "\n" + indent(spaces, v)
}
...@@ -13,7 +13,7 @@ VERSION: ...@@ -13,7 +13,7 @@ VERSION:
{{.Version}}{{end}}{{end}}{{if .Description}} {{.Version}}{{end}}{{end}}{{if .Description}}
DESCRIPTION: DESCRIPTION:
{{.Description}}{{end}}{{if len .Authors}} {{.Description | nindent 3 | trim}}{{end}}{{if len .Authors}}
AUTHOR{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}: AUTHOR{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}:
{{range $index, $author := .Authors}}{{if $index}} {{range $index, $author := .Authors}}{{if $index}}
...@@ -45,7 +45,7 @@ CATEGORY: ...@@ -45,7 +45,7 @@ CATEGORY:
{{.Category}}{{end}}{{if .Description}} {{.Category}}{{end}}{{if .Description}}
DESCRIPTION: DESCRIPTION:
{{.Description}}{{end}}{{if .VisibleFlags}} {{.Description | nindent 3 | trim}}{{end}}{{if .VisibleFlags}}
OPTIONS: OPTIONS:
{{range .VisibleFlags}}{{.}} {{range .VisibleFlags}}{{.}}
...@@ -62,7 +62,7 @@ USAGE: ...@@ -62,7 +62,7 @@ USAGE:
{{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Description}} {{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Description}}
DESCRIPTION: DESCRIPTION:
{{.Description}}{{end}} {{.Description | nindent 3 | trim}}{{end}}
COMMANDS:{{range .VisibleCategories}}{{if .Name}} COMMANDS:{{range .VisibleCategories}}{{if .Name}}
{{.Name}}:{{range .VisibleCommands}} {{.Name}}:{{range .VisibleCommands}}
......
...@@ -510,7 +510,10 @@ func CheckRequest(quotas []corev1.ResourceQuota, a admission.Attributes, evaluat ...@@ -510,7 +510,10 @@ func CheckRequest(quotas []corev1.ResourceQuota, a admission.Attributes, evaluat
} }
} }
if quota.IsZero(deltaUsage) { // ignore items in deltaUsage with zero usage
deltaUsage = quota.RemoveZeros(deltaUsage)
// if there is no remaining non-zero usage, short-circuit and return
if len(deltaUsage) == 0 {
return quotas, nil return quotas, nil
} }
......
...@@ -226,6 +226,17 @@ func IsZero(a corev1.ResourceList) bool { ...@@ -226,6 +226,17 @@ func IsZero(a corev1.ResourceList) bool {
return true return true
} }
// RemoveZeros returns a new resource list that only has no zero values
func RemoveZeros(a corev1.ResourceList) corev1.ResourceList {
result := corev1.ResourceList{}
for key, value := range a {
if !value.IsZero() {
result[key] = value
}
}
return result
}
// IsNegative returns the set of resource names that have a negative value. // IsNegative returns the set of resource names that have a negative value.
func IsNegative(a corev1.ResourceList) []corev1.ResourceName { func IsNegative(a corev1.ResourceList) []corev1.ResourceName {
results := []corev1.ResourceName{} results := []corev1.ResourceName{}
......
...@@ -21,10 +21,13 @@ go_test( ...@@ -21,10 +21,13 @@ go_test(
"//staging/src/k8s.io/api/flowcontrol/v1beta1:go_default_library", "//staging/src/k8s.io/api/flowcontrol/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/apis/flowcontrol/bootstrap:go_default_library", "//staging/src/k8s.io/apiserver/pkg/apis/flowcontrol/bootstrap:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/endpoints/filters:go_default_library", "//staging/src/k8s.io/apiserver/pkg/endpoints/filters:go_default_library",
...@@ -34,7 +37,11 @@ go_test( ...@@ -34,7 +37,11 @@ go_test(
"//staging/src/k8s.io/apiserver/pkg/util/flowcontrol:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/flowcontrol:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/flowcontrol/metrics:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/flowcontrol/metrics:go_default_library",
"//staging/src/k8s.io/client-go/informers:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
"//staging/src/k8s.io/component-base/metrics/legacyregistry:go_default_library", "//staging/src/k8s.io/component-base/metrics/legacyregistry:go_default_library",
"//staging/src/k8s.io/component-base/metrics/testutil:go_default_library",
"//vendor/golang.org/x/net/http2:go_default_library", "//vendor/golang.org/x/net/http2:go_default_library",
"//vendor/k8s.io/klog/v2:go_default_library", "//vendor/k8s.io/klog/v2:go_default_library",
], ],
......
...@@ -78,6 +78,7 @@ go_test( ...@@ -78,6 +78,7 @@ go_test(
"//staging/src/k8s.io/api/flowcontrol/v1beta1:go_default_library", "//staging/src/k8s.io/api/flowcontrol/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/apis/flowcontrol/bootstrap:go_default_library", "//staging/src/k8s.io/apiserver/pkg/apis/flowcontrol/bootstrap:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library", "//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
......
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- lavalamp
- deads2k
- yue9944882
- MikeSpreitzer
reviewers:
- lavalamp
- deads2k
- yue9944882
- MikeSpreitzer
labels:
- sig/api-machinery
- area/apiserver
...@@ -34,6 +34,7 @@ import ( ...@@ -34,6 +34,7 @@ import (
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
apitypes "k8s.io/apimachinery/pkg/types" apitypes "k8s.io/apimachinery/pkg/types"
apierrors "k8s.io/apimachinery/pkg/util/errors" apierrors "k8s.io/apimachinery/pkg/util/errors"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
fcboot "k8s.io/apiserver/pkg/apis/flowcontrol/bootstrap" fcboot "k8s.io/apiserver/pkg/apis/flowcontrol/bootstrap"
"k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/authentication/user"
...@@ -244,14 +245,28 @@ func (cfgCtlr *configController) updateObservations() { ...@@ -244,14 +245,28 @@ func (cfgCtlr *configController) updateObservations() {
} }
} }
// used from the unit tests only.
func (cfgCtlr *configController) getPriorityLevelState(plName string) *priorityLevelState {
cfgCtlr.lock.Lock()
defer cfgCtlr.lock.Unlock()
return cfgCtlr.priorityLevelStates[plName]
}
func (cfgCtlr *configController) Run(stopCh <-chan struct{}) error { func (cfgCtlr *configController) Run(stopCh <-chan struct{}) error {
defer utilruntime.HandleCrash()
// Let the config worker stop when we are done
defer cfgCtlr.configQueue.ShutDown() defer cfgCtlr.configQueue.ShutDown()
klog.Info("Starting API Priority and Fairness config controller") klog.Info("Starting API Priority and Fairness config controller")
if ok := cache.WaitForCacheSync(stopCh, cfgCtlr.plInformerSynced, cfgCtlr.fsInformerSynced); !ok { if ok := cache.WaitForCacheSync(stopCh, cfgCtlr.plInformerSynced, cfgCtlr.fsInformerSynced); !ok {
return fmt.Errorf("Never achieved initial sync") return fmt.Errorf("Never achieved initial sync")
} }
klog.Info("Running API Priority and Fairness config worker") klog.Info("Running API Priority and Fairness config worker")
wait.Until(cfgCtlr.runWorker, time.Second, stopCh) go wait.Until(cfgCtlr.runWorker, time.Second, stopCh)
<-stopCh
klog.Info("Shutting down API Priority and Fairness config worker") klog.Info("Shutting down API Priority and Fairness config worker")
return nil return nil
} }
......
...@@ -112,21 +112,28 @@ func (cfgCtlr *configController) Handle(ctx context.Context, requestDigest Reque ...@@ -112,21 +112,28 @@ func (cfgCtlr *configController) Handle(ctx context.Context, requestDigest Reque
} }
klog.V(7).Infof("Handle(%#+v) => fsName=%q, distMethod=%#+v, plName=%q, isExempt=%v, queued=%v", requestDigest, fs.Name, fs.Spec.DistinguisherMethod, pl.Name, isExempt, queued) klog.V(7).Infof("Handle(%#+v) => fsName=%q, distMethod=%#+v, plName=%q, isExempt=%v, queued=%v", requestDigest, fs.Name, fs.Spec.DistinguisherMethod, pl.Name, isExempt, queued)
var executed bool var executed bool
idle := req.Finish(func() { idle, panicking := true, true
defer func() {
klog.V(7).Infof("Handle(%#+v) => fsName=%q, distMethod=%#+v, plName=%q, isExempt=%v, queued=%v, Finish() => panicking=%v idle=%v",
requestDigest, fs.Name, fs.Spec.DistinguisherMethod, pl.Name, isExempt, queued, panicking, idle)
if idle {
cfgCtlr.maybeReap(pl.Name)
}
}()
idle = req.Finish(func() {
if queued { if queued {
metrics.ObserveWaitingDuration(pl.Name, fs.Name, strconv.FormatBool(req != nil), time.Since(startWaitingTime)) metrics.ObserveWaitingDuration(pl.Name, fs.Name, strconv.FormatBool(req != nil), time.Since(startWaitingTime))
} }
metrics.AddDispatch(pl.Name, fs.Name) metrics.AddDispatch(pl.Name, fs.Name)
executed = true executed = true
startExecutionTime := time.Now() startExecutionTime := time.Now()
defer func() {
metrics.ObserveExecutionDuration(pl.Name, fs.Name, time.Since(startExecutionTime))
}()
execFn() execFn()
metrics.ObserveExecutionDuration(pl.Name, fs.Name, time.Since(startExecutionTime))
}) })
if queued && !executed { if queued && !executed {
metrics.ObserveWaitingDuration(pl.Name, fs.Name, strconv.FormatBool(req != nil), time.Since(startWaitingTime)) metrics.ObserveWaitingDuration(pl.Name, fs.Name, strconv.FormatBool(req != nil), time.Since(startWaitingTime))
} }
klog.V(7).Infof("Handle(%#+v) => fsName=%q, distMethod=%#+v, plName=%q, isExempt=%v, queued=%v, Finish() => idle=%v", requestDigest, fs.Name, fs.Spec.DistinguisherMethod, pl.Name, isExempt, queued, idle) panicking = false
if idle {
cfgCtlr.maybeReap(pl.Name)
}
} }
...@@ -316,8 +316,15 @@ func (req *request) Finish(execFn func()) bool { ...@@ -316,8 +316,15 @@ func (req *request) Finish(execFn func()) bool {
if !exec { if !exec {
return idle return idle
} }
execFn() func() {
return req.qs.finishRequestAndDispatchAsMuchAsPossible(req) defer func() {
idle = req.qs.finishRequestAndDispatchAsMuchAsPossible(req)
}()
execFn()
}()
return idle
} }
func (req *request) wait() (bool, bool) { func (req *request) wait() (bool, bool) {
......
...@@ -160,17 +160,14 @@ func (saw *sampleAndWaterMarkHistograms) SetX1(x1 float64) { ...@@ -160,17 +160,14 @@ func (saw *sampleAndWaterMarkHistograms) SetX1(x1 float64) {
} }
func (saw *sampleAndWaterMarkHistograms) innerSet(updateXOrX1 func()) { func (saw *sampleAndWaterMarkHistograms) innerSet(updateXOrX1 func()) {
var when time.Time when, whenInt, acc, wellOrdered := func() (time.Time, int64, sampleAndWaterMarkAccumulator, bool) {
var whenInt int64
var acc sampleAndWaterMarkAccumulator
var wellOrdered bool
func() {
saw.Lock() saw.Lock()
defer saw.Unlock() defer saw.Unlock()
when = saw.clock.Now() // Moved these variables here to tiptoe around https://github.com/golang/go/issues/43570 for #97685
whenInt = saw.quantize(when) when := saw.clock.Now()
acc = saw.sampleAndWaterMarkAccumulator whenInt := saw.quantize(when)
wellOrdered = !when.Before(acc.lastSet) acc := saw.sampleAndWaterMarkAccumulator
wellOrdered := !when.Before(acc.lastSet)
updateXOrX1() updateXOrX1()
saw.relX = saw.x / saw.x1 saw.relX = saw.x / saw.x1
if wellOrdered { if wellOrdered {
...@@ -195,6 +192,7 @@ func (saw *sampleAndWaterMarkHistograms) innerSet(updateXOrX1 func()) { ...@@ -195,6 +192,7 @@ func (saw *sampleAndWaterMarkHistograms) innerSet(updateXOrX1 func()) {
} else if saw.relX > saw.hiRelX { } else if saw.relX > saw.hiRelX {
saw.hiRelX = saw.relX saw.hiRelX = saw.relX
} }
return when, whenInt, acc, wellOrdered
}() }()
if !wellOrdered { if !wellOrdered {
lastSetS := acc.lastSet.String() lastSetS := acc.lastSet.String()
......
...@@ -3,8 +3,8 @@ package version ...@@ -3,8 +3,8 @@ package version
var ( var (
gitMajor = "1" gitMajor = "1"
gitMinor = "20" gitMinor = "20"
gitVersion = "v1.20.0-k3s1" gitVersion = "v1.20.2-k3s1"
gitCommit = "3559625e27197f60bcc39c4b3ecffc80bad7785e" gitCommit = "426bcc7128ac615e92181e084eafdef3b0206d76"
gitTreeState = "clean" gitTreeState = "clean"
buildDate = "2020-12-08T20:42:55Z" buildDate = "2021-01-13T19:38:13Z"
) )
...@@ -3,8 +3,8 @@ package version ...@@ -3,8 +3,8 @@ package version
var ( var (
gitMajor = "1" gitMajor = "1"
gitMinor = "20" gitMinor = "20"
gitVersion = "v1.20.0-k3s1" gitVersion = "v1.20.2-k3s1"
gitCommit = "3559625e27197f60bcc39c4b3ecffc80bad7785e" gitCommit = "426bcc7128ac615e92181e084eafdef3b0206d76"
gitTreeState = "clean" gitTreeState = "clean"
buildDate = "2020-12-08T20:42:55Z" buildDate = "2021-01-13T19:38:13Z"
) )
...@@ -402,6 +402,7 @@ func (m *manager) reconcileState() (success []reconciledContainer, failure []rec ...@@ -402,6 +402,7 @@ func (m *manager) reconcileState() (success []reconciledContainer, failure []rec
continue continue
} }
m.Lock()
if cstatus.State.Terminated != nil { if cstatus.State.Terminated != nil {
// The container is terminated but we can't call m.RemoveContainer() // The container is terminated but we can't call m.RemoveContainer()
// here because it could remove the allocated cpuset for the container // here because it could remove the allocated cpuset for the container
...@@ -412,6 +413,7 @@ func (m *manager) reconcileState() (success []reconciledContainer, failure []rec ...@@ -412,6 +413,7 @@ func (m *manager) reconcileState() (success []reconciledContainer, failure []rec
if err == nil { if err == nil {
klog.Warningf("[cpumanager] reconcileState: ignoring terminated container (pod: %s, container id: %s)", pod.Name, containerID) klog.Warningf("[cpumanager] reconcileState: ignoring terminated container (pod: %s, container id: %s)", pod.Name, containerID)
} }
m.Unlock()
continue continue
} }
...@@ -419,6 +421,7 @@ func (m *manager) reconcileState() (success []reconciledContainer, failure []rec ...@@ -419,6 +421,7 @@ func (m *manager) reconcileState() (success []reconciledContainer, failure []rec
// Idempotently add it to the containerMap incase it is missing. // Idempotently add it to the containerMap incase it is missing.
// This can happen after a kubelet restart, for example. // This can happen after a kubelet restart, for example.
m.containerMap.Add(string(pod.UID), container.Name, containerID) m.containerMap.Add(string(pod.UID), container.Name, containerID)
m.Unlock()
cset := m.state.GetCPUSetOrDefault(string(pod.UID), container.Name) cset := m.state.GetCPUSetOrDefault(string(pod.UID), container.Name)
if cset.IsEmpty() { if cset.IsEmpty() {
......
...@@ -551,6 +551,9 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration, ...@@ -551,6 +551,9 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration,
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Avoid collector collects it as a timestamped metric
// See PR #95210 and #97006 for more details.
machineInfo.Timestamp = time.Time{}
klet.setCachedMachineInfo(machineInfo) klet.setCachedMachineInfo(machineInfo)
imageBackOff := flowcontrol.NewBackOff(backOffPeriod, MaxContainerBackOff) imageBackOff := flowcontrol.NewBackOff(backOffPeriod, MaxContainerBackOff)
......
...@@ -150,7 +150,7 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h ...@@ -150,7 +150,7 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h
mountEtcHostsFile = mountEtcHostsFile && (mount.MountPath != etcHostsPath) mountEtcHostsFile = mountEtcHostsFile && (mount.MountPath != etcHostsPath)
vol, ok := podVolumes[mount.Name] vol, ok := podVolumes[mount.Name]
if !ok || vol.Mounter == nil { if !ok || vol.Mounter == nil {
klog.Errorf("Mount cannot be satisfied for container %q, because the volume is missing or the volume mounter is nil: %+v", container.Name, mount) klog.Errorf("Mount cannot be satisfied for container %q, because the volume is missing (ok=%v) or the volume mounter (vol.Mounter) is nil (vol=%+v): %+v", container.Name, ok, vol, mount)
return nil, cleanupAction, fmt.Errorf("cannot find volume %q to mount into container %q", mount.Name, container.Name) return nil, cleanupAction, fmt.Errorf("cannot find volume %q to mount into container %q", mount.Name, container.Name)
} }
......
...@@ -367,6 +367,7 @@ func (s *Server) InstallDefaultHandlers(enableCAdvisorJSONEndpoints bool) { ...@@ -367,6 +367,7 @@ func (s *Server) InstallDefaultHandlers(enableCAdvisorJSONEndpoints bool) {
Recursive: true, Recursive: true,
} }
r.RawMustRegister(metrics.NewPrometheusCollector(prometheusHostAdapter{s.host}, containerPrometheusLabelsFunc(s.host), includedMetrics, clock.RealClock{}, cadvisorOpts)) r.RawMustRegister(metrics.NewPrometheusCollector(prometheusHostAdapter{s.host}, containerPrometheusLabelsFunc(s.host), includedMetrics, clock.RealClock{}, cadvisorOpts))
r.RawMustRegister(metrics.NewPrometheusMachineCollector(prometheusHostAdapter{s.host}, includedMetrics))
s.restfulCont.Handle(cadvisorMetricsPath, s.restfulCont.Handle(cadvisorMetricsPath,
compbasemetrics.HandlerFor(r, compbasemetrics.HandlerOpts{ErrorHandling: compbasemetrics.ContinueOnError}), compbasemetrics.HandlerFor(r, compbasemetrics.HandlerOpts{ErrorHandling: compbasemetrics.ContinueOnError}),
) )
......
...@@ -292,7 +292,7 @@ func (p *criStatsProvider) ListPodCPUAndMemoryStats() ([]statsapi.PodStats, erro ...@@ -292,7 +292,7 @@ func (p *criStatsProvider) ListPodCPUAndMemoryStats() ([]statsapi.PodStats, erro
if !caFound { if !caFound {
klog.V(4).Infof("Unable to find cadvisor stats for %q", containerID) klog.V(4).Infof("Unable to find cadvisor stats for %q", containerID)
} else { } else {
p.addCadvisorContainerStats(cs, &caStats) p.addCadvisorContainerCPUAndMemoryStats(cs, &caStats)
} }
ps.Containers = append(ps.Containers, *cs) ps.Containers = append(ps.Containers, *cs)
} }
...@@ -792,6 +792,25 @@ func (p *criStatsProvider) addCadvisorContainerStats( ...@@ -792,6 +792,25 @@ func (p *criStatsProvider) addCadvisorContainerStats(
if memory != nil { if memory != nil {
cs.Memory = memory cs.Memory = memory
} }
accelerators := cadvisorInfoToAcceleratorStats(caPodStats)
cs.Accelerators = accelerators
}
func (p *criStatsProvider) addCadvisorContainerCPUAndMemoryStats(
cs *statsapi.ContainerStats,
caPodStats *cadvisorapiv2.ContainerInfo,
) {
if caPodStats.Spec.HasCustomMetrics {
cs.UserDefinedMetrics = cadvisorInfoToUserDefinedMetrics(caPodStats)
}
cpu, memory := cadvisorInfoToCPUandMemoryStats(caPodStats)
if cpu != nil {
cs.CPU = cpu
}
if memory != nil {
cs.Memory = memory
}
} }
func getCRICadvisorStats(infos map[string]cadvisorapiv2.ContainerInfo) map[string]cadvisorapiv2.ContainerInfo { func getCRICadvisorStats(infos map[string]cadvisorapiv2.ContainerInfo) map[string]cadvisorapiv2.ContainerInfo {
......
...@@ -153,6 +153,27 @@ func cadvisorInfoToContainerCPUAndMemoryStats(name string, info *cadvisorapiv2.C ...@@ -153,6 +153,27 @@ func cadvisorInfoToContainerCPUAndMemoryStats(name string, info *cadvisorapiv2.C
return result return result
} }
// cadvisorInfoToAcceleratorStats returns the statsapi.AcceleratorStats converted from
// the container info from cadvisor.
func cadvisorInfoToAcceleratorStats(info *cadvisorapiv2.ContainerInfo) []statsapi.AcceleratorStats {
cstat, found := latestContainerStats(info)
if !found || cstat.Accelerators == nil {
return nil
}
var result []statsapi.AcceleratorStats
for _, acc := range cstat.Accelerators {
result = append(result, statsapi.AcceleratorStats{
Make: acc.Make,
Model: acc.Model,
ID: acc.ID,
MemoryTotal: acc.MemoryTotal,
MemoryUsed: acc.MemoryUsed,
DutyCycle: acc.DutyCycle,
})
}
return result
}
func cadvisorInfoToProcessStats(info *cadvisorapiv2.ContainerInfo) *statsapi.ProcessStats { func cadvisorInfoToProcessStats(info *cadvisorapiv2.ContainerInfo) *statsapi.ProcessStats {
cstat, found := latestContainerStats(info) cstat, found := latestContainerStats(info)
if !found || cstat.Processes == nil { if !found || cstat.Processes == nil {
......
...@@ -55,7 +55,8 @@ var _ volume.PersistentVolumePlugin = &azureFilePlugin{} ...@@ -55,7 +55,8 @@ var _ volume.PersistentVolumePlugin = &azureFilePlugin{}
var _ volume.ExpandableVolumePlugin = &azureFilePlugin{} var _ volume.ExpandableVolumePlugin = &azureFilePlugin{}
const ( const (
azureFilePluginName = "kubernetes.io/azure-file" azureFilePluginName = "kubernetes.io/azure-file"
defaultSecretNamespace = "default"
) )
func getPath(uid types.UID, volName string, host volume.VolumeHost) string { func getPath(uid types.UID, volName string, host volume.VolumeHost) string {
...@@ -115,7 +116,7 @@ func (plugin *azureFilePlugin) newMounterInternal(spec *volume.Spec, pod *v1.Pod ...@@ -115,7 +116,7 @@ func (plugin *azureFilePlugin) newMounterInternal(spec *volume.Spec, pod *v1.Pod
if err != nil { if err != nil {
return nil, err return nil, err
} }
secretName, secretNamespace, err := getSecretNameAndNamespace(spec, pod.Namespace) secretName, secretNamespace, err := getSecretNameAndNamespace(spec, defaultSecretNamespace)
if err != nil { if err != nil {
// Log-and-continue instead of returning an error for now // Log-and-continue instead of returning an error for now
// due to unspecified backwards compatibility concerns (a subject to revise) // due to unspecified backwards compatibility concerns (a subject to revise)
...@@ -173,7 +174,7 @@ func (plugin *azureFilePlugin) ExpandVolumeDevice( ...@@ -173,7 +174,7 @@ func (plugin *azureFilePlugin) ExpandVolumeDevice(
resourceGroup = spec.PersistentVolume.ObjectMeta.Annotations[resourceGroupAnnotation] resourceGroup = spec.PersistentVolume.ObjectMeta.Annotations[resourceGroupAnnotation]
} }
secretName, secretNamespace, err := getSecretNameAndNamespace(spec, spec.PersistentVolume.Spec.ClaimRef.Namespace) secretName, secretNamespace, err := getSecretNameAndNamespace(spec, defaultSecretNamespace)
if err != nil { if err != nil {
return oldSize, err return oldSize, err
} }
......
...@@ -79,7 +79,7 @@ func (plugin *azureFilePlugin) newDeleterInternal(spec *volume.Spec, util azureU ...@@ -79,7 +79,7 @@ func (plugin *azureFilePlugin) newDeleterInternal(spec *volume.Spec, util azureU
return nil, fmt.Errorf("invalid PV spec") return nil, fmt.Errorf("invalid PV spec")
} }
secretName, secretNamespace, err := getSecretNameAndNamespace(spec, spec.PersistentVolume.Spec.ClaimRef.Namespace) secretName, secretNamespace, err := getSecretNameAndNamespace(spec, defaultSecretNamespace)
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
...@@ -34,9 +34,12 @@ const ( ...@@ -34,9 +34,12 @@ const (
dirMode = "dir_mode" dirMode = "dir_mode"
gid = "gid" gid = "gid"
vers = "vers" vers = "vers"
actimeo = "actimeo"
mfsymlinks = "mfsymlinks"
defaultFileMode = "0777" defaultFileMode = "0777"
defaultDirMode = "0777" defaultDirMode = "0777"
defaultVers = "3.0" defaultVers = "3.0"
defaultActimeo = "30"
) )
// Abstract interface to azure file operations. // Abstract interface to azure file operations.
...@@ -106,6 +109,8 @@ func appendDefaultMountOptions(mountOptions []string, fsGroup *int64) []string { ...@@ -106,6 +109,8 @@ func appendDefaultMountOptions(mountOptions []string, fsGroup *int64) []string {
dirModeFlag := false dirModeFlag := false
versFlag := false versFlag := false
gidFlag := false gidFlag := false
actimeoFlag := false
mfsymlinksFlag := false
for _, mountOption := range mountOptions { for _, mountOption := range mountOptions {
if strings.HasPrefix(mountOption, fileMode) { if strings.HasPrefix(mountOption, fileMode) {
...@@ -120,6 +125,12 @@ func appendDefaultMountOptions(mountOptions []string, fsGroup *int64) []string { ...@@ -120,6 +125,12 @@ func appendDefaultMountOptions(mountOptions []string, fsGroup *int64) []string {
if strings.HasPrefix(mountOption, gid) { if strings.HasPrefix(mountOption, gid) {
gidFlag = true gidFlag = true
} }
if strings.HasPrefix(mountOption, actimeo) {
actimeoFlag = true
}
if strings.HasPrefix(mountOption, mfsymlinks) {
mfsymlinksFlag = true
}
} }
allMountOptions := mountOptions allMountOptions := mountOptions
...@@ -138,5 +149,13 @@ func appendDefaultMountOptions(mountOptions []string, fsGroup *int64) []string { ...@@ -138,5 +149,13 @@ func appendDefaultMountOptions(mountOptions []string, fsGroup *int64) []string {
if !gidFlag && fsGroup != nil { if !gidFlag && fsGroup != nil {
allMountOptions = append(allMountOptions, fmt.Sprintf("%s=%d", gid, *fsGroup)) allMountOptions = append(allMountOptions, fmt.Sprintf("%s=%d", gid, *fsGroup))
} }
if !actimeoFlag {
allMountOptions = append(allMountOptions, fmt.Sprintf("%s=%s", actimeo, defaultActimeo))
}
if !mfsymlinksFlag {
allMountOptions = append(allMountOptions, mfsymlinks)
}
return allMountOptions return allMountOptions
} }
...@@ -317,7 +317,7 @@ func (az *Cloud) cleanBackendpoolForPrimarySLB(primarySLB *network.LoadBalancer, ...@@ -317,7 +317,7 @@ func (az *Cloud) cleanBackendpoolForPrimarySLB(primarySLB *network.LoadBalancer,
return nil, err return nil, err
} }
primaryVMSetName := az.VMSet.GetPrimaryVMSetName() primaryVMSetName := az.VMSet.GetPrimaryVMSetName()
if !strings.EqualFold(primaryVMSetName, vmSetName) { if !strings.EqualFold(primaryVMSetName, vmSetName) && vmSetName != "" {
klog.V(2).Infof("cleanBackendpoolForPrimarySLB: found unwanted vmSet %s, decouple it from the LB", vmSetName) klog.V(2).Infof("cleanBackendpoolForPrimarySLB: found unwanted vmSet %s, decouple it from the LB", vmSetName)
// construct a backendPool that only contains the IP config of the node to be deleted // construct a backendPool that only contains the IP config of the node to be deleted
interfaceIPConfigToBeDeleted := network.InterfaceIPConfiguration{ interfaceIPConfigToBeDeleted := network.InterfaceIPConfiguration{
...@@ -1133,6 +1133,10 @@ func (az *Cloud) reconcileLoadBalancer(clusterName string, service *v1.Service, ...@@ -1133,6 +1133,10 @@ func (az *Cloud) reconcileLoadBalancer(clusterName string, service *v1.Service,
if err != nil { if err != nil {
return nil, err return nil, err
} }
if nodeName == "" {
// VM may under deletion
continue
}
// If a node is not supposed to be included in the LB, it // If a node is not supposed to be included in the LB, it
// would not be in the `nodes` slice. We need to check the nodes that // would not be in the `nodes` slice. We need to check the nodes that
// have been added to the LB's backendpool, find the unwanted ones and // have been added to the LB's backendpool, find the unwanted ones and
......
...@@ -76,7 +76,8 @@ var ( ...@@ -76,7 +76,8 @@ var (
providerIDRE = regexp.MustCompile(`.*/subscriptions/(?:.*)/Microsoft.Compute/virtualMachines/(.+)$`) providerIDRE = regexp.MustCompile(`.*/subscriptions/(?:.*)/Microsoft.Compute/virtualMachines/(.+)$`)
backendPoolIDRE = regexp.MustCompile(`^/subscriptions/(?:.*)/resourceGroups/(?:.*)/providers/Microsoft.Network/loadBalancers/(.+)/backendAddressPools/(?:.*)`) backendPoolIDRE = regexp.MustCompile(`^/subscriptions/(?:.*)/resourceGroups/(?:.*)/providers/Microsoft.Network/loadBalancers/(.+)/backendAddressPools/(?:.*)`)
nicResourceGroupRE = regexp.MustCompile(`.*/subscriptions/(?:.*)/resourceGroups/(.+)/providers/Microsoft.Network/networkInterfaces/(?:.*)`) nicResourceGroupRE = regexp.MustCompile(`.*/subscriptions/(?:.*)/resourceGroups/(.+)/providers/Microsoft.Network/networkInterfaces/(?:.*)`)
nicIDRE = regexp.MustCompile(`/subscriptions/(?:.*)/resourceGroups/(?:.+)/providers/Microsoft.Network/networkInterfaces/(.+)-nic-(.+)/ipConfigurations/(?:.*)`) nicIDRE = regexp.MustCompile(`(?i)/subscriptions/(?:.*)/resourceGroups/(.+)/providers/Microsoft.Network/networkInterfaces/(.+)/ipConfigurations/(?:.*)`)
vmIDRE = regexp.MustCompile(`(?i)/subscriptions/(?:.*)/resourceGroups/(?:.*)/providers/Microsoft.Compute/virtualMachines/(.+)`)
vmasIDRE = regexp.MustCompile(`/subscriptions/(?:.*)/resourceGroups/(?:.*)/providers/Microsoft.Compute/availabilitySets/(.+)`) vmasIDRE = regexp.MustCompile(`/subscriptions/(?:.*)/resourceGroups/(?:.*)/providers/Microsoft.Compute/availabilitySets/(.+)`)
) )
...@@ -1055,24 +1056,44 @@ func (as *availabilitySet) GetNodeNameByIPConfigurationID(ipConfigurationID stri ...@@ -1055,24 +1056,44 @@ func (as *availabilitySet) GetNodeNameByIPConfigurationID(ipConfigurationID stri
return "", "", fmt.Errorf("invalid ip config ID %s", ipConfigurationID) return "", "", fmt.Errorf("invalid ip config ID %s", ipConfigurationID)
} }
prefix := matches[1] nicResourceGroup, nicName := matches[1], matches[2]
suffix := matches[2] if nicResourceGroup == "" || nicName == "" {
nodeName := fmt.Sprintf("%s-%s", prefix, suffix) return "", "", fmt.Errorf("invalid ip config ID %s", ipConfigurationID)
}
nic, rerr := as.InterfacesClient.Get(context.Background(), nicResourceGroup, nicName, "")
if rerr != nil {
return "", "", fmt.Errorf("GetNodeNameByIPConfigurationID(%s): failed to get interface of name %s: %s", ipConfigurationID, nicName, rerr.Error().Error())
}
vmID := ""
if nic.InterfacePropertiesFormat != nil && nic.VirtualMachine != nil {
vmID = to.String(nic.VirtualMachine.ID)
}
if vmID == "" {
klog.V(2).Infof("GetNodeNameByIPConfigurationID(%s): empty vmID", ipConfigurationID)
return "", "", nil
}
vm, err := as.getVirtualMachine(types.NodeName(nodeName), azcache.CacheReadTypeDefault) matches = vmIDRE.FindStringSubmatch(vmID)
if len(matches) != 2 {
return "", "", fmt.Errorf("invalid virtual machine ID %s", vmID)
}
vmName := matches[1]
vm, err := as.getVirtualMachine(types.NodeName(vmName), azcache.CacheReadTypeDefault)
if err != nil { if err != nil {
return "", "", fmt.Errorf("cannot get the virtual machine by node name %s", nodeName) return "", "", fmt.Errorf("cannot get the virtual machine by node name %s", vmName)
} }
asID := "" asID := ""
if vm.VirtualMachineProperties != nil && vm.AvailabilitySet != nil { if vm.VirtualMachineProperties != nil && vm.AvailabilitySet != nil {
asID = to.String(vm.AvailabilitySet.ID) asID = to.String(vm.AvailabilitySet.ID)
} }
if asID == "" { if asID == "" {
return "", "", fmt.Errorf("cannot get the availability set ID from the virtual machine with node name %s", nodeName) return vmName, "", nil
} }
asName, err := getAvailabilitySetNameByID(asID) asName, err := getAvailabilitySetNameByID(asID)
if err != nil { if err != nil {
return "", "", fmt.Errorf("cannot get the availability set name by the availability set ID %s", asID) return "", "", fmt.Errorf("cannot get the availability set name by the availability set ID %s", asID)
} }
return nodeName, strings.ToLower(asName), nil return vmName, strings.ToLower(asName), nil
} }
...@@ -166,6 +166,12 @@ func (g *Cloud) ensureInternalLoadBalancer(clusterName, clusterID string, svc *v ...@@ -166,6 +166,12 @@ func (g *Cloud) ensureInternalLoadBalancer(clusterName, clusterID string, svc *v
return nil, err return nil, err
} }
klog.V(2).Infof("ensureInternalLoadBalancer(%v): reserved IP %q for the forwarding rule", loadBalancerName, ipToUse) klog.V(2).Infof("ensureInternalLoadBalancer(%v): reserved IP %q for the forwarding rule", loadBalancerName, ipToUse)
defer func() {
// Release the address if all resources were created successfully, or if we error out.
if err := addrMgr.ReleaseAddress(); err != nil {
klog.Errorf("ensureInternalLoadBalancer: failed to release address reservation, possibly causing an orphan: %v", err)
}
}()
} }
// Ensure firewall rules if necessary // Ensure firewall rules if necessary
...@@ -224,13 +230,6 @@ func (g *Cloud) ensureInternalLoadBalancer(clusterName, clusterID string, svc *v ...@@ -224,13 +230,6 @@ func (g *Cloud) ensureInternalLoadBalancer(clusterName, clusterID string, svc *v
g.clearPreviousInternalResources(svc, loadBalancerName, existingBackendService, backendServiceName, hcName) g.clearPreviousInternalResources(svc, loadBalancerName, existingBackendService, backendServiceName, hcName)
} }
if addrMgr != nil {
// Now that the controller knows the forwarding rule exists, we can release the address.
if err := addrMgr.ReleaseAddress(); err != nil {
klog.Errorf("ensureInternalLoadBalancer: failed to release address reservation, possibly causing an orphan: %v", err)
}
}
// Get the most recent forwarding rule for the address. // Get the most recent forwarding rule for the address.
updatedFwdRule, err := g.GetRegionForwardingRule(loadBalancerName, g.region) updatedFwdRule, err := g.GetRegionForwardingRule(loadBalancerName, g.region)
if err != nil { if err != nil {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment