@scandipwa/magento-scripts 2.1.4 → 2.2.0

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 (98) hide show
  1. package/lib/config/docker.js +29 -12
  2. package/lib/config/get-magento-version-config.js +4 -1
  3. package/lib/config/php-config.js +2 -1
  4. package/lib/config/services/composer/versions/composer-1.js +1 -1
  5. package/lib/config/services/composer/versions/composer-2.2.js +8 -0
  6. package/lib/config/services/composer/versions/composer-2.js +1 -1
  7. package/lib/config/services/composer/versions/index.js +2 -1
  8. package/lib/config/services/elasticsearch/versions/elasticsearch-8.4.js +4 -1
  9. package/lib/config/services/elasticsearch/versions/elasticsearch-8.5.js +4 -1
  10. package/lib/config/services/elasticsearch/versions/elasticsearch-8.7.js +14 -0
  11. package/lib/config/services/elasticsearch/versions/index.js +3 -1
  12. package/lib/config/services/mysql/versions/mysql-8.0.js +1 -1
  13. package/lib/config/services/php/default-php-env.js +6 -0
  14. package/lib/config/services/php/versions/php-7.2.js +3 -1
  15. package/lib/config/services/php/versions/php-7.3.js +3 -1
  16. package/lib/config/services/php/versions/php-7.4.js +3 -1
  17. package/lib/config/services/php/versions/php-8.1.js +3 -1
  18. package/lib/config/services/php/versions/php-8.2.js +3 -1
  19. package/lib/config/ssl-config.js +9 -0
  20. package/lib/config/templates/nginx.fastcgi_params.template +2 -2
  21. package/lib/config/templates/nginx.template.conf +19 -2
  22. package/lib/config/templates/ssl-terminator.template.conf +2 -6
  23. package/lib/config/versions/index.js +16 -33
  24. package/lib/config/versions/magento-2.2.10.js +3 -12
  25. package/lib/config/versions/magento-2.3.0.js +3 -12
  26. package/lib/config/versions/magento-2.3.1.js +3 -12
  27. package/lib/config/versions/magento-2.3.2-p1.js +3 -12
  28. package/lib/config/versions/magento-2.3.2-p2.js +3 -12
  29. package/lib/config/versions/magento-2.3.2.js +3 -12
  30. package/lib/config/versions/magento-2.3.3-p1.js +3 -12
  31. package/lib/config/versions/magento-2.3.3.js +3 -12
  32. package/lib/config/versions/magento-2.3.4-p1.js +3 -12
  33. package/lib/config/versions/magento-2.3.4-p2.js +3 -12
  34. package/lib/config/versions/magento-2.3.4.js +3 -12
  35. package/lib/config/versions/magento-2.3.5-p1.js +3 -12
  36. package/lib/config/versions/magento-2.3.5-p2.js +3 -12
  37. package/lib/config/versions/magento-2.3.5.js +3 -17
  38. package/lib/config/versions/magento-2.3.6-p1.js +3 -12
  39. package/lib/config/versions/magento-2.3.6.js +3 -12
  40. package/lib/config/versions/magento-2.3.7-p1.js +3 -12
  41. package/lib/config/versions/magento-2.3.7-p2.js +3 -12
  42. package/lib/config/versions/magento-2.3.7-p3.js +3 -12
  43. package/lib/config/versions/magento-2.3.7-p4.js +3 -12
  44. package/lib/config/versions/magento-2.3.7.js +3 -12
  45. package/lib/config/versions/magento-2.4.0-p1.js +3 -12
  46. package/lib/config/versions/magento-2.4.0.js +3 -12
  47. package/lib/config/versions/magento-2.4.1-p1.js +3 -12
  48. package/lib/config/versions/magento-2.4.1.js +3 -12
  49. package/lib/config/versions/magento-2.4.2-p1.js +3 -13
  50. package/lib/config/versions/magento-2.4.2-p2.js +3 -13
  51. package/lib/config/versions/magento-2.4.2.js +3 -12
  52. package/lib/config/versions/magento-2.4.3-p1.js +3 -13
  53. package/lib/config/versions/magento-2.4.3-p2.js +3 -13
  54. package/lib/config/versions/magento-2.4.3-p3.js +3 -13
  55. package/lib/config/versions/magento-2.4.3.js +3 -13
  56. package/lib/config/versions/magento-2.4.4-p1.js +3 -13
  57. package/lib/config/versions/magento-2.4.4-p2.js +3 -13
  58. package/lib/config/versions/magento-2.4.4-p3.js +3 -13
  59. package/lib/config/versions/magento-2.4.4-p4.js +1 -10
  60. package/lib/config/versions/magento-2.4.4-p5.js +38 -0
  61. package/lib/config/versions/magento-2.4.4-p6.js +38 -0
  62. package/lib/config/versions/magento-2.4.4.js +3 -13
  63. package/lib/config/versions/magento-2.4.5-p1.js +3 -13
  64. package/lib/config/versions/magento-2.4.5-p2.js +3 -13
  65. package/lib/config/versions/magento-2.4.5-p3.js +1 -10
  66. package/lib/config/versions/magento-2.4.5-p4.js +38 -0
  67. package/lib/config/versions/magento-2.4.5-p5.js +38 -0
  68. package/lib/config/versions/magento-2.4.5.js +3 -12
  69. package/lib/config/versions/magento-2.4.6-p1.js +1 -10
  70. package/lib/config/versions/magento-2.4.6-p2.js +38 -0
  71. package/lib/config/versions/magento-2.4.6-p3.js +39 -0
  72. package/lib/config/versions/magento-2.4.6.js +1 -10
  73. package/lib/config/versions/magento-2.4.7-beta2.js +38 -0
  74. package/lib/tasks/database/import-dump-to-database.js +1 -1
  75. package/lib/tasks/database/import-remote-db/ssh/database-dump-command.js +0 -2
  76. package/lib/tasks/database/import-remote-db/ssh/readymage.js +29 -28
  77. package/lib/tasks/docker/containers/container-api.d.ts +5 -0
  78. package/lib/tasks/docker/containers/container-api.js +4 -1
  79. package/lib/tasks/docker/project-image-builder.js +21 -0
  80. package/lib/tasks/file-system/create-nginx-config.js +7 -2
  81. package/lib/tasks/file-system/create-phpstorm-config/workspace-config/workspace-config.js +1 -1
  82. package/lib/tasks/file-system/create-ssl-terminator-config.js +9 -7
  83. package/lib/tasks/magento/install-magento-project.js +10 -7
  84. package/lib/tasks/magento/setup-magento/configure-elasticsearch.js +1 -1
  85. package/lib/tasks/magento/setup-magento/index-products.js +41 -1
  86. package/lib/tasks/magento/setup-magento/index.js +4 -1
  87. package/lib/tasks/magento/setup-magento/set-base-url.js +121 -13
  88. package/lib/tasks/requirements/elasticsearch-version.js +21 -6
  89. package/lib/util/config-file-validator.js +60 -19
  90. package/lib/util/config-php-json.js +2 -0
  91. package/lib/util/database.js +83 -1
  92. package/lib/util/instance-metadata.js +16 -19
  93. package/lib/util/match-filesystem.js +1 -0
  94. package/lib/util/run-magento.js +1 -0
  95. package/package.json +2 -2
  96. package/tsconfig.json +2 -1
  97. package/typings/common.d.ts +53 -0
  98. package/typings/index.d.ts +55 -0
@@ -25,7 +25,8 @@ const runCommand = (options) => {
25
25
  detach = true,
26
26
  rm = false,
27
27
  tty = false,
28
- user
28
+ user,
29
+ memory
29
30
  } = options
30
31
 
31
32
  const detachArg = (detach && '-d') || ''
@@ -59,6 +60,7 @@ const runCommand = (options) => {
59
60
  (tmpfs.length > 0 && tmpfs.map((t) => `--tmpfs=${t}`)) || ''
60
61
  const userArg = (user && `--user=${user}`) || ''
61
62
  const addHostArg = (addHost && `--add-host=${addHost}`) || ''
63
+ const memoryArg = (memory && `--memory=${memory}`) || ''
62
64
 
63
65
  const dockerCommand = [
64
66
  'docker',
@@ -80,6 +82,7 @@ const runCommand = (options) => {
80
82
  tmpfsArg,
81
83
  userArg,
82
84
  addHostArg,
85
+ memoryArg,
83
86
  image,
84
87
  command
85
88
  ]
@@ -193,6 +193,27 @@ const buildDockerFileInstructions = async (ctx, { image, tag }) => {
193
193
  })
194
194
  }
195
195
 
196
+ if (ctx.config.overridenConfiguration.configuration.newRelic.enabled) {
197
+ const { agentVersion, licenseKey } =
198
+ ctx.config.overridenConfiguration.configuration.newRelic
199
+
200
+ // eslint-disable-next-line max-len
201
+ dockerFileInstructions.run('apk add --no-cache gcompat')
202
+ .run(`curl -L https://download.newrelic.com/php_agent/archive/${agentVersion}/newrelic-php5-${agentVersion}-linux.tar.gz | tar -C /tmp -zx \
203
+ && export NR_INSTALL_USE_CP_NOT_LN=1 \
204
+ && export NR_INSTALL_SILENT=1 \
205
+ && /tmp/newrelic-php5-${agentVersion}-linux/newrelic-install install \
206
+ && rm -rf /tmp/newrelic-php5-* /tmp/nrinstall*`)
207
+ .run(`sed -i -e "s/REPLACE_WITH_REAL_KEY/${licenseKey}/" \
208
+ -e "s/newrelic.appname[[:space:]]=[[:space:]].*/newrelic.appname=\\"${
209
+ ctx.config.baseConfig.prefix
210
+ }\\"/" \
211
+ -e '\\$anewrelic.daemon.address="${
212
+ ctx.isDockerDesktop ? 'host.docker.internal' : 'localhost'
213
+ }:31339"' \
214
+ \\$PHP_INI_DIR/conf.d/newrelic.ini`)
215
+ }
216
+
196
217
  return dockerFileInstructions
197
218
  }
198
219
 
@@ -15,13 +15,16 @@ const createNginxConfig = () => ({
15
15
  } = ctx
16
16
 
17
17
  const {
18
- configuration: { nginx }
18
+ configuration: { nginx },
19
+ storeDomains
19
20
  } = overridenConfiguration
20
21
 
21
22
  const hostMachine = !isDockerDesktop
22
23
  ? '127.0.0.1'
23
24
  : 'host.docker.internal'
24
25
  const hostPort = !isDockerDesktop ? ports.app : 80
26
+ const useStoreDomainMapping =
27
+ storeDomains && Object.keys(storeDomains).length > 1
25
28
 
26
29
  try {
27
30
  await setConfigFile({
@@ -38,7 +41,9 @@ const createNginxConfig = () => ({
38
41
  mageRoot: baseConfig.containerMagentoDir,
39
42
  hostMachine,
40
43
  hostPort,
41
- config: overridenConfiguration
44
+ config: overridenConfiguration,
45
+ storeDomains,
46
+ useStoreDomainMapping
42
47
  }
43
48
  })
44
49
  } catch (e) {
@@ -5,7 +5,7 @@ const { baseConfig } = require('../../../../config')
5
5
  * @param {import('../../../../../typings/index').CMAConfiguration} app
6
6
  */
7
7
  const getWorkspaceConfig = (app) => ({
8
- debugServerAddress: `http://${app.host}`,
8
+ debugServerAddress: `http://${app.storeDomains.admin}`,
9
9
  serverName: 'create-magento-app',
10
10
  runManagerName: 'create-magento-app',
11
11
  sessionId: 'PHPSTORM',
@@ -2,7 +2,6 @@ const path = require('path')
2
2
  const fs = require('fs')
3
3
  const setConfigFile = require('../../util/set-config')
4
4
  const pathExists = require('../../util/path-exists')
5
- const { isIpAddress } = require('../../util/ip')
6
5
  const KnownError = require('../../errors/known-error')
7
6
  const UnknownError = require('../../errors/unknown-error')
8
7
 
@@ -21,14 +20,19 @@ const createSSLTerminatorConfig = () => ({
21
20
 
22
21
  const {
23
22
  configuration: { sslTerminator },
24
- ssl,
25
- host
23
+ ssl
26
24
  } = overridenConfiguration
27
25
 
28
- if (ssl.enabled) {
26
+ if (ssl.enabled && !ssl.external_provider) {
27
+ if (!ssl.ssl_certificate) {
28
+ throw new KnownError('ssl.ssl_certificate is not defined!')
29
+ }
29
30
  if (!(await pathExists(ssl.ssl_certificate))) {
30
31
  throw new KnownError('ssl.ssl_certificate file does not exist!')
31
32
  }
33
+ if (!ssl.ssl_certificate_key) {
34
+ throw new KnownError('ssl.ssl_certificate_key is not defined!')
35
+ }
32
36
  if (!(await pathExists(ssl.ssl_certificate_key))) {
33
37
  throw new KnownError(
34
38
  'ssl.ssl_certificate_key file does not exist!'
@@ -66,7 +70,6 @@ const createSSLTerminatorConfig = () => ({
66
70
  )
67
71
  }
68
72
 
69
- const networkToBindTo = isIpAddress(host) ? host : '127.0.0.1'
70
73
  const hostMachine = !isDockerDesktop
71
74
  ? '127.0.0.1'
72
75
  : 'host.docker.internal'
@@ -87,7 +90,6 @@ const createSSLTerminatorConfig = () => ({
87
90
  hostMachine,
88
91
  hostPort,
89
92
  config: overridenConfiguration,
90
- networkToBindTo,
91
93
  debug
92
94
  }
93
95
  })
@@ -111,7 +113,7 @@ const createSSLTerminatorConfig = () => ({
111
113
  ),
112
114
  overwrite: true,
113
115
  templateArgs: {
114
- isNgrok: host.endsWith('ngrok.io')
116
+ sslEnabled: ssl.enabled
115
117
  }
116
118
  })
117
119
  } catch (e) {
@@ -1,5 +1,6 @@
1
1
  const path = require('path')
2
2
  const fs = require('fs')
3
+ const semver = require('semver')
3
4
  const logger = require('@scandipwa/scandipwa-dev-utils/logger')
4
5
  const runComposerCommand = require('../../util/run-composer')
5
6
  const matchFilesystem = require('../../util/match-filesystem')
@@ -12,6 +13,8 @@ const { runPHPContainerCommand } = require('../php/php-container')
12
13
  const magentoProductEnterpriseEdition = 'magento/product-enterprise-edition'
13
14
  const magentoProductCommunityEdition = 'magento/product-community-edition'
14
15
 
16
+ const magentoRootUpdatePlugin = 'magento/composer-root-update-plugin'
17
+
15
18
  /**
16
19
  * @param {import('../../../typings/context').ListrContext} ctx
17
20
  * @param {import('listr2').ListrTaskWrapper<import('../../../typings/context').ListrContext, any>} task
@@ -61,15 +64,15 @@ const adjustComposerJson = async (
61
64
  )
62
65
  }
63
66
 
67
+ const isPHP7 = semver.satisfies(ctx.phpVersion, '^7.x.x')
68
+ const rootUpdatePluginVersion = isPHP7 ? '^1' : '^2'
69
+
64
70
  // if composer-root-update-plugin is not installed in composer, install it.
65
- if (
66
- composerData &&
67
- !composerData.require['magento/composer-root-update-plugin']
68
- ) {
69
- task.output = 'Installing magento/composer-root-update-plugin!'
71
+ if (composerData && !composerData.require[magentoRootUpdatePlugin]) {
72
+ task.output = `Installing ${magentoRootUpdatePlugin}:${rootUpdatePluginVersion}!`
70
73
  await runComposerCommand(
71
74
  ctx,
72
- 'require magento/composer-root-update-plugin:^1',
75
+ `require ${magentoRootUpdatePlugin}:${rootUpdatePluginVersion}`,
73
76
  {
74
77
  callback: !ctx.verbose
75
78
  ? undefined
@@ -195,7 +198,7 @@ const installMagentoProject = () => ({
195
198
  }
196
199
 
197
200
  task.title = `Installing Magento ${magentoPackageVersion}`
198
- task.output = 'Creating Magento project'
201
+ task.output = `Creating Magento ${magentoPackageVersion} project`
199
202
 
200
203
  if (!(await pathExists(path.join(process.cwd(), 'composer.json')))) {
201
204
  await createMagentoProject(ctx, task, {
@@ -92,7 +92,7 @@ const installElasticSearch8Module = () => ({
92
92
  task: async (ctx, task) => {
93
93
  await runComposerCommand(
94
94
  ctx,
95
- `require ${magentoModuleElasticSearch8} --with-all-dependencies`,
95
+ `require ${magentoModuleElasticSearch8} --update-with-all-dependencies`,
96
96
  {
97
97
  callback: !ctx.verbose
98
98
  ? undefined
@@ -1,10 +1,50 @@
1
1
  const magentoTask = require('../../../util/magento-task')
2
+ // const runMagentoCommand = require('../../../util/run-magento')
2
3
 
3
4
  /**
4
5
  * @returns {import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
5
6
  */
6
7
  const indexProducts = () => ({
7
- task: (ctx, task) => task.newListr(magentoTask('index:reindex')),
8
+ title: 'Index Products',
9
+ task: async (ctx, task) => {
10
+ const { databaseConnection } = ctx
11
+ /** @type {{ indexer_id: string, status: string }[][]} */
12
+ const data = await databaseConnection.query(
13
+ `select indexer_id,status from indexer_state;`
14
+ )
15
+
16
+ if (data.length === 0) {
17
+ task.skip('No indexers found')
18
+ return
19
+ }
20
+
21
+ const invalidIndexers = data[0].filter(
22
+ ({ status }) => status !== 'valid'
23
+ )
24
+
25
+ const doYouWantToSkipIndexingPart = await task.prompt({
26
+ type: 'Select',
27
+ message: `Do you want to index the products? (There are ${invalidIndexers.length} invalid indexers, total indexers: ${data[0].length})\n`,
28
+ choices: [
29
+ {
30
+ name: 'index',
31
+ message: 'Yes, index them please'
32
+ },
33
+ {
34
+ name: 'skip',
35
+ message:
36
+ 'Skip, do not index them. I will do it later myself'
37
+ }
38
+ ]
39
+ })
40
+
41
+ if (doYouWantToSkipIndexingPart === 'skip') {
42
+ task.skip()
43
+ return
44
+ }
45
+
46
+ return task.newListr(magentoTask('index:reindex'))
47
+ },
8
48
  retry: 2
9
49
  })
10
50
 
@@ -48,7 +48,10 @@ const setupMagento = (options = {}) => ({
48
48
  increaseAdminSessionLifetime()
49
49
  ],
50
50
  {
51
- concurrent: true
51
+ concurrent: true,
52
+ rendererOptions: {
53
+ collapse: false
54
+ }
52
55
  }
53
56
  )
54
57
  },
@@ -1,34 +1,96 @@
1
- const { updateTableValues } = require('../../../util/database')
1
+ const { updateTableValues, databaseQuery } = require('../../../util/database')
2
+ const KnownError = require('../../../errors/known-error')
2
3
 
3
4
  /**
5
+ * @param {number} scopeId
6
+ * @param {string} code
7
+ * @param {string} host
4
8
  * @returns {import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
5
9
  */
6
- module.exports = () => ({
7
- title: 'Setting baseurl and secure baseurl',
10
+ const setBaseUrlForScope = (scopeId, code, host) => ({
11
+ title: `store code ${code} at ${host}`,
8
12
  task: async (ctx, task) => {
9
13
  const {
10
14
  ports,
11
15
  config: {
12
- overridenConfiguration: { host, ssl }
13
- },
14
- databaseConnection
16
+ overridenConfiguration: { ssl }
17
+ }
15
18
  } = ctx
16
- const isNgrok = host.endsWith('ngrok.io')
17
- const enableSecureFrontend = isNgrok || ssl.enabled ? '1' : '0'
19
+
20
+ if (host.startsWith('http://') || host.startsWith('https://')) {
21
+ throw new KnownError(
22
+ `Host ${host} should not contain protocol, only domain name. Check your configuration in cma.js!`
23
+ )
24
+ }
25
+
18
26
  const location = `${host}${
19
- !isNgrok && ports.sslTerminator !== 80
20
- ? `:${ports.sslTerminator}`
21
- : ''
27
+ ssl.enabled || ports.sslTerminator === 80
28
+ ? ''
29
+ : `:${ports.sslTerminator}`
22
30
  }/`
23
31
  const secureLocation = `${host}/` // SSL will work only on port 443, so you cannot run multiple projects with SSL at the same time.
24
32
  const httpUrl = `http://${location}`
25
33
  const httpsUrl = `https://${secureLocation}`
34
+ const table = 'core_config_data'
35
+ const values = [
36
+ {
37
+ path: 'web/unsecure/base_url',
38
+ value: httpUrl
39
+ },
40
+ {
41
+ path: 'web/unsecure/base_link_url',
42
+ value: httpUrl
43
+ },
44
+ {
45
+ path: 'web/secure/base_url',
46
+ value: httpsUrl
47
+ },
48
+ {
49
+ path: 'web/secure/base_link_url',
50
+ value: httpsUrl
51
+ }
52
+ ]
53
+
54
+ task.title = `store ${code} at ${ssl.enabled ? httpsUrl : httpUrl}`
55
+
56
+ await Promise.all(
57
+ values.map(async ({ path, value }) => {
58
+ await databaseQuery(
59
+ {
60
+ table,
61
+ where: [
62
+ ['scope_id', '=', scopeId],
63
+ ['path', '=', path]
64
+ ],
65
+ data: {
66
+ value
67
+ }
68
+ },
69
+ ctx
70
+ )
71
+ })
72
+ )
73
+ }
74
+ })
75
+
76
+ /**
77
+ * @returns {import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
78
+ */
79
+ const setBaseUrl = () => ({
80
+ title: 'Setting base url for stores',
81
+ task: async (ctx, task) => {
82
+ const {
83
+ config: {
84
+ overridenConfiguration: { ssl, storeDomains }
85
+ },
86
+ databaseConnection
87
+ } = ctx
88
+
89
+ const enableSecureFrontend = ssl.enabled ? '1' : '0'
26
90
 
27
91
  await updateTableValues(
28
92
  'core_config_data',
29
93
  [
30
- { path: 'web/unsecure/base_url', value: httpUrl },
31
- { path: 'web/secure/base_url', value: httpsUrl },
32
94
  {
33
95
  path: 'web/secure/use_in_frontend',
34
96
  value: enableSecureFrontend
@@ -45,5 +107,51 @@ module.exports = () => ({
45
107
  ],
46
108
  { databaseConnection, task }
47
109
  )
110
+
111
+ /** @type {{ website_id: number, code: string }[][]}} */
112
+ const [storeWebsites] = await databaseConnection.query(
113
+ `select * from store_website;`
114
+ )
115
+
116
+ if (!storeWebsites || storeWebsites.length === 0) {
117
+ throw new KnownError(
118
+ `No store websites found in database, store_website table is empty or does not exist`
119
+ )
120
+ }
121
+
122
+ const storeDomainsWithMapping = Object.entries(storeDomains).reduce(
123
+ (acc, [key, val]) => {
124
+ const storeWebsite = storeWebsites.find(
125
+ ({ code }) => code === key
126
+ )
127
+ if (storeWebsite) {
128
+ return {
129
+ ...acc,
130
+ [storeWebsite.code]: {
131
+ websiteId: storeWebsite.website_id,
132
+ domain: val
133
+ }
134
+ }
135
+ }
136
+
137
+ return acc
138
+ },
139
+ {}
140
+ )
141
+
142
+ return task.newListr(
143
+ Object.entries(storeDomainsWithMapping).map(
144
+ ([storeCode, { websiteId, domain }]) =>
145
+ setBaseUrlForScope(websiteId, storeCode, domain)
146
+ ),
147
+ {
148
+ concurrent: true,
149
+ rendererOptions: {
150
+ collapse: false
151
+ }
152
+ }
153
+ )
48
154
  }
49
155
  })
156
+
157
+ module.exports = setBaseUrl
@@ -1,5 +1,5 @@
1
1
  const UnknownError = require('../../errors/unknown-error')
2
- const { runContainerImage } = require('../../util/run-container-image')
2
+ const { containerApi } = require('../docker/containers')
3
3
 
4
4
  /**
5
5
  * @returns {import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
@@ -7,10 +7,24 @@ const { runContainerImage } = require('../../util/run-container-image')
7
7
  const checkElasticSearchVersion = () => ({
8
8
  title: 'Checking container ElasticSearch version',
9
9
  task: async (ctx, task) => {
10
- const elasticSearchVersionResponse = await runContainerImage(
11
- ctx.config.overridenConfiguration.configuration.elasticsearch.image,
12
- 'elasticsearch --version'
13
- )
10
+ const { elasticsearch } =
11
+ ctx.config.overridenConfiguration.configuration
12
+ const { ports } = ctx
13
+
14
+ let elasticSearchVersionResponse
15
+
16
+ try {
17
+ elasticSearchVersionResponse = await containerApi.run({
18
+ ...elasticsearch,
19
+ command: 'elasticsearch --version',
20
+ detach: false,
21
+ rm: true,
22
+ ports: [`127.0.0.1:${ports.elasticsearch}:9200`],
23
+ memory: '512mb'
24
+ })
25
+ } catch (e) {
26
+ elasticSearchVersionResponse = e.message
27
+ }
14
28
 
15
29
  const elasticSearchVersionResponseResult =
16
30
  elasticSearchVersionResponse.match(/Version:\s(\d+\.\d+\.\d+)/i)
@@ -28,7 +42,8 @@ const checkElasticSearchVersion = () => ({
28
42
  `Cannot retrieve ElasticSearch Version!\n\n${elasticSearchVersionResponse}`
29
43
  )
30
44
  }
31
- }
45
+ },
46
+ exitOnError: false
32
47
  })
33
48
 
34
49
  module.exports = checkElasticSearchVersion
@@ -25,17 +25,7 @@ const versionValidator = (value, helpers) => {
25
25
  const isValidComposerVersion = composerVersionRegex.test(value)
26
26
 
27
27
  if (!isValidComposerVersion) {
28
- return helpers.error('any.invalid', {
29
- label: `Not a valid composer version!
30
- Allowed patterns:
31
- - latest-stable
32
- - latest-preview
33
- - latest-2.2.x
34
- - latest-2.x
35
- - latest-1.x
36
- - 2.2.21
37
- `
38
- })
28
+ return helpers.error('any.invalid')
39
29
  }
40
30
 
41
31
  return undefined
@@ -64,9 +54,25 @@ const magentoSchema = Joi.object({
64
54
  * @type {Joi.ObjectSchema<import('../../typings').SSLConfiguration>}
65
55
  */
66
56
  const sslSchema = Joi.object({
67
- enabled: Joi.bool().required(),
68
- ssl_certificate: Joi.string().required(),
69
- ssl_certificate_key: Joi.string().required()
57
+ enabled: Joi.boolean().required(),
58
+ ssl_certificate: Joi.string().optional(),
59
+ ssl_certificate_key: Joi.string().optional(),
60
+ external_provider: Joi.boolean().optional()
61
+ }).custom((d, helpers) => {
62
+ if (d.enabled) {
63
+ if (!d.ssl_certificate && !d.external_provider) {
64
+ return helpers.error(
65
+ 'ssl_certificate must be provided! or set ssl.external_provider to true!'
66
+ )
67
+ }
68
+ if (!d.ssl_certificate_key && !d.external_provider) {
69
+ return helpers.error(
70
+ 'ssl_certificate_key must be provided! or set ssl.external_provider to true!'
71
+ )
72
+ }
73
+ }
74
+
75
+ return true
70
76
  })
71
77
 
72
78
  /**
@@ -92,7 +98,10 @@ const phpConfigurationSchema = Joi.object({
92
98
  fpmConfigTemplate: Joi.string().optional(),
93
99
  configTemplate: Joi.string().optional().custom(fileExistsValidator),
94
100
  debugTemplate: Joi.string().optional().custom(fileExistsValidator),
95
- extensions: phpExtensionConfiguration.optional()
101
+ extensions: phpExtensionConfiguration.optional(),
102
+ env: Joi.object()
103
+ .pattern(Joi.string(), [Joi.string(), Joi.number()])
104
+ .optional()
96
105
  })
97
106
 
98
107
  /**
@@ -150,6 +159,19 @@ const composerConfigurationSchema = Joi.object({
150
159
  }
151
160
 
152
161
  return versionValidator(value, helper)
162
+ })
163
+ .messages({
164
+ 'any.invalid': `Composer version is not valid!
165
+ Allowed patterns:
166
+ - latest-stable
167
+ - latest-preview
168
+ - latest-2.2.x
169
+ - latest-2.x
170
+ - latest-1.x
171
+ - 2.2.21
172
+
173
+ Please check you composer configuration in cma.js!
174
+ `
153
175
  }),
154
176
  plugins: Joi.object().pattern(
155
177
  Joi.string(),
@@ -161,6 +183,23 @@ const composerConfigurationSchema = Joi.object({
161
183
  )
162
184
  })
163
185
 
186
+ /**
187
+ * @type {Joi.ObjectSchema<import('../../typings').NewRelicConfiguration>}
188
+ */
189
+ const newRelicConfigurationSchema = Joi.object({
190
+ enabled: Joi.boolean().optional(),
191
+ agentVersion: Joi.string().optional(),
192
+ licenseKey: Joi.string().optional()
193
+ }).custom((d, helpers) => {
194
+ if (d.enabled && !d.licenseKey) {
195
+ return helpers.error(
196
+ 'when newRelic is enabled license key is required!'
197
+ )
198
+ }
199
+
200
+ return true
201
+ })
202
+
164
203
  /**
165
204
  * @type {Joi.ObjectSchema<import('../../typings').CMAConfiguration['configuration']>}
166
205
  */
@@ -173,7 +212,8 @@ const configurationSchema = Joi.object({
173
212
  composer: composerConfigurationSchema.optional(),
174
213
  varnish: varnishConfigurationSchema.optional(),
175
214
  sslTerminator: nginxConfigurationSchema.optional(),
176
- maildev: serviceConfigurationSchema.optional()
215
+ maildev: serviceConfigurationSchema.optional(),
216
+ newRelic: newRelicConfigurationSchema.optional()
177
217
  })
178
218
 
179
219
  /**
@@ -182,8 +222,9 @@ const configurationSchema = Joi.object({
182
222
  const configFileSchema = Joi.object({
183
223
  magento: magentoSchema.required(),
184
224
  host: Joi.string().optional(),
225
+ storeDomains: Joi.object().pattern(Joi.string(), Joi.string()).optional(),
185
226
  ssl: sslSchema.optional(),
186
- prefix: Joi.bool().optional(),
227
+ prefix: Joi.boolean().optional(),
187
228
  configuration: configurationSchema.required()
188
229
  })
189
230
 
@@ -191,8 +232,8 @@ const configFileSchema = Joi.object({
191
232
  * @type {Joi.ObjectSchema<{ useNonOverlappingPorts:boolean, analytics:boolean }>}
192
233
  */
193
234
  const systemConfigurationSchema = Joi.object({
194
- useNonOverlappingPorts: Joi.bool().optional(),
195
- analytics: Joi.bool().optional()
235
+ useNonOverlappingPorts: Joi.boolean().optional(),
236
+ analytics: Joi.boolean().optional()
196
237
  })
197
238
 
198
239
  module.exports = {
@@ -5,6 +5,8 @@ const pathExists = require('./path-exists')
5
5
 
6
6
  /**
7
7
  * @param {import('../../typings/context').ListrContext} ctx
8
+ *
9
+ * @returns {Promise<import('../../typings/common').ConfigPHPType | null>}
8
10
  */
9
11
  const configPhpToJson = async (ctx) => {
10
12
  const configPhpOnSystemPath = path.join(