@scandipwa/magento-scripts 2.4.0-alpha.1 → 2.4.0-alpha.2
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/config/docker.js +164 -56
- package/lib/config/port-config.js +46 -10
- package/lib/config/services/elasticsearch/default-es-env.js +1 -1
- package/lib/config/services/mariadb/versions/mariadb-10.2.js +3 -1
- package/lib/config/services/mariadb/versions/mariadb-10.3.js +3 -1
- package/lib/config/services/mariadb/versions/mariadb-10.4.js +3 -1
- package/lib/config/services/mariadb/versions/mariadb-10.6.js +3 -1
- package/lib/config/services/mariadb/versions/mariadb-11.4.js +3 -1
- package/lib/config/services/mariadb/versions/mariadb-11.6.js +3 -1
- package/lib/config/services/opensearch/default-os-env.js +1 -1
- package/lib/config/services/php/extensions/xdebug.js +1 -0
- package/lib/config/templates/nginx.template.conf +2 -2
- package/lib/config/templates/php-fpm.template.conf +1 -1
- package/lib/config/templates/ssl-terminator.template.conf +1 -1
- package/lib/tasks/database/create-magento-database.js +2 -1
- package/lib/tasks/database/import-remote-db/ssh/index.js +1 -1
- package/lib/tasks/database/import-remote-db/ssh/readymage.js +1 -1
- package/lib/tasks/database/import-remote-db/ssh/regular-server.js +1 -1
- package/lib/tasks/docker/containers/container-api.d.ts +5 -0
- package/lib/tasks/docker/containers/container-api.js +3 -1
- package/lib/tasks/docker/containers/tasks.js +86 -21
- package/lib/tasks/docker/project-image-builder.js +55 -45
- package/lib/tasks/docker/system/system-api.d.ts +66 -0
- package/lib/tasks/docker/system/system-api.js +28 -1
- package/lib/tasks/execute.js +1 -1
- package/lib/tasks/file-system/create-nginx-config.js +22 -8
- package/lib/tasks/file-system/create-ssl-terminator-config.js +20 -7
- package/lib/tasks/magento/install-magento-project.js +40 -24
- package/lib/tasks/magento/setup-magento/check-file-permissions.php +32 -0
- package/lib/tasks/magento/setup-magento/index.js +2 -0
- package/lib/tasks/magento/setup-magento/make-magento-binaries-executable.js +44 -0
- package/lib/tasks/magento/setup-magento/setup-file-permissions.js +160 -0
- package/lib/tasks/php/php-container.js +20 -6
- package/lib/tasks/php/update-env-php.js +3 -9
- package/lib/tasks/requirements/cgroup-version.js +69 -0
- package/lib/tasks/requirements/elasticsearch-version.js +19 -3
- package/lib/tasks/requirements/index.js +3 -0
- package/lib/tasks/requirements/opensearch-version.js +1 -1
- package/lib/tasks/requirements/searchengine-version.js +1 -2
- package/lib/util/dockerfile-builder/build-instructions.js +5 -1
- package/lib/util/dockerfile-builder/types.d.ts +1 -1
- package/lib/util/execute-in-container.js +3 -1
- package/lib/util/get-installed-magento-version.js +60 -2
- package/lib/util/portscanner.js +3 -3
- package/lib/util/run-composer.js +1 -1
- package/lib/util/run-magento.js +2 -1
- package/lib/util/run-php.js +2 -1
- package/lib/util/set-config.js +4 -2
- package/package.json +16 -16
- package/typings/context.d.ts +4 -2
- package/typings/index.d.ts +10 -0
|
@@ -148,40 +148,105 @@ const pullImages = () => ({
|
|
|
148
148
|
*/
|
|
149
149
|
const startContainers = () => ({
|
|
150
150
|
title: 'Starting containers',
|
|
151
|
-
task: async ({ ports, config: { docker }
|
|
151
|
+
task: async ({ ports, config: { docker } }, task) => {
|
|
152
152
|
const containerList = await containerApi.ls({
|
|
153
153
|
formatToJSON: true,
|
|
154
154
|
all: true
|
|
155
155
|
})
|
|
156
156
|
|
|
157
|
-
const missingContainers = Object.
|
|
158
|
-
|
|
159
|
-
|
|
157
|
+
const missingContainers = Object.entries(docker.getContainers(ports))
|
|
158
|
+
.filter(
|
|
159
|
+
([nameWithoutPrefix, { name }]) =>
|
|
160
|
+
!containerList.some((c) => c.Names === name)
|
|
161
|
+
)
|
|
162
|
+
.map(([nameWithoutPrefix, containerOptions]) => ({
|
|
163
|
+
...containerOptions,
|
|
164
|
+
nameWithoutPrefix
|
|
165
|
+
}))
|
|
160
166
|
|
|
161
167
|
if (missingContainers.length === 0) {
|
|
162
168
|
task.skip()
|
|
163
169
|
return
|
|
164
170
|
}
|
|
165
171
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
)
|
|
172
|
+
const containerStatuses = missingContainers.reduce(
|
|
173
|
+
(acc, container) => ({
|
|
174
|
+
...acc,
|
|
175
|
+
[container.nameWithoutPrefix]: {
|
|
176
|
+
started: false,
|
|
177
|
+
onStarted: []
|
|
178
|
+
}
|
|
179
|
+
}),
|
|
180
|
+
{}
|
|
181
|
+
)
|
|
174
182
|
|
|
175
|
-
|
|
176
|
-
|
|
183
|
+
return task.newListr(
|
|
184
|
+
missingContainers.map((container) => ({
|
|
185
|
+
title: `Deploying ${logger.style.file(container._)} container`,
|
|
186
|
+
task: async (subCtx, subTask) => {
|
|
187
|
+
const { dependsOn } = container
|
|
188
|
+
if (Array.isArray(dependsOn)) {
|
|
189
|
+
const startedContainers = []
|
|
190
|
+
subTask.title = `Container ${
|
|
191
|
+
container._
|
|
192
|
+
} is waiting for ${dependsOn.join(', ')} to start...`
|
|
193
|
+
await Promise.all(
|
|
194
|
+
dependsOn.map(
|
|
195
|
+
async (name) =>
|
|
196
|
+
new Promise((resolve, reject) => {
|
|
197
|
+
const timeout = setTimeout(
|
|
198
|
+
() => {
|
|
199
|
+
reject(
|
|
200
|
+
new Error(
|
|
201
|
+
`Container ${name} not started in time`
|
|
202
|
+
)
|
|
203
|
+
)
|
|
204
|
+
},
|
|
205
|
+
// 2 minutes
|
|
206
|
+
1000 * 60 * 2
|
|
207
|
+
)
|
|
208
|
+
containerStatuses[name].onStarted.push(
|
|
209
|
+
() => {
|
|
210
|
+
startedContainers.push(name)
|
|
211
|
+
subTask.title = `Container ${
|
|
212
|
+
container._
|
|
213
|
+
} is waiting for ${dependsOn
|
|
214
|
+
.filter(
|
|
215
|
+
(d) =>
|
|
216
|
+
!startedContainers.includes(
|
|
217
|
+
d
|
|
218
|
+
)
|
|
219
|
+
)
|
|
220
|
+
.join(', ')} to start...`
|
|
221
|
+
clearTimeout(timeout)
|
|
222
|
+
resolve()
|
|
223
|
+
}
|
|
224
|
+
)
|
|
225
|
+
})
|
|
226
|
+
)
|
|
227
|
+
)
|
|
228
|
+
}
|
|
177
229
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
230
|
+
subTask.title = `${container._} is starting...`
|
|
231
|
+
|
|
232
|
+
await containerApi.run(container)
|
|
233
|
+
|
|
234
|
+
containerStatuses[
|
|
235
|
+
container.nameWithoutPrefix
|
|
236
|
+
].started = true
|
|
237
|
+
containerStatuses[
|
|
238
|
+
container.nameWithoutPrefix
|
|
239
|
+
].onStarted.forEach((cb) => {
|
|
240
|
+
cb()
|
|
241
|
+
})
|
|
242
|
+
|
|
243
|
+
subTask.output = `${container._} container started`
|
|
244
|
+
}
|
|
245
|
+
})),
|
|
246
|
+
{
|
|
247
|
+
concurrent: true,
|
|
248
|
+
exitOnError: true
|
|
249
|
+
}
|
|
185
250
|
)
|
|
186
251
|
},
|
|
187
252
|
options: {
|
|
@@ -170,9 +170,8 @@ const buildDockerFileInstructions = async (
|
|
|
170
170
|
}
|
|
171
171
|
|
|
172
172
|
if (!ctx.isDockerDesktop) {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
)
|
|
173
|
+
const { uid, gid } = os.userInfo()
|
|
174
|
+
dockerFileInstructions.run(`chown -R ${uid}:${gid} /composer/home`)
|
|
176
175
|
}
|
|
177
176
|
|
|
178
177
|
dockerFileInstructions.workDir(ctx.config.baseConfig.containerMagentoDir)
|
|
@@ -286,58 +285,69 @@ const buildProjectImage = () => ({
|
|
|
286
285
|
title: 'Building Project Images',
|
|
287
286
|
task: async (ctx, task) => {
|
|
288
287
|
const containers = ctx.config.docker.getContainers(ctx.ports)
|
|
289
|
-
const [image, tag = 'latest'] =
|
|
290
|
-
ctx.config.overridenConfiguration.configuration.php.baseImage.split(
|
|
291
|
-
':'
|
|
292
|
-
)
|
|
293
|
-
const dockerFileInstructions = await buildDockerFileInstructions(ctx, {
|
|
294
|
-
image,
|
|
295
|
-
tag,
|
|
296
|
-
ignorePHPExtensions: ['xdebug']
|
|
297
|
-
})
|
|
298
288
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
289
|
+
return task.newListr([
|
|
290
|
+
{
|
|
291
|
+
title: 'Building PHP image',
|
|
292
|
+
task: async () => {
|
|
293
|
+
const [image, tag = 'latest'] =
|
|
294
|
+
ctx.config.overridenConfiguration.configuration.php.baseImage.split(
|
|
295
|
+
':'
|
|
296
|
+
)
|
|
297
|
+
const dockerFileInstructions =
|
|
298
|
+
await buildDockerFileInstructions(ctx, {
|
|
299
|
+
image,
|
|
300
|
+
tag,
|
|
301
|
+
ignorePHPExtensions: ['xdebug']
|
|
302
|
+
})
|
|
303
|
+
|
|
304
|
+
try {
|
|
305
|
+
await execAsyncSpawn(
|
|
306
|
+
`docker build -t ${containers.php.image} -<<EOF
|
|
302
307
|
${dockerFileInstructions}
|
|
303
308
|
EOF`,
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
309
|
+
{
|
|
310
|
+
callback: (r) => {
|
|
311
|
+
task.output = r
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
)
|
|
315
|
+
} catch (e) {
|
|
316
|
+
throw new KnownError(
|
|
317
|
+
`Unexpected error during PHP image building!\n\n${e}`
|
|
318
|
+
)
|
|
307
319
|
}
|
|
308
320
|
}
|
|
309
|
-
|
|
310
|
-
} catch (e) {
|
|
311
|
-
throw new KnownError(
|
|
312
|
-
`Unexpected error during project image building!\n\n${e}`
|
|
313
|
-
)
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
const [phpImage, phpTag] = containers.php.image.split(':')
|
|
317
|
-
const debugImageInstructions = await buildDebugDockerFileInstructions(
|
|
318
|
-
ctx,
|
|
321
|
+
},
|
|
319
322
|
{
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
323
|
+
title: 'Building PHP with XDebug image',
|
|
324
|
+
task: async () => {
|
|
325
|
+
const [phpImage, phpTag] = containers.php.image.split(':')
|
|
326
|
+
const debugImageInstructions =
|
|
327
|
+
await buildDebugDockerFileInstructions(ctx, {
|
|
328
|
+
image: phpImage,
|
|
329
|
+
tag: phpTag
|
|
330
|
+
})
|
|
331
|
+
|
|
332
|
+
try {
|
|
333
|
+
await execAsyncSpawn(
|
|
334
|
+
`docker build -t ${containers.phpWithXdebug.image} -<<EOF
|
|
328
335
|
${debugImageInstructions}
|
|
329
336
|
EOF`,
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
337
|
+
{
|
|
338
|
+
callback: (r) => {
|
|
339
|
+
task.output = r
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
)
|
|
343
|
+
} catch (e) {
|
|
344
|
+
throw new KnownError(
|
|
345
|
+
`Unexpected error during PHP with XDebug image building!\n\n${e}`
|
|
346
|
+
)
|
|
333
347
|
}
|
|
334
348
|
}
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
throw new KnownError(
|
|
338
|
-
`Unexpected error during project image building!\n\n${e}`
|
|
339
|
-
)
|
|
340
|
-
}
|
|
349
|
+
}
|
|
350
|
+
])
|
|
341
351
|
},
|
|
342
352
|
options: {
|
|
343
353
|
bottomBar: 10
|
|
@@ -69,3 +69,69 @@ export function df(
|
|
|
69
69
|
options?: SystemDFOptions<true>,
|
|
70
70
|
execOptions?: ExecAsyncSpawnOptions<false>
|
|
71
71
|
): Promise<SystemDFResult>
|
|
72
|
+
|
|
73
|
+
export interface SystemVersionOptions<T extends boolean = false> {
|
|
74
|
+
format?: string
|
|
75
|
+
formatToJSON?: T
|
|
76
|
+
verbose?: boolean
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
interface DockerServiceComponent {
|
|
80
|
+
Name: string;
|
|
81
|
+
Version: string;
|
|
82
|
+
Details: {
|
|
83
|
+
ApiVersion?: string;
|
|
84
|
+
Arch?: string;
|
|
85
|
+
BuildTime?: string;
|
|
86
|
+
Experimental?: string;
|
|
87
|
+
GitCommit?: string;
|
|
88
|
+
GoVersion?: string;
|
|
89
|
+
KernelVersion?: string;
|
|
90
|
+
MinAPIVersion?: string;
|
|
91
|
+
Os?: string;
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
interface DockerServerInfo {
|
|
95
|
+
Platform: {
|
|
96
|
+
Name: string;
|
|
97
|
+
};
|
|
98
|
+
Components: DockerServiceComponent[];
|
|
99
|
+
Version: string;
|
|
100
|
+
ApiVersion: string;
|
|
101
|
+
MinAPIVersion: string;
|
|
102
|
+
GitCommit: string;
|
|
103
|
+
GoVersion: string;
|
|
104
|
+
Os: string;
|
|
105
|
+
Arch: string;
|
|
106
|
+
KernelVersion: string;
|
|
107
|
+
BuildTime: string;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
interface DockerClientInfo {
|
|
111
|
+
Platform: {
|
|
112
|
+
Name: string;
|
|
113
|
+
};
|
|
114
|
+
Version: string;
|
|
115
|
+
ApiVersion: string;
|
|
116
|
+
DefaultAPIVersion: string;
|
|
117
|
+
GitCommit: string;
|
|
118
|
+
GoVersion: string;
|
|
119
|
+
Os: string;
|
|
120
|
+
Arch: string;
|
|
121
|
+
BuildTime: string;
|
|
122
|
+
Context: string;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export interface SystemVersionResult {
|
|
126
|
+
Client: DockerClientInfo
|
|
127
|
+
Server: DockerServerInfo
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export function version(
|
|
131
|
+
options?: SystemVersionOptions,
|
|
132
|
+
execOptions?: ExecAsyncSpawnOptions<false>
|
|
133
|
+
): Promise<string>
|
|
134
|
+
export function version(
|
|
135
|
+
options?: SystemVersionOptions<true>,
|
|
136
|
+
execOptions?: ExecAsyncSpawnOptions<false>
|
|
137
|
+
): Promise<SystemVersionResult>
|
|
@@ -27,6 +27,33 @@ const df = async (options, execOptions = {}) => {
|
|
|
27
27
|
return execAsyncSpawn(`docker system df ${args}`, execOptions)
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* @param {import('./system-api').SystemVersionOptions} options
|
|
32
|
+
* @param {import('../../../util/exec-async-command').ExecAsyncSpawnOptions} execOptions
|
|
33
|
+
*/
|
|
34
|
+
const version = async (options, execOptions = {}) => {
|
|
35
|
+
const { format, formatToJSON } = options
|
|
36
|
+
|
|
37
|
+
const formatArg =
|
|
38
|
+
!formatToJSON && format
|
|
39
|
+
? `--format=${format}`
|
|
40
|
+
: formatToJSON && "--format='{{json .}}'"
|
|
41
|
+
|
|
42
|
+
const args = [formatArg].filter(Boolean).join(' ')
|
|
43
|
+
|
|
44
|
+
if (formatToJSON) {
|
|
45
|
+
const result = await execAsyncSpawn(
|
|
46
|
+
`docker version ${args}`,
|
|
47
|
+
execOptions
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
return JSON.parse(result)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return execAsyncSpawn(`docker version ${args}`, execOptions)
|
|
54
|
+
}
|
|
55
|
+
|
|
30
56
|
module.exports = {
|
|
31
|
-
df
|
|
57
|
+
df,
|
|
58
|
+
version
|
|
32
59
|
}
|
package/lib/tasks/execute.js
CHANGED
|
@@ -10,7 +10,7 @@ const createNginxConfig = () => ({
|
|
|
10
10
|
task: async (ctx) => {
|
|
11
11
|
const {
|
|
12
12
|
ports,
|
|
13
|
-
config: { overridenConfiguration, baseConfig },
|
|
13
|
+
config: { overridenConfiguration, baseConfig, docker },
|
|
14
14
|
isDockerDesktop
|
|
15
15
|
} = ctx
|
|
16
16
|
|
|
@@ -19,10 +19,26 @@ const createNginxConfig = () => ({
|
|
|
19
19
|
storeDomains
|
|
20
20
|
} = overridenConfiguration
|
|
21
21
|
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
: '
|
|
25
|
-
|
|
22
|
+
const networkSettings = {
|
|
23
|
+
phpNetwork: '127.0.0.1',
|
|
24
|
+
phpWithXdebugNetwork: '127.0.0.1',
|
|
25
|
+
fpmPort: ports.fpm,
|
|
26
|
+
fpmXdebugPort: ports.fpmXdebug,
|
|
27
|
+
hostPort: ports.app
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (isDockerDesktop) {
|
|
31
|
+
const containers = docker.getContainers(ports)
|
|
32
|
+
|
|
33
|
+
networkSettings.phpNetwork = containers.php.name
|
|
34
|
+
networkSettings.phpWithXdebugNetwork = containers.phpWithXdebug.name
|
|
35
|
+
|
|
36
|
+
networkSettings.fpmPort = 9000
|
|
37
|
+
networkSettings.fpmXdebugPort = 9001
|
|
38
|
+
|
|
39
|
+
networkSettings.hostPort = 80
|
|
40
|
+
}
|
|
41
|
+
|
|
26
42
|
const useStoreDomainMapping =
|
|
27
43
|
storeDomains && Object.keys(storeDomains).length > 1
|
|
28
44
|
|
|
@@ -37,10 +53,8 @@ const createNginxConfig = () => ({
|
|
|
37
53
|
template: nginx.configTemplate,
|
|
38
54
|
overwrite: true,
|
|
39
55
|
templateArgs: {
|
|
40
|
-
|
|
56
|
+
...networkSettings,
|
|
41
57
|
mageRoot: baseConfig.containerMagentoDir,
|
|
42
|
-
hostMachine,
|
|
43
|
-
hostPort,
|
|
44
58
|
config: overridenConfiguration,
|
|
45
59
|
storeDomains,
|
|
46
60
|
useStoreDomainMapping
|
|
@@ -15,8 +15,7 @@ const createSSLTerminatorConfig = () => ({
|
|
|
15
15
|
task: async (ctx) => {
|
|
16
16
|
const {
|
|
17
17
|
ports,
|
|
18
|
-
config: { overridenConfiguration, baseConfig },
|
|
19
|
-
debug,
|
|
18
|
+
config: { overridenConfiguration, baseConfig, docker },
|
|
20
19
|
isDockerDesktop
|
|
21
20
|
} = ctx
|
|
22
21
|
|
|
@@ -72,9 +71,24 @@ const createSSLTerminatorConfig = () => ({
|
|
|
72
71
|
)
|
|
73
72
|
}
|
|
74
73
|
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
:
|
|
74
|
+
const networkSettings = {
|
|
75
|
+
backendNetwork: '127.0.0.1',
|
|
76
|
+
backendPort: overridenConfiguration.configuration.varnish.enabled
|
|
77
|
+
? ports.varnish
|
|
78
|
+
: ports.app
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (isDockerDesktop) {
|
|
82
|
+
const containers = docker.getContainers(ports)
|
|
83
|
+
|
|
84
|
+
if (overridenConfiguration.configuration.varnish.enabled) {
|
|
85
|
+
networkSettings.backendNetwork = containers.varnish.name
|
|
86
|
+
networkSettings.backendPort = 80
|
|
87
|
+
} else {
|
|
88
|
+
networkSettings.backendNetwork = containers.nginx.name
|
|
89
|
+
networkSettings.backendPort = 80
|
|
90
|
+
}
|
|
91
|
+
}
|
|
78
92
|
const hostPort = !isDockerDesktop ? ports.sslTerminator : 80
|
|
79
93
|
|
|
80
94
|
const nginxVersionOutput = await run({
|
|
@@ -112,10 +126,9 @@ const createSSLTerminatorConfig = () => ({
|
|
|
112
126
|
overwrite: true,
|
|
113
127
|
templateArgs: {
|
|
114
128
|
ports,
|
|
115
|
-
|
|
129
|
+
...networkSettings,
|
|
116
130
|
hostPort,
|
|
117
131
|
config: overridenConfiguration,
|
|
118
|
-
debug,
|
|
119
132
|
isSSLDirectiveDeprecated
|
|
120
133
|
}
|
|
121
134
|
})
|
|
@@ -9,6 +9,11 @@ const getJsonFileData = require('../../util/get-jsonfile-data')
|
|
|
9
9
|
const KnownError = require('../../errors/known-error')
|
|
10
10
|
const UnknownError = require('../../errors/unknown-error')
|
|
11
11
|
const { runPHPContainerCommand } = require('../php/php-container')
|
|
12
|
+
const {
|
|
13
|
+
setupMagentoFilePermissions,
|
|
14
|
+
setupComposerCachePermissions
|
|
15
|
+
} = require('./setup-magento/setup-file-permissions')
|
|
16
|
+
const makeBinariesExecutable = require('./setup-magento/make-magento-binaries-executable')
|
|
12
17
|
|
|
13
18
|
const magentoProductEnterpriseEdition = 'magento/product-enterprise-edition'
|
|
14
19
|
const magentoProductCommunityEdition = 'magento/product-community-edition'
|
|
@@ -59,7 +64,8 @@ const adjustComposerJson = async (
|
|
|
59
64
|
? undefined
|
|
60
65
|
: (t) => {
|
|
61
66
|
task.output = t
|
|
62
|
-
}
|
|
67
|
+
},
|
|
68
|
+
useAutomaticUser: true
|
|
63
69
|
}
|
|
64
70
|
)
|
|
65
71
|
}
|
|
@@ -213,30 +219,40 @@ const installMagentoProject = () => ({
|
|
|
213
219
|
})
|
|
214
220
|
}
|
|
215
221
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
222
|
+
return task.newListr([
|
|
223
|
+
setupMagentoFilePermissions(),
|
|
224
|
+
setupComposerCachePermissions(),
|
|
225
|
+
{
|
|
226
|
+
title: 'Installing Magento dependencies',
|
|
227
|
+
task: async () => {
|
|
228
|
+
try {
|
|
229
|
+
await runComposerCommand(ctx, 'install', {
|
|
230
|
+
callback: !ctx.verbose
|
|
231
|
+
? undefined
|
|
232
|
+
: (t) => {
|
|
233
|
+
task.output = t
|
|
234
|
+
}
|
|
235
|
+
})
|
|
236
|
+
} catch (e) {
|
|
237
|
+
if (
|
|
238
|
+
e instanceof UnknownError &&
|
|
239
|
+
e.message.includes('man-in-the-middle attack')
|
|
240
|
+
) {
|
|
241
|
+
throw new KnownError(`Probably you haven't setup pubkeys in composer.
|
|
242
|
+
Please run ${logger.style.command(
|
|
243
|
+
'composer diagnose'
|
|
244
|
+
)} in cli to get mode.\n\n${e}`)
|
|
245
|
+
}
|
|
234
246
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
247
|
+
throw new UnknownError(
|
|
248
|
+
`Unexpected error during composer install.\n\n${e}`
|
|
249
|
+
)
|
|
250
|
+
}
|
|
251
|
+
ctx.magentoFirstInstall = true
|
|
252
|
+
}
|
|
253
|
+
},
|
|
254
|
+
makeBinariesExecutable()
|
|
255
|
+
])
|
|
240
256
|
},
|
|
241
257
|
options: {
|
|
242
258
|
bottomBar: 10
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
$directories = [
|
|
3
|
+
'/var',
|
|
4
|
+
'/generated',
|
|
5
|
+
'/vendor',
|
|
6
|
+
'/pub/static',
|
|
7
|
+
'/pub/media',
|
|
8
|
+
'/app/etc',
|
|
9
|
+
];
|
|
10
|
+
|
|
11
|
+
$results = [];
|
|
12
|
+
|
|
13
|
+
foreach ($directories as $dir) {
|
|
14
|
+
$directory = getcwd() . $dir;
|
|
15
|
+
$result = [];
|
|
16
|
+
$result['exists'] = file_exists($directory);
|
|
17
|
+
$result['writable'] = is_writable($directory);
|
|
18
|
+
$result['readable'] = is_readable($directory);
|
|
19
|
+
|
|
20
|
+
if ($result['exists']) {
|
|
21
|
+
$result['owner'] = posix_getpwuid(fileowner($directory));
|
|
22
|
+
$result['group'] = posix_getgrgid(filegroup($directory));
|
|
23
|
+
$result['current_user'] = posix_getpwuid(posix_geteuid());
|
|
24
|
+
|
|
25
|
+
$result['permissions'] =substr(sprintf('%o', fileperms($directory)), -4);
|
|
26
|
+
$result['is_current_user_directory_owner'] = $result['current_user'] === $result['owner'];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
$results[] = $result;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
echo json_encode($results, JSON_PRETTY_PRINT);
|
|
@@ -13,6 +13,7 @@ const urnHighlighter = require('./urn-highlighter')
|
|
|
13
13
|
const adjustFullPageCache = require('./adjust-full-page-cache')
|
|
14
14
|
const updateEnvPHP = require('../../php/update-env-php')
|
|
15
15
|
const setMailConfig = require('./set-mail-config')
|
|
16
|
+
const { setupMagentoFilePermissions } = require('./setup-file-permissions')
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* @param {Object} [options]
|
|
@@ -34,6 +35,7 @@ const setupMagento = (options = {}) => ({
|
|
|
34
35
|
return task.newListr(
|
|
35
36
|
[
|
|
36
37
|
waitingForRedis(),
|
|
38
|
+
setupMagentoFilePermissions(),
|
|
37
39
|
updateEnvPHP(),
|
|
38
40
|
migrateDatabase(),
|
|
39
41
|
flushRedisConfig(),
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Yes, I know binary files are files in binary format, but this is a common term for executable files
|
|
2
|
+
|
|
3
|
+
const fs = require('fs')
|
|
4
|
+
const path = require('path')
|
|
5
|
+
const pathExists = require('../../../util/path-exists')
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @returns {import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
|
|
9
|
+
*/
|
|
10
|
+
const makeBinariesExecutable = () => ({
|
|
11
|
+
task: async (ctx, task) => {
|
|
12
|
+
const directoriesWithBinFiles = [
|
|
13
|
+
path.join(ctx.config.baseConfig.magentoDir, 'bin'),
|
|
14
|
+
path.join(ctx.config.baseConfig.magentoDir, 'vendor', 'bin')
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
for (const directory of directoriesWithBinFiles) {
|
|
18
|
+
if (!(await pathExists(directory))) {
|
|
19
|
+
continue
|
|
20
|
+
}
|
|
21
|
+
const files = await fs.promises.readdir(directory, {
|
|
22
|
+
withFileTypes: true
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
for (const file of files) {
|
|
26
|
+
if (!file.isFile()) {
|
|
27
|
+
continue
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const filePath = path.join(directory, file.name)
|
|
31
|
+
const stats = await fs.promises.stat(filePath)
|
|
32
|
+
|
|
33
|
+
if (!filePath.startsWith(file.name) && stats.mode & 0o111) {
|
|
34
|
+
continue
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
task.output = `Making ${filePath} executable`
|
|
38
|
+
await fs.promises.chmod(filePath, 0o755)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
module.exports = makeBinariesExecutable
|