@florianpat/lando-core 3.23.7-compose → 3.23.22-test1

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 (96) hide show
  1. package/CHANGELOG.md +101 -1
  2. package/bin/lando +2 -0
  3. package/bin/lando.cmd +3 -0
  4. package/builders/_lando.js +2 -1
  5. package/components/l337-v4.js +2 -2
  6. package/config.yml +3 -2
  7. package/hooks/lando-autostart-engine.js +4 -25
  8. package/hooks/lando-run-setup.js +58 -0
  9. package/hooks/lando-setup-build-engine-darwin.js +13 -12
  10. package/hooks/lando-setup-build-engine-linux.js +14 -4
  11. package/hooks/lando-setup-build-engine-win32.js +27 -20
  12. package/hooks/lando-setup-build-engine-wsl.js +210 -0
  13. package/hooks/lando-setup-check.js +19 -0
  14. package/hooks/lando-setup-create-ca-wsl.js +34 -0
  15. package/hooks/lando-setup-create-ca.js +22 -23
  16. package/hooks/lando-setup-install-ca-darwin.js +5 -1
  17. package/hooks/lando-setup-install-ca-linux.js +4 -1
  18. package/hooks/lando-setup-install-ca-win32.js +5 -1
  19. package/hooks/lando-setup-install-ca-wsl.js +145 -0
  20. package/hooks/lando-setup-orchestrator.js +4 -4
  21. package/index.js +18 -12
  22. package/lib/app.js +2 -2
  23. package/lib/art.js +20 -8
  24. package/lib/compose.js +0 -3
  25. package/lib/daemon.js +79 -76
  26. package/lib/docker.js +2 -2
  27. package/lib/engine.js +10 -3
  28. package/lib/lando.js +2 -2
  29. package/lib/metrics.js +5 -3
  30. package/lib/updates.js +12 -2
  31. package/node_modules/nanoid/.devcontainer.json +23 -0
  32. package/node_modules/nanoid/README.md +517 -2
  33. package/node_modules/nanoid/async/index.browser.cjs +37 -2
  34. package/node_modules/nanoid/async/index.browser.js +37 -2
  35. package/node_modules/nanoid/async/index.cjs +38 -2
  36. package/node_modules/nanoid/async/index.js +38 -2
  37. package/node_modules/nanoid/async/index.native.js +33 -2
  38. package/node_modules/nanoid/index.browser.cjs +39 -1
  39. package/node_modules/nanoid/index.browser.js +39 -1
  40. package/node_modules/nanoid/index.cjs +42 -2
  41. package/node_modules/nanoid/index.js +42 -2
  42. package/node_modules/nanoid/non-secure/index.cjs +15 -2
  43. package/node_modules/nanoid/non-secure/index.js +15 -2
  44. package/node_modules/nanoid/package.json +1 -1
  45. package/node_modules/nanoid/url-alphabet/index.cjs +4 -0
  46. package/node_modules/nanoid/url-alphabet/index.js +4 -0
  47. package/package.json +7 -7
  48. package/plugins/networking/app.js +4 -2
  49. package/plugins/networking/index.js +19 -6
  50. package/plugins/proxy/builders/_proxy.js +1 -2
  51. package/release-aliases/3-EDGE +1 -1
  52. package/release-aliases/3-STABLE +1 -1
  53. package/renderers/dc2.js +2 -1
  54. package/scripts/add-to-group.sh +72 -0
  55. package/scripts/docker-engine-start.sh +15 -1
  56. package/scripts/install-docker-desktop.ps1 +11 -12
  57. package/scripts/install-system-ca-win32.ps1 +14 -14
  58. package/scripts/run-elevated.ps1 +2 -2
  59. package/scripts/semcompare.sh +142 -0
  60. package/scripts/wait-for-user.sh +1 -2
  61. package/tasks/destroy.js +3 -0
  62. package/tasks/info.js +2 -1
  63. package/tasks/init.js +35 -30
  64. package/tasks/rebuild.js +2 -8
  65. package/tasks/restart.js +2 -8
  66. package/tasks/setup.js +2 -2
  67. package/tasks/shellenv.js +2 -2
  68. package/tasks/start.js +2 -8
  69. package/tasks/stop.js +3 -0
  70. package/utils/build-config.js +2 -0
  71. package/utils/build-tooling-runner.js +2 -1
  72. package/utils/get-app.js +1 -1
  73. package/utils/get-bin-paths.js +2 -2
  74. package/utils/get-compose-x.js +1 -1
  75. package/utils/get-config-defaults.js +12 -7
  76. package/utils/get-docker-bin-path.js +6 -2
  77. package/utils/get-docker-desktop-x.js +21 -0
  78. package/utils/get-docker-x.js +3 -2
  79. package/utils/get-shellenv.js +1 -2
  80. package/utils/get-system-cas.js +25 -6
  81. package/utils/get-win32-envvar-from-wsl.js +7 -0
  82. package/utils/is-admin-user.js +9 -8
  83. package/utils/is-group-member.js +14 -7
  84. package/utils/is-wsl-interop.js +17 -4
  85. package/utils/run-elevated.js +9 -0
  86. package/utils/run-powershell-script.js +31 -5
  87. package/utils/run-tasks.js +3 -2
  88. package/utils/setup-metrics.js +10 -1
  89. package/utils/shutdown-os.js +8 -3
  90. package/utils/spawn-sync-stringer.js +1 -0
  91. package/utils/update-shell-profile.js +8 -7
  92. package/utils/validate-ca.js +31 -0
  93. package/utils/winpath-2-wslpath.js +6 -0
  94. package/utils/wslpath-2-winpath.js +6 -0
  95. package/hooks/lando-dep-check.js +0 -26
  96. package/lib/checksums.txt +0 -0
@@ -0,0 +1,210 @@
1
+ 'use strict';
2
+
3
+ const axios = require('../utils/get-axios')();
4
+ const fs = require('fs');
5
+ const getDockerDesktopBin = require('../utils/get-docker-desktop-x');
6
+ const getWinEnvar = require('../utils/get-win32-envvar-from-wsl');
7
+ const path = require('path');
8
+ const semver = require('semver');
9
+ const wslpath = require('../utils/winpath-2-wslpath');
10
+
11
+ const {color} = require('listr2');
12
+ const {nanoid} = require('nanoid');
13
+
14
+ const buildIds = {
15
+ '4.36.0': '175267',
16
+ '4.35.1': '173168',
17
+ '4.35.0': '172550',
18
+ '4.34.3': '170107',
19
+ '4.34.2': '167172',
20
+ '4.34.1': '166053',
21
+ '4.34.0': '165256',
22
+ '4.33.1': '161083',
23
+ '4.33.0': '160616',
24
+ '4.32.0': '157355',
25
+ '4.31.1': '153621',
26
+ '4.31.0': '153195',
27
+ '4.30.0': '149282',
28
+ '4.29.0': '145265',
29
+ '4.28.0': '139021',
30
+ '4.27.2': '137060',
31
+ '4.27.1': '136059',
32
+ '4.27.0': '135262',
33
+ '4.26.1': '131620',
34
+ '4.26.0': '130397',
35
+ '4.25.2': '129061',
36
+ '4.25.1': '128006',
37
+ '4.25.0': '126437',
38
+ };
39
+
40
+ /*
41
+ * Helper to get build engine id
42
+ */
43
+ const getId = version => {
44
+ // if version is an integer then assume its already the id
45
+ if (semver.valid(version) === null && Number.isInteger(parseInt(version))) return version;
46
+ // otherwise return that corresponding build-id
47
+ return buildIds[version];
48
+ };
49
+
50
+ const getVersion = version => {
51
+ // if version is not an integer then assume its already the version
52
+ if (semver.valid(version) !== null) return version;
53
+ // otherwise return the version that corresponds to the build id
54
+ return Object.keys(buildIds).find(key => buildIds[key] === version);
55
+ };
56
+
57
+ /*
58
+ * Helper to get docker compose v2 download url
59
+ */
60
+ const getEngineDownloadUrl = (id = '175267') => {
61
+ const arch = process.arch === 'arm64' ? 'arm64' : 'amd64';
62
+ return `https://desktop.docker.com/win/main/${arch}/${id}/Docker%20Desktop%20Installer.exe`;
63
+ };
64
+
65
+ /*
66
+ * wrapper for docker-desktop install
67
+ */
68
+ const downloadDockerDesktop = (url, {debug, dest, task, ctx}) => new Promise((resolve, reject) => {
69
+ const download = require('../utils/download-x')(url, {
70
+ debug,
71
+ dest: path.posix.join(dest, `${nanoid()}.exe`),
72
+ });
73
+
74
+ // success
75
+ download.on('done', result => {
76
+ task.title = `Downloaded build engine`;
77
+ resolve(result);
78
+ });
79
+ // handle errors
80
+ download.on('error', error => {
81
+ ctx.errors.push(error);
82
+ reject(error);
83
+ });
84
+ // update title to reflect download progress
85
+ download.on('progress', progress => {
86
+ task.title = `Downloading build engine ${color.dim(`[${progress.percentage}%]`)}`;
87
+ });
88
+ });
89
+
90
+ module.exports = async (lando, options) => {
91
+ const debug = require('../utils/debug-shim')(lando.log);
92
+ debug.enabled = lando.debuggy;
93
+
94
+ // if build engine is set to false allow it to be skipped
95
+ // @NOTE: this is mostly for internal stuff
96
+ if (options.buildEngine === false) return;
97
+
98
+ // get stuff from config/opts
99
+ const build = getId(options.buildEngine);
100
+ const version = getVersion(options.buildEngine);
101
+
102
+ // cosmetics
103
+ const install = version ? `v${version}` : `build ${build}`;
104
+
105
+ // download url
106
+ const url = getEngineDownloadUrl(build);
107
+
108
+ // win32 install docker desktop task
109
+ options.tasks.push({
110
+ title: 'Downloading build engine',
111
+ id: 'setup-build-engine',
112
+ description: '@lando/build-engine (docker-desktop)',
113
+ version: `Docker Desktop ${install}`,
114
+ hasRun: async () => {
115
+ // if we are missing the docker desktop executable then false
116
+ if (!fs.existsSync(getDockerDesktopBin())) return false;
117
+
118
+ // if we get here let's make sure the engine is on
119
+ try {
120
+ await lando.engine.daemon.up({max: 3, backoff: 1000});
121
+ return true;
122
+ } catch (error) {
123
+ lando.log.debug('docker install task has not run %j', error);
124
+ return false;
125
+ }
126
+ },
127
+ canRun: async () => {
128
+ // throw if we cannot resolve a semantic version to a buildid
129
+ if (!build) throw new Error(`Could not resolve ${install} to an installable version!`);
130
+ // throw error if we cannot ping the download link
131
+ await axios.head(url);
132
+ // @TODO: check for wsl2?
133
+ return true;
134
+ },
135
+ task: async (ctx, task) => {
136
+ try {
137
+ // get tmp dir from windows side
138
+ const winTmpDir = getWinEnvar('TEMP', {debug});
139
+ const dest = wslpath(winTmpDir);
140
+ debug('resolved win dir %o to wsl path %o', winTmpDir, dest);
141
+
142
+ // download the installer
143
+ ctx.download = await downloadDockerDesktop(url, {ctx, debug, dest, task});
144
+ ctx.download.windest = path.win32.join(winTmpDir, path.basename(ctx.download.dest));
145
+
146
+ // script
147
+ const script = path.posix.join(lando.config.userConfRoot, 'scripts', 'install-docker-desktop.ps1');
148
+ // args
149
+ const args = ['-Installer', ctx.download.windest];
150
+ if (options.buildEngineAcceptLicense) args.push('-AcceptLicense');
151
+ if ((options.debug || options.verbose > 0 || lando.debuggy) && lando.config.isInteractive) args.push('-Debug');
152
+
153
+ // run install command
154
+ task.title = `Installing build engine ${color.dim('(this may take a minute)')}`;
155
+ const result = await require('../utils/run-powershell-script')(script, args, {debug});
156
+ result.download = ctx.download;
157
+
158
+ // finish up
159
+ const location = getWinEnvar('ProgramW6432') ?? getWinEnvar('ProgramFiles');
160
+ task.title = `Installed build engine (Docker Desktop) to ${location}/Docker/Docker!`;
161
+ return result;
162
+ } catch (error) {
163
+ throw error;
164
+ }
165
+ },
166
+ });
167
+
168
+ // add docker group add task
169
+ options.tasks.push({
170
+ title: `Adding ${lando.config.username} to docker group`,
171
+ id: 'setup-build-engine-group',
172
+ dependsOn: ['setup-build-engine'],
173
+ description: `@lando/build-engine-group (${lando.config.username}@docker)`,
174
+ requiresRestart: true,
175
+ comments: {
176
+ 'NOT INSTALLED': `Will add ${lando.config.username} to docker group`,
177
+ },
178
+ hasRun: async () => require('../utils/is-group-member')('docker'),
179
+ task: async (ctx, task) => {
180
+ // check one last time incase this was added by a dependee or otherwise
181
+ if (require('../utils/is-group-member')('docker')) return {code: 0};
182
+
183
+ // prompt for password if interactive and we dont have it
184
+ if (ctx.password === undefined && lando.config.isInteractive) {
185
+ ctx.password = await task.prompt({
186
+ type: 'password',
187
+ name: 'password',
188
+ message: `Enter computer password for ${lando.config.username} to add them to docker group`,
189
+ validate: async (input, state) => {
190
+ const options = {debug, ignoreReturnCode: true, password: input};
191
+ const response = await require('../utils/run-elevated')(['echo', 'hello there'], options);
192
+ if (response.code !== 0) return response.stderr;
193
+ return true;
194
+ },
195
+ });
196
+ }
197
+
198
+ try {
199
+ const script = path.join(lando.config.userConfRoot, 'scripts', 'add-to-group.sh');
200
+ const command = [script, '--user', lando.config.username, '--group', 'docker'];
201
+ const response = await require('../utils/run-elevated')(command, {debug, password: ctx.password});
202
+ task.title = `Added ${lando.config.username} to docker group`;
203
+ return response;
204
+ } catch (error) {
205
+ throw error;
206
+ }
207
+ },
208
+ });
209
+ };
210
+
@@ -0,0 +1,19 @@
1
+ 'use strict';
2
+
3
+ module.exports = async lando => {
4
+ // fetch the command we are running
5
+ const command = lando?.config?.command?._?.[0] ?? 'unknown';
6
+
7
+ // only run if engine bootstrap or above and if engine/orchestrator have been installed
8
+ if (lando._bootstrapLevel >= 3 && command !== 'setup') {
9
+ lando.log.verbose('build-engine exists: %s', lando.engine.dockerInstalled);
10
+ lando.log.verbose('orchestrator exists: %s', lando.engine.composeInstalled);
11
+
12
+ // if we cannot even locate the buld engine then go into run setup
13
+ // @NOTE: this is mostly a catch-all fail-safe fall-back in case something
14
+ // gets through the setup cracks
15
+ if (lando.engine.dockerInstalled === false) {
16
+ await require('./lando-run-setup')(lando);
17
+ }
18
+ }
19
+ };
@@ -0,0 +1,34 @@
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const getWinEnvar = require('../utils/get-win32-envvar-from-wsl');
5
+ const path = require('path');
6
+ const wslpath = require('../utils/winpath-2-wslpath');
7
+ const remove = require('../utils/remove');
8
+
9
+ module.exports = async lando => {
10
+ const {caCert, caKey} = lando.config;
11
+
12
+ // if we dont have any CA stuff, lets see if we can get them from windows
13
+ // @NOTE: we preempt like this so our setup tasks will asses install successfully
14
+ if (lando.config.os.landoPlatform === 'wsl' && !fs.existsSync(caCert) && !fs.existsSync(caKey)) {
15
+ const debug = require('../utils/debug-shim')(lando.log);
16
+ const winHome = getWinEnvar('USERPROFILE');
17
+ const winCertsDir = wslpath(path.join(winHome, '.lando', 'certs'));
18
+ const wcaCert = path.join(winCertsDir, path.basename(caCert));
19
+ const wcaKey = path.join(winCertsDir, path.basename(caKey));
20
+
21
+ // if it makes sense to copy then lets to it
22
+ if (fs.existsSync(wcaCert) && fs.existsSync(wcaKey) && require('../utils/validate-ca')(wcaCert, wcaKey, {debug})) {
23
+ fs.copyFileSync(wcaCert, caCert);
24
+ fs.copyFileSync(wcaKey, caKey);
25
+ debug('copied existing and valid CA from %o to %o', wcaCert, caCert);
26
+
27
+ // otherwise lets purge
28
+ } else {
29
+ remove(wcaCert);
30
+ remove(wcaKey);
31
+ debug('removed invalid CA stuff from %o and %o', wcaCert, wcaKey);
32
+ }
33
+ }
34
+ };
@@ -1,6 +1,10 @@
1
1
  'use strict';
2
2
 
3
3
  const fs = require('fs');
4
+ const getWinEnvar = require('../utils/get-win32-envvar-from-wsl');
5
+ const path = require('path');
6
+ const wslpath = require('../utils/winpath-2-wslpath');
7
+ const remove = require('../utils/remove');
4
8
 
5
9
  module.exports = async (lando, options) => {
6
10
  const debug = require('../utils/debug-shim')(lando.log);
@@ -16,34 +20,17 @@ module.exports = async (lando, options) => {
16
20
  'NOT INSTALLED': 'Will create Lando Development Certificate Authority (CA)',
17
21
  },
18
22
  hasRun: async () => {
19
- const forge = require('node-forge');
20
- const read = require('../utils/read-file');
21
-
22
23
  if ([caCert, caKey].some(file => !fs.existsSync(file))) return false;
23
24
 
24
25
  // check if the ca is valid and has a matching key
25
- try {
26
- const ca = forge.pki.certificateFromPem(read(caCert));
27
- const key = forge.pki.privateKeyFromPem(read(caKey));
28
-
29
- // verify the signature using the public key in the CA certificate
30
- const md = forge.md.sha256.create();
31
- md.update('taanab', 'utf8');
32
- const signature = key.sign(md);
33
-
34
- // if they dont match then throw
35
- if (!ca.publicKey.verify(md.digest().bytes(), signature)) {
36
- throw new Error('CA and its private key do not match');
37
- }
38
-
39
- // @TODO: throw error if CA has expired?
40
-
41
- return true;
42
- } catch (error) {
43
- debug('Something is wrong with the CA %o %o', error.message, error.stack);
44
- [caCert, caKey].some(file => !fs.unlinkSync(file));
26
+ if (!require('../utils/validate-ca')(caCert, caKey, {debug})) {
27
+ remove(caCert);
28
+ remove(caKey);
45
29
  return false;
46
30
  }
31
+
32
+ // otherwise we are good
33
+ return true;
47
34
  },
48
35
  task: async (ctx, task) => {
49
36
  const write = require('../utils/write-file');
@@ -61,6 +48,18 @@ module.exports = async (lando, options) => {
61
48
  // write the cert and key
62
49
  write(caCert, cert);
63
50
  write(caKey, key);
51
+
52
+ // on wsl we also want to move these over
53
+ if (lando.config.os.landoPlatform === 'wsl') {
54
+ const write = require('../utils/write-file');
55
+ const winHome = getWinEnvar('USERPROFILE');
56
+ const winCertsDir = wslpath(path.join(winHome, '.lando', 'certs'));
57
+ const wcaCert = path.join(winCertsDir, path.basename(caCert));
58
+ const wcaKey = path.join(winCertsDir, path.basename(caKey));
59
+ write(wcaCert, cert);
60
+ write(wcaKey, key);
61
+ }
62
+
64
63
  task.title = 'Created Lando Development CA';
65
64
  },
66
65
  });
@@ -31,7 +31,11 @@ module.exports = async (lando, options) => {
31
31
  try {
32
32
  const fingerprint = require('../utils/get-fingerprint')(caCert);
33
33
  debug('computed sha1 fingerprint %o for ca %o', fingerprint, caCert);
34
- return require('../utils/get-system-cas')().includes(fingerprint);
34
+
35
+ // get fingerprints
36
+ const darwinfps = await require('../utils/get-system-cas')();
37
+
38
+ return darwinfps.includes(fingerprint);
35
39
  } catch (error) {
36
40
  debug('error determining fingerprint of %o: %o %o', caCert, error.message, error.stack);
37
41
  return false;
@@ -33,7 +33,10 @@ module.exports = async (lando, options) => {
33
33
  const fingerprint = require('../utils/get-fingerprint')(caCert);
34
34
  debug('computed sha1 fingerprint %o for ca %o', fingerprint, caCert);
35
35
 
36
- return require('../utils/get-system-cas')().includes(fingerprint);
36
+ // get fingerprints
37
+ const linuxfps = await require('../utils/get-system-cas')();
38
+
39
+ return linuxfps.includes(fingerprint);
37
40
  } catch (error) {
38
41
  debug('error determining fingerprint of %o: %o %o', caCert, error.message, error.stack);
39
42
  return false;
@@ -31,7 +31,11 @@ module.exports = async (lando, options) => {
31
31
  try {
32
32
  const fingerprint = require('../utils/get-fingerprint')(caCert);
33
33
  debug('computed sha1 fingerprint %o for ca %o', fingerprint, caCert);
34
- return require('../utils/get-system-cas')().includes(fingerprint);
34
+
35
+ // get fingerprints
36
+ const winfps = await require('../utils/get-system-cas')();
37
+
38
+ return winfps.includes(fingerprint);
35
39
  } catch (error) {
36
40
  debug('error determining fingerprint of %o: %o %o', caCert, error.message, error.stack);
37
41
  return false;
@@ -0,0 +1,145 @@
1
+ 'use strict';
2
+
3
+ const os = require('os');
4
+ const path = require('path');
5
+
6
+ /**
7
+ * Installs the Lando Development Certificate Authority (CA) on Windows systems.
8
+ * This module is called by `lando setup` to ensure the Lando CA is trusted by the system.
9
+ *
10
+ * @param {Object} lando - The Lando config object
11
+ * @param {Object} options - Options passed to the setup command
12
+ * @return {Promise<void>}
13
+ */
14
+ module.exports = async (lando, options) => {
15
+ const debug = require('../utils/debug-shim')(lando.log);
16
+
17
+ const {caCert} = lando.config;
18
+
19
+ // Skip the installation of the CA if set in options
20
+ if (options.skipInstallCa) return;
21
+
22
+ // Add linux CA installation task
23
+ options.tasks.push({
24
+ title: `Installing Lando Development CA on Linux`,
25
+ id: 'install-ca-linux',
26
+ dependsOn: ['create-ca'],
27
+ description: '@lando/install-ca-linux',
28
+ comments: {
29
+ 'NOT INSTALLED': 'Will install Lando Development Certificate Authority (CA) to Linux store',
30
+ },
31
+ hasRun: async () => {
32
+ try {
33
+ const fingerprint = require('../utils/get-fingerprint')(caCert);
34
+ debug('computed sha1 fingerprint %o for ca %o', fingerprint, caCert);
35
+
36
+ // get fingerprints
37
+ const linuxfps = await require('../utils/get-system-cas')({platform: 'linux'});
38
+
39
+ // check if we have it in both
40
+ return linuxfps.includes(fingerprint);
41
+ } catch (error) {
42
+ debug('error determining fingerprint of %o: %o %o', caCert, error.message, error.stack);
43
+ return false;
44
+ }
45
+ },
46
+ canRun: async () => {
47
+ // Check for admin privileges
48
+ if (!await require('../utils/is-admin-user')()) {
49
+ throw new Error([
50
+ `User "${lando.config.username}" does not have permission to trust the CA!`,
51
+ 'Contact your system admin for permission and then rerun setup.',
52
+ ].join(os.EOL));
53
+ }
54
+
55
+ return true;
56
+ },
57
+ task: async (ctx, task) => {
58
+ try {
59
+ task.title = 'Installing Lando Development Certificate Authority (CA) to Linux store';
60
+
61
+ // Prompt for password if in interactive mode and password not provided
62
+ if (ctx.password === undefined && lando.config.isInteractive) {
63
+ ctx.password = await task.prompt({
64
+ type: 'password',
65
+ name: 'password',
66
+ message: `Enter computer password for ${lando.config.username} to install the CA`,
67
+ validate: async (input, state) => {
68
+ const options = {debug, ignoreReturnCode: true, password: input};
69
+ const response = await require('../utils/run-elevated')(['echo', 'Validating elevated access'], options);
70
+ if (response.code !== 0) return response.stderr;
71
+ return true;
72
+ },
73
+ });
74
+ }
75
+
76
+ // Prepare the installation command
77
+ const script = path.join(lando.config.userConfRoot, 'scripts', 'install-system-ca-linux.sh');
78
+ const command = [script, '--ca', caCert];
79
+
80
+ // Add debug flag if necessary
81
+ if (options.debug || options.verbose > 0 || lando.debuggy) command.push('--debug');
82
+
83
+ // Execute the installation command with elevated privileges
84
+ const result = await require('../utils/run-elevated')(command, {debug, password: ctx.password});
85
+
86
+ // Update task title on successful installation
87
+ task.title = 'Installed Lando Development Certificate Authority (CA) to Linux store';
88
+ return result;
89
+ } catch (error) {
90
+ throw error;
91
+ }
92
+ },
93
+ });
94
+
95
+ // Add windows CA installation task
96
+ options.tasks.push({
97
+ title: `Installing Lando Development CA on Windows`,
98
+ id: 'install-ca-win32',
99
+ dependsOn: ['copy-ca'],
100
+ description: '@lando/install-ca-win32',
101
+ comments: {
102
+ 'NOT INSTALLED': 'Will install Lando Development Certificate Authority (CA) to Windows store',
103
+ },
104
+ hasRun: async () => {
105
+ try {
106
+ const fingerprint = require('../utils/get-fingerprint')(caCert);
107
+ debug('computed sha1 fingerprint %o for ca %o', fingerprint, caCert);
108
+
109
+ // get fingerprints
110
+ const winfps = await require('../utils/get-system-cas')();
111
+
112
+ // check if we have it in both
113
+ return winfps.includes(fingerprint);
114
+ } catch (error) {
115
+ debug('error determining fingerprint of %o: %o %o', caCert, error.message, error.stack);
116
+ return false;
117
+ }
118
+ },
119
+ canRun: async () => {
120
+ return true;
121
+ },
122
+ task: async (ctx, task) => {
123
+ try {
124
+ task.title = 'Installing Lando Development Certificate Authority (CA) to Windows store';
125
+
126
+ // Assemble the installation command
127
+ const script = path.join(lando.config.userConfRoot, 'scripts', 'install-system-ca-win32.ps1');
128
+ const args = ['-CA', caCert];
129
+
130
+ // Add optional arguments
131
+ if (options.debug || options.verbose > 0 || lando.debuggy) args.push('-Debug');
132
+ if (!lando.config.isInteractive) args.push('-NonInteractive');
133
+
134
+ // Run the installation command
135
+ const result = await require('../utils/run-powershell-script')(script, args, {debug});
136
+
137
+ // Update task title on successful installation
138
+ task.title = 'Installed Lando Development Certificate Authority (CA) to Windows store';
139
+ return result;
140
+ } catch (error) {
141
+ throw error;
142
+ }
143
+ },
144
+ });
145
+ };
@@ -7,7 +7,7 @@ const path = require('path');
7
7
  /*
8
8
  * Helper to get docker compose v2 download url
9
9
  */
10
- const getComposeDownloadUrl = (version = '2.29.2') => {
10
+ const getComposeDownloadUrl = (version = '2.30.3') => {
11
11
  const mv = version.split('.')[0] > 1 ? '2' : '1';
12
12
  const arch = process.arch === 'arm64' ? 'aarch64' : 'x86_64';
13
13
  const toggle = `${process.platform}-${mv}`;
@@ -31,7 +31,7 @@ const getComposeDownloadUrl = (version = '2.29.2') => {
31
31
  /*
32
32
  * Helper to get docker compose v2 download destination
33
33
  */
34
- const getComposeDownloadDest = (base, version = '2.29.2') => {
34
+ const getComposeDownloadDest = (base, version = '2.30.3') => {
35
35
  switch (process.platform) {
36
36
  case 'linux':
37
37
  case 'darwin':
@@ -60,7 +60,7 @@ module.exports = async (lando, options) => {
60
60
  title: `Downloading orchestrator`,
61
61
  id: 'setup-orchestrator',
62
62
  description: '@lando/orchestrator (docker-compose)',
63
- version: `docker-compose v${orchestrator}`,
63
+ version: `Docker Compose v${orchestrator}`,
64
64
  hasRun: async () => {
65
65
  return !!orchestratorBin && typeof orchestrator === 'string' && fs.existsSync(dest);
66
66
  },
@@ -74,7 +74,7 @@ module.exports = async (lando, options) => {
74
74
  const download = require('../utils/download-x')(url, {debug, dest, test: ['--version']});
75
75
  // success
76
76
  download.on('done', data => {
77
- task.title = `Installed orchestrator to ${dest}`;
77
+ task.title = `Installed orchestrator (Docker Compose) to ${dest}`;
78
78
  resolve(data);
79
79
  });
80
80
  // handle errors
package/index.js CHANGED
@@ -37,7 +37,7 @@ const uc = () => ({
37
37
  });
38
38
 
39
39
  module.exports = async lando => {
40
- // Set some stuff and set seom stuff up
40
+ // set some stuff and set seom stuff up
41
41
  const caDir = path.join(lando.config.userConfRoot, 'certs');
42
42
  const sshDir = path.join(lando.config.home, '.ssh');
43
43
  const binDir = path.join(lando.config.userConfRoot, 'bin');
@@ -49,26 +49,32 @@ module.exports = async lando => {
49
49
  const caCert = path.join(caDir, `${caName}.crt`);
50
50
  const caKey = path.join(caDir, `${caName}.key`);
51
51
 
52
- // Ensure some dirs exist before we start
52
+ const platform = lando.config.os.landoPlatform;
53
+
54
+ // ensure some dirs exist before we start
53
55
  _.forEach([binDir, caDir, sshDir], dir => fs.mkdirSync(dir, {recursive: true}));
54
56
 
55
- // Ensure we munge plugin stuff together appropriately
56
- lando.events.once('pre-install-plugins', async options => await require('./hooks/lando-setup-common-plugins')(lando, options)); // eslint-disable-line max-len
57
+ // ensure we munge plugin stuff together appropriately
58
+ lando.events.once('pre-install-plugins', async options => await require('./hooks/lando-setup-common-plugins')(lando, options));
57
59
 
58
60
  // move v3 scripts directories as needed
59
61
  lando.events.on('pre-setup', 0, async () => await require('./hooks/lando-copy-v3-scripts')(lando));
60
62
 
61
- // Ensure we setup docker if needed
62
- lando.events.once('pre-setup', async options => await require(`./hooks/lando-setup-build-engine-${process.platform}`)(lando, options)); // eslint-disable-line max-len
63
+ // ensure we setup docker if needed
64
+ lando.events.once('pre-setup', async options => await require(`./hooks/lando-setup-build-engine-${platform}`)(lando, options));
63
65
 
64
- // Ensure we create and install ca if needed
66
+ // do some sepecial handling on wsl
67
+ lando.events.once('pre-setup', async options => await require('./hooks/lando-setup-create-ca-wsl')(lando, options));
68
+ // ensure we create ca
65
69
  lando.events.once('pre-setup', async options => await require('./hooks/lando-setup-create-ca')(lando, options));
66
- lando.events.once('pre-setup', async options => await require(`./hooks/lando-setup-install-ca-${process.platform}`)(lando, options)); // eslint-disable-line max-len
70
+
71
+ // and install ca
72
+ lando.events.once('pre-setup', async options => await require(`./hooks/lando-setup-install-ca-${platform}`)(lando, options));
67
73
 
68
74
  // also move scripts for init considerations
69
75
  lando.events.on('pre-init', 0, async () => await require('./hooks/lando-copy-v3-scripts')(lando));
70
76
 
71
- // Ensure we setup docker-compose if needed
77
+ // ensure we setup docker-compose if needed
72
78
  lando.events.once('pre-setup', async options => await require('./hooks/lando-setup-orchestrator')(lando, options));
73
79
 
74
80
  // move v3 scripts directories as needed
@@ -87,8 +93,8 @@ module.exports = async lando => {
87
93
  // run engine compat checks
88
94
  lando.events.on('almost-ready', 2, async () => await require('./hooks/lando-get-compat')(lando));
89
95
 
90
- // throw error if engine/orchestrator is not available
91
- lando.events.once('pre-engine-autostart', async () => await require('./hooks/lando-dep-check')(lando));
96
+ // throw error if engine is not available
97
+ lando.events.once('pre-engine-autostart', async () => await require('./hooks/lando-setup-check')(lando));
92
98
 
93
99
  // autostart docker if we need to
94
100
  lando.events.once('engine-autostart', async () => await require('./hooks/lando-autostart-engine')(lando));
@@ -96,7 +102,7 @@ module.exports = async lando => {
96
102
  // move v3 scripts directories as needed
97
103
  lando.events.on('pre-engine-start', 0, async () => await require('./hooks/lando-copy-v3-scripts')(lando));
98
104
 
99
- // Return some default things
105
+ // return some default things
100
106
  return _.merge({}, defaults, uc(), {config: {
101
107
  appEnv: {
102
108
  LANDO_CA_CERT: '/lando/certs/' + path.basename(caCert),
package/lib/app.js CHANGED
@@ -57,7 +57,7 @@ module.exports = class App {
57
57
  * @alias app.name
58
58
  */
59
59
  this.name = require('../utils/slugify')(name);
60
- this.project = this.name;
60
+ this.project = require('../utils/docker-composify')(this.name);
61
61
  this._serviceApi = 3;
62
62
  this._config = lando.config;
63
63
  this._defaultService = 'appserver';
@@ -315,7 +315,7 @@ module.exports = class App {
315
315
  // Merge whatever we have thus far together
316
316
  this.info = require('../utils/get-app-info-defaults')(this);
317
317
  // finally just make a list of containers
318
- const separator = _.get(this, '_config.orchestratorSeparator', '-');
318
+ const separator = _.get(this, '_config.orchestratorSeparator', '_');
319
319
  this.containers = _(this.info)
320
320
  .map(service => ([service.service, `${this.project}${separator}${service.service}${separator}1`]))
321
321
  .fromPairs()