@automattic/vip 2.5.0 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -0
- package/dist/bin/vip-dev-env-create.js +11 -24
- package/dist/bin/vip-dev-env-import-sql.js +13 -2
- package/dist/bin/vip-dev-env-update.js +16 -8
- package/dist/bin/vip-dev-env.js +1 -1
- package/dist/bin/vip-import-sql.js +2 -1
- package/dist/bin/vip-logs.js +151 -0
- package/dist/bin/vip.js +1 -1
- package/dist/lib/app-logs/app-logs.js +62 -0
- package/dist/lib/constants/dev-environment.js +3 -1
- package/dist/lib/dev-environment/dev-environment-cli.js +107 -47
- package/dist/lib/dev-environment/dev-environment-core.js +47 -8
- package/dist/lib/dev-environment/types.js +1 -0
- package/dist/lib/site-import/db-file-import.js +1 -1
- package/dist/lib/site-import/status.js +17 -10
- package/package.json +7 -5
package/README.md
CHANGED
|
@@ -27,6 +27,23 @@ By default, we record information about the usage of this tool using an in-house
|
|
|
27
27
|
|
|
28
28
|
## Changelog
|
|
29
29
|
|
|
30
|
+
### 2.7.0 (07 December 2021)
|
|
31
|
+
- #941 [dev-env] Bump lando CLI dependency
|
|
32
|
+
- #938 Hide roll back message after SQL Import failure for launched sites
|
|
33
|
+
- #936 Sets jest maxWorkers to 4
|
|
34
|
+
|
|
35
|
+
https://github.com/Automattic/vip/releases/tag/v2.7.0
|
|
36
|
+
|
|
37
|
+
### 2.6.0 (23 November 2021)
|
|
38
|
+
- #921 [dev-env] Introuces update to change existing environment
|
|
39
|
+
- #928 [dev-env] Switch lando to use our fork
|
|
40
|
+
- #927 [dev-env] Handles user already exists during sql import
|
|
41
|
+
- #925 [dev-env] Fix the issue with dev-env update
|
|
42
|
+
- #924 FORNO-985 Increase SQL Import limit for unlaunched sites to 100GB
|
|
43
|
+
- #923 FORNO-943 Fixes a bug which prevents displaying SQL Import error messages
|
|
44
|
+
- #922 Update eslint-config-wpvip commit hash to c6605d1
|
|
45
|
+
- #873 Pin dependencies
|
|
46
|
+
|
|
30
47
|
### 2.5.0 (9 November 2021)
|
|
31
48
|
- #919 [dev-env] Expose lando core logs
|
|
32
49
|
- #916 [dev-env] Save instance data state
|
|
@@ -50,23 +50,14 @@ const examples = [{
|
|
|
50
50
|
usage: `${_devEnvironment.DEV_ENVIRONMENT_FULL_COMMAND} create --multisite --wordpress "5.8" --client-code "~/git/my_code"`,
|
|
51
51
|
description: 'Creates a local multisite dev environment using WP 5.8 and client code is expected to be in "~/git/my_code"'
|
|
52
52
|
}];
|
|
53
|
-
(0, _command.default)().option('slug', 'Custom name of the dev environment').option('title', 'Title for the WordPress site').option('multisite', 'Enable multisite install', undefined, value => {
|
|
53
|
+
const cmd = (0, _command.default)().option('slug', 'Custom name of the dev environment').option('title', 'Title for the WordPress site').option('multisite', 'Enable multisite install', undefined, value => {
|
|
54
54
|
var _value$toLowerCase;
|
|
55
55
|
|
|
56
56
|
return 'false' !== (value === null || value === void 0 ? void 0 : (_value$toLowerCase = value.toLowerCase) === null || _value$toLowerCase === void 0 ? void 0 : _value$toLowerCase.call(value));
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}).option('phpmyadmin', 'Enable PHPMyAdmin component. By default it is disabled', undefined, value => {
|
|
62
|
-
var _value$toLowerCase3;
|
|
63
|
-
|
|
64
|
-
return 'false' !== (value === null || value === void 0 ? void 0 : (_value$toLowerCase3 = value.toLowerCase) === null || _value$toLowerCase3 === void 0 ? void 0 : _value$toLowerCase3.call(value));
|
|
65
|
-
}).option('xdebug', 'Enable XDebug. By default it is disabled', undefined, value => {
|
|
66
|
-
var _value$toLowerCase4;
|
|
67
|
-
|
|
68
|
-
return 'false' !== (value === null || value === void 0 ? void 0 : (_value$toLowerCase4 = value.toLowerCase) === null || _value$toLowerCase4 === void 0 ? void 0 : _value$toLowerCase4.call(value));
|
|
69
|
-
}).option('elasticsearch', 'Explicitly choose Elasticsearch version to use').option('mariadb', 'Explicitly choose MariaDB version to use').option('media-redirect-domain', 'Domain to redirect for missing media files. This can be used to still have images without the need to import them locally.').examples(examples).argv(process.argv, async (arg, opt) => {
|
|
57
|
+
});
|
|
58
|
+
(0, _devEnvironmentCli.addDevEnvConfigurationOptions)(cmd);
|
|
59
|
+
cmd.examples(examples);
|
|
60
|
+
cmd.argv(process.argv, async (arg, opt) => {
|
|
70
61
|
const slug = (0, _devEnvironmentCli.getEnvironmentName)(opt);
|
|
71
62
|
debug('Args: ', arg, 'Options: ', opt);
|
|
72
63
|
|
|
@@ -79,11 +70,12 @@ const examples = [{
|
|
|
79
70
|
exit.withError(messageToShow);
|
|
80
71
|
}
|
|
81
72
|
|
|
82
|
-
let
|
|
73
|
+
let defaultOptions = {};
|
|
83
74
|
|
|
84
75
|
try {
|
|
85
76
|
if (opt.app) {
|
|
86
|
-
appInfo = await (0, _devEnvironmentCore.getApplicationInformation)(opt.app, opt.env);
|
|
77
|
+
const appInfo = await (0, _devEnvironmentCore.getApplicationInformation)(opt.app, opt.env);
|
|
78
|
+
defaultOptions = (0, _devEnvironmentCli.getOptionsFromAppInfo)(appInfo);
|
|
87
79
|
}
|
|
88
80
|
} catch (error) {
|
|
89
81
|
const message = `failed to fetch application "${opt.app}" information`;
|
|
@@ -91,16 +83,11 @@ const examples = [{
|
|
|
91
83
|
console.log(_chalk.default.yellow('Warning:'), message);
|
|
92
84
|
}
|
|
93
85
|
|
|
94
|
-
const instanceData = await (0, _devEnvironmentCli.promptForArguments)(opt,
|
|
95
|
-
|
|
96
|
-
siteSlug: slug,
|
|
97
|
-
statsd: opt.statsd || false,
|
|
98
|
-
phpmyadmin: opt.phpmyadmin || false,
|
|
99
|
-
xdebug: opt.xdebug || false
|
|
100
|
-
};
|
|
86
|
+
const instanceData = await (0, _devEnvironmentCli.promptForArguments)(opt, defaultOptions);
|
|
87
|
+
instanceData.siteSlug = slug;
|
|
101
88
|
|
|
102
89
|
try {
|
|
103
|
-
await (0, _devEnvironmentCore.createEnvironment)(
|
|
90
|
+
await (0, _devEnvironmentCore.createEnvironment)(instanceData);
|
|
104
91
|
await (0, _devEnvironmentCore.printEnvironmentInfo)(slug);
|
|
105
92
|
const message = '\n' + _chalk.default.green('✓') + ` environment created.\n\nTo start it please run:\n\n${startCommand}\n`;
|
|
106
93
|
console.log(message);
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
|
|
13
13
|
var _fs = _interopRequireDefault(require("fs"));
|
|
14
14
|
|
|
15
|
+
var _chalk = _interopRequireDefault(require("chalk"));
|
|
16
|
+
|
|
15
17
|
var _command = _interopRequireDefault(require("../lib/cli/command"));
|
|
16
18
|
|
|
17
19
|
var _devEnvironmentCli = require("../lib/dev-environment/dev-environment-cli");
|
|
@@ -62,8 +64,17 @@ const examples = [{
|
|
|
62
64
|
|
|
63
65
|
const cacheArg = ['wp', 'cache', 'flush'];
|
|
64
66
|
await (0, _devEnvironmentCore.exec)(slug, cacheArg);
|
|
65
|
-
|
|
66
|
-
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
const addUserArg = ['wp', 'user', 'create', 'vipgo', 'vipgo@go-vip.net', '--user_pass=password', '--role=administrator'];
|
|
70
|
+
await (0, _devEnvironmentCore.exec)(slug, addUserArg);
|
|
71
|
+
} catch (exception) {
|
|
72
|
+
if ((exception.message || '').includes('is already registered')) {
|
|
73
|
+
console.log(_chalk.default.bold(_chalk.default.green('Success: ')) + 'Skipping user vipgo provisioning');
|
|
74
|
+
} else {
|
|
75
|
+
throw exception;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
67
78
|
} catch (error) {
|
|
68
79
|
(0, _devEnvironmentCli.handleCLIException)(error);
|
|
69
80
|
}
|
|
@@ -53,14 +53,22 @@ cmd.argv(process.argv, async (arg, opt) => {
|
|
|
53
53
|
multisite: currentInstanceData.multisite,
|
|
54
54
|
...opt
|
|
55
55
|
};
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
56
|
+
const defaultOptions = {
|
|
57
|
+
clientCode: currentInstanceData.clientCode.dir || currentInstanceData.clientCode.tag || 'latest',
|
|
58
|
+
muPlugins: currentInstanceData.muPlugins.dir || currentInstanceData.muPlugins.tag || 'latest',
|
|
59
|
+
wordpress: currentInstanceData.wordpress.tag,
|
|
60
|
+
elasticsearch: currentInstanceData.elasticsearch,
|
|
61
|
+
mariadb: currentInstanceData.mariadb,
|
|
62
|
+
statsd: currentInstanceData.statsd,
|
|
63
|
+
phpmyadmin: currentInstanceData.phpmyadmin,
|
|
64
|
+
xdebug: currentInstanceData.xdebug,
|
|
65
|
+
mediaRedirectDomain: currentInstanceData.mediaRedirectDomain
|
|
66
|
+
};
|
|
67
|
+
const instanceData = await (0, _devEnvironmentCli.promptForArguments)(preselectedOptions, defaultOptions);
|
|
68
|
+
instanceData.siteSlug = slug;
|
|
69
|
+
await (0, _devEnvironmentCore.updateEnvironment)(instanceData);
|
|
70
|
+
const message = '\n' + _chalk.default.green('✓') + ' environment updated. Restart environment for changes to take an affect.';
|
|
71
|
+
console.log(message);
|
|
64
72
|
} catch (error) {
|
|
65
73
|
if ('ENOENT' === error.code) {
|
|
66
74
|
const message = 'Environment was created before update was supported.\n\nTo update environment please destroy it and create a new one.';
|
package/dist/bin/vip-dev-env.js
CHANGED
|
@@ -20,4 +20,4 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
20
20
|
|
|
21
21
|
(0, _command.default)({
|
|
22
22
|
requiredArgs: 1
|
|
23
|
-
}).command('create', 'Create a new local dev environment').command('start', 'Start a local dev environment').command('stop', 'Stop a local dev environment').command('destroy', 'Remove containers, networks, volumes and configuration files of a local dev environment').command('info', 'Provides basic info about one or multiple local dev environments').command('exec', 'Execute an operation on a dev environment').command('import', 'Import data into a local WordPress environment').argv(process.argv);
|
|
23
|
+
}).command('create', 'Create a new local dev environment').command('update', 'Update an already created local dev environment').command('start', 'Start a local dev environment').command('stop', 'Stop a local dev environment').command('destroy', 'Remove containers, networks, volumes and configuration files of a local dev environment').command('info', 'Provides basic info about one or multiple local dev environments').command('exec', 'Execute an operation on a dev environment').command('import', 'Import data into a local WordPress environment').argv(process.argv);
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Internal dependencies
|
|
5
|
+
*/
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
Object.defineProperty(exports, "__esModule", {
|
|
9
|
+
value: true
|
|
10
|
+
});
|
|
11
|
+
exports.getLogs = getLogs;
|
|
12
|
+
exports.validateInputs = validateInputs;
|
|
13
|
+
exports.appQuery = void 0;
|
|
14
|
+
|
|
15
|
+
var _command = _interopRequireDefault(require("../lib/cli/command"));
|
|
16
|
+
|
|
17
|
+
var _rollbar = require("../lib/rollbar");
|
|
18
|
+
|
|
19
|
+
var _tracker = require("../lib/tracker");
|
|
20
|
+
|
|
21
|
+
var logsLib = _interopRequireWildcard(require("../lib/app-logs/app-logs"));
|
|
22
|
+
|
|
23
|
+
var exit = _interopRequireWildcard(require("../lib/cli/exit"));
|
|
24
|
+
|
|
25
|
+
var _format = require("../lib/cli/format");
|
|
26
|
+
|
|
27
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
28
|
+
|
|
29
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
30
|
+
|
|
31
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
32
|
+
|
|
33
|
+
const LIMIT_MAX = 5000;
|
|
34
|
+
const LIMIT_MIN = 1;
|
|
35
|
+
const ALLOWED_TYPES = ['app', 'batch'];
|
|
36
|
+
const ALLOWED_FORMATS = ['csv', 'json', 'text'];
|
|
37
|
+
|
|
38
|
+
async function getLogs(arg, opt) {
|
|
39
|
+
validateInputs(opt.type, opt.limit, opt.format);
|
|
40
|
+
const trackingParams = {
|
|
41
|
+
command: 'vip logs',
|
|
42
|
+
org_id: opt.app.organization.id,
|
|
43
|
+
app_id: opt.app.id,
|
|
44
|
+
env_id: opt.env.id,
|
|
45
|
+
type: opt.type,
|
|
46
|
+
limit: opt.limit,
|
|
47
|
+
format: opt.format
|
|
48
|
+
};
|
|
49
|
+
await (0, _tracker.trackEvent)('logs_command_execute', trackingParams);
|
|
50
|
+
let logs = [];
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
logs = await logsLib.getRecentLogs(opt.app.id, opt.env.id, opt.type, opt.limit);
|
|
54
|
+
} catch (error) {
|
|
55
|
+
_rollbar.rollbar.error(error);
|
|
56
|
+
|
|
57
|
+
await (0, _tracker.trackEvent)('logs_command_error', { ...trackingParams,
|
|
58
|
+
error: error.message
|
|
59
|
+
});
|
|
60
|
+
return exit.withError(error.message);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
await (0, _tracker.trackEvent)('logs_command_success', { ...trackingParams,
|
|
64
|
+
logs_output: logs.length
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
if (!logs.length) {
|
|
68
|
+
console.error('No logs found');
|
|
69
|
+
return;
|
|
70
|
+
} // Strip out __typename
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
logs = logs.map(log => {
|
|
74
|
+
const {
|
|
75
|
+
timestamp,
|
|
76
|
+
message
|
|
77
|
+
} = log;
|
|
78
|
+
return {
|
|
79
|
+
timestamp,
|
|
80
|
+
message
|
|
81
|
+
};
|
|
82
|
+
});
|
|
83
|
+
let output = '';
|
|
84
|
+
|
|
85
|
+
if (opt.format && 'text' === opt.format) {
|
|
86
|
+
const rows = [];
|
|
87
|
+
|
|
88
|
+
for (const {
|
|
89
|
+
timestamp,
|
|
90
|
+
message
|
|
91
|
+
} of logs) {
|
|
92
|
+
rows.push(`${timestamp} ${message}`);
|
|
93
|
+
output = rows.join('\n');
|
|
94
|
+
}
|
|
95
|
+
} else {
|
|
96
|
+
output = (0, _format.formatData)(logs, opt.format);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
console.log(output);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function validateInputs(type, limit, format) {
|
|
103
|
+
if (!ALLOWED_TYPES.includes(type)) {
|
|
104
|
+
exit.withError(`Invalid type: ${type}. The supported types are: ${ALLOWED_TYPES.join(', ')}.`);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (!ALLOWED_FORMATS.includes(format)) {
|
|
108
|
+
exit.withError(`Invalid format: ${format}. The supported formats are: ${ALLOWED_FORMATS.join(', ')}.`);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (!Number.isInteger(limit) || limit < LIMIT_MIN || limit > LIMIT_MAX) {
|
|
112
|
+
exit.withError(`Invalid limit: ${limit}. It should be a number between ${LIMIT_MIN} and ${LIMIT_MAX}.`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const appQuery = `
|
|
117
|
+
id
|
|
118
|
+
name
|
|
119
|
+
environments {
|
|
120
|
+
id
|
|
121
|
+
appId
|
|
122
|
+
name
|
|
123
|
+
type
|
|
124
|
+
}
|
|
125
|
+
organization {
|
|
126
|
+
id
|
|
127
|
+
name
|
|
128
|
+
}
|
|
129
|
+
`;
|
|
130
|
+
exports.appQuery = appQuery;
|
|
131
|
+
(0, _command.default)({
|
|
132
|
+
appContext: true,
|
|
133
|
+
appQuery,
|
|
134
|
+
envContext: true,
|
|
135
|
+
module: 'logs'
|
|
136
|
+
}).option('type', 'The type of logs to be returned: "app" or "batch"', 'app').option('limit', 'The maximum number of log lines', 500).option('format', 'Output the log lines in CSV or JSON format', 'text').examples([{
|
|
137
|
+
usage: 'vip @mysite.production logs',
|
|
138
|
+
description: 'Get the most recent app logs'
|
|
139
|
+
}, {
|
|
140
|
+
usage: 'vip @mysite.production logs --type batch',
|
|
141
|
+
description: 'Get the most recent batch logs'
|
|
142
|
+
}, {
|
|
143
|
+
usage: 'vip @mysite.production logs --limit 100',
|
|
144
|
+
description: 'Get the most recent 100 log entries'
|
|
145
|
+
}, {
|
|
146
|
+
usage: 'vip @mysite.production logs --limit 100 --format csv',
|
|
147
|
+
description: 'Get the most recent 100 log entries formatted as comma-separated values (CSV)'
|
|
148
|
+
}, {
|
|
149
|
+
usage: 'vip @mysite.production logs --limit 100 --format json',
|
|
150
|
+
description: 'Get the most recent 100 log entries formatted as JSON'
|
|
151
|
+
}]).argv(process.argv, getLogs);
|
package/dist/bin/vip.js
CHANGED
|
@@ -48,7 +48,7 @@ const runCmd = async function () {
|
|
|
48
48
|
await _token.default.purge();
|
|
49
49
|
await (0, _tracker.trackEvent)('logout_command_execute');
|
|
50
50
|
console.log('You are successfully logged out.');
|
|
51
|
-
}).command('app', 'List and modify your VIP applications').command('config', 'Set configuration for your VIP applications').command('dev-env', 'Use local dev-environment').command('import', 'Import media or SQL files into your VIP applications').command('search-replace', 'Perform search and replace tasks on files').command('sync', 'Sync production to a development environment').command('wp', 'Run WP CLI commands against an environment');
|
|
51
|
+
}).command('app', 'List and modify your VIP applications').command('config', 'Set configuration for your VIP applications').command('dev-env', 'Use local dev-environment').command('import', 'Import media or SQL files into your VIP applications').command('logs', 'Get logs from your VIP applications').command('search-replace', 'Perform search and replace tasks on files').command('sync', 'Sync production to a development environment').command('wp', 'Run WP CLI commands against an environment');
|
|
52
52
|
cmd.argv(process.argv);
|
|
53
53
|
};
|
|
54
54
|
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getRecentLogs = getRecentLogs;
|
|
7
|
+
|
|
8
|
+
var _graphqlTag = _interopRequireDefault(require("graphql-tag"));
|
|
9
|
+
|
|
10
|
+
var _api = _interopRequireDefault(require("../api"));
|
|
11
|
+
|
|
12
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
*
|
|
16
|
+
* @format
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* External dependencies
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Internal dependencies
|
|
25
|
+
*/
|
|
26
|
+
const QUERY_ENVIRONMENT_LOGS = (0, _graphqlTag.default)`
|
|
27
|
+
query GetAppLogs( $appId: Int, $envId: Int, $type: AppEnvironmentLogType, $limit: Int ) {
|
|
28
|
+
app( id: $appId ) {
|
|
29
|
+
environments( id: $envId ) {
|
|
30
|
+
id
|
|
31
|
+
logs( type: $type, limit: $limit ) {
|
|
32
|
+
nodes {
|
|
33
|
+
timestamp
|
|
34
|
+
message
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
`;
|
|
41
|
+
|
|
42
|
+
async function getRecentLogs(appId, envId, type, limit) {
|
|
43
|
+
var _response$data, _response$data$app, _response$data$app$en, _response$data$app$en2;
|
|
44
|
+
|
|
45
|
+
const api = await (0, _api.default)();
|
|
46
|
+
const response = await api.query({
|
|
47
|
+
query: QUERY_ENVIRONMENT_LOGS,
|
|
48
|
+
variables: {
|
|
49
|
+
appId,
|
|
50
|
+
envId,
|
|
51
|
+
type,
|
|
52
|
+
limit
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
const logs = response === null || response === void 0 ? void 0 : (_response$data = response.data) === null || _response$data === void 0 ? void 0 : (_response$data$app = _response$data.app) === null || _response$data$app === void 0 ? void 0 : (_response$data$app$en = _response$data$app.environments[0]) === null || _response$data$app$en === void 0 ? void 0 : (_response$data$app$en2 = _response$data$app$en.logs) === null || _response$data$app$en2 === void 0 ? void 0 : _response$data$app$en2.nodes;
|
|
56
|
+
|
|
57
|
+
if (!logs) {
|
|
58
|
+
throw new Error('Unable to query logs');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return logs;
|
|
62
|
+
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.DEV_ENVIRONMENT_COMPONENTS = exports.DEV_ENVIRONMENT_PROMPT_INTRO = exports.DEV_ENVIRONMENT_DEFAULTS = exports.DEV_ENVIRONMENT_FULL_COMMAND = exports.DEV_ENVIRONMENT_SUBCOMMAND = void 0;
|
|
6
|
+
exports.DEV_ENVIRONMENT_COMPONENTS = exports.DEV_ENVIRONMENT_NOT_FOUND = exports.DEV_ENVIRONMENT_PROMPT_INTRO = exports.DEV_ENVIRONMENT_DEFAULTS = exports.DEV_ENVIRONMENT_FULL_COMMAND = exports.DEV_ENVIRONMENT_SUBCOMMAND = void 0;
|
|
7
7
|
const DEV_ENVIRONMENT_SUBCOMMAND = 'dev-env';
|
|
8
8
|
exports.DEV_ENVIRONMENT_SUBCOMMAND = DEV_ENVIRONMENT_SUBCOMMAND;
|
|
9
9
|
const DEV_ENVIRONMENT_FULL_COMMAND = `vip ${DEV_ENVIRONMENT_SUBCOMMAND}`;
|
|
@@ -17,5 +17,7 @@ const DEV_ENVIRONMENT_DEFAULTS = {
|
|
|
17
17
|
exports.DEV_ENVIRONMENT_DEFAULTS = DEV_ENVIRONMENT_DEFAULTS;
|
|
18
18
|
const DEV_ENVIRONMENT_PROMPT_INTRO = 'This is a wizard to help you set up your local dev environment.\n\n' + 'Sensible default values were pre-selected for convenience. ' + 'You may also choose to create multiple environments with different settings using the --slug option.\n\n';
|
|
19
19
|
exports.DEV_ENVIRONMENT_PROMPT_INTRO = DEV_ENVIRONMENT_PROMPT_INTRO;
|
|
20
|
+
const DEV_ENVIRONMENT_NOT_FOUND = 'Environment not found.';
|
|
21
|
+
exports.DEV_ENVIRONMENT_NOT_FOUND = DEV_ENVIRONMENT_NOT_FOUND;
|
|
20
22
|
const DEV_ENVIRONMENT_COMPONENTS = ['wordpress', 'muPlugins', 'clientCode'];
|
|
21
23
|
exports.DEV_ENVIRONMENT_COMPONENTS = DEV_ENVIRONMENT_COMPONENTS;
|
|
@@ -8,11 +8,13 @@ exports.getEnvironmentName = getEnvironmentName;
|
|
|
8
8
|
exports.getEnvironmentStartCommand = getEnvironmentStartCommand;
|
|
9
9
|
exports.printTable = printTable;
|
|
10
10
|
exports.processComponentOptionInput = processComponentOptionInput;
|
|
11
|
+
exports.getOptionsFromAppInfo = getOptionsFromAppInfo;
|
|
11
12
|
exports.promptForArguments = promptForArguments;
|
|
12
13
|
exports.resolvePath = resolvePath;
|
|
13
14
|
exports.promptForText = promptForText;
|
|
14
15
|
exports.promptForBoolean = promptForBoolean;
|
|
15
16
|
exports.promptForComponent = promptForComponent;
|
|
17
|
+
exports.addDevEnvConfigurationOptions = addDevEnvConfigurationOptions;
|
|
16
18
|
|
|
17
19
|
var _chalk = _interopRequireDefault(require("chalk"));
|
|
18
20
|
|
|
@@ -30,6 +32,8 @@ var _os = _interopRequireDefault(require("os"));
|
|
|
30
32
|
|
|
31
33
|
var _devEnvironment = require("../constants/dev-environment");
|
|
32
34
|
|
|
35
|
+
var _types = require("./types");
|
|
36
|
+
|
|
33
37
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
34
38
|
|
|
35
39
|
/**
|
|
@@ -50,7 +54,7 @@ const DEFAULT_SLUG = 'vip-local';
|
|
|
50
54
|
function handleCLIException(exception) {
|
|
51
55
|
const errorPrefix = _chalk.default.red('Error:');
|
|
52
56
|
|
|
53
|
-
if (
|
|
57
|
+
if (_devEnvironment.DEV_ENVIRONMENT_NOT_FOUND === exception.message) {
|
|
54
58
|
const createCommand = _chalk.default.bold(_devEnvironment.DEV_ENVIRONMENT_FULL_COMMAND + ' create');
|
|
55
59
|
|
|
56
60
|
const message = `Environment doesn't exist.\n\n\nTo create a new environment run:\n\n${createCommand}\n`;
|
|
@@ -121,60 +125,89 @@ function processComponentOptionInput(passedParam, allowLocal) {
|
|
|
121
125
|
};
|
|
122
126
|
}
|
|
123
127
|
|
|
124
|
-
|
|
125
|
-
var _appInfo$environment, _appInfo$environment3;
|
|
128
|
+
function getOptionsFromAppInfo(appInfo) {
|
|
129
|
+
var _appInfo$environment, _appInfo$environment2, _appInfo$environment3;
|
|
130
|
+
|
|
131
|
+
if (!appInfo) {
|
|
132
|
+
return {};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
title: ((_appInfo$environment = appInfo.environment) === null || _appInfo$environment === void 0 ? void 0 : _appInfo$environment.name) || appInfo.name,
|
|
137
|
+
multisite: !!(appInfo !== null && appInfo !== void 0 && (_appInfo$environment2 = appInfo.environment) !== null && _appInfo$environment2 !== void 0 && _appInfo$environment2.isMultisite),
|
|
138
|
+
mediaRedirectDomain: (_appInfo$environment3 = appInfo.environment) === null || _appInfo$environment3 === void 0 ? void 0 : _appInfo$environment3.primaryDomain
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Prompt for arguments
|
|
143
|
+
* @param {InstanceOptions} preselectedOptions - options to be used without prompt
|
|
144
|
+
* @param {InstanceOptions} defaultOptions - options to be used as default values for prompt
|
|
145
|
+
* @returns {any} instance data
|
|
146
|
+
*/
|
|
126
147
|
|
|
127
|
-
|
|
148
|
+
|
|
149
|
+
async function promptForArguments(preselectedOptions, defaultOptions) {
|
|
150
|
+
debug('Provided preselected', preselectedOptions, 'and default', defaultOptions);
|
|
128
151
|
console.log(_devEnvironment.DEV_ENVIRONMENT_PROMPT_INTRO);
|
|
129
|
-
const name = (appInfo === null || appInfo === void 0 ? void 0 : (_appInfo$environment = appInfo.environment) === null || _appInfo$environment === void 0 ? void 0 : _appInfo$environment.name) || (appInfo === null || appInfo === void 0 ? void 0 : appInfo.name);
|
|
130
152
|
let multisiteText = 'Multisite';
|
|
131
153
|
let multisiteDefault = _devEnvironment.DEV_ENVIRONMENT_DEFAULTS.multisite;
|
|
132
154
|
|
|
133
|
-
if (
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
const isEnvMultisite = !!(appInfo !== null && appInfo !== void 0 && (_appInfo$environment2 = appInfo.environment) !== null && _appInfo$environment2 !== void 0 && _appInfo$environment2.isMultisite);
|
|
137
|
-
multisiteText += ` (${name} ${isEnvMultisite ? 'IS' : 'is NOT'} multisite)`;
|
|
138
|
-
multisiteDefault = isEnvMultisite;
|
|
155
|
+
if (defaultOptions.title) {
|
|
156
|
+
multisiteText += ` (${defaultOptions.title} ${defaultOptions.multisite ? 'IS' : 'is NOT'} multisite)`;
|
|
157
|
+
multisiteDefault = defaultOptions.multisite;
|
|
139
158
|
}
|
|
140
159
|
|
|
141
160
|
const instanceData = {
|
|
142
|
-
wpTitle:
|
|
143
|
-
multisite: 'multisite' in
|
|
144
|
-
elasticsearch:
|
|
145
|
-
mariadb:
|
|
146
|
-
mediaRedirectDomain: '',
|
|
161
|
+
wpTitle: preselectedOptions.title || (await promptForText('WordPress site title', defaultOptions.title || _devEnvironment.DEV_ENVIRONMENT_DEFAULTS.title)),
|
|
162
|
+
multisite: 'multisite' in preselectedOptions ? preselectedOptions.multisite : await promptForBoolean(multisiteText, !!multisiteDefault),
|
|
163
|
+
elasticsearch: preselectedOptions.elasticsearch || defaultOptions.elasticsearch || _devEnvironment.DEV_ENVIRONMENT_DEFAULTS.elasticsearchVersion,
|
|
164
|
+
mariadb: preselectedOptions.mariadb || defaultOptions.mariadb || _devEnvironment.DEV_ENVIRONMENT_DEFAULTS.mariadbVersion,
|
|
165
|
+
mediaRedirectDomain: preselectedOptions.mediaRedirectDomain || '',
|
|
147
166
|
wordpress: {},
|
|
148
167
|
muPlugins: {},
|
|
149
|
-
clientCode: {}
|
|
168
|
+
clientCode: {},
|
|
169
|
+
statsd: false,
|
|
170
|
+
phpmyadmin: false,
|
|
171
|
+
xdebug: false
|
|
150
172
|
};
|
|
151
|
-
const primaryDomain = appInfo === null || appInfo === void 0 ? void 0 : (_appInfo$environment3 = appInfo.environment) === null || _appInfo$environment3 === void 0 ? void 0 : _appInfo$environment3.primaryDomain;
|
|
152
173
|
|
|
153
|
-
if (
|
|
154
|
-
const mediaRedirectPromptText = `Would you like to redirect to ${
|
|
174
|
+
if (!instanceData.mediaRedirectDomain && defaultOptions.mediaRedirectDomain) {
|
|
175
|
+
const mediaRedirectPromptText = `Would you like to redirect to ${defaultOptions.mediaRedirectDomain} for missing media files?`;
|
|
155
176
|
const setMediaRedirectDomain = await promptForBoolean(mediaRedirectPromptText, true);
|
|
156
177
|
|
|
157
178
|
if (setMediaRedirectDomain) {
|
|
158
|
-
instanceData.mediaRedirectDomain =
|
|
179
|
+
instanceData.mediaRedirectDomain = defaultOptions.mediaRedirectDomain;
|
|
159
180
|
}
|
|
160
181
|
}
|
|
161
182
|
|
|
162
183
|
for (const component of _devEnvironment.DEV_ENVIRONMENT_COMPONENTS) {
|
|
163
|
-
const option =
|
|
164
|
-
|
|
184
|
+
const option = preselectedOptions[component];
|
|
185
|
+
const defaultValue = defaultOptions[component];
|
|
186
|
+
instanceData[component] = await processComponent(component, option, defaultValue);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
for (const service of ['statsd', 'phpmyadmin', 'xdebug']) {
|
|
190
|
+
if (service in preselectedOptions) {
|
|
191
|
+
instanceData[service] = preselectedOptions[service];
|
|
192
|
+
} else if (service in defaultOptions) {
|
|
193
|
+
instanceData[service] = defaultOptions[service];
|
|
194
|
+
}
|
|
165
195
|
}
|
|
166
196
|
|
|
197
|
+
debug('Instance data after prompts', instanceData);
|
|
167
198
|
return instanceData;
|
|
168
199
|
}
|
|
169
200
|
|
|
170
|
-
async function processComponent(component,
|
|
201
|
+
async function processComponent(component, preselectedValue, defaultValue) {
|
|
202
|
+
debug(`processing a component '${component}', with preselected/deafault - ${preselectedValue}/${defaultValue}`);
|
|
171
203
|
let result = null;
|
|
172
204
|
const allowLocal = component !== 'wordpress';
|
|
205
|
+
const defaultObject = defaultValue ? processComponentOptionInput(defaultValue, allowLocal) : null;
|
|
173
206
|
|
|
174
|
-
if (
|
|
175
|
-
result = processComponentOptionInput(
|
|
207
|
+
if (preselectedValue) {
|
|
208
|
+
result = processComponentOptionInput(preselectedValue, allowLocal);
|
|
176
209
|
} else {
|
|
177
|
-
result = await promptForComponent(component, allowLocal);
|
|
210
|
+
result = await promptForComponent(component, allowLocal, defaultObject);
|
|
178
211
|
}
|
|
179
212
|
|
|
180
213
|
while ('local' === ((_result = result) === null || _result === void 0 ? void 0 : _result.mode)) {
|
|
@@ -192,7 +225,7 @@ async function processComponent(component, option) {
|
|
|
192
225
|
} else {
|
|
193
226
|
const message = `Provided path "${resolvedPath}" does not point to a valid or existing directory.`;
|
|
194
227
|
console.log(_chalk.default.yellow('Warning:'), message);
|
|
195
|
-
result = await promptForComponent(component, allowLocal);
|
|
228
|
+
result = await promptForComponent(component, allowLocal, defaultObject);
|
|
196
229
|
}
|
|
197
230
|
}
|
|
198
231
|
|
|
@@ -222,7 +255,7 @@ async function promptForText(message, initial) {
|
|
|
222
255
|
initial,
|
|
223
256
|
validate: nonEmptyValidator
|
|
224
257
|
});
|
|
225
|
-
return result.input.trim();
|
|
258
|
+
return ((result === null || result === void 0 ? void 0 : result.input) || '').trim();
|
|
226
259
|
}
|
|
227
260
|
|
|
228
261
|
async function promptForBoolean(message, initial) {
|
|
@@ -239,19 +272,19 @@ const componentDisplayNames = {
|
|
|
239
272
|
clientCode: 'site-code'
|
|
240
273
|
};
|
|
241
274
|
|
|
242
|
-
async function promptForComponent(component, allowLocal) {
|
|
243
|
-
debug(`Prompting for ${component}
|
|
275
|
+
async function promptForComponent(component, allowLocal, defaultObject) {
|
|
276
|
+
debug(`Prompting for ${component} with default:`, defaultObject);
|
|
244
277
|
const componentDisplayName = componentDisplayNames[component] || component;
|
|
245
|
-
const
|
|
278
|
+
const modChoices = [];
|
|
246
279
|
|
|
247
280
|
if (allowLocal) {
|
|
248
|
-
|
|
281
|
+
modChoices.push({
|
|
249
282
|
message: `local folder - where you already have ${componentDisplayName} code`,
|
|
250
283
|
value: 'local'
|
|
251
284
|
});
|
|
252
285
|
}
|
|
253
286
|
|
|
254
|
-
|
|
287
|
+
modChoices.push({
|
|
255
288
|
message: 'image - that gets automatically fetched',
|
|
256
289
|
value: 'image'
|
|
257
290
|
});
|
|
@@ -261,14 +294,18 @@ async function promptForComponent(component, allowLocal) {
|
|
|
261
294
|
initialMode = 'local';
|
|
262
295
|
}
|
|
263
296
|
|
|
297
|
+
if (defaultObject !== null && defaultObject !== void 0 && defaultObject.mode) {
|
|
298
|
+
initialMode = defaultObject.mode;
|
|
299
|
+
}
|
|
300
|
+
|
|
264
301
|
let modeResult = initialMode;
|
|
265
|
-
const selectMode =
|
|
302
|
+
const selectMode = modChoices.length > 1;
|
|
266
303
|
|
|
267
304
|
if (selectMode) {
|
|
268
|
-
const initialModeIndex =
|
|
305
|
+
const initialModeIndex = modChoices.findIndex(choice => choice.value === initialMode);
|
|
269
306
|
const select = new _enquirer.Select({
|
|
270
307
|
message: `How would you like to source ${componentDisplayName}`,
|
|
271
|
-
choices,
|
|
308
|
+
choices: modChoices,
|
|
272
309
|
initial: initialModeIndex
|
|
273
310
|
});
|
|
274
311
|
modeResult = await select.run();
|
|
@@ -277,38 +314,61 @@ async function promptForComponent(component, allowLocal) {
|
|
|
277
314
|
const messagePrefix = selectMode ? '\t' : `${componentDisplayName} - `;
|
|
278
315
|
|
|
279
316
|
if ('local' === modeResult) {
|
|
280
|
-
const directoryPath = await promptForText(`${messagePrefix}What is a path to your local ${componentDisplayName}`, '');
|
|
317
|
+
const directoryPath = await promptForText(`${messagePrefix}What is a path to your local ${componentDisplayName}`, (defaultObject === null || defaultObject === void 0 ? void 0 : defaultObject.dir) || '');
|
|
281
318
|
return {
|
|
282
319
|
mode: modeResult,
|
|
283
320
|
dir: directoryPath
|
|
284
321
|
};
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
if ('inherit' === modeResult) {
|
|
288
|
-
return {
|
|
289
|
-
mode: modeResult
|
|
290
|
-
};
|
|
291
|
-
} // image
|
|
322
|
+
} // image with selection
|
|
292
323
|
|
|
293
324
|
|
|
294
325
|
if (component === 'wordpress') {
|
|
295
326
|
const message = `${messagePrefix}Which version would you like`;
|
|
327
|
+
const tagChoices = getWordpressImageTags();
|
|
328
|
+
let initialTagIndex = 0;
|
|
329
|
+
|
|
330
|
+
if (defaultObject !== null && defaultObject !== void 0 && defaultObject.tag) {
|
|
331
|
+
const defaultTagIndex = tagChoices.indexOf(defaultObject.tag);
|
|
332
|
+
|
|
333
|
+
if (defaultTagIndex !== -1) {
|
|
334
|
+
initialTagIndex = defaultTagIndex;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
296
338
|
const selectTag = new _enquirer.Select({
|
|
297
339
|
message,
|
|
298
|
-
choices:
|
|
340
|
+
choices: tagChoices,
|
|
341
|
+
initial: initialTagIndex
|
|
299
342
|
});
|
|
300
343
|
const tag = await selectTag.run();
|
|
301
344
|
return {
|
|
302
345
|
mode: modeResult,
|
|
303
346
|
tag
|
|
304
347
|
};
|
|
305
|
-
}
|
|
348
|
+
} // image
|
|
349
|
+
|
|
306
350
|
|
|
307
351
|
return {
|
|
308
352
|
mode: modeResult
|
|
309
353
|
};
|
|
310
354
|
}
|
|
311
355
|
|
|
356
|
+
function addDevEnvConfigurationOptions(command) {
|
|
357
|
+
return command.option('wordpress', 'Use a specific WordPress version').option(['u', 'mu-plugins'], 'Use a specific mu-plugins changeset or local directory').option('client-code', 'Use the client code from a local directory or VIP skeleton').option('statsd', 'Enable statsd component. By default it is disabled', undefined, value => {
|
|
358
|
+
var _value$toLowerCase;
|
|
359
|
+
|
|
360
|
+
return 'false' !== (value === null || value === void 0 ? void 0 : (_value$toLowerCase = value.toLowerCase) === null || _value$toLowerCase === void 0 ? void 0 : _value$toLowerCase.call(value));
|
|
361
|
+
}).option('phpmyadmin', 'Enable PHPMyAdmin component. By default it is disabled', undefined, value => {
|
|
362
|
+
var _value$toLowerCase2;
|
|
363
|
+
|
|
364
|
+
return 'false' !== (value === null || value === void 0 ? void 0 : (_value$toLowerCase2 = value.toLowerCase) === null || _value$toLowerCase2 === void 0 ? void 0 : _value$toLowerCase2.call(value));
|
|
365
|
+
}).option('xdebug', 'Enable XDebug. By default it is disabled', undefined, value => {
|
|
366
|
+
var _value$toLowerCase3;
|
|
367
|
+
|
|
368
|
+
return 'false' !== (value === null || value === void 0 ? void 0 : (_value$toLowerCase3 = value.toLowerCase) === null || _value$toLowerCase3 === void 0 ? void 0 : _value$toLowerCase3.call(value));
|
|
369
|
+
}).option('elasticsearch', 'Explicitly choose Elasticsearch version to use').option('mariadb', 'Explicitly choose MariaDB version to use').option('media-redirect-domain', 'Domain to redirect for missing media files. This can be used to still have images without the need to import them locally.');
|
|
370
|
+
}
|
|
371
|
+
|
|
312
372
|
function getWordpressImageTags() {
|
|
313
373
|
return ['5.8.1', '5.8', '5.7.3', '5.7.2'];
|
|
314
374
|
}
|
|
@@ -6,11 +6,13 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.startEnvironment = startEnvironment;
|
|
7
7
|
exports.stopEnvironment = stopEnvironment;
|
|
8
8
|
exports.createEnvironment = createEnvironment;
|
|
9
|
+
exports.updateEnvironment = updateEnvironment;
|
|
9
10
|
exports.destroyEnvironment = destroyEnvironment;
|
|
10
11
|
exports.printAllEnvironmentsInfo = printAllEnvironmentsInfo;
|
|
11
12
|
exports.printEnvironmentInfo = printEnvironmentInfo;
|
|
12
13
|
exports.exec = exec;
|
|
13
14
|
exports.doesEnvironmentExist = doesEnvironmentExist;
|
|
15
|
+
exports.readEnvironmentData = readEnvironmentData;
|
|
14
16
|
exports.getEnvironmentPath = getEnvironmentPath;
|
|
15
17
|
exports.getApplicationInformation = getApplicationInformation;
|
|
16
18
|
exports.resolveImportPath = resolveImportPath;
|
|
@@ -42,6 +44,8 @@ var _devEnvironmentCli = require("./dev-environment-cli");
|
|
|
42
44
|
|
|
43
45
|
var _app = _interopRequireDefault(require("../api/app"));
|
|
44
46
|
|
|
47
|
+
var _devEnvironment = require("../constants/dev-environment");
|
|
48
|
+
|
|
45
49
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
46
50
|
|
|
47
51
|
/**
|
|
@@ -77,7 +81,7 @@ async function startEnvironment(slug, options) {
|
|
|
77
81
|
const environmentExists = _fs.default.existsSync(instancePath);
|
|
78
82
|
|
|
79
83
|
if (!environmentExists) {
|
|
80
|
-
throw new Error(
|
|
84
|
+
throw new Error(_devEnvironment.DEV_ENVIRONMENT_NOT_FOUND);
|
|
81
85
|
}
|
|
82
86
|
|
|
83
87
|
if (options.skipRebuild) {
|
|
@@ -97,7 +101,7 @@ async function stopEnvironment(slug) {
|
|
|
97
101
|
const environmentExists = _fs.default.existsSync(instancePath);
|
|
98
102
|
|
|
99
103
|
if (!environmentExists) {
|
|
100
|
-
throw new Error(
|
|
104
|
+
throw new Error(_devEnvironment.DEV_ENVIRONMENT_NOT_FOUND);
|
|
101
105
|
}
|
|
102
106
|
|
|
103
107
|
await (0, _devEnvironmentLando.landoStop)(instancePath);
|
|
@@ -105,7 +109,7 @@ async function stopEnvironment(slug) {
|
|
|
105
109
|
|
|
106
110
|
async function createEnvironment(instanceData) {
|
|
107
111
|
const slug = instanceData.siteSlug;
|
|
108
|
-
debug('Will
|
|
112
|
+
debug('Will create an environment', slug, 'with instanceData: ', instanceData);
|
|
109
113
|
const instancePath = getEnvironmentPath(slug);
|
|
110
114
|
debug('Instance path for', slug, 'is:', instancePath);
|
|
111
115
|
|
|
@@ -115,12 +119,36 @@ async function createEnvironment(instanceData) {
|
|
|
115
119
|
throw new Error('Environment already exists.');
|
|
116
120
|
}
|
|
117
121
|
|
|
122
|
+
const preProcessedInstanceData = preProcessInstanceData(instanceData);
|
|
123
|
+
await prepareLandoEnv(preProcessedInstanceData, instancePath);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async function updateEnvironment(instanceData) {
|
|
127
|
+
const slug = instanceData.siteSlug;
|
|
128
|
+
debug('Will update an environment', slug, 'with instanceData: ', instanceData);
|
|
129
|
+
const instancePath = getEnvironmentPath(slug);
|
|
130
|
+
debug('Instance path for', slug, 'is:', instancePath);
|
|
131
|
+
|
|
132
|
+
const alreadyExists = _fs.default.existsSync(instancePath);
|
|
133
|
+
|
|
134
|
+
if (!alreadyExists) {
|
|
135
|
+
throw new Error('Environment doesn\'t exist.');
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const preProcessedInstanceData = preProcessInstanceData(instanceData);
|
|
139
|
+
await prepareLandoEnv(preProcessedInstanceData, instancePath);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function preProcessInstanceData(instanceData) {
|
|
143
|
+
const newInstanceData = { ...instanceData
|
|
144
|
+
};
|
|
145
|
+
|
|
118
146
|
if (instanceData.mediaRedirectDomain && !instanceData.mediaRedirectDomain.match(/^http/)) {
|
|
119
147
|
// We need to make sure the redirect is an absolute path
|
|
120
|
-
|
|
148
|
+
newInstanceData.mediaRedirectDomain = `https://${instanceData.mediaRedirectDomain}`;
|
|
121
149
|
}
|
|
122
150
|
|
|
123
|
-
|
|
151
|
+
return newInstanceData;
|
|
124
152
|
}
|
|
125
153
|
|
|
126
154
|
async function destroyEnvironment(slug, removeFiles) {
|
|
@@ -131,7 +159,7 @@ async function destroyEnvironment(slug, removeFiles) {
|
|
|
131
159
|
const environmentExists = _fs.default.existsSync(instancePath);
|
|
132
160
|
|
|
133
161
|
if (!environmentExists) {
|
|
134
|
-
throw new Error(
|
|
162
|
+
throw new Error(_devEnvironment.DEV_ENVIRONMENT_NOT_FOUND);
|
|
135
163
|
}
|
|
136
164
|
|
|
137
165
|
const landoFilePath = _path.default.join(instancePath, landoFileName);
|
|
@@ -170,7 +198,7 @@ async function printEnvironmentInfo(slug) {
|
|
|
170
198
|
const environmentExists = _fs.default.existsSync(instancePath);
|
|
171
199
|
|
|
172
200
|
if (!environmentExists) {
|
|
173
|
-
throw new Error(
|
|
201
|
+
throw new Error(_devEnvironment.DEV_ENVIRONMENT_NOT_FOUND);
|
|
174
202
|
}
|
|
175
203
|
|
|
176
204
|
const appInfo = await (0, _devEnvironmentLando.landoInfo)(instancePath);
|
|
@@ -185,7 +213,7 @@ async function exec(slug, args) {
|
|
|
185
213
|
const environmentExists = _fs.default.existsSync(instancePath);
|
|
186
214
|
|
|
187
215
|
if (!environmentExists) {
|
|
188
|
-
throw new Error(
|
|
216
|
+
throw new Error(_devEnvironment.DEV_ENVIRONMENT_NOT_FOUND);
|
|
189
217
|
}
|
|
190
218
|
|
|
191
219
|
const command = args.shift();
|
|
@@ -205,6 +233,17 @@ function doesEnvironmentExist(slug) {
|
|
|
205
233
|
return _fs.default.existsSync(instancePath);
|
|
206
234
|
}
|
|
207
235
|
|
|
236
|
+
function readEnvironmentData(slug) {
|
|
237
|
+
debug('Will try to get instance data for environment', slug);
|
|
238
|
+
const instancePath = getEnvironmentPath(slug);
|
|
239
|
+
|
|
240
|
+
const instanceDataTargetPath = _path.default.join(instancePath, instanceDataFileName);
|
|
241
|
+
|
|
242
|
+
const instanceDataString = _fs.default.readFileSync(instanceDataTargetPath, 'utf8');
|
|
243
|
+
|
|
244
|
+
return JSON.parse(instanceDataString);
|
|
245
|
+
}
|
|
246
|
+
|
|
208
247
|
async function prepareLandoEnv(instanceData, instancePath) {
|
|
209
248
|
const landoFile = await _ejs.default.renderFile(landoFileTemplatePath, instanceData);
|
|
210
249
|
const nginxFile = await _ejs.default.renderFile(nginxFileTemplatePath, instanceData);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
@@ -16,7 +16,7 @@ var _fileSize = require("../constants/file-size");
|
|
|
16
16
|
/**
|
|
17
17
|
* Internal dependencies
|
|
18
18
|
*/
|
|
19
|
-
const SQL_IMPORT_FILE_SIZE_LIMIT =
|
|
19
|
+
const SQL_IMPORT_FILE_SIZE_LIMIT = 100 * _fileSize.GB_IN_BYTES;
|
|
20
20
|
exports.SQL_IMPORT_FILE_SIZE_LIMIT = SQL_IMPORT_FILE_SIZE_LIMIT;
|
|
21
21
|
const SQL_IMPORT_FILE_SIZE_LIMIT_LAUNCHED = 350 * _fileSize.MB_IN_BYTES;
|
|
22
22
|
exports.SQL_IMPORT_FILE_SIZE_LIMIT_LAUNCHED = SQL_IMPORT_FILE_SIZE_LIMIT_LAUNCHED;
|
|
@@ -48,6 +48,7 @@ const IMPORT_SQL_PROGRESS_QUERY = (0, _graphqlTag.default)`
|
|
|
48
48
|
environments(id: $envId) {
|
|
49
49
|
id
|
|
50
50
|
isK8sResident
|
|
51
|
+
launched
|
|
51
52
|
jobs(types: "sql_import") {
|
|
52
53
|
id
|
|
53
54
|
type
|
|
@@ -106,7 +107,8 @@ async function getStatus(api, appId, envId) {
|
|
|
106
107
|
const [environment] = environments;
|
|
107
108
|
const {
|
|
108
109
|
importStatus,
|
|
109
|
-
jobs
|
|
110
|
+
jobs,
|
|
111
|
+
launched
|
|
110
112
|
} = environment;
|
|
111
113
|
|
|
112
114
|
if (!environment.isK8sResident && !(jobs !== null && jobs !== void 0 && jobs.length)) {
|
|
@@ -116,15 +118,16 @@ async function getStatus(api, appId, envId) {
|
|
|
116
118
|
const [importJob] = jobs;
|
|
117
119
|
return {
|
|
118
120
|
importStatus,
|
|
119
|
-
importJob
|
|
121
|
+
importJob,
|
|
122
|
+
launched
|
|
120
123
|
};
|
|
121
124
|
}
|
|
122
125
|
|
|
123
|
-
function getErrorMessage(importFailed) {
|
|
126
|
+
function getErrorMessage(importFailed, launched = false) {
|
|
124
127
|
debug({
|
|
125
128
|
importFailed
|
|
126
129
|
});
|
|
127
|
-
const rollbackMessage = `Your site is ${_chalk.default.blue('automatically being rolled back')} to the last backup prior to your import job.
|
|
130
|
+
const rollbackMessage = launched ? '' : `Your site is ${_chalk.default.blue('automatically being rolled back')} to the last backup prior to your import job.
|
|
128
131
|
`;
|
|
129
132
|
let message = importFailed.error;
|
|
130
133
|
|
|
@@ -262,7 +265,8 @@ ${maybeExitPrompt}
|
|
|
262
265
|
}
|
|
263
266
|
|
|
264
267
|
const {
|
|
265
|
-
importStatus
|
|
268
|
+
importStatus,
|
|
269
|
+
launched
|
|
266
270
|
} = status;
|
|
267
271
|
let {
|
|
268
272
|
importJob
|
|
@@ -345,14 +349,15 @@ ${maybeExitPrompt}
|
|
|
345
349
|
|
|
346
350
|
let failedImportStep;
|
|
347
351
|
|
|
348
|
-
if (jobCreationTime && (importStepProgress === null || importStepProgress === void 0 ? void 0 : importStepProgress.started_at) * 1000
|
|
352
|
+
if (jobCreationTime && (importStepProgress === null || importStepProgress === void 0 ? void 0 : importStepProgress.started_at) * 1000 >= jobCreationTime) {
|
|
349
353
|
// The contents of the `import_progress` meta are pertinent to the most recent import job
|
|
350
354
|
failedImportStep = importStepProgress.steps.find(step => (step === null || step === void 0 ? void 0 : step.result) === 'failed' && 1000 * (step === null || step === void 0 ? void 0 : step.started_at) > new Date(createdAt).getTime());
|
|
351
355
|
}
|
|
352
356
|
|
|
353
357
|
if (!jobSteps.length) {
|
|
354
358
|
return reject({
|
|
355
|
-
error: 'Could not enumerate the import job steps'
|
|
359
|
+
error: 'Could not enumerate the import job steps',
|
|
360
|
+
launched
|
|
356
361
|
});
|
|
357
362
|
}
|
|
358
363
|
|
|
@@ -375,7 +380,8 @@ ${maybeExitPrompt}
|
|
|
375
380
|
commandOutput: failedImportStep.output,
|
|
376
381
|
error: 'Import step failed',
|
|
377
382
|
stepName: failedImportStep.name,
|
|
378
|
-
errorText: failedImportStep.error
|
|
383
|
+
errorText: failedImportStep.error,
|
|
384
|
+
launched
|
|
379
385
|
});
|
|
380
386
|
}
|
|
381
387
|
|
|
@@ -385,7 +391,8 @@ ${maybeExitPrompt}
|
|
|
385
391
|
if (jobStatus === 'error') {
|
|
386
392
|
return reject({
|
|
387
393
|
error: 'Import job failed',
|
|
388
|
-
steps: jobSteps
|
|
394
|
+
steps: jobSteps,
|
|
395
|
+
launched
|
|
389
396
|
});
|
|
390
397
|
}
|
|
391
398
|
|
|
@@ -425,7 +432,7 @@ ${maybeExitPrompt}
|
|
|
425
432
|
progressTracker.print({
|
|
426
433
|
clearAfter: true
|
|
427
434
|
});
|
|
428
|
-
exit.withError(getErrorMessage(importFailed));
|
|
435
|
+
exit.withError(getErrorMessage(importFailed, importFailed.launched));
|
|
429
436
|
}
|
|
430
437
|
}
|
|
431
438
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automattic/vip",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0",
|
|
4
4
|
"description": "The VIP Javascript library & CLI",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"vip-config-envvar-set": "dist/bin/vip-config-envvar-set.js",
|
|
17
17
|
"vip-dev-env": "dist/bin/vip-dev-env.js",
|
|
18
18
|
"vip-dev-env-create": "dist/bin/vip-dev-env-create.js",
|
|
19
|
+
"vip-dev-env-update": "dist/bin/vip-dev-env-update.js",
|
|
19
20
|
"vip-dev-env-destroy": "dist/bin/vip-dev-env-destroy.js",
|
|
20
21
|
"vip-dev-env-exec": "dist/bin/vip-dev-env-exec.js",
|
|
21
22
|
"vip-dev-env-import": "dist/bin/vip-dev-env-import.js",
|
|
@@ -32,6 +33,7 @@
|
|
|
32
33
|
"vip-import-sql-status": "dist/bin/vip-import-sql-status.js",
|
|
33
34
|
"vip-import-validate-files": "dist/bin/vip-import-validate-files.js",
|
|
34
35
|
"vip-import-validate-sql": "dist/bin/vip-import-validate-sql.js",
|
|
36
|
+
"vip-logs": "dist/bin/vip-logs.js",
|
|
35
37
|
"vip-search-replace": "dist/bin/vip-search-replace.js",
|
|
36
38
|
"vip-sync": "dist/bin/vip-sync.js",
|
|
37
39
|
"vip-wp": "dist/bin/vip-wp.js"
|
|
@@ -75,7 +77,7 @@
|
|
|
75
77
|
"devDependencies": {
|
|
76
78
|
"@babel/cli": "7.15.7",
|
|
77
79
|
"@babel/core": "7.14.0",
|
|
78
|
-
"@babel/eslint-parser": "
|
|
80
|
+
"@babel/eslint-parser": "7.13.14",
|
|
79
81
|
"@babel/plugin-transform-modules-commonjs": "7.14.0",
|
|
80
82
|
"@babel/preset-env": "7.14.1",
|
|
81
83
|
"@babel/preset-flow": "7.13.13",
|
|
@@ -84,14 +86,14 @@
|
|
|
84
86
|
"babel-plugin-module-resolver": "4.1.0",
|
|
85
87
|
"core-js": "3.12.0",
|
|
86
88
|
"eslint": "7.32.0",
|
|
87
|
-
"eslint-config-wpvip": "github:automattic/eslint-config-wpvip#
|
|
89
|
+
"eslint-config-wpvip": "github:automattic/eslint-config-wpvip#c6605d1",
|
|
88
90
|
"eslint-plugin-flowtype": "5.7.2",
|
|
89
91
|
"eslint-plugin-import": "2.22.1",
|
|
90
92
|
"eslint-plugin-jest": "24.3.6",
|
|
91
93
|
"eslint-plugin-json": "3.0.0",
|
|
92
94
|
"eslint-plugin-jsx-a11y": "6.4.1",
|
|
93
95
|
"eslint-plugin-no-async-foreach": "0.1.1",
|
|
94
|
-
"eslint-plugin-react": "
|
|
96
|
+
"eslint-plugin-react": "7.26.0",
|
|
95
97
|
"eslint-plugin-wpcalypso": "5.0.0",
|
|
96
98
|
"flow-bin": "0.150.0",
|
|
97
99
|
"jest": "27.2.1",
|
|
@@ -115,7 +117,7 @@
|
|
|
115
117
|
"ini": "2.0.0",
|
|
116
118
|
"json2csv": "5.0.6",
|
|
117
119
|
"jwt-decode": "2.2.0",
|
|
118
|
-
"lando": "git+https://github.com/lando
|
|
120
|
+
"lando": "git+https://github.com/Automattic/lando-cli.git#v3.5.1-patch2021_12_06",
|
|
119
121
|
"node-fetch": "^2.6.1",
|
|
120
122
|
"opn": "5.5.0",
|
|
121
123
|
"rollbar": "2.22.0",
|