@scandipwa/magento-scripts 2.0.0-alpha.9 → 2.0.1

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 (183) hide show
  1. package/lib/commands/cli.js +18 -1
  2. package/lib/commands/logs.js +28 -2
  3. package/lib/commands/start.js +24 -3
  4. package/lib/commands/status.js +19 -1
  5. package/lib/config/config.js +20 -2
  6. package/lib/config/dependencies-for-platforms.js +1 -113
  7. package/lib/config/docker.js +94 -54
  8. package/lib/config/get-project-configuration.js +5 -0
  9. package/lib/config/index.js +10 -3
  10. package/lib/config/magento/required-php-extensions/index.js +1 -1
  11. package/lib/config/php-config.js +4 -3
  12. package/lib/config/port-config.js +3 -1
  13. package/lib/config/services/composer/versions/composer-1.js +13 -0
  14. package/lib/config/services/composer/versions/composer-2.js +8 -0
  15. package/lib/config/services/composer/versions/index.js +4 -0
  16. package/lib/config/services/elasticsearch/versions/elasticsearch-7.10.js +11 -0
  17. package/lib/config/services/elasticsearch/versions/elasticsearch-7.12.js +11 -0
  18. package/lib/config/services/elasticsearch/versions/elasticsearch-7.16.js +11 -0
  19. package/lib/config/services/elasticsearch/versions/elasticsearch-7.17.js +11 -0
  20. package/lib/config/services/elasticsearch/versions/elasticsearch-7.6.js +11 -0
  21. package/lib/config/services/elasticsearch/versions/elasticsearch-7.7.js +11 -0
  22. package/lib/config/services/elasticsearch/versions/elasticsearch-7.9.js +11 -0
  23. package/lib/config/services/elasticsearch/versions/index.js +15 -1
  24. package/lib/config/services/maildev/index.js +7 -0
  25. package/lib/config/services/mariadb/versions/index.js +5 -0
  26. package/lib/config/services/mariadb/versions/mariadb-10.2.js +8 -0
  27. package/lib/config/services/mariadb/versions/mariadb-10.3.js +8 -0
  28. package/lib/config/services/mariadb/versions/mariadb-10.4.js +8 -0
  29. package/lib/config/services/nginx/versions/index.js +3 -0
  30. package/lib/config/services/nginx/versions/nginx-1.18.js +11 -0
  31. package/lib/config/{php → services/php}/base-repo.js +0 -0
  32. package/lib/config/{php → services/php}/extensions/apcu.js +0 -0
  33. package/lib/config/{php → services/php}/extensions/bcmath.js +0 -0
  34. package/lib/config/{php → services/php}/extensions/curl.js +0 -0
  35. package/lib/config/{php → services/php}/extensions/gd.js +0 -0
  36. package/lib/config/{php → services/php}/extensions/index.js +0 -0
  37. package/lib/config/{php → services/php}/extensions/intl.js +0 -0
  38. package/lib/config/{php → services/php}/extensions/opcache.js +0 -0
  39. package/lib/config/{php → services/php}/extensions/pdo_mysql.js +0 -0
  40. package/lib/config/{php → services/php}/extensions/soap.js +0 -0
  41. package/lib/config/{php → services/php}/extensions/sodium.js +0 -0
  42. package/lib/config/{php → services/php}/extensions/xdebug.js +0 -0
  43. package/lib/config/{php → services/php}/extensions/xsl.js +0 -0
  44. package/lib/config/{php → services/php}/extensions/zip.js +0 -0
  45. package/lib/config/{php → services/php}/versions/index.js +0 -0
  46. package/lib/config/{php → services/php}/versions/php-7.2.js +1 -0
  47. package/lib/config/{php → services/php}/versions/php-7.3.js +1 -0
  48. package/lib/config/{php → services/php}/versions/php-7.4.js +1 -0
  49. package/lib/config/{php → services/php}/versions/php-8.1.js +1 -0
  50. package/lib/config/services/redis/index.js +5 -0
  51. package/lib/config/services/redis/redis-5.0.js +8 -0
  52. package/lib/config/services/redis/redis-6.0.js +8 -0
  53. package/lib/config/services/redis/redis-6.2.js +8 -0
  54. package/lib/config/{ssl-terminator → services/ssl-terminator}/index.js +3 -0
  55. package/lib/config/services/varnish/index.js +5 -0
  56. package/lib/config/{varnish → services/varnish}/varnish-6-0.js +5 -3
  57. package/lib/config/{varnish → services/varnish}/varnish-6-6.js +5 -3
  58. package/lib/config/{varnish → services/varnish}/varnish-7-0.js +5 -3
  59. package/lib/config/templates/magentorc.template +12 -5
  60. package/lib/config/templates/nginx.fastcgi_params.template +29 -0
  61. package/lib/config/templates/nginx.template.conf +1 -1
  62. package/lib/config/templates/php-debug.template.ini +31 -0
  63. package/lib/config/templates/php-fpm.template.conf +1 -2
  64. package/lib/config/templates/php.template.ini +5 -201
  65. package/lib/config/templates/ssl-terminator.template.conf +2 -0
  66. package/lib/config/templates/varnish.template.vcl +20 -13
  67. package/lib/config/versions/magento-2.2.10.js +39 -0
  68. package/lib/config/versions/magento-2.3.0.js +15 -19
  69. package/lib/config/versions/magento-2.3.1.js +15 -19
  70. package/lib/config/versions/magento-2.3.2-p1.js +15 -19
  71. package/lib/config/versions/magento-2.3.2-p2.js +15 -19
  72. package/lib/config/versions/magento-2.3.2.js +15 -19
  73. package/lib/config/versions/magento-2.3.3-p1.js +15 -19
  74. package/lib/config/versions/magento-2.3.3.js +15 -19
  75. package/lib/config/versions/magento-2.3.4-p1.js +15 -19
  76. package/lib/config/versions/magento-2.3.4-p2.js +15 -19
  77. package/lib/config/versions/magento-2.3.4.js +15 -19
  78. package/lib/config/versions/magento-2.3.5-p1.js +17 -22
  79. package/lib/config/versions/magento-2.3.5-p2.js +17 -22
  80. package/lib/config/versions/magento-2.3.5.js +17 -22
  81. package/lib/config/versions/magento-2.3.6-p1.js +17 -22
  82. package/lib/config/versions/magento-2.3.6.js +17 -22
  83. package/lib/config/versions/magento-2.3.7-p1.js +17 -22
  84. package/lib/config/versions/magento-2.3.7-p2.js +17 -22
  85. package/lib/config/versions/magento-2.3.7-p3.js +17 -22
  86. package/lib/config/versions/magento-2.3.7-p4.js +17 -22
  87. package/lib/config/versions/magento-2.3.7.js +17 -22
  88. package/lib/config/versions/magento-2.4.0-p1.js +17 -22
  89. package/lib/config/versions/magento-2.4.0.js +17 -22
  90. package/lib/config/versions/magento-2.4.1-p1.js +18 -23
  91. package/lib/config/versions/magento-2.4.1.js +18 -23
  92. package/lib/config/versions/magento-2.4.2-p1.js +18 -23
  93. package/lib/config/versions/magento-2.4.2-p2.js +18 -23
  94. package/lib/config/versions/magento-2.4.2.js +18 -23
  95. package/lib/config/versions/magento-2.4.3-p1.js +18 -23
  96. package/lib/config/versions/magento-2.4.3-p2.js +18 -23
  97. package/lib/config/versions/magento-2.4.3-p3.js +18 -23
  98. package/lib/config/versions/magento-2.4.3.js +18 -23
  99. package/lib/config/versions/magento-2.4.4-p1.js +18 -23
  100. package/lib/config/versions/magento-2.4.4-p2.js +41 -0
  101. package/lib/config/versions/magento-2.4.4.js +18 -23
  102. package/lib/config/versions/magento-2.4.5-p1.js +41 -0
  103. package/lib/config/versions/magento-2.4.5.js +18 -23
  104. package/lib/tasks/cli/create-bashrc-config.js +4 -2
  105. package/lib/tasks/composer/local-auth-json.js +1 -1
  106. package/lib/tasks/database/connect-to-database.js +6 -3
  107. package/lib/tasks/database/create-magento-database.js +5 -2
  108. package/lib/tasks/database/create-magento-user.js +50 -0
  109. package/lib/tasks/database/default-magento-database.js +3 -0
  110. package/lib/tasks/database/default-magento-user.js +7 -0
  111. package/lib/tasks/database/import-dump-to-database.js +3 -2
  112. package/lib/tasks/docker/api.d.ts +25 -1
  113. package/lib/tasks/docker/api.js +31 -1
  114. package/lib/tasks/docker/containers/container-api.d.ts +17 -0
  115. package/lib/tasks/docker/containers/container-api.js +64 -9
  116. package/lib/tasks/docker/containers/tasks.js +44 -13
  117. package/lib/tasks/docker/convert-composer-home-to-composer-cache-volume.js +52 -0
  118. package/lib/tasks/docker/convert-mysql-to-mariadb.js +2 -2
  119. package/lib/tasks/docker/image/image-api.d.ts +44 -0
  120. package/lib/tasks/docker/image/image-api.js +30 -2
  121. package/lib/tasks/docker/index.js +6 -1
  122. package/lib/tasks/docker/network/tasks.js +19 -14
  123. package/lib/tasks/docker/project-image-builder.js +39 -14
  124. package/lib/tasks/docker/system/index.js +5 -0
  125. package/lib/tasks/docker/system/system-api.d.ts +71 -0
  126. package/lib/tasks/docker/system/system-api.js +35 -0
  127. package/lib/tasks/docker/volume/index.js +2 -1
  128. package/lib/tasks/docker/volume/tasks.js +67 -9
  129. package/lib/tasks/docker/volume/volume-api.d.ts +40 -0
  130. package/lib/tasks/docker/volume/volume-api.js +55 -2
  131. package/lib/tasks/execute.js +5 -2
  132. package/lib/tasks/file-system/create-nginx-config.js +3 -5
  133. package/lib/tasks/file-system/create-php-config.js +2 -23
  134. package/lib/tasks/file-system/create-php-debug-config.js +45 -0
  135. package/lib/tasks/file-system/create-php-fpm-config.js +2 -4
  136. package/lib/tasks/file-system/create-phpstorm-config/database-config.js +24 -5
  137. package/lib/tasks/file-system/create-phpstorm-config/eslint-config.js +25 -13
  138. package/lib/tasks/file-system/create-phpstorm-config/exclude-folder-config.js +13 -3
  139. package/lib/tasks/file-system/create-phpstorm-config/index.js +2 -1
  140. package/lib/tasks/file-system/create-phpstorm-config/inspection-tools-config/custom-ruleset-path-config.js +18 -7
  141. package/lib/tasks/file-system/create-phpstorm-config/inspection-tools-config/paths.js +4 -0
  142. package/lib/tasks/file-system/create-ssl-terminator-config.js +23 -8
  143. package/lib/tasks/file-system/create-varnish-config.js +4 -7
  144. package/lib/tasks/file-system/create-vscode-config.js +2 -1
  145. package/lib/tasks/file-system/index.js +3 -2
  146. package/lib/tasks/magento/setup-magento/configure-elasticsearch.js +2 -4
  147. package/lib/tasks/magento/setup-magento/flush-redis-config.js +3 -6
  148. package/lib/tasks/magento/setup-magento/index.js +2 -0
  149. package/lib/tasks/magento/setup-magento/install-magento.js +8 -13
  150. package/lib/tasks/magento/setup-magento/set-base-url.js +2 -1
  151. package/lib/tasks/magento/setup-magento/set-mail-config.js +22 -0
  152. package/lib/tasks/magento/setup-magento/varnish-config.js +4 -9
  153. package/lib/tasks/magento/setup-magento/waiting-for-varnish.js +15 -16
  154. package/lib/tasks/php/php-container.js +1 -1
  155. package/lib/tasks/php/update-env-php.js +4 -6
  156. package/lib/tasks/{prefix → project-config}/index.js +6 -6
  157. package/lib/tasks/requirements/composer-credentials.js +7 -3
  158. package/lib/tasks/requirements/docker/context.js +88 -0
  159. package/lib/tasks/requirements/docker/index.js +111 -19
  160. package/lib/tasks/requirements/docker/install.js +21 -7
  161. package/lib/tasks/requirements/docker/permissions.js +2 -11
  162. package/lib/tasks/requirements/docker/running-status.js +94 -24
  163. package/lib/tasks/requirements/docker/version.js +1 -0
  164. package/lib/tasks/requirements/index.js +0 -2
  165. package/lib/tasks/requirements/php-version.js +4 -2
  166. package/lib/tasks/start.js +27 -8
  167. package/lib/tasks/status/index.js +86 -21
  168. package/lib/tasks/stop.js +2 -0
  169. package/lib/tasks/theme/retrieve-theme-data.js +12 -2
  170. package/lib/util/config-file-validator.js +17 -3
  171. package/lib/util/connection-string.js +62 -0
  172. package/lib/util/execute-in-container.js +7 -8
  173. package/lib/util/instance-metadata.js +14 -2
  174. package/lib/util/systemctl.js +62 -13
  175. package/package.json +2 -2
  176. package/typings/context.d.ts +11 -0
  177. package/typings/index.d.ts +46 -1
  178. package/lib/tasks/requirements/dependency/arch.js +0 -50
  179. package/lib/tasks/requirements/dependency/centos.js +0 -36
  180. package/lib/tasks/requirements/dependency/fedora.js +0 -36
  181. package/lib/tasks/requirements/dependency/index.js +0 -33
  182. package/lib/tasks/requirements/dependency/mac.js +0 -124
  183. package/lib/tasks/requirements/dependency/ubuntu.js +0 -83
@@ -4,9 +4,9 @@ const fs = require('fs');
4
4
  const path = require('path');
5
5
  const { request } = require('smol-request');
6
6
  const KnownError = require('../../../errors/known-error');
7
- const { execAsyncSpawn } = require('../../../util/exec-async-command');
8
7
  const { NginxParser } = require('../../../util/nginx-logs-parser');
9
8
  const sleep = require('../../../util/sleep');
9
+ const { containerApi } = require('../../docker/containers');
10
10
 
11
11
  const pathToWorkingHealthCheckPhp = path.join(__dirname, '..', '..', 'php', 'working_health_check.php');
12
12
  const pathToProjectsHealthCheckPhp = path.join(process.cwd(), 'pub', 'health_check.php');
@@ -17,19 +17,18 @@ const pathToHealthCheckBackupPhp = path.join(process.cwd(), 'pub', 'health_check
17
17
  */
18
18
  const getIsHealthCheckRequestBroken = async (ctx) => {
19
19
  const { nginx } = ctx.config.docker.getContainers(ctx.ports);
20
-
21
- const nginxLogs = await execAsyncSpawn(`docker logs ${nginx.name}`);
22
-
23
- const healthCheckRequests = nginxLogs
24
- .split('\n')
25
- .filter((line) => line.includes('"GET /health_check.php HTTP/1.1"'));
26
-
27
- // eslint-disable-next-line max-len
28
- const parser = new NginxParser('$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"');
29
-
30
- const parsedRequests = healthCheckRequests.map((line) => parser.parseLine(line));
31
-
32
- return parsedRequests.every((parsedRequest) => parsedRequest.status !== '200');
20
+ const parser = new NginxParser(
21
+ '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"'
22
+ );
23
+ const parsedLogs = await containerApi.logs({
24
+ name: nginx.name,
25
+ parser: (line) => parser.parseLine(line)
26
+ });
27
+
28
+ const healthCheckRequests = parsedLogs
29
+ .filter((line) => line.request.includes('/health_check.php'));
30
+
31
+ return healthCheckRequests.every((parsedRequest) => parsedRequest.status !== '200');
33
32
  };
34
33
 
35
34
  /**
@@ -39,12 +38,12 @@ const waitingForVarnish = () => ({
39
38
  title: 'Waiting for Varnish to return code 200',
40
39
  skip: (ctx) => ctx.debug
41
40
  || !ctx.config.overridenConfiguration.configuration.varnish.enabled
42
- || ctx.config.overridenConfiguration.ssl.enabled,
41
+ || ctx.config.overridenConfiguration.ssl.enabled
42
+ || !ctx.config.overridenConfiguration.configuration.varnish.healthCheck,
43
43
  task: async (ctx, task) => {
44
44
  const pureMagentoVersion = ctx.magentoVersion.match(/^([0-9]+\.[0-9]+\.[0-9]+)/)[1];
45
45
 
46
46
  const isMagento23 = semver.satisfies(pureMagentoVersion, '<2.4');
47
-
48
47
  let tries = 0;
49
48
  while (tries < 10) {
50
49
  try {
@@ -29,7 +29,7 @@ const runPHPContainerCommand = async (ctx, command, options = {}) => {
29
29
  },
30
30
  options.useXDebugContainer
31
31
  ? {
32
- image: `${ php.image }.xdebug`
32
+ image: php.debugImage
33
33
  }
34
34
  : {},
35
35
  {
@@ -19,11 +19,10 @@ const updateEnvPHP = () => ({
19
19
  return;
20
20
  }
21
21
 
22
+ const { isDockerDesktop } = ctx;
22
23
  const { php } = ctx.config.docker.getContainers(ctx.ports);
23
24
 
24
- const isLinux = ctx.platform === 'linux';
25
- const isNativeLinux = isLinux && !ctx.isWsl;
26
- const hostMachine = isNativeLinux ? '127.0.0.1' : 'host.docker.internal';
25
+ const hostMachine = !isDockerDesktop ? '127.0.0.1' : 'host.docker.internal';
27
26
 
28
27
  const useVarnish = (!ctx.debug && ctx.config.overridenConfiguration.configuration.varnish.enabled) ? '1' : '';
29
28
  const varnishHost = hostMachine;
@@ -53,7 +52,6 @@ const updateEnvPHP = () => ({
53
52
  || persistedQueryConfig.redis.host === hostMachine)
54
53
  ) {
55
54
  SETUP_PQ = '';
56
- return;
57
55
  }
58
56
  }
59
57
  }
@@ -73,12 +71,12 @@ const updateEnvPHP = () => ({
73
71
  command: 'php ./update-env-php.php',
74
72
  mountVolumes: [
75
73
  `${path.join(__dirname, 'update-env.php')}:${ctx.config.baseConfig.containerMagentoDir}/update-env-php.php`,
76
- `${envPhpPath}:/${ctx.config.baseConfig.containerMagentoDir}/env.php`
74
+ `${envPhpPath}:${ctx.config.baseConfig.containerMagentoDir}/env.php`
77
75
  ],
78
76
  image: php.image,
79
77
  detach: false,
80
78
  rm: true,
81
- user: isLinux ? `${os.userInfo().uid}:${os.userInfo().gid}` : ''
79
+ user: ((ctx.platform === 'linux' && isDockerDesktop) || !isDockerDesktop) ? `${os.userInfo().uid}:${os.userInfo().gid}` : ''
82
80
  });
83
81
 
84
82
  task.output = result;
@@ -1,21 +1,21 @@
1
+ const { setProjectConfig } = require('../../config/config');
1
2
  const { setPrefix: setPrefixUtil } = require('../../util/prefix');
2
3
 
3
4
  /**
4
5
  * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
5
6
  */
6
- const setPrefix = () => ({
7
- // if project is missing prefix, set one
8
- title: 'Settings project prefix',
7
+ const setProjectConfigTask = () => ({
8
+ title: 'Settings project config',
9
9
  task: (ctx) => {
10
10
  const { config: { overridenConfiguration: { prefix } } } = ctx;
11
11
 
12
12
  setPrefixUtil(prefix);
13
+
14
+ setProjectConfig('debug', ctx.debug);
13
15
  },
14
16
  options: {
15
17
  showTimer: false
16
18
  }
17
19
  });
18
20
 
19
- module.exports = {
20
- setPrefix
21
- };
21
+ module.exports = { setProjectConfigTask };
@@ -96,9 +96,9 @@ ${ logger.style.misc('Password') } (${ logger.style.misc('Private key') }):`,
96
96
  };
97
97
 
98
98
  const authJsonContent = JSON.stringify(authContent, null, 4);
99
- const authEnvContent = `export COMPOSER_AUTH='${JSON.stringify(authContent)}'`;
99
+ const authEnvContent = `export COMPOSER_AUTH='${JSON.stringify(authContent, null, 0)}'`;
100
100
 
101
- process.env.COMPOSER_AUTH = authJsonContent;
101
+ process.env.COMPOSER_AUTH = JSON.stringify(JSON.parse(authJsonContent), null, 0);
102
102
 
103
103
  if (configureLocation === 'auth.json') {
104
104
  await fs.promises.writeFile(authJsonPath, authJsonContent, 'utf-8');
@@ -175,7 +175,11 @@ Would you like to load them now?`
175
175
 
176
176
  if (loadCredentialsFrom) {
177
177
  const credentialsLine = lines.find((line) => line.startsWith('export COMPOSER_AUTH='));
178
- process.env.COMPOSER_AUTH = credentialsLine.replace('export COMPOSER_AUTH=', '').replace(/'/ig, '').trim();
178
+ process.env.COMPOSER_AUTH = JSON.stringify(
179
+ JSON.parse(credentialsLine.replace('export COMPOSER_AUTH=', '').replace(/'/ig, '').trim()),
180
+ null,
181
+ 0
182
+ );
179
183
  problems.delete(MISSING_COMPOSER_AUTH_ENV);
180
184
  }
181
185
  }
@@ -0,0 +1,88 @@
1
+ const logger = require('@scandipwa/scandipwa-dev-utils/logger');
2
+ const os = require('os');
3
+ const { cmaGlobalConfig } = require('../../../config/cma-config');
4
+ const { getCachedPorts } = require('../../../config/get-port-config');
5
+ const { getSystemConfigTask } = require('../../../config/system-config');
6
+ const UnknownError = require('../../../errors/unknown-error');
7
+ const { execCommandTask } = require('../../../util/exec-async-command');
8
+ const createCacheFolder = require('../../cache/create-cache-folder');
9
+ const { dockerApi } = require('../../docker');
10
+ const { stopContainers } = require('../../docker/containers');
11
+ const { getDockerEngineAndDesktopServiceStatus } = require('./running-status');
12
+ const getMagentoVersionConfig = require('../../../config/get-magento-version-config');
13
+ const checkConfigurationFile = require('../../../config/check-configuration-file');
14
+ const getProjectConfiguration = require('../../../config/get-project-configuration');
15
+ const getDockerVersion = require('./version');
16
+
17
+ const USE_DEFAULT_DOCKER_DESKTOP_CONTEXT_ANSWER = 'useDefaultDockerDesktopContext';
18
+
19
+ /**
20
+ * @type {() => import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
21
+ */
22
+ const checkDockerDesktopContext = () => ({
23
+ task: async (ctx, task) => {
24
+ if (os.platform() !== 'linux' || !ctx.isDockerDesktop) {
25
+ task.skip();
26
+ return;
27
+ }
28
+
29
+ task.title = 'Checking contexts for Docker Desktop';
30
+
31
+ const contexts = await dockerApi.context({ formatToJSON: true });
32
+ const currentlyUsedContext = contexts.find((c) => c.Current);
33
+
34
+ if (!currentlyUsedContext) {
35
+ throw new UnknownError('We haven\'t found contexts in Docker...');
36
+ }
37
+
38
+ const { engine } = await getDockerEngineAndDesktopServiceStatus();
39
+
40
+ if (currentlyUsedContext.Name !== 'default' && engine.exists) {
41
+ if (cmaGlobalConfig.get(USE_DEFAULT_DOCKER_DESKTOP_CONTEXT_ANSWER) === false) {
42
+ task.skip();
43
+ return;
44
+ }
45
+
46
+ const confirmContextChange = await task.prompt({
47
+ type: 'Select',
48
+ message: `Do you want to change current Docker Desktop context (${logger.style.code(currentlyUsedContext.Name)}) to ${logger.style.code('default')}?`,
49
+ choices: [
50
+ {
51
+ name: 'yes',
52
+ message: 'Yes'
53
+ },
54
+ {
55
+ name: 'no',
56
+ message: 'No, I don\'t know what this means, but you can ask again on next start.'
57
+ },
58
+ {
59
+ name: 'skip',
60
+ // eslint-disable-next-line max-len
61
+ message: 'I do know what this means and I DON\'T want to change context for Docker. Also, save this answer to never ask again.'
62
+ }
63
+ ]
64
+ });
65
+
66
+ if (confirmContextChange === 'skip') {
67
+ cmaGlobalConfig.set(USE_DEFAULT_DOCKER_DESKTOP_CONTEXT_ANSWER, false);
68
+ task.skip();
69
+ }
70
+
71
+ if (confirmContextChange === 'yes') {
72
+ return task.newListr([
73
+ getMagentoVersionConfig(),
74
+ checkConfigurationFile(),
75
+ getProjectConfiguration(),
76
+ createCacheFolder(),
77
+ getSystemConfigTask(),
78
+ getCachedPorts(),
79
+ stopContainers(),
80
+ execCommandTask('docker context use default'),
81
+ getDockerVersion()
82
+ ]);
83
+ }
84
+ }
85
+ }
86
+ });
87
+
88
+ module.exports = checkDockerDesktopContext;
@@ -1,17 +1,23 @@
1
+ const os = require('os');
1
2
  const logger = require('@scandipwa/scandipwa-dev-utils/logger');
3
+ const { cmaGlobalConfig } = require('../../../config/cma-config');
2
4
  const KnownError = require('../../../errors/known-error');
3
5
  const { execAsyncSpawn } = require('../../../util/exec-async-command');
4
6
  const openBrowser = require('../../../util/open-browser');
5
- const installDocker = require('./install');
7
+ const checkDockerDesktopContext = require('./context');
8
+ const { installDockerEngine } = require('./install');
6
9
  const installDockerOnMac = require('./install-on-mac');
7
10
  const { checkDockerPerformance } = require('./performance');
8
11
  const { checkDockerSocketPermissions } = require('./permissions');
9
- const checkDockerStatus = require('./running-status');
12
+ const { checkDockerStatus, getDockerEngineAndDesktopServiceStatus } = require('./running-status');
10
13
  const getDockerVersion = require('./version');
14
+ const getIsWsl = require('../../../util/is-wsl');
15
+
16
+ const USE_DOCKER_ENGINE_WITH_DOCKER_DESKTOP_ANSWER = 'useDockerEngineWithDockerDesktop';
11
17
 
12
18
  const setVersionInContextTask = (task) => ({
13
19
  task: (ctx) => {
14
- if (ctx.platform === 'darwin' && ctx.dockerServerData && ctx.dockerServerData.Platform && ctx.dockerServerData.Platform.Name) {
20
+ if (os.platform() === 'darwin' && ctx.dockerServerData && ctx.dockerServerData.Platform && ctx.dockerServerData.Platform.Name) {
15
21
  task.title = `Using ${ctx.dockerServerData.Platform.Name} for Mac`;
16
22
  } else {
17
23
  task.title = `Using Docker version ${ctx.dockerVersion}`;
@@ -19,33 +25,72 @@ const setVersionInContextTask = (task) => ({
19
25
  }
20
26
  });
21
27
 
22
- const dockerInstallPromptLinux = async (task) => {
23
- const automaticallyInstallDocker = await task.prompt({
24
- type: 'Confirm',
28
+ const dockerInstallPromptLinux = async (task, { skipPrompt = false } = {}) => {
29
+ const automaticallyInstallDocker = skipPrompt ? 'yes' : await task.prompt({
30
+ type: 'Select',
25
31
  message: `You don't have Docker installed!
26
32
  Do you want to install it automatically?
27
- NOTE: After installation it's recommended to log out and log back in so your group membership is re-evaluated!`
33
+ `,
34
+ choices: [
35
+ {
36
+ name: 'yes',
37
+ message: 'Yes, I to install Docker automatically'
38
+ },
39
+ {
40
+ name: 'no',
41
+ message: 'No, I want to install Docker myself'
42
+ },
43
+ {
44
+ name: 'skip',
45
+ message: 'Skip installing Docker'
46
+ }
47
+ ]
28
48
  });
29
49
 
30
- if (automaticallyInstallDocker) {
50
+ if (automaticallyInstallDocker === 'yes') {
31
51
  return task.newListr([
32
- installDocker(),
52
+ installDockerEngine(),
33
53
  checkDockerSocketPermissions(),
34
54
  getDockerVersion(),
35
55
  {
36
- task: (ctx) => {
56
+ task: async (ctx) => {
37
57
  task.title = `Using docker version ${ctx.dockerVersion}`;
38
58
 
59
+ const confirmLogOut = await task.prompt({
60
+ type: 'Select',
61
+ message: 'Docker installed successfully!\n',
62
+ choices: [
63
+ {
64
+ name: 'log-out',
65
+ message: `${logger.style.command('[Recommended]')} Now I will log out and log back it (or restart my system) to re-evaluate group membership`
66
+ },
67
+ {
68
+ name: 'skip',
69
+ message: 'Skip log out and proceed with installation'
70
+ }
71
+ ]
72
+ });
73
+
74
+ if (confirmLogOut === 'skip') {
75
+ return;
76
+ }
77
+
39
78
  throw new KnownError(
40
79
  `Docker is installed successfully!
41
- Please log out and log back to so your group membership is re-evaluated!
80
+ Please log out and log back in (or restart your system) so your group membership is re-evaluated!
42
81
  Learn more here: ${ logger.style.link('https://docs.docker.com/engine/install/linux-postinstall/') }`
43
82
  );
44
83
  }
45
- }
84
+ },
85
+ checkDockerStatus(),
86
+ checkDockerDesktopContext()
46
87
  ]);
47
88
  }
48
89
 
90
+ if (automaticallyInstallDocker === 'skip') {
91
+ return;
92
+ }
93
+
49
94
  throw new KnownError('Docker is not installed!');
50
95
  };
51
96
 
@@ -65,7 +110,8 @@ const dockerInstallPromptMacOS = async (task) => {
65
110
  const confirmationToInstallDocker = await task.prompt({
66
111
  type: 'Select',
67
112
  message: `You don't have Docker installed!
68
- Would you like to install it automatically using brew cask or you prefer to install it manually?`,
113
+ Would you like to install it automatically using brew cask or you prefer to install it manually?
114
+ `,
69
115
  choices: [
70
116
  {
71
117
  name: 'automatic',
@@ -108,25 +154,71 @@ const checkDocker = () => ({
108
154
  });
109
155
 
110
156
  if (code !== 0) {
111
- if (ctx.platform === 'linux' && !ctx.isWsl) {
112
- const result = await dockerInstallPromptLinux(task);
113
- if (result) {
114
- return result;
157
+ if (os.platform() === 'linux') {
158
+ const isWsl = await getIsWsl();
159
+ if (!isWsl) {
160
+ const { engine } = await getDockerEngineAndDesktopServiceStatus();
161
+ if (!engine.exists) {
162
+ const result = await dockerInstallPromptLinux(task);
163
+ if (result) {
164
+ return result;
165
+ }
166
+ }
167
+ } else if (isWsl) {
168
+ dockerInstallPromptWindows();
115
169
  }
116
- } else if (ctx.isWsl) {
117
- dockerInstallPromptWindows();
118
170
  } else {
119
171
  const result = await dockerInstallPromptMacOS(task);
120
172
  if (result) {
121
173
  return result;
122
174
  }
123
175
  }
176
+ } else if (os.platform() === 'linux') {
177
+ const { engine, desktop } = await getDockerEngineAndDesktopServiceStatus();
178
+ if (!engine.exists
179
+ && desktop.exists
180
+ && cmaGlobalConfig.get(USE_DOCKER_ENGINE_WITH_DOCKER_DESKTOP_ANSWER) !== false
181
+ ) {
182
+ const confirmInstallingDockerEngine = await task.prompt({
183
+ type: 'Select',
184
+ message: `Looks like you have Docker Desktop installed on Linux system, but Docker Engine is not installed.
185
+ Do you want to install it and use it's context together with Docker Desktop?
186
+ `,
187
+ choices: [
188
+ {
189
+ name: 'yes',
190
+ message: 'Sure, if it means I will have less issues with my setup!'
191
+ },
192
+ {
193
+ name: 'no',
194
+ message: 'No. But you can ask me again later.'
195
+ },
196
+ {
197
+ name: 'skip',
198
+ message: 'No. And don\'t ask me again.'
199
+ }
200
+ ]
201
+ });
202
+
203
+ if (confirmInstallingDockerEngine === 'skip') {
204
+ cmaGlobalConfig.set(USE_DOCKER_ENGINE_WITH_DOCKER_DESKTOP_ANSWER, false);
205
+ } else if (confirmInstallingDockerEngine === 'yes') {
206
+ const result = await dockerInstallPromptLinux(task, {
207
+ skipPrompt: true
208
+ });
209
+
210
+ if (result) {
211
+ return result;
212
+ }
213
+ }
214
+ }
124
215
  }
125
216
 
126
217
  return task.newListr([
127
218
  checkDockerSocketPermissions(),
128
219
  checkDockerStatus(),
129
220
  getDockerVersion(),
221
+ checkDockerDesktopContext(),
130
222
  setVersionInContextTask(task)
131
223
  ]);
132
224
  }
@@ -17,8 +17,8 @@ const postInstallSteps = [
17
17
  /**
18
18
  * @type {() => import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
19
19
  */
20
- const installDocker = () => ({
21
- title: 'Installing Docker',
20
+ const installDockerEngine = () => ({
21
+ title: 'Installing Docker Engine',
22
22
  task: async (ctx, task) => {
23
23
  const distro = await osPlatform();
24
24
  switch (distro) {
@@ -32,12 +32,21 @@ const installDocker = () => ({
32
32
  ...postInstallSteps
33
33
  ]);
34
34
  }
35
- case 'Fedora':
35
+ case 'Fedora': {
36
+ return task.newListr([
37
+ executeSudoCommand('sudo dnf -y install dnf-plugins-core'),
38
+ executeSudoCommand('sudo dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo'),
39
+ executeSudoCommand('sudo dnf -y install docker-ce docker-ce-cli containerd.io docker-compose-plugin'),
40
+ enableAndStartDockerCommand(),
41
+ ...postInstallSteps
42
+ ]);
43
+ }
36
44
  case 'CentOS': {
37
45
  return task.newListr([
38
- downloadDockerInstallScriptCommand(),
39
- runDockerInstallScriptCommand(),
40
- enableAndStartDockerCommand()
46
+ executeSudoCommand('sudo yum install -y yum-utils'),
47
+ executeSudoCommand('sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo'),
48
+ executeSudoCommand('sudo yum install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin'),
49
+ ...postInstallSteps
41
50
  ]);
42
51
  }
43
52
  case 'Ubuntu': {
@@ -53,7 +62,12 @@ const installDocker = () => ({
53
62
  Your distro ${distro} is not supported by automatic installation.`);
54
63
  }
55
64
  }
65
+ },
66
+ options: {
67
+ bottomBar: 10
56
68
  }
57
69
  });
58
70
 
59
- module.exports = installDocker;
71
+ module.exports = {
72
+ installDockerEngine
73
+ };
@@ -2,7 +2,7 @@ const os = require('os');
2
2
  const fs = require('fs');
3
3
  const logger = require('@scandipwa/scandipwa-dev-utils/logger');
4
4
  const pathExists = require('../../../util/path-exists');
5
- const { execCommandTask } = require('../../../util/exec-async-command');
5
+ const executeSudoCommand = require('../../../util/execute-sudo-command');
6
6
 
7
7
  const dockerSocketPath = '/var/run/docker.sock';
8
8
 
@@ -33,16 +33,7 @@ Otherwise installation will likely fail.`
33
33
  });
34
34
 
35
35
  if (confirmPrompt) {
36
- task.output = 'Enter your sudo password!';
37
- task.output = logger.style.command(`>[sudo] password for ${ os.userInfo().username }:`);
38
- return task.newListr(
39
- execCommandTask(fixCommand, {
40
- callback: (t) => {
41
- task.output = t;
42
- },
43
- pipeInput: true
44
- })
45
- );
36
+ return task.newListr(executeSudoCommand(fixCommand));
46
37
  }
47
38
  task.skip(`Permission issue detected in ${ logger.style.file(dockerSocketPath) } but user decided not to fix it.`);
48
39
  }
@@ -10,6 +10,41 @@ const getDockerVersion = () => execAsyncSpawn('docker version --format {{.Server
10
10
  withCode: true
11
11
  });
12
12
 
13
+ const getDockerEngineAndDesktopServiceStatus = async () => {
14
+ const dockerEngineService = systemctlControl('docker');
15
+ const dockerDesktopService = systemctlControl('docker-desktop', { user: true });
16
+ const [
17
+ dockerEngineServiceExists,
18
+ dockerDesktopServiceExists,
19
+ dockerEngineServiceIsRunning,
20
+ dockerDesktopServiceIsRunning,
21
+ dockerEngineServiceIsEnabled,
22
+ dockerDesktopServiceIsEnabled
23
+ ] = await Promise.all([
24
+ dockerEngineService.exists(),
25
+ dockerDesktopService.exists(),
26
+ dockerEngineService.isRunning(),
27
+ dockerDesktopService.isRunning(),
28
+ dockerEngineService.isEnabled(),
29
+ dockerDesktopService.isEnabled()
30
+ ]);
31
+
32
+ return {
33
+ engine: {
34
+ service: dockerEngineService,
35
+ exists: dockerEngineServiceExists,
36
+ isRunning: dockerEngineServiceIsRunning,
37
+ isEnabled: dockerEngineServiceIsEnabled
38
+ },
39
+ desktop: {
40
+ service: dockerDesktopService,
41
+ exists: dockerDesktopServiceExists,
42
+ isRunning: dockerDesktopServiceIsRunning,
43
+ isEnabled: dockerDesktopServiceIsEnabled
44
+ }
45
+ };
46
+ };
47
+
13
48
  /**
14
49
  * @type {() => import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
15
50
  */
@@ -81,39 +116,71 @@ Please open Docker Desktop application for Windows and make sure that Docker is
81
116
  const checkDockerStatusLinux = () => ({
82
117
  title: 'Checking Docker status on Linux',
83
118
  task: async (ctx, task) => {
84
- const dockerService = systemctlControl('docker');
119
+ const {
120
+ engine,
121
+ desktop
122
+ } = await getDockerEngineAndDesktopServiceStatus();
123
+
124
+ if (engine.exists) {
125
+ if (!engine.isEnabled && !engine.isRunning) {
126
+ const dockerStartConfirmation = await task.prompt({
127
+ type: 'Confirm',
128
+ message: `Looks like Docker Engine is not enabled and not running, would you like to enable and run it?
85
129
 
86
- const isRunning = await dockerService.isRunning();
87
- const isEnabled = await dockerService.isEnabled();
130
+ This action requires root privileges.`
131
+ });
132
+
133
+ if (dockerStartConfirmation) {
134
+ await engine.service.enableAndStart();
88
135
 
89
- if (!isEnabled && !isRunning) {
90
- const dockerStartConfirmation = await task.prompt({
91
- type: 'Confirm',
92
- message: `Looks like Docker is not enabled and not running, would you like to enable and run it?
136
+ return;
137
+ }
138
+ task.skip('User skipped running Docker');
139
+ } else if (!engine.isRunning) {
140
+ const dockerStartConfirmation = await task.prompt({
141
+ type: 'Confirm',
142
+ message: `Looks like Docker Engine is not running, would you like to run it?
93
143
 
94
- This action requires root privileges.`
95
- });
144
+ This action requires root privileges.`
145
+ });
96
146
 
97
- if (dockerStartConfirmation) {
98
- await dockerService.enableAndStart();
147
+ if (dockerStartConfirmation) {
148
+ await engine.service.start();
99
149
 
100
- return;
150
+ return;
151
+ }
152
+ task.skip('User skipped running Docker Engine');
101
153
  }
102
- task.skip('User skipped running Docker');
103
- } else if (!isRunning) {
104
- const dockerStartConfirmation = await task.prompt({
105
- type: 'Confirm',
106
- message: `Looks like Docker is not running, would you like to run it?
154
+ } else if (desktop.exists) {
155
+ if (!desktop.isEnabled && !desktop.isRunning) {
156
+ const dockerStartConfirmation = await task.prompt({
157
+ type: 'Confirm',
158
+ message: `Looks like Docker Desktop is not enabled and not running, would you like to enable and run it?
159
+
160
+ This action requires root privileges.`
161
+ });
162
+
163
+ if (dockerStartConfirmation) {
164
+ await desktop.service.enableAndStart();
165
+
166
+ return;
167
+ }
168
+ task.skip('User skipped running Docker');
169
+ } else if (!desktop.isRunning) {
170
+ const dockerStartConfirmation = await task.prompt({
171
+ type: 'Confirm',
172
+ message: `Looks like Docker Desktop is not running, would you like to run it?
107
173
 
108
- This action requires root privileges.`
109
- });
174
+ This action requires root privileges.`
175
+ });
110
176
 
111
- if (dockerStartConfirmation) {
112
- await dockerService.start();
177
+ if (dockerStartConfirmation) {
178
+ await desktop.service.start();
113
179
 
114
- return;
180
+ return;
181
+ }
182
+ task.skip('User skipped running Docker Desktop');
115
183
  }
116
- task.skip('User skipped running Docker');
117
184
  }
118
185
  }
119
186
  });
@@ -135,4 +202,7 @@ const checkDockerStatus = () => ({
135
202
  }
136
203
  });
137
204
 
138
- module.exports = checkDockerStatus;
205
+ module.exports = {
206
+ checkDockerStatus,
207
+ getDockerEngineAndDesktopServiceStatus
208
+ };