@scandipwa/magento-scripts 2.0.0-alpha.0 → 2.0.0-alpha.11
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/exec.js +71 -0
- package/index.js +1 -1
- package/lib/commands/cli.js +7 -2
- package/lib/commands/execute.js +3 -58
- package/lib/commands/import-db.js +1 -1
- package/lib/commands/logs.js +1 -1
- package/lib/commands/start.js +18 -8
- package/lib/commands/status.js +9 -1
- package/lib/config/config.js +20 -2
- package/lib/config/docker.js +79 -85
- package/lib/config/index.js +2 -2
- package/lib/config/php/versions/php-7.2.js +1 -0
- package/lib/config/php/versions/php-7.3.js +1 -0
- package/lib/config/php/versions/php-7.4.js +1 -0
- package/lib/config/php/versions/php-8.1.js +1 -0
- package/lib/config/php-config.js +4 -3
- package/lib/config/port-config.js +1 -1
- package/lib/config/services/composer/versions/composer-1.js +8 -0
- package/lib/config/services/composer/versions/composer-2.js +8 -0
- package/lib/config/services/composer/versions/index.js +4 -0
- package/lib/config/services/elasticsearch/base-repo.js +3 -0
- package/lib/config/services/elasticsearch/default-es-env.js +6 -0
- package/lib/config/services/elasticsearch/versions/elasticsearch-6.8.js +19 -0
- package/lib/config/services/elasticsearch/versions/index.js +5 -0
- package/lib/config/services/nginx/versions/index.js +3 -0
- package/lib/config/services/nginx/versions/nginx-1.18.js +11 -0
- package/lib/config/{ssl-terminator → services/ssl-terminator}/index.js +3 -0
- package/lib/config/templates/magentorc.template +6 -5
- package/lib/config/templates/mariadb.template.cnf +191 -0
- package/lib/config/templates/php-debug.template.ini +31 -0
- package/lib/config/templates/php-fpm.template.conf +1 -2
- package/lib/config/templates/php.template.ini +6 -202
- package/lib/config/templates/ssl-terminator.template.conf +10 -3
- package/lib/config/templates/varnish.template.vcl +20 -13
- package/lib/config/varnish/varnish-6-0.js +4 -0
- package/lib/config/varnish/varnish-6-6.js +4 -0
- package/lib/config/varnish/varnish-7-0.js +4 -0
- package/lib/config/versions/magento-2.3.0.js +7 -12
- package/lib/config/versions/magento-2.3.1.js +7 -12
- package/lib/config/versions/magento-2.3.2-p1.js +7 -12
- package/lib/config/versions/magento-2.3.2-p2.js +7 -12
- package/lib/config/versions/magento-2.3.2.js +7 -12
- package/lib/config/versions/magento-2.3.3-p1.js +7 -12
- package/lib/config/versions/magento-2.3.3.js +7 -12
- package/lib/config/versions/magento-2.3.4-p1.js +7 -12
- package/lib/config/versions/magento-2.3.4-p2.js +7 -12
- package/lib/config/versions/magento-2.3.4.js +7 -12
- package/lib/config/versions/magento-2.3.5-p1.js +5 -9
- package/lib/config/versions/magento-2.3.5-p2.js +5 -9
- package/lib/config/versions/magento-2.3.5.js +5 -9
- package/lib/config/versions/magento-2.3.6-p1.js +5 -9
- package/lib/config/versions/magento-2.3.6.js +5 -9
- package/lib/config/versions/magento-2.3.7-p1.js +5 -9
- package/lib/config/versions/magento-2.3.7-p2.js +5 -9
- package/lib/config/versions/magento-2.3.7-p3.js +5 -9
- package/lib/config/versions/magento-2.3.7-p4.js +40 -0
- package/lib/config/versions/magento-2.3.7.js +5 -9
- package/lib/config/versions/magento-2.4.0-p1.js +5 -9
- package/lib/config/versions/magento-2.4.0.js +5 -9
- package/lib/config/versions/magento-2.4.1-p1.js +5 -9
- package/lib/config/versions/magento-2.4.1.js +5 -9
- package/lib/config/versions/magento-2.4.2-p1.js +5 -9
- package/lib/config/versions/magento-2.4.2-p2.js +5 -9
- package/lib/config/versions/magento-2.4.2.js +5 -9
- package/lib/config/versions/magento-2.4.3-p1.js +5 -9
- package/lib/config/versions/magento-2.4.3-p2.js +5 -9
- package/lib/config/versions/magento-2.4.3-p3.js +42 -0
- package/lib/config/versions/magento-2.4.3.js +5 -9
- package/lib/config/versions/magento-2.4.4-p1.js +42 -0
- package/lib/config/versions/magento-2.4.4.js +5 -9
- package/lib/config/versions/magento-2.4.5.js +42 -0
- package/lib/tasks/cleanup.js +1 -1
- package/lib/tasks/composer/local-auth-json.js +1 -1
- package/lib/tasks/database/connect-to-database.js +120 -0
- package/lib/tasks/database/create-magento-database.js +21 -0
- package/lib/tasks/database/create-magento-user.js +50 -0
- package/lib/tasks/database/default-magento-database.js +3 -0
- package/lib/tasks/database/default-magento-user.js +7 -0
- package/lib/tasks/{mysql → database}/dump-theme-config.js +3 -3
- package/lib/tasks/{mysql → database}/fix-db.js +2 -2
- package/lib/tasks/{mysql/import-dump-to-mysql.js → database/import-dump-to-database.js} +21 -20
- package/lib/tasks/{mysql → database}/import-remote-db/index.js +0 -0
- package/lib/tasks/{mysql/import-remote-db/ssh/mysqldump-command.js → database/import-remote-db/ssh/database-dump-command.js} +2 -2
- package/lib/tasks/{mysql → database}/import-remote-db/ssh/index.js +0 -0
- package/lib/tasks/{mysql → database}/import-remote-db/ssh/readymage.js +4 -4
- package/lib/tasks/{mysql → database}/import-remote-db/ssh/regular-server.js +2 -2
- package/lib/tasks/{mysql → database}/index.js +2 -2
- package/lib/tasks/{mysql → database}/magento-tables.js +0 -0
- package/lib/tasks/{mysql → database}/restore-theme-config.js +4 -4
- package/lib/tasks/docker/api.d.ts +25 -1
- package/lib/tasks/docker/api.js +31 -1
- package/lib/tasks/docker/containers/container-api.d.ts +18 -0
- package/lib/tasks/docker/containers/container-api.js +76 -17
- package/lib/tasks/docker/containers/tasks.js +32 -1
- package/lib/tasks/docker/convert-legacy-volumes.js +8 -7
- package/lib/tasks/docker/convert-mysql-to-mariadb.js +284 -0
- package/lib/tasks/docker/index.js +6 -1
- package/lib/tasks/docker/network/network-api.d.ts +1 -1
- package/lib/tasks/docker/project-image-builder.js +7 -9
- package/lib/tasks/docker/volume/index.js +9 -0
- package/lib/tasks/docker/volume/tasks.js +94 -0
- package/lib/tasks/docker/volume/volume-api.d.ts +49 -0
- package/lib/tasks/docker/volume/volume-api.js +90 -0
- package/lib/tasks/execute.js +100 -0
- package/lib/tasks/file-system/create-mariadb-config.js +23 -0
- package/lib/tasks/file-system/create-nginx-config.js +3 -5
- package/lib/tasks/file-system/create-php-config.js +2 -23
- package/lib/tasks/file-system/create-php-debug-config.js +45 -0
- package/lib/tasks/file-system/create-php-fpm-config.js +2 -4
- package/lib/tasks/file-system/create-phpstorm-config/workspace-config/php-workspace-project-configuration-config.js +1 -1
- package/lib/tasks/file-system/create-ssl-terminator-config.js +4 -7
- package/lib/tasks/file-system/create-varnish-config.js +4 -7
- package/lib/tasks/file-system/index.js +5 -1
- package/lib/tasks/import-dump.js +6 -6
- package/lib/tasks/link.js +4 -2
- package/lib/tasks/magento/enable-magento-composer-plugins.js +85 -30
- package/lib/tasks/magento/install-magento-project.js +3 -2
- package/lib/tasks/magento/setup-magento/configure-elasticsearch.js +3 -5
- package/lib/tasks/magento/setup-magento/create-admin.js +1 -1
- package/lib/tasks/magento/setup-magento/delete-admin-users.js +2 -2
- package/lib/tasks/magento/setup-magento/delete-customers.js +4 -4
- package/lib/tasks/magento/setup-magento/delete-orders.js +4 -4
- package/lib/tasks/magento/setup-magento/flush-redis-config.js +3 -6
- package/lib/tasks/magento/setup-magento/increase-admin-session-lifetime.js +2 -2
- package/lib/tasks/magento/setup-magento/index.js +2 -0
- package/lib/tasks/magento/setup-magento/install-magento.js +15 -17
- package/lib/tasks/magento/setup-magento/migrate-database.js +5 -11
- package/lib/tasks/magento/setup-magento/set-base-url.js +3 -3
- package/lib/tasks/magento/setup-magento/set-url-rewrite.js +2 -2
- package/lib/tasks/magento/setup-magento/varnish-config.js +8 -13
- package/lib/tasks/magento/setup-magento/waiting-for-varnish.js +17 -16
- package/lib/tasks/php/php-container.js +7 -3
- package/lib/tasks/php/update-env-php.js +7 -6
- package/lib/tasks/php/update-env.php +12 -12
- package/lib/tasks/requirements/composer-credentials.js +7 -3
- package/lib/tasks/requirements/docker/context.js +88 -0
- package/lib/tasks/requirements/docker/index.js +110 -19
- package/lib/tasks/requirements/docker/install.js +21 -7
- package/lib/tasks/requirements/docker/permissions.js +2 -11
- package/lib/tasks/requirements/docker/running-status.js +94 -24
- package/lib/tasks/requirements/docker/version.js +1 -0
- package/lib/tasks/requirements/index.js +0 -2
- package/lib/tasks/requirements/php-version.js +4 -2
- package/lib/tasks/start.js +32 -31
- package/lib/tasks/status/index.js +17 -13
- package/lib/tasks/stop.js +2 -0
- package/lib/tasks/theme/link-theme.js +2 -2
- package/lib/util/config-file-validator.js +29 -13
- package/lib/util/database.js +7 -7
- package/lib/util/execute-in-container.js +63 -0
- package/lib/util/prefix.js +1 -1
- package/lib/util/systemctl.js +62 -13
- package/package.json +4 -3
- package/typings/context.d.ts +12 -5
- package/typings/index.d.ts +69 -31
- package/lib/tasks/docker/volumes.js +0 -63
- package/lib/tasks/execute/index.js +0 -23
- package/lib/tasks/mysql/connect-to-mysql.js +0 -127
- package/lib/tasks/mysql/create-magento-database.js +0 -18
- package/lib/tasks/requirements/dependency/arch.js +0 -50
- package/lib/tasks/requirements/dependency/centos.js +0 -36
- package/lib/tasks/requirements/dependency/fedora.js +0 -36
- package/lib/tasks/requirements/dependency/index.js +0 -33
- package/lib/tasks/requirements/dependency/mac.js +0 -124
- package/lib/tasks/requirements/dependency/ubuntu.js +0 -83
|
@@ -3,9 +3,9 @@ const { execAsyncSpawn } = require('../../../util/exec-async-command');
|
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @param {import('./container-api').ContainerRunOptions} options
|
|
6
|
-
* @
|
|
6
|
+
* @returns {string[]}
|
|
7
7
|
*/
|
|
8
|
-
const
|
|
8
|
+
const runCommand = (options) => {
|
|
9
9
|
const {
|
|
10
10
|
addHost,
|
|
11
11
|
ports = [],
|
|
@@ -24,32 +24,35 @@ const run = (options, execOptions = {}) => {
|
|
|
24
24
|
expose = [],
|
|
25
25
|
detach = true,
|
|
26
26
|
rm = false,
|
|
27
|
+
tty = false,
|
|
27
28
|
user
|
|
28
29
|
} = options;
|
|
29
30
|
|
|
30
31
|
const detachArg = detach && '-d';
|
|
31
32
|
const rmArg = rm && '--rm';
|
|
33
|
+
const ttyArg = tty && '-it';
|
|
32
34
|
const exposeArg = expose && expose.map((e) => `--expose=${ e }`);
|
|
33
|
-
const restartArg = !rm && restart && `--restart
|
|
34
|
-
const networkArg = network && `--network
|
|
35
|
-
const portsArgs = ports.map((port) => `-p
|
|
36
|
-
const mountsArgs = mounts.map((mount) => `--mount
|
|
37
|
-
const mountVolumesArgs = mountVolumes.map((mount) => `-v
|
|
38
|
-
const envArgs = !env ? '' : Object.entries(env).map(([key, value]) => `--env
|
|
39
|
-
const nameArg = name && `--name
|
|
40
|
-
const entrypointArg = entrypoint && `--entrypoint
|
|
41
|
-
const healthCheckArg = healthCheck && Object.entries(healthCheck).map(([key, value]) => `--health-${key}
|
|
42
|
-
const securityArg = securityOptions.length > 0 && securityOptions.map((opt) => `--security-opt
|
|
43
|
-
const tmpfsArg = tmpfs.length > 0 && tmpfs.map((t) => `--tmpfs
|
|
35
|
+
const restartArg = !rm && restart && `--restart=${ restart }`;
|
|
36
|
+
const networkArg = network && `--network=${ network }`;
|
|
37
|
+
const portsArgs = ports && ports.length > 0 && ports.map((port) => `-p=${ port }`).join(' ');
|
|
38
|
+
const mountsArgs = mounts && mounts.map((mount) => `--mount=${ mount }`).join(' ');
|
|
39
|
+
const mountVolumesArgs = mountVolumes && mountVolumes.map((mount) => `-v=${mount}`).join(' ');
|
|
40
|
+
const envArgs = !env ? '' : Object.entries(env).map(([key, value]) => `--env=${ key }='${ value }'`).join(' ');
|
|
41
|
+
const nameArg = name && `--name=${name}`;
|
|
42
|
+
const entrypointArg = entrypoint && `--entrypoint="${entrypoint}"`;
|
|
43
|
+
const healthCheckArg = healthCheck && Object.entries(healthCheck).map(([key, value]) => `--health-${key}='${value}'`).join(' ');
|
|
44
|
+
const securityArg = securityOptions.length > 0 && securityOptions.map((opt) => `--security-opt=${opt}`).join(' ');
|
|
45
|
+
const tmpfsArg = tmpfs.length > 0 && tmpfs.map((t) => `--tmpfs=${t}`).join(' ');
|
|
44
46
|
const userArg = user && `--user=${user}`;
|
|
45
47
|
const addHostArg = addHost && `--add-host=${addHost}`;
|
|
46
48
|
|
|
47
49
|
const dockerCommand = [
|
|
48
50
|
'docker',
|
|
49
51
|
'run',
|
|
52
|
+
nameArg,
|
|
53
|
+
ttyArg,
|
|
50
54
|
detachArg,
|
|
51
55
|
rmArg,
|
|
52
|
-
nameArg,
|
|
53
56
|
networkArg,
|
|
54
57
|
restartArg,
|
|
55
58
|
portsArgs,
|
|
@@ -65,11 +68,17 @@ const run = (options, execOptions = {}) => {
|
|
|
65
68
|
addHostArg,
|
|
66
69
|
image,
|
|
67
70
|
command
|
|
68
|
-
].filter(Boolean).
|
|
71
|
+
].filter(Boolean).filter((arg) => typeof arg === 'string');
|
|
69
72
|
|
|
70
|
-
return
|
|
73
|
+
return dockerCommand;
|
|
71
74
|
};
|
|
72
75
|
|
|
76
|
+
/**
|
|
77
|
+
* @param {import('./container-api').ContainerRunOptions} options
|
|
78
|
+
* @param {import('../../../util/exec-async-command').ExecAsyncSpawnOptions<false>} execOptions
|
|
79
|
+
*/
|
|
80
|
+
const run = (options, execOptions = {}) => execAsyncSpawn(runCommand(options).join(' '), execOptions);
|
|
81
|
+
|
|
73
82
|
/**
|
|
74
83
|
* @param {string} command
|
|
75
84
|
* @param {string} container container id or name
|
|
@@ -140,14 +149,64 @@ const ls = async (options = {}, execOptions = {}) => {
|
|
|
140
149
|
|
|
141
150
|
if (formatToJSON) {
|
|
142
151
|
const result = await execAsyncSpawn(`docker container ls ${args}`, execOptions);
|
|
152
|
+
if (result.startsWith('[')) {
|
|
153
|
+
return JSON.parse(result);
|
|
154
|
+
}
|
|
155
|
+
|
|
143
156
|
return JSON.parse(`[${result.split('\n').join(', ')}]`);
|
|
144
157
|
}
|
|
145
158
|
|
|
146
159
|
return execAsyncSpawn(`docker container ls ${args}`, execOptions);
|
|
147
160
|
};
|
|
148
161
|
|
|
162
|
+
/**
|
|
163
|
+
* @param {import('./container-api').ContainerLogsOptions} options
|
|
164
|
+
* @param {import('../../../util/exec-async-command').ExecAsyncSpawnOptions<false>} execOptions
|
|
165
|
+
*/
|
|
166
|
+
const logs = async (options = {}, execOptions = {}) => {
|
|
167
|
+
const {
|
|
168
|
+
name,
|
|
169
|
+
details = false,
|
|
170
|
+
follow = false,
|
|
171
|
+
since = '',
|
|
172
|
+
tail = '',
|
|
173
|
+
timestamps = false,
|
|
174
|
+
until = '',
|
|
175
|
+
parser
|
|
176
|
+
} = options;
|
|
177
|
+
const detailsArg = details && '--details';
|
|
178
|
+
const followArg = follow && '--follow';
|
|
179
|
+
const sinceArg = since && `--since=${since}`;
|
|
180
|
+
const tailArg = tail && `--tail=${tail}`;
|
|
181
|
+
const timestampsArg = timestamps && '--timestamps';
|
|
182
|
+
const untilArg = until && `--until=${until}`;
|
|
183
|
+
|
|
184
|
+
const logsCommand = [
|
|
185
|
+
'docker',
|
|
186
|
+
'container',
|
|
187
|
+
'logs',
|
|
188
|
+
detailsArg,
|
|
189
|
+
followArg,
|
|
190
|
+
sinceArg,
|
|
191
|
+
tailArg,
|
|
192
|
+
timestampsArg,
|
|
193
|
+
untilArg,
|
|
194
|
+
name
|
|
195
|
+
].filter(Boolean).join(' ');
|
|
196
|
+
|
|
197
|
+
if (parser) {
|
|
198
|
+
const result = await execAsyncSpawn(logsCommand, execOptions);
|
|
199
|
+
|
|
200
|
+
return result.split('\n').map((line) => parser(line));
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return execAsyncSpawn(logsCommand, execOptions);
|
|
204
|
+
};
|
|
205
|
+
|
|
149
206
|
module.exports = {
|
|
150
207
|
run,
|
|
208
|
+
runCommand,
|
|
151
209
|
exec,
|
|
152
|
-
ls
|
|
210
|
+
ls,
|
|
211
|
+
logs
|
|
153
212
|
};
|
|
@@ -26,8 +26,39 @@ const remoteImageReducer = (acc, val) => {
|
|
|
26
26
|
*/
|
|
27
27
|
const pullImages = () => ({
|
|
28
28
|
title: 'Pulling container images',
|
|
29
|
-
task: async ({ config: { docker } }, task) => {
|
|
29
|
+
task: async ({ config: { docker }, pullImages }, task) => {
|
|
30
30
|
const containers = Object.values(docker.getContainers());
|
|
31
|
+
|
|
32
|
+
if (pullImages) {
|
|
33
|
+
return task.newListr(
|
|
34
|
+
containers
|
|
35
|
+
.reduce(remoteImageReducer, [])
|
|
36
|
+
.map((image) => {
|
|
37
|
+
const [repo, tag = 'latest'] = image.split(':');
|
|
38
|
+
|
|
39
|
+
return { repo, tag };
|
|
40
|
+
})
|
|
41
|
+
.reduce(
|
|
42
|
+
(acc, val) => acc.concat(
|
|
43
|
+
acc.some(
|
|
44
|
+
(c) => c.repo === val.repo
|
|
45
|
+
&& c.tag === val.tag
|
|
46
|
+
)
|
|
47
|
+
? []
|
|
48
|
+
: val
|
|
49
|
+
),
|
|
50
|
+
[]
|
|
51
|
+
)
|
|
52
|
+
.map(({ repo, tag }) => ({
|
|
53
|
+
title: `Pulling ${ logger.style.file(`${repo}:${tag}`) } image`,
|
|
54
|
+
task: () => pull(`${repo}:${tag}`)
|
|
55
|
+
})), {
|
|
56
|
+
concurrent: true,
|
|
57
|
+
exitOnError: true
|
|
58
|
+
}
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
31
62
|
const imagesFilter = containers
|
|
32
63
|
.reduce(remoteImageReducer, [])
|
|
33
64
|
.map((image) => `reference='${image}'`);
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
/* eslint-disable no-param-reassign */
|
|
1
2
|
/* eslint-disable max-len */
|
|
2
3
|
const { stopServices } = require('./index');
|
|
3
4
|
const { getBaseConfig, getConfigFromMagentoVersion } = require('../../config');
|
|
4
5
|
const getDockerConfig = require('../../config/docker');
|
|
5
6
|
const { execAsyncSpawn } = require('../../util/exec-async-command');
|
|
6
7
|
const { folderName, legacyFolderName } = require('../../util/prefix');
|
|
7
|
-
const {
|
|
8
|
+
const { volumeApi } = require('./volume');
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
|
|
@@ -14,20 +15,20 @@ const convertLegacyVolumes = () => ({
|
|
|
14
15
|
const { config: { overridenConfiguration } } = ctx;
|
|
15
16
|
const newDockerConfig = await getDockerConfig(ctx, overridenConfiguration, getBaseConfig(process.cwd(), folderName));
|
|
16
17
|
|
|
17
|
-
const newVolumeNames = Object.values(newDockerConfig.volumes).filter((v) => !v.
|
|
18
|
+
const newVolumeNames = Object.values(newDockerConfig.volumes).filter((v) => !v.opt).map(({ name }) => name);
|
|
18
19
|
|
|
19
|
-
const existingVolumes =
|
|
20
|
+
const existingVolumes = await volumeApi.ls({ formatToJSON: true });
|
|
20
21
|
|
|
21
22
|
if (newVolumeNames.every((v) => existingVolumes.includes(v))) {
|
|
22
23
|
return;
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
const legacyDockerConfig = await getDockerConfig(ctx, overridenConfiguration, getBaseConfig(process.cwd(), legacyFolderName));
|
|
26
|
-
const legacyVolumeNames = Object.values(legacyDockerConfig.volumes).filter((v) => !v.
|
|
27
|
+
const legacyVolumeNames = Object.values(legacyDockerConfig.volumes).filter((v) => !v.opt).map(({ name }) => name);
|
|
27
28
|
|
|
28
29
|
if (
|
|
29
|
-
newVolumeNames.every((name) => !existingVolumes.
|
|
30
|
-
&& legacyVolumeNames.every((name) => existingVolumes.
|
|
30
|
+
newVolumeNames.every((name) => !existingVolumes.some((v) => v.Name === name))
|
|
31
|
+
&& legacyVolumeNames.every((name) => existingVolumes.some((v) => v.Name === name))
|
|
31
32
|
) {
|
|
32
33
|
ctx.config = await getConfigFromMagentoVersion(ctx, {
|
|
33
34
|
magentoVersion: ctx.magentoVersion,
|
|
@@ -46,7 +47,7 @@ const convertLegacyVolumes = () => ({
|
|
|
46
47
|
const legacyVolumeConfig = legacyDockerConfig.volumes[volumeName];
|
|
47
48
|
|
|
48
49
|
subTask.output = `Creating volume ${volumeConfig.name}...`;
|
|
49
|
-
await
|
|
50
|
+
await volumeApi.create(volumeConfig);
|
|
50
51
|
subTask.output = `Copying data from ${legacyVolumeConfig.name} to ${volumeConfig.name}...`;
|
|
51
52
|
await execAsyncSpawn(
|
|
52
53
|
`docker run --rm -v ${legacyVolumeConfig.name}:/from:ro -v ${volumeConfig.name}:/to alpine ash -c "cd /from; cp -av . /to"`, {
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const logger = require('@scandipwa/scandipwa-dev-utils/logger');
|
|
4
|
+
const { volumeApi, createVolumes } = require('./volume');
|
|
5
|
+
const { execAsyncSpawn } = require('../../util/exec-async-command');
|
|
6
|
+
const { containerApi, stopContainers, pullImages } = require('./containers');
|
|
7
|
+
const { importDumpToDatabase, connectToDatabase } = require('../database');
|
|
8
|
+
const { setPrefix } = require('../prefix');
|
|
9
|
+
const getProjectConfiguration = require('../../config/get-project-configuration');
|
|
10
|
+
const { getAvailablePorts, getCachedPorts } = require('../../config/get-port-config');
|
|
11
|
+
const { saveConfiguration } = require('../../config/save-config');
|
|
12
|
+
const { buildProjectImage, buildDebugProjectImage } = require('./project-image-builder');
|
|
13
|
+
const checkPHPVersion = require('../requirements/php-version');
|
|
14
|
+
const { getComposerVersionTask } = require('../composer');
|
|
15
|
+
const { prepareFileSystem } = require('../file-system');
|
|
16
|
+
const { installMagentoProject } = require('../magento');
|
|
17
|
+
const enableMagentoComposerPlugins = require('../magento/enable-magento-composer-plugins');
|
|
18
|
+
const { startServices } = require('./index');
|
|
19
|
+
const dockerNetwork = require('./network');
|
|
20
|
+
const KnownError = require('../../errors/known-error');
|
|
21
|
+
const { createCacheFolder } = require('../cache');
|
|
22
|
+
const { getSystemConfigTask } = require('../../config/system-config');
|
|
23
|
+
const sleep = require('../../util/sleep');
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
|
|
27
|
+
*/
|
|
28
|
+
const convertMySQLDatabaseToMariaDB = () => ({
|
|
29
|
+
task: async (ctx, task) => {
|
|
30
|
+
const mysqlVolumeName = `${ ctx.config.baseConfig.prefix }_mysql-data`;
|
|
31
|
+
const volumes = await volumeApi.ls({ formatToJSON: true });
|
|
32
|
+
if (ctx.isArmMac) {
|
|
33
|
+
if (volumes.some(
|
|
34
|
+
(volume) => volume.Name === mysqlVolumeName
|
|
35
|
+
) && !volumes.some(
|
|
36
|
+
(volume) => volume.Name === ctx.config.docker.volumes.mariadb.name
|
|
37
|
+
)
|
|
38
|
+
) {
|
|
39
|
+
task.title = 'Converting MySQL database to MariaDB';
|
|
40
|
+
return task.newListr([
|
|
41
|
+
stopContainers(),
|
|
42
|
+
{
|
|
43
|
+
title: 'Converting MySQL volume to MariaDB',
|
|
44
|
+
task: async (subCtx, subTask) => {
|
|
45
|
+
subTask.output = `Creating volume ${subCtx.config.docker.volumes.mariadb.name}...`;
|
|
46
|
+
await volumeApi.create(subCtx.config.docker.volumes.mariadb);
|
|
47
|
+
subTask.output = `Copying data from ${mysqlVolumeName} to ${subCtx.config.docker.volumes.mariadb.name}...`;
|
|
48
|
+
await execAsyncSpawn(
|
|
49
|
+
// eslint-disable-next-line max-len
|
|
50
|
+
`docker run --rm -v ${mysqlVolumeName}:/from:ro -v ${subCtx.config.docker.volumes.mariadb.name}:/to alpine ash -c "cd /from; cp -av . /to"`, {
|
|
51
|
+
callback: (t) => {
|
|
52
|
+
subTask.output = t;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
);
|
|
56
|
+
subTask.output = 'Deleting old volume...';
|
|
57
|
+
await execAsyncSpawn(`docker volume rm ${mysqlVolumeName}`);
|
|
58
|
+
},
|
|
59
|
+
options: {
|
|
60
|
+
bottomBar: 10
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
]);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (volumes.some(
|
|
70
|
+
(volume) => volume.Name === mysqlVolumeName
|
|
71
|
+
) && !volumes.some(
|
|
72
|
+
(volume) => volume.Name === ctx.config.docker.volumes.mariadb.name
|
|
73
|
+
)
|
|
74
|
+
) {
|
|
75
|
+
task.title = 'Converting MySQL database to MariaDB';
|
|
76
|
+
const confirmConvert = await task.prompt({
|
|
77
|
+
type: 'Select',
|
|
78
|
+
message: `We see that you have old mysql-data volume in the project!
|
|
79
|
+
Since ${logger.style.code('magento-scripts@2.0.0')} ${logger.style.misc('MariaDB')} is used as database instead of MySQL.
|
|
80
|
+
|
|
81
|
+
To use MariaDB with data from MySQL we need to convert your database.
|
|
82
|
+
`,
|
|
83
|
+
choices: [
|
|
84
|
+
{
|
|
85
|
+
name: 'yes',
|
|
86
|
+
message: 'Okay, let\'s do that!'
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: 'no',
|
|
90
|
+
message: 'ABORT ABORT ABORT'
|
|
91
|
+
}
|
|
92
|
+
]
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
if (confirmConvert === 'yes') {
|
|
96
|
+
const pathToMySQLDumpFile = path.join(process.cwd(), 'mysql-database.sql');
|
|
97
|
+
const containerName = 'mysql-database';
|
|
98
|
+
task.output = 'Creating dump file from MySQL database...';
|
|
99
|
+
|
|
100
|
+
const existingContainers = await containerApi.ls({ formatToJSON: true, all: true });
|
|
101
|
+
|
|
102
|
+
if (existingContainers.some((c) => c.Names === containerName)) {
|
|
103
|
+
await execAsyncSpawn(`docker container stop ${containerName}`);
|
|
104
|
+
await execAsyncSpawn(`docker container rm ${containerName}`);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
task.output = 'Starting MySQL server...';
|
|
108
|
+
|
|
109
|
+
await containerApi.run(
|
|
110
|
+
{
|
|
111
|
+
mounts: [
|
|
112
|
+
`source=${ mysqlVolumeName },target=/var/lib/mysql`
|
|
113
|
+
],
|
|
114
|
+
env: {
|
|
115
|
+
MYSQL_PORT: 3306,
|
|
116
|
+
MYSQL_ROOT_PASSWORD: 'scandipwa',
|
|
117
|
+
MYSQL_USER: 'magento',
|
|
118
|
+
MYSQL_PASSWORD: 'magento',
|
|
119
|
+
MYSQL_DATABASE: 'magento'
|
|
120
|
+
},
|
|
121
|
+
command: [
|
|
122
|
+
'--log_bin_trust_function_creators=1',
|
|
123
|
+
'--default-authentication-plugin=mysql_native_password',
|
|
124
|
+
'--max_allowed_packet=1GB',
|
|
125
|
+
'--bind-address=0.0.0.0'
|
|
126
|
+
]
|
|
127
|
+
.join(' '),
|
|
128
|
+
securityOptions: [
|
|
129
|
+
'seccomp=unconfined'
|
|
130
|
+
],
|
|
131
|
+
name: containerName,
|
|
132
|
+
image: `mysql:${ ctx.config.overridenConfiguration.configuration.mysql.version }`
|
|
133
|
+
}
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
task.output = 'Waiting for MySQL to initialize...';
|
|
137
|
+
|
|
138
|
+
let mysqlReadyForConnections = false;
|
|
139
|
+
|
|
140
|
+
while (!mysqlReadyForConnections) {
|
|
141
|
+
const mysqlOutput = await execAsyncSpawn(`docker logs ${containerName}`);
|
|
142
|
+
if (mysqlOutput.includes('ready for connections')) {
|
|
143
|
+
mysqlReadyForConnections = true;
|
|
144
|
+
task.output = 'MySQL is ready!';
|
|
145
|
+
break;
|
|
146
|
+
} else if (mysqlOutput.includes('Initializing database files')) {
|
|
147
|
+
task.output = `MySQL is initializing database files!
|
|
148
|
+
Please wait, this will take some time and do not restart the MySQL container until initialization is finished!`;
|
|
149
|
+
|
|
150
|
+
let mysqlFinishedInitialization = false;
|
|
151
|
+
while (!mysqlFinishedInitialization) {
|
|
152
|
+
const mysqlOutput = await execAsyncSpawn(`docker logs ${containerName}`);
|
|
153
|
+
if (mysqlOutput.includes('init process done.') && !mysqlFinishedInitialization) {
|
|
154
|
+
mysqlFinishedInitialization = true;
|
|
155
|
+
task.output = 'MySQL is initialized!';
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
await sleep(2000);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
await sleep(2000);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
task.output = 'Dumping MySQL database to dump file...';
|
|
166
|
+
|
|
167
|
+
await containerApi.exec(
|
|
168
|
+
[
|
|
169
|
+
'mysqldump',
|
|
170
|
+
'--user=root',
|
|
171
|
+
'--password=scandipwa',
|
|
172
|
+
'magento',
|
|
173
|
+
`--result-file=${ path.parse(pathToMySQLDumpFile).base }`
|
|
174
|
+
].join(' '),
|
|
175
|
+
containerName,
|
|
176
|
+
{},
|
|
177
|
+
{
|
|
178
|
+
callback: (t) => {
|
|
179
|
+
task.output = t;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
task.output = 'Copying dump file from container to system...';
|
|
185
|
+
|
|
186
|
+
await execAsyncSpawn(
|
|
187
|
+
`docker cp ${containerName}:/${ path.parse(pathToMySQLDumpFile).base } ${ pathToMySQLDumpFile }`
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
task.output = 'Removing migration container...';
|
|
191
|
+
|
|
192
|
+
await execAsyncSpawn(
|
|
193
|
+
`docker container stop ${containerName}`
|
|
194
|
+
);
|
|
195
|
+
await execAsyncSpawn(
|
|
196
|
+
`docker container rm ${containerName}`
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
ctx.importDb = pathToMySQLDumpFile;
|
|
200
|
+
|
|
201
|
+
return task.newListr([
|
|
202
|
+
createCacheFolder(),
|
|
203
|
+
getSystemConfigTask(),
|
|
204
|
+
getCachedPorts(),
|
|
205
|
+
stopContainers(),
|
|
206
|
+
setPrefix(),
|
|
207
|
+
getProjectConfiguration(),
|
|
208
|
+
// get fresh ports
|
|
209
|
+
getAvailablePorts(),
|
|
210
|
+
saveConfiguration(),
|
|
211
|
+
pullImages(),
|
|
212
|
+
dockerNetwork.tasks.createNetwork(),
|
|
213
|
+
createVolumes(),
|
|
214
|
+
{
|
|
215
|
+
task: (ctx, task) => task.newListr([
|
|
216
|
+
buildProjectImage(),
|
|
217
|
+
buildDebugProjectImage()
|
|
218
|
+
], {
|
|
219
|
+
concurrent: true
|
|
220
|
+
})
|
|
221
|
+
},
|
|
222
|
+
checkPHPVersion(),
|
|
223
|
+
getComposerVersionTask(),
|
|
224
|
+
prepareFileSystem(),
|
|
225
|
+
installMagentoProject(),
|
|
226
|
+
enableMagentoComposerPlugins(),
|
|
227
|
+
startServices(),
|
|
228
|
+
connectToDatabase(),
|
|
229
|
+
importDumpToDatabase(),
|
|
230
|
+
{
|
|
231
|
+
task: async (subCtx, subTask) => {
|
|
232
|
+
const confirmDeleteOldVolume = await subTask.prompt({
|
|
233
|
+
type: 'Select',
|
|
234
|
+
message: 'Okay, looks like conversion went well, do you want to delete old mysql-data volume?',
|
|
235
|
+
choices: [
|
|
236
|
+
{
|
|
237
|
+
name: 'yes',
|
|
238
|
+
message: 'Sure'
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
name: 'no',
|
|
242
|
+
message: 'No, I want to keep it'
|
|
243
|
+
}
|
|
244
|
+
]
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
if (confirmDeleteOldVolume === 'yes') {
|
|
248
|
+
await execAsyncSpawn(`docker volume rm ${ mysqlVolumeName }`);
|
|
249
|
+
|
|
250
|
+
const confirmDeleteDump = await subTask.prompt({
|
|
251
|
+
type: 'Select',
|
|
252
|
+
message: `Last question for today.
|
|
253
|
+
Do you want to keep database dump created during conversion process? (${logger.style.file(pathToMySQLDumpFile)})`,
|
|
254
|
+
choices: [
|
|
255
|
+
{
|
|
256
|
+
name: 'yes',
|
|
257
|
+
message: 'I don\'t need it, thanks'
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
name: 'no',
|
|
261
|
+
message: 'I would like to keep it, thanks'
|
|
262
|
+
}
|
|
263
|
+
]
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
if (confirmDeleteDump === 'yes') {
|
|
267
|
+
await fs.promises.rm(pathToMySQLDumpFile);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
]);
|
|
273
|
+
}
|
|
274
|
+
throw new KnownError('ABORTING');
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
task.skip();
|
|
278
|
+
},
|
|
279
|
+
options: {
|
|
280
|
+
bottomBar: 10
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
module.exports = convertMySQLDatabaseToMariaDB;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
const containers = require('./containers');
|
|
2
2
|
const network = require('./network');
|
|
3
|
+
const volume = require('./volume');
|
|
4
|
+
const dockerApi = require('./api');
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
7
|
* @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
|
|
@@ -19,13 +21,16 @@ const startServices = () => ({
|
|
|
19
21
|
* @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
|
|
20
22
|
*/
|
|
21
23
|
const stopServices = () => ({
|
|
24
|
+
title: 'Stopping Docker services',
|
|
22
25
|
task: (ctx, task) => task.newListr([
|
|
23
26
|
containers.stopContainers(),
|
|
27
|
+
volume.removeLocalVolumes(),
|
|
24
28
|
network.tasks.removeNetwork()
|
|
25
29
|
])
|
|
26
30
|
});
|
|
27
31
|
|
|
28
32
|
module.exports = {
|
|
29
33
|
startServices,
|
|
30
|
-
stopServices
|
|
34
|
+
stopServices,
|
|
35
|
+
dockerApi
|
|
31
36
|
};
|
|
@@ -27,13 +27,13 @@ const getEnabledExtensionsFromImage = async (imageWithTag) => {
|
|
|
27
27
|
.reduce((acc, [name, version]) => ({ ...acc, [name]: version }), {});
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
-
const addExtensionToBuilder = (builder, ctx) => ([extensionName, extensionInstructions]) => {
|
|
30
|
+
const addExtensionToBuilder = (builder, ctx) => async ([extensionName, extensionInstructions]) => {
|
|
31
31
|
const { command, ...extensionInstructionsWithoutCommand } = extensionInstructions;
|
|
32
32
|
let runCommand = '';
|
|
33
33
|
if (typeof command === 'string') {
|
|
34
34
|
runCommand += ` ${command}`;
|
|
35
|
-
} else if (typeof command === 'function') {
|
|
36
|
-
runCommand += ` ${command({ ...extensionInstructionsWithoutCommand, ctx })}`;
|
|
35
|
+
} else if (typeof command === 'function' || command instanceof Promise) {
|
|
36
|
+
runCommand += ` ${await Promise.resolve(command({ ...extensionInstructionsWithoutCommand, ctx }))}`;
|
|
37
37
|
} else {
|
|
38
38
|
runCommand += ` docker-php-ext-install ${extensionInstructionsWithoutCommand.name}`;
|
|
39
39
|
}
|
|
@@ -68,10 +68,6 @@ const buildDockerFileInstructions = async (ctx, { image, tag }) => {
|
|
|
68
68
|
.comment('project image')
|
|
69
69
|
.from({ image, tag });
|
|
70
70
|
|
|
71
|
-
// install bash in image
|
|
72
|
-
dockerFileInstructions
|
|
73
|
-
.run('apk add --no-cache bash');
|
|
74
|
-
|
|
75
71
|
if (missingExtensions.length > 0) {
|
|
76
72
|
const allDependencies = missingExtensions.map(
|
|
77
73
|
([_extensionName, extensionInstructions]) => (extensionInstructions.dependencies || [])
|
|
@@ -79,7 +75,9 @@ const buildDockerFileInstructions = async (ctx, { image, tag }) => {
|
|
|
79
75
|
.reduce((acc, val) => acc.concat(val.filter((ex) => !acc.includes(ex))), []);
|
|
80
76
|
|
|
81
77
|
dockerFileInstructions.run(`apk add --no-cache ${allDependencies.join(' ')}`);
|
|
82
|
-
|
|
78
|
+
for (const missingExtensionInstructions of missingExtensions) {
|
|
79
|
+
await addExtensionToBuilder(dockerFileInstructions, ctx)(missingExtensionInstructions);
|
|
80
|
+
}
|
|
83
81
|
}
|
|
84
82
|
|
|
85
83
|
const composerVersion = /^\d$/.test(composer.version)
|
|
@@ -101,7 +99,7 @@ const buildDockerFileInstructions = async (ctx, { image, tag }) => {
|
|
|
101
99
|
}
|
|
102
100
|
|
|
103
101
|
dockerFileInstructions
|
|
104
|
-
.workDir(
|
|
102
|
+
.workDir(ctx.config.baseConfig.containerMagentoDir);
|
|
105
103
|
|
|
106
104
|
return dockerFileInstructions;
|
|
107
105
|
};
|