@automattic/vip 4.1.6 → 4.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/dev-env.lando.template.yml.ejs +1 -1
- package/dist/bin/vip-app-deploy-token-generate.js +110 -78
- package/dist/bin/vip-app-deploy-token.js +24 -16
- package/dist/bin/vip-app-deploy-validate.js +45 -41
- package/dist/bin/vip-app-deploy.js +222 -215
- package/dist/bin/vip-app-list.js +59 -43
- package/dist/bin/vip-app.js +97 -66
- package/dist/bin/vip-backup-db.js +36 -29
- package/dist/bin/vip-backup.js +16 -9
- package/dist/bin/vip-cache-purge-url.js +93 -55
- package/dist/bin/vip-cache.js +23 -14
- package/dist/bin/vip-config-envvar-delete.js +74 -73
- package/dist/bin/vip-config-envvar-get-all.js +68 -68
- package/dist/bin/vip-config-envvar-get.js +46 -46
- package/dist/bin/vip-config-envvar-list.js +54 -57
- package/dist/bin/vip-config-envvar-set.js +102 -96
- package/dist/bin/vip-config-envvar.js +38 -24
- package/dist/bin/vip-config-software-get.js +88 -75
- package/dist/bin/vip-config-software-update.js +116 -120
- package/dist/bin/vip-config-software.js +31 -21
- package/dist/bin/vip-config.js +25 -17
- package/dist/bin/vip-db-phpmyadmin.js +40 -39
- package/dist/bin/vip-db.js +13 -12
- package/dist/bin/vip-defensive-mode-configure.js +197 -197
- package/dist/bin/vip-defensive-mode-disable.js +43 -35
- package/dist/bin/vip-defensive-mode-enable.js +47 -38
- package/dist/bin/vip-defensive-mode.js +28 -17
- package/dist/bin/vip-dev-env-create.js +147 -104
- package/dist/bin/vip-dev-env-destroy.js +48 -39
- package/dist/bin/vip-dev-env-envvar-delete.js +60 -49
- package/dist/bin/vip-dev-env-envvar-get-all.js +52 -45
- package/dist/bin/vip-dev-env-envvar-get.js +48 -37
- package/dist/bin/vip-dev-env-envvar-list.js +48 -41
- package/dist/bin/vip-dev-env-envvar-set.js +83 -70
- package/dist/bin/vip-dev-env-envvar.js +38 -23
- package/dist/bin/vip-dev-env-exec.js +81 -74
- package/dist/bin/vip-dev-env-import-media.js +34 -26
- package/dist/bin/vip-dev-env-import-sql.js +65 -51
- package/dist/bin/vip-dev-env-import.js +23 -14
- package/dist/bin/vip-dev-env-info.js +59 -50
- package/dist/bin/vip-dev-env-list.js +34 -31
- package/dist/bin/vip-dev-env-logs.js +59 -49
- package/dist/bin/vip-dev-env-purge.js +71 -63
- package/dist/bin/vip-dev-env-shell.js +82 -71
- package/dist/bin/vip-dev-env-start.js +77 -65
- package/dist/bin/vip-dev-env-stop.js +80 -74
- package/dist/bin/vip-dev-env-sync-sql.js +80 -72
- package/dist/bin/vip-dev-env-sync.js +18 -11
- package/dist/bin/vip-dev-env-update.js +93 -84
- package/dist/bin/vip-dev-env.js +25 -8
- package/dist/bin/vip-edge-workers-build.js +82 -54
- package/dist/bin/vip-edge-workers-delete.js +84 -52
- package/dist/bin/vip-edge-workers-deploy.js +186 -126
- package/dist/bin/vip-edge-workers-disable.js +75 -44
- package/dist/bin/vip-edge-workers-enable.js +86 -54
- package/dist/bin/vip-edge-workers-get.js +108 -88
- package/dist/bin/vip-edge-workers-init.js +83 -53
- package/dist/bin/vip-edge-workers-list.js +89 -54
- package/dist/bin/vip-edge-workers-new.js +98 -69
- package/dist/bin/vip-edge-workers-validate.js +123 -82
- package/dist/bin/vip-edge-workers.js +19 -6
- package/dist/bin/vip-export-sql.js +75 -69
- package/dist/bin/vip-export.js +12 -7
- package/dist/bin/vip-import-media-abort.js +99 -73
- package/dist/bin/vip-import-media-status.js +83 -51
- package/dist/bin/vip-import-media.js +165 -166
- package/dist/bin/vip-import-sql-status.js +75 -45
- package/dist/bin/vip-import-sql.js +536 -596
- package/dist/bin/vip-import-validate-files.js +122 -141
- package/dist/bin/vip-import-validate-sql.js +52 -16
- package/dist/bin/vip-import.js +16 -7
- package/dist/bin/vip-logout.js +17 -13
- package/dist/bin/vip-logs.js +209 -183
- package/dist/bin/vip-search-replace.js +85 -53
- package/dist/bin/vip-slowlogs.js +168 -147
- package/dist/bin/vip-sync.js +163 -133
- package/dist/bin/vip-whoami.js +71 -35
- package/dist/bin/vip-wp.js +506 -549
- package/dist/bin/vip.js +161 -116
- package/dist/commands/backup-db.js +183 -149
- package/dist/commands/dev-env-import-sql.js +162 -117
- package/dist/commands/dev-env-sync-sql.js +372 -330
- package/dist/commands/export-sql.js +441 -425
- package/dist/commands/phpmyadmin.js +232 -212
- package/dist/commands/wp-ssh.js +218 -187
- package/dist/lib/analytics/clients/tracks.js +84 -91
- package/dist/lib/analytics/index.js +27 -27
- package/dist/lib/api/app.js +37 -36
- package/dist/lib/api/cache-purge.js +17 -20
- package/dist/lib/api/constants.js +5 -6
- package/dist/lib/api/edge-workers.js +84 -135
- package/dist/lib/api/error-debug.js +10 -13
- package/dist/lib/api/feature-flags.js +16 -17
- package/dist/lib/api/http.js +47 -48
- package/dist/lib/api/user.js +17 -18
- package/dist/lib/api.js +107 -116
- package/dist/lib/app-logs/app-logs.js +24 -25
- package/dist/lib/app-slowlogs/app-slowlogs.js +23 -24
- package/dist/lib/app-slowlogs/types.js +2 -1
- package/dist/lib/app.js +6 -8
- package/dist/lib/backup-storage-availability/backup-storage-availability.js +119 -119
- package/dist/lib/backup-storage-availability/docker-machine-not-found-error.js +5 -6
- package/dist/lib/cli/apiConfig.js +71 -41
- package/dist/lib/cli/command.js +1120 -873
- package/dist/lib/cli/config.js +29 -29
- package/dist/lib/cli/envAlias.js +35 -50
- package/dist/lib/cli/exit.js +19 -19
- package/dist/lib/cli/format.js +172 -172
- package/dist/lib/cli/progress.js +193 -236
- package/dist/lib/cli/prompt.js +14 -15
- package/dist/lib/cli/runtime-mode.js +5 -6
- package/dist/lib/client-file-uploader.js +489 -641
- package/dist/lib/config/software.js +206 -212
- package/dist/lib/constants/dev-environment.js +40 -37
- package/dist/lib/constants/file-size.js +6 -7
- package/dist/lib/constants/vipgo.js +24 -12
- package/dist/lib/custom-deploy/custom-deploy.js +138 -120
- package/dist/lib/database.js +88 -85
- package/dist/lib/defensive-mode/api.js +41 -46
- package/dist/lib/defensive-mode/cli-helpers.js +40 -40
- package/dist/lib/dev-environment/dev-environment-cli.js +776 -735
- package/dist/lib/dev-environment/dev-environment-configuration-file.js +224 -191
- package/dist/lib/dev-environment/dev-environment-core.js +697 -732
- package/dist/lib/dev-environment/dev-environment-database.js +57 -41
- package/dist/lib/dev-environment/dev-environment-lando.js +734 -666
- package/dist/lib/dev-environment/docker-utils.js +96 -90
- package/dist/lib/dev-environment/env-vars.js +61 -59
- package/dist/lib/dev-environment/lando-loader.js +6 -7
- package/dist/lib/dev-environment/types.js +2 -1
- package/dist/lib/edge-workers/confirmation.js +42 -36
- package/dist/lib/edge-workers/deployment.js +150 -159
- package/dist/lib/edge-workers/index.js +68 -85
- package/dist/lib/edge-workers/location.js +26 -26
- package/dist/lib/edge-workers/output.js +14 -15
- package/dist/lib/edge-workers/project.js +123 -132
- package/dist/lib/edge-workers/toolchains/assemblyscript/constants.js +6 -8
- package/dist/lib/edge-workers/toolchains/assemblyscript/index.js +100 -101
- package/dist/lib/edge-workers/toolchains/assemblyscript/templates.js +31 -33
- package/dist/lib/edge-workers/toolchains/index.js +15 -15
- package/dist/lib/edge-workers/types.js +10 -38
- package/dist/lib/edge-workers/validation.js +161 -150
- package/dist/lib/env.js +16 -17
- package/dist/lib/envvar/api-delete.js +16 -18
- package/dist/lib/envvar/api-get-all.js +15 -19
- package/dist/lib/envvar/api-get.js +8 -9
- package/dist/lib/envvar/api-list.js +16 -21
- package/dist/lib/envvar/api-set.js +20 -19
- package/dist/lib/envvar/api.js +34 -29
- package/dist/lib/envvar/input.js +29 -34
- package/dist/lib/envvar/logging.js +9 -11
- package/dist/lib/envvar/read-file.js +6 -7
- package/dist/lib/http/download-file.js +76 -44
- package/dist/lib/http/proxy-agent.js +37 -40
- package/dist/lib/http/proxy-dispatcher.js +69 -71
- package/dist/lib/keychain/insecure.js +40 -36
- package/dist/lib/keychain/keychain.js +2 -1
- package/dist/lib/keychain/secure.js +16 -15
- package/dist/lib/keychain.js +22 -22
- package/dist/lib/live-backup-copy.js +117 -115
- package/dist/lib/logout.js +17 -19
- package/dist/lib/media-import/config.js +15 -14
- package/dist/lib/media-import/media-file-import.js +9 -13
- package/dist/lib/media-import/progress.js +53 -65
- package/dist/lib/media-import/status.js +241 -256
- package/dist/lib/media-import/utils.js +15 -15
- package/dist/lib/node-version-check.js +16 -16
- package/dist/lib/promise.js +16 -17
- package/dist/lib/read-file.js +48 -16
- package/dist/lib/rechallenge/client.js +37 -43
- package/dist/lib/rechallenge/errors.js +38 -37
- package/dist/lib/rechallenge/flow.js +148 -123
- package/dist/lib/rechallenge/index.js +23 -24
- package/dist/lib/rechallenge/link.js +153 -151
- package/dist/lib/rechallenge/open-browser.js +14 -17
- package/dist/lib/rechallenge/token-cache.js +83 -86
- package/dist/lib/rechallenge/types.js +5 -14
- package/dist/lib/retry.js +93 -129
- package/dist/lib/search-and-replace.js +164 -148
- package/dist/lib/site-import/db-file-import.js +12 -16
- package/dist/lib/site-import/status.js +291 -291
- package/dist/lib/token.js +86 -87
- package/dist/lib/tracker.js +51 -62
- package/dist/lib/types/graphql/rate-limit-exceeded-error.js +2 -1
- package/dist/lib/types.js +2 -1
- package/dist/lib/user-error.js +6 -8
- package/dist/lib/utils.js +81 -87
- package/dist/lib/validations/custom-deploy.js +218 -186
- package/dist/lib/validations/is-multi-site-sql-dump.js +6 -6
- package/dist/lib/validations/is-multi-site.js +83 -50
- package/dist/lib/validations/is-multisite-domain-mapped.js +92 -62
- package/dist/lib/validations/line-by-line.js +78 -46
- package/dist/lib/validations/site-type.js +59 -63
- package/dist/lib/validations/sql-insert-parser.js +415 -0
- package/dist/lib/validations/sql.js +551 -431
- package/dist/lib/validations/utils.js +27 -29
- package/dist/lib/vip-import-validate-files.js +481 -490
- package/dist/lib/wp/helpers.js +41 -45
- package/dist/lib/wp/readline.js +21 -57
- package/dist/lib/xdg-data.js +11 -12
- package/helpers/mark-cli-executable.js +9 -0
- package/node_modules/@apollo/client/CHANGELOG.md +10 -0
- package/node_modules/@apollo/client/__cjs/cache/inmemory/helpers.cjs +5 -0
- package/node_modules/@apollo/client/__cjs/cache/inmemory/helpers.cjs.map +1 -1
- package/node_modules/@apollo/client/__cjs/cache/inmemory/inMemoryCache.cjs +2 -1
- package/node_modules/@apollo/client/__cjs/cache/inmemory/inMemoryCache.cjs.map +1 -1
- package/node_modules/@apollo/client/__cjs/cache/inmemory/key-extractor.cjs +14 -2
- package/node_modules/@apollo/client/__cjs/cache/inmemory/key-extractor.cjs.map +1 -1
- package/node_modules/@apollo/client/__cjs/cache/inmemory/policies.cjs +16 -0
- package/node_modules/@apollo/client/__cjs/cache/inmemory/policies.cjs.map +1 -1
- package/node_modules/@apollo/client/__cjs/cache/inmemory/policies.d.cts +2 -0
- package/node_modules/@apollo/client/__cjs/cache/inmemory/writeToStore.cjs +3 -2
- package/node_modules/@apollo/client/__cjs/cache/inmemory/writeToStore.cjs.map +1 -1
- package/node_modules/@apollo/client/__cjs/core/QueryInfo.cjs +9 -1
- package/node_modules/@apollo/client/__cjs/core/QueryInfo.cjs.map +1 -1
- package/node_modules/@apollo/client/__cjs/core/QueryInfo.d.cts +1 -1
- package/node_modules/@apollo/client/__cjs/core/QueryManager.cjs +10 -3
- package/node_modules/@apollo/client/__cjs/core/QueryManager.cjs.map +1 -1
- package/node_modules/@apollo/client/__cjs/react/hooks/useFragment.cjs.map +1 -1
- package/node_modules/@apollo/client/__cjs/react/hooks/useFragment.d.cts +42 -43
- package/node_modules/@apollo/client/__cjs/version.cjs +1 -1
- package/node_modules/@apollo/client/cache/inmemory/helpers.js +5 -0
- package/node_modules/@apollo/client/cache/inmemory/helpers.js.map +1 -1
- package/node_modules/@apollo/client/cache/inmemory/inMemoryCache.js +2 -1
- package/node_modules/@apollo/client/cache/inmemory/inMemoryCache.js.map +1 -1
- package/node_modules/@apollo/client/cache/inmemory/key-extractor.js +14 -2
- package/node_modules/@apollo/client/cache/inmemory/key-extractor.js.map +1 -1
- package/node_modules/@apollo/client/cache/inmemory/policies.d.ts +2 -0
- package/node_modules/@apollo/client/cache/inmemory/policies.js +17 -1
- package/node_modules/@apollo/client/cache/inmemory/policies.js.map +1 -1
- package/node_modules/@apollo/client/cache/inmemory/writeToStore.js +3 -2
- package/node_modules/@apollo/client/cache/inmemory/writeToStore.js.map +1 -1
- package/node_modules/@apollo/client/core/QueryInfo.d.ts +1 -1
- package/node_modules/@apollo/client/core/QueryInfo.js +10 -2
- package/node_modules/@apollo/client/core/QueryInfo.js.map +1 -1
- package/node_modules/@apollo/client/core/QueryManager.js +10 -3
- package/node_modules/@apollo/client/core/QueryManager.js.map +1 -1
- package/node_modules/@apollo/client/package.json +1 -1
- package/node_modules/@apollo/client/react/hooks/useFragment.d.ts +42 -43
- package/node_modules/@apollo/client/react/hooks/useFragment.js.map +1 -1
- package/node_modules/@apollo/client/react/hooks-compiled/useFragment.d.ts +42 -43
- package/node_modules/@apollo/client/react/hooks-compiled/useFragment.js.map +1 -1
- package/node_modules/@apollo/client/version.js +1 -1
- package/node_modules/@automattic/vip-search-replace/README.md +6 -1
- package/node_modules/@automattic/vip-search-replace/lib/index.js +46 -14
- package/node_modules/@automattic/vip-search-replace/package.json +1 -1
- package/node_modules/@types/node/README.md +1 -1
- package/node_modules/@types/node/package.json +2 -2
- package/node_modules/@types/node/zlib.d.ts +752 -0
- package/node_modules/check-disk-space/README.md +92 -32
- package/node_modules/check-disk-space/dist/check-disk-space.d.mts +58 -0
- package/node_modules/check-disk-space/dist/check-disk-space.mjs +170 -190
- package/node_modules/check-disk-space/package.json +43 -71
- package/node_modules/cpu-features/build/Makefile +2 -2
- package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/filesystem.o.d +1 -1
- package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/impl_aarch64_linux_or_android.o.d +1 -1
- package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/impl_aarch64_macos_or_iphone.o.d +1 -1
- package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/impl_aarch64_windows.o.d +1 -1
- package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/impl_arm_linux_or_android.o.d +1 -1
- package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/impl_mips_linux_or_android.o.d +1 -1
- package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/impl_ppc_linux.o.d +1 -1
- package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/impl_x86_freebsd.o.d +1 -1
- package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/impl_x86_linux_or_android.o.d +1 -1
- package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/impl_x86_macos.o.d +1 -1
- package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/impl_x86_windows.o.d +1 -1
- package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/stack_line_reader.o.d +1 -1
- package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/string_view.o.d +1 -1
- package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpufeatures/src/binding.o.d +157 -145
- package/node_modules/cpu-features/build/Release/cpufeatures.node +0 -0
- package/node_modules/cpu-features/build/Release/obj.target/cpufeatures/src/binding.o +0 -0
- package/node_modules/cpu-features/build/Release/obj.target/cpufeatures.node +0 -0
- package/node_modules/cpu-features/build/config.gypi +100 -31
- package/node_modules/cpu-features/build/cpufeatures.target.mk +14 -14
- package/node_modules/cpu-features/build/deps/cpu_features/cpu_features.target.mk +14 -14
- package/node_modules/ssh2/lib/protocol/crypto/build/Makefile +2 -2
- package/node_modules/ssh2/lib/protocol/crypto/build/Release/.deps/Release/obj.target/sshcrypto/src/binding.o.d.raw +136 -0
- package/node_modules/ssh2/lib/protocol/crypto/build/sshcrypto.target.mk +14 -14
- package/node_modules/undici/docs/docs/api/Interceptors.md +15 -2
- package/node_modules/undici/lib/dispatcher/client-h2.js +78 -3
- package/node_modules/undici/lib/dispatcher/pool-base.js +20 -3
- package/node_modules/undici/package.json +3 -3
- package/node_modules/undici/types/api.d.ts +1 -1
- package/node_modules/undici/types/utility.d.ts +4 -4
- package/package.json +44 -13
- package/dist/lib/analytics/clients/client.js +0 -1
- package/dist/lib/analytics/clients/pendo.js +0 -78
- package/helpers/check-version.js +0 -16
- package/node_modules/check-disk-space/dist/check-disk-space.cjs +0 -210
- package/node_modules/check-disk-space/dist/check-disk-space.d.ts +0 -53
- package/node_modules/fetch-retry/.eslintignore +0 -1
- package/node_modules/fetch-retry/.eslintrc.yml +0 -20
- package/node_modules/fetch-retry/.github/workflows/node.js.yml +0 -32
- package/node_modules/fetch-retry/.husky/pre-commit +0 -6
- package/node_modules/fetch-retry/.nycrc.json +0 -24
- package/node_modules/fetch-retry/.travis.yml +0 -3
- package/node_modules/fetch-retry/LICENSE +0 -21
- package/node_modules/fetch-retry/README.md +0 -128
- package/node_modules/fetch-retry/dist/fetch-retry.umd.js +0 -151
- package/node_modules/fetch-retry/index.d.ts +0 -29
- package/node_modules/fetch-retry/index.js +0 -143
- package/node_modules/fetch-retry/package.json +0 -41
- package/node_modules/fetch-retry/rollup.config.js +0 -12
- package/node_modules/fetch-retry/test/.eslintrc.yml +0 -7
- package/node_modules/fetch-retry/test/integration/index.js +0 -212
- package/node_modules/fetch-retry/test/integration/mock-api/index.js +0 -42
- package/node_modules/fetch-retry/test/unit/index.js +0 -1169
- package/node_modules/ssh2/lib/protocol/crypto/build/Release/.deps/Release/obj.target/sshcrypto/src/binding.o.d +0 -265
- package/node_modules/ssh2/lib/protocol/crypto/build/Release/.deps/Release/obj.target/sshcrypto.node.d +0 -1
- package/node_modules/ssh2/lib/protocol/crypto/build/Release/.deps/Release/sshcrypto.node.d +0 -1
- package/node_modules/ssh2/lib/protocol/crypto/build/Release/obj.target/sshcrypto/src/binding.o +0 -0
- package/node_modules/ssh2/lib/protocol/crypto/build/Release/obj.target/sshcrypto.node +0 -0
- package/node_modules/ssh2/lib/protocol/crypto/build/Release/sshcrypto.node +0 -0
|
@@ -1,725 +1,794 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.getLandoApplication = getLandoApplication;
|
|
4
40
|
exports.bootstrapLando = bootstrapLando;
|
|
41
|
+
exports.landoStart = landoStart;
|
|
42
|
+
exports.landoLogs = landoLogs;
|
|
43
|
+
exports.landoRebuild = landoRebuild;
|
|
44
|
+
exports.removeProxyCache = removeProxyCache;
|
|
45
|
+
exports.landoStop = landoStop;
|
|
46
|
+
exports.landoDestroy = landoDestroy;
|
|
47
|
+
exports.landoInfo = landoInfo;
|
|
5
48
|
exports.checkEnvHealth = checkEnvHealth;
|
|
6
|
-
exports.getLandoApplication = getLandoApplication;
|
|
7
|
-
exports.getProxyContainer = getProxyContainer;
|
|
8
|
-
exports.isContainerRunning = isContainerRunning;
|
|
9
49
|
exports.isEnvUp = isEnvUp;
|
|
10
|
-
exports.landoDestroy = landoDestroy;
|
|
11
50
|
exports.landoExec = landoExec;
|
|
12
|
-
exports.landoInfo = landoInfo;
|
|
13
|
-
exports.landoLogs = landoLogs;
|
|
14
|
-
exports.landoRebuild = landoRebuild;
|
|
15
51
|
exports.landoShell = landoShell;
|
|
16
|
-
exports.
|
|
17
|
-
exports.landoStop = landoStop;
|
|
18
|
-
exports.removeProxyCache = removeProxyCache;
|
|
52
|
+
exports.getProxyContainer = getProxyContainer;
|
|
19
53
|
exports.validateDockerInstalled = validateDockerInstalled;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
54
|
+
exports.isContainerRunning = isContainerRunning;
|
|
55
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
56
|
+
const debug_1 = __importDefault(require("debug"));
|
|
57
|
+
const node_child_process_1 = require("node:child_process");
|
|
58
|
+
const promises_1 = require("node:dns/promises");
|
|
59
|
+
const promises_2 = require("node:fs/promises");
|
|
60
|
+
const node_os_1 = require("node:os");
|
|
61
|
+
const node_path_1 = __importStar(require("node:path"));
|
|
62
|
+
const node_util_1 = require("node:util");
|
|
63
|
+
const semver_1 = require("semver");
|
|
64
|
+
const dev_environment_core_1 = require("./dev-environment-core");
|
|
65
|
+
const docker_utils_1 = require("./docker-utils");
|
|
66
|
+
const lando_loader_1 = require("./lando-loader");
|
|
67
|
+
const runtime_mode_1 = require("../cli/runtime-mode");
|
|
68
|
+
const dev_environment_1 = require("../constants/dev-environment");
|
|
69
|
+
const env_1 = __importDefault(require("../env"));
|
|
70
|
+
const user_error_1 = __importDefault(require("../user-error"));
|
|
71
|
+
const xdg_data_1 = require("../xdg-data");
|
|
39
72
|
/**
|
|
40
73
|
* This file will hold all the interactions with lando library
|
|
41
74
|
*/
|
|
42
75
|
const DEBUG_KEY = '@automattic/vip:bin:dev-environment';
|
|
43
|
-
const debug = (0,
|
|
44
|
-
const execFileAsync = (0,
|
|
45
|
-
const unwrapLandoModuleDefault = loaded => {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
76
|
+
const debug = (0, debug_1.default)(DEBUG_KEY);
|
|
77
|
+
const execFileAsync = (0, node_util_1.promisify)(node_child_process_1.execFile);
|
|
78
|
+
const unwrapLandoModuleDefault = (loaded) => {
|
|
79
|
+
if (loaded && typeof loaded === 'object' && 'default' in loaded) {
|
|
80
|
+
return loaded.default;
|
|
81
|
+
}
|
|
82
|
+
return loaded;
|
|
50
83
|
};
|
|
51
84
|
let landoConstructor = null;
|
|
52
85
|
let landoBuildTaskFn = null;
|
|
53
86
|
let landoUtilsModule = null;
|
|
54
87
|
let buildConfigFn = null;
|
|
55
88
|
const getLandoConstructor = () => {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
89
|
+
if (!landoConstructor) {
|
|
90
|
+
landoConstructor = unwrapLandoModuleDefault((0, lando_loader_1.loadLandoModule)('lando/lib/lando'));
|
|
91
|
+
}
|
|
92
|
+
return landoConstructor;
|
|
60
93
|
};
|
|
61
94
|
const getLandoBuildTask = () => {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
95
|
+
if (!landoBuildTaskFn) {
|
|
96
|
+
landoBuildTaskFn = unwrapLandoModuleDefault((0, lando_loader_1.loadLandoModule)('lando/plugins/lando-tooling/lib/build'));
|
|
97
|
+
}
|
|
98
|
+
return landoBuildTaskFn;
|
|
66
99
|
};
|
|
67
100
|
const getLandoUtils = () => {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
101
|
+
if (!landoUtilsModule) {
|
|
102
|
+
landoUtilsModule = unwrapLandoModuleDefault((0, lando_loader_1.loadLandoModule)('lando/plugins/lando-core/lib/utils'));
|
|
103
|
+
}
|
|
104
|
+
return landoUtilsModule;
|
|
72
105
|
};
|
|
73
106
|
const getLandoBuildConfig = () => {
|
|
74
|
-
if (!buildConfigFn) {
|
|
75
|
-
const loaded = (0, _landoLoader.loadLandoModule)('lando/lib/bootstrap');
|
|
76
|
-
buildConfigFn = loaded.buildConfig ?? loaded.default?.buildConfig ?? null;
|
|
77
107
|
if (!buildConfigFn) {
|
|
78
|
-
|
|
108
|
+
const loaded = (0, lando_loader_1.loadLandoModule)('lando/lib/bootstrap');
|
|
109
|
+
buildConfigFn = loaded.buildConfig ?? loaded.default?.buildConfig ?? null;
|
|
110
|
+
if (!buildConfigFn) {
|
|
111
|
+
throw new Error('Unable to load Lando bootstrap buildConfig.');
|
|
112
|
+
}
|
|
79
113
|
}
|
|
80
|
-
|
|
81
|
-
return buildConfigFn;
|
|
114
|
+
return buildConfigFn;
|
|
82
115
|
};
|
|
83
116
|
const bannerLabelWidth = 18;
|
|
84
117
|
let logPathRegistered = false;
|
|
85
118
|
let resolvedLogPath = null;
|
|
86
|
-
const getLogFilePath = config => {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
119
|
+
const getLogFilePath = (config) => {
|
|
120
|
+
if (config.logFile) {
|
|
121
|
+
return node_path_1.default.isAbsolute(config.logFile)
|
|
122
|
+
? config.logFile
|
|
123
|
+
: node_path_1.default.join(config.logDir ?? '', config.logFile);
|
|
124
|
+
}
|
|
125
|
+
if (config.logDir && config.logName) {
|
|
126
|
+
return node_path_1.default.join(config.logDir, `${config.logName}.log`);
|
|
127
|
+
}
|
|
128
|
+
return null;
|
|
94
129
|
};
|
|
95
130
|
const registerLogPathOutput = (config, quiet) => {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
131
|
+
if (logPathRegistered) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
resolvedLogPath = getLogFilePath(config);
|
|
135
|
+
if (!resolvedLogPath) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
logPathRegistered = true;
|
|
139
|
+
if (quiet) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
process.once('exit', () => {
|
|
143
|
+
if (resolvedLogPath && process.stdout.isTTY) {
|
|
144
|
+
console.log(`\n ${formatBannerLine(chalk_1.default.cyan('COMMAND LOG FILE'.padEnd(bannerLabelWidth)), resolvedLogPath)}`);
|
|
145
|
+
}
|
|
146
|
+
});
|
|
112
147
|
};
|
|
113
|
-
const formatBytes = bytes => {
|
|
114
|
-
|
|
115
|
-
|
|
148
|
+
const formatBytes = (bytes) => {
|
|
149
|
+
const gb = bytes / 1024 ** 3;
|
|
150
|
+
return `${gb.toFixed(1)} GB`;
|
|
116
151
|
};
|
|
117
|
-
const isRecord = value => typeof value === 'object' && value !== null;
|
|
118
|
-
const isDockerPluginInfo = value => isRecord(value);
|
|
119
|
-
const getDockerVersions = async config => {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
152
|
+
const isRecord = (value) => typeof value === 'object' && value !== null;
|
|
153
|
+
const isDockerPluginInfo = (value) => isRecord(value);
|
|
154
|
+
const getDockerVersions = async (config) => {
|
|
155
|
+
const dockerBin = config.dockerBin ?? '';
|
|
156
|
+
const composeBin = config.composeBin ?? '';
|
|
157
|
+
let engine = 'unknown';
|
|
158
|
+
let compose = 'unknown';
|
|
159
|
+
let composePlugin = 'unknown';
|
|
160
|
+
try {
|
|
161
|
+
if (dockerBin) {
|
|
162
|
+
const { stdout } = await execFileAsync(dockerBin, ['info', '--format', 'json']);
|
|
163
|
+
const dockerData = JSON.parse(stdout);
|
|
164
|
+
if (isRecord(dockerData)) {
|
|
165
|
+
const serverVersion = dockerData.ServerVersion;
|
|
166
|
+
if (typeof serverVersion === 'string') {
|
|
167
|
+
engine = serverVersion;
|
|
168
|
+
}
|
|
169
|
+
const clientInfo = dockerData.ClientInfo;
|
|
170
|
+
if (isRecord(clientInfo)) {
|
|
171
|
+
const plugins = clientInfo.Plugins;
|
|
172
|
+
if (Array.isArray(plugins)) {
|
|
173
|
+
const composePluginEntry = plugins.find(plugin => isDockerPluginInfo(plugin) && plugin.Name === 'compose');
|
|
174
|
+
if (composePluginEntry && typeof composePluginEntry.Version === 'string') {
|
|
175
|
+
composePlugin = composePluginEntry.Version;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
143
179
|
}
|
|
144
|
-
}
|
|
145
180
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}
|
|
161
|
-
return {
|
|
162
|
-
engine,
|
|
163
|
-
compose,
|
|
164
|
-
composePlugin
|
|
165
|
-
};
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
debug('Failed to read docker version info: %O', error);
|
|
184
|
+
}
|
|
185
|
+
try {
|
|
186
|
+
if (composeBin) {
|
|
187
|
+
const { stdout } = await execFileAsync(composeBin, ['version', '--short']);
|
|
188
|
+
compose = stdout.trim() || compose;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
debug('Failed to read docker-compose version info: %O', error);
|
|
193
|
+
}
|
|
194
|
+
return { engine, compose, composePlugin };
|
|
166
195
|
};
|
|
167
196
|
const formatBannerLine = (label, value) => `${label.padEnd(bannerLabelWidth)} ${value}`;
|
|
168
|
-
const writeLogBanner = async config => {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
recursive: true
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
197
|
+
const writeLogBanner = async (config) => {
|
|
198
|
+
const logFilePath = getLogFilePath(config);
|
|
199
|
+
if (!logFilePath) {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
try {
|
|
203
|
+
const existing = await (0, promises_2.stat)(logFilePath);
|
|
204
|
+
if (existing.size > 0) {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
// File does not exist yet.
|
|
210
|
+
}
|
|
211
|
+
await (0, promises_2.mkdir)(node_path_1.default.dirname(logFilePath), { recursive: true });
|
|
212
|
+
const dockerVersions = await getDockerVersions(config);
|
|
213
|
+
const command = process.argv.slice(1).join(' ');
|
|
214
|
+
const bannerLines = [
|
|
215
|
+
'=== VIP Dev Env Log ===',
|
|
216
|
+
formatBannerLine('COMMAND', command),
|
|
217
|
+
formatBannerLine('OS', `${env_1.default.os.name} ${env_1.default.os.version} ${env_1.default.os.arch}`),
|
|
218
|
+
formatBannerLine('NODE', env_1.default.node.version),
|
|
219
|
+
formatBannerLine('VIP-CLI', env_1.default.app.version),
|
|
220
|
+
formatBannerLine('RUNTIME', (0, runtime_mode_1.getRuntimeModeLabel)()),
|
|
221
|
+
formatBannerLine('DOCKER ENGINE', dockerVersions.engine),
|
|
222
|
+
formatBannerLine('DOCKER COMPOSE', dockerVersions.compose),
|
|
223
|
+
formatBannerLine('COMPOSE PLUGIN', dockerVersions.composePlugin),
|
|
224
|
+
formatBannerLine('DOCKER BIN', config.dockerBin ?? 'unknown'),
|
|
225
|
+
formatBannerLine('COMPOSE BIN', config.composeBin ?? 'unknown'),
|
|
226
|
+
formatBannerLine('RAM', formatBytes((0, node_os_1.totalmem)())),
|
|
227
|
+
formatBannerLine('CPU', String((0, node_os_1.cpus)().length)),
|
|
228
|
+
'===',
|
|
229
|
+
'',
|
|
230
|
+
'',
|
|
231
|
+
];
|
|
232
|
+
await (0, promises_2.writeFile)(logFilePath, bannerLines.join('\n'), { flag: 'a' });
|
|
190
233
|
};
|
|
191
|
-
|
|
192
234
|
/**
|
|
193
235
|
* @return {Promise<LandoConfig>} Lando configuration
|
|
194
236
|
*/
|
|
195
237
|
async function getLandoConfig(options = {}) {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
238
|
+
// The path will be smth like `yarn/global/node_modules/lando/lib/lando.js`; we need the path up to `lando` (inclusive)
|
|
239
|
+
const landoPath = (0, node_path_1.dirname)((0, node_path_1.dirname)((0, lando_loader_1.resolveLandoModule)('lando')));
|
|
240
|
+
debug(`Getting Lando config, using paths '${landoPath}' for plugins`);
|
|
241
|
+
const isLandoDebugSelected = debug_1.default.enabled(DEBUG_KEY);
|
|
242
|
+
const isAllDebugSelected = debug_1.default.enabled('"*"');
|
|
243
|
+
let logLevelConsole;
|
|
244
|
+
if (isAllDebugSelected) {
|
|
245
|
+
logLevelConsole = 'silly';
|
|
246
|
+
}
|
|
247
|
+
else if (isLandoDebugSelected) {
|
|
248
|
+
logLevelConsole = 'debug';
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
logLevelConsole = 'warn';
|
|
252
|
+
}
|
|
253
|
+
const vipDir = node_path_1.default.join((0, xdg_data_1.xdgData)(), 'vip');
|
|
254
|
+
const landoDir = node_path_1.default.join(vipDir, 'lando');
|
|
255
|
+
const fakeHomeDir = node_path_1.default.join(landoDir, 'home');
|
|
256
|
+
const logDir = node_path_1.default.join(landoDir, 'logs');
|
|
257
|
+
try {
|
|
258
|
+
await (0, promises_2.mkdir)(fakeHomeDir, { recursive: true });
|
|
259
|
+
}
|
|
260
|
+
catch {
|
|
261
|
+
// Ignore
|
|
262
|
+
}
|
|
263
|
+
const config = {
|
|
264
|
+
logLevelConsole,
|
|
265
|
+
logDir,
|
|
266
|
+
logFile: options.logFile ?? 'vip-dev-env.log',
|
|
267
|
+
logName: options.logName ?? 'vip-dev-env',
|
|
268
|
+
configSources: [node_path_1.default.join(landoDir, 'config.yml')],
|
|
269
|
+
landoFile: '.lando.yml',
|
|
270
|
+
preLandoFiles: ['.lando.base.yml', '.lando.dist.yml', '.lando.upstream.yml'],
|
|
271
|
+
postLandoFiles: ['.lando.local.yml'],
|
|
272
|
+
pluginDirs: [landoPath],
|
|
273
|
+
disablePlugins: [],
|
|
274
|
+
proxyName: 'vip-dev-env-proxy',
|
|
275
|
+
userConfRoot: landoDir,
|
|
276
|
+
home: fakeHomeDir,
|
|
277
|
+
domain: 'vipdev.lndo.site',
|
|
278
|
+
version: 'unknown',
|
|
279
|
+
env: {
|
|
280
|
+
LANDO_HOST_USER_ID: process.platform === 'win32' ? '1000' : `${(0, node_os_1.userInfo)().uid}`,
|
|
281
|
+
LANDO_HOST_GROUP_ID: process.platform === 'win32' ? '1000' : `${(0, node_os_1.userInfo)().gid}`,
|
|
282
|
+
},
|
|
283
|
+
};
|
|
284
|
+
return getLandoBuildConfig()(config);
|
|
242
285
|
}
|
|
243
286
|
const appMap = new Map();
|
|
244
287
|
async function initLandoApplication(lando, instancePath) {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
288
|
+
const app = lando.getApp(instancePath);
|
|
289
|
+
app.events.on('post-init', 1, () => {
|
|
290
|
+
const initOnly = [];
|
|
291
|
+
const services = app.config.services;
|
|
292
|
+
Object.keys(services).forEach(serviceName => {
|
|
293
|
+
if (services[serviceName].initOnly) {
|
|
294
|
+
initOnly.push(serviceName);
|
|
295
|
+
app.config.services[serviceName].scanner =
|
|
296
|
+
false;
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
app.services = app.services.filter(service => !initOnly.includes(service));
|
|
254
300
|
});
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
await app.init();
|
|
258
|
-
return app;
|
|
301
|
+
await app.init();
|
|
302
|
+
return app;
|
|
259
303
|
}
|
|
260
304
|
async function regenerateLandofile(lando, instancePath) {
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
305
|
+
const landoFile = node_path_1.default.join(instancePath, '.lando.yml');
|
|
306
|
+
try {
|
|
307
|
+
const now = new Date().toISOString().replace(/[^\d]/g, '').slice(0, -3);
|
|
308
|
+
const backup = `${landoFile}.${now}`;
|
|
309
|
+
await (0, promises_2.rename)(landoFile, backup);
|
|
310
|
+
console.warn(chalk_1.default.yellow('Backed up %s to %s'), landoFile, backup);
|
|
311
|
+
}
|
|
312
|
+
catch (error) {
|
|
313
|
+
debug(`Failed to backup lando file ${landoFile}:`, error);
|
|
314
|
+
// Rename failed - possibly the file does not exist. Silently ignoring.
|
|
315
|
+
}
|
|
316
|
+
const slug = node_path_1.default.basename(instancePath);
|
|
317
|
+
const currentInstanceData = (0, dev_environment_core_1.readEnvironmentData)(slug);
|
|
318
|
+
currentInstanceData.pullAfter = 0;
|
|
319
|
+
await (0, dev_environment_core_1.updateEnvironment)(lando, currentInstanceData);
|
|
275
320
|
}
|
|
276
321
|
async function landoRecovery(lando, instancePath, error) {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
} catch (err) {
|
|
282
|
-
console.error(`${_chalk.default.bold.red('Recovery failed, aborting.')} Please recreate the environment or contact support.`);
|
|
283
|
-
throw err;
|
|
284
|
-
}
|
|
285
|
-
console.error(_chalk.default.green('Recovery successful, trying to initialize again...'));
|
|
286
|
-
try {
|
|
287
|
-
return await initLandoApplication(lando, instancePath);
|
|
288
|
-
} catch (initError) {
|
|
289
|
-
console.error(`${_chalk.default.bold.red('Initialization failed, aborting.')} Please recreate the environment or contact support.`);
|
|
290
|
-
throw initError;
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
async function getLandoApplication(lando, instancePath) {
|
|
294
|
-
const started = new Date();
|
|
295
|
-
try {
|
|
296
|
-
if (appMap.has(instancePath)) {
|
|
297
|
-
return Promise.resolve(appMap.get(instancePath));
|
|
322
|
+
debug('Error initializing Lando app', error);
|
|
323
|
+
console.warn(chalk_1.default.yellow('There was an error initializing Lando, trying to recover...'));
|
|
324
|
+
try {
|
|
325
|
+
await regenerateLandofile(lando, instancePath);
|
|
298
326
|
}
|
|
299
|
-
|
|
300
|
-
|
|
327
|
+
catch (err) {
|
|
328
|
+
console.error(`${chalk_1.default.bold.red('Recovery failed, aborting.')} Please recreate the environment or contact support.`);
|
|
329
|
+
throw err;
|
|
301
330
|
}
|
|
302
|
-
|
|
331
|
+
console.error(chalk_1.default.green('Recovery successful, trying to initialize again...'));
|
|
303
332
|
try {
|
|
304
|
-
|
|
305
|
-
}
|
|
306
|
-
|
|
333
|
+
return await initLandoApplication(lando, instancePath);
|
|
334
|
+
}
|
|
335
|
+
catch (initError) {
|
|
336
|
+
console.error(`${chalk_1.default.bold.red('Initialization failed, aborting.')} Please recreate the environment or contact support.`);
|
|
337
|
+
throw initError;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
async function getLandoApplication(lando, instancePath) {
|
|
341
|
+
const started = new Date();
|
|
342
|
+
try {
|
|
343
|
+
if (appMap.has(instancePath)) {
|
|
344
|
+
return Promise.resolve(appMap.get(instancePath));
|
|
345
|
+
}
|
|
346
|
+
if (!(await (0, dev_environment_core_1.doesEnvironmentExist)(instancePath))) {
|
|
347
|
+
throw new Error(dev_environment_1.DEV_ENVIRONMENT_NOT_FOUND);
|
|
348
|
+
}
|
|
349
|
+
let app;
|
|
350
|
+
try {
|
|
351
|
+
app = await initLandoApplication(lando, instancePath);
|
|
352
|
+
}
|
|
353
|
+
catch (error) {
|
|
354
|
+
app = await landoRecovery(lando, instancePath, error);
|
|
355
|
+
}
|
|
356
|
+
appMap.set(instancePath, app);
|
|
357
|
+
return app;
|
|
358
|
+
}
|
|
359
|
+
finally {
|
|
360
|
+
const duration = new Date().getTime() - started.getTime();
|
|
361
|
+
debug('getLandoApplication() took %d ms', duration);
|
|
307
362
|
}
|
|
308
|
-
appMap.set(instancePath, app);
|
|
309
|
-
return app;
|
|
310
|
-
} finally {
|
|
311
|
-
const duration = new Date().getTime() - started.getTime();
|
|
312
|
-
debug('getLandoApplication() took %d ms', duration);
|
|
313
|
-
}
|
|
314
363
|
}
|
|
315
364
|
async function bootstrapLando(options = {}) {
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
365
|
+
const started = new Date();
|
|
366
|
+
try {
|
|
367
|
+
if (process.env.DEBUG && !process.env.DEBUG.includes('-winston:*')) {
|
|
368
|
+
process.env.DEBUG = `${process.env.DEBUG},-winston:*`;
|
|
369
|
+
}
|
|
370
|
+
const socket = await (0, docker_utils_1.getDockerSocket)();
|
|
371
|
+
const config = await getLandoConfig(options);
|
|
372
|
+
debug('Docker socket: %j', socket);
|
|
373
|
+
if (socket) {
|
|
374
|
+
config.engineConfig = await (0, docker_utils_1.getEngineConfig)(socket);
|
|
375
|
+
debug('Engine config: %j', config.engineConfig);
|
|
376
|
+
}
|
|
377
|
+
registerLogPathOutput(config, Boolean(options.quiet));
|
|
378
|
+
await writeLogBanner(config);
|
|
379
|
+
const LandoClass = getLandoConstructor();
|
|
380
|
+
const lando = new LandoClass(config);
|
|
381
|
+
debug_1.default.log = (message, ...args) => {
|
|
382
|
+
lando.log.debug(message, ...args);
|
|
383
|
+
};
|
|
384
|
+
lando.events.once('pre-engine-build', async (data) => {
|
|
385
|
+
const instanceData = (0, dev_environment_core_1.readEnvironmentData)(data.name);
|
|
386
|
+
let registryResolvable = false;
|
|
387
|
+
try {
|
|
388
|
+
registryResolvable = (await (0, promises_1.lookup)('ghcr.io')).address.length > 0 || false;
|
|
389
|
+
debug('Registry ghcr.io is resolvable');
|
|
390
|
+
}
|
|
391
|
+
catch (err) {
|
|
392
|
+
debug('Registry ghcr.io is not resolvable, image pull might be broken. Error: %O', err);
|
|
393
|
+
registryResolvable = false;
|
|
394
|
+
}
|
|
395
|
+
const pull = registryResolvable && (instanceData.pullAfter ?? 0) < Date.now();
|
|
396
|
+
if (Array.isArray(data.opts.pullable) &&
|
|
397
|
+
Array.isArray(data.opts.local) &&
|
|
398
|
+
data.opts.local.length === 0 &&
|
|
399
|
+
!pull) {
|
|
400
|
+
// Setting `data.opts.pullable` to an empty array prevents Lando from pulling images with `docker pull`.
|
|
401
|
+
// Note that if some of the images are not available, they will still be pulled by `docker-compose`.
|
|
402
|
+
data.opts.local = data.opts.pullable;
|
|
403
|
+
data.opts.pullable = [];
|
|
404
|
+
}
|
|
405
|
+
if (pull || !instanceData.pullAfter) {
|
|
406
|
+
instanceData.pullAfter = Date.now() + 7 * 24 * 60 * 60 * 1000;
|
|
407
|
+
await (0, dev_environment_core_1.writeEnvironmentData)(data.name, instanceData);
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
await lando.bootstrap();
|
|
411
|
+
return lando;
|
|
412
|
+
}
|
|
413
|
+
finally {
|
|
414
|
+
const duration = new Date().getTime() - started.getTime();
|
|
415
|
+
debug('bootstrapLando() took %d ms', duration);
|
|
416
|
+
}
|
|
363
417
|
}
|
|
364
418
|
async function landoStart(lando, instancePath) {
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
419
|
+
const started = new Date();
|
|
420
|
+
try {
|
|
421
|
+
debug('Will start lando app on path:', instancePath);
|
|
422
|
+
const app = await getLandoApplication(lando, instancePath);
|
|
423
|
+
await app.start();
|
|
424
|
+
}
|
|
425
|
+
finally {
|
|
426
|
+
const duration = new Date().getTime() - started.getTime();
|
|
427
|
+
debug('landoStart() took %d ms', duration);
|
|
428
|
+
}
|
|
374
429
|
}
|
|
375
430
|
async function landoLogs(lando, instancePath, options) {
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
431
|
+
const started = new Date();
|
|
432
|
+
try {
|
|
433
|
+
debug('Will show lando logs on path:', instancePath, ' with options: ', options);
|
|
434
|
+
const app = await getLandoApplication(lando, instancePath);
|
|
435
|
+
const logTask = lando.tasks.find(task => task.command === 'logs');
|
|
436
|
+
await logTask?.run({
|
|
437
|
+
follow: options.follow,
|
|
438
|
+
service: options.service,
|
|
439
|
+
timestamps: options.timestamps,
|
|
440
|
+
_app: app,
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
finally {
|
|
444
|
+
const duration = new Date().getTime() - started.getTime();
|
|
445
|
+
debug('landoLogs() took %d ms', duration);
|
|
446
|
+
}
|
|
391
447
|
}
|
|
392
448
|
async function landoRebuild(lando, instancePath) {
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
449
|
+
const started = new Date();
|
|
450
|
+
try {
|
|
451
|
+
debug('Will rebuild lando app on path:', instancePath);
|
|
452
|
+
const app = await getLandoApplication(lando, instancePath);
|
|
453
|
+
await ensureNoOrphantProxyContainer(lando);
|
|
454
|
+
await app.rebuild();
|
|
455
|
+
}
|
|
456
|
+
finally {
|
|
457
|
+
const duration = new Date().getTime() - started.getTime();
|
|
458
|
+
debug('landoRebuild() took %d ms', duration);
|
|
459
|
+
}
|
|
403
460
|
}
|
|
404
461
|
async function getBridgeNetwork(lando) {
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
462
|
+
const networkName = lando.config.networkBridge ?? 'lando_bridge_network';
|
|
463
|
+
try {
|
|
464
|
+
return await lando.engine.getNetwork(networkName).inspect();
|
|
465
|
+
}
|
|
466
|
+
catch (err) {
|
|
467
|
+
debug('Error getting network %s: %s', networkName, err.message);
|
|
468
|
+
return null;
|
|
469
|
+
}
|
|
412
470
|
}
|
|
413
471
|
async function removeProxyCache(lando) {
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
// Swallow
|
|
422
|
-
}
|
|
472
|
+
const { userConfRoot, proxyCache } = lando.config;
|
|
473
|
+
try {
|
|
474
|
+
await (0, promises_2.unlink)(node_path_1.default.join(userConfRoot, 'cache', proxyCache ?? 'proxyCache'));
|
|
475
|
+
}
|
|
476
|
+
catch {
|
|
477
|
+
// Swallow
|
|
478
|
+
}
|
|
423
479
|
}
|
|
424
480
|
async function cleanUpLandoProxy(lando) {
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
}
|
|
481
|
+
const network = await getBridgeNetwork(lando);
|
|
482
|
+
if (network?.Containers && Object.keys(network.Containers).length === 1) {
|
|
483
|
+
const proxy = lando.engine.docker.getContainer(lando.config.proxyContainer);
|
|
484
|
+
try {
|
|
485
|
+
await proxy.remove({ force: true });
|
|
486
|
+
}
|
|
487
|
+
catch (err) {
|
|
488
|
+
debug('Error removing proxy container: %s', err.message);
|
|
489
|
+
}
|
|
490
|
+
await removeProxyCache(lando);
|
|
491
|
+
}
|
|
437
492
|
}
|
|
438
493
|
async function landoStop(lando, instancePath) {
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
494
|
+
const started = new Date();
|
|
495
|
+
try {
|
|
496
|
+
debug('Will stop lando app on path:', instancePath);
|
|
497
|
+
const app = await getLandoApplication(lando, instancePath);
|
|
498
|
+
app.events.once('post-stop', () => cleanUpLandoProxy(lando));
|
|
499
|
+
await app.stop();
|
|
500
|
+
}
|
|
501
|
+
finally {
|
|
502
|
+
const duration = new Date().getTime() - started.getTime();
|
|
503
|
+
debug('landoStop() took %d ms', duration);
|
|
504
|
+
}
|
|
449
505
|
}
|
|
450
506
|
async function landoDestroy(lando, instancePath) {
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
507
|
+
const started = new Date();
|
|
508
|
+
try {
|
|
509
|
+
debug('Will destroy lando app on path:', instancePath);
|
|
510
|
+
const app = await getLandoApplication(lando, instancePath);
|
|
511
|
+
app.events.once('post-stop', () => cleanUpLandoProxy(lando));
|
|
512
|
+
await app.destroy();
|
|
513
|
+
}
|
|
514
|
+
finally {
|
|
515
|
+
const duration = new Date().getTime() - started.getTime();
|
|
516
|
+
debug('landoDestroy() took %d ms', duration);
|
|
517
|
+
}
|
|
461
518
|
}
|
|
462
519
|
async function landoInfo(lando, instancePath, options = {}) {
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
// Add login information
|
|
489
|
-
if (frontEndUrl) {
|
|
490
|
-
const loginURL = new URL(`${frontEndUrl}wp-admin/`);
|
|
491
|
-
if (options.autologinKey) {
|
|
492
|
-
loginURL.searchParams.set('vip-dev-autologin', options.autologinKey);
|
|
493
|
-
}
|
|
494
|
-
loginURL.protocol = 'http:';
|
|
495
|
-
const httpLoginUrl = loginURL.toString();
|
|
496
|
-
loginURL.protocol = 'https:';
|
|
497
|
-
const httpsLoginUrl = loginURL.toString();
|
|
498
|
-
appInfo['Login URL'] = [httpsLoginUrl, httpLoginUrl].join(_nodeOs.EOL);
|
|
499
|
-
appInfo['Default username'] = 'vipgo';
|
|
500
|
-
|
|
501
|
-
// Get the stored password from instance data
|
|
502
|
-
const instanceData = (0, _devEnvironmentCore.readEnvironmentData)(appInfo.slug);
|
|
503
|
-
appInfo['Default password'] = instanceData.adminPassword || 'password'; // NOSONAR
|
|
504
|
-
}
|
|
505
|
-
if (!options.suppressWarnings && hasWarnings) {
|
|
506
|
-
let message = _chalk.default.bold.yellow('The following services have failed health checks:\n');
|
|
507
|
-
Object.keys(health).forEach(service => {
|
|
508
|
-
if (!health[service]) {
|
|
509
|
-
message += `${_chalk.default.red(service)}\n`;
|
|
520
|
+
const started = new Date();
|
|
521
|
+
try {
|
|
522
|
+
const app = await getLandoApplication(lando, instancePath);
|
|
523
|
+
const info = getLandoUtils().startTable(app);
|
|
524
|
+
const reachableServices = app.info.filter(service => service.urls.length);
|
|
525
|
+
reachableServices.forEach(service => (info[`${service.service} urls`] = service.urls));
|
|
526
|
+
const health = await checkEnvHealth(lando, app);
|
|
527
|
+
const frontEndUrl = app.info.find(service => 'nginx' === service.service)?.urls[0] ?? '';
|
|
528
|
+
const extraService = await getExtraServicesConnections(lando, app);
|
|
529
|
+
const appInfo = {
|
|
530
|
+
slug: info.name.replace(/^vipdev/, ''),
|
|
531
|
+
...info,
|
|
532
|
+
...extraService,
|
|
533
|
+
};
|
|
534
|
+
delete appInfo.name;
|
|
535
|
+
const hasResults = Object.values(health).length > 0;
|
|
536
|
+
const hasWarnings = Object.values(health).some(status => !status);
|
|
537
|
+
if (hasResults && !hasWarnings) {
|
|
538
|
+
appInfo.status = chalk_1.default.green('UP');
|
|
539
|
+
}
|
|
540
|
+
else if (health.nginx) {
|
|
541
|
+
appInfo.status = chalk_1.default.yellow('PARTIALLY UP');
|
|
542
|
+
}
|
|
543
|
+
else {
|
|
544
|
+
appInfo.status = chalk_1.default.red('DOWN');
|
|
510
545
|
}
|
|
511
|
-
|
|
512
|
-
|
|
546
|
+
// Add login information
|
|
547
|
+
if (frontEndUrl) {
|
|
548
|
+
const loginURL = new URL(`${frontEndUrl}wp-admin/`);
|
|
549
|
+
if (options.autologinKey) {
|
|
550
|
+
loginURL.searchParams.set('vip-dev-autologin', options.autologinKey);
|
|
551
|
+
}
|
|
552
|
+
loginURL.protocol = 'http:';
|
|
553
|
+
const httpLoginUrl = loginURL.toString();
|
|
554
|
+
loginURL.protocol = 'https:';
|
|
555
|
+
const httpsLoginUrl = loginURL.toString();
|
|
556
|
+
appInfo['Login URL'] = [httpsLoginUrl, httpLoginUrl].join(node_os_1.EOL);
|
|
557
|
+
appInfo['Default username'] = 'vipgo';
|
|
558
|
+
// Get the stored password from instance data
|
|
559
|
+
const instanceData = (0, dev_environment_core_1.readEnvironmentData)(appInfo.slug);
|
|
560
|
+
appInfo['Default password'] = instanceData.adminPassword || 'password'; // NOSONAR
|
|
561
|
+
}
|
|
562
|
+
if (!options.suppressWarnings && hasWarnings) {
|
|
563
|
+
let message = chalk_1.default.bold.yellow('The following services have failed health checks:\n');
|
|
564
|
+
Object.keys(health).forEach(service => {
|
|
565
|
+
if (!health[service]) {
|
|
566
|
+
message += `${chalk_1.default.red(service)}\n`;
|
|
567
|
+
}
|
|
568
|
+
});
|
|
569
|
+
appInfo['Health warnings'] = message;
|
|
570
|
+
}
|
|
571
|
+
// Add documentation link
|
|
572
|
+
appInfo.Documentation = 'https://docs.wpvip.com/vip-local-development-environment/';
|
|
573
|
+
return appInfo;
|
|
574
|
+
}
|
|
575
|
+
finally {
|
|
576
|
+
const duration = new Date().getTime() - started.getTime();
|
|
577
|
+
debug('landoInfo() took %d ms', duration);
|
|
513
578
|
}
|
|
514
|
-
|
|
515
|
-
// Add documentation link
|
|
516
|
-
appInfo.Documentation = 'https://docs.wpvip.com/vip-local-development-environment/';
|
|
517
|
-
return appInfo;
|
|
518
|
-
} finally {
|
|
519
|
-
const duration = new Date().getTime() - started.getTime();
|
|
520
|
-
debug('landoInfo() took %d ms', duration);
|
|
521
|
-
}
|
|
522
579
|
}
|
|
523
|
-
const extraServiceDisplayConfiguration = [
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
}
|
|
580
|
+
const extraServiceDisplayConfiguration = [
|
|
581
|
+
{
|
|
582
|
+
name: 'elasticsearch',
|
|
583
|
+
label: 'enterprise search',
|
|
584
|
+
protocol: 'http',
|
|
585
|
+
},
|
|
586
|
+
{
|
|
587
|
+
name: 'phpmyadmin',
|
|
588
|
+
// Skipping, as the phpmyadmin was already printed by the regular services
|
|
589
|
+
skip: true,
|
|
590
|
+
},
|
|
591
|
+
{
|
|
592
|
+
name: 'mailhog',
|
|
593
|
+
skip: true,
|
|
594
|
+
},
|
|
595
|
+
{
|
|
596
|
+
name: 'mailpit',
|
|
597
|
+
skip: true,
|
|
598
|
+
},
|
|
599
|
+
];
|
|
538
600
|
async function getExtraServicesConnections(lando, app) {
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
601
|
+
const extraServices = {};
|
|
602
|
+
const allServices = await lando.engine.list({ project: app.project });
|
|
603
|
+
const defaultDisplayConfiguration = {
|
|
604
|
+
skip: false,
|
|
605
|
+
label: null,
|
|
606
|
+
protocol: null,
|
|
607
|
+
};
|
|
608
|
+
for (const service of allServices) {
|
|
609
|
+
const displayConfiguration = extraServiceDisplayConfiguration.find(conf => conf.name === service.service) ??
|
|
610
|
+
defaultDisplayConfiguration;
|
|
611
|
+
if (displayConfiguration.skip) {
|
|
612
|
+
continue;
|
|
613
|
+
}
|
|
614
|
+
// eslint-disable-next-line no-await-in-loop
|
|
615
|
+
const containerScan = service.id ? await lando.engine.docker.scan(service.id) : null;
|
|
616
|
+
if (containerScan?.NetworkSettings.Ports) {
|
|
617
|
+
const mappings = Object.values(containerScan.NetworkSettings.Ports).filter(externalMapping => externalMapping?.length);
|
|
618
|
+
mappings[0]?.forEach(({ HostIp: host, HostPort: port }) => {
|
|
619
|
+
const label = displayConfiguration.label ?? service.service;
|
|
620
|
+
const hostname = host.includes(':') ? `[${host}]` : host;
|
|
621
|
+
const value = (displayConfiguration.protocol ? `${displayConfiguration.protocol}://` : '') +
|
|
622
|
+
`${hostname}:${port}`;
|
|
623
|
+
if (extraServices[label]) {
|
|
624
|
+
extraServices[label] += `, ${value}`;
|
|
625
|
+
}
|
|
626
|
+
else {
|
|
627
|
+
extraServices[label] = value;
|
|
628
|
+
}
|
|
629
|
+
});
|
|
568
630
|
}
|
|
569
|
-
});
|
|
570
631
|
}
|
|
571
|
-
|
|
572
|
-
return extraServices;
|
|
632
|
+
return extraServices;
|
|
573
633
|
}
|
|
574
634
|
async function tryResolveDomains(urls) {
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
635
|
+
const domains = [
|
|
636
|
+
...new Set(urls
|
|
637
|
+
.filter(url => url.toLowerCase().startsWith('http'))
|
|
638
|
+
.map(url => {
|
|
639
|
+
try {
|
|
640
|
+
return new URL(url).hostname;
|
|
641
|
+
}
|
|
642
|
+
catch {
|
|
643
|
+
return undefined;
|
|
644
|
+
}
|
|
645
|
+
})
|
|
646
|
+
.filter(domain => domain !== undefined)),
|
|
647
|
+
];
|
|
648
|
+
const domainsToFix = [];
|
|
649
|
+
for (const domain of domains) {
|
|
650
|
+
try {
|
|
651
|
+
// eslint-disable-next-line no-await-in-loop
|
|
652
|
+
const address = await (0, promises_1.lookup)(domain, 4);
|
|
653
|
+
debug('%s resolves to %s', domain, address.address);
|
|
654
|
+
if (address.address !== '127.0.0.1') {
|
|
655
|
+
domainsToFix.push(domain);
|
|
656
|
+
console.warn(chalk_1.default.yellow.bold('WARNING:'), `${domain} resolves to ${address.address} instead of 127.0.0.1. Things may not work as expected.`);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
catch (err) {
|
|
660
|
+
const msg = err instanceof Error ? err.message : 'Unknown error';
|
|
661
|
+
domainsToFix.push(domain);
|
|
662
|
+
console.warn(chalk_1.default.yellow.bold('WARNING:'), `Failed to resolve ${domain}: ${msg}`);
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
if (domainsToFix.length) {
|
|
666
|
+
console.warn(chalk_1.default.yellow('Please add the following lines to the hosts file on your system:\n'));
|
|
667
|
+
console.warn(domainsToFix.map(domain => `127.0.0.1 ${domain}`).join('\n'));
|
|
668
|
+
console.warn(chalk_1.default.yellow('\nLearn more: https://docs.wpvip.com/vip-local-development-environment/troubleshooting-dev-env/#h-resolve-networking-configuration-issues\n'));
|
|
580
669
|
}
|
|
581
|
-
}).filter(domain => domain !== undefined))];
|
|
582
|
-
const domainsToFix = [];
|
|
583
|
-
for (const domain of domains) {
|
|
584
|
-
try {
|
|
585
|
-
// eslint-disable-next-line no-await-in-loop
|
|
586
|
-
const address = await (0, _promises.lookup)(domain, 4);
|
|
587
|
-
debug('%s resolves to %s', domain, address.address);
|
|
588
|
-
if (address.address !== '127.0.0.1') {
|
|
589
|
-
domainsToFix.push(domain);
|
|
590
|
-
console.warn(_chalk.default.yellow.bold('WARNING:'), `${domain} resolves to ${address.address} instead of 127.0.0.1. Things may not work as expected.`);
|
|
591
|
-
}
|
|
592
|
-
} catch (err) {
|
|
593
|
-
const msg = err instanceof Error ? err.message : 'Unknown error';
|
|
594
|
-
domainsToFix.push(domain);
|
|
595
|
-
console.warn(_chalk.default.yellow.bold('WARNING:'), `Failed to resolve ${domain}: ${msg}`);
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
if (domainsToFix.length) {
|
|
599
|
-
console.warn(_chalk.default.yellow('Please add the following lines to the hosts file on your system:\n'));
|
|
600
|
-
console.warn(domainsToFix.map(domain => `127.0.0.1 ${domain}`).join('\n'));
|
|
601
|
-
console.warn(_chalk.default.yellow('\nLearn more: https://docs.wpvip.com/vip-local-development-environment/troubleshooting-dev-env/#h-resolve-networking-configuration-issues\n'));
|
|
602
|
-
}
|
|
603
670
|
}
|
|
604
671
|
async function getRunningServicesForProject(docker, project) {
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
672
|
+
const containers = await docker.listContainers({
|
|
673
|
+
filters: {
|
|
674
|
+
label: [`com.docker.compose.project=${project}`],
|
|
675
|
+
},
|
|
676
|
+
});
|
|
677
|
+
return containers
|
|
678
|
+
.filter(container => container.State === 'running')
|
|
679
|
+
.map(container => container.Labels['com.docker.compose.service']);
|
|
611
680
|
}
|
|
612
681
|
async function checkEnvHealth(lando, app) {
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
urls
|
|
620
|
-
|
|
682
|
+
const urls = {};
|
|
683
|
+
const now = new Date();
|
|
684
|
+
app.urls ??= [];
|
|
685
|
+
app.info
|
|
686
|
+
.filter(service => service.urls.length)
|
|
687
|
+
.forEach(service => {
|
|
688
|
+
service.urls.forEach(url => {
|
|
689
|
+
if (!/^https?:\/\/(localhost|127\.0\.0\.1):/.exec(url)) {
|
|
690
|
+
urls[url] = service.service;
|
|
691
|
+
}
|
|
692
|
+
});
|
|
693
|
+
});
|
|
694
|
+
const urlsToScan = Object.keys(urls).filter(url => !url.includes('*'));
|
|
695
|
+
await tryResolveDomains(urlsToScan);
|
|
696
|
+
app.urls.forEach(entry => {
|
|
697
|
+
// We use different status codes to see if the service is up.
|
|
698
|
+
// We may consider the service is up when Lando considers it is down.
|
|
699
|
+
if (entry.color !== 'red') {
|
|
700
|
+
urlsToScan.splice(urlsToScan.indexOf(entry.url), 1);
|
|
701
|
+
}
|
|
621
702
|
});
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
if (urlsToScan.length) {
|
|
646
|
-
scanResults = scanResults.concat(await app.scanUrls(urlsToScan, {
|
|
647
|
-
max: 1,
|
|
648
|
-
waitCodes: [502, 504]
|
|
649
|
-
}));
|
|
650
|
-
}
|
|
651
|
-
const result = {};
|
|
652
|
-
scanResults.forEach(scanResult => {
|
|
653
|
-
result[urls[scanResult.url]] = scanResult.status;
|
|
654
|
-
});
|
|
655
|
-
const duration = new Date().getTime() - now.getTime();
|
|
656
|
-
debug('checkEnvHealth took %d ms', duration);
|
|
657
|
-
return result;
|
|
703
|
+
const runningServices = await getRunningServicesForProject(lando.engine.docker, app.project);
|
|
704
|
+
Object.entries(urls).forEach(([url, service]) => {
|
|
705
|
+
if (!runningServices.includes(service)) {
|
|
706
|
+
app.urls.push({
|
|
707
|
+
url,
|
|
708
|
+
color: 'red',
|
|
709
|
+
status: false,
|
|
710
|
+
});
|
|
711
|
+
debug('Service %s is not running, removing %s from the scan queue', service, url);
|
|
712
|
+
urlsToScan.splice(urlsToScan.indexOf(url), 1);
|
|
713
|
+
}
|
|
714
|
+
});
|
|
715
|
+
let scanResults = app.urls;
|
|
716
|
+
if (urlsToScan.length) {
|
|
717
|
+
scanResults = scanResults.concat(await app.scanUrls(urlsToScan, { max: 1, waitCodes: [502, 504] }));
|
|
718
|
+
}
|
|
719
|
+
const result = {};
|
|
720
|
+
scanResults.forEach(scanResult => {
|
|
721
|
+
result[urls[scanResult.url]] = scanResult.status;
|
|
722
|
+
});
|
|
723
|
+
const duration = new Date().getTime() - now.getTime();
|
|
724
|
+
debug('checkEnvHealth took %d ms', duration);
|
|
725
|
+
return result;
|
|
658
726
|
}
|
|
659
727
|
async function isEnvUp(lando, instancePath) {
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
728
|
+
const app = await getLandoApplication(lando, instancePath);
|
|
729
|
+
const healthResults = await checkEnvHealth(lando, app);
|
|
730
|
+
return Object.keys(healthResults).length > 0 && Object.values(healthResults).every(Boolean);
|
|
663
731
|
}
|
|
664
732
|
async function landoExec(lando, instancePath, toolName, args, options) {
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
733
|
+
const app = await getLandoApplication(lando, instancePath);
|
|
734
|
+
const tool = app.config.tooling[toolName];
|
|
735
|
+
if (!tool) {
|
|
736
|
+
throw new user_error_1.default(`${toolName} is not a known lando task`);
|
|
737
|
+
}
|
|
738
|
+
const savedArgv = process.argv;
|
|
739
|
+
try {
|
|
740
|
+
/*
|
|
741
|
+
lando is looking in both passed args and process.argv so we need to do a bit of hack to fake process.argv
|
|
742
|
+
so that lando doesn't try to interpret args not meant for wp.
|
|
743
|
+
|
|
744
|
+
Lando drops first 3 args (<node> <lando> <command>) from process.argv and process rest, so we will fake 3 args + the real args
|
|
745
|
+
*/
|
|
746
|
+
process.argv = ['0', '1', '3'].concat(args);
|
|
747
|
+
tool.app = app;
|
|
748
|
+
tool.name = toolName;
|
|
749
|
+
if (options.stdio) {
|
|
750
|
+
tool.stdio = options.stdio;
|
|
751
|
+
}
|
|
752
|
+
const task = getLandoBuildTask()(tool, lando);
|
|
753
|
+
const argv = {
|
|
754
|
+
// eslint-disable-next-line id-length
|
|
755
|
+
_: args,
|
|
756
|
+
};
|
|
757
|
+
await task.run(argv);
|
|
758
|
+
}
|
|
759
|
+
finally {
|
|
760
|
+
process.argv = savedArgv;
|
|
761
|
+
}
|
|
692
762
|
}
|
|
693
763
|
async function landoShell(lando, instancePath, service, user, command) {
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
user,
|
|
705
|
-
|
|
706
|
-
|
|
764
|
+
const app = await getLandoApplication(lando, instancePath);
|
|
765
|
+
const shellTask = lando.tasks.find(task => task.command === 'ssh');
|
|
766
|
+
if (!command.length) {
|
|
767
|
+
const interactive = process.stdin.isTTY ? '-i' : '';
|
|
768
|
+
command = [
|
|
769
|
+
'/bin/sh',
|
|
770
|
+
'-c',
|
|
771
|
+
`if [ -x /bin/bash ]; then /bin/bash ${interactive}; else /bin/sh ${interactive}; fi; exit 0`,
|
|
772
|
+
];
|
|
773
|
+
}
|
|
774
|
+
debug('Running command "%o" in service "%s" as user "%s"', command, service, user);
|
|
775
|
+
await shellTask?.run({
|
|
776
|
+
command,
|
|
777
|
+
service,
|
|
778
|
+
user,
|
|
779
|
+
_app: app,
|
|
780
|
+
});
|
|
707
781
|
}
|
|
708
782
|
async function getProxyContainer(lando) {
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
docker
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
const container = docker.getContainer(proxyContainerName);
|
|
718
|
-
return container.inspect();
|
|
719
|
-
}
|
|
720
|
-
return null;
|
|
783
|
+
const proxyContainerName = lando.config.proxyContainer;
|
|
784
|
+
const { docker } = lando.engine;
|
|
785
|
+
const containers = await docker.listContainers({ all: true });
|
|
786
|
+
if (containers.some(container => container.Names.includes(`/${proxyContainerName}`))) {
|
|
787
|
+
const container = docker.getContainer(proxyContainerName);
|
|
788
|
+
return container.inspect();
|
|
789
|
+
}
|
|
790
|
+
return null;
|
|
721
791
|
}
|
|
722
|
-
|
|
723
792
|
/**
|
|
724
793
|
* Sometimes the proxy network seems to disapper leaving only orphant stopped proxy container.
|
|
725
794
|
* It seems to happen while restarting/powering off computer. This container would then failed
|
|
@@ -729,48 +798,47 @@ async function getProxyContainer(lando) {
|
|
|
729
798
|
* can safely add a network and a new proxy container.
|
|
730
799
|
*/
|
|
731
800
|
async function ensureNoOrphantProxyContainer(lando) {
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
801
|
+
const proxyContainer = await getProxyContainer(lando);
|
|
802
|
+
if (proxyContainer && !proxyContainer.State.Running) {
|
|
803
|
+
const containerName = proxyContainer.Name.startsWith('/')
|
|
804
|
+
? proxyContainer.Name.slice(1)
|
|
805
|
+
: proxyContainer.Name;
|
|
806
|
+
const container = lando.engine.docker.getContainer(containerName);
|
|
807
|
+
await container.remove();
|
|
808
|
+
}
|
|
738
809
|
}
|
|
739
810
|
function validateDockerInstalled(lando) {
|
|
740
|
-
|
|
741
|
-
engine,
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
}
|
|
758
|
-
if (!(0, _semver.satisfies)(compose, '>=2.0.0')) {
|
|
759
|
-
throw new Error(`docker-compose version ${compose} is not supported. Please upgrade to version 2.0.0 or higher - https://docs.docker.com/compose/install/`);
|
|
760
|
-
}
|
|
761
|
-
}
|
|
811
|
+
const { engine, composePlugin, compose } = lando.config.versions;
|
|
812
|
+
lando.log.verbose('docker-engine version: %s', engine);
|
|
813
|
+
if (!engine) {
|
|
814
|
+
if (!lando.config.dockerBin) {
|
|
815
|
+
throw new user_error_1.default('docker binary could not be located! Please follow the following instructions to install it - https://docs.docker.com/engine/install/');
|
|
816
|
+
}
|
|
817
|
+
throw new user_error_1.default('Failed to connect to Docker. Please verify that Docker engine (service) is running and follow the troubleshooting instructions for your platform.');
|
|
818
|
+
}
|
|
819
|
+
lando.log.verbose('docker-compose version: %s', compose);
|
|
820
|
+
lando.log.verbose('compose plugin version: %s', composePlugin);
|
|
821
|
+
if (!composePlugin) {
|
|
822
|
+
if (!compose) {
|
|
823
|
+
throw new Error('docker-compose binary could not be located! Please follow the following instructions to install it - https://docs.docker.com/compose/install/');
|
|
824
|
+
}
|
|
825
|
+
if (!(0, semver_1.satisfies)(compose, '>=2.0.0')) {
|
|
826
|
+
throw new Error(`docker-compose version ${compose} is not supported. Please upgrade to version 2.0.0 or higher - https://docs.docker.com/compose/install/`);
|
|
827
|
+
}
|
|
828
|
+
}
|
|
762
829
|
}
|
|
763
830
|
async function isContainerRunning(lando, slug, serviceName) {
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
docker
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
831
|
+
const envPath = (0, dev_environment_core_1.getEnvironmentPath)(slug);
|
|
832
|
+
const app = await getLandoApplication(lando, envPath);
|
|
833
|
+
const { docker } = app.engine;
|
|
834
|
+
const containers = await docker.listContainers({
|
|
835
|
+
filters: {
|
|
836
|
+
label: [
|
|
837
|
+
`com.docker.compose.project=${app.project}`,
|
|
838
|
+
`com.docker.compose.service=${serviceName}`,
|
|
839
|
+
],
|
|
840
|
+
status: ['running'],
|
|
841
|
+
},
|
|
842
|
+
});
|
|
843
|
+
return containers.length > 0;
|
|
844
|
+
}
|