@nocobase/app-installer 0.0.0-stage → 0.1.0-beta.3
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/README.md +217 -2
- package/bin/run.js +43 -0
- package/dist/cli.js +171 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/install.js +383 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/commands/rollback.js +287 -0
- package/dist/commands/rollback.js.map +1 -0
- package/dist/commands/status.js +155 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/upgrade.js +709 -0
- package/dist/commands/upgrade.js.map +1 -0
- package/dist/lib/app-cli.js +89 -0
- package/dist/lib/app-cli.js.map +1 -0
- package/dist/lib/backup.js +167 -0
- package/dist/lib/backup.js.map +1 -0
- package/dist/lib/confirm.js +36 -0
- package/dist/lib/confirm.js.map +1 -0
- package/dist/lib/current-link.js +22 -0
- package/dist/lib/current-link.js.map +1 -0
- package/dist/lib/ecosystem.js +86 -0
- package/dist/lib/ecosystem.js.map +1 -0
- package/dist/lib/env-file.js +87 -0
- package/dist/lib/env-file.js.map +1 -0
- package/dist/lib/errors.js +32 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/health.js +55 -0
- package/dist/lib/health.js.map +1 -0
- package/dist/lib/initial-admin.js +39 -0
- package/dist/lib/initial-admin.js.map +1 -0
- package/dist/lib/interrupt.js +50 -0
- package/dist/lib/interrupt.js.map +1 -0
- package/dist/lib/invocation.js +33 -0
- package/dist/lib/invocation.js.map +1 -0
- package/dist/lib/layout.js +61 -0
- package/dist/lib/layout.js.map +1 -0
- package/dist/lib/lock.js +59 -0
- package/dist/lib/lock.js.map +1 -0
- package/dist/lib/mount-path.js +34 -0
- package/dist/lib/mount-path.js.map +1 -0
- package/dist/lib/output.js +61 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/lib/pm2.js +92 -0
- package/dist/lib/pm2.js.map +1 -0
- package/dist/lib/prechecks.js +236 -0
- package/dist/lib/prechecks.js.map +1 -0
- package/dist/lib/registry.js +59 -0
- package/dist/lib/registry.js.map +1 -0
- package/dist/lib/release.js +328 -0
- package/dist/lib/release.js.map +1 -0
- package/dist/lib/run-command.js +108 -0
- package/dist/lib/run-command.js.map +1 -0
- package/dist/lib/service.js +100 -0
- package/dist/lib/service.js.map +1 -0
- package/dist/lib/source.js +100 -0
- package/dist/lib/source.js.map +1 -0
- package/dist/lib/state.js +73 -0
- package/dist/lib/state.js.map +1 -0
- package/dist/lib/version.js +51 -0
- package/dist/lib/version.js.map +1 -0
- package/package.json +51 -3
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
import { mkdir, readdir, rm, writeFile } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { Args, Flags } from '@oclif/core';
|
|
4
|
+
import { runAppCli } from "../lib/app-cli.js";
|
|
5
|
+
import { switchCurrent } from "../lib/current-link.js";
|
|
6
|
+
import { buildEcosystemConfig, buildLauncher } from "../lib/ecosystem.js";
|
|
7
|
+
import { quoteForShell } from '@nocobase/cli-envelope';
|
|
8
|
+
import { buildAppEnv, endpointsOf, healthUrl, mountPathOf, readAppEnv, } from "../lib/env-file.js";
|
|
9
|
+
import { EXIT_INVALID, InstallerError } from "../lib/errors.js";
|
|
10
|
+
import { pm2StartFailed, waitForHealthy } from "../lib/health.js";
|
|
11
|
+
import { readInitialAdmin } from "../lib/initial-admin.js";
|
|
12
|
+
import { HUB_TEMPLATE, layoutOf, releaseLinkTarget } from "../lib/layout.js";
|
|
13
|
+
import { acquireLock } from "../lib/lock.js";
|
|
14
|
+
import { assertFixedMountPath, parseBasePathFlag } from "../lib/mount-path.js";
|
|
15
|
+
import { checkEnvVariables, checkPlatform, checkPm2, checkPm2NameFree, checkPnpm, checkPortFree, checkTargetEmpty, } from "../lib/prechecks.js";
|
|
16
|
+
import { defaultRegistry, normalizeRegistry, resolveTemplateVersion, } from "../lib/registry.js";
|
|
17
|
+
import { DIALECTS, assertStorageOutsideRelease, buildFromTemplate, checkArchiveDriver, driversFor, unpackRelease, } from "../lib/release.js";
|
|
18
|
+
import { runCommand } from "../lib/run-command.js";
|
|
19
|
+
import { errorLogCommandLine, errorLogTail, startAdvice, } from "../lib/service.js";
|
|
20
|
+
import { parseTemplateSpec, resolveArchivePath } from "../lib/source.js";
|
|
21
|
+
import { writeState } from "../lib/state.js";
|
|
22
|
+
export const INSTALL_ARGS = {
|
|
23
|
+
directory: Args.string({
|
|
24
|
+
description: 'Directory to install into. Must be new or empty. --dir names it too.',
|
|
25
|
+
}),
|
|
26
|
+
};
|
|
27
|
+
export const INSTALL_FLAGS = {
|
|
28
|
+
dir: Flags.string({
|
|
29
|
+
description: 'Directory to install into, as the other commands name it; the same as the DIRECTORY argument.',
|
|
30
|
+
}),
|
|
31
|
+
archive: Flags.string({
|
|
32
|
+
description: 'Deployment archive to install, as `pnpm build --tar` writes it to storage/exports/dist.tar.gz. Build it for this machine with --target and --node-version.',
|
|
33
|
+
}),
|
|
34
|
+
template: Flags.string({
|
|
35
|
+
description: 'Published template to build on this machine instead: hub, or hub@<version or dist-tag> (latest by default).',
|
|
36
|
+
}),
|
|
37
|
+
origin: Flags.string({
|
|
38
|
+
description: 'Public origin the application is reached at, without its base path, e.g. https://apps.example.com. Defaults to http://HOST:PORT.',
|
|
39
|
+
}),
|
|
40
|
+
'base-path': Flags.string({
|
|
41
|
+
description: "Path the application is mounted at, e.g. /crm, or / for the origin root. Written to app.env as APP_BASE_PATH; without it the server's default applies, /hub for a Hub whether from the template or an archive. An archive from before relocatable builds runs only at the path it was built for.",
|
|
42
|
+
}),
|
|
43
|
+
host: Flags.string({
|
|
44
|
+
default: '127.0.0.1',
|
|
45
|
+
description: 'Address the application listens on. Keep the loopback default behind a reverse proxy.',
|
|
46
|
+
}),
|
|
47
|
+
port: Flags.integer({
|
|
48
|
+
default: 13000,
|
|
49
|
+
min: 1,
|
|
50
|
+
max: 65535,
|
|
51
|
+
description: 'Port the application listens on. It must be free; give each installation on a machine its own.',
|
|
52
|
+
}),
|
|
53
|
+
dialect: Flags.string({
|
|
54
|
+
default: 'sqlite',
|
|
55
|
+
options: [...DIALECTS],
|
|
56
|
+
description: 'Database. Anything but SQLite needs --set for its connection; an archive must carry its driver.',
|
|
57
|
+
}),
|
|
58
|
+
set: Flags.string({
|
|
59
|
+
multiple: true,
|
|
60
|
+
description: 'A config.yml setting as key=value, applied with `nocobase config set`, e.g. database.connections.main.host=db.internal. Values are YAML scalars: quote text that looks like a number or boolean, as in key=\'"0123"\'.',
|
|
61
|
+
}),
|
|
62
|
+
'set-from-env': Flags.string({
|
|
63
|
+
multiple: true,
|
|
64
|
+
description: 'A setting read from an environment variable, as key=VARIABLE, e.g. database.connections.main.password=DB_PASSWORD.',
|
|
65
|
+
}),
|
|
66
|
+
registry: Flags.string({
|
|
67
|
+
description: 'npm registry for the template, NocoBase packages and the installer commands suggested later.',
|
|
68
|
+
}),
|
|
69
|
+
name: Flags.string({
|
|
70
|
+
description: 'pm2 process name. Defaults to nocobase- followed by the directory name, so each installation on a machine has its own.',
|
|
71
|
+
}),
|
|
72
|
+
start: Flags.boolean({
|
|
73
|
+
allowNo: true,
|
|
74
|
+
default: true,
|
|
75
|
+
description: 'Start the application with pm2 once it is installed.',
|
|
76
|
+
}),
|
|
77
|
+
'health-timeout': Flags.integer({
|
|
78
|
+
default: 180,
|
|
79
|
+
min: 1,
|
|
80
|
+
description: 'Seconds to wait for the application to answer its health check.',
|
|
81
|
+
}),
|
|
82
|
+
'keep-source': Flags.boolean({
|
|
83
|
+
default: false,
|
|
84
|
+
description: 'With --template, keep the build directory with the sources and development dependencies, also when the install fails.',
|
|
85
|
+
}),
|
|
86
|
+
json: Flags.boolean({
|
|
87
|
+
default: false,
|
|
88
|
+
description: 'Print one JSON result on stdout; progress stays on stderr.',
|
|
89
|
+
}),
|
|
90
|
+
};
|
|
91
|
+
function parsePairs(values, flag) {
|
|
92
|
+
return (values ?? []).map((value) => {
|
|
93
|
+
const index = value.indexOf('=');
|
|
94
|
+
if (index <= 0 || index === value.length - 1) {
|
|
95
|
+
throw new InstallerError('INVALID_USAGE', `--${flag} expects key=value, got "${value}".`, { exitCode: EXIT_INVALID });
|
|
96
|
+
}
|
|
97
|
+
return [value.slice(0, index), value.slice(index + 1)];
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
/** The sign-in line of the summary: who, and where the password is, never the password itself. */
|
|
101
|
+
function describeInitialAdmin(admin) {
|
|
102
|
+
const who = [admin.username, admin.email && `(${admin.email})`]
|
|
103
|
+
.filter(Boolean)
|
|
104
|
+
.join(' ') || 'the account';
|
|
105
|
+
const password = admin.defaultPassword === true
|
|
106
|
+
? `the template's default password; change it after signing in`
|
|
107
|
+
: 'the password set there';
|
|
108
|
+
return `${who} under ${admin.key} in config.yml, with ${password}`;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Removes what a failed install wrote. The target was new or empty when the install began, so everything in it now
|
|
112
|
+
* came from this run. `created` is the topmost directory the install created, which may be a parent of the root;
|
|
113
|
+
* `keep` names entries to leave, such as the build directory under `--keep-source`.
|
|
114
|
+
*/
|
|
115
|
+
async function cleanUp(root, created, keep) {
|
|
116
|
+
if (created && keep.length === 0) {
|
|
117
|
+
await rm(created, { recursive: true, force: true });
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
for (const entry of await readdir(root).catch(() => [])) {
|
|
121
|
+
if (keep.includes(entry))
|
|
122
|
+
continue;
|
|
123
|
+
await rm(path.join(root, entry), { recursive: true, force: true });
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
export async function install(input, deps) {
|
|
127
|
+
const { flags } = input;
|
|
128
|
+
const { reporter, pm2 } = deps;
|
|
129
|
+
const run = deps.run ?? runCommand;
|
|
130
|
+
const cwd = deps.cwd ?? process.cwd();
|
|
131
|
+
const directory = input.directory ?? flags.dir;
|
|
132
|
+
if (directory === undefined) {
|
|
133
|
+
throw new InstallerError('INVALID_USAGE', 'Name the directory to install into, as an argument or with --dir.', { exitCode: EXIT_INVALID });
|
|
134
|
+
}
|
|
135
|
+
if (input.directory !== undefined &&
|
|
136
|
+
flags.dir !== undefined &&
|
|
137
|
+
path.resolve(cwd, input.directory) !== path.resolve(cwd, flags.dir)) {
|
|
138
|
+
throw new InstallerError('INVALID_USAGE', `The DIRECTORY argument (${input.directory}) and --dir (${flags.dir}) name different directories; give one of them.`, { exitCode: EXIT_INVALID });
|
|
139
|
+
}
|
|
140
|
+
if ((flags.archive === undefined) === (flags.template === undefined)) {
|
|
141
|
+
throw new InstallerError('INVALID_USAGE', flags.archive === undefined
|
|
142
|
+
? 'Name what to install: --archive with a deployment archive built by `pnpm build --tar`, or --template hub to build the published Hub here.'
|
|
143
|
+
: '--archive and --template name two different things to install; give one of them.', { exitCode: EXIT_INVALID });
|
|
144
|
+
}
|
|
145
|
+
const requestedBasePath = parseBasePathFlag(flags['base-path']);
|
|
146
|
+
const root = path.resolve(cwd, directory);
|
|
147
|
+
const layout = layoutOf(root);
|
|
148
|
+
const spec = flags.template === undefined
|
|
149
|
+
? undefined
|
|
150
|
+
: parseTemplateSpec(flags.template);
|
|
151
|
+
const template = spec?.template;
|
|
152
|
+
const archive = flags.archive === undefined
|
|
153
|
+
? undefined
|
|
154
|
+
: resolveArchivePath(cwd, flags.archive);
|
|
155
|
+
const title = template?.title ?? 'application';
|
|
156
|
+
const name = flags.name ?? `nocobase-${path.basename(root)}`;
|
|
157
|
+
const dialect = flags.dialect;
|
|
158
|
+
const registry = normalizeRegistry(flags.registry ?? defaultRegistry());
|
|
159
|
+
const origin = (flags.origin ?? `http://${flags.host}:${flags.port}`).replace(/\/+$/u, '');
|
|
160
|
+
const sets = parsePairs(flags.set, 'set');
|
|
161
|
+
const setsFromEnv = parsePairs(flags['set-from-env'], 'set-from-env');
|
|
162
|
+
if (!/^https?:\/\/[^/]+$/u.test(origin)) {
|
|
163
|
+
throw new InstallerError('INVALID_USAGE', `--origin must be a protocol and host without a path, such as https://apps.example.com; got "${origin}".`, { exitCode: EXIT_INVALID });
|
|
164
|
+
}
|
|
165
|
+
// Everything that can be checked is checked before the first write, so a failed precheck leaves nothing behind.
|
|
166
|
+
checkPlatform();
|
|
167
|
+
await checkTargetEmpty(root);
|
|
168
|
+
checkEnvVariables(setsFromEnv.map(([, variable]) => variable));
|
|
169
|
+
if (template)
|
|
170
|
+
await checkPnpm(run);
|
|
171
|
+
if (flags.start) {
|
|
172
|
+
await checkPm2(pm2);
|
|
173
|
+
await checkPm2NameFree(pm2, name);
|
|
174
|
+
}
|
|
175
|
+
await checkPortFree(flags.host, flags.port, { suggestPort: true });
|
|
176
|
+
const version = spec && template
|
|
177
|
+
? await resolveTemplateVersion(registry, template.package, spec.version, deps.fetchImpl)
|
|
178
|
+
: undefined;
|
|
179
|
+
if (!flags.origin) {
|
|
180
|
+
reporter.warn(`No --origin given; the ${title} will build links for ${origin}. Pass --origin with the public address before exposing it.`);
|
|
181
|
+
}
|
|
182
|
+
// `mkdir` returns the first directory it created, so a failure can remove parents the install made as well.
|
|
183
|
+
const created = await mkdir(root, { recursive: true });
|
|
184
|
+
let releaseLock;
|
|
185
|
+
try {
|
|
186
|
+
releaseLock = await acquireLock(layout.lockFile);
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
if (created)
|
|
190
|
+
await rm(created, { recursive: true, force: true });
|
|
191
|
+
throw error;
|
|
192
|
+
}
|
|
193
|
+
let switched = false;
|
|
194
|
+
try {
|
|
195
|
+
const drivers = template ? driversFor(dialect) : [];
|
|
196
|
+
let prepared;
|
|
197
|
+
if (template && version) {
|
|
198
|
+
reporter.progress(`Installing the ${title} ${version} into ${root}`);
|
|
199
|
+
prepared = await buildFromTemplate({
|
|
200
|
+
layout,
|
|
201
|
+
template,
|
|
202
|
+
version,
|
|
203
|
+
registry,
|
|
204
|
+
drivers,
|
|
205
|
+
keepSource: flags['keep-source'],
|
|
206
|
+
reporter,
|
|
207
|
+
run,
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
reporter.progress(`Unpacking ${archive} into ${root}`);
|
|
212
|
+
prepared = await unpackRelease({ layout, archive: archive });
|
|
213
|
+
checkArchiveDriver(prepared.dir, dialect);
|
|
214
|
+
reporter.progress(`Installing ${prepared.appName} ${prepared.version} (${prepared.id})`);
|
|
215
|
+
}
|
|
216
|
+
// What the application is, by its own manifest: a Hub deployed from an archive is as much a Hub as one built from
|
|
217
|
+
// the template. Builds too old to record it are only ever the Hub template's, which the template names.
|
|
218
|
+
const templateKind = prepared.templateKind ?? (template === HUB_TEMPLATE ? 'hub' : 'app');
|
|
219
|
+
const hub = templateKind === 'hub';
|
|
220
|
+
// A relocatable release is mounted where the installation says. A Hub keeps its own default whether it was built
|
|
221
|
+
// from the template or arrived as an archive: a build records no path and ships no `.env`, so nothing else carries
|
|
222
|
+
// the `/hub` its checkout served at, and the server's `/main` would move it. An earlier release runs only at the
|
|
223
|
+
// path its client was compiled for.
|
|
224
|
+
let mountPath;
|
|
225
|
+
if (prepared.relocatable) {
|
|
226
|
+
mountPath =
|
|
227
|
+
requestedBasePath ?? (hub ? HUB_TEMPLATE.basePath : template?.basePath);
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
mountPath = prepared.basePath;
|
|
231
|
+
if (requestedBasePath !== undefined) {
|
|
232
|
+
assertFixedMountPath(`${prepared.appName} ${prepared.version}`, mountPath, requestedBasePath);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
await writeFile(layout.appEnv, buildAppEnv(layout, {
|
|
236
|
+
origin,
|
|
237
|
+
host: flags.host,
|
|
238
|
+
port: flags.port,
|
|
239
|
+
basePath: mountPath,
|
|
240
|
+
}));
|
|
241
|
+
const env = await readAppEnv(layout);
|
|
242
|
+
const cli = { releaseDir: prepared.dir, cwd: root, env, run };
|
|
243
|
+
reporter.progress('Writing config.yml');
|
|
244
|
+
await runAppCli(['config', 'init', '--config', layout.configFile, '--dialect', dialect], cli);
|
|
245
|
+
if (sets.length > 0) {
|
|
246
|
+
await runAppCli(['config', 'set', ...sets.map(([key, value]) => `${key}=${value}`)], cli);
|
|
247
|
+
}
|
|
248
|
+
for (const [key, variable] of setsFromEnv) {
|
|
249
|
+
await runAppCli(['config', 'set', '--from-env', `${key}=${variable}`], cli);
|
|
250
|
+
}
|
|
251
|
+
await runAppCli(['config', 'check'], cli);
|
|
252
|
+
reporter.progress('Applying database migrations');
|
|
253
|
+
await runAppCli(['db', 'apply'], cli);
|
|
254
|
+
assertStorageOutsideRelease(prepared.dir);
|
|
255
|
+
// Everything else the root needs is written first: the switch is the last write before starting, so a failure
|
|
256
|
+
// anywhere up to it leaves nothing half-installed for status and install to disagree about.
|
|
257
|
+
await mkdir(layout.logsDir, { recursive: true });
|
|
258
|
+
await writeFile(layout.ecosystemFile, buildEcosystemConfig({
|
|
259
|
+
name,
|
|
260
|
+
nodePath: process.execPath,
|
|
261
|
+
keepChildren: hub,
|
|
262
|
+
}));
|
|
263
|
+
await writeFile(layout.launcherFile, buildLauncher());
|
|
264
|
+
const at = new Date().toISOString();
|
|
265
|
+
const state = {
|
|
266
|
+
schemaVersion: 1,
|
|
267
|
+
appName: prepared.appName,
|
|
268
|
+
basePath: mountPathOf(env) || '/',
|
|
269
|
+
templateKind,
|
|
270
|
+
source: template
|
|
271
|
+
? {
|
|
272
|
+
kind: 'template',
|
|
273
|
+
template: template.name,
|
|
274
|
+
package: template.package,
|
|
275
|
+
}
|
|
276
|
+
: { kind: 'archive' },
|
|
277
|
+
name,
|
|
278
|
+
registry,
|
|
279
|
+
dialect,
|
|
280
|
+
drivers,
|
|
281
|
+
current: prepared.id,
|
|
282
|
+
releases: [
|
|
283
|
+
{
|
|
284
|
+
id: prepared.id,
|
|
285
|
+
version: prepared.version,
|
|
286
|
+
builtAt: prepared.builtAt,
|
|
287
|
+
installedAt: at,
|
|
288
|
+
buildTarget: prepared.buildTarget,
|
|
289
|
+
...(prepared.relocatable
|
|
290
|
+
? { relocatable: true }
|
|
291
|
+
: { basePath: prepared.basePath }),
|
|
292
|
+
},
|
|
293
|
+
],
|
|
294
|
+
history: [{ action: 'install', to: prepared.id, at }],
|
|
295
|
+
};
|
|
296
|
+
await writeState(layout, state);
|
|
297
|
+
await switchCurrent(layout, releaseLinkTarget(prepared.id));
|
|
298
|
+
switched = true;
|
|
299
|
+
const url = healthUrl(env);
|
|
300
|
+
if (flags.start) {
|
|
301
|
+
reporter.progress(`Starting the ${title} with pm2`);
|
|
302
|
+
await pm2.start(layout.ecosystemFile, root);
|
|
303
|
+
const healthy = await waitForHealthy(url, {
|
|
304
|
+
timeoutMs: flags['health-timeout'] * 1000,
|
|
305
|
+
fetchImpl: deps.fetchImpl,
|
|
306
|
+
failed: pm2StartFailed(pm2, name),
|
|
307
|
+
});
|
|
308
|
+
if (!healthy) {
|
|
309
|
+
// The name was free before this install, so the process under it is the one just started.
|
|
310
|
+
await pm2.remove(name).catch(() => undefined);
|
|
311
|
+
throw new InstallerError('START_FAILED', `The ${title} did not become healthy at ${url} (waited up to ${flags['health-timeout']}s). It is installed but not running.`, {
|
|
312
|
+
details: { log: await errorLogTail(layout) },
|
|
313
|
+
suggestions: [
|
|
314
|
+
{
|
|
315
|
+
message: 'Read the error log:',
|
|
316
|
+
run: errorLogCommandLine(layout),
|
|
317
|
+
},
|
|
318
|
+
...startAdvice(layout, 'Start it again once fixed:'),
|
|
319
|
+
],
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
await pm2.save();
|
|
323
|
+
}
|
|
324
|
+
const endpoints = endpointsOf(env);
|
|
325
|
+
const initialAdmin = await readInitialAdmin(layout.configFile, path.join(prepared.dir, 'config.example.yml'));
|
|
326
|
+
// `nextCommands` are lines for a shell, as the application CLI's are, so one may chain two commands.
|
|
327
|
+
const startCommand = `pm2 start ${quoteForShell(layout.ecosystemFile)} && pm2 save`;
|
|
328
|
+
const nextCommands = [
|
|
329
|
+
...(flags.start ? [] : [startCommand]),
|
|
330
|
+
'pm2 startup',
|
|
331
|
+
];
|
|
332
|
+
return {
|
|
333
|
+
status: 'success',
|
|
334
|
+
result: {
|
|
335
|
+
directory: root,
|
|
336
|
+
version: prepared.version,
|
|
337
|
+
releaseId: prepared.id,
|
|
338
|
+
builtAt: prepared.builtAt,
|
|
339
|
+
release: prepared.dir,
|
|
340
|
+
appName: prepared.appName,
|
|
341
|
+
basePath: mountPathOf(env) || '/',
|
|
342
|
+
dialect,
|
|
343
|
+
url: endpoints.url,
|
|
344
|
+
endpoints,
|
|
345
|
+
healthUrl: url,
|
|
346
|
+
name,
|
|
347
|
+
started: flags.start,
|
|
348
|
+
configFile: layout.configFile,
|
|
349
|
+
storageDir: layout.storageDir,
|
|
350
|
+
initialAdmin,
|
|
351
|
+
nextCommands,
|
|
352
|
+
},
|
|
353
|
+
summary: [
|
|
354
|
+
`${template ? title : prepared.appName} ${prepared.version} is installed at ${root}${flags.start ? ' and running' : ''}.`,
|
|
355
|
+
` URL ${endpoints.url}`,
|
|
356
|
+
` Release ${prepared.id}`,
|
|
357
|
+
` Sign in ${describeInitialAdmin(initialAdmin)}`,
|
|
358
|
+
` Logs pm2 logs ${name}`,
|
|
359
|
+
'Next steps',
|
|
360
|
+
...(flags.start ? [] : [` Start it: ${startCommand}`]),
|
|
361
|
+
' Start pm2 at boot: run `pm2 startup` and execute the command it prints (needs sudo).',
|
|
362
|
+
` Proxy ${origin} to http://${flags.host}:${flags.port} with location / and client_max_body_size 260m.`,
|
|
363
|
+
],
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
catch (error) {
|
|
367
|
+
// Before the switch nothing is in use yet, so a retry should find the target as empty as it was.
|
|
368
|
+
// After it, the release, configuration and data are real and stay.
|
|
369
|
+
if (!switched) {
|
|
370
|
+
await releaseLock();
|
|
371
|
+
const keep = flags['keep-source'] ? ['.build'] : [];
|
|
372
|
+
await cleanUp(root, created, keep);
|
|
373
|
+
if (keep.length > 0) {
|
|
374
|
+
reporter.warn(`The build directory was kept for inspection: ${path.join(layout.buildDir)}. Remove it before installing into ${root} again.`);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
throw error;
|
|
378
|
+
}
|
|
379
|
+
finally {
|
|
380
|
+
await releaseLock();
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
//# sourceMappingURL=install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"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"}
|