@scandipwa/magento-scripts 2.4.10-alpha.0 → 2.4.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/lib/commands/cli.js +25 -9
- package/lib/commands/execute.js +18 -4
- package/lib/config/docker.js +17 -12
- package/lib/config/magento/required-php-extensions/magento-2.4.js +1 -0
- package/lib/config/php-config.js +2 -1
- package/lib/config/services/composer/versions/composer-1.js +1 -1
- package/lib/config/services/composer/versions/composer-2.9.js +8 -0
- package/lib/config/services/composer/versions/index.js +2 -1
- package/lib/config/services/elasticsearch/versions/elasticsearch-6.8.js +4 -4
- package/lib/config/services/elasticsearch/versions/elasticsearch-7.6.js +2 -1
- package/lib/config/services/mariadb/versions/index.js +2 -1
- package/lib/config/services/mariadb/versions/mariadb-11.8.js +11 -0
- package/lib/config/services/nginx/versions/nginx-1.18.js +2 -1
- package/lib/config/services/nginx/versions/nginx-1.22.js +2 -1
- package/lib/config/services/nginx/versions/nginx-1.24.js +2 -1
- package/lib/config/services/nginx/versions/nginx-1.26.js +2 -1
- package/lib/config/services/nginx/versions/nginx-1.28.js +3 -2
- package/lib/config/services/php/versions/php-8.1.js +1 -1
- package/lib/config/services/php/versions/php-8.2.js +1 -1
- package/lib/config/services/php/versions/php-8.3.js +1 -1
- package/lib/config/services/php/versions/php-8.4.js +1 -1
- package/lib/config/services/php/versions/php-8.5.js +32 -0
- package/lib/config/services/redis/index.js +3 -1
- package/lib/config/services/redis/valkey-9.0.js +8 -0
- package/lib/config/services/varnish/index.js +2 -1
- package/lib/config/services/varnish/varnish-8-0.js +15 -0
- package/lib/config/templates/magentorc.template +1 -0
- package/lib/config/templates/nginx.template.conf +1 -1
- package/lib/config/versions/magento-2.4.4-p16.js +1 -1
- package/lib/config/versions/magento-2.4.4-p17.js +41 -0
- package/lib/config/versions/magento-2.4.4-p18.js +43 -0
- package/lib/config/versions/magento-2.4.5-p16.js +41 -0
- package/lib/config/versions/magento-2.4.5-p17.js +43 -0
- package/lib/config/versions/magento-2.4.6-p14.js +41 -0
- package/lib/config/versions/magento-2.4.6-p15.js +43 -0
- package/lib/config/versions/magento-2.4.7-p1.js +2 -2
- package/lib/config/versions/magento-2.4.7-p10.js +42 -0
- package/lib/config/versions/magento-2.4.7-p2.js +2 -2
- package/lib/config/versions/magento-2.4.7-p3.js +2 -2
- package/lib/config/versions/magento-2.4.7-p4.js +2 -2
- package/lib/config/versions/magento-2.4.7-p5.js +2 -2
- package/lib/config/versions/magento-2.4.7-p6.js +2 -2
- package/lib/config/versions/magento-2.4.7-p7.js +2 -2
- package/lib/config/versions/magento-2.4.7-p8.js +2 -2
- package/lib/config/versions/magento-2.4.7-p9.js +41 -0
- package/lib/config/versions/magento-2.4.7.js +2 -2
- package/lib/config/versions/magento-2.4.8-p1.js +2 -2
- package/lib/config/versions/magento-2.4.8-p2.js +2 -2
- package/lib/config/versions/magento-2.4.8-p3.js +2 -3
- package/lib/config/versions/magento-2.4.8-p4.js +42 -0
- package/lib/config/versions/magento-2.4.8-p5.js +42 -0
- package/lib/config/versions/magento-2.4.8.js +2 -2
- package/lib/config/versions/magento-2.4.9-beta1.js +41 -0
- package/lib/config/versions/magento-2.4.9.js +44 -0
- package/lib/tasks/docker/containers/container-api.d.ts +4 -4
- package/lib/tasks/docker/containers/container-api.js +2 -2
- package/lib/tasks/docker/containers/tasks.js +31 -18
- package/lib/tasks/docker/image/image-api.d.ts +12 -0
- package/lib/tasks/docker/image/image-api.js +22 -1
- package/lib/tasks/docker/project-image-builder.js +25 -13
- package/lib/tasks/execute.js +51 -7
- package/lib/tasks/magento/setup-magento/clear-logs.js +31 -0
- package/lib/tasks/magento/setup-magento/disable-2fa.js +13 -0
- package/lib/tasks/magento/setup-magento/index.js +29 -1
- package/lib/tasks/magento/setup-magento/set-base-url.js +42 -15
- package/lib/tasks/magento/setup-magento/urn-highlighter.js +84 -2
- package/lib/tasks/requirements/searchengine-version.js +25 -30
- package/lib/tasks/start.js +9 -5
- package/lib/util/config-file-validator.js +15 -7
- package/lib/util/execute-in-container.js +88 -6
- package/lib/util/instance-metadata.js +15 -9
- package/lib/util/open-browser.js +7 -0
- package/lib/util/wait-for-logs.js +5 -2
- package/package.json +2 -2
- package/typings/context.d.ts +4 -2
- package/typings/index.d.ts +22 -0
- package/lib/config/services/elasticsearch/base-repo.js +0 -3
|
@@ -70,10 +70,10 @@ export interface ContainerExecOptions {
|
|
|
70
70
|
interactive?: boolean
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
export function exec<T>(
|
|
73
|
+
export function exec<T extends boolean = false>(
|
|
74
74
|
options: ContainerExecOptions,
|
|
75
75
|
execOptions?: ExecAsyncSpawnOptions<T>
|
|
76
|
-
): Promise<string>
|
|
76
|
+
): Promise<T extends true ? { code: number; result: string } : string>
|
|
77
77
|
|
|
78
78
|
export function execCommand(options: ContainerExecOptions): string[]
|
|
79
79
|
|
|
@@ -168,10 +168,10 @@ export interface ContainerRunOptions {
|
|
|
168
168
|
platform?: string
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
-
export function run<T>(
|
|
171
|
+
export function run<T extends boolean = false>(
|
|
172
172
|
containerOptions: ContainerRunOptions,
|
|
173
173
|
execOptions?: ExecAsyncSpawnOptions<T>
|
|
174
|
-
): Promise<string>
|
|
174
|
+
): Promise<T extends true ? { code: number; result: string } : string>
|
|
175
175
|
|
|
176
176
|
export function runCommand(options: ContainerRunOptions): string[]
|
|
177
177
|
|
|
@@ -16,9 +16,9 @@ const transformEnvValue = (value) => {
|
|
|
16
16
|
|
|
17
17
|
for (const [key, val] of Object.entries(value)) {
|
|
18
18
|
if (typeof val === 'string' && val) {
|
|
19
|
-
envArguments.push(`--env
|
|
19
|
+
envArguments.push(`--env=${key}='${val.replaceAll("'", "\\'")}'`)
|
|
20
20
|
} else if (String(val)) {
|
|
21
|
-
envArguments.push(`--env
|
|
21
|
+
envArguments.push(`--env=${key}=${val}`)
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
|
|
@@ -16,23 +16,28 @@ const stopAndRemoveContainers = async (containers) => {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
|
-
* @param {string}
|
|
20
|
-
|
|
21
|
-
const pull = async (image) => execAsyncSpawn(`docker pull ${image}`)
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* @param {string[]} acc
|
|
25
|
-
* @param {{ remoteImages?: string[], image: string }} val
|
|
19
|
+
* @param {{ image: string, platform?: string }[]} acc
|
|
20
|
+
* @param {{ remoteImages?: string[], image: string, platform?: string }} val
|
|
26
21
|
*/
|
|
27
22
|
const remoteImageReducer = (acc, val) => {
|
|
28
23
|
if (
|
|
29
24
|
Array.isArray(val.remoteImages) &&
|
|
30
25
|
val.remoteImages.every((image) => typeof image === 'string')
|
|
31
26
|
) {
|
|
32
|
-
return acc.concat(
|
|
27
|
+
return acc.concat(
|
|
28
|
+
val.remoteImages.map((image) => ({
|
|
29
|
+
image,
|
|
30
|
+
platform: val.platform
|
|
31
|
+
}))
|
|
32
|
+
)
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
return acc.concat([
|
|
35
|
+
return acc.concat([
|
|
36
|
+
{
|
|
37
|
+
image: val.image,
|
|
38
|
+
platform: val.platform
|
|
39
|
+
}
|
|
40
|
+
])
|
|
36
41
|
}
|
|
37
42
|
|
|
38
43
|
/**
|
|
@@ -59,10 +64,10 @@ const pullImages = () => ({
|
|
|
59
64
|
containers
|
|
60
65
|
.filter(filterNonPullableImages)
|
|
61
66
|
.reduce(remoteImageReducer, [])
|
|
62
|
-
.map((image) => {
|
|
67
|
+
.map(({ image, platform }) => {
|
|
63
68
|
const [repo, tag = 'latest'] = image.split(':')
|
|
64
69
|
|
|
65
|
-
return { repo, tag }
|
|
70
|
+
return { repo, tag, platform }
|
|
66
71
|
})
|
|
67
72
|
.reduce(
|
|
68
73
|
(acc, val) =>
|
|
@@ -76,11 +81,15 @@ const pullImages = () => ({
|
|
|
76
81
|
),
|
|
77
82
|
[]
|
|
78
83
|
)
|
|
79
|
-
.map(({ repo, tag }) => ({
|
|
84
|
+
.map(({ repo, tag, platform }) => ({
|
|
80
85
|
title: `Pulling ${logger.style.file(
|
|
81
86
|
`${repo}:${tag}`
|
|
82
87
|
)} image`,
|
|
83
|
-
task: () =>
|
|
88
|
+
task: () =>
|
|
89
|
+
imageApi.pull({
|
|
90
|
+
image: `${repo}:${tag}`,
|
|
91
|
+
platform
|
|
92
|
+
})
|
|
84
93
|
})),
|
|
85
94
|
{
|
|
86
95
|
concurrent: true,
|
|
@@ -92,7 +101,7 @@ const pullImages = () => ({
|
|
|
92
101
|
const imagesFilter = containers
|
|
93
102
|
.filter(filterNonPullableImages)
|
|
94
103
|
.reduce(remoteImageReducer, [])
|
|
95
|
-
.map((image) => `reference='${image}'`)
|
|
104
|
+
.map(({ image }) => `reference='${image}'`)
|
|
96
105
|
|
|
97
106
|
const existingImages = await imageApi.ls({
|
|
98
107
|
formatToJSON: true,
|
|
@@ -102,10 +111,10 @@ const pullImages = () => ({
|
|
|
102
111
|
const missingContainerImages = containers
|
|
103
112
|
.filter(filterNonPullableImages)
|
|
104
113
|
.reduce(remoteImageReducer, [])
|
|
105
|
-
.map((image) => {
|
|
114
|
+
.map(({ image, platform }) => {
|
|
106
115
|
const [repo, tag = 'latest'] = image.split(':')
|
|
107
116
|
|
|
108
|
-
return { repo, tag }
|
|
117
|
+
return { repo, tag, platform }
|
|
109
118
|
})
|
|
110
119
|
.filter(
|
|
111
120
|
({ repo, tag }) =>
|
|
@@ -132,9 +141,13 @@ const pullImages = () => ({
|
|
|
132
141
|
}
|
|
133
142
|
|
|
134
143
|
return task.newListr(
|
|
135
|
-
missingContainerImages.map(({ repo, tag }) => ({
|
|
144
|
+
missingContainerImages.map(({ repo, tag, platform }) => ({
|
|
136
145
|
title: `Pulling ${logger.style.file(`${repo}:${tag}`)} image`,
|
|
137
|
-
task: () =>
|
|
146
|
+
task: () =>
|
|
147
|
+
imageApi.pull({
|
|
148
|
+
image: `${repo}:${tag}`,
|
|
149
|
+
platform
|
|
150
|
+
})
|
|
138
151
|
})),
|
|
139
152
|
{
|
|
140
153
|
concurrent: true,
|
|
@@ -75,3 +75,15 @@ export function inspect(
|
|
|
75
75
|
options?: ImagesInspectOptions<true>,
|
|
76
76
|
execOptions?: ExecAsyncSpawnOptions<false>
|
|
77
77
|
): Promise<ImagesInspectResult>
|
|
78
|
+
|
|
79
|
+
export interface ImagesPullOptions {
|
|
80
|
+
image: string
|
|
81
|
+
allTags?: boolean
|
|
82
|
+
platform?: string
|
|
83
|
+
quiet?: boolean
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function pull(
|
|
87
|
+
options?: ImagesPullOptions,
|
|
88
|
+
execOptions?: ExecAsyncSpawnOptions<false>
|
|
89
|
+
): Promise<string>
|
|
@@ -78,7 +78,28 @@ const inspect = async (options, execOptions = {}) => {
|
|
|
78
78
|
return execAsyncSpawn(`docker image inspect ${args}`, execOptions)
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
/**
|
|
82
|
+
* @param {import('./image-api').ImagesPullOptions} options
|
|
83
|
+
* @param {import('../../../util/exec-async-command').ExecAsyncSpawnOptions} execOptions
|
|
84
|
+
*/
|
|
85
|
+
const pull = async (options, execOptions = {}) => {
|
|
86
|
+
const { image, allTags, platform, quiet } = options
|
|
87
|
+
|
|
88
|
+
const allTagsArg = typeof allTags === 'boolean' ? '--all-tags' : ''
|
|
89
|
+
const platformArg =
|
|
90
|
+
typeof platform === 'string' ? `--platform=${platform}` : ''
|
|
91
|
+
|
|
92
|
+
const quietArg = typeof quiet === 'boolean' ? '--quiet' : ''
|
|
93
|
+
|
|
94
|
+
const args = [allTagsArg, platformArg, quietArg, image]
|
|
95
|
+
.filter(Boolean)
|
|
96
|
+
.join(' ')
|
|
97
|
+
|
|
98
|
+
return execAsyncSpawn(`docker image pull ${args}`, execOptions)
|
|
99
|
+
}
|
|
100
|
+
|
|
81
101
|
module.exports = {
|
|
82
102
|
ls,
|
|
83
|
-
inspect
|
|
103
|
+
inspect,
|
|
104
|
+
pull
|
|
84
105
|
}
|
|
@@ -223,11 +223,13 @@ const buildDockerFileInstructions = async (
|
|
|
223
223
|
const { agentVersion, licenseKey } = newRelic
|
|
224
224
|
|
|
225
225
|
// eslint-disable-next-line max-len
|
|
226
|
+
// Use linux-musl archive for Alpine-based images.
|
|
227
|
+
const newRelicArchive = `newrelic-php5-${agentVersion}-linux-musl`
|
|
226
228
|
dockerFileInstructions.run('apk add --no-cache gcompat')
|
|
227
|
-
.run(`curl -L https://download.newrelic.com/php_agent/archive/${agentVersion}
|
|
229
|
+
.run(`curl -L https://download.newrelic.com/php_agent/archive/${agentVersion}/${newRelicArchive}.tar.gz | tar -C /tmp -zx \
|
|
228
230
|
&& export NR_INSTALL_USE_CP_NOT_LN=1 \
|
|
229
231
|
&& export NR_INSTALL_SILENT=1 \
|
|
230
|
-
&& /tmp
|
|
232
|
+
&& /tmp/${newRelicArchive}/newrelic-install install \
|
|
231
233
|
&& rm -rf /tmp/newrelic-php5-* /tmp/nrinstall*`)
|
|
232
234
|
.run(`sed -i -e "s/REPLACE_WITH_REAL_KEY/${licenseKey}/" \
|
|
233
235
|
-e "s/newrelic.appname[[:space:]]=[[:space:]].*/newrelic.appname=\\"${
|
|
@@ -302,17 +304,25 @@ const buildDebugDockerFileInstructions = async (ctx, { image, tag }) => {
|
|
|
302
304
|
* @returns {import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
|
|
303
305
|
*/
|
|
304
306
|
const buildProjectImage = () => ({
|
|
305
|
-
title:
|
|
306
|
-
? 'Building Project Images (for x86)'
|
|
307
|
-
: 'Building Project Images',
|
|
307
|
+
title: 'Building Project Images',
|
|
308
308
|
task: async (ctx, task) => {
|
|
309
309
|
const containers = ctx.config.docker.getContainers(ctx.ports)
|
|
310
|
+
const isUsingLinuxAmd64Platform =
|
|
311
|
+
rosettaTranslatedContainers.includes('php') ||
|
|
312
|
+
containers.php.platform === 'linux/amd64'
|
|
313
|
+
|
|
314
|
+
if (isUsingLinuxAmd64Platform) {
|
|
315
|
+
task.title = 'Building Project Images (for x86)'
|
|
316
|
+
} else if (
|
|
317
|
+
containers.php.platform &&
|
|
318
|
+
containers.php.platform !== 'linux/amd64'
|
|
319
|
+
) {
|
|
320
|
+
task.title = `Building Project Images (for ${containers.php.platform})`
|
|
321
|
+
}
|
|
310
322
|
|
|
311
323
|
return task.newListr([
|
|
312
324
|
{
|
|
313
|
-
title:
|
|
314
|
-
? 'Building PHP image (for x86)'
|
|
315
|
-
: 'Building PHP image',
|
|
325
|
+
title: 'Building PHP image',
|
|
316
326
|
task: async () => {
|
|
317
327
|
const [image, tag = 'latest'] =
|
|
318
328
|
ctx.config.overridenConfiguration.configuration.php.baseImage.split(
|
|
@@ -328,8 +338,10 @@ const buildProjectImage = () => ({
|
|
|
328
338
|
try {
|
|
329
339
|
await execAsyncSpawn(
|
|
330
340
|
`docker build -t ${containers.php.image}${
|
|
331
|
-
|
|
341
|
+
isUsingLinuxAmd64Platform
|
|
332
342
|
? ' --platform linux/amd64'
|
|
343
|
+
: containers.php.platform
|
|
344
|
+
? ` --platform ${containers.php.platform}`
|
|
333
345
|
: ''
|
|
334
346
|
} -<<EOF
|
|
335
347
|
${dockerFileInstructions}
|
|
@@ -350,9 +362,7 @@ EOF`,
|
|
|
350
362
|
}
|
|
351
363
|
},
|
|
352
364
|
{
|
|
353
|
-
title:
|
|
354
|
-
? 'Building PHP with XDebug image (for x86)'
|
|
355
|
-
: 'Building PHP with XDebug image',
|
|
365
|
+
title: 'Building PHP with XDebug image',
|
|
356
366
|
task: async () => {
|
|
357
367
|
const [phpImage, phpTag] = containers.php.image.split(':')
|
|
358
368
|
const debugImageInstructions =
|
|
@@ -364,8 +374,10 @@ EOF`,
|
|
|
364
374
|
try {
|
|
365
375
|
await execAsyncSpawn(
|
|
366
376
|
`docker build -t ${containers.phpWithXdebug.image}${
|
|
367
|
-
|
|
377
|
+
isUsingLinuxAmd64Platform
|
|
368
378
|
? ' --platform linux/amd64'
|
|
379
|
+
: containers.php.platform
|
|
380
|
+
? ` --platform ${containers.php.platform}`
|
|
369
381
|
: ''
|
|
370
382
|
} -<<EOF
|
|
371
383
|
${debugImageInstructions}
|
package/lib/tasks/execute.js
CHANGED
|
@@ -8,7 +8,9 @@ const { getCachedPorts } = require('../config/get-port-config')
|
|
|
8
8
|
const checkPHPVersion = require('./requirements/php-version')
|
|
9
9
|
const {
|
|
10
10
|
executeInContainer,
|
|
11
|
-
|
|
11
|
+
executeInContainerNonInteractive,
|
|
12
|
+
runInContainer,
|
|
13
|
+
runInContainerNonInteractive
|
|
12
14
|
} = require('../util/execute-in-container')
|
|
13
15
|
const { containerApi } = require('./docker/containers')
|
|
14
16
|
const dockerNetwork = require('./docker/network')
|
|
@@ -17,10 +19,11 @@ const { prepareFileSystem } = require('./file-system')
|
|
|
17
19
|
|
|
18
20
|
/**
|
|
19
21
|
*
|
|
20
|
-
* @param {{ containerName: string, commands: string[] }} argv
|
|
22
|
+
* @param {{ containerName: string, commands: string[], nonInteractive?: boolean }} argv
|
|
21
23
|
* @returns
|
|
22
24
|
*/
|
|
23
25
|
const executeTask = async (argv) => {
|
|
26
|
+
const { nonInteractive = false } = argv
|
|
24
27
|
const tasks = new Listr(
|
|
25
28
|
[
|
|
26
29
|
checkRequirements(),
|
|
@@ -35,8 +38,12 @@ const executeTask = async (argv) => {
|
|
|
35
38
|
{
|
|
36
39
|
concurrent: false,
|
|
37
40
|
exitOnError: true,
|
|
38
|
-
ctx: { throwMagentoVersionMissing: true },
|
|
39
|
-
renderer:
|
|
41
|
+
ctx: /** @type {any} */ ({ throwMagentoVersionMissing: true }),
|
|
42
|
+
renderer: nonInteractive
|
|
43
|
+
? 'silent'
|
|
44
|
+
: process.stdout.isTTY
|
|
45
|
+
? 'default'
|
|
46
|
+
: 'silent',
|
|
40
47
|
rendererOptions: { collapse: false, clearOutput: true }
|
|
41
48
|
}
|
|
42
49
|
)
|
|
@@ -45,10 +52,12 @@ const executeTask = async (argv) => {
|
|
|
45
52
|
try {
|
|
46
53
|
ctx = await tasks.run()
|
|
47
54
|
} catch (e) {
|
|
48
|
-
logger.error(e.message
|
|
55
|
+
logger.error(e instanceof Error ? e.message : String(e))
|
|
49
56
|
process.exit(1)
|
|
50
57
|
}
|
|
51
|
-
const containers =
|
|
58
|
+
const containers = /** @type {Record<string, any>} */ (
|
|
59
|
+
ctx.config.docker.getContainers(ctx.ports)
|
|
60
|
+
)
|
|
52
61
|
const services = Object.keys(containers)
|
|
53
62
|
|
|
54
63
|
if (
|
|
@@ -71,6 +80,11 @@ const executeTask = async (argv) => {
|
|
|
71
80
|
? containerResult[1]
|
|
72
81
|
: containerResult
|
|
73
82
|
|
|
83
|
+
if (nonInteractive && argv.commands.length === 0) {
|
|
84
|
+
logger.error('Non-interactive mode requires a command to execute')
|
|
85
|
+
process.exit(1)
|
|
86
|
+
}
|
|
87
|
+
|
|
74
88
|
if (argv.commands.length === 0) {
|
|
75
89
|
// if we have default connect command then use it
|
|
76
90
|
if (container.connectCommand) {
|
|
@@ -88,6 +102,20 @@ const executeTask = async (argv) => {
|
|
|
88
102
|
})
|
|
89
103
|
|
|
90
104
|
if (containerList.length > 0) {
|
|
105
|
+
if (nonInteractive) {
|
|
106
|
+
const result = await executeInContainerNonInteractive({
|
|
107
|
+
containerName: container.name,
|
|
108
|
+
commands: argv.commands,
|
|
109
|
+
user: container.user,
|
|
110
|
+
env: container.execCommandEnv
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
if (result.result) {
|
|
114
|
+
process.stdout.write(`${result.result}\n`)
|
|
115
|
+
}
|
|
116
|
+
process.exit(result.code)
|
|
117
|
+
}
|
|
118
|
+
|
|
91
119
|
if (process.stdout.isTTY) {
|
|
92
120
|
logger.logN(
|
|
93
121
|
`Executing container ${logger.style.misc(
|
|
@@ -101,13 +129,29 @@ const executeTask = async (argv) => {
|
|
|
101
129
|
const result = executeInContainer({
|
|
102
130
|
containerName: container.name,
|
|
103
131
|
commands: argv.commands,
|
|
104
|
-
user: container.user
|
|
132
|
+
user: container.user,
|
|
133
|
+
env: container.execCommandEnv
|
|
105
134
|
})
|
|
106
135
|
|
|
107
136
|
return result
|
|
108
137
|
}
|
|
109
138
|
|
|
110
139
|
if (container.name.includes('php')) {
|
|
140
|
+
if (nonInteractive) {
|
|
141
|
+
const result = await runInContainerNonInteractive(
|
|
142
|
+
{
|
|
143
|
+
...container,
|
|
144
|
+
name: `${container.name}_exec-${Date.now()}`
|
|
145
|
+
},
|
|
146
|
+
argv.commands
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
if (result.result) {
|
|
150
|
+
process.stdout.write(`${result.result}\n`)
|
|
151
|
+
}
|
|
152
|
+
process.exit(result.code)
|
|
153
|
+
}
|
|
154
|
+
|
|
111
155
|
if (process.stdout.isTTY) {
|
|
112
156
|
logger.logN(
|
|
113
157
|
`Starting container ${logger.style.misc(
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
const pathExists = require('../../../util/path-exists')
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @returns {import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
|
|
7
|
+
*/
|
|
8
|
+
const clearLogs = () => ({
|
|
9
|
+
title: 'Clearing Magento logs',
|
|
10
|
+
task: async (ctx, task) => {
|
|
11
|
+
let deletedLogsCount = 0
|
|
12
|
+
await Promise.all(
|
|
13
|
+
[
|
|
14
|
+
'./var/log/system.log',
|
|
15
|
+
'./var/log/debug.log',
|
|
16
|
+
'./var/log/xdebug.log'
|
|
17
|
+
].map(async (logPath) => {
|
|
18
|
+
if (await pathExists(path.join(process.cwd(), logPath))) {
|
|
19
|
+
await fs.promises.rm(path.join(process.cwd(), logPath))
|
|
20
|
+
deletedLogsCount++
|
|
21
|
+
}
|
|
22
|
+
})
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
if (deletedLogsCount === 0) {
|
|
26
|
+
task.skip()
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
module.exports = clearLogs
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const configPhpToJson = require('../../../util/config-php-json')
|
|
2
2
|
const getJsonfileData = require('../../../util/get-jsonfile-data')
|
|
3
3
|
const path = require('path')
|
|
4
|
+
const semver = require('semver')
|
|
4
5
|
const composerTask = require('../../../util/composer-task')
|
|
5
6
|
const magentoTask = require('../../../util/magento-task')
|
|
6
7
|
|
|
@@ -9,6 +10,18 @@ const magentoTask = require('../../../util/magento-task')
|
|
|
9
10
|
*/
|
|
10
11
|
module.exports = () => ({
|
|
11
12
|
title: 'Disabling 2FA module',
|
|
13
|
+
// this module is only for magento 2.4 or newer
|
|
14
|
+
skip: (ctx) => {
|
|
15
|
+
const { magentoVersion } = ctx
|
|
16
|
+
|
|
17
|
+
const pureMagentoVersion = magentoVersion.match(
|
|
18
|
+
/^([0-9]+\.[0-9]+\.[0-9]+)/
|
|
19
|
+
)[1]
|
|
20
|
+
|
|
21
|
+
const isMagento24 = semver.satisfies(pureMagentoVersion, '>=2.4.0')
|
|
22
|
+
|
|
23
|
+
return !isMagento24
|
|
24
|
+
},
|
|
12
25
|
task: async (ctx, task) => {
|
|
13
26
|
// Check if MarkShust module is already installed via composer.lock
|
|
14
27
|
const composerLockPath = path.join(
|
|
@@ -26,7 +26,21 @@ const setupMagento = (options = {}) => ({
|
|
|
26
26
|
if (options.onlyInstallMagento) {
|
|
27
27
|
return task.newListr([
|
|
28
28
|
flushRedisConfig(),
|
|
29
|
-
migrateDatabase({ onlyInstallMagento: true })
|
|
29
|
+
migrateDatabase({ onlyInstallMagento: true }),
|
|
30
|
+
{
|
|
31
|
+
title: 'Disabling Magento caches',
|
|
32
|
+
task: (ctx, task) => {
|
|
33
|
+
const { varnish } =
|
|
34
|
+
ctx.config.overridenConfiguration.configuration
|
|
35
|
+
return task.newListr(
|
|
36
|
+
magentoTask(
|
|
37
|
+
`cache:disable block_html layout${
|
|
38
|
+
!varnish.enabled ? ' full_page' : ''
|
|
39
|
+
}`
|
|
40
|
+
)
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
30
44
|
])
|
|
31
45
|
}
|
|
32
46
|
|
|
@@ -35,6 +49,20 @@ const setupMagento = (options = {}) => ({
|
|
|
35
49
|
setupMagentoFilePermissions(),
|
|
36
50
|
updateEnvPHP(),
|
|
37
51
|
migrateDatabase(),
|
|
52
|
+
{
|
|
53
|
+
title: 'Disabling Magento caches',
|
|
54
|
+
task: (ctx, task) => {
|
|
55
|
+
const { varnish } =
|
|
56
|
+
ctx.config.overridenConfiguration.configuration
|
|
57
|
+
return task.newListr(
|
|
58
|
+
magentoTask(
|
|
59
|
+
`cache:disable block_html layout${
|
|
60
|
+
!varnish.enabled ? ' full_page' : ''
|
|
61
|
+
}`
|
|
62
|
+
)
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
},
|
|
38
66
|
flushRedisConfig(),
|
|
39
67
|
{
|
|
40
68
|
title: 'Configuring Magento settings',
|
|
@@ -5,9 +5,10 @@ const KnownError = require('../../../errors/known-error')
|
|
|
5
5
|
* @param {number} scopeId
|
|
6
6
|
* @param {string} code
|
|
7
7
|
* @param {string} host
|
|
8
|
+
* @param {'websites' | 'stores'} scopeType
|
|
8
9
|
* @returns {import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
|
|
9
10
|
*/
|
|
10
|
-
const setBaseUrlForScope = (scopeId, code, host) => ({
|
|
11
|
+
const setBaseUrlForScope = (scopeId, code, host, scopeType) => ({
|
|
11
12
|
title: `store code ${code} at ${host}`,
|
|
12
13
|
task: async (ctx, task) => {
|
|
13
14
|
const {
|
|
@@ -31,7 +32,7 @@ const setBaseUrlForScope = (scopeId, code, host) => ({
|
|
|
31
32
|
const secureLocation = `${host}/` // SSL will work only on port 443, so you cannot run multiple projects with SSL at the same time.
|
|
32
33
|
const httpUrl = `http://${location}`
|
|
33
34
|
const httpsUrl = `https://${secureLocation}`
|
|
34
|
-
const scope = scopeId === 0 ? 'default' :
|
|
35
|
+
const scope = scopeId === 0 ? 'default' : scopeType
|
|
35
36
|
const table = 'core_config_data'
|
|
36
37
|
const values = [
|
|
37
38
|
{
|
|
@@ -83,11 +84,13 @@ const setBaseUrl = () => ({
|
|
|
83
84
|
task: async (ctx, task) => {
|
|
84
85
|
const {
|
|
85
86
|
config: {
|
|
86
|
-
overridenConfiguration: { ssl, storeDomains }
|
|
87
|
+
overridenConfiguration: { ssl, storeDomains, configuration }
|
|
87
88
|
},
|
|
88
89
|
databaseConnection
|
|
89
90
|
} = ctx
|
|
90
91
|
|
|
92
|
+
const runType = configuration?.nginx?.runType || 'website'
|
|
93
|
+
|
|
91
94
|
const enableSecureFrontend = ssl.enabled ? '1' : '0'
|
|
92
95
|
|
|
93
96
|
await updateTableValues(
|
|
@@ -110,27 +113,33 @@ const setBaseUrl = () => ({
|
|
|
110
113
|
{ databaseConnection, task }
|
|
111
114
|
)
|
|
112
115
|
|
|
113
|
-
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
+
const scopeType = runType === 'store' ? 'stores' : 'websites'
|
|
117
|
+
const tableName = runType === 'store' ? 'store' : 'store_website'
|
|
118
|
+
const idField = runType === 'store' ? 'store_id' : 'website_id'
|
|
119
|
+
|
|
120
|
+
const [entities] = await databaseConnection.query(
|
|
121
|
+
`select * from ${tableName};`
|
|
116
122
|
)
|
|
117
123
|
|
|
118
|
-
if (!
|
|
124
|
+
if (!entities || entities.length === 0) {
|
|
119
125
|
throw new KnownError(
|
|
120
|
-
`No
|
|
126
|
+
`No ${
|
|
127
|
+
runType === 'store' ? 'stores' : 'store websites'
|
|
128
|
+
} found in database, ${tableName} table is empty or does not exist`
|
|
121
129
|
)
|
|
122
130
|
}
|
|
123
131
|
|
|
124
132
|
const storeDomainsWithMapping = Object.entries(storeDomains).reduce(
|
|
125
133
|
(acc, [key, val]) => {
|
|
126
|
-
const
|
|
127
|
-
|
|
134
|
+
const entity = entities.find(
|
|
135
|
+
/** @param {{ code: string }} entity */
|
|
136
|
+
(entity) => entity.code === key
|
|
128
137
|
)
|
|
129
|
-
if (
|
|
138
|
+
if (entity) {
|
|
130
139
|
return {
|
|
131
140
|
...acc,
|
|
132
|
-
[
|
|
133
|
-
|
|
141
|
+
[entity.code]: {
|
|
142
|
+
scopeId: entity[idField],
|
|
134
143
|
domain: val
|
|
135
144
|
}
|
|
136
145
|
}
|
|
@@ -141,10 +150,28 @@ const setBaseUrl = () => ({
|
|
|
141
150
|
{}
|
|
142
151
|
)
|
|
143
152
|
|
|
153
|
+
// Check for missing store codes when runType is 'store'
|
|
154
|
+
if (runType === 'store') {
|
|
155
|
+
const missingCodes = Object.keys(storeDomains).filter(
|
|
156
|
+
(code) =>
|
|
157
|
+
!entities.some(
|
|
158
|
+
/** @param {{ code: string }} entity */
|
|
159
|
+
(entity) => entity.code === code
|
|
160
|
+
)
|
|
161
|
+
)
|
|
162
|
+
if (missingCodes.length > 0) {
|
|
163
|
+
throw new KnownError(
|
|
164
|
+
`Store codes not found in database: ${missingCodes.join(
|
|
165
|
+
', '
|
|
166
|
+
)}. Please check your storeDomains configuration in cma.js matches the store codes in the store table.`
|
|
167
|
+
)
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
144
171
|
return task.newListr(
|
|
145
172
|
Object.entries(storeDomainsWithMapping).map(
|
|
146
|
-
([storeCode, {
|
|
147
|
-
setBaseUrlForScope(
|
|
173
|
+
([storeCode, { scopeId, domain }]) =>
|
|
174
|
+
setBaseUrlForScope(scopeId, storeCode, domain, scopeType)
|
|
148
175
|
),
|
|
149
176
|
{
|
|
150
177
|
concurrent: true,
|