{"action":"created","comment":{"url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments/92722099","pull_request_review_id":13243476,"id":92722099,"diff_hunk":"@@ -0,0 +1,501 @@\n+/*\n+Copyright 2016 The Kubernetes Authors.\n+\n+Licensed under the Apache License, Version 2.0 (the \"License\");\n+you may not use this file except in compliance with the License.\n+You may obtain a copy of the License at\n+\n+    http://www.apache.org/licenses/LICENSE-2.0\n+\n+Unless required by applicable law or agreed to in writing, software\n+distributed under the License is distributed on an \"AS IS\" BASIS,\n+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+See the License for the specific language governing permissions and\n+limitations under the License.\n+*/\n+\n+package garbagecollector\n+\n+import (\n+\t\"fmt\"\n+\t\"sync\"\n+\t\"time\"\n+\n+\t\"github.com/golang/glog\"\n+\n+\t\"k8s.io/kubernetes/pkg/api/errors\"\n+\t\"k8s.io/kubernetes/pkg/api/meta\"\n+\t\"k8s.io/kubernetes/pkg/api/v1\"\n+\tmetav1 \"k8s.io/kubernetes/pkg/apis/meta/v1\"\n+\t\"k8s.io/kubernetes/pkg/client/cache\"\n+\t\"k8s.io/kubernetes/pkg/client/typed/dynamic\"\n+\t\"k8s.io/kubernetes/pkg/controller/garbagecollector/metaonly\"\n+\t\"k8s.io/kubernetes/pkg/runtime\"\n+\t\"k8s.io/kubernetes/pkg/runtime/schema\"\n+\t\"k8s.io/kubernetes/pkg/types\"\n+\t\"k8s.io/kubernetes/pkg/util/clock\"\n+\tutilerrors \"k8s.io/kubernetes/pkg/util/errors\"\n+\tutilruntime \"k8s.io/kubernetes/pkg/util/runtime\"\n+\t\"k8s.io/kubernetes/pkg/util/wait\"\n+\t\"k8s.io/kubernetes/pkg/util/workqueue\"\n+\t\"k8s.io/kubernetes/pkg/watch\"\n+)\n+\n+const ResourceResyncTime time.Duration = 0\n+\n+type monitor struct {\n+\tstore      cache.Store\n+\tcontroller *cache.Controller\n+}\n+\n+// GarbageCollector is responsible for carrying out cascading deletion, and\n+// removing ownerReferences from the dependents if the owner is deleted with\n+// DeleteOptions.OrphanDependents=true.\n+type GarbageCollector struct {\n+\trestMapper meta.RESTMapper\n+\t// metaOnlyClientPool uses a special codec, which removes fields except for\n+\t// apiVersion, kind, and metadata during decoding.\n+\tmetaOnlyClientPool dynamic.ClientPool\n+\t// clientPool uses the regular dynamicCodec. We need it to update\n+\t// finalizers. It can be removed if we support patching finalizers.\n+\tclientPool                       dynamic.ClientPool\n+\tdirtyQueue                       *workqueue.TimedWorkQueue\n+\torphanQueue                      *workqueue.TimedWorkQueue\n+\tmonitors                         []monitor\n+\tpropagator                       *Propagator\n+\tclock                            clock.Clock\n+\tregisteredRateLimiter            *RegisteredRateLimiter\n+\tregisteredRateLimiterForMonitors *RegisteredRateLimiter\n+\t// GC caches the owners that do not exist according to the API server.\n+\tabsentOwnerCache *UIDCache\n+}\n+\n+func gcListWatcher(client *dynamic.Client, resource schema.GroupVersionResource) *cache.ListWatch {\n+\treturn &cache.ListWatch{\n+\t\tListFunc: func(options v1.ListOptions) (runtime.Object, error) {\n+\t\t\t// APIResource.Kind is not used by the dynamic client, so\n+\t\t\t// leave it empty. We want to list this resource in all\n+\t\t\t// namespaces if it's namespace scoped, so leave\n+\t\t\t// APIResource.Namespaced as false is all right.\n+\t\t\tapiResource := metav1.APIResource{Name: resource.Resource}\n+\t\t\treturn client.ParameterCodec(dynamic.VersionedParameterEncoderWithV1Fallback).\n+\t\t\t\tResource(&apiResource, v1.NamespaceAll).\n+\t\t\t\tList(&options)\n+\t\t},\n+\t\tWatchFunc: func(options v1.ListOptions) (watch.Interface, error) {\n+\t\t\t// APIResource.Kind is not used by the dynamic client, so\n+\t\t\t// leave it empty. We want to list this resource in all\n+\t\t\t// namespaces if it's namespace scoped, so leave\n+\t\t\t// APIResource.Namespaced as false is all right.\n+\t\t\tapiResource := metav1.APIResource{Name: resource.Resource}\n+\t\t\treturn client.ParameterCodec(dynamic.VersionedParameterEncoderWithV1Fallback).\n+\t\t\t\tResource(&apiResource, v1.NamespaceAll).\n+\t\t\t\tWatch(&options)\n+\t\t},\n+\t}\n+}\n+\n+func (gc *GarbageCollector) monitorFor(resource schema.GroupVersionResource, kind schema.GroupVersionKind) (monitor, error) {\n+\t// TODO: consider store in one storage.\n+\tglog.V(6).Infof(\"create storage for resource %s\", resource)\n+\tvar monitor monitor\n+\tclient, err := gc.metaOnlyClientPool.ClientForGroupVersionKind(kind)\n+\tif err != nil {\n+\t\treturn monitor, err\n+\t}\n+\tgc.registeredRateLimiterForMonitors.registerIfNotPresent(resource.GroupVersion(), client, \"garbage_collector_monitoring\")\n+\tsetObjectTypeMeta := func(obj interface{}) {\n+\t\truntimeObject, ok := obj.(runtime.Object)\n+\t\tif !ok {\n+\t\t\tutilruntime.HandleError(fmt.Errorf(\"expected runtime.Object, got %#v\", obj))\n+\t\t}\n+\t\truntimeObject.GetObjectKind().SetGroupVersionKind(kind)\n+\t}\n+\tmonitor.store, monitor.controller = cache.NewInformer(\n+\t\tgcListWatcher(client, resource),\n+\t\tnil,\n+\t\tResourceResyncTime,\n+\t\tcache.ResourceEventHandlerFuncs{\n+\t\t\t// add the event to the propagator's eventQueue.\n+\t\t\tAddFunc: func(obj interface{}) {\n+\t\t\t\tsetObjectTypeMeta(obj)\n+\t\t\t\tevent := &event{\n+\t\t\t\t\teventType: addEvent,\n+\t\t\t\t\tobj:       obj,\n+\t\t\t\t}\n+\t\t\t\tgc.propagator.eventQueue.Add(&workqueue.TimedWorkQueueItem{StartTime: gc.clock.Now(), Object: event})\n+\t\t\t},\n+\t\t\tUpdateFunc: func(oldObj, newObj interface{}) {\n+\t\t\t\tsetObjectTypeMeta(newObj)\n+\t\t\t\tevent := &event{updateEvent, newObj, oldObj}\n+\t\t\t\tgc.propagator.eventQueue.Add(&workqueue.TimedWorkQueueItem{StartTime: gc.clock.Now(), Object: event})\n+\t\t\t},\n+\t\t\tDeleteFunc: func(obj interface{}) {\n+\t\t\t\t// delta fifo may wrap the object in a cache.DeletedFinalStateUnknown, unwrap it\n+\t\t\t\tif deletedFinalStateUnknown, ok := obj.(cache.DeletedFinalStateUnknown); ok {\n+\t\t\t\t\tobj = deletedFinalStateUnknown.Obj\n+\t\t\t\t}\n+\t\t\t\tsetObjectTypeMeta(obj)\n+\t\t\t\tevent := &event{\n+\t\t\t\t\teventType: deleteEvent,\n+\t\t\t\t\tobj:       obj,\n+\t\t\t\t}\n+\t\t\t\tgc.propagator.eventQueue.Add(&workqueue.TimedWorkQueueItem{StartTime: gc.clock.Now(), Object: event})\n+\t\t\t},\n+\t\t},\n+\t)\n+\treturn monitor, nil\n+}\n+\n+var ignoredResources = map[schema.GroupVersionResource]struct{}{\n+\tschema.GroupVersionResource{Group: \"extensions\", Version: \"v1beta1\", Resource: \"replicationcontrollers\"}:              {},\n+\tschema.GroupVersionResource{Group: \"\", Version: \"v1\", Resource: \"bindings\"}:                                           {},\n+\tschema.GroupVersionResource{Group: \"\", Version: \"v1\", Resource: \"componentstatuses\"}:                                  {},\n+\tschema.GroupVersionResource{Group: \"\", Version: \"v1\", Resource: \"events\"}:                                             {},\n+\tschema.GroupVersionResource{Group: \"authentication.k8s.io\", Version: \"v1beta1\", Resource: \"tokenreviews\"}:             {},\n+\tschema.GroupVersionResource{Group: \"authorization.k8s.io\", Version: \"v1beta1\", Resource: \"subjectaccessreviews\"}:      {},\n+\tschema.GroupVersionResource{Group: \"authorization.k8s.io\", Version: \"v1beta1\", Resource: \"selfsubjectaccessreviews\"}:  {},\n+\tschema.GroupVersionResource{Group: \"authorization.k8s.io\", Version: \"v1beta1\", Resource: \"localsubjectaccessreviews\"}: {},\n+}\n+\n+func NewGarbageCollector(metaOnlyClientPool dynamic.ClientPool, clientPool dynamic.ClientPool, mapper meta.RESTMapper, deletableResources map[schema.GroupVersionResource]struct{}) (*GarbageCollector, error) {\n+\tgc := &GarbageCollector{\n+\t\tmetaOnlyClientPool:               metaOnlyClientPool,\n+\t\tclientPool:                       clientPool,\n+\t\trestMapper:                       mapper,\n+\t\tclock:                            clock.RealClock{},\n+\t\tdirtyQueue:                       workqueue.NewTimedWorkQueue(),\n+\t\torphanQueue:                      workqueue.NewTimedWorkQueue(),\n+\t\tregisteredRateLimiter:            NewRegisteredRateLimiter(deletableResources),\n+\t\tregisteredRateLimiterForMonitors: NewRegisteredRateLimiter(deletableResources),\n+\t\tabsentOwnerCache:                 NewUIDCache(500),\n+\t}\n+\tgc.propagator = &Propagator{\n+\t\teventQueue: workqueue.NewTimedWorkQueue(),\n+\t\tuidToNode: &concurrentUIDToNode{\n+\t\t\tRWMutex:   &sync.RWMutex{},\n+\t\t\tuidToNode: make(map[types.UID]*node),\n+\t\t},\n+\t\tgc: gc,\n+\t}\n+\tfor resource := range deletableResources {\n+\t\tif _, ok := ignoredResources[resource]; ok {\n+\t\t\tglog.V(6).Infof(\"ignore resource %#v\", resource)\n+\t\t\tcontinue\n+\t\t}\n+\t\tkind, err := gc.restMapper.KindFor(resource)\n+\t\tif err != nil {\n+\t\t\treturn nil, err\n+\t\t}\n+\t\tmonitor, err := gc.monitorFor(resource, kind)\n+\t\tif err != nil {\n+\t\t\treturn nil, err\n+\t\t}\n+\t\tgc.monitors = append(gc.monitors, monitor)\n+\t}\n+\treturn gc, nil\n+}\n+\n+func (gc *GarbageCollector) Run(workers int, stopCh <-chan struct{}) {\n+\tdefer gc.dirtyQueue.ShutDown()\n+\tdefer gc.orphanQueue.ShutDown()\n+\tdefer gc.propagator.eventQueue.ShutDown()\n+\n+\tglog.Infof(\"Garbage Collector: Initializing\")\n+\tfor _, monitor := range gc.monitors {\n+\t\tgo monitor.controller.Run(stopCh)\n+\t}\n+\n+\tvar syncs []cache.InformerSynced\n+\tfor _, monitor := range gc.monitors {\n+\t\tsyncs = syncs.append(monitor.controller.HasSynced())\n+\t}\n+\tif !cache.WaitForCacheSync(stopCh, syncs...) {\n+\t\treturn\n+\t}\n+\tglog.Infof(\"Garbage Collector: All monitored resources synced. Proceeding to collect garbage\")\n+\n+\t// worker\n+\tgo wait.Until(gc.propagator.processEvent, 0, stopCh)\n+\n+\tfor i := 0; i < workers; i++ {\n+\t\tgo wait.Until(gc.worker, 0, stopCh)\n+\t\tgo wait.Until(gc.orphanFinalizer, 0, stopCh)\n+\t}\n+\tRegister()\n+\t<-stopCh\n+\tglog.Infof(\"Garbage Collector: Shutting down\")\n+}\n+\n+func (gc *GarbageCollector) worker() {","path":"pkg/controller/garbagecollector/garbage_collector.go","position":null,"original_position":230,"commit_id":"b49f2530c5ba3e8623722850e47c9b2dfd6f9bac","original_commit_id":"d6d693f949ecd2761c75571d96772ba66853869a","user":{"login":"caesarxuchao","id":2823529,"avatar_url":"https://avatars.githubusercontent.com/u/2823529?v=3","gravatar_id":"","url":"https://api.github.com/users/caesarxuchao","html_url":"https://github.com/caesarxuchao","followers_url":"https://api.github.com/users/caesarxuchao/followers","following_url":"https://api.github.com/users/caesarxuchao/following{/other_user}","gists_url":"https://api.github.com/users/caesarxuchao/gists{/gist_id}","starred_url":"https://api.github.com/users/caesarxuchao/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/caesarxuchao/subscriptions","organizations_url":"https://api.github.com/users/caesarxuchao/orgs","repos_url":"https://api.github.com/users/caesarxuchao/repos","events_url":"https://api.github.com/users/caesarxuchao/events{/privacy}","received_events_url":"https://api.github.com/users/caesarxuchao/received_events","type":"User","site_admin":false},"body":"Renamed to attempToDeleteWorker.","created_at":"2016-12-15T23:19:29Z","updated_at":"2016-12-15T23:19:29Z","html_url":"https://github.com/kubernetes/kubernetes/pull/38679#discussion_r92722099","pull_request_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/38679","_links":{"self":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments/92722099"},"html":{"href":"https://github.com/kubernetes/kubernetes/pull/38679#discussion_r92722099"},"pull_request":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/38679"}}},"pull_request":{"url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/38679","id":97706445,"html_url":"https://github.com/kubernetes/kubernetes/pull/38679","diff_url":"https://github.com/kubernetes/kubernetes/pull/38679.diff","patch_url":"https://github.com/kubernetes/kubernetes/pull/38679.patch","issue_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/38679","number":38679,"state":"open","locked":false,"title":"GC changes for synchronous GC supports","user":{"login":"caesarxuchao","id":2823529,"avatar_url":"https://avatars.githubusercontent.com/u/2823529?v=3","gravatar_id":"","url":"https://api.github.com/users/caesarxuchao","html_url":"https://github.com/caesarxuchao","followers_url":"https://api.github.com/users/caesarxuchao/followers","following_url":"https://api.github.com/users/caesarxuchao/following{/other_user}","gists_url":"https://api.github.com/users/caesarxuchao/gists{/gist_id}","starred_url":"https://api.github.com/users/caesarxuchao/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/caesarxuchao/subscriptions","organizations_url":"https://api.github.com/users/caesarxuchao/orgs","repos_url":"https://api.github.com/users/caesarxuchao/repos","events_url":"https://api.github.com/users/caesarxuchao/events{/privacy}","received_events_url":"https://api.github.com/users/caesarxuchao/received_events","type":"User","site_admin":false},"body":"Split from #38676.\r\nDesign doc: https://github.com/kubernetes/community/blob/master/contributors/design-proposals/synchronous-garbage-collection.md.\r\n\r\nThis PR won't compile. It's for review only.\r\n\r\ncc @kubernetes/sig-api-machinery","created_at":"2016-12-13T08:37:20Z","updated_at":"2016-12-15T23:19:29Z","closed_at":null,"merged_at":null,"merge_commit_sha":"8d289ff980680316f0323223a959e78de93a7691","assignee":{"login":"deads2k","id":8225098,"avatar_url":"https://avatars.githubusercontent.com/u/8225098?v=3","gravatar_id":"","url":"https://api.github.com/users/deads2k","html_url":"https://github.com/deads2k","followers_url":"https://api.github.com/users/deads2k/followers","following_url":"https://api.github.com/users/deads2k/following{/other_user}","gists_url":"https://api.github.com/users/deads2k/gists{/gist_id}","starred_url":"https://api.github.com/users/deads2k/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/deads2k/subscriptions","organizations_url":"https://api.github.com/users/deads2k/orgs","repos_url":"https://api.github.com/users/deads2k/repos","events_url":"https://api.github.com/users/deads2k/events{/privacy}","received_events_url":"https://api.github.com/users/deads2k/received_events","type":"User","site_admin":false},"assignees":[{"login":"deads2k","id":8225098,"avatar_url":"https://avatars.githubusercontent.com/u/8225098?v=3","gravatar_id":"","url":"https://api.github.com/users/deads2k","html_url":"https://github.com/deads2k","followers_url":"https://api.github.com/users/deads2k/followers","following_url":"https://api.github.com/users/deads2k/following{/other_user}","gists_url":"https://api.github.com/users/deads2k/gists{/gist_id}","starred_url":"https://api.github.com/users/deads2k/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/deads2k/subscriptions","organizations_url":"https://api.github.com/users/deads2k/orgs","repos_url":"https://api.github.com/users/deads2k/repos","events_url":"https://api.github.com/users/deads2k/events{/privacy}","received_events_url":"https://api.github.com/users/deads2k/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/38679/commits","review_comments_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/38679/comments","review_comment_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments{/number}","comments_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/38679/comments","statuses_url":"https://api.github.com/repos/kubernetes/kubernetes/statuses/b49f2530c5ba3e8623722850e47c9b2dfd6f9bac","head":{"label":"caesarxuchao:sync-gc-controller","ref":"sync-gc-controller","sha":"b49f2530c5ba3e8623722850e47c9b2dfd6f9bac","user":{"login":"caesarxuchao","id":2823529,"avatar_url":"https://avatars.githubusercontent.com/u/2823529?v=3","gravatar_id":"","url":"https://api.github.com/users/caesarxuchao","html_url":"https://github.com/caesarxuchao","followers_url":"https://api.github.com/users/caesarxuchao/followers","following_url":"https://api.github.com/users/caesarxuchao/following{/other_user}","gists_url":"https://api.github.com/users/caesarxuchao/gists{/gist_id}","starred_url":"https://api.github.com/users/caesarxuchao/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/caesarxuchao/subscriptions","organizations_url":"https://api.github.com/users/caesarxuchao/orgs","repos_url":"https://api.github.com/users/caesarxuchao/repos","events_url":"https://api.github.com/users/caesarxuchao/events{/privacy}","received_events_url":"https://api.github.com/users/caesarxuchao/received_events","type":"User","site_admin":false},"repo":{"id":34024678,"name":"kubernetes","full_name":"caesarxuchao/kubernetes","owner":{"login":"caesarxuchao","id":2823529,"avatar_url":"https://avatars.githubusercontent.com/u/2823529?v=3","gravatar_id":"","url":"https://api.github.com/users/caesarxuchao","html_url":"https://github.com/caesarxuchao","followers_url":"https://api.github.com/users/caesarxuchao/followers","following_url":"https://api.github.com/users/caesarxuchao/following{/other_user}","gists_url":"https://api.github.com/users/caesarxuchao/gists{/gist_id}","starred_url":"https://api.github.com/users/caesarxuchao/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/caesarxuchao/subscriptions","organizations_url":"https://api.github.com/users/caesarxuchao/orgs","repos_url":"https://api.github.com/users/caesarxuchao/repos","events_url":"https://api.github.com/users/caesarxuchao/events{/privacy}","received_events_url":"https://api.github.com/users/caesarxuchao/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/caesarxuchao/kubernetes","description":"Container Cluster Manager from Google","fork":true,"url":"https://api.github.com/repos/caesarxuchao/kubernetes","forks_url":"https://api.github.com/repos/caesarxuchao/kubernetes/forks","keys_url":"https://api.github.com/repos/caesarxuchao/kubernetes/keys{/key_id}","collaborators_url":"https://api.github.com/repos/caesarxuchao/kubernetes/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/caesarxuchao/kubernetes/teams","hooks_url":"https://api.github.com/repos/caesarxuchao/kubernetes/hooks","issue_events_url":"https://api.github.com/repos/caesarxuchao/kubernetes/issues/events{/number}","events_url":"https://api.github.com/repos/caesarxuchao/kubernetes/events","assignees_url":"https://api.github.com/repos/caesarxuchao/kubernetes/assignees{/user}","branches_url":"https://api.github.com/repos/caesarxuchao/kubernetes/branches{/branch}","tags_url":"https://api.github.com/repos/caesarxuchao/kubernetes/tags","blobs_url":"https://api.github.com/repos/caesarxuchao/kubernetes/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/caesarxuchao/kubernetes/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/caesarxuchao/kubernetes/git/refs{/sha}","trees_url":"https://api.github.com/repos/caesarxuchao/kubernetes/git/trees{/sha}","statuses_url":"https://api.github.com/repos/caesarxuchao/kubernetes/statuses/{sha}","languages_url":"https://api.github.com/repos/caesarxuchao/kubernetes/languages","stargazers_url":"https://api.github.com/repos/caesarxuchao/kubernetes/stargazers","contributors_url":"https://api.github.com/repos/caesarxuchao/kubernetes/contributors","subscribers_url":"https://api.github.com/repos/caesarxuchao/kubernetes/subscribers","subscription_url":"https://api.github.com/repos/caesarxuchao/kubernetes/subscription","commits_url":"https://api.github.com/repos/caesarxuchao/kubernetes/commits{/sha}","git_commits_url":"https://api.github.com/repos/caesarxuchao/kubernetes/git/commits{/sha}","comments_url":"https://api.github.com/repos/caesarxuchao/kubernetes/comments{/number}","issue_comment_url":"https://api.github.com/repos/caesarxuchao/kubernetes/issues/comments{/number}","contents_url":"https://api.github.com/repos/caesarxuchao/kubernetes/contents/{+path}","compare_url":"https://api.github.com/repos/caesarxuchao/kubernetes/compare/{base}...{head}","merges_url":"https://api.github.com/repos/caesarxuchao/kubernetes/merges","archive_url":"https://api.github.com/repos/caesarxuchao/kubernetes/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/caesarxuchao/kubernetes/downloads","issues_url":"https://api.github.com/repos/caesarxuchao/kubernetes/issues{/number}","pulls_url":"https://api.github.com/repos/caesarxuchao/kubernetes/pulls{/number}","milestones_url":"https://api.github.com/repos/caesarxuchao/kubernetes/milestones{/number}","notifications_url":"https://api.github.com/repos/caesarxuchao/kubernetes/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/caesarxuchao/kubernetes/labels{/name}","releases_url":"https://api.github.com/repos/caesarxuchao/kubernetes/releases{/id}","deployments_url":"https://api.github.com/repos/caesarxuchao/kubernetes/deployments","created_at":"2015-04-15T23:57:43Z","updated_at":"2016-08-12T23:35:58Z","pushed_at":"2016-12-15T23:05:27Z","git_url":"git://github.com/caesarxuchao/kubernetes.git","ssh_url":"git@github.com:caesarxuchao/kubernetes.git","clone_url":"https://github.com/caesarxuchao/kubernetes.git","svn_url":"https://github.com/caesarxuchao/kubernetes","homepage":"http://kubernetes.io","size":370445,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"kubernetes:master","ref":"master","sha":"18d05c7d56a8580485fd87e1b71d7bca13841296","user":{"login":"kubernetes","id":13629408,"avatar_url":"https://avatars.githubusercontent.com/u/13629408?v=3","gravatar_id":"","url":"https://api.github.com/users/kubernetes","html_url":"https://github.com/kubernetes","followers_url":"https://api.github.com/users/kubernetes/followers","following_url":"https://api.github.com/users/kubernetes/following{/other_user}","gists_url":"https://api.github.com/users/kubernetes/gists{/gist_id}","starred_url":"https://api.github.com/users/kubernetes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kubernetes/subscriptions","organizations_url":"https://api.github.com/users/kubernetes/orgs","repos_url":"https://api.github.com/users/kubernetes/repos","events_url":"https://api.github.com/users/kubernetes/events{/privacy}","received_events_url":"https://api.github.com/users/kubernetes/received_events","type":"Organization","site_admin":false},"repo":{"id":20580498,"name":"kubernetes","full_name":"kubernetes/kubernetes","owner":{"login":"kubernetes","id":13629408,"avatar_url":"https://avatars.githubusercontent.com/u/13629408?v=3","gravatar_id":"","url":"https://api.github.com/users/kubernetes","html_url":"https://github.com/kubernetes","followers_url":"https://api.github.com/users/kubernetes/followers","following_url":"https://api.github.com/users/kubernetes/following{/other_user}","gists_url":"https://api.github.com/users/kubernetes/gists{/gist_id}","starred_url":"https://api.github.com/users/kubernetes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kubernetes/subscriptions","organizations_url":"https://api.github.com/users/kubernetes/orgs","repos_url":"https://api.github.com/users/kubernetes/repos","events_url":"https://api.github.com/users/kubernetes/events{/privacy}","received_events_url":"https://api.github.com/users/kubernetes/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/kubernetes/kubernetes","description":"Production-Grade Container Scheduling and Management","fork":false,"url":"https://api.github.com/repos/kubernetes/kubernetes","forks_url":"https://api.github.com/repos/kubernetes/kubernetes/forks","keys_url":"https://api.github.com/repos/kubernetes/kubernetes/keys{/key_id}","collaborators_url":"https://api.github.com/repos/kubernetes/kubernetes/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/kubernetes/kubernetes/teams","hooks_url":"https://api.github.com/repos/kubernetes/kubernetes/hooks","issue_events_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/events{/number}","events_url":"https://api.github.com/repos/kubernetes/kubernetes/events","assignees_url":"https://api.github.com/repos/kubernetes/kubernetes/assignees{/user}","branches_url":"https://api.github.com/repos/kubernetes/kubernetes/branches{/branch}","tags_url":"https://api.github.com/repos/kubernetes/kubernetes/tags","blobs_url":"https://api.github.com/repos/kubernetes/kubernetes/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/kubernetes/kubernetes/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/kubernetes/kubernetes/git/refs{/sha}","trees_url":"https://api.github.com/repos/kubernetes/kubernetes/git/trees{/sha}","statuses_url":"https://api.github.com/repos/kubernetes/kubernetes/statuses/{sha}","languages_url":"https://api.github.com/repos/kubernetes/kubernetes/languages","stargazers_url":"https://api.github.com/repos/kubernetes/kubernetes/stargazers","contributors_url":"https://api.github.com/repos/kubernetes/kubernetes/contributors","subscribers_url":"https://api.github.com/repos/kubernetes/kubernetes/subscribers","subscription_url":"https://api.github.com/repos/kubernetes/kubernetes/subscription","commits_url":"https://api.github.com/repos/kubernetes/kubernetes/commits{/sha}","git_commits_url":"https://api.github.com/repos/kubernetes/kubernetes/git/commits{/sha}","comments_url":"https://api.github.com/repos/kubernetes/kubernetes/comments{/number}","issue_comment_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/comments{/number}","contents_url":"https://api.github.com/repos/kubernetes/kubernetes/contents/{+path}","compare_url":"https://api.github.com/repos/kubernetes/kubernetes/compare/{base}...{head}","merges_url":"https://api.github.com/repos/kubernetes/kubernetes/merges","archive_url":"https://api.github.com/repos/kubernetes/kubernetes/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/kubernetes/kubernetes/downloads","issues_url":"https://api.github.com/repos/kubernetes/kubernetes/issues{/number}","pulls_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls{/number}","milestones_url":"https://api.github.com/repos/kubernetes/kubernetes/milestones{/number}","notifications_url":"https://api.github.com/repos/kubernetes/kubernetes/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/kubernetes/kubernetes/labels{/name}","releases_url":"https://api.github.com/repos/kubernetes/kubernetes/releases{/id}","deployments_url":"https://api.github.com/repos/kubernetes/kubernetes/deployments","created_at":"2014-06-06T22:56:04Z","updated_at":"2016-12-15T20:44:16Z","pushed_at":"2016-12-15T23:08:41Z","git_url":"git://github.com/kubernetes/kubernetes.git","ssh_url":"git@github.com:kubernetes/kubernetes.git","clone_url":"https://github.com/kubernetes/kubernetes.git","svn_url":"https://github.com/kubernetes/kubernetes","homepage":"http://kubernetes.io","size":479874,"stargazers_count":19270,"watchers_count":19270,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":6414,"mirror_url":null,"open_issues_count":5380,"forks":6414,"open_issues":5380,"watchers":19270,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/38679"},"html":{"href":"https://github.com/kubernetes/kubernetes/pull/38679"},"issue":{"href":"https://api.github.com/repos/kubernetes/kubernetes/issues/38679"},"comments":{"href":"https://api.github.com/repos/kubernetes/kubernetes/issues/38679/comments"},"review_comments":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/38679/comments"},"review_comment":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/38679/commits"},"statuses":{"href":"https://api.github.com/repos/kubernetes/kubernetes/statuses/b49f2530c5ba3e8623722850e47c9b2dfd6f9bac"}}}}
{"actor":{"display_login":"caesarxuchao"}}