-
Notifications
You must be signed in to change notification settings - Fork 8.6k
Plugin zip support #4975
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Plugin zip support #4975
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
be59dc6
initial pass at zip support
BigFunger de76a10
[cli] [plugin] Reworked to download and extract in two steps to allow…
BigFunger 73cf78b
[cli] [plugin] Added check for unsupported archive type.
BigFunger 4ac8ebd
[cli] [plugin] Adds decompress-zip dependency
BigFunger 6abed25
[cli] [plugin] Adds decompress-zip dependency
BigFunger 7b7feea
Fixed regex
BigFunger 8e460d2
updated the reference to extract-zip to forked version
BigFunger File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| var zlib = require('zlib'); | ||
| var Promise = require('bluebird'); | ||
| var fs = require('fs'); | ||
| var tar = require('tar'); | ||
|
|
||
| module.exports = function (settings, logger) { | ||
| return new Promise(function (resolve, reject) { | ||
| var gunzip = zlib.createGunzip(); | ||
| var tarExtract = new tar.Extract({ path: settings.workingPath, strip: 1 }); | ||
|
|
||
| logger.log('Extracting plugin archive'); | ||
|
|
||
| fs.createReadStream(settings.tempArchiveFile) | ||
| .pipe(gunzip) | ||
| .on('error', handleError) | ||
| .pipe(tarExtract) | ||
| .on('error', handleError) | ||
| .on('end', handleEnd); | ||
|
|
||
| function handleError(err) { | ||
| logger.error(err); | ||
| return reject(new Error('Error extracting plugin archive')); | ||
| } | ||
|
|
||
| function handleEnd() { | ||
| logger.log('Extraction complete'); | ||
| return resolve(); | ||
| } | ||
| }); | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| var Promise = require('bluebird'); | ||
| var DecompressZip = require('@bigfunger/decompress-zip'); | ||
|
|
||
| module.exports = function (settings, logger) { | ||
| return new Promise(function (resolve, reject) { | ||
| logger.log('Extracting plugin archive'); | ||
|
|
||
| var unzipper = new DecompressZip(settings.tempArchiveFile); | ||
|
|
||
| unzipper.on('error', function (err) { | ||
| logger.error(err); | ||
| return reject(new Error('Error extracting plugin archive')); | ||
| }); | ||
|
|
||
| unzipper.on('extract', function (log) { | ||
| logger.log('Extraction complete'); | ||
| return resolve(); | ||
| }); | ||
|
|
||
| unzipper.extract({ | ||
| path: settings.workingPath, | ||
| filter: function (file) { | ||
| return file.type !== 'SymbolicLink'; | ||
| }, | ||
| strip: 1 | ||
| }); | ||
| }); | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,39 +1,35 @@ | ||
| var _ = require('lodash'); | ||
| var zlib = require('zlib'); | ||
| var Promise = require('bluebird'); | ||
| var url = require('url'); | ||
| var fs = require('fs'); | ||
| var request = require('request'); | ||
| var tar = require('tar'); | ||
| var progressReporter = require('./progressReporter'); | ||
| let _ = require('lodash'); | ||
| let Promise = require('bluebird'); | ||
| let urlParse = require('url').parse; | ||
| let fs = require('fs'); | ||
| let request = require('request'); | ||
| let progressReporter = require('./progressReporter'); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think for modules, you want to have those declared with |
||
|
|
||
| module.exports = function (settings, logger) { | ||
| let archiveType; | ||
|
|
||
| //Attempts to download each url in turn until one is successful | ||
| function download() { | ||
| var urls = settings.urls; | ||
| let urls = settings.urls; | ||
|
|
||
| function tryNext() { | ||
| var sourceUrl = urls.shift(); | ||
| let sourceUrl = urls.shift(); | ||
| if (!sourceUrl) { | ||
| throw new Error('Not a valid url.'); | ||
| throw new Error('No valid url specified.'); | ||
| } | ||
|
|
||
| logger.log('Attempting to extract from ' + sourceUrl); | ||
| logger.log(`Attempting to transfer from ${sourceUrl}`); | ||
|
|
||
| return Promise.try(function () { | ||
| return Promise.try(() => { | ||
| return downloadSingle(sourceUrl, settings.workingPath, settings.timeout, logger) | ||
| .catch(function (err) { | ||
| .catch((err) => { | ||
| if (err.message === 'ENOTFOUND') { | ||
| return tryNext(); | ||
| } | ||
| if (err.message === 'EEXTRACT') { | ||
| throw (new Error('Error extracting the plugin archive... is this a valid tar.gz file?')); | ||
| } | ||
| throw (err); | ||
| }); | ||
| }) | ||
| .catch(function (err) { | ||
| .catch((err) => { | ||
| //Special case for when request.get throws an exception | ||
| if (err.message.match(/invalid uri/i)) { | ||
| return tryNext(); | ||
|
|
@@ -45,51 +41,69 @@ module.exports = function (settings, logger) { | |
| return tryNext(); | ||
| } | ||
|
|
||
| //Attempts to download a single url | ||
| function downloadSingle(source, dest, timeout) { | ||
| var gunzip = zlib.createGunzip(); | ||
| var tarExtract = new tar.Extract({ path: dest, strip: 1 }); | ||
|
|
||
| var requestOptions = { url: source }; | ||
| let requestOptions = { url: source }; | ||
| if (timeout !== 0) { | ||
| requestOptions.timeout = timeout; | ||
| } | ||
|
|
||
| return wrappedRequest(requestOptions) | ||
| .then(function (fileStream) { | ||
| var reporter = progressReporter(logger, fileStream); | ||
| return getReadStream(requestOptions) | ||
| .then((readStream) => { | ||
| let writeStream = fs.createWriteStream(settings.tempArchiveFile); | ||
| let reporter = progressReporter(logger, readStream); | ||
|
|
||
| fileStream | ||
| readStream | ||
| .on('response', reporter.handleResponse) | ||
| .on('data', reporter.handleData) | ||
| .on('error', _.partial(reporter.handleError, 'ENOTFOUND')) | ||
| .pipe(gunzip) | ||
| .on('error', _.partial(reporter.handleError, 'EEXTRACT')) | ||
| .pipe(tarExtract) | ||
| .on('error', _.partial(reporter.handleError, 'EEXTRACT')) | ||
| .on('end', reporter.handleEnd); | ||
| .pipe(writeStream) | ||
| .on('finish', reporter.handleEnd); | ||
|
|
||
| return reporter.promise; | ||
| }) | ||
| .then((downloadResult) => { | ||
| archiveType = archiveType || downloadResult.archiveType; | ||
| return archiveType; | ||
| }); | ||
| } | ||
|
|
||
| function wrappedRequest(requestOptions) { | ||
| return Promise.try(function () { | ||
| let urlInfo = url.parse(requestOptions.url); | ||
| if (/^file/.test(urlInfo.protocol)) { | ||
| return fs.createReadStream(urlInfo.path); | ||
| } else { | ||
| return request.get(requestOptions); | ||
| } | ||
| function getReadStream(requestOptions) { | ||
| let urlInfo = urlParse(requestOptions.url); | ||
|
|
||
| if (/^file/.test(urlInfo.protocol)) { | ||
| return getReadStreamFromFile(urlInfo.path); | ||
| } else { | ||
| return getReadStreamFromUrl(requestOptions); | ||
| } | ||
| } | ||
|
|
||
| function getReadStreamFromFile(filePath) { | ||
| return Promise.try(() => { | ||
| archiveType = getArchiveTypeFromFilename(filePath); | ||
| return fs.createReadStream(filePath); | ||
| }); | ||
| } | ||
|
|
||
| function getReadStreamFromUrl(requestOptions) { | ||
| return Promise.try(() => { | ||
| return request.get(requestOptions); | ||
| }) | ||
| .catch(function (err) { | ||
| .catch((err) => { | ||
| if (err.message.match(/invalid uri/i)) { | ||
| throw new Error('ENOTFOUND'); | ||
| } | ||
| throw err; | ||
| }); | ||
| } | ||
|
|
||
| function getArchiveTypeFromFilename(filePath) { | ||
| if (/\.zip$/i.test(filePath)) { | ||
| return '.zip'; | ||
| } | ||
| if (/\.tar\.gz$/i.test(filePath)) { | ||
| return '.tar.gz'; | ||
| } | ||
| } | ||
|
|
||
| return { | ||
| download: download, | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| var zipExtract = require('./extractors/zip'); | ||
| var tarGzExtract = require('./extractors/tarGz'); | ||
|
|
||
| module.exports = function (settings, logger, archiveType) { | ||
| switch (archiveType) { | ||
| case '.zip': | ||
| return zipExtract(settings, logger); | ||
| break; | ||
| case '.tar.gz': | ||
| return tarGzExtract(settings, logger); | ||
| break; | ||
| default: | ||
| throw new Error('Unsupported archive format.'); | ||
| } | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,15 @@ | ||
| let _ = require('lodash'); | ||
| var utils = require('requirefrom')('src/utils'); | ||
| var fromRoot = utils('fromRoot'); | ||
| var pluginDownloader = require('./pluginDownloader'); | ||
| var pluginCleaner = require('./pluginCleaner'); | ||
| var KbnServer = require('../../server/KbnServer'); | ||
| var readYamlConfig = require('../serve/readYamlConfig'); | ||
| var fs = require('fs'); | ||
| let utils = require('requirefrom')('src/utils'); | ||
| let fromRoot = utils('fromRoot'); | ||
| let pluginDownloader = require('./pluginDownloader'); | ||
| let pluginCleaner = require('./pluginCleaner'); | ||
| let pluginExtractor = require('./pluginExtractor'); | ||
| let KbnServer = require('../../server/KbnServer'); | ||
| let readYamlConfig = require('../serve/readYamlConfig'); | ||
| let fs = require('fs'); | ||
| let Promise = require('bluebird'); | ||
| let rimraf = require('rimraf'); | ||
| let mkdirp = Promise.promisify(require('mkdirp')); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All these |
||
|
|
||
| module.exports = { | ||
| install: install | ||
|
|
@@ -23,13 +27,19 @@ function install(settings, logger) { | |
| if (e.code !== 'ENOENT') throw e; | ||
| } | ||
|
|
||
| var cleaner = pluginCleaner(settings, logger); | ||
| var downloader = pluginDownloader(settings, logger); | ||
| let cleaner = pluginCleaner(settings, logger); | ||
| let downloader = pluginDownloader(settings, logger); | ||
|
|
||
| return cleaner.cleanPrevious() | ||
| .then(function () { | ||
| .then(() => { | ||
| return mkdirp(settings.workingPath); | ||
| }) | ||
| .then(() => { | ||
| return downloader.download(); | ||
| }) | ||
| .then((archiveType) => { | ||
| return pluginExtractor (settings, logger, archiveType); | ||
| }) | ||
| .then(async function() { | ||
| logger.log('Optimizing and caching browser bundles...'); | ||
| let serverConfig = _.merge( | ||
|
|
@@ -59,12 +69,15 @@ function install(settings, logger) { | |
| await kbnServer.ready(); | ||
| await kbnServer.close(); | ||
| }) | ||
| .then(function () { | ||
| .then(() => { | ||
| rimraf.sync(settings.tempArchiveFile); | ||
| }) | ||
| .then(() => { | ||
| fs.renameSync(settings.workingPath, settings.pluginPath); | ||
| logger.log('Plugin installation complete'); | ||
| }) | ||
| .catch(function (e) { | ||
| logger.error(`Plugin installation was unsuccessful due to error "${e.message}"`); | ||
| .catch((err) => { | ||
| logger.error(`Plugin installation was unsuccessful due to error "${err.message}"`); | ||
| cleaner.cleanError(); | ||
| process.exit(70); // eslint-disable-line no-process-exit | ||
| }); | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the expected behavior now if downloading/extracting an archive fails?