Change:
Is this a request for help? (If yes, you should use our troubleshooting guide and community support channels, see ): No What keywords did you search in Kubernetes issues before filing this one? (If you have found any duplicates, you should instead reply there.): "LRUExpireCache" Is this a BUG REPORT or FEATURE REQUEST? (choose one): BUG REPORT What happened: requires write lock since needs to manipulate its list to track recently used item. Currently it uses read lock so it may introduce race condition. What you expected to happen: How to reproduce it (as minimally and precisely as possible): Anything else do we need to know:
This was fixed in

Discussion:
function save-logs() { local -r node_name="${1}" local -r dir="${2}" <del> local files="${3} ${common_logfiles}" </del> <ins> local files="${3}" </ins> if [[ "${KUBERNETES_PROVIDER}" == "gce" || "${KUBERNETES_PROVIDER}" == "gke" ]]; then files="${files} ${gce_logfiles}" fi if [[ "${KUBERNETES_PROVIDER}" == "aws" ]]; then files="${files} ${aws_logfiles}" fi if ssh-to-node "${node_name}" "sudo systemctl status kubelet.service" &> /dev/null; then ssh-to-node "${node_name}" "sudo journalctl --output=cat -u kubelet.service" > "${dir}/kubelet.log" || true ssh-to-node "${node_name}" "sudo journalctl --output=cat -u docker.service" > "${dir}/docker.log" || true <ins> ssh-to-node "${node_name}" "sudo journalctl --output=cat -k" > "${dir}/kern.log" || true </ins> else <del> files="${files} ${initd_logfiles} ${supervisord_logfiles}" </del> <ins> files="${kern_logfile} ${files} ${initd_logfiles} ${supervisord_logfiles}" </ins> fi copy-logs-from-node "${node_name}" "${dir}" "${files}" }

readonly node_logfiles="kube-proxy" readonly aws_logfiles="cloud-init-output" readonly gce_logfiles="startupscript" <del> readonly common_logfiles="kern" </del> <ins> readonly kern_logfile="kern" </ins> readonly initd_logfiles="docker" readonly supervisord_logfiles="kubelet supervisor/supervisord supervisor/kubelet-stdout supervisor/kubelet-stderr supervisor/docker-stdout supervisor/docker-stderr"

const ( operationDeleteCollection operation = "deleteCollection" operationList             operation = "list" <ins> // assume a default estimate for finalizers to complete when found on items pending deletion. finalizerEstimateSeconds int64 = int64(15) </ins> ) // operationKey is an entry in a cache.

} apiResource := unversioned.APIResource{Name: gvr.Resource, Namespaced: true} <del> err := dynamicClient.Resource(&apiResource, namespace).DeleteCollection(nil, &v1.ListOptions{}) </del> <ins> // namespace controller does not want the garbage collector to insert the orphan finalizer since it calls // resource deletions generically.  it will ensure all resources in the namespace are purged prior to releasing // namespace itself. orphanDependents := false err := dynamicClient.Resource(&apiResource, namespace).DeleteCollection(&v1.DeleteOptions{OrphanDependents: &orphanDependents}, &v1.ListOptions{}) </ins> if err == nil { return true, nil

} glog.V(5).Infof("namespace controller - deleteAllContentForGroupVersionResource - items remaining - namespace: %s, gvr: %v, items: %v", namespace, gvr, len(unstructuredList.Items)) if len(unstructuredList.Items) != 0 && estimate == int64(0) { <ins> // if any item has a finalizer, we treat that as a normal condition, and use a default estimation to allow for GC to complete. for _, item := range unstructuredList.Items { if len(item.GetFinalizers()) > 0 { glog.V(5).Infof("namespace controller - deleteAllContentForGroupVersionResource - items remaining with finalizers - namespace: %s, gvr: %v, finalizers: %v", namespace, gvr, item.GetFinalizers()) return finalizerEstimateSeconds, nil } } // nothing reported a finalizer, so something was unexpected as it should have been deleted. </ins> return estimate, fmt.Errorf("unexpected items still remain in namespace: %s for gvr: %v", namespace, gvr) } return estimate, nil

type LRUExpireCache struct { cache *lru.Cache <del> lock  sync.RWMutex </del> <ins> lock  sync.Mutex </ins> } func NewLRUExpireCache(maxSize int) *LRUExpireCache {

} func (c *LRUExpireCache) Get(key lru.Key) (interface{}, bool) { <del> c.lock.RLock() defer c.lock.RUnlock() </del> <ins> c.lock.Lock() defer c.lock.Unlock() </ins> e, ok := c.cache.Get(key) if !ok { return nil, false