@lamalibre/create-portlama 1.0.23 → 1.0.25
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/LICENSE.md +2 -1
- package/README.md +7 -7
- package/package.json +1 -1
- package/scripts/bundle-vendor.js +2 -6
- package/src/index.js +5 -8
- package/src/lib/env.js +3 -7
- package/src/lib/service-config.js +1 -4
- package/src/tasks/harden.js +3 -12
- package/src/tasks/mtls.js +27 -28
- package/src/tasks/nginx.js +3 -12
- package/src/tasks/node.js +1 -3
- package/src/tasks/panel.js +5 -22
- package/src/tasks/redeploy.js +6 -23
- package/vendor/panel-client/dist/assets/index-C0A3Xsrf.js +619 -0
- package/vendor/panel-client/dist/docs/00-introduction/how-it-works.md +55 -55
- package/vendor/panel-client/dist/docs/00-introduction/quickstart.md +50 -36
- package/vendor/panel-client/dist/docs/00-introduction/what-is-portlama.md +27 -21
- package/vendor/panel-client/dist/docs/01-concepts/authentication.md +56 -55
- package/vendor/panel-client/dist/docs/01-concepts/certificates.md +59 -49
- package/vendor/panel-client/dist/docs/01-concepts/dns-and-domains.md +61 -61
- package/vendor/panel-client/dist/docs/01-concepts/mtls.md +105 -76
- package/vendor/panel-client/dist/docs/01-concepts/nginx-reverse-proxy.md +54 -54
- package/vendor/panel-client/dist/docs/01-concepts/security-model.md +136 -96
- package/vendor/panel-client/dist/docs/01-concepts/tunneling.md +27 -27
- package/vendor/panel-client/dist/docs/02-guides/certificate-management.md +65 -62
- package/vendor/panel-client/dist/docs/02-guides/desktop-app-setup.md +172 -0
- package/vendor/panel-client/dist/docs/02-guides/disaster-recovery.md +52 -52
- package/vendor/panel-client/dist/docs/02-guides/first-tunnel.md +31 -27
- package/vendor/panel-client/dist/docs/02-guides/installation.md +41 -41
- package/vendor/panel-client/dist/docs/02-guides/mac-client-setup.md +50 -23
- package/vendor/panel-client/dist/docs/02-guides/managing-users.md +39 -39
- package/vendor/panel-client/dist/docs/02-guides/onboarding.md +47 -43
- package/vendor/panel-client/dist/docs/02-guides/remote-shell.md +277 -0
- package/vendor/panel-client/dist/docs/02-guides/static-sites.md +93 -55
- package/vendor/panel-client/dist/docs/03-architecture/installer.md +74 -49
- package/vendor/panel-client/dist/docs/03-architecture/management-flow.md +43 -42
- package/vendor/panel-client/dist/docs/03-architecture/nginx-configuration.md +24 -17
- package/vendor/panel-client/dist/docs/03-architecture/overview.md +46 -45
- package/vendor/panel-client/dist/docs/03-architecture/panel-client.md +67 -57
- package/vendor/panel-client/dist/docs/03-architecture/panel-server.md +45 -33
- package/vendor/panel-client/dist/docs/03-architecture/state-management.md +52 -42
- package/vendor/panel-client/dist/docs/04-api-reference/certificates.md +150 -95
- package/vendor/panel-client/dist/docs/04-api-reference/onboarding.md +101 -64
- package/vendor/panel-client/dist/docs/04-api-reference/overview.md +105 -75
- package/vendor/panel-client/dist/docs/04-api-reference/services.md +50 -49
- package/vendor/panel-client/dist/docs/04-api-reference/sites.md +136 -95
- package/vendor/panel-client/dist/docs/04-api-reference/system.md +35 -33
- package/vendor/panel-client/dist/docs/04-api-reference/tunnels.md +51 -51
- package/vendor/panel-client/dist/docs/04-api-reference/users.md +65 -65
- package/vendor/panel-client/dist/docs/05-operations/backup-and-restore.md +58 -58
- package/vendor/panel-client/dist/docs/05-operations/monitoring.md +64 -61
- package/vendor/panel-client/dist/docs/05-operations/uninstalling.md +21 -15
- package/vendor/panel-client/dist/docs/05-operations/upgrades.md +16 -16
- package/vendor/panel-client/dist/docs/06-reference/config-files.md +78 -78
- package/vendor/panel-client/dist/docs/06-reference/glossary.md +74 -47
- package/vendor/panel-client/dist/docs/06-reference/installer-flags.md +45 -45
- package/vendor/panel-client/dist/docs/06-reference/ports-and-services.md +102 -102
- package/vendor/panel-client/dist/docs/06-reference/troubleshooting.md +45 -45
- package/vendor/panel-client/dist/docs/_index.json +155 -29
- package/vendor/panel-client/dist/index.html +1 -1
- package/vendor/panel-server/package.json +1 -1
- package/vendor/panel-server/src/index.js +1 -3
- package/vendor/panel-server/src/lib/authelia.js +122 -78
- package/vendor/panel-server/src/lib/certbot.js +32 -21
- package/vendor/panel-server/src/lib/chisel.js +8 -6
- package/vendor/panel-server/src/lib/config.js +9 -5
- package/vendor/panel-server/src/lib/files.js +113 -20
- package/vendor/panel-server/src/lib/mtls.js +264 -173
- package/vendor/panel-server/src/lib/nginx.js +12 -7
- package/vendor/panel-server/src/lib/services.js +1 -6
- package/vendor/panel-server/src/lib/shell.js +487 -0
- package/vendor/panel-server/src/middleware/mtls.js +19 -3
- package/vendor/panel-server/src/routes/invite.js +7 -1
- package/vendor/panel-server/src/routes/management/certs.js +330 -205
- package/vendor/panel-server/src/routes/management/invitations.js +139 -128
- package/vendor/panel-server/src/routes/management/logs.js +7 -13
- package/vendor/panel-server/src/routes/management/services.js +39 -31
- package/vendor/panel-server/src/routes/management/shell.js +1012 -0
- package/vendor/panel-server/src/routes/management/sites.js +463 -378
- package/vendor/panel-server/src/routes/management/system.js +14 -10
- package/vendor/panel-server/src/routes/management/tunnels.js +249 -227
- package/vendor/panel-server/src/routes/management/users.js +218 -191
- package/vendor/panel-server/src/routes/management.js +2 -0
- package/vendor/panel-server/src/routes/onboarding/domain.js +1 -1
- package/vendor/panel-server/src/routes/onboarding/provision.js +24 -8
- package/vendor/panel-client/dist/assets/index-Di5bjQ77.js +0 -619
package/LICENSE.md
CHANGED
|
@@ -13,6 +13,7 @@ You may use, copy, modify, and distribute this software for any **noncommercial*
|
|
|
13
13
|
Commercial use of this software requires a commercial license, available by contacting licence@codelama.com.tr.
|
|
14
14
|
|
|
15
15
|
Commercial use includes, but is not limited to:
|
|
16
|
+
|
|
16
17
|
- Using Portlama in a business to serve data to clients or partners
|
|
17
18
|
- Deploying Portlama as part of a revenue-generating service or product
|
|
18
19
|
- Using Portlama internally at a for-profit organization
|
|
@@ -85,7 +86,7 @@ The first time you are notified in writing that you have violated any of these t
|
|
|
85
86
|
|
|
86
87
|
### No Liability
|
|
87
88
|
|
|
88
|
-
|
|
89
|
+
**_As far as the law allows, the software comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of legal claim._**
|
|
89
90
|
|
|
90
91
|
### Definitions
|
|
91
92
|
|
package/README.md
CHANGED
|
@@ -30,13 +30,13 @@ configured through the browser-based onboarding wizard after installation.
|
|
|
30
30
|
|
|
31
31
|
## Requirements
|
|
32
32
|
|
|
33
|
-
| Requirement
|
|
34
|
-
|
|
|
35
|
-
| OS
|
|
36
|
-
| Access
|
|
37
|
-
| Node.js
|
|
38
|
-
| RAM
|
|
39
|
-
| Recommended
|
|
33
|
+
| Requirement | Details |
|
|
34
|
+
| ----------- | ----------------------- |
|
|
35
|
+
| OS | Ubuntu 24.04 LTS |
|
|
36
|
+
| Access | root |
|
|
37
|
+
| Node.js | >= 20.0.0 |
|
|
38
|
+
| RAM | 512 MB minimum |
|
|
39
|
+
| Recommended | DigitalOcean $4 droplet |
|
|
40
40
|
|
|
41
41
|
## Further Reading
|
|
42
42
|
|
package/package.json
CHANGED
package/scripts/bundle-vendor.js
CHANGED
|
@@ -23,9 +23,7 @@ async function main() {
|
|
|
23
23
|
// --- panel-server: package.json + src/ ---
|
|
24
24
|
const serverSrc = join(monorepoRoot, 'packages', 'panel-server');
|
|
25
25
|
if (!existsSync(serverSrc)) {
|
|
26
|
-
throw new Error(
|
|
27
|
-
`panel-server not found at ${serverSrc}. Run from the monorepo root.`,
|
|
28
|
-
);
|
|
26
|
+
throw new Error(`panel-server not found at ${serverSrc}. Run from the monorepo root.`);
|
|
29
27
|
}
|
|
30
28
|
|
|
31
29
|
const serverDest = join(vendorDir, 'panel-server');
|
|
@@ -40,9 +38,7 @@ async function main() {
|
|
|
40
38
|
// --- panel-client: dist/ (pre-built assets) ---
|
|
41
39
|
const clientDist = join(monorepoRoot, 'packages', 'panel-client', 'dist');
|
|
42
40
|
if (!existsSync(clientDist)) {
|
|
43
|
-
throw new Error(
|
|
44
|
-
`panel-client/dist/ not found at ${clientDist}. Run "npm run build" first.`,
|
|
45
|
-
);
|
|
41
|
+
throw new Error(`panel-client/dist/ not found at ${clientDist}. Run "npm run build" first.`);
|
|
46
42
|
}
|
|
47
43
|
|
|
48
44
|
const clientDest = join(vendorDir, 'panel-client');
|
package/src/index.js
CHANGED
|
@@ -167,7 +167,7 @@ ${b('9. Remove swap file (optional)')}
|
|
|
167
167
|
${c('sudo rm /swapfile')}
|
|
168
168
|
${d('Remove the /swapfile line from /etc/fstab')}
|
|
169
169
|
|
|
170
|
-
${b(
|
|
170
|
+
${b("10. Remove Let's Encrypt certificates (optional)")}
|
|
171
171
|
|
|
172
172
|
${d('List Portlama-issued certs:')}
|
|
173
173
|
${c('sudo certbot certificates')}
|
|
@@ -364,13 +364,10 @@ ${chalk.cyan.bold('└───────────────────
|
|
|
364
364
|
});
|
|
365
365
|
|
|
366
366
|
await new Promise((resolve) => {
|
|
367
|
-
rl.question(
|
|
368
|
-
|
|
369
|
-
()
|
|
370
|
-
|
|
371
|
-
resolve();
|
|
372
|
-
},
|
|
373
|
-
);
|
|
367
|
+
rl.question(`\n ${chalk.white.bold('Press Enter to continue or Ctrl+C to abort...')} `, () => {
|
|
368
|
+
rl.close();
|
|
369
|
+
resolve();
|
|
370
|
+
});
|
|
374
371
|
});
|
|
375
372
|
}
|
|
376
373
|
|
package/src/lib/env.js
CHANGED
|
@@ -10,9 +10,7 @@ export async function detectOS() {
|
|
|
10
10
|
try {
|
|
11
11
|
content = await readFile('/etc/os-release', 'utf8');
|
|
12
12
|
} catch {
|
|
13
|
-
throw new Error(
|
|
14
|
-
'Could not read /etc/os-release. Portlama requires Ubuntu 24.04.',
|
|
15
|
-
);
|
|
13
|
+
throw new Error('Could not read /etc/os-release. Portlama requires Ubuntu 24.04.');
|
|
16
14
|
}
|
|
17
15
|
|
|
18
16
|
const fields = {};
|
|
@@ -29,9 +27,7 @@ export async function detectOS() {
|
|
|
29
27
|
const prettyName = fields.PRETTY_NAME || `${id} ${versionId}`;
|
|
30
28
|
|
|
31
29
|
if (id !== 'ubuntu' || !versionId.startsWith('24.04')) {
|
|
32
|
-
throw new Error(
|
|
33
|
-
`Portlama requires Ubuntu 24.04. Detected: ${prettyName}`,
|
|
34
|
-
);
|
|
30
|
+
throw new Error(`Portlama requires Ubuntu 24.04. Detected: ${prettyName}`);
|
|
35
31
|
}
|
|
36
32
|
|
|
37
33
|
return { id, versionId, prettyName };
|
|
@@ -45,7 +41,7 @@ export async function detectOS() {
|
|
|
45
41
|
* @returns {string} The IPv4 address.
|
|
46
42
|
*/
|
|
47
43
|
export async function detectIP({ allowPrivate = false } = {}) {
|
|
48
|
-
const isAcceptable = (ip) => allowPrivate ? isValidIPv4(ip) : isPublicIP(ip);
|
|
44
|
+
const isAcceptable = (ip) => (allowPrivate ? isValidIPv4(ip) : isPublicIP(ip));
|
|
49
45
|
|
|
50
46
|
// Try DigitalOcean metadata API first
|
|
51
47
|
try {
|
|
@@ -47,9 +47,6 @@ WantedBy=multi-user.target
|
|
|
47
47
|
* @returns {string}
|
|
48
48
|
*/
|
|
49
49
|
export function generateSudoersContent() {
|
|
50
|
-
const processUid = process.getuid?.() ?? 0;
|
|
51
|
-
const processGid = process.getgid?.() ?? 0;
|
|
52
|
-
|
|
53
50
|
return `# Portlama panel-server sudo rules
|
|
54
51
|
# Allows the portlama user to manage specific services and run specific commands
|
|
55
52
|
|
|
@@ -120,7 +117,7 @@ portlama ALL=(root) NOPASSWD: /usr/local/bin/authelia storage *
|
|
|
120
117
|
portlama ALL=(root) NOPASSWD: /usr/bin/mkdir -p /var/www/portlama/*
|
|
121
118
|
portlama ALL=(root) NOPASSWD: /usr/bin/chown -R www-data\\:www-data /var/www/portlama/*
|
|
122
119
|
portlama ALL=(root) NOPASSWD: /usr/bin/chown www-data\\:www-data /var/www/portlama/*
|
|
123
|
-
portlama ALL=(root) NOPASSWD: /usr/bin/chown
|
|
120
|
+
portlama ALL=(root) NOPASSWD: /usr/bin/chown portlama\\:portlama /var/www/portlama/*
|
|
124
121
|
portlama ALL=(root) NOPASSWD: /usr/bin/chmod -R 755 /var/www/portlama/*
|
|
125
122
|
portlama ALL=(root) NOPASSWD: /usr/bin/chmod 644 /var/www/portlama/*
|
|
126
123
|
portlama ALL=(root) NOPASSWD: /usr/bin/rm -rf /var/www/portlama/*
|
package/src/tasks/harden.js
CHANGED
|
@@ -31,18 +31,12 @@ export function hardenTasks(ctx, task) {
|
|
|
31
31
|
// Add to /etc/fstab if not already present
|
|
32
32
|
const fstab = await readFile('/etc/fstab', 'utf8');
|
|
33
33
|
if (!fstab.includes('/swapfile')) {
|
|
34
|
-
await writeFile(
|
|
35
|
-
'/etc/fstab',
|
|
36
|
-
fstab.trimEnd() + '\n/swapfile none swap sw 0 0\n',
|
|
37
|
-
);
|
|
34
|
+
await writeFile('/etc/fstab', fstab.trimEnd() + '\n/swapfile none swap sw 0 0\n');
|
|
38
35
|
}
|
|
39
36
|
|
|
40
37
|
// Set swappiness
|
|
41
38
|
await execa('sysctl', ['vm.swappiness=10']);
|
|
42
|
-
await writeFile(
|
|
43
|
-
'/etc/sysctl.d/99-portlama.conf',
|
|
44
|
-
'vm.swappiness=10\n',
|
|
45
|
-
);
|
|
39
|
+
await writeFile('/etc/sysctl.d/99-portlama.conf', 'vm.swappiness=10\n');
|
|
46
40
|
|
|
47
41
|
subtask.output = 'Swap file created and activated';
|
|
48
42
|
},
|
|
@@ -177,10 +171,7 @@ bantime = 3600
|
|
|
177
171
|
subtask.output = 'Restarting fail2ban...';
|
|
178
172
|
await execa('systemctl', ['restart', 'fail2ban']);
|
|
179
173
|
|
|
180
|
-
const { stdout: status } = await execa('systemctl', [
|
|
181
|
-
'is-active',
|
|
182
|
-
'fail2ban',
|
|
183
|
-
]);
|
|
174
|
+
const { stdout: status } = await execa('systemctl', ['is-active', 'fail2ban']);
|
|
184
175
|
subtask.output = `fail2ban status: ${status.trim()}`;
|
|
185
176
|
},
|
|
186
177
|
rendererOptions: { persistentOutput: true },
|
package/src/tasks/mtls.js
CHANGED
|
@@ -17,8 +17,7 @@ import { generatePassword } from '../lib/secrets.js';
|
|
|
17
17
|
*/
|
|
18
18
|
export function mtlsTasks(ctx, task) {
|
|
19
19
|
const pkiDir = ctx.pkiDir;
|
|
20
|
-
const alreadyProvisioned =
|
|
21
|
-
existsSync(`${pkiDir}/ca.key`) && existsSync(`${pkiDir}/client.p12`);
|
|
20
|
+
const alreadyProvisioned = existsSync(`${pkiDir}/ca.key`) && existsSync(`${pkiDir}/client.p12`);
|
|
22
21
|
|
|
23
22
|
if (alreadyProvisioned) {
|
|
24
23
|
return task.newListr([
|
|
@@ -26,10 +25,7 @@ export function mtlsTasks(ctx, task) {
|
|
|
26
25
|
title: 'mTLS certificates already exist — skipping generation',
|
|
27
26
|
task: async () => {
|
|
28
27
|
// Read the existing p12 password so the summary can display it.
|
|
29
|
-
ctx.p12Password = await readFile(
|
|
30
|
-
`${pkiDir}/.p12-password`,
|
|
31
|
-
'utf8',
|
|
32
|
-
);
|
|
28
|
+
ctx.p12Password = await readFile(`${pkiDir}/.p12-password`, 'utf8');
|
|
33
29
|
},
|
|
34
30
|
},
|
|
35
31
|
]);
|
|
@@ -83,12 +79,7 @@ export function mtlsTasks(ctx, task) {
|
|
|
83
79
|
title: 'Generating client key and CSR',
|
|
84
80
|
task: async (_ctx, subtask) => {
|
|
85
81
|
subtask.output = 'Generating 4096-bit RSA client key...';
|
|
86
|
-
await execa('openssl', [
|
|
87
|
-
'genrsa',
|
|
88
|
-
'-out',
|
|
89
|
-
`${pkiDir}/client.key`,
|
|
90
|
-
'4096',
|
|
91
|
-
]);
|
|
82
|
+
await execa('openssl', ['genrsa', '-out', `${pkiDir}/client.key`, '4096']);
|
|
92
83
|
|
|
93
84
|
subtask.output = 'Creating certificate signing request...';
|
|
94
85
|
await execa('openssl', [
|
|
@@ -149,22 +140,30 @@ export function mtlsTasks(ctx, task) {
|
|
|
149
140
|
const password = generatePassword();
|
|
150
141
|
|
|
151
142
|
subtask.output = 'Creating PKCS12 bundle for browser import...';
|
|
152
|
-
await execa(
|
|
153
|
-
'
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
143
|
+
await execa(
|
|
144
|
+
'openssl',
|
|
145
|
+
[
|
|
146
|
+
'pkcs12',
|
|
147
|
+
'-export',
|
|
148
|
+
'-keypbe',
|
|
149
|
+
'PBE-SHA1-3DES',
|
|
150
|
+
'-certpbe',
|
|
151
|
+
'PBE-SHA1-3DES',
|
|
152
|
+
'-macalg',
|
|
153
|
+
'sha1',
|
|
154
|
+
'-out',
|
|
155
|
+
`${pkiDir}/client.p12`,
|
|
156
|
+
'-inkey',
|
|
157
|
+
`${pkiDir}/client.key`,
|
|
158
|
+
'-in',
|
|
159
|
+
`${pkiDir}/client.crt`,
|
|
160
|
+
'-certfile',
|
|
161
|
+
`${pkiDir}/ca.crt`,
|
|
162
|
+
'-passout',
|
|
163
|
+
'stdin',
|
|
164
|
+
],
|
|
165
|
+
{ input: password },
|
|
166
|
+
);
|
|
168
167
|
|
|
169
168
|
// Save password to file (no trailing newline)
|
|
170
169
|
await writeFile(`${pkiDir}/.p12-password`, password, { mode: 0o600 });
|
package/src/tasks/nginx.js
CHANGED
|
@@ -54,10 +54,7 @@ export function nginxTasks(ctx, task) {
|
|
|
54
54
|
const mtlsSnippet = `ssl_client_certificate ${pkiDir}/ca.crt;
|
|
55
55
|
ssl_verify_client on;
|
|
56
56
|
`;
|
|
57
|
-
await writeFile(
|
|
58
|
-
'/etc/nginx/snippets/portlama-mtls.conf',
|
|
59
|
-
mtlsSnippet,
|
|
60
|
-
);
|
|
57
|
+
await writeFile('/etc/nginx/snippets/portlama-mtls.conf', mtlsSnippet);
|
|
61
58
|
|
|
62
59
|
subtask.output = 'mTLS snippet written to /etc/nginx/snippets/portlama-mtls.conf';
|
|
63
60
|
},
|
|
@@ -130,10 +127,7 @@ server {
|
|
|
130
127
|
}
|
|
131
128
|
}
|
|
132
129
|
`;
|
|
133
|
-
await writeFile(
|
|
134
|
-
'/etc/nginx/sites-available/portlama-panel-ip',
|
|
135
|
-
vhostConfig,
|
|
136
|
-
);
|
|
130
|
+
await writeFile('/etc/nginx/sites-available/portlama-panel-ip', vhostConfig);
|
|
137
131
|
|
|
138
132
|
subtask.output = 'Vhost written to /etc/nginx/sites-available/portlama-panel-ip';
|
|
139
133
|
},
|
|
@@ -187,10 +181,7 @@ server {
|
|
|
187
181
|
await execa('systemctl', ['enable', 'nginx']);
|
|
188
182
|
await execa('systemctl', ['restart', 'nginx']);
|
|
189
183
|
|
|
190
|
-
const { stdout: status } = await execa('systemctl', [
|
|
191
|
-
'is-active',
|
|
192
|
-
'nginx',
|
|
193
|
-
]);
|
|
184
|
+
const { stdout: status } = await execa('systemctl', ['is-active', 'nginx']);
|
|
194
185
|
if (status.trim() !== 'active') {
|
|
195
186
|
throw new Error(`nginx failed to start. Status: ${status.trim()}`);
|
|
196
187
|
}
|
package/src/tasks/node.js
CHANGED
|
@@ -54,9 +54,7 @@ export function nodeTasks(ctx, task) {
|
|
|
54
54
|
try {
|
|
55
55
|
await execa('bash', [setupScript]);
|
|
56
56
|
} catch (error) {
|
|
57
|
-
throw new Error(
|
|
58
|
-
`NodeSource setup script failed.\n${error.stderr || error.message}`,
|
|
59
|
-
);
|
|
57
|
+
throw new Error(`NodeSource setup script failed.\n${error.stderr || error.message}`);
|
|
60
58
|
}
|
|
61
59
|
|
|
62
60
|
await unlink(setupScript).catch(() => {});
|
package/src/tasks/panel.js
CHANGED
|
@@ -92,11 +92,7 @@ export function panelTasks(ctx, task) {
|
|
|
92
92
|
);
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
await execa('chown', [
|
|
96
|
-
'-R',
|
|
97
|
-
'portlama:portlama',
|
|
98
|
-
serverDest,
|
|
99
|
-
]);
|
|
95
|
+
await execa('chown', ['-R', 'portlama:portlama', serverDest]);
|
|
100
96
|
|
|
101
97
|
subtask.output = 'Panel server deployed';
|
|
102
98
|
},
|
|
@@ -203,16 +199,9 @@ export function panelTasks(ctx, task) {
|
|
|
203
199
|
};
|
|
204
200
|
}
|
|
205
201
|
|
|
206
|
-
await writeFile(
|
|
207
|
-
configPath,
|
|
208
|
-
JSON.stringify(config, null, 2) + '\n',
|
|
209
|
-
{ mode: 0o640 },
|
|
210
|
-
);
|
|
202
|
+
await writeFile(configPath, JSON.stringify(config, null, 2) + '\n', { mode: 0o640 });
|
|
211
203
|
|
|
212
|
-
await execa('chown', [
|
|
213
|
-
'portlama:portlama',
|
|
214
|
-
configPath,
|
|
215
|
-
]);
|
|
204
|
+
await execa('chown', ['portlama:portlama', configPath]);
|
|
216
205
|
|
|
217
206
|
subtask.output = `Configuration written to ${configPath}`;
|
|
218
207
|
},
|
|
@@ -222,10 +211,7 @@ export function panelTasks(ctx, task) {
|
|
|
222
211
|
title: 'Writing systemd service unit',
|
|
223
212
|
task: async (_ctx, subtask) => {
|
|
224
213
|
const serviceUnit = generateServiceUnit({ installDir, configDir });
|
|
225
|
-
await writeFile(
|
|
226
|
-
'/etc/systemd/system/portlama-panel.service',
|
|
227
|
-
serviceUnit,
|
|
228
|
-
);
|
|
214
|
+
await writeFile('/etc/systemd/system/portlama-panel.service', serviceUnit);
|
|
229
215
|
|
|
230
216
|
subtask.output = 'Systemd service unit written';
|
|
231
217
|
},
|
|
@@ -267,10 +253,7 @@ export function panelTasks(ctx, task) {
|
|
|
267
253
|
subtask.output = 'Waiting for service to start...';
|
|
268
254
|
await sleep(3000);
|
|
269
255
|
|
|
270
|
-
const { stdout: status } = await execa('systemctl', [
|
|
271
|
-
'is-active',
|
|
272
|
-
'portlama-panel',
|
|
273
|
-
]);
|
|
256
|
+
const { stdout: status } = await execa('systemctl', ['is-active', 'portlama-panel']);
|
|
274
257
|
if (status.trim() !== 'active') {
|
|
275
258
|
const { stdout: logs } = await execa('journalctl', [
|
|
276
259
|
'-u',
|
package/src/tasks/redeploy.js
CHANGED
|
@@ -70,10 +70,7 @@ export function redeployTasks(ctx, task) {
|
|
|
70
70
|
title: 'Stopping panel service',
|
|
71
71
|
task: async (_ctx, subtask) => {
|
|
72
72
|
try {
|
|
73
|
-
const { stdout: status } = await execa('systemctl', [
|
|
74
|
-
'is-active',
|
|
75
|
-
'portlama-panel',
|
|
76
|
-
]);
|
|
73
|
+
const { stdout: status } = await execa('systemctl', ['is-active', 'portlama-panel']);
|
|
77
74
|
if (status.trim() === 'active') {
|
|
78
75
|
await execa('systemctl', ['stop', 'portlama-panel']);
|
|
79
76
|
subtask.output = 'Service stopped';
|
|
@@ -134,9 +131,7 @@ export function redeployTasks(ctx, task) {
|
|
|
134
131
|
|
|
135
132
|
const prebuiltDist = join(clientSrc, 'dist');
|
|
136
133
|
if (!existsSync(join(prebuiltDist, 'index.html'))) {
|
|
137
|
-
throw new Error(
|
|
138
|
-
'Pre-built panel-client dist not found. The package may be corrupted.',
|
|
139
|
-
);
|
|
134
|
+
throw new Error('Pre-built panel-client dist not found. The package may be corrupted.');
|
|
140
135
|
}
|
|
141
136
|
|
|
142
137
|
subtask.output = 'Copying panel-client dist...';
|
|
@@ -169,11 +164,7 @@ export function redeployTasks(ctx, task) {
|
|
|
169
164
|
staticDir: join(installDir, 'panel-client', 'dist'),
|
|
170
165
|
};
|
|
171
166
|
|
|
172
|
-
await writeFile(
|
|
173
|
-
configPath,
|
|
174
|
-
JSON.stringify(config, null, 2) + '\n',
|
|
175
|
-
{ mode: 0o640 },
|
|
176
|
-
);
|
|
167
|
+
await writeFile(configPath, JSON.stringify(config, null, 2) + '\n', { mode: 0o640 });
|
|
177
168
|
await execa('chown', ['portlama:portlama', configPath]);
|
|
178
169
|
|
|
179
170
|
subtask.output = 'Configuration updated';
|
|
@@ -185,10 +176,7 @@ export function redeployTasks(ctx, task) {
|
|
|
185
176
|
task: async (_ctx, subtask) => {
|
|
186
177
|
subtask.output = 'Writing systemd service unit...';
|
|
187
178
|
const serviceUnit = generateServiceUnit({ installDir, configDir });
|
|
188
|
-
await writeFile(
|
|
189
|
-
'/etc/systemd/system/portlama-panel.service',
|
|
190
|
-
serviceUnit,
|
|
191
|
-
);
|
|
179
|
+
await writeFile('/etc/systemd/system/portlama-panel.service', serviceUnit);
|
|
192
180
|
|
|
193
181
|
subtask.output = 'Writing sudoers rules...';
|
|
194
182
|
const sudoersContent = generateSudoersContent();
|
|
@@ -220,10 +208,7 @@ export function redeployTasks(ctx, task) {
|
|
|
220
208
|
subtask.output = 'Waiting for service to start...';
|
|
221
209
|
await sleep(3000);
|
|
222
210
|
|
|
223
|
-
const { stdout: status } = await execa('systemctl', [
|
|
224
|
-
'is-active',
|
|
225
|
-
'portlama-panel',
|
|
226
|
-
]);
|
|
211
|
+
const { stdout: status } = await execa('systemctl', ['is-active', 'portlama-panel']);
|
|
227
212
|
if (status.trim() !== 'active') {
|
|
228
213
|
const { stdout: logs } = await execa('journalctl', [
|
|
229
214
|
'-u',
|
|
@@ -254,9 +239,7 @@ export function redeployTasks(ctx, task) {
|
|
|
254
239
|
'-n',
|
|
255
240
|
'20',
|
|
256
241
|
]);
|
|
257
|
-
throw new Error(
|
|
258
|
-
`Panel health check failed.\nRecent logs:\n${logs}\n${error.message}`,
|
|
259
|
-
);
|
|
242
|
+
throw new Error(`Panel health check failed.\nRecent logs:\n${logs}\n${error.message}`);
|
|
260
243
|
}
|
|
261
244
|
},
|
|
262
245
|
rendererOptions: { persistentOutput: true },
|