{"action":"created","comment":{"url":"https://api.github.com/repos/kubernetes-incubator/external-storage/pulls/comments/179936345","pull_request_review_id":110275673,"id":179936345,"diff_hunk":"@@ -0,0 +1,479 @@\n+/*\n+Copyright 2017 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 monitor\n+\n+import (\n+\t\"fmt\"\n+\t\"strings\"\n+\t\"sync\"\n+\t\"time\"\n+\n+\t\"github.com/golang/glog\"\n+\t\"github.com/kubernetes-incubator/external-storage/local-volume/provisioner/pkg/common\"\n+\t\"github.com/kubernetes-incubator/external-storage/local-volume/provisioner/pkg/util\"\n+\n+\t\"k8s.io/api/core/v1\"\n+\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n+\t\"k8s.io/apimachinery/pkg/labels\"\n+\t\"k8s.io/apimachinery/pkg/runtime\"\n+\t\"k8s.io/apimachinery/pkg/watch\"\n+\t\"k8s.io/client-go/tools/cache\"\n+\t\"k8s.io/kubernetes/pkg/api/v1/helper\"\n+)\n+\n+const (\n+\t// DefaultInformerResyncPeriod is the resync period of informer\n+\tDefaultInformerResyncPeriod = 15 * time.Second\n+\n+\t// DefaultMonitorResyncPeriod is the resync period of monitor\n+\tDefaultMonitorResyncPeriod = 1 * time.Minute\n+\n+\t// UpdatePVRetryCount is the retry count of PV updating\n+\tUpdatePVRetryCount = 5\n+\n+\t// UpdatePVInterval is the interval of PV updating\n+\tUpdatePVInterval = 5 * time.Millisecond\n+)\n+\n+// marking event related const vars\n+const (\n+\tMarkPVFailed      = \"MarkPVFailed\"\n+\tUnMarkPVFailed    = \"UnMarkPVFailed\"\n+\tMarkPVSucceeded   = \"MarkPVSucceeded\"\n+\tUnMarkPVSucceeded = \"UnMarkPVSucceeded\"\n+\n+\tHostPathNotExist  = \"HostPathNotExist\"\n+\tMisMatchedVolSize = \"MisMatchedVolSize\"\n+\tNotMountPoint     = \"NotMountPoint\"\n+\n+\tFirstMarkTime = \"FirstMarkTime\"\n+)\n+\n+// PVUnhealthyKeys stores all the unhealthy marking keys\n+var PVUnhealthyKeys []string\n+\n+func init() {\n+\tPVUnhealthyKeys = append(PVUnhealthyKeys, HostPathNotExist)\n+\tPVUnhealthyKeys = append(PVUnhealthyKeys, MisMatchedVolSize)\n+\tPVUnhealthyKeys = append(PVUnhealthyKeys, NotMountPoint)\n+}\n+\n+// Monitor checks PVs' health condition and taint them if they are unhealthy\n+type Monitor struct {\n+\t*common.RuntimeConfig\n+\n+\tvolumeLW         cache.ListerWatcher\n+\tvolumeController cache.Controller\n+\n+\tlocalVolumeMap LocalVolumeMap\n+\n+\thasRun     bool\n+\thasRunLock *sync.Mutex\n+}\n+\n+// NewMonitor creates a monitor object that will scan through\n+// the configured directories and check volume status\n+func NewMonitor(config *common.RuntimeConfig) *Monitor {\n+\tmonitor := &Monitor{\n+\t\tRuntimeConfig: config,\n+\t\thasRun:        false,\n+\t\thasRunLock:    &sync.Mutex{},\n+\t}\n+\n+\tlabelOps := metav1.ListOptions{\n+\t\tLabelSelector: labels.Everything().String(),\n+\t}\n+\tif len(monitor.UserConfig.LabelSelectorForPV) > 0 {\n+\t\tlabelOps.LabelSelector = monitor.UserConfig.LabelSelectorForPV\n+\t}\n+\n+\tmonitor.localVolumeMap = NewLocalVolumeMap()\n+\n+\tmonitor.volumeLW = &cache.ListWatch{\n+\t\tListFunc: func(options metav1.ListOptions) (runtime.Object, error) {\n+\t\t\treturn config.Client.CoreV1().PersistentVolumes().List(labelOps)\n+\t\t},\n+\t\tWatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {\n+\t\t\treturn config.Client.CoreV1().PersistentVolumes().Watch(labelOps)\n+\t\t},\n+\t}\n+\t_, monitor.volumeController = cache.NewInformer(\n+\t\tmonitor.volumeLW,\n+\t\t&v1.PersistentVolume{},\n+\t\tDefaultInformerResyncPeriod,\n+\t\tcache.ResourceEventHandlerFuncs{\n+\t\t\tAddFunc:    monitor.addVolume,\n+\t\t\tUpdateFunc: monitor.updateVolume,\n+\t\t\tDeleteFunc: monitor.deleteVolume,\n+\t\t},\n+\t)\n+\n+\t// fill map at first with data from ETCD\n+\tmonitor.flushFromETCDFirst()\n+\n+\treturn monitor\n+}\n+\n+// flushFromETCDFirst fill map with data from etcd at first\n+func (monitor *Monitor) flushFromETCDFirst() error {\n+\tpvs, err := monitor.Client.CoreV1().PersistentVolumes().List(metav1.ListOptions{})\n+\tif err != nil {\n+\t\treturn err\n+\t}\n+\tif len(pvs.Items) == 0 {\n+\t\tglog.Infof(\"no pv in ETCD at first\")\n+\t\treturn nil\n+\t}\n+\n+\tfor _, pv := range pvs.Items {\n+\t\tmonitor.localVolumeMap.AddLocalVolume(&pv)\n+\t}\n+\treturn nil\n+}\n+\n+func (monitor *Monitor) addVolume(obj interface{}) {\n+\tvolume, ok := obj.(*v1.PersistentVolume)\n+\tif !ok {\n+\t\tglog.Errorf(\"Expected PersistentVolume but handler received %#v\", obj)\n+\t\treturn\n+\t}\n+\n+\tmonitor.localVolumeMap.AddLocalVolume(volume)\n+\n+}\n+\n+func (monitor *Monitor) updateVolume(oldObj, newObj interface{}) {\n+\tnewVolume, ok := newObj.(*v1.PersistentVolume)\n+\tif !ok {\n+\t\tglog.Errorf(\"Expected PersistentVolume but handler received %#v\", newObj)\n+\t\treturn\n+\t}\n+\n+\tmonitor.localVolumeMap.UpdateLocalVolume(newVolume)\n+}\n+\n+func (monitor *Monitor) deleteVolume(obj interface{}) {\n+\tvolume, ok := obj.(*v1.PersistentVolume)\n+\tif !ok {\n+\t\tglog.Errorf(\"Expected PersistentVolume but handler received %#v\", obj)\n+\t\treturn\n+\t}\n+\n+\tmonitor.localVolumeMap.DeleteLocalVolume(volume)\n+\n+}\n+\n+// Run starts all of this controller's control loops\n+func (monitor *Monitor) Run(stopCh <-chan struct{}) {\n+\tglog.Infof(\"Starting monitor controller %s!\", string(monitor.RuntimeConfig.Name))\n+\tmonitor.hasRunLock.Lock()\n+\tmonitor.hasRun = true\n+\tmonitor.hasRunLock.Unlock()\n+\tgo monitor.volumeController.Run(stopCh)\n+\n+\tgo monitor.MonitorLocalVolumes()\n+\t<-stopCh\n+}\n+\n+// HasRun returns whether the volume controller has Run\n+func (monitor *Monitor) HasRun() bool {\n+\tmonitor.hasRunLock.Lock()\n+\tdefer monitor.hasRunLock.Unlock()\n+\treturn monitor.hasRun\n+}\n+\n+// MonitorLocalVolumes checks local PVs periodically\n+func (monitor *Monitor) MonitorLocalVolumes() {\n+\tfor {\n+\t\tif monitor.HasRun() {\n+\t\t\tpvs := monitor.localVolumeMap.GetPVs()\n+\t\t\tfor _, pv := range pvs {\n+\t\t\t\tmonitor.checkStatus(pv)\n+\t\t\t}\n+\t\t}\n+\n+\t\ttime.Sleep(DefaultMonitorResyncPeriod)\n+\t}\n+}\n+\n+// checkStatus checks pv health condition\n+func (monitor *Monitor) checkStatus(pv *v1.PersistentVolume) {","path":"local-volume/provisioner/pkg/monitor/monitor.go","position":214,"original_position":214,"commit_id":"0433041a67e77d3928fb1fb16e5aaa09863a58bf","original_commit_id":"0433041a67e77d3928fb1fb16e5aaa09863a58bf","user":{"login":"NickrenREN","id":6104418,"avatar_url":"https://avatars3.githubusercontent.com/u/6104418?v=4","gravatar_id":"","url":"https://api.github.com/users/NickrenREN","html_url":"https://github.com/NickrenREN","followers_url":"https://api.github.com/users/NickrenREN/followers","following_url":"https://api.github.com/users/NickrenREN/following{/other_user}","gists_url":"https://api.github.com/users/NickrenREN/gists{/gist_id}","starred_url":"https://api.github.com/users/NickrenREN/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/NickrenREN/subscriptions","organizations_url":"https://api.github.com/users/NickrenREN/orgs","repos_url":"https://api.github.com/users/NickrenREN/repos","events_url":"https://api.github.com/users/NickrenREN/events{/privacy}","received_events_url":"https://api.github.com/users/NickrenREN/received_events","type":"User","site_admin":false},"body":"yes, this is just a simple demo, lots of extra work needs to be done for local pv monitor.\r\n","created_at":"2018-04-08T05:59:08Z","updated_at":"2018-04-08T05:59:08Z","html_url":"https://github.com/kubernetes-incubator/external-storage/pull/528#discussion_r179936345","pull_request_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/pulls/528","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/kubernetes-incubator/external-storage/pulls/comments/179936345"},"html":{"href":"https://github.com/kubernetes-incubator/external-storage/pull/528#discussion_r179936345"},"pull_request":{"href":"https://api.github.com/repos/kubernetes-incubator/external-storage/pulls/528"}},"in_reply_to_id":179936203},"pull_request":{"url":"https://api.github.com/repos/kubernetes-incubator/external-storage/pulls/528","id":160117837,"html_url":"https://github.com/kubernetes-incubator/external-storage/pull/528","diff_url":"https://github.com/kubernetes-incubator/external-storage/pull/528.diff","patch_url":"https://github.com/kubernetes-incubator/external-storage/pull/528.patch","issue_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/issues/528","number":528,"state":"open","locked":false,"title":"[WIP]: Monitor local pv","user":{"login":"NickrenREN","id":6104418,"avatar_url":"https://avatars3.githubusercontent.com/u/6104418?v=4","gravatar_id":"","url":"https://api.github.com/users/NickrenREN","html_url":"https://github.com/NickrenREN","followers_url":"https://api.github.com/users/NickrenREN/followers","following_url":"https://api.github.com/users/NickrenREN/following{/other_user}","gists_url":"https://api.github.com/users/NickrenREN/gists{/gist_id}","starred_url":"https://api.github.com/users/NickrenREN/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/NickrenREN/subscriptions","organizations_url":"https://api.github.com/users/NickrenREN/orgs","repos_url":"https://api.github.com/users/NickrenREN/repos","events_url":"https://api.github.com/users/NickrenREN/events{/privacy}","received_events_url":"https://api.github.com/users/NickrenREN/received_events","type":"User","site_admin":false},"body":"First commit: add monitor for local storage PVs.\r\nThe specific checking methods meed to be discussed more.\r\nThis one checks mount point, host dir and capacity.\r\n\r\nxref : [pv health monitoring proposal](https://github.com/kubernetes/community/pull/1484)\r\n\r\nTODOs:\r\n- [ ] ensure that PV usage is not greater than PV capacity ?\r\n- [ ] provide different monitor methods for different devices ?\r\n- [ ] node failure checking\r\n- [ ] add reaction\r\n\r\ncc @ddysher  @msau42 ","created_at":"2017-12-26T11:20:18Z","updated_at":"2018-04-08T05:59:09Z","closed_at":null,"merged_at":null,"merge_commit_sha":"42c5b4bcb763807cb0fda3e32cdb82ce61c71744","assignee":{"login":"msau42","id":24448061,"avatar_url":"https://avatars3.githubusercontent.com/u/24448061?v=4","gravatar_id":"","url":"https://api.github.com/users/msau42","html_url":"https://github.com/msau42","followers_url":"https://api.github.com/users/msau42/followers","following_url":"https://api.github.com/users/msau42/following{/other_user}","gists_url":"https://api.github.com/users/msau42/gists{/gist_id}","starred_url":"https://api.github.com/users/msau42/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/msau42/subscriptions","organizations_url":"https://api.github.com/users/msau42/orgs","repos_url":"https://api.github.com/users/msau42/repos","events_url":"https://api.github.com/users/msau42/events{/privacy}","received_events_url":"https://api.github.com/users/msau42/received_events","type":"User","site_admin":false},"assignees":[{"login":"msau42","id":24448061,"avatar_url":"https://avatars3.githubusercontent.com/u/24448061?v=4","gravatar_id":"","url":"https://api.github.com/users/msau42","html_url":"https://github.com/msau42","followers_url":"https://api.github.com/users/msau42/followers","following_url":"https://api.github.com/users/msau42/following{/other_user}","gists_url":"https://api.github.com/users/msau42/gists{/gist_id}","starred_url":"https://api.github.com/users/msau42/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/msau42/subscriptions","organizations_url":"https://api.github.com/users/msau42/orgs","repos_url":"https://api.github.com/users/msau42/repos","events_url":"https://api.github.com/users/msau42/events{/privacy}","received_events_url":"https://api.github.com/users/msau42/received_events","type":"User","site_admin":false}],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":612557102,"url":"https://api.github.com/repos/kubernetes-incubator/external-storage/labels/area/local-volume","name":"area/local-volume","color":"1d76db","default":false},{"id":547661380,"url":"https://api.github.com/repos/kubernetes-incubator/external-storage/labels/cncf-cla:%20yes","name":"cncf-cla: yes","color":"ededed","default":false},{"id":679095782,"url":"https://api.github.com/repos/kubernetes-incubator/external-storage/labels/size/XL","name":"size/XL","color":"ededed","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/pulls/528/commits","review_comments_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/pulls/528/comments","review_comment_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/pulls/comments{/number}","comments_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/issues/528/comments","statuses_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/statuses/0433041a67e77d3928fb1fb16e5aaa09863a58bf","head":{"label":"NickrenREN:monitor-local-pv","ref":"monitor-local-pv","sha":"0433041a67e77d3928fb1fb16e5aaa09863a58bf","user":{"login":"NickrenREN","id":6104418,"avatar_url":"https://avatars3.githubusercontent.com/u/6104418?v=4","gravatar_id":"","url":"https://api.github.com/users/NickrenREN","html_url":"https://github.com/NickrenREN","followers_url":"https://api.github.com/users/NickrenREN/followers","following_url":"https://api.github.com/users/NickrenREN/following{/other_user}","gists_url":"https://api.github.com/users/NickrenREN/gists{/gist_id}","starred_url":"https://api.github.com/users/NickrenREN/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/NickrenREN/subscriptions","organizations_url":"https://api.github.com/users/NickrenREN/orgs","repos_url":"https://api.github.com/users/NickrenREN/repos","events_url":"https://api.github.com/users/NickrenREN/events{/privacy}","received_events_url":"https://api.github.com/users/NickrenREN/received_events","type":"User","site_admin":false},"repo":{"id":110840008,"name":"external-storage","full_name":"NickrenREN/external-storage","owner":{"login":"NickrenREN","id":6104418,"avatar_url":"https://avatars3.githubusercontent.com/u/6104418?v=4","gravatar_id":"","url":"https://api.github.com/users/NickrenREN","html_url":"https://github.com/NickrenREN","followers_url":"https://api.github.com/users/NickrenREN/followers","following_url":"https://api.github.com/users/NickrenREN/following{/other_user}","gists_url":"https://api.github.com/users/NickrenREN/gists{/gist_id}","starred_url":"https://api.github.com/users/NickrenREN/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/NickrenREN/subscriptions","organizations_url":"https://api.github.com/users/NickrenREN/orgs","repos_url":"https://api.github.com/users/NickrenREN/repos","events_url":"https://api.github.com/users/NickrenREN/events{/privacy}","received_events_url":"https://api.github.com/users/NickrenREN/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/NickrenREN/external-storage","description":"External storage plugins, provisioners, and helper libraries","fork":true,"url":"https://api.github.com/repos/NickrenREN/external-storage","forks_url":"https://api.github.com/repos/NickrenREN/external-storage/forks","keys_url":"https://api.github.com/repos/NickrenREN/external-storage/keys{/key_id}","collaborators_url":"https://api.github.com/repos/NickrenREN/external-storage/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/NickrenREN/external-storage/teams","hooks_url":"https://api.github.com/repos/NickrenREN/external-storage/hooks","issue_events_url":"https://api.github.com/repos/NickrenREN/external-storage/issues/events{/number}","events_url":"https://api.github.com/repos/NickrenREN/external-storage/events","assignees_url":"https://api.github.com/repos/NickrenREN/external-storage/assignees{/user}","branches_url":"https://api.github.com/repos/NickrenREN/external-storage/branches{/branch}","tags_url":"https://api.github.com/repos/NickrenREN/external-storage/tags","blobs_url":"https://api.github.com/repos/NickrenREN/external-storage/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/NickrenREN/external-storage/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/NickrenREN/external-storage/git/refs{/sha}","trees_url":"https://api.github.com/repos/NickrenREN/external-storage/git/trees{/sha}","statuses_url":"https://api.github.com/repos/NickrenREN/external-storage/statuses/{sha}","languages_url":"https://api.github.com/repos/NickrenREN/external-storage/languages","stargazers_url":"https://api.github.com/repos/NickrenREN/external-storage/stargazers","contributors_url":"https://api.github.com/repos/NickrenREN/external-storage/contributors","subscribers_url":"https://api.github.com/repos/NickrenREN/external-storage/subscribers","subscription_url":"https://api.github.com/repos/NickrenREN/external-storage/subscription","commits_url":"https://api.github.com/repos/NickrenREN/external-storage/commits{/sha}","git_commits_url":"https://api.github.com/repos/NickrenREN/external-storage/git/commits{/sha}","comments_url":"https://api.github.com/repos/NickrenREN/external-storage/comments{/number}","issue_comment_url":"https://api.github.com/repos/NickrenREN/external-storage/issues/comments{/number}","contents_url":"https://api.github.com/repos/NickrenREN/external-storage/contents/{+path}","compare_url":"https://api.github.com/repos/NickrenREN/external-storage/compare/{base}...{head}","merges_url":"https://api.github.com/repos/NickrenREN/external-storage/merges","archive_url":"https://api.github.com/repos/NickrenREN/external-storage/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/NickrenREN/external-storage/downloads","issues_url":"https://api.github.com/repos/NickrenREN/external-storage/issues{/number}","pulls_url":"https://api.github.com/repos/NickrenREN/external-storage/pulls{/number}","milestones_url":"https://api.github.com/repos/NickrenREN/external-storage/milestones{/number}","notifications_url":"https://api.github.com/repos/NickrenREN/external-storage/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/NickrenREN/external-storage/labels{/name}","releases_url":"https://api.github.com/repos/NickrenREN/external-storage/releases{/id}","deployments_url":"https://api.github.com/repos/NickrenREN/external-storage/deployments","created_at":"2017-11-15T13:55:57Z","updated_at":"2018-04-08T04:10:35Z","pushed_at":"2018-04-08T04:10:29Z","git_url":"git://github.com/NickrenREN/external-storage.git","ssh_url":"git@github.com:NickrenREN/external-storage.git","clone_url":"https://github.com/NickrenREN/external-storage.git","svn_url":"https://github.com/NickrenREN/external-storage","homepage":"","size":111277,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":1,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"base":{"label":"kubernetes-incubator:master","ref":"master","sha":"e1568ce0681e17061f6183cd4f624b0bf46f9fa8","user":{"login":"kubernetes-incubator","id":20862812,"avatar_url":"https://avatars2.githubusercontent.com/u/20862812?v=4","gravatar_id":"","url":"https://api.github.com/users/kubernetes-incubator","html_url":"https://github.com/kubernetes-incubator","followers_url":"https://api.github.com/users/kubernetes-incubator/followers","following_url":"https://api.github.com/users/kubernetes-incubator/following{/other_user}","gists_url":"https://api.github.com/users/kubernetes-incubator/gists{/gist_id}","starred_url":"https://api.github.com/users/kubernetes-incubator/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kubernetes-incubator/subscriptions","organizations_url":"https://api.github.com/users/kubernetes-incubator/orgs","repos_url":"https://api.github.com/users/kubernetes-incubator/repos","events_url":"https://api.github.com/users/kubernetes-incubator/events{/privacy}","received_events_url":"https://api.github.com/users/kubernetes-incubator/received_events","type":"Organization","site_admin":false},"repo":{"id":82572869,"name":"external-storage","full_name":"kubernetes-incubator/external-storage","owner":{"login":"kubernetes-incubator","id":20862812,"avatar_url":"https://avatars2.githubusercontent.com/u/20862812?v=4","gravatar_id":"","url":"https://api.github.com/users/kubernetes-incubator","html_url":"https://github.com/kubernetes-incubator","followers_url":"https://api.github.com/users/kubernetes-incubator/followers","following_url":"https://api.github.com/users/kubernetes-incubator/following{/other_user}","gists_url":"https://api.github.com/users/kubernetes-incubator/gists{/gist_id}","starred_url":"https://api.github.com/users/kubernetes-incubator/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kubernetes-incubator/subscriptions","organizations_url":"https://api.github.com/users/kubernetes-incubator/orgs","repos_url":"https://api.github.com/users/kubernetes-incubator/repos","events_url":"https://api.github.com/users/kubernetes-incubator/events{/privacy}","received_events_url":"https://api.github.com/users/kubernetes-incubator/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/kubernetes-incubator/external-storage","description":"External storage plugins, provisioners, and helper libraries","fork":false,"url":"https://api.github.com/repos/kubernetes-incubator/external-storage","forks_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/forks","keys_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/keys{/key_id}","collaborators_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/teams","hooks_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/hooks","issue_events_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/issues/events{/number}","events_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/events","assignees_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/assignees{/user}","branches_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/branches{/branch}","tags_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/tags","blobs_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/git/refs{/sha}","trees_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/git/trees{/sha}","statuses_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/statuses/{sha}","languages_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/languages","stargazers_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/stargazers","contributors_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/contributors","subscribers_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/subscribers","subscription_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/subscription","commits_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/commits{/sha}","git_commits_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/git/commits{/sha}","comments_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/comments{/number}","issue_comment_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/issues/comments{/number}","contents_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/contents/{+path}","compare_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/compare/{base}...{head}","merges_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/merges","archive_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/downloads","issues_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/issues{/number}","pulls_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/pulls{/number}","milestones_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/milestones{/number}","notifications_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/labels{/name}","releases_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/releases{/id}","deployments_url":"https://api.github.com/repos/kubernetes-incubator/external-storage/deployments","created_at":"2017-02-20T15:29:16Z","updated_at":"2018-04-07T13:12:58Z","pushed_at":"2018-04-08T03:03:57Z","git_url":"git://github.com/kubernetes-incubator/external-storage.git","ssh_url":"git@github.com:kubernetes-incubator/external-storage.git","clone_url":"https://github.com/kubernetes-incubator/external-storage.git","svn_url":"https://github.com/kubernetes-incubator/external-storage","homepage":"","size":111379,"stargazers_count":500,"watchers_count":500,"language":"Go","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":310,"mirror_url":null,"archived":false,"open_issues_count":144,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":310,"open_issues":144,"watchers":500,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/kubernetes-incubator/external-storage/pulls/528"},"html":{"href":"https://github.com/kubernetes-incubator/external-storage/pull/528"},"issue":{"href":"https://api.github.com/repos/kubernetes-incubator/external-storage/issues/528"},"comments":{"href":"https://api.github.com/repos/kubernetes-incubator/external-storage/issues/528/comments"},"review_comments":{"href":"https://api.github.com/repos/kubernetes-incubator/external-storage/pulls/528/comments"},"review_comment":{"href":"https://api.github.com/repos/kubernetes-incubator/external-storage/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/kubernetes-incubator/external-storage/pulls/528/commits"},"statuses":{"href":"https://api.github.com/repos/kubernetes-incubator/external-storage/statuses/0433041a67e77d3928fb1fb16e5aaa09863a58bf"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"NickrenREN"}}