{"action":"created","comment":{"url":"https://api.github.com/repos/elastic/logstash/pulls/comments/88050307","pull_request_review_id":8635777,"id":88050307,"diff_hunk":"@@ -0,0 +1,23 @@\n+# encoding: utf-8\n+require \"pluginmanager/ui\"\n+require \"pluginmanager/install_strategy/elastic_xpack\"\n+require \"pluginmanager/install_strategy/uri_xpack\"\n+\n+module LogStash module PluginManager\n+  class InstallStrategyFactory\n+    AVAILABLES_STRATEGIES = [\n+      LogStash::PluginManager::InstallStrategy::UriXpack,\n+      LogStash::PluginManager::InstallStrategy::ElasticXpack,\n+    ]\n+\n+    def self.create(plugins_arg)\n+      AVAILABLES_STRATEGIES.each do |strategy|\n+        if klass = strategy.match?(plugins_arg.first)\n+          return klass","path":"lib/pluginmanager/install_strategy_factory.rb","position":16,"original_position":16,"commit_id":"da561484762e97d586c6abb0e9a2951d3ef6110b","original_commit_id":"aaf0250c2e02359ff7c5416b3917571f1644fafe","user":{"login":"ph","id":640,"avatar_url":"https://avatars.githubusercontent.com/u/640?v=3","gravatar_id":"","url":"https://api.github.com/users/ph","html_url":"https://github.com/ph","followers_url":"https://api.github.com/users/ph/followers","following_url":"https://api.github.com/users/ph/following{/other_user}","gists_url":"https://api.github.com/users/ph/gists{/gist_id}","starred_url":"https://api.github.com/users/ph/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ph/subscriptions","organizations_url":"https://api.github.com/users/ph/orgs","repos_url":"https://api.github.com/users/ph/repos","events_url":"https://api.github.com/users/ph/events{/privacy}","received_events_url":"https://api.github.com/users/ph/received_events","type":"User","site_admin":false},"body":"We cannot use `#find` in this context because find will return the first occurrence that matched the predicate, in this case `LogStash::PluginManager::InstallStrategy::UriXpack`, using each and breaking early seems OK to retrieve the installer.","created_at":"2016-11-15T16:09:46Z","updated_at":"2016-11-15T16:09:50Z","html_url":"https://github.com/elastic/logstash/pull/6168#discussion_r88050307","pull_request_url":"https://api.github.com/repos/elastic/logstash/pulls/6168","_links":{"self":{"href":"https://api.github.com/repos/elastic/logstash/pulls/comments/88050307"},"html":{"href":"https://github.com/elastic/logstash/pull/6168#discussion_r88050307"},"pull_request":{"href":"https://api.github.com/repos/elastic/logstash/pulls/6168"}}},"pull_request":{"url":"https://api.github.com/repos/elastic/logstash/pulls/6168","id":91970847,"html_url":"https://github.com/elastic/logstash/pull/6168","diff_url":"https://github.com/elastic/logstash/pull/6168.diff","patch_url":"https://github.com/elastic/logstash/pull/6168.patch","issue_url":"https://api.github.com/repos/elastic/logstash/issues/6168","number":6168,"state":"open","locked":false,"title":"Feature: A way to install/remove a plugin pack","user":{"login":"ph","id":640,"avatar_url":"https://avatars.githubusercontent.com/u/640?v=3","gravatar_id":"","url":"https://api.github.com/users/ph","html_url":"https://github.com/ph","followers_url":"https://api.github.com/users/ph/followers","following_url":"https://api.github.com/users/ph/following{/other_user}","gists_url":"https://api.github.com/users/ph/gists{/gist_id}","starred_url":"https://api.github.com/users/ph/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ph/subscriptions","organizations_url":"https://api.github.com/users/ph/orgs","repos_url":"https://api.github.com/users/ph/repos","events_url":"https://api.github.com/users/ph/events{/privacy}","received_events_url":"https://api.github.com/users/ph/received_events","type":"User","site_admin":false},"body":"This PR add a new installation options for plugins, first, let's get some definition so are all on the same page.\r\n\r\n#### What is a pack?\r\n\r\nA pack in this context is a *bundle* of plugins that can be distributed outside of rubygems; it is similar to what ES and kibana are doing, and\r\nthe user interface is modeled after them. See https://www.elastic.co/downloads/x-pack\r\n\r\n**Do not mix it with the `bin/logstash-plugin pack/unpack` command.**\r\n\r\n##### A pack need to follow a few guidelines:\r\n\r\n- it contains one or more plugins that need to be installed\r\n- it is self-contains with the gems and the needed jars\r\n- it is distributed as a zip file\r\n- the file structure needs to follow some rules.\r\n\r\n##### A pack can be installed from multiple ways\r\n\r\n- As a reserved name name on elastic.co download http server\r\n    - `bin/plugin install logstash-mypack` will check on the download server if a pack for the current specific logstash version exist and it will be downloaded, if it doesn't exist we fallback on rubygems.\r\n    - The file on the server will follow this convention `logstash-mypack-{LOGSTASH_VERSION}.zip`\r\n\r\n- As a fully qualified url\r\n    - `bin/plugin install http://test.abc/logstash-mypack.zip`, if it exists it will be downloaded and installed if it does not we raise an error.\r\n\r\n- As a local file\r\n    - `bin/plugin install file:///tmp/logstash-mypack.zip`, if it exists it will be installed\r\n\r\n##### The structure of the pack\r\n\r\nFor the installer to work the structure of the pack need to followed, the pack itself doesn't have any metadata it just relies on the structure to do the right thing.\r\nThe name of the pack or the archive name is only used to describe the purpose of the pack, i.e., `logstash-monitoring` or `logstash-alerting`, the plugins contains in the pack can have their own name.\r\n\r\nLets assume that we have a pack name `logstash-specialpack` that contains a plugin named `logstash-output-secret`, the structure would look to something like this:\r\n\r\n\r\n```\r\n.\r\n├── dependencies\r\n│   ├── addressable-2.4.0.gem\r\n│   ├── cabin-0.9.0.gem\r\n│   ├── ffi-1.9.14-java.gem\r\n│   ├── gemoji-1.5.0.gem\r\n│   ├── launchy-2.4.3-java.gem\r\n│   ├── logstash-output-elasticsearch-5.2.0-java.gem\r\n│   ├── manticore-0.6.0-java.gem\r\n│   ├── spoon-0.0.6.gem\r\n│   └── stud-0.0.22.gem\r\n└── logstash-output-secret-0.1.0.gem\r\n```\r\n\r\nThe gems in the root of the folder will be the gems that need to be added to the logstash *Gemfile*; the dependencies directory contains the dependencies that the gems requires.\r\nWhen we develop plugins that will be shipped as a pack, we need to pay special attention of how we define the constraints in the gem.\r\n\r\n- External dependencies need to be flexible\r\n- Internal dependencies on other plugins need to be flexible\r\n- Core dependencies can be strict if you want a pack to work on a specific version of the core.\r\n- Java dependencies need to be included in the gem. (Jar-dependencies hooks aren't triggered since they require internet access)\r\n\r\n\r\nThe `pack` are build using a tool I've developed called `paquet`, French word for a package, it takes care of reading the gemspec and whitelisting or blacklisting gems needed for the pack.\r\n\r\nYou can see paquet at https://github.com/ph/paquet, and an example of a pack using it at https://github.com/ph/logstash-output-secret, the most interesting part is the [Rakefile](https://github.com/ph/logstash-output-secret/blob/master/Rakefile) and the [bash script](https://github.com/ph/logstash-output-secret/blob/master/bundle.sh)\r\n\r\n#### How a pack is installed in logstash?\r\n\r\nInstalling a pack diverges from installing a gems or normal plugins, if you look at the plugin manager's install command you see that we take a completely different path.\r\nWe do this for two reasons, its faster and we have better control on the process for the offline scenario. Installing a reserved pack, an URL pack or a local pack will go through the same **local** install path.\r\n\r\nLets look at the flow for installing an official pack.\r\n\r\n- Does the pack exist on elastic's server? (HEAD request on a specific URL)\r\n- The pack is downloaded into a temporary folder\r\n- The pack gets extracted\r\n- A special folder gets created as a Rubygems' Indexed format\r\n- This folder is added to the available sources\r\n- The definition (lock file graph) is loaded in memory\r\n- The plugin(s) get added directly to the gemfile\r\n- Their dependencies get resolved and added to the graph\r\n- The graph is valid if it can accept theses gems with the local graph (no remote calls are needed)\r\n- If added gems respect the currently installed gems\r\n- The Gemfile and the lockfile get saved to disk\r\n- The gems get extracted to *GEM_HOME* in the bundle directory\r\n- The gems specification get saved in bundle specification folder\r\n- Temporary files get deleted\r\n- The gems now show up in logstash `bin/logstash-plugin list --verbose.'\r\n\r\n\r\n#### Offline uninstall\r\n\r\nSince a pack can now be installed successfully offline the remove command also need to be changed to support an offline workflow.\r\n\r\n- Remove use the same local graph stategy.\r\n- We now display information when trying to remove a gem that other gem depends on it.\r\n- We have rats test for theses cases. \r\n\r\n\r\n### Notes:\r\n\r\n#### TODO:\r\n\r\n- Add tests for conflict; I've been having a hard time to add unit test on conflicting gem.\r\n- We use a side effect of `Gem::Indexer` to make the gem available, I've tried really hard to manually supply the source to the graph without luck for now.\r\n\r\n####\r\n- ~~Add a post install message~~ Added in the current PR, the feature was short.\r\n- ~~Allow uninstall/remove to be run offline~~","created_at":"2016-11-02T13:38:18Z","updated_at":"2016-11-15T16:09:50Z","closed_at":null,"merged_at":null,"merge_commit_sha":"a9bcf745add48010e315bf872326753149ca7100","assignee":{"login":"jsvd","id":31809,"avatar_url":"https://avatars.githubusercontent.com/u/31809?v=3","gravatar_id":"","url":"https://api.github.com/users/jsvd","html_url":"https://github.com/jsvd","followers_url":"https://api.github.com/users/jsvd/followers","following_url":"https://api.github.com/users/jsvd/following{/other_user}","gists_url":"https://api.github.com/users/jsvd/gists{/gist_id}","starred_url":"https://api.github.com/users/jsvd/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jsvd/subscriptions","organizations_url":"https://api.github.com/users/jsvd/orgs","repos_url":"https://api.github.com/users/jsvd/repos","events_url":"https://api.github.com/users/jsvd/events{/privacy}","received_events_url":"https://api.github.com/users/jsvd/received_events","type":"User","site_admin":false},"assignees":[{"login":"jsvd","id":31809,"avatar_url":"https://avatars.githubusercontent.com/u/31809?v=3","gravatar_id":"","url":"https://api.github.com/users/jsvd","html_url":"https://github.com/jsvd","followers_url":"https://api.github.com/users/jsvd/followers","following_url":"https://api.github.com/users/jsvd/following{/other_user}","gists_url":"https://api.github.com/users/jsvd/gists{/gist_id}","starred_url":"https://api.github.com/users/jsvd/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jsvd/subscriptions","organizations_url":"https://api.github.com/users/jsvd/orgs","repos_url":"https://api.github.com/users/jsvd/repos","events_url":"https://api.github.com/users/jsvd/events{/privacy}","received_events_url":"https://api.github.com/users/jsvd/received_events","type":"User","site_admin":false},{"login":"jordansissel","id":131818,"avatar_url":"https://avatars.githubusercontent.com/u/131818?v=3","gravatar_id":"","url":"https://api.github.com/users/jordansissel","html_url":"https://github.com/jordansissel","followers_url":"https://api.github.com/users/jordansissel/followers","following_url":"https://api.github.com/users/jordansissel/following{/other_user}","gists_url":"https://api.github.com/users/jordansissel/gists{/gist_id}","starred_url":"https://api.github.com/users/jordansissel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jordansissel/subscriptions","organizations_url":"https://api.github.com/users/jordansissel/orgs","repos_url":"https://api.github.com/users/jordansissel/repos","events_url":"https://api.github.com/users/jordansissel/events{/privacy}","received_events_url":"https://api.github.com/users/jordansissel/received_events","type":"User","site_admin":false},{"login":"suyograo","id":1595958,"avatar_url":"https://avatars.githubusercontent.com/u/1595958?v=3","gravatar_id":"","url":"https://api.github.com/users/suyograo","html_url":"https://github.com/suyograo","followers_url":"https://api.github.com/users/suyograo/followers","following_url":"https://api.github.com/users/suyograo/following{/other_user}","gists_url":"https://api.github.com/users/suyograo/gists{/gist_id}","starred_url":"https://api.github.com/users/suyograo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/suyograo/subscriptions","organizations_url":"https://api.github.com/users/suyograo/orgs","repos_url":"https://api.github.com/users/suyograo/repos","events_url":"https://api.github.com/users/suyograo/events{/privacy}","received_events_url":"https://api.github.com/users/suyograo/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/elastic/logstash/pulls/6168/commits","review_comments_url":"https://api.github.com/repos/elastic/logstash/pulls/6168/comments","review_comment_url":"https://api.github.com/repos/elastic/logstash/pulls/comments{/number}","comments_url":"https://api.github.com/repos/elastic/logstash/issues/6168/comments","statuses_url":"https://api.github.com/repos/elastic/logstash/statuses/da561484762e97d586c6abb0e9a2951d3ef6110b","head":{"label":"ph:feature/pack-install","ref":"feature/pack-install","sha":"da561484762e97d586c6abb0e9a2951d3ef6110b","user":{"login":"ph","id":640,"avatar_url":"https://avatars.githubusercontent.com/u/640?v=3","gravatar_id":"","url":"https://api.github.com/users/ph","html_url":"https://github.com/ph","followers_url":"https://api.github.com/users/ph/followers","following_url":"https://api.github.com/users/ph/following{/other_user}","gists_url":"https://api.github.com/users/ph/gists{/gist_id}","starred_url":"https://api.github.com/users/ph/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ph/subscriptions","organizations_url":"https://api.github.com/users/ph/orgs","repos_url":"https://api.github.com/users/ph/repos","events_url":"https://api.github.com/users/ph/events{/privacy}","received_events_url":"https://api.github.com/users/ph/received_events","type":"User","site_admin":false},"repo":{"id":24861697,"name":"logstash","full_name":"ph/logstash","owner":{"login":"ph","id":640,"avatar_url":"https://avatars.githubusercontent.com/u/640?v=3","gravatar_id":"","url":"https://api.github.com/users/ph","html_url":"https://github.com/ph","followers_url":"https://api.github.com/users/ph/followers","following_url":"https://api.github.com/users/ph/following{/other_user}","gists_url":"https://api.github.com/users/ph/gists{/gist_id}","starred_url":"https://api.github.com/users/ph/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ph/subscriptions","organizations_url":"https://api.github.com/users/ph/orgs","repos_url":"https://api.github.com/users/ph/repos","events_url":"https://api.github.com/users/ph/events{/privacy}","received_events_url":"https://api.github.com/users/ph/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/ph/logstash","description":"logstash - logs/event transport, processing, management, search.","fork":true,"url":"https://api.github.com/repos/ph/logstash","forks_url":"https://api.github.com/repos/ph/logstash/forks","keys_url":"https://api.github.com/repos/ph/logstash/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ph/logstash/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ph/logstash/teams","hooks_url":"https://api.github.com/repos/ph/logstash/hooks","issue_events_url":"https://api.github.com/repos/ph/logstash/issues/events{/number}","events_url":"https://api.github.com/repos/ph/logstash/events","assignees_url":"https://api.github.com/repos/ph/logstash/assignees{/user}","branches_url":"https://api.github.com/repos/ph/logstash/branches{/branch}","tags_url":"https://api.github.com/repos/ph/logstash/tags","blobs_url":"https://api.github.com/repos/ph/logstash/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ph/logstash/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ph/logstash/git/refs{/sha}","trees_url":"https://api.github.com/repos/ph/logstash/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ph/logstash/statuses/{sha}","languages_url":"https://api.github.com/repos/ph/logstash/languages","stargazers_url":"https://api.github.com/repos/ph/logstash/stargazers","contributors_url":"https://api.github.com/repos/ph/logstash/contributors","subscribers_url":"https://api.github.com/repos/ph/logstash/subscribers","subscription_url":"https://api.github.com/repos/ph/logstash/subscription","commits_url":"https://api.github.com/repos/ph/logstash/commits{/sha}","git_commits_url":"https://api.github.com/repos/ph/logstash/git/commits{/sha}","comments_url":"https://api.github.com/repos/ph/logstash/comments{/number}","issue_comment_url":"https://api.github.com/repos/ph/logstash/issues/comments{/number}","contents_url":"https://api.github.com/repos/ph/logstash/contents/{+path}","compare_url":"https://api.github.com/repos/ph/logstash/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ph/logstash/merges","archive_url":"https://api.github.com/repos/ph/logstash/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ph/logstash/downloads","issues_url":"https://api.github.com/repos/ph/logstash/issues{/number}","pulls_url":"https://api.github.com/repos/ph/logstash/pulls{/number}","milestones_url":"https://api.github.com/repos/ph/logstash/milestones{/number}","notifications_url":"https://api.github.com/repos/ph/logstash/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ph/logstash/labels{/name}","releases_url":"https://api.github.com/repos/ph/logstash/releases{/id}","deployments_url":"https://api.github.com/repos/ph/logstash/deployments","created_at":"2014-10-06T19:37:59Z","updated_at":"2015-06-05T14:18:00Z","pushed_at":"2016-11-14T21:51:06Z","git_url":"git://github.com/ph/logstash.git","ssh_url":"git@github.com:ph/logstash.git","clone_url":"https://github.com/ph/logstash.git","svn_url":"https://github.com/ph/logstash","homepage":"http://logstash.net/","size":77794,"stargazers_count":0,"watchers_count":0,"language":"Ruby","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"elastic:master","ref":"master","sha":"c8bf755f7b7ee84576fef3fad3c2355ab72bb901","user":{"login":"elastic","id":6764390,"avatar_url":"https://avatars.githubusercontent.com/u/6764390?v=3","gravatar_id":"","url":"https://api.github.com/users/elastic","html_url":"https://github.com/elastic","followers_url":"https://api.github.com/users/elastic/followers","following_url":"https://api.github.com/users/elastic/following{/other_user}","gists_url":"https://api.github.com/users/elastic/gists{/gist_id}","starred_url":"https://api.github.com/users/elastic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/elastic/subscriptions","organizations_url":"https://api.github.com/users/elastic/orgs","repos_url":"https://api.github.com/users/elastic/repos","events_url":"https://api.github.com/users/elastic/events{/privacy}","received_events_url":"https://api.github.com/users/elastic/received_events","type":"Organization","site_admin":false},"repo":{"id":1090311,"name":"logstash","full_name":"elastic/logstash","owner":{"login":"elastic","id":6764390,"avatar_url":"https://avatars.githubusercontent.com/u/6764390?v=3","gravatar_id":"","url":"https://api.github.com/users/elastic","html_url":"https://github.com/elastic","followers_url":"https://api.github.com/users/elastic/followers","following_url":"https://api.github.com/users/elastic/following{/other_user}","gists_url":"https://api.github.com/users/elastic/gists{/gist_id}","starred_url":"https://api.github.com/users/elastic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/elastic/subscriptions","organizations_url":"https://api.github.com/users/elastic/orgs","repos_url":"https://api.github.com/users/elastic/repos","events_url":"https://api.github.com/users/elastic/events{/privacy}","received_events_url":"https://api.github.com/users/elastic/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/elastic/logstash","description":"Logstash - transport and process your logs, events, or other data","fork":false,"url":"https://api.github.com/repos/elastic/logstash","forks_url":"https://api.github.com/repos/elastic/logstash/forks","keys_url":"https://api.github.com/repos/elastic/logstash/keys{/key_id}","collaborators_url":"https://api.github.com/repos/elastic/logstash/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/elastic/logstash/teams","hooks_url":"https://api.github.com/repos/elastic/logstash/hooks","issue_events_url":"https://api.github.com/repos/elastic/logstash/issues/events{/number}","events_url":"https://api.github.com/repos/elastic/logstash/events","assignees_url":"https://api.github.com/repos/elastic/logstash/assignees{/user}","branches_url":"https://api.github.com/repos/elastic/logstash/branches{/branch}","tags_url":"https://api.github.com/repos/elastic/logstash/tags","blobs_url":"https://api.github.com/repos/elastic/logstash/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/elastic/logstash/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/elastic/logstash/git/refs{/sha}","trees_url":"https://api.github.com/repos/elastic/logstash/git/trees{/sha}","statuses_url":"https://api.github.com/repos/elastic/logstash/statuses/{sha}","languages_url":"https://api.github.com/repos/elastic/logstash/languages","stargazers_url":"https://api.github.com/repos/elastic/logstash/stargazers","contributors_url":"https://api.github.com/repos/elastic/logstash/contributors","subscribers_url":"https://api.github.com/repos/elastic/logstash/subscribers","subscription_url":"https://api.github.com/repos/elastic/logstash/subscription","commits_url":"https://api.github.com/repos/elastic/logstash/commits{/sha}","git_commits_url":"https://api.github.com/repos/elastic/logstash/git/commits{/sha}","comments_url":"https://api.github.com/repos/elastic/logstash/comments{/number}","issue_comment_url":"https://api.github.com/repos/elastic/logstash/issues/comments{/number}","contents_url":"https://api.github.com/repos/elastic/logstash/contents/{+path}","compare_url":"https://api.github.com/repos/elastic/logstash/compare/{base}...{head}","merges_url":"https://api.github.com/repos/elastic/logstash/merges","archive_url":"https://api.github.com/repos/elastic/logstash/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/elastic/logstash/downloads","issues_url":"https://api.github.com/repos/elastic/logstash/issues{/number}","pulls_url":"https://api.github.com/repos/elastic/logstash/pulls{/number}","milestones_url":"https://api.github.com/repos/elastic/logstash/milestones{/number}","notifications_url":"https://api.github.com/repos/elastic/logstash/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/elastic/logstash/labels{/name}","releases_url":"https://api.github.com/repos/elastic/logstash/releases{/id}","deployments_url":"https://api.github.com/repos/elastic/logstash/deployments","created_at":"2010-11-18T01:31:50Z","updated_at":"2016-11-15T15:31:02Z","pushed_at":"2016-11-15T02:30:37Z","git_url":"git://github.com/elastic/logstash.git","ssh_url":"git@github.com:elastic/logstash.git","clone_url":"https://github.com/elastic/logstash.git","svn_url":"https://github.com/elastic/logstash","homepage":"https://www.elastic.co/products/logstash","size":91440,"stargazers_count":6681,"watchers_count":6681,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1958,"mirror_url":null,"open_issues_count":847,"forks":1958,"open_issues":847,"watchers":6681,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/elastic/logstash/pulls/6168"},"html":{"href":"https://github.com/elastic/logstash/pull/6168"},"issue":{"href":"https://api.github.com/repos/elastic/logstash/issues/6168"},"comments":{"href":"https://api.github.com/repos/elastic/logstash/issues/6168/comments"},"review_comments":{"href":"https://api.github.com/repos/elastic/logstash/pulls/6168/comments"},"review_comment":{"href":"https://api.github.com/repos/elastic/logstash/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/elastic/logstash/pulls/6168/commits"},"statuses":{"href":"https://api.github.com/repos/elastic/logstash/statuses/da561484762e97d586c6abb0e9a2951d3ef6110b"}}}}
{"actor":{"display_login":"ph"}}