mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[plugin cli] Retry folder rename on windows eperm (#9279)
Backports PR #9260
**Commit 1:**
[plugin cli] Retry folder rename on windows eperm
* Original sha: 398662fc84
* Authored by Jonathan Budzenski <jon@jbudz.me> on 2016-11-29T20:05:19Z
This commit is contained in:
parent
59b31e5b3d
commit
0fd25ab9ea
3 changed files with 95 additions and 2 deletions
72
src/cli_plugin/install/__tests__/rename.js
Normal file
72
src/cli_plugin/install/__tests__/rename.js
Normal file
|
@ -0,0 +1,72 @@
|
|||
import expect from 'expect.js';
|
||||
import sinon from 'sinon';
|
||||
import fs from 'fs';
|
||||
|
||||
import { renamePlugin } from '../rename';
|
||||
|
||||
describe('plugin folder rename', function () {
|
||||
let renameStub;
|
||||
|
||||
beforeEach(function () {
|
||||
renameStub = sinon.stub();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
fs.rename.restore();
|
||||
});
|
||||
|
||||
it('should rethrow any exceptions', function () {
|
||||
renameStub = sinon.stub(fs, 'rename', function (from, to, cb) {
|
||||
cb({
|
||||
code: 'error'
|
||||
});
|
||||
});
|
||||
|
||||
return renamePlugin('/foo/bar', '/bar/foo')
|
||||
.catch(function (err) {
|
||||
expect(err.code).to.be('error');
|
||||
expect(renameStub.callCount).to.be(1);
|
||||
});
|
||||
});
|
||||
|
||||
it('should resolve if there are no errors', function () {
|
||||
renameStub = sinon.stub(fs, 'rename', function (from, to, cb) {
|
||||
cb();
|
||||
});
|
||||
|
||||
return renamePlugin('/foo/bar', '/bar/foo')
|
||||
.then(function (err) {
|
||||
expect(renameStub.callCount).to.be(1);
|
||||
})
|
||||
.catch(function () {
|
||||
throw new Error('We shouln\'t have any errors');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Windows', function () {
|
||||
let platform;
|
||||
beforeEach(function () {
|
||||
platform = Object.getOwnPropertyDescriptor(process, 'platform');
|
||||
Object.defineProperty(process, 'platform', {
|
||||
value: 'win32'
|
||||
});
|
||||
});
|
||||
afterEach(function () {
|
||||
Object.defineProperty(process, 'platform', platform);
|
||||
});
|
||||
|
||||
it('should retry on Windows EPERM errors for up to 3 seconds', function () {
|
||||
this.timeout(5000);
|
||||
renameStub = sinon.stub(fs, 'rename', function (from, to, cb) {
|
||||
cb({
|
||||
code: 'EPERM'
|
||||
});
|
||||
});
|
||||
return renamePlugin('/foo/bar', '/bar/foo')
|
||||
.catch(function (err) {
|
||||
expect(err.code).to.be('EPERM');
|
||||
expect(renameStub.callCount).to.be.greaterThan(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -2,8 +2,8 @@ import { download } from './download';
|
|||
import Promise from 'bluebird';
|
||||
import { cleanPrevious, cleanArtifacts } from './cleanup';
|
||||
import { extract, getPackData } from './pack';
|
||||
import { renamePlugin } from './rename';
|
||||
import { sync as rimrafSync } from 'rimraf';
|
||||
import { renameSync } from 'fs';
|
||||
import { existingInstall, rebuildCache, assertVersion } from './kibana';
|
||||
import mkdirp from 'mkdirp';
|
||||
|
||||
|
@ -27,7 +27,7 @@ export default async function install(settings, logger) {
|
|||
|
||||
assertVersion(settings);
|
||||
|
||||
renameSync(settings.workingPath, settings.plugins[0].path);
|
||||
await renamePlugin(settings.workingPath, settings.plugins[0].path);
|
||||
|
||||
await rebuildCache(settings, logger);
|
||||
|
||||
|
|
21
src/cli_plugin/install/rename.js
Normal file
21
src/cli_plugin/install/rename.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
import { rename } from 'fs';
|
||||
import { delay } from 'lodash';
|
||||
|
||||
export function renamePlugin(workingPath, finalPath) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
const start = Date.now();
|
||||
const retryTime = 3000;
|
||||
const retryDelay = 100;
|
||||
rename(workingPath, finalPath, function retry(err) {
|
||||
if (err) {
|
||||
// In certain cases on Windows, such as running AV, plugin folders can be locked shortly after extracting
|
||||
// Retry for up to retryTime seconds
|
||||
const windowsEPERM = process.platform === 'win32' && err.code === 'EPERM';
|
||||
const retryAvailable = Date.now() - start < retryTime;
|
||||
if (windowsEPERM && retryAvailable) return delay(rename, retryDelay, workingPath, finalPath, retry);
|
||||
reject(err);
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue