portok 1.0.3 → 1.0.4
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/package.json +1 -1
- package/portok.js +69 -35
package/package.json
CHANGED
package/portok.js
CHANGED
|
@@ -353,46 +353,80 @@ async function cmdInit(options) {
|
|
|
353
353
|
results.push({ path: stateDir, status: 'error', error: err.message });
|
|
354
354
|
}
|
|
355
355
|
|
|
356
|
-
// Install systemd template unit
|
|
356
|
+
// Install systemd template unit (embedded content)
|
|
357
357
|
const systemdDest = path.join(systemdDir, serviceFileName);
|
|
358
|
+
const serviceContent = `# Portok systemd template unit for multi-instance deployments
|
|
359
|
+
# Auto-generated by: portok init
|
|
360
|
+
|
|
361
|
+
[Unit]
|
|
362
|
+
Description=Portok Zero-Downtime Proxy (%i)
|
|
363
|
+
After=network.target
|
|
364
|
+
Documentation=https://github.com/nicatdursunlu/portok
|
|
365
|
+
|
|
366
|
+
[Service]
|
|
367
|
+
Type=simple
|
|
368
|
+
User=www-data
|
|
369
|
+
Group=www-data
|
|
370
|
+
|
|
371
|
+
# Instance configuration from env file
|
|
372
|
+
EnvironmentFile=/etc/portok/%i.env
|
|
373
|
+
|
|
374
|
+
# Set instance name automatically from systemd specifier
|
|
375
|
+
Environment=INSTANCE_NAME=%i
|
|
376
|
+
|
|
377
|
+
# Working directory
|
|
378
|
+
WorkingDirectory=/opt/portok
|
|
379
|
+
|
|
380
|
+
# Start the daemon
|
|
381
|
+
ExecStart=/usr/bin/node /opt/portok/portokd.js
|
|
382
|
+
|
|
383
|
+
# Restart policy
|
|
384
|
+
Restart=always
|
|
385
|
+
RestartSec=5
|
|
386
|
+
StartLimitBurst=5
|
|
387
|
+
StartLimitIntervalSec=60
|
|
388
|
+
|
|
389
|
+
# Logging
|
|
390
|
+
StandardOutput=journal
|
|
391
|
+
StandardError=journal
|
|
392
|
+
SyslogIdentifier=portok-%i
|
|
393
|
+
|
|
394
|
+
# Security hardening
|
|
395
|
+
NoNewPrivileges=true
|
|
396
|
+
ProtectSystem=strict
|
|
397
|
+
ProtectHome=true
|
|
398
|
+
PrivateTmp=true
|
|
399
|
+
ProtectKernelTunables=true
|
|
400
|
+
ProtectKernelModules=true
|
|
401
|
+
ProtectControlGroups=true
|
|
402
|
+
|
|
403
|
+
# Allow writing to state directory
|
|
404
|
+
ReadWritePaths=/var/lib/portok
|
|
405
|
+
|
|
406
|
+
# Network access (required for proxying)
|
|
407
|
+
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
|
|
408
|
+
|
|
409
|
+
[Install]
|
|
410
|
+
WantedBy=multi-user.target
|
|
411
|
+
`;
|
|
412
|
+
|
|
358
413
|
try {
|
|
359
|
-
|
|
360
|
-
const scriptDir = path.dirname(process.argv[1]);
|
|
361
|
-
const possiblePaths = [
|
|
362
|
-
path.join(scriptDir, serviceFileName),
|
|
363
|
-
path.join(scriptDir, '..', serviceFileName),
|
|
364
|
-
'/opt/portok/' + serviceFileName,
|
|
365
|
-
];
|
|
414
|
+
const existingContent = fs.existsSync(systemdDest) ? fs.readFileSync(systemdDest, 'utf-8') : null;
|
|
366
415
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
if (sourceFile) {
|
|
376
|
-
const content = fs.readFileSync(sourceFile, 'utf-8');
|
|
377
|
-
const existingContent = fs.existsSync(systemdDest) ? fs.readFileSync(systemdDest, 'utf-8') : null;
|
|
416
|
+
if (existingContent === serviceContent) {
|
|
417
|
+
results.push({ path: systemdDest, status: 'exists' });
|
|
418
|
+
} else {
|
|
419
|
+
fs.writeFileSync(systemdDest, serviceContent, { mode: 0o644 });
|
|
420
|
+
results.push({ path: systemdDest, status: 'created' });
|
|
378
421
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
results.push({ path:
|
|
384
|
-
|
|
385
|
-
//
|
|
386
|
-
try {
|
|
387
|
-
const { execSync } = require('child_process');
|
|
388
|
-
execSync('systemctl daemon-reload', { stdio: 'pipe' });
|
|
389
|
-
results.push({ path: 'systemctl daemon-reload', status: 'created' });
|
|
390
|
-
} catch (e) {
|
|
391
|
-
// Ignore if systemctl not available (e.g., in Docker)
|
|
392
|
-
}
|
|
422
|
+
// Reload systemd daemon
|
|
423
|
+
try {
|
|
424
|
+
const { execSync } = require('child_process');
|
|
425
|
+
execSync('systemctl daemon-reload', { stdio: 'pipe' });
|
|
426
|
+
results.push({ path: 'systemctl daemon-reload', status: 'created' });
|
|
427
|
+
} catch (e) {
|
|
428
|
+
// Ignore if systemctl not available (e.g., in Docker)
|
|
393
429
|
}
|
|
394
|
-
} else {
|
|
395
|
-
results.push({ path: systemdDest, status: 'skipped', error: 'Template file not found' });
|
|
396
430
|
}
|
|
397
431
|
} catch (err) {
|
|
398
432
|
results.push({ path: systemdDest, status: 'error', error: err.message });
|