@aifabrix/builder 2.44.5 → 2.45.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cursor/rules/cli-layout.mdc +8 -4
- package/.cursor/rules/project-rules.mdc +1 -1
- package/README.md +15 -23
- package/integration/hubspot-test/README.md +2 -0
- package/integration/hubspot-test/test.js +5 -3
- package/jest.projects.js +104 -2
- package/lib/api/controller-health.api.js +49 -0
- package/lib/api/dimension-values.api.js +82 -0
- package/lib/api/dimensions.api.js +114 -0
- package/lib/api/external-systems.api.js +1 -0
- package/lib/api/integration-clients.api.js +168 -0
- package/lib/api/types/dimension-values.types.js +28 -0
- package/lib/api/types/dimensions.types.js +31 -0
- package/lib/api/types/integration-clients.types.js +45 -0
- package/lib/api/validation-runner.js +46 -25
- package/lib/app/deploy-config.js +11 -1
- package/lib/app/deploy-status-display.js +3 -3
- package/lib/app/deploy.js +36 -14
- package/lib/app/display.js +15 -11
- package/lib/app/helpers.js +3 -3
- package/lib/app/index.js +3 -3
- package/lib/app/push.js +46 -23
- package/lib/app/register.js +7 -6
- package/lib/app/restart-display.js +126 -0
- package/lib/app/rotate-secret.js +7 -6
- package/lib/app/run-container-start.js +12 -6
- package/lib/app/run-env-compose.js +30 -1
- package/lib/app/run-helpers.js +58 -19
- package/lib/app/run-reload-sync.js +148 -0
- package/lib/app/run-resolve-image.js +51 -1
- package/lib/app/run.js +148 -74
- package/lib/app/show-display.js +7 -0
- package/lib/app/show.js +87 -5
- package/lib/build/index.js +83 -49
- package/lib/cli/doctor-check.js +117 -0
- package/lib/cli/index.js +8 -2
- package/lib/cli/infra-guided.js +460 -0
- package/lib/cli/installation-log-command.js +73 -0
- package/lib/cli/setup-app.js +31 -3
- package/lib/cli/setup-auth.js +98 -27
- package/lib/cli/setup-dev-path-commands.js +50 -3
- package/lib/cli/setup-infra-up-dataplane-action.js +111 -0
- package/lib/cli/setup-infra-up-platform-action.js +131 -0
- package/lib/cli/setup-infra.js +132 -118
- package/lib/cli/setup-integration-client.js +182 -0
- package/lib/cli/setup-parameters.js +21 -2
- package/lib/cli/setup-platform.js +102 -0
- package/lib/cli/setup-secrets.js +18 -6
- package/lib/cli/setup-utility-resolve.js +132 -0
- package/lib/cli/setup-utility.js +143 -84
- package/lib/commands/app-logs.js +81 -33
- package/lib/commands/auth-config.js +116 -18
- package/lib/commands/datasource-capability-dimension-cli.js +128 -0
- package/lib/commands/datasource-capability-output.js +29 -0
- package/lib/commands/datasource-capability-relate-cli.js +140 -0
- package/lib/commands/datasource-capability.js +411 -0
- package/lib/commands/datasource-unified-test-cli.options.js +1 -1
- package/lib/commands/datasource.js +53 -13
- package/lib/commands/dev-down.js +3 -3
- package/lib/commands/dev-infra-gate.js +32 -0
- package/lib/commands/dev-init.js +13 -7
- package/lib/commands/dimension-value.js +179 -0
- package/lib/commands/dimension.js +330 -0
- package/lib/commands/integration-client.js +430 -0
- package/lib/commands/login-device.js +65 -30
- package/lib/commands/login.js +21 -10
- package/lib/commands/parameters-validate.js +78 -13
- package/lib/commands/repair-datasource-auto-rbac.js +166 -0
- package/lib/commands/repair-datasource-keys.js +10 -5
- package/lib/commands/repair-datasource.js +19 -7
- package/lib/commands/repair-env-template.js +4 -1
- package/lib/commands/repair-openapi-sync.js +172 -0
- package/lib/commands/repair-persist.js +102 -0
- package/lib/commands/repair-rbac-extract.js +27 -0
- package/lib/commands/repair-rbac-migrate.js +186 -0
- package/lib/commands/repair-rbac.js +214 -31
- package/lib/commands/repair-system-alignment.js +246 -0
- package/lib/commands/repair-system-permissions.js +168 -0
- package/lib/commands/repair.js +120 -338
- package/lib/commands/secure.js +1 -1
- package/lib/commands/setup-modes.js +468 -0
- package/lib/commands/setup-prompts.js +421 -0
- package/lib/commands/setup.js +254 -0
- package/lib/commands/teardown.js +277 -0
- package/lib/commands/up-common.js +113 -19
- package/lib/commands/up-dataplane.js +44 -19
- package/lib/commands/up-miso.js +18 -18
- package/lib/commands/upload.js +111 -23
- package/lib/commands/wizard-core-helpers.js +14 -11
- package/lib/commands/wizard-core.js +6 -5
- package/lib/commands/wizard-dataplane.js +2 -2
- package/lib/commands/wizard-entity-selection.js +4 -3
- package/lib/commands/wizard-headless.js +2 -1
- package/lib/commands/wizard.js +2 -1
- package/lib/constants/infra-compose-service-names.js +40 -0
- package/lib/core/audit-logger.js +1 -34
- package/lib/core/config-admin-email.js +56 -0
- package/lib/core/config-normalize.js +60 -0
- package/lib/core/config-registered-controller-urls.js +54 -0
- package/lib/core/config.js +33 -50
- package/lib/core/env-reader.js +16 -3
- package/lib/core/secrets-admin-env.js +101 -0
- package/lib/core/secrets-ensure-infra.js +34 -1
- package/lib/core/secrets-ensure.js +88 -66
- package/lib/core/secrets-env-content.js +428 -0
- package/lib/core/secrets-env-declarative-expand.js +170 -0
- package/lib/core/secrets-env-write.js +29 -1
- package/lib/core/secrets-load.js +252 -0
- package/lib/core/secrets-names.js +32 -0
- package/lib/core/secrets.js +17 -757
- package/lib/datasource/capability/basic-exposure.js +76 -0
- package/lib/datasource/capability/capability-diff-slice.js +41 -0
- package/lib/datasource/capability/capability-key.js +34 -0
- package/lib/datasource/capability/capability-resolve.js +172 -0
- package/lib/datasource/capability/capability-storage-keys.js +22 -0
- package/lib/datasource/capability/copy-operations.js +348 -0
- package/lib/datasource/capability/copy-test-payload.js +139 -0
- package/lib/datasource/capability/create-operations.js +235 -0
- package/lib/datasource/capability/dimension-operations.js +151 -0
- package/lib/datasource/capability/dimension-validate.js +219 -0
- package/lib/datasource/capability/json-pointer.js +31 -0
- package/lib/datasource/capability/reference-rewrite.js +51 -0
- package/lib/datasource/capability/relate-operations.js +325 -0
- package/lib/datasource/capability/relate-validate.js +219 -0
- package/lib/datasource/capability/remove-operations.js +275 -0
- package/lib/datasource/capability/run-capability-copy.js +152 -0
- package/lib/datasource/capability/run-capability-diff.js +135 -0
- package/lib/datasource/capability/run-capability-dimension.js +291 -0
- package/lib/datasource/capability/run-capability-edit.js +377 -0
- package/lib/datasource/capability/run-capability-relate.js +193 -0
- package/lib/datasource/capability/run-capability-remove.js +105 -0
- package/lib/datasource/capability/templates/minimal-fetch.json +18 -0
- package/lib/datasource/capability/validate-capability-slice.js +35 -0
- package/lib/datasource/list.js +136 -23
- package/lib/datasource/log-viewer.js +2 -4
- package/lib/datasource/unified-validation-run.js +51 -16
- package/lib/datasource/validate.js +53 -1
- package/lib/deployment/deploy-poll-ui.js +60 -0
- package/lib/deployment/deployer-status.js +29 -3
- package/lib/deployment/deployer.js +48 -30
- package/lib/deployment/environment.js +7 -2
- package/lib/deployment/poll-interval.js +72 -0
- package/lib/deployment/push.js +11 -9
- package/lib/external-system/deploy.js +9 -2
- package/lib/external-system/download.js +61 -32
- package/lib/external-system/sync-deploy-manifest.js +33 -0
- package/lib/infrastructure/index.js +49 -19
- package/lib/infrastructure/orphan-infra-docker-teardown.js +177 -0
- package/lib/internal/node-fs.js +2 -0
- package/lib/parameters/infra-kv-discovery.js +29 -4
- package/lib/parameters/infra-parameter-catalog.js +6 -3
- package/lib/parameters/infra-parameter-validate.js +67 -19
- package/lib/resolvers/datasource-resolver.js +53 -0
- package/lib/resolvers/dimension-file.js +52 -0
- package/lib/resolvers/manifest-resolver.js +133 -0
- package/lib/schema/application-schema.json +4 -0
- package/lib/schema/external-datasource.schema.json +183 -53
- package/lib/schema/external-system.schema.json +23 -10
- package/lib/schema/infra.parameter.yaml +26 -1
- package/lib/schema/wizard-config.schema.json +1 -1
- package/lib/utils/aifabrix-config-dir-walk.js +40 -0
- package/lib/utils/aifabrix-runtime-config-dir.js +26 -3
- package/lib/utils/app-config-resolver.js +24 -1
- package/lib/utils/app-run-containers.js +2 -2
- package/lib/utils/applications-config-defaults.js +206 -0
- package/lib/utils/auth-config-validator.js +2 -12
- package/lib/utils/bash-secret-env.js +59 -0
- package/lib/utils/cli-secrets-error-format.js +78 -0
- package/lib/utils/cli-test-layout-chalk.js +31 -9
- package/lib/utils/cli-utils.js +4 -36
- package/lib/utils/compose-generate-docker-compose.js +111 -6
- package/lib/utils/compose-generator.js +17 -8
- package/lib/utils/controller-url.js +50 -7
- package/lib/utils/datasource-test-run-display.js +8 -0
- package/lib/utils/dev-hosts-helper.js +3 -2
- package/lib/utils/dev-init-ssh-merge.js +2 -1
- package/lib/utils/docker-build.js +17 -9
- package/lib/utils/docker-reload-mount.js +127 -0
- package/lib/utils/env-copy.js +99 -14
- package/lib/utils/env-template.js +5 -1
- package/lib/utils/external-readme.js +71 -2
- package/lib/utils/external-system-local-test-tty.js +3 -2
- package/lib/utils/external-system-readiness-core.js +45 -12
- package/lib/utils/external-system-readiness-deploy-display.js +3 -3
- package/lib/utils/external-system-readiness-display-internals.js +33 -3
- package/lib/utils/external-system-readiness-display.js +10 -1
- package/lib/utils/file-upload.js +40 -3
- package/lib/utils/health-check-db-init.js +107 -0
- package/lib/utils/health-check-public-warn.js +69 -0
- package/lib/utils/health-check-url.js +28 -10
- package/lib/utils/health-check.js +139 -107
- package/lib/utils/help-builder.js +5 -1
- package/lib/utils/image-name.js +34 -7
- package/lib/utils/infra-optional-service-flags.js +69 -0
- package/lib/utils/installation-log-core.js +282 -0
- package/lib/utils/installation-log-record.js +237 -0
- package/lib/utils/installation-log.js +123 -0
- package/lib/utils/integration-file-backup.js +74 -0
- package/lib/utils/log-redaction.js +105 -0
- package/lib/utils/manifest-location.js +164 -0
- package/lib/utils/manifest-source-emit.js +162 -0
- package/lib/utils/mutagen-install.js +30 -3
- package/lib/utils/paths.js +308 -76
- package/lib/utils/postgres-wipe.js +212 -0
- package/lib/utils/register-aifabrix-shell-env.js +15 -0
- package/lib/utils/remote-dev-auth.js +21 -5
- package/lib/utils/remote-docker-env.js +9 -1
- package/lib/utils/remote-secrets-loader.js +49 -4
- package/lib/utils/resolve-docker-image-ref.js +9 -3
- package/lib/utils/run-cli-flags.js +29 -0
- package/lib/utils/secrets-ancestor-paths.js +47 -0
- package/lib/utils/secrets-canonical.js +10 -3
- package/lib/utils/secrets-helpers.js +17 -10
- package/lib/utils/secrets-kv-refs.js +42 -0
- package/lib/utils/secrets-kv-scope.js +19 -2
- package/lib/utils/secrets-materialize-local.js +134 -0
- package/lib/utils/secrets-path.js +26 -13
- package/lib/utils/secrets-utils.js +20 -10
- package/lib/utils/system-builder-root.js +42 -0
- package/lib/utils/url-declarative-public-base.js +80 -12
- package/lib/utils/url-declarative-resolve-build-urls.js +238 -0
- package/lib/utils/url-declarative-resolve-build.js +24 -388
- package/lib/utils/url-declarative-resolve-expand-token.js +189 -0
- package/lib/utils/url-declarative-resolve-load-doc.js +12 -3
- package/lib/utils/url-declarative-resolve-surface-state.js +102 -0
- package/lib/utils/url-declarative-resolve.js +47 -7
- package/lib/utils/url-declarative-runtime-base-path.js +52 -0
- package/lib/utils/url-declarative-vdir-inactive-env.js +2 -1
- package/lib/utils/urls-local-registry-scan.js +103 -0
- package/lib/utils/urls-local-registry.js +158 -76
- package/lib/utils/validation-poll-ui.js +81 -0
- package/lib/utils/validation-run-poll.js +29 -5
- package/lib/utils/with-muted-logger.js +53 -0
- package/package.json +3 -1
- package/templates/applications/dataplane/application.yaml +5 -1
- package/templates/applications/dataplane/rbac.yaml +10 -10
- package/templates/applications/keycloak/env.template +8 -6
- package/templates/applications/miso-controller/application.yaml +9 -0
- package/templates/applications/miso-controller/env.template +27 -29
- package/templates/applications/miso-controller/rbac.yaml +9 -9
- package/templates/external-system/README.md.hbs +83 -123
- package/.npmrc.token +0 -1
- package/.nyc_output/55e9d034-ddab-4579-a706-e02a91d75c91.json +0 -1
- package/.nyc_output/processinfo/55e9d034-ddab-4579-a706-e02a91d75c91.json +0 -1
- package/.nyc_output/processinfo/index.json +0 -1
- package/lib/api/service-users.api.js +0 -150
- package/lib/api/types/service-users.types.js +0 -65
- package/lib/cli/setup-service-user.js +0 -187
- package/lib/commands/service-user.js +0 -429
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mutagen sync for `aifabrix run --reload` when Docker runs on another host.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview ensureReloadSync extracted from run.js (size limits)
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 2.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const chalk = require('chalk');
|
|
12
|
+
const { formatProgress } = require('../utils/cli-test-layout-chalk');
|
|
13
|
+
const config = require('../core/config');
|
|
14
|
+
const logger = require('../utils/logger');
|
|
15
|
+
const mutagen = require('../utils/mutagen');
|
|
16
|
+
const pathsUtil = require('../utils/paths');
|
|
17
|
+
const {
|
|
18
|
+
isReloadBindMountOnEngineHost,
|
|
19
|
+
isLocalhostSyncSshHost
|
|
20
|
+
} = require('../utils/docker-reload-mount');
|
|
21
|
+
const { sectionTitle, headerKeyValue, metadata } = require('../utils/cli-test-layout-chalk');
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @typedef {Object} ReloadSyncSummaryBind
|
|
25
|
+
* @property {'bind-mount'} transport
|
|
26
|
+
* @property {string} hostPath - Host directory bind-mounted to /app in the container
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @typedef {Object} ReloadSyncSummaryMutagen
|
|
31
|
+
* @property {'mutagen'} transport
|
|
32
|
+
* @property {string} remotePath - Path on sync host used for Docker -v
|
|
33
|
+
* @property {string} sessionName - Mutagen session name
|
|
34
|
+
* @property {string} localPath - Local folder synced (same as build context)
|
|
35
|
+
* @property {string} syncSshHost - sync-ssh-host from config
|
|
36
|
+
* @property {string} sshUrl - Mutagen endpoint (user@host:path)
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @typedef {ReloadSyncSummaryBind|ReloadSyncSummaryMutagen} ReloadSyncSummary
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Install Mutagen if needed, create sync session, return summary for compose and UX.
|
|
45
|
+
* @param {string} appName
|
|
46
|
+
* @param {string} developerId
|
|
47
|
+
* @param {boolean} debug
|
|
48
|
+
* @param {string} codePath
|
|
49
|
+
* @param {string} [remoteSyncPath]
|
|
50
|
+
* @param {string} syncSshHost
|
|
51
|
+
* @returns {Promise<ReloadSyncSummaryMutagen>}
|
|
52
|
+
*/
|
|
53
|
+
async function startMutagenReloadSync(
|
|
54
|
+
appName,
|
|
55
|
+
developerId,
|
|
56
|
+
debug,
|
|
57
|
+
codePath,
|
|
58
|
+
remoteSyncPath,
|
|
59
|
+
syncSshHost
|
|
60
|
+
) {
|
|
61
|
+
const [userMutagenFolder, syncSshUser] = await Promise.all([
|
|
62
|
+
config.getUserMutagenFolder(),
|
|
63
|
+
config.getSyncSshUser()
|
|
64
|
+
]);
|
|
65
|
+
if (!userMutagenFolder || !syncSshUser || !syncSshHost) {
|
|
66
|
+
throw new Error(
|
|
67
|
+
'run --reload requires remote server sync settings. Run "aifabrix dev init" or set user-mutagen-folder, sync-ssh-user, sync-ssh-host in config.'
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
const mutagenPath = await mutagen.ensureMutagenPath(logger.log);
|
|
71
|
+
const remotePath = mutagen.getRemotePath(userMutagenFolder, appName, remoteSyncPath);
|
|
72
|
+
const sshUrl = mutagen.getSyncSshUrl(syncSshUser, syncSshHost, remotePath);
|
|
73
|
+
const sessionName = mutagen.getSessionName(developerId, appName);
|
|
74
|
+
const localPath = (codePath && typeof codePath === 'string') ? codePath : pathsUtil.getBuilderPath(appName);
|
|
75
|
+
if (debug) logger.log(chalk.gray(`[DEBUG] Mutagen sync: ${sessionName} ${localPath} <-> ${sshUrl}`));
|
|
76
|
+
logger.log(formatProgress('Reload: ensuring Mutagen sync (remote Docker engine)…'));
|
|
77
|
+
await mutagen.ensureSyncSession(mutagenPath, sessionName, localPath, sshUrl);
|
|
78
|
+
return {
|
|
79
|
+
transport: 'mutagen',
|
|
80
|
+
remotePath,
|
|
81
|
+
sessionName,
|
|
82
|
+
localPath,
|
|
83
|
+
syncSshHost,
|
|
84
|
+
sshUrl
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* When run --reload in dev with remote: ensure Mutagen sync session; return summary for mounts and CLI copy.
|
|
90
|
+
* Uses codePath (resolved build.context) as Mutagen local path so one config field drives both local and remote.
|
|
91
|
+
* Skips Mutagen when docker-endpoint targets this host (bind mount) or sync-ssh-host is localhost.
|
|
92
|
+
*
|
|
93
|
+
* @param {string} appName - Application name
|
|
94
|
+
* @param {string} developerId - Developer ID
|
|
95
|
+
* @param {boolean} debug - Debug flag
|
|
96
|
+
* @param {string} codePath - Resolved build.context (absolute path to app code)
|
|
97
|
+
* @param {string} [remoteSyncPath] - Optional relative path under user-mutagen-folder (from build.remoteSyncPath); when unset, defaults to dev/<appKey>
|
|
98
|
+
* @returns {Promise<ReloadSyncSummary>}
|
|
99
|
+
* @throws {Error} If --reload but remote not configured, or Mutagen install fails
|
|
100
|
+
*/
|
|
101
|
+
async function ensureReloadSync(appName, developerId, debug, codePath, remoteSyncPath) {
|
|
102
|
+
const endpoint = await config.getDockerEndpoint();
|
|
103
|
+
if (isReloadBindMountOnEngineHost(endpoint)) {
|
|
104
|
+
if (debug) {
|
|
105
|
+
logger.log(
|
|
106
|
+
chalk.gray('[DEBUG] Docker engine shares this host filesystem; skipping Mutagen for --reload')
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
return { transport: 'bind-mount', hostPath: codePath };
|
|
110
|
+
}
|
|
111
|
+
const syncSshHost = await config.getSyncSshHost();
|
|
112
|
+
if (isLocalhostSyncSshHost(syncSshHost || '')) {
|
|
113
|
+
if (debug) {
|
|
114
|
+
logger.log(chalk.gray('[DEBUG] sync-ssh-host is localhost; skipping Mutagen, using local path'));
|
|
115
|
+
}
|
|
116
|
+
return { transport: 'bind-mount', hostPath: codePath };
|
|
117
|
+
}
|
|
118
|
+
return startMutagenReloadSync(appName, developerId, debug, codePath, remoteSyncPath, syncSshHost);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Log how --reload is wired (bind vs Mutagen) after compose/env prep, before container start.
|
|
123
|
+
* @param {boolean} reload
|
|
124
|
+
* @param {ReloadSyncSummary|undefined} summary
|
|
125
|
+
*/
|
|
126
|
+
function logReloadDevSummary(reload, summary) {
|
|
127
|
+
if (!reload || !summary) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
logger.log('');
|
|
131
|
+
logger.log(sectionTitle('Reload (dev)'));
|
|
132
|
+
if (summary.transport === 'bind-mount') {
|
|
133
|
+
logger.log(headerKeyValue('Transport:', 'Direct bind mount on the Docker host (no Mutagen).'));
|
|
134
|
+
logger.log(headerKeyValue('Host path → container:', `${summary.hostPath} → /app`));
|
|
135
|
+
logger.log(metadata('Edits under the host path are visible inside the container immediately.'));
|
|
136
|
+
logger.log('');
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
logger.log(headerKeyValue('Transport:', 'Mutagen two-way sync (Docker engine on another host).'));
|
|
140
|
+
logger.log(headerKeyValue('Session:', summary.sessionName));
|
|
141
|
+
logger.log(headerKeyValue('Sync host:', summary.syncSshHost));
|
|
142
|
+
logger.log(headerKeyValue('Local folder:', summary.localPath));
|
|
143
|
+
logger.log(headerKeyValue('Remote mount (-v):', summary.remotePath));
|
|
144
|
+
logger.log(metadata(`Mutagen endpoint: ${summary.sshUrl}`));
|
|
145
|
+
logger.log('');
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
module.exports = { ensureReloadSync, logReloadDevSummary };
|
|
@@ -6,7 +6,10 @@
|
|
|
6
6
|
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
|
+
const config = require('../core/config');
|
|
9
10
|
const { resolveDockerImageRef } = require('../utils/resolve-docker-image-ref');
|
|
11
|
+
const { checkImageExists } = require('../utils/app-run-containers');
|
|
12
|
+
const { buildDevImageRepositoryPath } = require('../utils/image-name');
|
|
10
13
|
|
|
11
14
|
/**
|
|
12
15
|
* @param {string} appName
|
|
@@ -18,4 +21,51 @@ function resolveRunImage(appName, appConfig, runOptions) {
|
|
|
18
21
|
return resolveDockerImageRef(appName, appConfig, runOptions);
|
|
19
22
|
}
|
|
20
23
|
|
|
21
|
-
|
|
24
|
+
/**
|
|
25
|
+
* Resolves which local image to run: developer-scoped ref first when present, else manifest base.
|
|
26
|
+
* With {@link runOptions.base} true, uses manifest base only (no dev-first probe).
|
|
27
|
+
*
|
|
28
|
+
* @async
|
|
29
|
+
* @param {string} appName
|
|
30
|
+
* @param {Object} appConfig
|
|
31
|
+
* @param {Object} [runOptions]
|
|
32
|
+
* @param {string} [runOptions.image] - Full override (skips fallback logic)
|
|
33
|
+
* @param {boolean} [runOptions.base] - When true, manifest base ref only
|
|
34
|
+
* @returns {Promise<{ imageName: string, imageTag: string }>}
|
|
35
|
+
*/
|
|
36
|
+
async function resolveRunImageWithLocalFallback(appName, appConfig, runOptions = {}) {
|
|
37
|
+
const opts = runOptions || {};
|
|
38
|
+
if (opts.image) {
|
|
39
|
+
return resolveDockerImageRef(appName, appConfig, opts);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const baseRef = resolveDockerImageRef(appName, appConfig, opts);
|
|
43
|
+
|
|
44
|
+
if (opts.base === true) {
|
|
45
|
+
return baseRef;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const developerId = await config.getDeveloperId();
|
|
49
|
+
const idNum = typeof developerId === 'string' ? parseInt(developerId, 10) : developerId;
|
|
50
|
+
if (!Number.isFinite(idNum) || idNum === 0) {
|
|
51
|
+
return baseRef;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const tag = baseRef.imageTag;
|
|
55
|
+
const devRepo = buildDevImageRepositoryPath(baseRef.imageName, developerId);
|
|
56
|
+
const devExists = await checkImageExists(devRepo, tag, false);
|
|
57
|
+
if (devExists) {
|
|
58
|
+
return { imageName: devRepo, imageTag: tag };
|
|
59
|
+
}
|
|
60
|
+
const baseExists = await checkImageExists(baseRef.imageName, tag, false);
|
|
61
|
+
if (baseExists) {
|
|
62
|
+
return baseRef;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
throw new Error(
|
|
66
|
+
`Docker image not found (tried ${devRepo}:${tag} then ${baseRef.imageName}:${tag})\n` +
|
|
67
|
+
`Run 'aifabrix build ${appName}' or pull the manifest image, or use --base after pulling the base image.`
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
module.exports = { resolveRunImage, resolveRunImageWithLocalFallback };
|
package/lib/app/run.js
CHANGED
|
@@ -10,16 +10,25 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
const chalk = require('chalk');
|
|
13
|
+
const {
|
|
14
|
+
formatWarningLine,
|
|
15
|
+
sectionTitle,
|
|
16
|
+
headerKeyValue,
|
|
17
|
+
metadata,
|
|
18
|
+
formatNextActions
|
|
19
|
+
} = require('../utils/cli-test-layout-chalk');
|
|
13
20
|
const config = require('../core/config');
|
|
14
21
|
const logger = require('../utils/logger');
|
|
15
22
|
const pathsUtil = require('../utils/paths');
|
|
16
23
|
const { checkPortAvailable, waitForHealthCheck } = require('../utils/health-check');
|
|
17
24
|
const composeGenerator = require('../utils/compose-generator');
|
|
18
25
|
const containerHelpers = require('../utils/app-run-containers');
|
|
19
|
-
const mutagen = require('../utils/mutagen');
|
|
20
26
|
// Helper functions extracted to reduce file size and complexity
|
|
21
27
|
const helpers = require('./run-helpers');
|
|
28
|
+
const { ensureReloadSync, logReloadDevSummary } = require('./run-reload-sync');
|
|
29
|
+
const { logRestartDevMountSummary } = require('./restart-display');
|
|
22
30
|
const { execWithDockerEnv } = require('../utils/docker-exec');
|
|
31
|
+
const { isRunCliNoProxy } = require('../utils/run-cli-flags');
|
|
23
32
|
|
|
24
33
|
/**
|
|
25
34
|
* True if host is localhost or 127.0.0.1 (case-insensitive).
|
|
@@ -60,7 +69,7 @@ function isLocalhostEndpoint(urlOrEndpoint) {
|
|
|
60
69
|
* @async
|
|
61
70
|
* @param {string} appName - Application name
|
|
62
71
|
* @param {boolean} _debug - Debug flag (unused)
|
|
63
|
-
* @returns {Promise<boolean>} True if should continue, false if external
|
|
72
|
+
* @returns {Promise<boolean>} True if run should continue, false if app is integration-scoped or external (not a runnable container app)
|
|
64
73
|
* @throws {Error} If app name is invalid
|
|
65
74
|
*/
|
|
66
75
|
async function validateAppForRun(appName, _debug) {
|
|
@@ -73,8 +82,23 @@ async function validateAppForRun(appName, _debug) {
|
|
|
73
82
|
try {
|
|
74
83
|
const { isExternal, baseDir } = await detectAppType(appName);
|
|
75
84
|
if (baseDir !== 'builder' || isExternal) {
|
|
76
|
-
logger.log(
|
|
77
|
-
logger.log(
|
|
85
|
+
logger.log('');
|
|
86
|
+
logger.log(sectionTitle('Run'));
|
|
87
|
+
logger.log(headerKeyValue('Application:', appName));
|
|
88
|
+
logger.log(
|
|
89
|
+
formatWarningLine('External integrations are not started as local Docker containers.')
|
|
90
|
+
);
|
|
91
|
+
logger.log(
|
|
92
|
+
metadata(
|
|
93
|
+
'Publish config to the dataplane (upload) or through the controller (deploy), then use the integration APIs from your environment.'
|
|
94
|
+
)
|
|
95
|
+
);
|
|
96
|
+
logger.log(
|
|
97
|
+
formatNextActions([
|
|
98
|
+
`aifabrix upload ${appName}`,
|
|
99
|
+
`aifabrix deploy ${appName}`
|
|
100
|
+
])
|
|
101
|
+
);
|
|
78
102
|
return false;
|
|
79
103
|
}
|
|
80
104
|
} catch (error) {
|
|
@@ -114,7 +138,7 @@ async function checkAndStopContainer(appName, appConfig, options, debug) {
|
|
|
114
138
|
}
|
|
115
139
|
|
|
116
140
|
const containerName = containerHelpers.getContainerName(appName, developerId, scopeOpts);
|
|
117
|
-
logger.log(
|
|
141
|
+
logger.log(formatWarningLine(`Container ${containerName} is already running`));
|
|
118
142
|
await helpers.stopAndRemoveContainer(appName, developerId, debug, scopeOpts);
|
|
119
143
|
}
|
|
120
144
|
|
|
@@ -149,48 +173,6 @@ async function calculateHostPort(appConfig, options, debug) {
|
|
|
149
173
|
return hostPort;
|
|
150
174
|
}
|
|
151
175
|
|
|
152
|
-
/**
|
|
153
|
-
* When run --reload in dev with remote: ensure Mutagen sync session; return remote path for compose mount.
|
|
154
|
-
* Uses codePath (resolved build.context) as Mutagen local path so one config field drives both local and remote.
|
|
155
|
-
* When Docker endpoint, remote-server, or sync-ssh-host is localhost/127.0.0.1, returns null (no sync; use local path).
|
|
156
|
-
*
|
|
157
|
-
* @param {string} appName - Application name
|
|
158
|
-
* @param {string} developerId - Developer ID
|
|
159
|
-
* @param {boolean} debug - Debug flag
|
|
160
|
-
* @param {string} codePath - Resolved build.context (absolute path to app code)
|
|
161
|
-
* @param {string} [remoteSyncPath] - Optional relative path under user-mutagen-folder (from build.remoteSyncPath); when unset, defaults to dev/<appKey>
|
|
162
|
-
* @returns {Promise<string|null>} Remote path for -v mount or null if not remote/reload or already on server (localhost)
|
|
163
|
-
* @throws {Error} If --reload but remote not configured, or Mutagen install fails
|
|
164
|
-
*/
|
|
165
|
-
async function ensureReloadSync(appName, developerId, debug, codePath, remoteSyncPath) {
|
|
166
|
-
const endpoint = await config.getDockerEndpoint();
|
|
167
|
-
const serverUrl = await config.getRemoteServer();
|
|
168
|
-
if (!endpoint && !serverUrl) return null;
|
|
169
|
-
const syncSshHost = await config.getSyncSshHost();
|
|
170
|
-
if (isLocalhostEndpoint(endpoint) || isLocalhostEndpoint(serverUrl) || isLocalhostHost(syncSshHost || '')) {
|
|
171
|
-
if (debug) logger.log(chalk.gray('[DEBUG] Docker/remote/sync host is localhost; skipping Mutagen, using local path'));
|
|
172
|
-
return null;
|
|
173
|
-
}
|
|
174
|
-
const [userMutagenFolder, syncSshUser] = await Promise.all([
|
|
175
|
-
config.getUserMutagenFolder(),
|
|
176
|
-
config.getSyncSshUser()
|
|
177
|
-
]);
|
|
178
|
-
if (!userMutagenFolder || !syncSshUser || !syncSshHost) {
|
|
179
|
-
throw new Error(
|
|
180
|
-
'run --reload requires remote server sync settings. Run "aifabrix dev init" or set user-mutagen-folder, sync-ssh-user, sync-ssh-host in config.'
|
|
181
|
-
);
|
|
182
|
-
}
|
|
183
|
-
const mutagenPath = await mutagen.ensureMutagenPath(logger.log);
|
|
184
|
-
const remotePath = mutagen.getRemotePath(userMutagenFolder, appName, remoteSyncPath);
|
|
185
|
-
const sshUrl = mutagen.getSyncSshUrl(syncSshUser, syncSshHost, remotePath);
|
|
186
|
-
const sessionName = mutagen.getSessionName(developerId, appName);
|
|
187
|
-
const localPath = (codePath && typeof codePath === 'string') ? codePath : pathsUtil.getBuilderPath(appName);
|
|
188
|
-
if (debug) logger.log(chalk.gray(`[DEBUG] Mutagen sync: ${sessionName} ${localPath} <-> ${sshUrl}`));
|
|
189
|
-
logger.log(chalk.blue('Ensuring Mutagen sync session...'));
|
|
190
|
-
await mutagen.ensureSyncSession(mutagenPath, sessionName, localPath, sshUrl);
|
|
191
|
-
return remotePath;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
176
|
/**
|
|
195
177
|
* Load and configure application
|
|
196
178
|
* @async
|
|
@@ -238,12 +220,21 @@ async function startAppContainer(appName, tempComposePath, hostPort, appConfig,
|
|
|
238
220
|
devMountPath,
|
|
239
221
|
misoEnvironment
|
|
240
222
|
});
|
|
241
|
-
await helpers.displayRunStatus(
|
|
223
|
+
await helpers.displayRunStatus(
|
|
224
|
+
appName,
|
|
225
|
+
hostPort,
|
|
226
|
+
appConfig,
|
|
227
|
+
opts.runScopeOpts || null,
|
|
228
|
+
runOptions || {}
|
|
229
|
+
);
|
|
242
230
|
} catch (error) {
|
|
243
|
-
logger.log(
|
|
244
|
-
logger.log(
|
|
231
|
+
logger.log('');
|
|
232
|
+
logger.log(formatWarningLine(`Compose file preserved at ${tempComposePath}`));
|
|
233
|
+
logger.log(metadata(' Review the compose file, fix the issue, then run again.'));
|
|
245
234
|
if (runEnvPath || runEnvAdminPath) {
|
|
246
|
-
logger.log(
|
|
235
|
+
logger.log(
|
|
236
|
+
metadata(' Run .env file(s) contain secrets and were not deleted; remove manually if needed.')
|
|
237
|
+
);
|
|
247
238
|
}
|
|
248
239
|
if (debug) {
|
|
249
240
|
logger.log(chalk.gray(`[DEBUG] Error during container start: ${error.message}`));
|
|
@@ -271,30 +262,46 @@ async function resolveRunOptions(appName, appConfig, options, envKey, debug, eff
|
|
|
271
262
|
const codePath = pathsUtil.resolveBuildContext(builderPath, appConfig.build?.context || '.');
|
|
272
263
|
if (options.reload && envKey === 'dev') {
|
|
273
264
|
const remoteSyncPath = appConfig.build?.remoteSyncPath;
|
|
274
|
-
const
|
|
275
|
-
runOptions.
|
|
265
|
+
const reloadSummary = await ensureReloadSync(appName, appConfig.developerId, debug, codePath, remoteSyncPath);
|
|
266
|
+
runOptions.reloadSyncSummary = reloadSummary;
|
|
267
|
+
runOptions.devMountPath =
|
|
268
|
+
reloadSummary.transport === 'mutagen' ? reloadSummary.remotePath : codePath;
|
|
276
269
|
}
|
|
277
270
|
return runOptions;
|
|
278
271
|
}
|
|
279
272
|
|
|
280
273
|
/**
|
|
281
|
-
*
|
|
282
|
-
* @param {
|
|
283
|
-
* @param {Object}
|
|
284
|
-
* @param {boolean} debug - Debug flag
|
|
285
|
-
* @returns {Promise<{ appConfig: Object, tempComposePath: string, hostPort: number }|null>} Prepared run context or null if should not continue
|
|
274
|
+
* When Traefik is enabled in user config and this run should use proxy hints (`runOptions.noProxy` is false), enable Traefik/DNS URL hints.
|
|
275
|
+
* @param {Object} runOptions
|
|
276
|
+
* @param {Object} userCfg
|
|
286
277
|
*/
|
|
287
|
-
|
|
288
|
-
|
|
278
|
+
function applyTraefikFlagToRunOptions(runOptions, userCfg) {
|
|
279
|
+
if (userCfg && userCfg.traefik === true && !runOptions.noProxy) {
|
|
280
|
+
runOptions.traefikEnabled = true;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* @param {string} envKey
|
|
286
|
+
* @throws {Error} If env is not dev, tst, or pro
|
|
287
|
+
*/
|
|
288
|
+
function assertValidRunEnvKey(envKey) {
|
|
289
289
|
if (envKey !== 'dev' && envKey !== 'tst' && envKey !== 'pro') {
|
|
290
290
|
throw new Error('--env must be dev, tst, or pro');
|
|
291
291
|
}
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Image resolution, prereqs, port, compose env — after app config and user config are loaded.
|
|
296
|
+
* @param {string} appName
|
|
297
|
+
* @param {Object} appConfig
|
|
298
|
+
* @param {Object} options - Original run options
|
|
299
|
+
* @param {string} envKey
|
|
300
|
+
* @param {Object} userCfg - getConfig() result
|
|
301
|
+
* @param {boolean} debug
|
|
302
|
+
* @returns {Promise<Object>} Prepared run context (same shape as prepareAppRun return)
|
|
303
|
+
*/
|
|
304
|
+
async function computeRunPreparationCore(appName, appConfig, options, envKey, userCfg, debug) {
|
|
298
305
|
const { computeEffectiveEnvironmentScopedResources } = require('../utils/environment-scoped-resources');
|
|
299
306
|
const effectiveEnvironmentScopedResources = computeEffectiveEnvironmentScopedResources(
|
|
300
307
|
Boolean(userCfg.useEnvironmentScopedResources),
|
|
@@ -304,17 +311,24 @@ async function prepareAppRun(appName, options, debug) {
|
|
|
304
311
|
const runScopeOpts = effectiveEnvironmentScopedResources
|
|
305
312
|
? { effectiveEnvironmentScopedResources: true, env: envKey }
|
|
306
313
|
: null;
|
|
307
|
-
|
|
308
|
-
await
|
|
309
|
-
const
|
|
314
|
+
const { resolveRunImageWithLocalFallback } = require('./run-resolve-image');
|
|
315
|
+
const resolvedRef = await resolveRunImageWithLocalFallback(appName, appConfig, options);
|
|
316
|
+
const effectiveRunOptions = {
|
|
317
|
+
...options,
|
|
318
|
+
image: `${resolvedRef.imageName}:${resolvedRef.imageTag}`
|
|
319
|
+
};
|
|
320
|
+
await helpers.checkPrerequisites(appName, appConfig, debug, effectiveRunOptions.skipInfraCheck === true, effectiveRunOptions);
|
|
321
|
+
await checkAndStopContainer(appName, appConfig, effectiveRunOptions, debug);
|
|
322
|
+
const hostPort = await calculateHostPort(appConfig, effectiveRunOptions, debug);
|
|
310
323
|
const runOptions = await resolveRunOptions(
|
|
311
324
|
appName,
|
|
312
325
|
appConfig,
|
|
313
|
-
|
|
326
|
+
effectiveRunOptions,
|
|
314
327
|
envKey,
|
|
315
328
|
debug,
|
|
316
329
|
effectiveEnvironmentScopedResources
|
|
317
330
|
);
|
|
331
|
+
applyTraefikFlagToRunOptions(runOptions, userCfg);
|
|
318
332
|
const { composePath: tempComposePath, runEnvPath, runEnvAdminPath } = await helpers.prepareEnvironment(appName, appConfig, runOptions);
|
|
319
333
|
const result = {
|
|
320
334
|
appConfig,
|
|
@@ -329,6 +343,59 @@ async function prepareAppRun(appName, options, debug) {
|
|
|
329
343
|
return result;
|
|
330
344
|
}
|
|
331
345
|
|
|
346
|
+
/**
|
|
347
|
+
* Gray **Manifest:** line before container start (skipped when orchestration already emitted).
|
|
348
|
+
* @param {string} appName
|
|
349
|
+
* @param {Object} options
|
|
350
|
+
* @returns {void}
|
|
351
|
+
*/
|
|
352
|
+
function emitRunManifestMetadataIfRequested(appName, options) {
|
|
353
|
+
if (options.skipManifestMetadataLine === true) return;
|
|
354
|
+
const { emitManifestMetadataLineIfTTY } = require('../utils/manifest-source-emit');
|
|
355
|
+
emitManifestMetadataLineIfTTY(logger, {
|
|
356
|
+
appKey: appName,
|
|
357
|
+
appPath: pathsUtil.getBuilderPath(appName),
|
|
358
|
+
envOnly: false,
|
|
359
|
+
json: false
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Prepare run: validate app, load config, check prereqs, stop existing container, resolve port and reload, prepare env.
|
|
365
|
+
* @param {string} appName - Application name
|
|
366
|
+
* @param {Object} options - Run options
|
|
367
|
+
* @param {boolean} [options.skipManifestMetadataLine] - When true, skip gray **Manifest:** line (caller already emitted for platform orchestration)
|
|
368
|
+
* @param {boolean} debug - Debug flag
|
|
369
|
+
* @returns {Promise<{ appConfig: Object, tempComposePath: string, hostPort: number }|null>} Prepared run context or null if should not continue
|
|
370
|
+
*/
|
|
371
|
+
async function prepareAppRun(appName, options, debug) {
|
|
372
|
+
const envKey = (options.env || 'dev').toLowerCase();
|
|
373
|
+
assertValidRunEnvKey(envKey);
|
|
374
|
+
const shouldContinue = await validateAppForRun(appName, debug);
|
|
375
|
+
if (!shouldContinue) {
|
|
376
|
+
return null;
|
|
377
|
+
}
|
|
378
|
+
let userCfg = await config.getConfig();
|
|
379
|
+
const appsDefaults = require('../utils/applications-config-defaults');
|
|
380
|
+
await appsDefaults.persistApplicationRunProxyFlag(appName, !isRunCliNoProxy(options));
|
|
381
|
+
if (envKey === 'dev') {
|
|
382
|
+
await appsDefaults.persistApplicationReloadFlag(appName, options.reload === true);
|
|
383
|
+
}
|
|
384
|
+
userCfg = await config.getConfig();
|
|
385
|
+
const savedProxyHint = appsDefaults.getApplicationsRunProxyHint(userCfg, appName);
|
|
386
|
+
const mergedOpts = {
|
|
387
|
+
...options,
|
|
388
|
+
reload: options.reload === true,
|
|
389
|
+
noProxy: isRunCliNoProxy(options) || !savedProxyHint
|
|
390
|
+
};
|
|
391
|
+
logger.log('');
|
|
392
|
+
logger.log(sectionTitle('Run'));
|
|
393
|
+
logger.log(headerKeyValue('Application:', appName));
|
|
394
|
+
const appConfig = await loadAndConfigureApp(appName, debug);
|
|
395
|
+
emitRunManifestMetadataIfRequested(appName, options);
|
|
396
|
+
return computeRunPreparationCore(appName, appConfig, mergedOpts, envKey, userCfg, debug);
|
|
397
|
+
}
|
|
398
|
+
|
|
332
399
|
/**
|
|
333
400
|
* Runs the application locally using Docker
|
|
334
401
|
* Starts container with proper port mapping and environment
|
|
@@ -339,6 +406,7 @@ async function prepareAppRun(appName, options, debug) {
|
|
|
339
406
|
* @param {Object} options - Run options
|
|
340
407
|
* @param {number} [options.port] - Override local port
|
|
341
408
|
* @param {boolean} [options.debug] - Enable debug output
|
|
409
|
+
* @param {boolean} [options.skipManifestMetadataLine] - When true, skip gray **Manifest:** line in prepare (orchestration already emitted)
|
|
342
410
|
* @returns {Promise<void>} Resolves when app is running
|
|
343
411
|
* @throws {Error} If run fails or app is not built
|
|
344
412
|
*
|
|
@@ -360,10 +428,7 @@ async function runApp(appName, options = {}) {
|
|
|
360
428
|
if (debug) {
|
|
361
429
|
logger.log(chalk.gray(`[DEBUG] Compose file generated: ${prepared.tempComposePath}`));
|
|
362
430
|
}
|
|
363
|
-
|
|
364
|
-
logger.log(chalk.gray('With --reload: workspace mounted from host at /app (container runs as your user for write access).'));
|
|
365
|
-
logger.log(chalk.gray(` Host path: ${prepared.devMountPath}`));
|
|
366
|
-
}
|
|
431
|
+
logReloadDevSummary(Boolean(prepared.mergedRunOptions.reload), prepared.mergedRunOptions.reloadSyncSummary);
|
|
367
432
|
await startAppContainer(appName, prepared.tempComposePath, prepared.hostPort, prepared.appConfig, {
|
|
368
433
|
debug,
|
|
369
434
|
runEnvPath: prepared.runEnvPath,
|
|
@@ -397,10 +462,18 @@ async function restartApp(appName) {
|
|
|
397
462
|
if (!appName || typeof appName !== 'string') {
|
|
398
463
|
throw new Error('Application name is required and must be a string');
|
|
399
464
|
}
|
|
465
|
+
const { emitManifestMetadataLineIfTTY } = require('../utils/manifest-source-emit');
|
|
466
|
+
emitManifestMetadataLineIfTTY(logger, {
|
|
467
|
+
appKey: appName,
|
|
468
|
+
appPath: pathsUtil.getBuilderPath(appName),
|
|
469
|
+
envOnly: false,
|
|
470
|
+
json: false
|
|
471
|
+
});
|
|
400
472
|
const developerId = await config.getDeveloperId();
|
|
401
473
|
const containerName = containerHelpers.getContainerName(appName, developerId);
|
|
402
474
|
try {
|
|
403
475
|
await execWithDockerEnv(`docker restart ${containerName}`);
|
|
476
|
+
await logRestartDevMountSummary(containerName, appName);
|
|
404
477
|
} catch (error) {
|
|
405
478
|
const msg = (error.stderr || error.stdout || error.message || '').toLowerCase();
|
|
406
479
|
if (msg.includes('no such container') || msg.includes('is not running')) {
|
|
@@ -413,6 +486,7 @@ async function restartApp(appName) {
|
|
|
413
486
|
module.exports = {
|
|
414
487
|
runApp,
|
|
415
488
|
restartApp,
|
|
489
|
+
validateAppForRun,
|
|
416
490
|
ensureReloadSync,
|
|
417
491
|
isLocalhostHost,
|
|
418
492
|
isLocalhostEndpoint,
|
package/lib/app/show-display.js
CHANGED
|
@@ -96,6 +96,13 @@ function logApplicationSection(a, summary) {
|
|
|
96
96
|
} else {
|
|
97
97
|
logApplicationFields(a);
|
|
98
98
|
}
|
|
99
|
+
if (summary.runReloadDefault && !summary.isExternal) {
|
|
100
|
+
logger.log(` ${'Run default:'.padEnd(16)} reload on (config)`);
|
|
101
|
+
}
|
|
102
|
+
if (!summary.isExternal) {
|
|
103
|
+
const proxyOn = summary.runProxyDefault === true;
|
|
104
|
+
logger.log(` ${'Run default:'.padEnd(16)} proxy ${proxyOn ? 'on' : 'off'} (config)`);
|
|
105
|
+
}
|
|
99
106
|
/* External integration is logged after Dataplane block in display() when external */
|
|
100
107
|
}
|
|
101
108
|
|