{"action":"created","comment":{"url":"https://api.github.com/repos/cockpit-project/cockpit/pulls/comments/90516461","pull_request_review_id":11033561,"id":90516461,"diff_hunk":"@@ -0,0 +1,216 @@\n+/*jshint esversion: 6 */\n+/*\n+ * This file is part of Cockpit.\n+ *\n+ * Copyright (C) 2016 Red Hat, Inc.\n+ *\n+ * Cockpit is free software; you can redistribute it and/or modify it\n+ * under the terms of the GNU Lesser General Public License as published by\n+ * the Free Software Foundation; either version 2.1 of the License, or\n+ * (at your option) any later version.\n+ *\n+ * Cockpit is distributed in the hope that it will be useful, but\n+ * WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public License\n+ * along with Cockpit; If not, see <http://www.gnu.org/licenses/>.\n+ */\n+\n+import cockpit from 'cockpit';\n+import CONFIG from './config.es6';\n+import { logDebug, logError, spawnScript, getRandomInt } from './helpers.es6';\n+import { updatePciDevices, addPciDrivers, pciDeviceActionFailed, fullRefreshAction } from './actions.es6';\n+\n+function readFile({ path, mustExist = false, doneCallback = content => {}}) {\n+    const file = cockpit.file(path, {superuser: 'try'});\n+    file.read()\n+        .done(content => {\n+            if (content) { // null if file does not exist\n+                doneCallback(content);\n+            } else if (mustExist) {\n+                logError(`Content of ${path} cannot be read`);\n+            }\n+        }).fail(error => {\n+            logError(`File '${path}' read error: ${error}`);\n+        }).always(() => {\n+            file.close();\n+        });\n+}\n+\n+/**\n+ * Same as readFile() but avoids 'mmap() failed' on '/sys/...' files by using 'cat'.\n+ *\n+ * @param path\n+ * @param mustExist\n+ * @param doneCallback\n+ */\n+function readSysfsFile({ path, mustExist = false, doneCallback = content => {}}) {\n+    cockpit.script(`cat ${path}`, [], {superuser: 'try', err: 'out'})\n+        .done( content => {\n+            if (content) {\n+                doneCallback(content);\n+            }\n+        }).fail(() => {\n+            if (mustExist) {\n+                logError(`Content of ${path} cannot be read`);\n+            }\n+        } );\n+}\n+\n+function refreshPciDevice({ pciAddr, dispatch }) {\n+    logDebug(`refreshPciDevice: ${pciAddr}`);\n+    const DEVDIR = `${CONFIG.directories.pciDevs}/${pciAddr}`;\n+\n+    readSysfsFile({path: `${DEVDIR}/vendor`, mustExist: true, doneCallback: vendor => {\n+        readSysfsFile({path: `${DEVDIR}/class`, mustExist: true, doneCallback: devClass => {\n+            readSysfsFile({path: `${DEVDIR}/device`, mustExist: true, doneCallback: device => {","path":"pkg/devices/sysfs.es6","position":68,"original_position":68,"commit_id":"8806a6e064458a37e3c7faa43926fa1da969fd9c","original_commit_id":"8806a6e064458a37e3c7faa43926fa1da969fd9c","user":{"login":"stefwalter","id":795070,"avatar_url":"https://avatars.githubusercontent.com/u/795070?v=3","gravatar_id":"","url":"https://api.github.com/users/stefwalter","html_url":"https://github.com/stefwalter","followers_url":"https://api.github.com/users/stefwalter/followers","following_url":"https://api.github.com/users/stefwalter/following{/other_user}","gists_url":"https://api.github.com/users/stefwalter/gists{/gist_id}","starred_url":"https://api.github.com/users/stefwalter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stefwalter/subscriptions","organizations_url":"https://api.github.com/users/stefwalter/orgs","repos_url":"https://api.github.com/users/stefwalter/repos","events_url":"https://api.github.com/users/stefwalter/events{/privacy}","received_events_url":"https://api.github.com/users/stefwalter/received_events","type":"User","site_admin":false},"body":"Can you read these in parallel rather than one after the other. See ```cockpit.all()``` or ES6 ```Promise.all```","created_at":"2016-12-01T19:17:21Z","updated_at":"2016-12-01T19:20:48Z","html_url":"https://github.com/cockpit-project/cockpit/pull/5523#discussion_r90516461","pull_request_url":"https://api.github.com/repos/cockpit-project/cockpit/pulls/5523","_links":{"self":{"href":"https://api.github.com/repos/cockpit-project/cockpit/pulls/comments/90516461"},"html":{"href":"https://github.com/cockpit-project/cockpit/pull/5523#discussion_r90516461"},"pull_request":{"href":"https://api.github.com/repos/cockpit-project/cockpit/pulls/5523"}}},"pull_request":{"url":"https://api.github.com/repos/cockpit-project/cockpit/pulls/5523","id":96100711,"html_url":"https://github.com/cockpit-project/cockpit/pull/5523","diff_url":"https://github.com/cockpit-project/cockpit/pull/5523.diff","patch_url":"https://github.com/cockpit-project/cockpit/pull/5523.patch","issue_url":"https://api.github.com/repos/cockpit-project/cockpit/issues/5523","number":5523,"state":"open","locked":false,"title":"WIP: Hardware Devices","user":{"login":"mareklibra","id":17194943,"avatar_url":"https://avatars.githubusercontent.com/u/17194943?v=3","gravatar_id":"","url":"https://api.github.com/users/mareklibra","html_url":"https://github.com/mareklibra","followers_url":"https://api.github.com/users/mareklibra/followers","following_url":"https://api.github.com/users/mareklibra/following{/other_user}","gists_url":"https://api.github.com/users/mareklibra/gists{/gist_id}","starred_url":"https://api.github.com/users/mareklibra/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mareklibra/subscriptions","organizations_url":"https://api.github.com/users/mareklibra/orgs","repos_url":"https://api.github.com/users/mareklibra/repos","events_url":"https://api.github.com/users/mareklibra/events{/privacy}","received_events_url":"https://api.github.com/users/mareklibra/received_events","type":"User","site_admin":false},"body":"New package listing/managing hardware devices is introduced.\r\n\r\nThis PR is WIP for early synchronization.\r\n\r\nFeature page: https://github.com/cockpit-project/cockpit/wiki/Feature:-Hardware-Devices\r\n\r\nTODO:\r\n[ ] IOMMU Groups\r\n[ ] Integration tests\r\n[ ] USB Bus\r\n[ ] SCSI Bus","created_at":"2016-12-01T14:41:16Z","updated_at":"2016-12-01T19:20:48Z","closed_at":null,"merged_at":null,"merge_commit_sha":"b84711c9ab6a57acab32108a2c280fec1a8d8740","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/cockpit-project/cockpit/pulls/5523/commits","review_comments_url":"https://api.github.com/repos/cockpit-project/cockpit/pulls/5523/comments","review_comment_url":"https://api.github.com/repos/cockpit-project/cockpit/pulls/comments{/number}","comments_url":"https://api.github.com/repos/cockpit-project/cockpit/issues/5523/comments","statuses_url":"https://api.github.com/repos/cockpit-project/cockpit/statuses/8806a6e064458a37e3c7faa43926fa1da969fd9c","head":{"label":"mareklibra:devices","ref":"devices","sha":"8806a6e064458a37e3c7faa43926fa1da969fd9c","user":{"login":"mareklibra","id":17194943,"avatar_url":"https://avatars.githubusercontent.com/u/17194943?v=3","gravatar_id":"","url":"https://api.github.com/users/mareklibra","html_url":"https://github.com/mareklibra","followers_url":"https://api.github.com/users/mareklibra/followers","following_url":"https://api.github.com/users/mareklibra/following{/other_user}","gists_url":"https://api.github.com/users/mareklibra/gists{/gist_id}","starred_url":"https://api.github.com/users/mareklibra/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mareklibra/subscriptions","organizations_url":"https://api.github.com/users/mareklibra/orgs","repos_url":"https://api.github.com/users/mareklibra/repos","events_url":"https://api.github.com/users/mareklibra/events{/privacy}","received_events_url":"https://api.github.com/users/mareklibra/received_events","type":"User","site_admin":false},"repo":{"id":56306512,"name":"cockpit","full_name":"mareklibra/cockpit","owner":{"login":"mareklibra","id":17194943,"avatar_url":"https://avatars.githubusercontent.com/u/17194943?v=3","gravatar_id":"","url":"https://api.github.com/users/mareklibra","html_url":"https://github.com/mareklibra","followers_url":"https://api.github.com/users/mareklibra/followers","following_url":"https://api.github.com/users/mareklibra/following{/other_user}","gists_url":"https://api.github.com/users/mareklibra/gists{/gist_id}","starred_url":"https://api.github.com/users/mareklibra/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mareklibra/subscriptions","organizations_url":"https://api.github.com/users/mareklibra/orgs","repos_url":"https://api.github.com/users/mareklibra/repos","events_url":"https://api.github.com/users/mareklibra/events{/privacy}","received_events_url":"https://api.github.com/users/mareklibra/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/mareklibra/cockpit","description":"Cockpit, a user interface for Linux servers","fork":true,"url":"https://api.github.com/repos/mareklibra/cockpit","forks_url":"https://api.github.com/repos/mareklibra/cockpit/forks","keys_url":"https://api.github.com/repos/mareklibra/cockpit/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mareklibra/cockpit/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mareklibra/cockpit/teams","hooks_url":"https://api.github.com/repos/mareklibra/cockpit/hooks","issue_events_url":"https://api.github.com/repos/mareklibra/cockpit/issues/events{/number}","events_url":"https://api.github.com/repos/mareklibra/cockpit/events","assignees_url":"https://api.github.com/repos/mareklibra/cockpit/assignees{/user}","branches_url":"https://api.github.com/repos/mareklibra/cockpit/branches{/branch}","tags_url":"https://api.github.com/repos/mareklibra/cockpit/tags","blobs_url":"https://api.github.com/repos/mareklibra/cockpit/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mareklibra/cockpit/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mareklibra/cockpit/git/refs{/sha}","trees_url":"https://api.github.com/repos/mareklibra/cockpit/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mareklibra/cockpit/statuses/{sha}","languages_url":"https://api.github.com/repos/mareklibra/cockpit/languages","stargazers_url":"https://api.github.com/repos/mareklibra/cockpit/stargazers","contributors_url":"https://api.github.com/repos/mareklibra/cockpit/contributors","subscribers_url":"https://api.github.com/repos/mareklibra/cockpit/subscribers","subscription_url":"https://api.github.com/repos/mareklibra/cockpit/subscription","commits_url":"https://api.github.com/repos/mareklibra/cockpit/commits{/sha}","git_commits_url":"https://api.github.com/repos/mareklibra/cockpit/git/commits{/sha}","comments_url":"https://api.github.com/repos/mareklibra/cockpit/comments{/number}","issue_comment_url":"https://api.github.com/repos/mareklibra/cockpit/issues/comments{/number}","contents_url":"https://api.github.com/repos/mareklibra/cockpit/contents/{+path}","compare_url":"https://api.github.com/repos/mareklibra/cockpit/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mareklibra/cockpit/merges","archive_url":"https://api.github.com/repos/mareklibra/cockpit/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mareklibra/cockpit/downloads","issues_url":"https://api.github.com/repos/mareklibra/cockpit/issues{/number}","pulls_url":"https://api.github.com/repos/mareklibra/cockpit/pulls{/number}","milestones_url":"https://api.github.com/repos/mareklibra/cockpit/milestones{/number}","notifications_url":"https://api.github.com/repos/mareklibra/cockpit/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mareklibra/cockpit/labels{/name}","releases_url":"https://api.github.com/repos/mareklibra/cockpit/releases{/id}","deployments_url":"https://api.github.com/repos/mareklibra/cockpit/deployments","created_at":"2016-04-15T09:02:51Z","updated_at":"2016-04-15T09:02:55Z","pushed_at":"2016-12-01T15:17:42Z","git_url":"git://github.com/mareklibra/cockpit.git","ssh_url":"git@github.com:mareklibra/cockpit.git","clone_url":"https://github.com/mareklibra/cockpit.git","svn_url":"https://github.com/mareklibra/cockpit","homepage":"http://www.cockpit-project.org/","size":29490,"stargazers_count":0,"watchers_count":0,"language":"C","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":0,"forks":1,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"cockpit-project:master","ref":"master","sha":"5b94c372a262f645d9a2cd41646198be207edc26","user":{"login":"cockpit-project","id":5765104,"avatar_url":"https://avatars.githubusercontent.com/u/5765104?v=3","gravatar_id":"","url":"https://api.github.com/users/cockpit-project","html_url":"https://github.com/cockpit-project","followers_url":"https://api.github.com/users/cockpit-project/followers","following_url":"https://api.github.com/users/cockpit-project/following{/other_user}","gists_url":"https://api.github.com/users/cockpit-project/gists{/gist_id}","starred_url":"https://api.github.com/users/cockpit-project/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cockpit-project/subscriptions","organizations_url":"https://api.github.com/users/cockpit-project/orgs","repos_url":"https://api.github.com/users/cockpit-project/repos","events_url":"https://api.github.com/users/cockpit-project/events{/privacy}","received_events_url":"https://api.github.com/users/cockpit-project/received_events","type":"Organization","site_admin":false},"repo":{"id":14049216,"name":"cockpit","full_name":"cockpit-project/cockpit","owner":{"login":"cockpit-project","id":5765104,"avatar_url":"https://avatars.githubusercontent.com/u/5765104?v=3","gravatar_id":"","url":"https://api.github.com/users/cockpit-project","html_url":"https://github.com/cockpit-project","followers_url":"https://api.github.com/users/cockpit-project/followers","following_url":"https://api.github.com/users/cockpit-project/following{/other_user}","gists_url":"https://api.github.com/users/cockpit-project/gists{/gist_id}","starred_url":"https://api.github.com/users/cockpit-project/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cockpit-project/subscriptions","organizations_url":"https://api.github.com/users/cockpit-project/orgs","repos_url":"https://api.github.com/users/cockpit-project/repos","events_url":"https://api.github.com/users/cockpit-project/events{/privacy}","received_events_url":"https://api.github.com/users/cockpit-project/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/cockpit-project/cockpit","description":"Cockpit, an admin interface for Linux servers","fork":false,"url":"https://api.github.com/repos/cockpit-project/cockpit","forks_url":"https://api.github.com/repos/cockpit-project/cockpit/forks","keys_url":"https://api.github.com/repos/cockpit-project/cockpit/keys{/key_id}","collaborators_url":"https://api.github.com/repos/cockpit-project/cockpit/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/cockpit-project/cockpit/teams","hooks_url":"https://api.github.com/repos/cockpit-project/cockpit/hooks","issue_events_url":"https://api.github.com/repos/cockpit-project/cockpit/issues/events{/number}","events_url":"https://api.github.com/repos/cockpit-project/cockpit/events","assignees_url":"https://api.github.com/repos/cockpit-project/cockpit/assignees{/user}","branches_url":"https://api.github.com/repos/cockpit-project/cockpit/branches{/branch}","tags_url":"https://api.github.com/repos/cockpit-project/cockpit/tags","blobs_url":"https://api.github.com/repos/cockpit-project/cockpit/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/cockpit-project/cockpit/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/cockpit-project/cockpit/git/refs{/sha}","trees_url":"https://api.github.com/repos/cockpit-project/cockpit/git/trees{/sha}","statuses_url":"https://api.github.com/repos/cockpit-project/cockpit/statuses/{sha}","languages_url":"https://api.github.com/repos/cockpit-project/cockpit/languages","stargazers_url":"https://api.github.com/repos/cockpit-project/cockpit/stargazers","contributors_url":"https://api.github.com/repos/cockpit-project/cockpit/contributors","subscribers_url":"https://api.github.com/repos/cockpit-project/cockpit/subscribers","subscription_url":"https://api.github.com/repos/cockpit-project/cockpit/subscription","commits_url":"https://api.github.com/repos/cockpit-project/cockpit/commits{/sha}","git_commits_url":"https://api.github.com/repos/cockpit-project/cockpit/git/commits{/sha}","comments_url":"https://api.github.com/repos/cockpit-project/cockpit/comments{/number}","issue_comment_url":"https://api.github.com/repos/cockpit-project/cockpit/issues/comments{/number}","contents_url":"https://api.github.com/repos/cockpit-project/cockpit/contents/{+path}","compare_url":"https://api.github.com/repos/cockpit-project/cockpit/compare/{base}...{head}","merges_url":"https://api.github.com/repos/cockpit-project/cockpit/merges","archive_url":"https://api.github.com/repos/cockpit-project/cockpit/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/cockpit-project/cockpit/downloads","issues_url":"https://api.github.com/repos/cockpit-project/cockpit/issues{/number}","pulls_url":"https://api.github.com/repos/cockpit-project/cockpit/pulls{/number}","milestones_url":"https://api.github.com/repos/cockpit-project/cockpit/milestones{/number}","notifications_url":"https://api.github.com/repos/cockpit-project/cockpit/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/cockpit-project/cockpit/labels{/name}","releases_url":"https://api.github.com/repos/cockpit-project/cockpit/releases{/id}","deployments_url":"https://api.github.com/repos/cockpit-project/cockpit/deployments","created_at":"2013-11-01T17:36:46Z","updated_at":"2016-12-01T18:04:38Z","pushed_at":"2016-12-01T19:01:18Z","git_url":"git://github.com/cockpit-project/cockpit.git","ssh_url":"git@github.com:cockpit-project/cockpit.git","clone_url":"https://github.com/cockpit-project/cockpit.git","svn_url":"https://github.com/cockpit-project/cockpit","homepage":"http://www.cockpit-project.org/","size":42052,"stargazers_count":1817,"watchers_count":1817,"language":"C","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":252,"mirror_url":null,"open_issues_count":409,"forks":252,"open_issues":409,"watchers":1817,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/cockpit-project/cockpit/pulls/5523"},"html":{"href":"https://github.com/cockpit-project/cockpit/pull/5523"},"issue":{"href":"https://api.github.com/repos/cockpit-project/cockpit/issues/5523"},"comments":{"href":"https://api.github.com/repos/cockpit-project/cockpit/issues/5523/comments"},"review_comments":{"href":"https://api.github.com/repos/cockpit-project/cockpit/pulls/5523/comments"},"review_comment":{"href":"https://api.github.com/repos/cockpit-project/cockpit/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/cockpit-project/cockpit/pulls/5523/commits"},"statuses":{"href":"https://api.github.com/repos/cockpit-project/cockpit/statuses/8806a6e064458a37e3c7faa43926fa1da969fd9c"}}}}
{"actor":{"display_login":"stefwalter"}}