@scandipwa/magento-scripts 2.4.0-alpha.0 → 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.
Files changed (100) hide show
  1. package/exec.js +2 -2
  2. package/index.js +1 -0
  3. package/lib/commands/cli.js +17 -19
  4. package/lib/commands/execute.js +8 -4
  5. package/lib/commands/start.js +0 -6
  6. package/lib/config/docker.js +196 -79
  7. package/lib/config/get-project-configuration.js +0 -5
  8. package/lib/config/php-config.js +4 -0
  9. package/lib/config/port-config.js +47 -10
  10. package/lib/config/services/composer/versions/composer-2.8.js +1 -1
  11. package/lib/config/services/elasticsearch/default-es-env.js +1 -1
  12. package/lib/config/services/elasticsearch/versions/elasticsearch-8.17.js +14 -0
  13. package/lib/config/services/elasticsearch/versions/index.js +3 -1
  14. package/lib/config/services/mariadb/versions/index.js +3 -1
  15. package/lib/config/services/mariadb/versions/mariadb-10.2.js +3 -1
  16. package/lib/config/services/mariadb/versions/mariadb-10.3.js +3 -1
  17. package/lib/config/services/mariadb/versions/mariadb-10.4.js +3 -1
  18. package/lib/config/services/mariadb/versions/mariadb-10.6.js +3 -1
  19. package/lib/config/services/mariadb/versions/mariadb-11.4.js +11 -0
  20. package/lib/config/services/mariadb/versions/mariadb-11.6.js +11 -0
  21. package/lib/config/services/opensearch/default-os-env.js +1 -1
  22. package/lib/config/services/opensearch/versions/index.js +3 -1
  23. package/lib/config/services/opensearch/versions/opensearch-2.19.js +14 -0
  24. package/lib/config/services/php/extensions/ftp.js +7 -0
  25. package/lib/config/services/php/extensions/xdebug.js +1 -0
  26. package/lib/config/services/php/versions/index.js +2 -1
  27. package/lib/config/services/php/versions/php-7.2.js +0 -1
  28. package/lib/config/services/php/versions/php-7.3.js +0 -1
  29. package/lib/config/services/php/versions/php-7.4.js +0 -1
  30. package/lib/config/services/php/versions/php-8.1.js +4 -2
  31. package/lib/config/services/php/versions/php-8.2.js +1 -2
  32. package/lib/config/services/php/versions/php-8.3.js +32 -0
  33. package/lib/config/services/redis/index.js +6 -1
  34. package/lib/config/services/redis/valkey-8.0.js +8 -0
  35. package/lib/config/services/redis/valkey-8.1.js +8 -0
  36. package/lib/config/services/varnish/varnish-6-0.js +1 -1
  37. package/lib/config/services/varnish/varnish-6-6.js +1 -1
  38. package/lib/config/services/varnish/varnish-7-0.js +1 -1
  39. package/lib/config/services/varnish/varnish-7-1.js +1 -1
  40. package/lib/config/services/varnish/varnish-7-3.js +1 -1
  41. package/lib/config/services/varnish/varnish-7-4.js +1 -1
  42. package/lib/config/services/varnish/varnish-7-5.js +1 -1
  43. package/lib/config/services/varnish/varnish-7-6.js +1 -1
  44. package/lib/config/templates/nginx.template.conf +32 -9
  45. package/lib/config/templates/php-fpm.template.conf +1 -1
  46. package/lib/config/templates/ssl-terminator.template.conf +3 -1
  47. package/lib/config/versions/magento-2.4.4-p13.js +40 -0
  48. package/lib/config/versions/magento-2.4.5-p12.js +40 -0
  49. package/lib/config/versions/magento-2.4.6-p10.js +40 -0
  50. package/lib/config/versions/magento-2.4.7-p4.js +0 -1
  51. package/lib/config/versions/magento-2.4.7-p5.js +41 -0
  52. package/lib/config/versions/magento-2.4.8.js +43 -0
  53. package/lib/tasks/database/create-magento-database.js +6 -4
  54. package/lib/tasks/database/import-remote-db/ssh/index.js +1 -1
  55. package/lib/tasks/database/import-remote-db/ssh/readymage.js +1 -1
  56. package/lib/tasks/database/import-remote-db/ssh/regular-server.js +1 -1
  57. package/lib/tasks/docker/containers/container-api.d.ts +14 -3
  58. package/lib/tasks/docker/containers/container-api.js +16 -9
  59. package/lib/tasks/docker/containers/tasks.js +99 -28
  60. package/lib/tasks/docker/convert-mysql-to-mariadb.js +14 -22
  61. package/lib/tasks/docker/project-image-builder.js +153 -91
  62. package/lib/tasks/docker/system/system-api.d.ts +66 -0
  63. package/lib/tasks/docker/system/system-api.js +28 -1
  64. package/lib/tasks/execute.js +10 -10
  65. package/lib/tasks/file-system/create-nginx-config.js +22 -8
  66. package/lib/tasks/file-system/create-php-debug-config.js +1 -2
  67. package/lib/tasks/file-system/create-php-fpm-debug-config.js +33 -0
  68. package/lib/tasks/file-system/create-phpstorm-config/php-config/php-interpreters-config.js +5 -5
  69. package/lib/tasks/file-system/create-phpstorm-config/workspace-config/composer-settings-config.js +2 -2
  70. package/lib/tasks/file-system/create-phpstorm-config/workspace-config/php-workspace-project-configuration-config.js +4 -3
  71. package/lib/tasks/file-system/create-ssl-terminator-config.js +46 -7
  72. package/lib/tasks/file-system/index.js +2 -0
  73. package/lib/tasks/magento/install-magento-project.js +40 -24
  74. package/lib/tasks/magento/setup-magento/check-file-permissions.php +32 -0
  75. package/lib/tasks/magento/setup-magento/index.js +2 -0
  76. package/lib/tasks/magento/setup-magento/make-magento-binaries-executable.js +44 -0
  77. package/lib/tasks/magento/setup-magento/setup-file-permissions.js +160 -0
  78. package/lib/tasks/magento/setup-magento/waiting-for-varnish.js +0 -1
  79. package/lib/tasks/php/php-container.d.ts +3 -3
  80. package/lib/tasks/php/php-container.js +22 -18
  81. package/lib/tasks/php/update-env-php.js +7 -14
  82. package/lib/tasks/project-config/index.js +0 -3
  83. package/lib/tasks/requirements/cgroup-version.js +69 -0
  84. package/lib/tasks/requirements/elasticsearch-version.js +23 -7
  85. package/lib/tasks/requirements/index.js +3 -0
  86. package/lib/tasks/requirements/opensearch-version.js +5 -5
  87. package/lib/tasks/requirements/searchengine-version.js +1 -2
  88. package/lib/tasks/start.js +2 -13
  89. package/lib/util/dockerfile-builder/build-instructions.js +5 -1
  90. package/lib/util/dockerfile-builder/types.d.ts +1 -1
  91. package/lib/util/execute-in-container.js +14 -8
  92. package/lib/util/get-installed-magento-version.js +60 -2
  93. package/lib/util/portscanner.js +3 -3
  94. package/lib/util/run-composer.js +1 -1
  95. package/lib/util/run-magento.js +2 -1
  96. package/lib/util/run-php.js +2 -1
  97. package/lib/util/set-config.js +4 -2
  98. package/package.json +16 -16
  99. package/typings/context.d.ts +13 -5
  100. package/typings/index.d.ts +10 -5
@@ -1,9 +1,11 @@
1
1
  const path = require('path')
2
2
  const fs = require('fs')
3
+ const semver = require('semver')
3
4
  const setConfigFile = require('../../util/set-config')
4
5
  const pathExists = require('../../util/path-exists')
5
6
  const KnownError = require('../../errors/known-error')
6
7
  const UnknownError = require('../../errors/unknown-error')
8
+ const { run } = require('../docker/containers/container-api')
7
9
 
8
10
  /**
9
11
  * @returns {import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
@@ -13,8 +15,7 @@ const createSSLTerminatorConfig = () => ({
13
15
  task: async (ctx) => {
14
16
  const {
15
17
  ports,
16
- config: { overridenConfiguration, baseConfig },
17
- debug,
18
+ config: { overridenConfiguration, baseConfig, docker },
18
19
  isDockerDesktop
19
20
  } = ctx
20
21
 
@@ -70,11 +71,49 @@ const createSSLTerminatorConfig = () => ({
70
71
  )
71
72
  }
72
73
 
73
- const hostMachine = !isDockerDesktop
74
- ? '127.0.0.1'
75
- : 'host.docker.internal'
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
+ }
76
92
  const hostPort = !isDockerDesktop ? ports.sslTerminator : 80
77
93
 
94
+ const nginxVersionOutput = await run({
95
+ image: sslTerminator.image,
96
+ command: 'nginx -v',
97
+ detach: false,
98
+ rm: true
99
+ })
100
+
101
+ const nginxVersionMatch = nginxVersionOutput.match(
102
+ /nginx version: nginx\/(\d+\.\d+\.\d+)/
103
+ )
104
+ if (!nginxVersionMatch) {
105
+ throw new UnknownError(
106
+ `Unexpected error appeared during ssl terminator config creation\n\n${nginxVersionOutput}`
107
+ )
108
+ }
109
+
110
+ const nginxVersion = nginxVersionMatch[1]
111
+
112
+ const isSSLDirectiveDeprecated = semver.satisfies(
113
+ nginxVersion,
114
+ '>=1.25.0'
115
+ )
116
+
78
117
  try {
79
118
  await setConfigFile({
80
119
  configPathname: path.join(
@@ -87,10 +126,10 @@ const createSSLTerminatorConfig = () => ({
87
126
  overwrite: true,
88
127
  templateArgs: {
89
128
  ports,
90
- hostMachine,
129
+ ...networkSettings,
91
130
  hostPort,
92
131
  config: overridenConfiguration,
93
- debug
132
+ isSSLDirectiveDeprecated
94
133
  }
95
134
  })
96
135
  } catch (e) {
@@ -3,6 +3,7 @@ const createNginxConfig = require('./create-nginx-config')
3
3
  const createPhpConfig = require('./create-php-config')
4
4
  const createPhpDebugConfig = require('./create-php-debug-config')
5
5
  const createPhpFpmConfig = require('./create-php-fpm-config')
6
+ const createPhpFpmDebugConfig = require('./create-php-fpm-debug-config')
6
7
  const createPhpStormConfig = require('./create-phpstorm-config')
7
8
  const createSSLTerminatorConfig = require('./create-ssl-terminator-config')
8
9
  const createVarnishConfig = require('./create-varnish-config')
@@ -19,6 +20,7 @@ const prepareFileSystem = () => ({
19
20
  createSSLTerminatorConfig(),
20
21
  createNginxConfig(),
21
22
  createPhpFpmConfig(),
23
+ createPhpFpmDebugConfig(),
22
24
  createPhpConfig(),
23
25
  createPhpDebugConfig(),
24
26
  createPhpStormConfig(),
@@ -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
- try {
217
- await runComposerCommand(ctx, 'install', {
218
- callback: !ctx.verbose
219
- ? undefined
220
- : (t) => {
221
- task.output = t
222
- }
223
- })
224
- } catch (e) {
225
- if (
226
- e instanceof UnknownError &&
227
- e.message.includes('man-in-the-middle attack')
228
- ) {
229
- throw new KnownError(`Probably you haven't setup pubkeys in composer.
230
- Please run ${logger.style.command(
231
- 'composer diagnose'
232
- )} in cli to get mode.\n\n${e}`)
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
- throw new UnknownError(
236
- `Unexpected error during composer install.\n\n${e}`
237
- )
238
- }
239
- ctx.magentoFirstInstall = true
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
@@ -0,0 +1,160 @@
1
+ const os = require('os')
2
+ const fs = require('fs')
3
+ const path = require('path')
4
+ const {
5
+ runPHPContainerCommandTask,
6
+ runPHPContainerCommand
7
+ } = require('../../php/php-container')
8
+
9
+ /**
10
+ * @returns {import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
11
+ */
12
+ const makeNewFilesCreatedInFolderUseDirectoryGroup = () => ({
13
+ title: 'Make new files created in folder use directory group',
14
+ task: (ctx, task) =>
15
+ task.newListr([
16
+ runPHPContainerCommandTask(
17
+ 'find var generated vendor pub/static pub/media app/etc -type d -exec chmod g+ws {} +',
18
+ {
19
+ // should prevent command from failing the task
20
+ // if the folder does not exist
21
+ withCode: true
22
+ }
23
+ )
24
+ ])
25
+ })
26
+
27
+ /**
28
+ * @returns {import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
29
+ */
30
+ const makeFilesWritableForGroupMembers = () => ({
31
+ title: 'Make files writable for group members',
32
+ task: (ctx, task) =>
33
+ task.newListr([
34
+ runPHPContainerCommandTask(
35
+ 'find var generated vendor pub/static pub/media app/etc -type f -exec chmod g+w {} +',
36
+ {
37
+ // should prevent command from failing the task
38
+ // if the folder does not exist
39
+ withCode: true
40
+ }
41
+ )
42
+ ])
43
+ })
44
+
45
+ /**
46
+ * @param {string} folder
47
+ * @param {string | number} user
48
+ * @param {string | number} [group]
49
+ * @returns {import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
50
+ */
51
+ const makeFolderOwnedByUser = (folder, user, group) => ({
52
+ title: `Make folder ${folder} owned by ${user} user${
53
+ group ? ` and ${group} group` : ''
54
+ }`,
55
+ task: (ctx, task) =>
56
+ task.newListr([
57
+ runPHPContainerCommandTask(
58
+ `chown -R ${user}${group ? `:${group}` : ''} ${folder}`,
59
+ {
60
+ user: 'root:root'
61
+ }
62
+ )
63
+ ])
64
+ })
65
+
66
+ /**
67
+ * @param {import('../../../../typings/context').ListrContext} ctx
68
+ */
69
+ const doesFileSystemNeedsPermissionsSetup = async (ctx) => {
70
+ const checkPHPPermissionsFileName = 'check-file-permissions.php'
71
+ const cacheDirFilePath = path.join(
72
+ ctx.config.baseConfig.cacheDir,
73
+ checkPHPPermissionsFileName
74
+ )
75
+ await fs.promises.copyFile(
76
+ path.join(__dirname, checkPHPPermissionsFileName),
77
+ cacheDirFilePath
78
+ )
79
+
80
+ const result = await runPHPContainerCommand(
81
+ ctx,
82
+ `php ${path.relative(process.cwd(), cacheDirFilePath)}`,
83
+ {
84
+ user: 'www-data:www-data',
85
+ cwd: ctx.config.baseConfig.containerMagentoDir
86
+ }
87
+ )
88
+
89
+ await fs.promises.unlink(cacheDirFilePath)
90
+
91
+ /**
92
+ * @type {{directory: string, exists: boolean, writable: boolean, permissions: string, directory_owner: {name: string, passwd: string, uid: number, gid: number, gecos: string, dir: string, shell: string} | boolean, directory_group: boolean, current_user: {name: string, passwd: string, uid: number, gid: number, gecos: string, dir: string, shell: string} | boolean, is_current_user_directory_owner: boolean}[]}
93
+ */
94
+ const parsedResult = JSON.parse(result)
95
+
96
+ if (parsedResult.some(({ exists, writable }) => exists && !writable)) {
97
+ return true
98
+ }
99
+
100
+ return false
101
+ }
102
+
103
+ /**
104
+ * @returns {import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
105
+ */
106
+ const setupMagentoFilePermissions = () => ({
107
+ title: 'Setting Magento file permissions',
108
+ // skip: true,
109
+ skip: async (ctx) =>
110
+ ctx.magentoFirstInstall ||
111
+ !(await doesFileSystemNeedsPermissionsSetup(ctx)),
112
+ task: (ctx, task) =>
113
+ task.newListr(
114
+ [
115
+ makeNewFilesCreatedInFolderUseDirectoryGroup(),
116
+ makeFilesWritableForGroupMembers()
117
+ ].concat(
118
+ ctx.isDockerDesktop
119
+ ? [
120
+ makeFolderOwnedByUser(
121
+ ctx.config.baseConfig.containerMagentoDir,
122
+ 'www-data',
123
+ 'www-data'
124
+ )
125
+ ]
126
+ : []
127
+ )
128
+ )
129
+ })
130
+
131
+ /**
132
+ * @returns {import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
133
+ */
134
+ const setupComposerCachePermissions = () => ({
135
+ title: 'Setting Composer Cache permissions',
136
+ task: (ctx, task) =>
137
+ task.newListr([
138
+ ctx.isDockerDesktop
139
+ ? makeFolderOwnedByUser(
140
+ '/composer/home',
141
+ 'www-data',
142
+ 'www-data'
143
+ )
144
+ : makeFolderOwnedByUser(
145
+ '/composer/home',
146
+ os.userInfo().uid,
147
+ os.userInfo().gid
148
+ ),
149
+
150
+ runPHPContainerCommandTask('chmod g+ws /composer/home/cache'),
151
+ runPHPContainerCommandTask('chmod g+w /composer/home/cache')
152
+ ])
153
+ })
154
+
155
+ module.exports = {
156
+ makeFilesWritableForGroupMembers,
157
+ makeNewFilesCreatedInFolderUseDirectoryGroup,
158
+ setupMagentoFilePermissions,
159
+ setupComposerCachePermissions
160
+ }
@@ -55,7 +55,6 @@ const getIsHealthCheckRequestBroken = async (ctx) => {
55
55
  const waitingForVarnish = () => ({
56
56
  title: 'Waiting for Varnish to return code 200',
57
57
  skip: (ctx) =>
58
- ctx.debug ||
59
58
  !ctx.config.overridenConfiguration.configuration.varnish.enabled ||
60
59
  ctx.config.overridenConfiguration.ssl.enabled ||
61
60
  !ctx.config.overridenConfiguration.configuration.varnish.healthCheck,
@@ -4,16 +4,16 @@ import { ExecAsyncSpawnOptions } from "../../util/exec-async-command";
4
4
  export function runPHPContainerCommand<T>(
5
5
  ctx: ListrContext,
6
6
  command: string,
7
- options?: ExecAsyncSpawnOptions<T> & { useXDebugContainer?: boolean }
7
+ options?: ExecAsyncSpawnOptions<T>
8
8
  ): Promise<any>
9
9
 
10
10
  export function runPHPContainerCommandTask<T>(
11
11
  command: string,
12
- options?: ExecAsyncSpawnOptions<T> & { useXDebugContainer?: boolean }
12
+ options?: ExecAsyncSpawnOptions<T>
13
13
  ): import('listr2').ListrTask<import('../../../typings/context').ListrContext>
14
14
 
15
15
  export function execPHPContainerCommand<T>(
16
16
  ctx: ListrContext,
17
17
  command: string,
18
- options?: ExecAsyncSpawnOptions<T> & { useXDebugContainer?: boolean }
18
+ options?: ExecAsyncSpawnOptions<T>
19
19
  ): Promise<any>
@@ -1,9 +1,12 @@
1
1
  /* eslint-disable no-use-before-define */
2
+ const os = require('os')
2
3
  const { deepmerge } = require('../../util/deepmerge')
3
4
  const { containerApi } = require('../docker/containers')
4
5
 
5
6
  /**
6
- * @type {typeof import('./php-container')['runPHPContainerCommand']}
7
+ * @param {Parameters<typeof import('./php-container')['runPHPContainerCommand']>[0]} ctx
8
+ * @param {Parameters<typeof import('./php-container')['runPHPContainerCommand']>[1]} command
9
+ * @param {Parameters<typeof import('./php-container')['runPHPContainerCommand']>[2] & { useAutomaticUser?: boolean}} [options]
7
10
  */
8
11
  const runPHPContainerCommand = async (ctx, command, options = {}) => {
9
12
  const { php } = ctx.config.docker.getContainers(ctx.ports)
@@ -23,16 +26,21 @@ const runPHPContainerCommand = async (ctx, command, options = {}) => {
23
26
  php,
24
27
  {
25
28
  detach: false,
26
- rm: true
29
+ rm: true,
30
+ command
27
31
  },
28
- options.useXDebugContainer
32
+ options.user
29
33
  ? {
30
- image: php.debugImage
34
+ user: options.user
31
35
  }
32
36
  : {},
33
- {
34
- command
35
- }
37
+ options.useAutomaticUser
38
+ ? {
39
+ user: ctx.isDockerDesktop
40
+ ? 'www-data:www-data'
41
+ : `${os.userInfo().uid}:${os.userInfo().gid}`
42
+ }
43
+ : {}
36
44
  ),
37
45
  options
38
46
  )
@@ -70,23 +78,19 @@ const execPHPContainerCommand = async (ctx, command, options = {}) => {
70
78
  }
71
79
 
72
80
  return containerApi.exec(
73
- command,
74
- php.name,
75
- deepmerge(
76
- php,
77
- options.env
78
- ? {
79
- env: options.env
80
- }
81
- : {}
82
- ),
81
+ {
82
+ container: php.name,
83
+ ...deepmerge(php, options.env ? { env: options.env } : {}),
84
+ command,
85
+ ...(options.user ? { user: options.user } : {})
86
+ },
83
87
  options
84
88
  )
85
89
  }
86
90
 
87
91
  /**
88
92
  * @param {string} command
89
- * @param {import('../../util/exec-async-command').ExecAsyncSpawnOptions<false> & { useXDebugContainer?: boolean, title?: string }} [options]
93
+ * @param {import('../../util/exec-async-command').ExecAsyncSpawnOptions<false> & { title?: string }} [options]
90
94
  * @returns {import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
91
95
  */
92
96
  const execPHPContainerCommandTask = (command, options = {}) => ({
@@ -1,5 +1,4 @@
1
1
  const path = require('path')
2
- const os = require('os')
3
2
  const getJsonfileData = require('../../util/get-jsonfile-data')
4
3
  const pathExists = require('../../util/path-exists')
5
4
  const { containerApi } = require('../docker/containers')
@@ -25,11 +24,10 @@ const updateEnvPHP = () => ({
25
24
  ? '127.0.0.1'
26
25
  : 'host.docker.internal'
27
26
 
28
- const useVarnish =
29
- !ctx.debug &&
30
- ctx.config.overridenConfiguration.configuration.varnish.enabled
31
- ? '1'
32
- : ''
27
+ const useVarnish = ctx.config.overridenConfiguration.configuration
28
+ .varnish.enabled
29
+ ? '1'
30
+ : ''
33
31
  const varnishHost = hostMachine
34
32
  const varnishPort = ctx.ports.varnish
35
33
  const previousVarnishPort = ctx.cachedPorts
@@ -66,21 +64,16 @@ const updateEnvPHP = () => ({
66
64
  HOST_MACHINE: hostMachine,
67
65
  PORTS: JSON.stringify(ctx.ports)
68
66
  },
69
- command: 'php ./update-env-php.php',
67
+ command: 'php ./update-env.php',
70
68
  mountVolumes: [
71
69
  `${path.join(__dirname, 'update-env.php')}:${
72
70
  ctx.config.baseConfig.containerMagentoDir
73
- }/update-env-php.php`,
71
+ }/update-env.php`,
74
72
  `${envPhpPath}:${ctx.config.baseConfig.containerMagentoDir}/env.php`
75
73
  ],
76
74
  image: php.image,
77
75
  detach: false,
78
- rm: true,
79
- user:
80
- (ctx.platform === 'linux' && isDockerDesktop) ||
81
- !isDockerDesktop
82
- ? `${os.userInfo().uid}:${os.userInfo().gid}`
83
- : ''
76
+ rm: true
84
77
  })
85
78
 
86
79
  task.output = result
@@ -1,4 +1,3 @@
1
- const { setProjectConfig } = require('../../config/config')
2
1
  const { setPrefix: setPrefixUtil } = require('../../util/prefix')
3
2
 
4
3
  /**
@@ -14,8 +13,6 @@ const setProjectConfigTask = () => ({
14
13
  } = ctx
15
14
 
16
15
  setPrefixUtil(prefix)
17
-
18
- setProjectConfig('debug', ctx.debug)
19
16
  },
20
17
  options: {
21
18
  showTimer: false
@@ -0,0 +1,69 @@
1
+ const semver = require('semver')
2
+ const { execAsync } = require('../../util/exec-async')
3
+ const { systemApi } = require('../docker/system')
4
+
5
+ /**
6
+ * @returns {import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
7
+ */
8
+ const checkCGroupVersion = () => ({
9
+ title: 'Checking CGroup version',
10
+ task: async (ctx, task) => {
11
+ ctx.cgroupVersion = 'v1'
12
+
13
+ let cgroupVersionDetected
14
+
15
+ if (ctx.platform === 'linux' && !ctx.isWsl) {
16
+ const cgroupVersion = await execAsync(`stat -fc %T /sys/fs/cgroup/`)
17
+
18
+ if (cgroupVersion && cgroupVersion.includes('cgroup2')) {
19
+ ctx.cgroupVersion = 'v2'
20
+
21
+ cgroupVersionDetected = true
22
+ } else {
23
+ const kernelReleaseVersionResult =
24
+ ctx.platformVersion.match(/(\d+\.\d+\.\d+)/)
25
+
26
+ if (
27
+ kernelReleaseVersionResult &&
28
+ kernelReleaseVersionResult.length > 0
29
+ ) {
30
+ const kernelVersion = kernelReleaseVersionResult[1]
31
+
32
+ if (semver.satisfies(kernelVersion, '>=6.12.0')) {
33
+ ctx.cgroupVersion = 'v2'
34
+
35
+ cgroupVersionDetected = true
36
+ } else {
37
+ cgroupVersionDetected = true
38
+ }
39
+ }
40
+ }
41
+ }
42
+
43
+ if (!cgroupVersionDetected) {
44
+ const dockerSystemVersions = await systemApi.version({
45
+ formatToJSON: true
46
+ })
47
+
48
+ const kernelReleaseVersionResult =
49
+ dockerSystemVersions.Server.KernelVersion.match(
50
+ /(\d+\.\d+\.\d+)/
51
+ )
52
+
53
+ if (
54
+ kernelReleaseVersionResult &&
55
+ kernelReleaseVersionResult.length > 0
56
+ ) {
57
+ const kernelVersion = kernelReleaseVersionResult[1]
58
+
59
+ if (semver.satisfies(kernelVersion, '>=6.12.0')) {
60
+ ctx.cgroupVersion = 'v2'
61
+ }
62
+ }
63
+ }
64
+
65
+ task.title = `Using CGroup ${ctx.cgroupVersion}`
66
+ }
67
+ })
68
+
69
+ module.exports = checkCGroupVersion