Commit 73d1903c authored by Brad Davidson's avatar Brad Davidson Committed by Brad Davidson

Update Kubernetes to v1.17.13-k3s1

parent 263502d0
...@@ -33,31 +33,31 @@ replace ( ...@@ -33,31 +33,31 @@ replace (
github.com/prometheus/client_model => github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 github.com/prometheus/client_model => github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910
github.com/prometheus/common => github.com/prometheus/common v0.0.0-20181126121408-4724e9255275 github.com/prometheus/common => github.com/prometheus/common v0.0.0-20181126121408-4724e9255275
github.com/prometheus/procfs => github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a github.com/prometheus/procfs => github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a
k8s.io/api => github.com/rancher/kubernetes/staging/src/k8s.io/api v1.17.12-k3s1 k8s.io/api => github.com/rancher/kubernetes/staging/src/k8s.io/api v1.17.13-k3s1
k8s.io/apiextensions-apiserver => github.com/rancher/kubernetes/staging/src/k8s.io/apiextensions-apiserver v1.17.12-k3s1 k8s.io/apiextensions-apiserver => github.com/rancher/kubernetes/staging/src/k8s.io/apiextensions-apiserver v1.17.13-k3s1
k8s.io/apimachinery => github.com/rancher/kubernetes/staging/src/k8s.io/apimachinery v1.17.12-k3s1 k8s.io/apimachinery => github.com/rancher/kubernetes/staging/src/k8s.io/apimachinery v1.17.13-k3s1
k8s.io/apiserver => github.com/rancher/kubernetes/staging/src/k8s.io/apiserver v1.17.12-k3s1 k8s.io/apiserver => github.com/rancher/kubernetes/staging/src/k8s.io/apiserver v1.17.13-k3s1
k8s.io/cli-runtime => github.com/rancher/kubernetes/staging/src/k8s.io/cli-runtime v1.17.12-k3s1 k8s.io/cli-runtime => github.com/rancher/kubernetes/staging/src/k8s.io/cli-runtime v1.17.13-k3s1
k8s.io/client-go => github.com/rancher/kubernetes/staging/src/k8s.io/client-go v1.17.12-k3s1 k8s.io/client-go => github.com/rancher/kubernetes/staging/src/k8s.io/client-go v1.17.13-k3s1
k8s.io/cloud-provider => github.com/rancher/kubernetes/staging/src/k8s.io/cloud-provider v1.17.12-k3s1 k8s.io/cloud-provider => github.com/rancher/kubernetes/staging/src/k8s.io/cloud-provider v1.17.13-k3s1
k8s.io/cluster-bootstrap => github.com/rancher/kubernetes/staging/src/k8s.io/cluster-bootstrap v1.17.12-k3s1 k8s.io/cluster-bootstrap => github.com/rancher/kubernetes/staging/src/k8s.io/cluster-bootstrap v1.17.13-k3s1
k8s.io/code-generator => github.com/rancher/kubernetes/staging/src/k8s.io/code-generator v1.17.12-k3s1 k8s.io/code-generator => github.com/rancher/kubernetes/staging/src/k8s.io/code-generator v1.17.13-k3s1
k8s.io/component-base => github.com/rancher/kubernetes/staging/src/k8s.io/component-base v1.17.12-k3s1 k8s.io/component-base => github.com/rancher/kubernetes/staging/src/k8s.io/component-base v1.17.13-k3s1
k8s.io/cri-api => github.com/rancher/kubernetes/staging/src/k8s.io/cri-api v1.17.12-k3s1 k8s.io/cri-api => github.com/rancher/kubernetes/staging/src/k8s.io/cri-api v1.17.13-k3s1
k8s.io/csi-translation-lib => github.com/rancher/kubernetes/staging/src/k8s.io/csi-translation-lib v1.17.12-k3s1 k8s.io/csi-translation-lib => github.com/rancher/kubernetes/staging/src/k8s.io/csi-translation-lib v1.17.13-k3s1
k8s.io/kube-aggregator => github.com/rancher/kubernetes/staging/src/k8s.io/kube-aggregator v1.17.12-k3s1 k8s.io/kube-aggregator => github.com/rancher/kubernetes/staging/src/k8s.io/kube-aggregator v1.17.13-k3s1
k8s.io/kube-controller-manager => github.com/rancher/kubernetes/staging/src/k8s.io/kube-controller-manager v1.17.12-k3s1 k8s.io/kube-controller-manager => github.com/rancher/kubernetes/staging/src/k8s.io/kube-controller-manager v1.17.13-k3s1
k8s.io/kube-proxy => github.com/rancher/kubernetes/staging/src/k8s.io/kube-proxy v1.17.12-k3s1 k8s.io/kube-proxy => github.com/rancher/kubernetes/staging/src/k8s.io/kube-proxy v1.17.13-k3s1
k8s.io/kube-scheduler => github.com/rancher/kubernetes/staging/src/k8s.io/kube-scheduler v1.17.12-k3s1 k8s.io/kube-scheduler => github.com/rancher/kubernetes/staging/src/k8s.io/kube-scheduler v1.17.13-k3s1
k8s.io/kubectl => github.com/rancher/kubernetes/staging/src/k8s.io/kubectl v1.17.12-k3s1 k8s.io/kubectl => github.com/rancher/kubernetes/staging/src/k8s.io/kubectl v1.17.13-k3s1
k8s.io/kubelet => github.com/rancher/kubernetes/staging/src/k8s.io/kubelet v1.17.12-k3s1 k8s.io/kubelet => github.com/rancher/kubernetes/staging/src/k8s.io/kubelet v1.17.13-k3s1
k8s.io/kubernetes => github.com/rancher/kubernetes v1.17.12-k3s1 k8s.io/kubernetes => github.com/rancher/kubernetes v1.17.13-k3s1
k8s.io/legacy-cloud-providers => github.com/rancher/kubernetes/staging/src/k8s.io/legacy-cloud-providers v1.17.12-k3s1 k8s.io/legacy-cloud-providers => github.com/rancher/kubernetes/staging/src/k8s.io/legacy-cloud-providers v1.17.13-k3s1
k8s.io/metrics => github.com/rancher/kubernetes/staging/src/k8s.io/metrics v1.17.12-k3s1 k8s.io/metrics => github.com/rancher/kubernetes/staging/src/k8s.io/metrics v1.17.13-k3s1
k8s.io/node-api => github.com/rancher/kubernetes/staging/src/k8s.io/node-api v1.17.12-k3s1 k8s.io/node-api => github.com/rancher/kubernetes/staging/src/k8s.io/node-api v1.17.13-k3s1
k8s.io/sample-apiserver => github.com/rancher/kubernetes/staging/src/k8s.io/sample-apiserver v1.17.12-k3s1 k8s.io/sample-apiserver => github.com/rancher/kubernetes/staging/src/k8s.io/sample-apiserver v1.17.13-k3s1
k8s.io/sample-cli-plugin => github.com/rancher/kubernetes/staging/src/k8s.io/sample-cli-plugin v1.17.12-k3s1 k8s.io/sample-cli-plugin => github.com/rancher/kubernetes/staging/src/k8s.io/sample-cli-plugin v1.17.13-k3s1
k8s.io/sample-controller => github.com/rancher/kubernetes/staging/src/k8s.io/sample-controller v1.17.12-k3s1 k8s.io/sample-controller => github.com/rancher/kubernetes/staging/src/k8s.io/sample-controller v1.17.13-k3s1
mvdan.cc/unparam => mvdan.cc/unparam v0.0.0-20190209190245-fbb59629db34 mvdan.cc/unparam => mvdan.cc/unparam v0.0.0-20190209190245-fbb59629db34
) )
...@@ -123,5 +123,5 @@ require ( ...@@ -123,5 +123,5 @@ require (
k8s.io/component-base v0.0.0 k8s.io/component-base v0.0.0
k8s.io/cri-api v0.0.0 k8s.io/cri-api v0.0.0
k8s.io/klog v1.0.0 k8s.io/klog v1.0.0
k8s.io/kubernetes v1.17.0 k8s.io/kubernetes v1.17.13
) )
...@@ -440,6 +440,14 @@ func getNewItemFunc(listObj runtime.Object, v reflect.Value) func() runtime.Obje ...@@ -440,6 +440,14 @@ func getNewItemFunc(listObj runtime.Object, v reflect.Value) func() runtime.Obje
func (s *store) Count(key string) (int64, error) { func (s *store) Count(key string) (int64, error) {
key = path.Join(s.pathPrefix, key) key = path.Join(s.pathPrefix, key)
// We need to make sure the key ended with "/" so that we only get children "directories".
// e.g. if we have key "/a", "/a/b", "/ab", getting keys with prefix "/a" will return all three,
// while with prefix "/a/" will return only "/a/b" which is the correct answer.
if !strings.HasSuffix(key, "/") {
key += "/"
}
startTime := time.Now() startTime := time.Now()
getResp, err := s.client.KV.Get(context.Background(), key, clientv3.WithRange(clientv3.GetPrefixRangeEnd(key)), clientv3.WithCountOnly()) getResp, err := s.client.KV.Get(context.Background(), key, clientv3.WithRange(clientv3.GetPrefixRangeEnd(key)), clientv3.WithCountOnly())
metrics.RecordEtcdRequestLatency("listWithCount", key, startTime) metrics.RecordEtcdRequestLatency("listWithCount", key, startTime)
......
...@@ -3,8 +3,8 @@ package version ...@@ -3,8 +3,8 @@ package version
var ( var (
gitMajor = "1" gitMajor = "1"
gitMinor = "17" gitMinor = "17"
gitVersion = "v1.17.12-k3s1" gitVersion = "v1.17.13-k3s1"
gitCommit = "3a47527bc3f8a5ea50a5332060ebad8809b7bef8" gitCommit = "366a8c26ba3492468e5983bf564938d3ac14fcb8"
gitTreeState = "clean" gitTreeState = "clean"
buildDate = "2020-09-16T20:26:31Z" buildDate = "2020-10-15T17:20:31Z"
) )
...@@ -3,8 +3,8 @@ package version ...@@ -3,8 +3,8 @@ package version
var ( var (
gitMajor = "1" gitMajor = "1"
gitMinor = "17" gitMinor = "17"
gitVersion = "v1.17.12-k3s1" gitVersion = "v1.17.13-k3s1"
gitCommit = "3a47527bc3f8a5ea50a5332060ebad8809b7bef8" gitCommit = "366a8c26ba3492468e5983bf564938d3ac14fcb8"
gitTreeState = "clean" gitTreeState = "clean"
buildDate = "2020-09-16T20:26:31Z" buildDate = "2020-10-15T17:20:31Z"
) )
...@@ -207,6 +207,13 @@ func isLess(i, j reflect.Value) (bool, error) { ...@@ -207,6 +207,13 @@ func isLess(i, j reflect.Value) (bool, error) {
return true, nil return true, nil
case reflect.Interface: case reflect.Interface:
if i.IsNil() && j.IsNil() {
return false, nil
} else if i.IsNil() {
return true, nil
} else if j.IsNil() {
return false, nil
}
switch itype := i.Interface().(type) { switch itype := i.Interface().(type) {
case uint8: case uint8:
if jtype, ok := j.Interface().(uint8); ok { if jtype, ok := j.Interface().(uint8); ok {
......
...@@ -3552,6 +3552,9 @@ func DescribeEvents(el *corev1.EventList, w PrefixWriter) { ...@@ -3552,6 +3552,9 @@ func DescribeEvents(el *corev1.EventList, w PrefixWriter) {
interval = fmt.Sprintf("%s (x%d over %s)", translateTimestampSince(e.LastTimestamp), e.Count, translateTimestampSince(e.FirstTimestamp)) interval = fmt.Sprintf("%s (x%d over %s)", translateTimestampSince(e.LastTimestamp), e.Count, translateTimestampSince(e.FirstTimestamp))
} else { } else {
interval = translateTimestampSince(e.FirstTimestamp) interval = translateTimestampSince(e.FirstTimestamp)
if e.FirstTimestamp.IsZero() {
interval = translateMicroTimestampSince(e.EventTime)
}
} }
w.Write(LEVEL_1, "%v\t%v\t%s\t%v\t%v\n", w.Write(LEVEL_1, "%v\t%v\t%s\t%v\t%v\n",
e.Type, e.Type,
...@@ -4619,6 +4622,16 @@ func shorten(s string, maxLength int) string { ...@@ -4619,6 +4622,16 @@ func shorten(s string, maxLength int) string {
return s return s
} }
// translateMicroTimestampSince returns the elapsed time since timestamp in
// human-readable approximation.
func translateMicroTimestampSince(timestamp metav1.MicroTime) string {
if timestamp.IsZero() {
return "<unknown>"
}
return duration.HumanDuration(time.Since(timestamp.Time))
}
// translateTimestampSince returns the elapsed time since timestamp in // translateTimestampSince returns the elapsed time since timestamp in
// human-readable approximation. // human-readable approximation.
func translateTimestampSince(timestamp metav1.Time) string { func translateTimestampSince(timestamp metav1.Time) string {
......
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
name = "go_default_library",
srcs = ["util.go"],
importpath = "k8s.io/kubernetes/pkg/api/endpoints",
deps = [
"//pkg/apis/core:go_default_library",
"//pkg/util/hash:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = ["util_test.go"],
embed = [":go_default_library"],
deps = [
"//pkg/apis/core:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//vendor/github.com/davecgh/go-spew/spew:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)
# See the OWNERS docs at https://go.k8s.io/owners
reviewers:
- thockin
- smarterclayton
- mikedanese
- sttts
- eparis
- resouer
- david-mcmahon
/*
Copyright 2015 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package endpoints
import (
"bytes"
"crypto/md5"
"encoding/hex"
"hash"
"sort"
"k8s.io/apimachinery/pkg/types"
api "k8s.io/kubernetes/pkg/apis/core"
hashutil "k8s.io/kubernetes/pkg/util/hash"
)
// RepackSubsets takes a slice of EndpointSubset objects, expands it to the full
// representation, and then repacks that into the canonical layout. This
// ensures that code which operates on these objects can rely on the common
// form for things like comparison. The result is a newly allocated slice.
func RepackSubsets(subsets []api.EndpointSubset) []api.EndpointSubset {
// First map each unique port definition to the sets of hosts that
// offer it.
allAddrs := map[addressKey]*api.EndpointAddress{}
portToAddrReadyMap := map[api.EndpointPort]addressSet{}
for i := range subsets {
if len(subsets[i].Ports) == 0 {
// Don't discard endpoints with no ports defined, use a sentinel.
mapAddressesByPort(&subsets[i], api.EndpointPort{Port: -1}, allAddrs, portToAddrReadyMap)
} else {
for _, port := range subsets[i].Ports {
mapAddressesByPort(&subsets[i], port, allAddrs, portToAddrReadyMap)
}
}
}
// Next, map the sets of hosts to the sets of ports they offer.
// Go does not allow maps or slices as keys to maps, so we have
// to synthesize an artificial key and do a sort of 2-part
// associative entity.
type keyString string
keyToAddrReadyMap := map[keyString]addressSet{}
addrReadyMapKeyToPorts := map[keyString][]api.EndpointPort{}
for port, addrs := range portToAddrReadyMap {
key := keyString(hashAddresses(addrs))
keyToAddrReadyMap[key] = addrs
if port.Port > 0 { // avoid sentinels
addrReadyMapKeyToPorts[key] = append(addrReadyMapKeyToPorts[key], port)
} else {
if _, found := addrReadyMapKeyToPorts[key]; !found {
// Force it to be present in the map
addrReadyMapKeyToPorts[key] = nil
}
}
}
// Next, build the N-to-M association the API wants.
final := []api.EndpointSubset{}
for key, ports := range addrReadyMapKeyToPorts {
var readyAddrs, notReadyAddrs []api.EndpointAddress
for addr, ready := range keyToAddrReadyMap[key] {
if ready {
readyAddrs = append(readyAddrs, *addr)
} else {
notReadyAddrs = append(notReadyAddrs, *addr)
}
}
final = append(final, api.EndpointSubset{Addresses: readyAddrs, NotReadyAddresses: notReadyAddrs, Ports: ports})
}
// Finally, sort it.
return SortSubsets(final)
}
// The sets of hosts must be de-duped, using IP+UID as the key.
type addressKey struct {
ip string
uid types.UID
}
// mapAddressesByPort adds all ready and not-ready addresses into a map by a single port.
func mapAddressesByPort(subset *api.EndpointSubset, port api.EndpointPort, allAddrs map[addressKey]*api.EndpointAddress, portToAddrReadyMap map[api.EndpointPort]addressSet) {
for k := range subset.Addresses {
mapAddressByPort(&subset.Addresses[k], port, true, allAddrs, portToAddrReadyMap)
}
for k := range subset.NotReadyAddresses {
mapAddressByPort(&subset.NotReadyAddresses[k], port, false, allAddrs, portToAddrReadyMap)
}
}
// mapAddressByPort adds one address into a map by port, registering the address with a unique pointer, and preserving
// any existing ready state.
func mapAddressByPort(addr *api.EndpointAddress, port api.EndpointPort, ready bool, allAddrs map[addressKey]*api.EndpointAddress, portToAddrReadyMap map[api.EndpointPort]addressSet) *api.EndpointAddress {
// use addressKey to distinguish between two endpoints that are identical addresses
// but may have come from different hosts, for attribution.
key := addressKey{ip: addr.IP}
if addr.TargetRef != nil {
key.uid = addr.TargetRef.UID
}
// Accumulate the address. The full EndpointAddress structure is preserved for use when
// we rebuild the subsets so that the final TargetRef has all of the necessary data.
existingAddress := allAddrs[key]
if existingAddress == nil {
// Make a copy so we don't write to the
// input args of this function.
existingAddress = &api.EndpointAddress{}
*existingAddress = *addr
allAddrs[key] = existingAddress
}
// Remember that this port maps to this address.
if _, found := portToAddrReadyMap[port]; !found {
portToAddrReadyMap[port] = addressSet{}
}
// if we have not yet recorded this port for this address, or if the previous
// state was ready, write the current ready state. not ready always trumps
// ready.
if wasReady, found := portToAddrReadyMap[port][existingAddress]; !found || wasReady {
portToAddrReadyMap[port][existingAddress] = ready
}
return existingAddress
}
type addressSet map[*api.EndpointAddress]bool
type addrReady struct {
addr *api.EndpointAddress
ready bool
}
func hashAddresses(addrs addressSet) string {
// Flatten the list of addresses into a string so it can be used as a
// map key. Unfortunately, DeepHashObject is implemented in terms of
// spew, and spew does not handle non-primitive map keys well. So
// first we collapse it into a slice, sort the slice, then hash that.
slice := make([]addrReady, 0, len(addrs))
for k, ready := range addrs {
slice = append(slice, addrReady{k, ready})
}
sort.Sort(addrsReady(slice))
hasher := md5.New()
hashutil.DeepHashObject(hasher, slice)
return hex.EncodeToString(hasher.Sum(nil)[0:])
}
func lessAddrReady(a, b addrReady) bool {
// ready is not significant to hashing since we can't have duplicate addresses
return LessEndpointAddress(a.addr, b.addr)
}
type addrsReady []addrReady
func (sl addrsReady) Len() int { return len(sl) }
func (sl addrsReady) Swap(i, j int) { sl[i], sl[j] = sl[j], sl[i] }
func (sl addrsReady) Less(i, j int) bool {
return lessAddrReady(sl[i], sl[j])
}
// LessEndpointAddress compares IP addresses lexicographically and returns true if first argument is lesser than second
func LessEndpointAddress(a, b *api.EndpointAddress) bool {
ipComparison := bytes.Compare([]byte(a.IP), []byte(b.IP))
if ipComparison != 0 {
return ipComparison < 0
}
if b.TargetRef == nil {
return false
}
if a.TargetRef == nil {
return true
}
return a.TargetRef.UID < b.TargetRef.UID
}
// SortSubsets sorts an array of EndpointSubset objects in place. For ease of
// use it returns the input slice.
func SortSubsets(subsets []api.EndpointSubset) []api.EndpointSubset {
for i := range subsets {
ss := &subsets[i]
sort.Sort(addrsByIPAndUID(ss.Addresses))
sort.Sort(addrsByIPAndUID(ss.NotReadyAddresses))
sort.Sort(portsByHash(ss.Ports))
}
sort.Sort(subsetsByHash(subsets))
return subsets
}
func hashObject(hasher hash.Hash, obj interface{}) []byte {
hashutil.DeepHashObject(hasher, obj)
return hasher.Sum(nil)
}
type subsetsByHash []api.EndpointSubset
func (sl subsetsByHash) Len() int { return len(sl) }
func (sl subsetsByHash) Swap(i, j int) { sl[i], sl[j] = sl[j], sl[i] }
func (sl subsetsByHash) Less(i, j int) bool {
hasher := md5.New()
h1 := hashObject(hasher, sl[i])
h2 := hashObject(hasher, sl[j])
return bytes.Compare(h1, h2) < 0
}
type addrsByIPAndUID []api.EndpointAddress
func (sl addrsByIPAndUID) Len() int { return len(sl) }
func (sl addrsByIPAndUID) Swap(i, j int) { sl[i], sl[j] = sl[j], sl[i] }
func (sl addrsByIPAndUID) Less(i, j int) bool {
return LessEndpointAddress(&sl[i], &sl[j])
}
type portsByHash []api.EndpointPort
func (sl portsByHash) Len() int { return len(sl) }
func (sl portsByHash) Swap(i, j int) { sl[i], sl[j] = sl[j], sl[i] }
func (sl portsByHash) Less(i, j int) bool {
hasher := md5.New()
h1 := hashObject(hasher, sl[i])
h2 := hashObject(hasher, sl[j])
return bytes.Compare(h1, h2) < 0
}
...@@ -42,7 +42,8 @@ func BindFlags(l *componentbaseconfig.LeaderElectionConfiguration, fs *pflag.Fla ...@@ -42,7 +42,8 @@ func BindFlags(l *componentbaseconfig.LeaderElectionConfiguration, fs *pflag.Fla
"of a leadership. This is only applicable if leader election is enabled.") "of a leadership. This is only applicable if leader election is enabled.")
fs.StringVar(&l.ResourceLock, "leader-elect-resource-lock", l.ResourceLock, ""+ fs.StringVar(&l.ResourceLock, "leader-elect-resource-lock", l.ResourceLock, ""+
"The type of resource object that is used for locking during "+ "The type of resource object that is used for locking during "+
"leader election. Supported options are `endpoints` (default) and `configmaps`.") "leader election. Supported options are 'endpoints', 'configmaps', "+
"'leases', 'endpointsleases' and 'configmapsleases'.")
fs.StringVar(&l.ResourceName, "leader-elect-resource-name", l.ResourceName, ""+ fs.StringVar(&l.ResourceName, "leader-elect-resource-name", l.ResourceName, ""+
"The name of resource object that is used for locking during "+ "The name of resource object that is used for locking during "+
"leader election.") "leader election.")
......
...@@ -479,9 +479,18 @@ func (e *EndpointController) syncService(key string) error { ...@@ -479,9 +479,18 @@ func (e *EndpointController) syncService(key string) error {
createEndpoints := len(currentEndpoints.ResourceVersion) == 0 createEndpoints := len(currentEndpoints.ResourceVersion) == 0
// Compare the sorted subsets and labels
// Remove the HeadlessService label from the endpoints if it exists,
// as this won't be set on the service itself
// and will cause a false negative in this diff check.
// But first check if it has that label to avoid expensive copies.
compareLabels := currentEndpoints.Labels
if _, ok := currentEndpoints.Labels[v1.IsHeadlessService]; ok {
compareLabels = utillabels.CloneAndRemoveLabel(currentEndpoints.Labels, v1.IsHeadlessService)
}
if !createEndpoints && if !createEndpoints &&
apiequality.Semantic.DeepEqual(currentEndpoints.Subsets, subsets) && apiequality.Semantic.DeepEqual(currentEndpoints.Subsets, subsets) &&
apiequality.Semantic.DeepEqual(currentEndpoints.Labels, service.Labels) { apiequality.Semantic.DeepEqual(compareLabels, service.Labels) {
klog.V(5).Infof("endpoints are equal for %s/%s, skipping update", service.Namespace, service.Name) klog.V(5).Infof("endpoints are equal for %s/%s, skipping update", service.Namespace, service.Name)
return nil return nil
} }
......
...@@ -114,10 +114,14 @@ func ReadDockercfgFile(searchPaths []string) (cfg DockerConfig, err error) { ...@@ -114,10 +114,14 @@ func ReadDockercfgFile(searchPaths []string) (cfg DockerConfig, err error) {
continue continue
} }
cfg, err := readDockerConfigFileFromBytes(contents) cfg, err := readDockerConfigFileFromBytes(contents)
if err == nil { if err != nil {
klog.V(4).Infof("found .dockercfg at %s", absDockerConfigFileLocation) klog.V(4).Infof("couldn't get the config from %q contents: %v", absDockerConfigFileLocation, err)
return cfg, nil continue
} }
klog.V(4).Infof("found .dockercfg at %s", absDockerConfigFileLocation)
return cfg, nil
} }
return nil, fmt.Errorf("couldn't find valid .dockercfg after checking in %v", searchPaths) return nil, fmt.Errorf("couldn't find valid .dockercfg after checking in %v", searchPaths)
} }
...@@ -224,8 +228,7 @@ func ReadDockerConfigFileFromUrl(url string, client *http.Client, header *http.H ...@@ -224,8 +228,7 @@ func ReadDockerConfigFileFromUrl(url string, client *http.Client, header *http.H
func readDockerConfigFileFromBytes(contents []byte) (cfg DockerConfig, err error) { func readDockerConfigFileFromBytes(contents []byte) (cfg DockerConfig, err error) {
if err = json.Unmarshal(contents, &cfg); err != nil { if err = json.Unmarshal(contents, &cfg); err != nil {
klog.Errorf("while trying to parse blob %q: %v", contents, err) return nil, errors.New("error occurred while trying to unmarshal json")
return nil, err
} }
return return
} }
...@@ -233,8 +236,7 @@ func readDockerConfigFileFromBytes(contents []byte) (cfg DockerConfig, err error ...@@ -233,8 +236,7 @@ func readDockerConfigFileFromBytes(contents []byte) (cfg DockerConfig, err error
func readDockerConfigJsonFileFromBytes(contents []byte) (cfg DockerConfig, err error) { func readDockerConfigJsonFileFromBytes(contents []byte) (cfg DockerConfig, err error) {
var cfgJson DockerConfigJson var cfgJson DockerConfigJson
if err = json.Unmarshal(contents, &cfgJson); err != nil { if err = json.Unmarshal(contents, &cfgJson); err != nil {
klog.Errorf("while trying to parse blob %q: %v", contents, err) return nil, errors.New("error occurred while trying to unmarshal json")
return nil, err
} }
cfg = cfgJson.Auths cfg = cfgJson.Auths
return return
......
...@@ -13,7 +13,6 @@ go_library( ...@@ -13,7 +13,6 @@ go_library(
], ],
importpath = "k8s.io/kubernetes/pkg/registry/core/endpoint", importpath = "k8s.io/kubernetes/pkg/registry/core/endpoint",
deps = [ deps = [
"//pkg/api/endpoints:go_default_library",
"//pkg/api/legacyscheme:go_default_library", "//pkg/api/legacyscheme:go_default_library",
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/apis/core/validation:go_default_library", "//pkg/apis/core/validation:go_default_library",
......
...@@ -22,7 +22,6 @@ import ( ...@@ -22,7 +22,6 @@ import (
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/apiserver/pkg/storage/names" "k8s.io/apiserver/pkg/storage/names"
endptspkg "k8s.io/kubernetes/pkg/api/endpoints"
"k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/legacyscheme"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/apis/core/validation" "k8s.io/kubernetes/pkg/apis/core/validation"
...@@ -60,8 +59,6 @@ func (endpointsStrategy) Validate(ctx context.Context, obj runtime.Object) field ...@@ -60,8 +59,6 @@ func (endpointsStrategy) Validate(ctx context.Context, obj runtime.Object) field
// Canonicalize normalizes the object after validation. // Canonicalize normalizes the object after validation.
func (endpointsStrategy) Canonicalize(obj runtime.Object) { func (endpointsStrategy) Canonicalize(obj runtime.Object) {
endpoints := obj.(*api.Endpoints)
endpoints.Subsets = endptspkg.RepackSubsets(endpoints.Subsets)
} }
// AllowCreateOnUpdate is true for endpoints. // AllowCreateOnUpdate is true for endpoints.
......
...@@ -48,6 +48,9 @@ const ( ...@@ -48,6 +48,9 @@ const (
errLeaseIDMissing = "LeaseIdMissing" errLeaseIDMissing = "LeaseIdMissing"
errContainerNotFound = "ContainerNotFound" errContainerNotFound = "ContainerNotFound"
errDiskNotFound = "is not found" errDiskNotFound = "is not found"
errStatusCode400 = "statuscode=400"
errInvalidParameter = `code="invalidparameter"`
errTargetInstanceIds = `target="instanceids"`
) )
var defaultBackOff = kwait.Backoff{ var defaultBackOff = kwait.Backoff{
...@@ -188,6 +191,11 @@ func (c *controllerCommon) DetachDisk(diskName, diskURI string, nodeName types.N ...@@ -188,6 +191,11 @@ func (c *controllerCommon) DetachDisk(diskName, diskURI string, nodeName types.N
c.diskAttachDetachMap.Delete(strings.ToLower(diskURI)) c.diskAttachDetachMap.Delete(strings.ToLower(diskURI))
c.vmLockMap.UnlockEntry(strings.ToLower(string(nodeName))) c.vmLockMap.UnlockEntry(strings.ToLower(string(nodeName)))
if err != nil && isInstanceNotFoundError(err) {
// if host doesn't exist, no need to detach
klog.Warningf("azureDisk - got InstanceNotFoundError(%v), DetachDisk(%s) will assume disk is already detached", err, diskURI)
return nil
}
if c.cloud.CloudProviderBackoff && shouldRetryHTTPRequest(resp, err) { if c.cloud.CloudProviderBackoff && shouldRetryHTTPRequest(resp, err) {
klog.V(2).Infof("azureDisk - update backing off: detach disk(%s, %s), err: %v", diskName, diskURI, err) klog.V(2).Infof("azureDisk - update backing off: detach disk(%s, %s), err: %v", diskName, diskURI, err)
retryErr := kwait.ExponentialBackoff(c.cloud.RequestBackoff(), func() (bool, error) { retryErr := kwait.ExponentialBackoff(c.cloud.RequestBackoff(), func() (bool, error) {
...@@ -359,3 +367,8 @@ func (c *controllerCommon) checkDiskExists(ctx context.Context, diskURI string) ...@@ -359,3 +367,8 @@ func (c *controllerCommon) checkDiskExists(ctx context.Context, diskURI string)
return true, nil return true, nil
} }
func isInstanceNotFoundError(err error) bool {
errMsg := strings.ToLower(err.Error())
return strings.Contains(errMsg, errStatusCode400) && strings.Contains(errMsg, errInvalidParameter) && strings.Contains(errMsg, errTargetInstanceIds)
}
...@@ -137,7 +137,11 @@ func (as *availabilitySet) DetachDisk(diskName, diskURI string, nodeName types.N ...@@ -137,7 +137,11 @@ func (as *availabilitySet) DetachDisk(diskName, diskURI string, nodeName types.N
(disk.ManagedDisk != nil && diskURI != "" && strings.EqualFold(*disk.ManagedDisk.ID, diskURI)) { (disk.ManagedDisk != nil && diskURI != "" && strings.EqualFold(*disk.ManagedDisk.ID, diskURI)) {
// found the disk // found the disk
klog.V(2).Infof("azureDisk - detach disk: name %q uri %q", diskName, diskURI) klog.V(2).Infof("azureDisk - detach disk: name %q uri %q", diskName, diskURI)
disks[i].ToBeDetached = to.BoolPtr(true) if strings.EqualFold(as.cloud.Environment.Name, "AZURESTACKCLOUD") {
disks = append(disks[:i], disks[i+1:]...)
} else {
disks[i].ToBeDetached = to.BoolPtr(true)
}
bFoundDisk = true bFoundDisk = true
break break
} }
......
...@@ -141,7 +141,11 @@ func (ss *scaleSet) DetachDisk(diskName, diskURI string, nodeName types.NodeName ...@@ -141,7 +141,11 @@ func (ss *scaleSet) DetachDisk(diskName, diskURI string, nodeName types.NodeName
(disk.ManagedDisk != nil && diskURI != "" && strings.EqualFold(*disk.ManagedDisk.ID, diskURI)) { (disk.ManagedDisk != nil && diskURI != "" && strings.EqualFold(*disk.ManagedDisk.ID, diskURI)) {
// found the disk // found the disk
klog.V(2).Infof("azureDisk - detach disk: name %q uri %q", diskName, diskURI) klog.V(2).Infof("azureDisk - detach disk: name %q uri %q", diskName, diskURI)
disks[i].ToBeDetached = to.BoolPtr(true) if strings.EqualFold(ss.cloud.Environment.Name, "AZURESTACKCLOUD") {
disks = append(disks[:i], disks[i+1:]...)
} else {
disks[i].ToBeDetached = to.BoolPtr(true)
}
bFoundDisk = true bFoundDisk = true
break break
} }
......
...@@ -74,6 +74,7 @@ func registerAPIMetrics(attributes ...string) *apiCallMetrics { ...@@ -74,6 +74,7 @@ func registerAPIMetrics(attributes ...string) *apiCallMetrics {
&metrics.HistogramOpts{ &metrics.HistogramOpts{
Name: "cloudprovider_azure_api_request_duration_seconds", Name: "cloudprovider_azure_api_request_duration_seconds",
Help: "Latency of an Azure API call", Help: "Latency of an Azure API call",
Buckets: []float64{.1, .25, .5, 1, 2.5, 5, 10, 15, 25, 50, 120, 300, 600, 1200},
StabilityLevel: metrics.ALPHA, StabilityLevel: metrics.ALPHA,
}, },
attributes, attributes,
......
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