diff --git a/go.mod b/go.mod index 6959eaa27..f05c20d2b 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/openshift/api v0.0.0-20201019163320-c6a5ec25f267 github.com/openshift/build-machinery-go v0.0.0-20200917070002-f171684f77ab github.com/openshift/client-go v0.0.0-20201020074620-f8fd44879f7c - github.com/openshift/library-go v0.0.0-20201023142140-a2f8f23f66f0 + github.com/openshift/library-go v0.0.0-20201102091359-c4fa0f5b3a08 github.com/prometheus/common v0.10.0 github.com/spf13/cobra v1.0.0 github.com/spf13/pflag v1.0.5 diff --git a/go.sum b/go.sum index 8cc9881d8..260f69289 100644 --- a/go.sum +++ b/go.sum @@ -356,8 +356,8 @@ github.com/openshift/build-machinery-go v0.0.0-20200917070002-f171684f77ab h1:lB github.com/openshift/build-machinery-go v0.0.0-20200917070002-f171684f77ab/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE= github.com/openshift/client-go v0.0.0-20201020074620-f8fd44879f7c h1:NB9g4Y/aegId7fyNqYyGxEfyNOytYFT5dxWJtfOJFQs= github.com/openshift/client-go v0.0.0-20201020074620-f8fd44879f7c/go.mod h1:yZ3u8vgWC19I9gbDMRk8//9JwG/0Sth6v7C+m6R8HXs= -github.com/openshift/library-go v0.0.0-20201023142140-a2f8f23f66f0 h1:IQTsOsr3sjHmakUmjTUCUSBETu51SVl/xoFM0IxLCZ8= -github.com/openshift/library-go v0.0.0-20201023142140-a2f8f23f66f0/go.mod h1:qbwvTwCy4btqEcqU3oI59CopNgcRgZUPXG4Y2jc+B4E= +github.com/openshift/library-go v0.0.0-20201102091359-c4fa0f5b3a08 h1:Z+8t3ooTH2T+J/GoCZbgaOk5WqNZgPuHlUAKMfG1FEk= +github.com/openshift/library-go v0.0.0-20201102091359-c4fa0f5b3a08/go.mod h1:1xYaYQcQsn+AyCRsvOU+Qn5z6GGiCmcblXkT/RZLVfo= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= diff --git a/vendor/github.com/openshift/library-go/pkg/config/client/client_config.go b/vendor/github.com/openshift/library-go/pkg/config/client/client_config.go index a24731105..e2b90ca53 100644 --- a/vendor/github.com/openshift/library-go/pkg/config/client/client_config.go +++ b/vendor/github.com/openshift/library-go/pkg/config/client/client_config.go @@ -2,14 +2,12 @@ package client import ( "io/ioutil" - "net" - "net/http" - "time" - "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" + "net/http" configv1 "github.com/openshift/api/config/v1" + "github.com/openshift/library-go/pkg/network" ) // GetKubeConfigOrInClusterConfig loads in-cluster config if kubeConfigFile is empty or the file if not, @@ -101,10 +99,7 @@ func (c ClientTransportOverrides) DefaultClientTransport(rt http.RoundTripper) h return rt } - transport.DialContext = (&net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - }).DialContext + transport.DialContext = network.DefaultClientDialContext() // Hold open more internal idle connections transport.MaxIdleConnsPerHost = 100 diff --git a/vendor/github.com/openshift/library-go/pkg/network/dialer.go b/vendor/github.com/openshift/library-go/pkg/network/dialer.go new file mode 100644 index 000000000..f19be44a3 --- /dev/null +++ b/vendor/github.com/openshift/library-go/pkg/network/dialer.go @@ -0,0 +1,13 @@ +package network + +import ( + "context" + "net" +) + +type DialContext func(ctx context.Context, network, address string) (net.Conn, error) + +// DefaultDialContext returns a DialContext function from a network dialer with default options sets. +func DefaultClientDialContext() DialContext { + return dialerWithDefaultOptions() +} diff --git a/vendor/github.com/openshift/library-go/pkg/network/dialer_linux.go b/vendor/github.com/openshift/library-go/pkg/network/dialer_linux.go new file mode 100644 index 000000000..e3cd3f4d3 --- /dev/null +++ b/vendor/github.com/openshift/library-go/pkg/network/dialer_linux.go @@ -0,0 +1,91 @@ +// +build linux + +package network + +import ( + "context" + "net" + "os" + "syscall" + "time" + + "golang.org/x/sys/unix" +) + +func dialerWithDefaultOptions() DialContext { + nd := &net.Dialer{ + // TCP_USER_TIMEOUT does affect the behaviour of connect() which is controlled by this field so we set it to the same value + Timeout: 25 * time.Second, + } + return wrapDialContext(nd.DialContext) +} + +func wrapDialContext(dc DialContext) DialContext { + return func(ctx context.Context, network, address string) (net.Conn, error) { + conn, err := dc(ctx, network, address) + if err != nil { + return conn, err + } + + if tcpCon, ok := conn.(*net.TCPConn); ok { + tcpFD, err := tcpCon.File() + if err != nil { + return conn, err + } + if err := setDefaultSocketOptions(int(tcpFD.Fd())); err != nil { + return conn, err + } + } + return conn, nil + } +} + +// setDefaultSocketOptions sets custom socket options so that we can detect connections to an unhealthy (dead) peer quickly. +// In particular we set TCP_USER_TIMEOUT that specifies the maximum amount of time that transmitted data may remain +// unacknowledged before TCP will forcibly close the connection. +// +// Note +// TCP_USER_TIMEOUT can't be too low because a single dropped packet might drop the entire connection. +// Ideally it should be set to: TCP_KEEPIDLE + TCP_KEEPINTVL * TCP_KEEPCNT +func setDefaultSocketOptions(fd int) error { + // specifies the maximum amount of time in milliseconds that transmitted data may remain + // unacknowledged before TCP will forcibly close the corresponding connection and return ETIMEDOUT to the application + tcpUserTimeoutInMilliSeconds := int(25 * time.Second / time.Millisecond) + + // specifies the interval at which probes are sent in seconds + tcpKeepIntvl := int(roundDuration(5*time.Second, time.Second)) + + // specifies the threshold for sending the first KEEP ALIVE probe in seconds + tcpKeepIdle := int(roundDuration(2*time.Second, time.Second)) + + if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, unix.TCP_USER_TIMEOUT, tcpUserTimeoutInMilliSeconds); err != nil { + return wrapSyscallError("setsockopt", err) + } + + if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, syscall.TCP_KEEPINTVL, tcpKeepIntvl); err != nil { + return wrapSyscallError("setsockopt", err) + } + + if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, syscall.TCP_KEEPIDLE, tcpKeepIdle); err != nil { + return wrapSyscallError("setsockopt", err) + } + return nil +} + +// roundDurationUp rounds d to the next multiple of to. +// +// note that it was copied from the std library +func roundDuration(d time.Duration, to time.Duration) time.Duration { + return (d + to - 1) / to +} + +// wrapSyscallError takes an error and a syscall name. If the error is +// a syscall.Errno, it wraps it in a os.SyscallError using the syscall name. +// +// note that it was copied from the std library +func wrapSyscallError(name string, err error) error { + if _, ok := err.(syscall.Errno); ok { + err = os.NewSyscallError(name, err) + } + return err +} diff --git a/vendor/github.com/openshift/library-go/pkg/network/dialer_others.go b/vendor/github.com/openshift/library-go/pkg/network/dialer_others.go new file mode 100644 index 000000000..6519b0986 --- /dev/null +++ b/vendor/github.com/openshift/library-go/pkg/network/dialer_others.go @@ -0,0 +1,19 @@ +// +build !linux + +package network + +import ( + "net" + "time" + + "k8s.io/klog/v2" +) + +func dialerWithDefaultOptions() DialContext { + klog.V(2).Info("Creating the default network Dialer (unsupported platform). It may take up to 15 minutes to detect broken connections and establish a new one") + nd := &net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + } + return nd.DialContext +} diff --git a/vendor/github.com/openshift/library-go/pkg/operator/staticpod/installerpod/cmd.go b/vendor/github.com/openshift/library-go/pkg/operator/staticpod/installerpod/cmd.go index 68d38f78f..ba584e714 100644 --- a/vendor/github.com/openshift/library-go/pkg/operator/staticpod/installerpod/cmd.go +++ b/vendor/github.com/openshift/library-go/pkg/operator/staticpod/installerpod/cmd.go @@ -299,7 +299,7 @@ func (o *InstallOptions) copyContent(ctx context.Context) error { } // Gather pod yaml from config map - var podContent string + var rawPodBytes string err := retry.RetryOnConnectionErrors(ctx, func(ctx context.Context) (bool, error) { klog.Infof("Getting pod configmaps/%s -n %s", o.nameFor(o.PodConfigMapNamePrefix), o.Namespace) @@ -311,7 +311,7 @@ func (o *InstallOptions) copyContent(ctx context.Context) error { return true, fmt.Errorf("required 'pod.yaml' key does not exist in configmap") } podConfigMap = o.substituteConfigMap(podConfigMap) - podContent = podConfigMap.Data["pod.yaml"] + rawPodBytes = podConfigMap.Data["pod.yaml"] return true, nil }) if err != nil { @@ -320,11 +320,18 @@ func (o *InstallOptions) copyContent(ctx context.Context) error { // the kubelet has a bug that prevents graceful termination from working on static pods with the same name, filename // and uuid. By setting the pod UID we can work around the kubelet bug and get our graceful termination honored. // Per the node team, this is hard to fix in the kubelet, though it will affect all static pods. - pod, err := resourceread.ReadPodV1([]byte(podContent)) + pod, err := resourceread.ReadPodV1([]byte(rawPodBytes)) if err != nil { return err } pod.UID = uuid.NewUUID() + for _, fn := range o.PodMutationFns { + klog.V(2).Infof("Customizing static pod ...") + pod = pod.DeepCopy() + if err := fn(pod); err != nil { + return err + } + } finalPodBytes := resourceread.WritePodV1OrDie(pod) // Write secrets, config maps and pod to disk @@ -341,17 +348,8 @@ func (o *InstallOptions) copyContent(ctx context.Context) error { return err } - for _, fn := range o.PodMutationFns { - klog.V(2).Infof("Customizing static pod ...") - pod := resourceread.ReadPodV1OrDie([]byte(podContent)) - if err := fn(pod); err != nil { - return err - } - podContent = resourceread.WritePodV1OrDie(pod) - } - - klog.Infof("Writing static pod manifest %q ...\n%s", path.Join(o.PodManifestDir, podFileName), podContent) - if err := ioutil.WriteFile(path.Join(o.PodManifestDir, podFileName), []byte(podContent), 0644); err != nil { + klog.Infof("Writing static pod manifest %q ...\n%s", path.Join(o.PodManifestDir, podFileName), finalPodBytes) + if err := ioutil.WriteFile(path.Join(o.PodManifestDir, podFileName), []byte(finalPodBytes), 0644); err != nil { return err } diff --git a/vendor/modules.txt b/vendor/modules.txt index 352b716f2..592e8853f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -196,7 +196,7 @@ github.com/openshift/client-go/config/listers/config/v1 github.com/openshift/client-go/route/clientset/versioned github.com/openshift/client-go/route/clientset/versioned/scheme github.com/openshift/client-go/route/clientset/versioned/typed/route/v1 -# github.com/openshift/library-go v0.0.0-20201023142140-a2f8f23f66f0 +# github.com/openshift/library-go v0.0.0-20201102091359-c4fa0f5b3a08 github.com/openshift/library-go/pkg/assets github.com/openshift/library-go/pkg/certs github.com/openshift/library-go/pkg/config/client @@ -210,6 +210,7 @@ github.com/openshift/library-go/pkg/controller/fileobserver github.com/openshift/library-go/pkg/controller/manager github.com/openshift/library-go/pkg/controller/metrics github.com/openshift/library-go/pkg/crypto +github.com/openshift/library-go/pkg/network github.com/openshift/library-go/pkg/operator/certrotation github.com/openshift/library-go/pkg/operator/condition github.com/openshift/library-go/pkg/operator/configobserver