{"action":"created","comment":{"url":"https://api.github.com/repos/elastic/logstash/pulls/comments/38683990","id":38683990,"diff_hunk":"@@ -0,0 +1,47 @@\n+require \"bootstrap/util/compress\"\n+require \"fileutils\"\n+\n+class LogStash::PluginManager::Unpack < LogStash::PluginManager::Command\n+\n+  option \"--tgz\", :flag, \"unpack a packaged tar.gz file\", :default => !LogStash::Environment.windows?\n+  option \"--zip\", :flag, \"unpack a packaged  zip file\", :default => LogStash::Environment.windows?\n+  option \"--force\", :flag, \"Overwrite previously generated plugins package\", :default => false\n+\n+  parameter \"file\", \"the package file name\", :attribute_name => :package_file, :required => true\n+\n+  def execute\n+    puts(\"Unpacking #{package_file}\")\n+\n+    FileUtils.rm_rf(LogStash::Environment::CACHE_PATH) if force?\n+    validate_cache_location\n+    unpack(package_file)\n+\n+    puts(\"Unpacked at #{LogStash::Environment::CACHE_PATH}\")\n+    puts(\"the unpacked plugins can now be installed in local-only mode using bin/plugin install --local [plugin name]\")\n+  end\n+\n+  private\n+\n+  def validate_cache_location\n+    location = LogStash::Environment::CACHE_PATH\n+    if File.exist?(location)\n+      puts(\"Directory #{location} is going to be overwritten, do you want to continue? (Y/N)\")\n+      override = ( \"y\" == STDIN.gets.strip.downcase ? true : false)\n+      if override\n+        FileUtils.rm_rf(location)\n+      else\n+        puts(\"Unpack cancelled: file #{location} already exists, please delete or move it\")\n+        exit\n+      end\n+    end\n+  end","path":"lib/pluginmanager/unpack.rb","position":37,"original_position":37,"commit_id":"a68b209393587695b0104f8ee32375402e7e8903","original_commit_id":"a68b209393587695b0104f8ee32375402e7e8903","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 function should use the constant directly instead of assigning the constant to a local variable.","created_at":"2015-09-03T19:06:01Z","updated_at":"2015-09-03T19:06:01Z","html_url":"https://github.com/elastic/logstash/pull/3404#discussion_r38683990","pull_request_url":"https://api.github.com/repos/elastic/logstash/pulls/3404","_links":{"self":{"href":"https://api.github.com/repos/elastic/logstash/pulls/comments/38683990"},"html":{"href":"https://github.com/elastic/logstash/pull/3404#discussion_r38683990"},"pull_request":{"href":"https://api.github.com/repos/elastic/logstash/pulls/3404"}}},"pull_request":{"url":"https://api.github.com/repos/elastic/logstash/pulls/3404","id":37267505,"html_url":"https://github.com/elastic/logstash/pull/3404","diff_url":"https://github.com/elastic/logstash/pull/3404.diff","patch_url":"https://github.com/elastic/logstash/pull/3404.patch","issue_url":"https://api.github.com/repos/elastic/logstash/issues/3404","number":3404,"state":"open","locked":false,"title":"Manage plugins to be installed offline","user":{"login":"purbon","id":68540,"avatar_url":"https://avatars.githubusercontent.com/u/68540?v=3","gravatar_id":"","url":"https://api.github.com/users/purbon","html_url":"https://github.com/purbon","followers_url":"https://api.github.com/users/purbon/followers","following_url":"https://api.github.com/users/purbon/following{/other_user}","gists_url":"https://api.github.com/users/purbon/gists{/gist_id}","starred_url":"https://api.github.com/users/purbon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/purbon/subscriptions","organizations_url":"https://api.github.com/users/purbon/orgs","repos_url":"https://api.github.com/users/purbon/repos","events_url":"https://api.github.com/users/purbon/events{/privacy}","received_events_url":"https://api.github.com/users/purbon/received_events","type":"User","site_admin":false},"body":"The motivation of this PR is to enable users to dump a set of plugins, to later be managed in machines that have no internet connection.\r\n\r\nDesired features:\r\n- [x] enable the option to create a bundler of dependencies, aka cache that could be used in offline machines.\r\n- [x] enable the option to compress as ```zip``` or ```tar.gz``` the generated dump of plugins.\r\n- [x] enable ```bin/plugin update``` task to update plugins from the local cache under ```vendor/cache```\r\n- [x] enable ```bin/plugin install``` task to install plugins from the local cache (from default place).\r\n- [x] enable ```bin/plugin unpack [path] ``` task to unpack and install a packaged set of plugins.\r\n\r\nImportant checks:\r\n- [x] a plugin is being updated from the cache.\r\n- [x] a plugin is installed from the cache.\r\n- [x] are the plugins with jar dependencies working properly, specially check up on ```logstash-*-kafka```.\r\n\r\nRelates/Fixes to #2376\r\n\r\n# Notes:\r\n\r\nTask added:\r\n\r\n* ```bin/plugin pack``` to build the cache of current installed plugins.\r\n* ```bin/plugin pack --zip``` to compress the dump as a zip file.\r\n* ```bin/plugin pack --tgz``` to compress the dump as tar.gz file.\r\n* ```bin/plugin pack --clean``` to cleanup the raw, not compressed dump.    \r\n* ```bin/plugin unpack [file]``` to unpack a package file. \r\n* ```rake package:build-cache``` build a cache with the current installed plugins.\r\n* ```rake package:plugins-default``` build a cache with default plugins on it, installing them if not there.\r\n* ```rake package:plugins-all``` build a cache with all plugins on it, installing them if not there.\r\n\r\nnew functionality:\r\n\r\n* Add a flag in ```bin/plugin update``` named  ```--local``` that point bundler to use the local cache of gems.\r\n* Add a flag in ```bin/plugin install``` named ```--local``` that point bundler to use the local cache of gems.\r\n\r\nThis is actually an example of usage from the user perspective: \r\n```\r\n╰─$ bin/plugin update --local logstash-input-stdin\r\n\r\nUpdate is not supported for manually defined plugins or local .gem plugin installations, skipping: \r\nUpdating logstash-input-stdin\r\nUpdated logstash-input-stdin 0.1.5 to 0.1.6\r\n```","created_at":"2015-06-09T15:41:31Z","updated_at":"2015-09-03T19:06:01Z","closed_at":null,"merged_at":null,"merge_commit_sha":"653921fa9a844f96452d9967e04c56af611f9209","assignee":{"login":"colinsurprenant","id":2010,"avatar_url":"https://avatars.githubusercontent.com/u/2010?v=3","gravatar_id":"","url":"https://api.github.com/users/colinsurprenant","html_url":"https://github.com/colinsurprenant","followers_url":"https://api.github.com/users/colinsurprenant/followers","following_url":"https://api.github.com/users/colinsurprenant/following{/other_user}","gists_url":"https://api.github.com/users/colinsurprenant/gists{/gist_id}","starred_url":"https://api.github.com/users/colinsurprenant/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/colinsurprenant/subscriptions","organizations_url":"https://api.github.com/users/colinsurprenant/orgs","repos_url":"https://api.github.com/users/colinsurprenant/repos","events_url":"https://api.github.com/users/colinsurprenant/events{/privacy}","received_events_url":"https://api.github.com/users/colinsurprenant/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/elastic/logstash/pulls/3404/commits","review_comments_url":"https://api.github.com/repos/elastic/logstash/pulls/3404/comments","review_comment_url":"https://api.github.com/repos/elastic/logstash/pulls/comments{/number}","comments_url":"https://api.github.com/repos/elastic/logstash/issues/3404/comments","statuses_url":"https://api.github.com/repos/elastic/logstash/statuses/a68b209393587695b0104f8ee32375402e7e8903","head":{"label":"purbon:feature/plugins_offline","ref":"feature/plugins_offline","sha":"a68b209393587695b0104f8ee32375402e7e8903","user":{"login":"purbon","id":68540,"avatar_url":"https://avatars.githubusercontent.com/u/68540?v=3","gravatar_id":"","url":"https://api.github.com/users/purbon","html_url":"https://github.com/purbon","followers_url":"https://api.github.com/users/purbon/followers","following_url":"https://api.github.com/users/purbon/following{/other_user}","gists_url":"https://api.github.com/users/purbon/gists{/gist_id}","starred_url":"https://api.github.com/users/purbon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/purbon/subscriptions","organizations_url":"https://api.github.com/users/purbon/orgs","repos_url":"https://api.github.com/users/purbon/repos","events_url":"https://api.github.com/users/purbon/events{/privacy}","received_events_url":"https://api.github.com/users/purbon/received_events","type":"User","site_admin":false},"repo":{"id":26748658,"name":"logstash","full_name":"purbon/logstash","owner":{"login":"purbon","id":68540,"avatar_url":"https://avatars.githubusercontent.com/u/68540?v=3","gravatar_id":"","url":"https://api.github.com/users/purbon","html_url":"https://github.com/purbon","followers_url":"https://api.github.com/users/purbon/followers","following_url":"https://api.github.com/users/purbon/following{/other_user}","gists_url":"https://api.github.com/users/purbon/gists{/gist_id}","starred_url":"https://api.github.com/users/purbon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/purbon/subscriptions","organizations_url":"https://api.github.com/users/purbon/orgs","repos_url":"https://api.github.com/users/purbon/repos","events_url":"https://api.github.com/users/purbon/events{/privacy}","received_events_url":"https://api.github.com/users/purbon/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/purbon/logstash","description":"logstash - logs/event transport, processing, management, search.","fork":true,"url":"https://api.github.com/repos/purbon/logstash","forks_url":"https://api.github.com/repos/purbon/logstash/forks","keys_url":"https://api.github.com/repos/purbon/logstash/keys{/key_id}","collaborators_url":"https://api.github.com/repos/purbon/logstash/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/purbon/logstash/teams","hooks_url":"https://api.github.com/repos/purbon/logstash/hooks","issue_events_url":"https://api.github.com/repos/purbon/logstash/issues/events{/number}","events_url":"https://api.github.com/repos/purbon/logstash/events","assignees_url":"https://api.github.com/repos/purbon/logstash/assignees{/user}","branches_url":"https://api.github.com/repos/purbon/logstash/branches{/branch}","tags_url":"https://api.github.com/repos/purbon/logstash/tags","blobs_url":"https://api.github.com/repos/purbon/logstash/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/purbon/logstash/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/purbon/logstash/git/refs{/sha}","trees_url":"https://api.github.com/repos/purbon/logstash/git/trees{/sha}","statuses_url":"https://api.github.com/repos/purbon/logstash/statuses/{sha}","languages_url":"https://api.github.com/repos/purbon/logstash/languages","stargazers_url":"https://api.github.com/repos/purbon/logstash/stargazers","contributors_url":"https://api.github.com/repos/purbon/logstash/contributors","subscribers_url":"https://api.github.com/repos/purbon/logstash/subscribers","subscription_url":"https://api.github.com/repos/purbon/logstash/subscription","commits_url":"https://api.github.com/repos/purbon/logstash/commits{/sha}","git_commits_url":"https://api.github.com/repos/purbon/logstash/git/commits{/sha}","comments_url":"https://api.github.com/repos/purbon/logstash/comments{/number}","issue_comment_url":"https://api.github.com/repos/purbon/logstash/issues/comments{/number}","contents_url":"https://api.github.com/repos/purbon/logstash/contents/{+path}","compare_url":"https://api.github.com/repos/purbon/logstash/compare/{base}...{head}","merges_url":"https://api.github.com/repos/purbon/logstash/merges","archive_url":"https://api.github.com/repos/purbon/logstash/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/purbon/logstash/downloads","issues_url":"https://api.github.com/repos/purbon/logstash/issues{/number}","pulls_url":"https://api.github.com/repos/purbon/logstash/pulls{/number}","milestones_url":"https://api.github.com/repos/purbon/logstash/milestones{/number}","notifications_url":"https://api.github.com/repos/purbon/logstash/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/purbon/logstash/labels{/name}","releases_url":"https://api.github.com/repos/purbon/logstash/releases{/id}","created_at":"2014-11-17T09:01:27Z","updated_at":"2015-06-28T17:00:59Z","pushed_at":"2015-09-03T13:51:23Z","git_url":"git://github.com/purbon/logstash.git","ssh_url":"git@github.com:purbon/logstash.git","clone_url":"https://github.com/purbon/logstash.git","svn_url":"https://github.com/purbon/logstash","homepage":"http://logstash.net/","size":73869,"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":"beae32b96286f88e7ef4afce39327e7973684a98","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}","created_at":"2010-11-18T01:31:50Z","updated_at":"2015-09-03T16:16:05Z","pushed_at":"2015-09-03T19:04:04Z","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":94079,"stargazers_count":4658,"watchers_count":4658,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1538,"mirror_url":null,"open_issues_count":570,"forks":1538,"open_issues":570,"watchers":4658,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/elastic/logstash/pulls/3404"},"html":{"href":"https://github.com/elastic/logstash/pull/3404"},"issue":{"href":"https://api.github.com/repos/elastic/logstash/issues/3404"},"comments":{"href":"https://api.github.com/repos/elastic/logstash/issues/3404/comments"},"review_comments":{"href":"https://api.github.com/repos/elastic/logstash/pulls/3404/comments"},"review_comment":{"href":"https://api.github.com/repos/elastic/logstash/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/elastic/logstash/pulls/3404/commits"},"statuses":{"href":"https://api.github.com/repos/elastic/logstash/statuses/a68b209393587695b0104f8ee32375402e7e8903"}}}}