feat(cli): add options for user, home, and working directory
- Add `--run-as` option to specify user for system-wide timers - Add `--home` option to set the HOME environment variable - Add `--cwd` option to define the working directory - Update tests to validate new options and behavior
This commit is contained in:
@@ -18,6 +18,18 @@ export const createCommand = new Command()
|
|||||||
})
|
})
|
||||||
.option('--description <desc:string>', 'Beschreibung des Timers')
|
.option('--description <desc:string>', 'Beschreibung des Timers')
|
||||||
.option('--user', 'Erstellt die Unit als User-Timer')
|
.option('--user', 'Erstellt die Unit als User-Timer')
|
||||||
|
.option(
|
||||||
|
'--run-as <user:string>',
|
||||||
|
'Führe den systemweiten Timer als bestimmter Benutzer aus (setzt User= in der Service-Unit)',
|
||||||
|
)
|
||||||
|
.option(
|
||||||
|
'--home <path:string>',
|
||||||
|
'HOME-Variable für den Service setzen',
|
||||||
|
)
|
||||||
|
.option(
|
||||||
|
'--cwd <path:string>',
|
||||||
|
'Arbeitsverzeichnis (WorkingDirectory) für den Service-Prozess',
|
||||||
|
)
|
||||||
.option('--output <dir:string>', 'Zielverzeichnis der Unit-Dateien')
|
.option('--output <dir:string>', 'Zielverzeichnis der Unit-Dateien')
|
||||||
.option(
|
.option(
|
||||||
'--after <target:string>',
|
'--after <target:string>',
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
|
assert,
|
||||||
assertStringIncludes,
|
assertStringIncludes,
|
||||||
} from 'https://deno.land/std@0.224.0/assert/mod.ts';
|
} from 'https://deno.land/std@0.224.0/assert/mod.ts';
|
||||||
import { TimerOptions } from '../../types/mod.ts';
|
import { TimerOptions } from '../../types/mod.ts';
|
||||||
@@ -53,3 +54,63 @@ Deno.test('generateUnits berücksichtigt environment und logfile', () => {
|
|||||||
assertStringIncludes(serviceUnit, 'StandardOutput=append:/var/log/job.log');
|
assertStringIncludes(serviceUnit, 'StandardOutput=append:/var/log/job.log');
|
||||||
assertStringIncludes(serviceUnit, 'StandardError=append:/var/log/job.log');
|
assertStringIncludes(serviceUnit, 'StandardError=append:/var/log/job.log');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Deno.test('generateUnits berücksichtigt runAs', () => {
|
||||||
|
const opts: TimerOptions = {
|
||||||
|
exec: '/bin/true',
|
||||||
|
calendar: 'daily',
|
||||||
|
runAs: 'myuser',
|
||||||
|
};
|
||||||
|
const { serviceUnit } = generateUnits('job', opts);
|
||||||
|
|
||||||
|
assertStringIncludes(serviceUnit, 'User=myuser');
|
||||||
|
});
|
||||||
|
|
||||||
|
Deno.test('generateUnits berücksichtigt home', () => {
|
||||||
|
const opts: TimerOptions = {
|
||||||
|
exec: '/bin/true',
|
||||||
|
calendar: 'daily',
|
||||||
|
home: '/home/myuser',
|
||||||
|
};
|
||||||
|
const { serviceUnit } = generateUnits('job', opts);
|
||||||
|
|
||||||
|
assertStringIncludes(serviceUnit, 'Environment=HOME=/home/myuser');
|
||||||
|
});
|
||||||
|
|
||||||
|
Deno.test('generateUnits berücksichtigt cwd', () => {
|
||||||
|
const opts: TimerOptions = {
|
||||||
|
exec: '/bin/true',
|
||||||
|
calendar: 'daily',
|
||||||
|
cwd: '/srv/app',
|
||||||
|
};
|
||||||
|
const { serviceUnit } = generateUnits('job', opts);
|
||||||
|
|
||||||
|
assertStringIncludes(serviceUnit, 'WorkingDirectory=/srv/app');
|
||||||
|
});
|
||||||
|
|
||||||
|
Deno.test('generateUnits verwendet default.target bei User-Timern', () => {
|
||||||
|
const opts: TimerOptions = {
|
||||||
|
exec: '/bin/true',
|
||||||
|
calendar: 'daily',
|
||||||
|
user: true,
|
||||||
|
};
|
||||||
|
const { timerUnit } = generateUnits('job', opts);
|
||||||
|
|
||||||
|
assertStringIncludes(timerUnit, 'WantedBy=default.target');
|
||||||
|
});
|
||||||
|
|
||||||
|
Deno.test('generateUnits ignoriert runAs bei --user', () => {
|
||||||
|
const opts = {
|
||||||
|
exec: '/bin/true',
|
||||||
|
calendar: 'daily',
|
||||||
|
user: true,
|
||||||
|
runAs: 'should-not-appear',
|
||||||
|
};
|
||||||
|
|
||||||
|
const { serviceUnit } = generateUnits('job', opts);
|
||||||
|
|
||||||
|
assert(
|
||||||
|
!serviceUnit.includes('User=should-not-appear'),
|
||||||
|
'User= sollte bei --user nicht enthalten sein',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
@@ -51,14 +51,18 @@ export function generateUnits(name: string, options: TimerOptions): {
|
|||||||
`[Service]`,
|
`[Service]`,
|
||||||
`Type=oneshot`,
|
`Type=oneshot`,
|
||||||
`ExecStart=${options.exec}`,
|
`ExecStart=${options.exec}`,
|
||||||
|
...(options.cwd ? [`WorkingDirectory=${options.cwd}`] : []),
|
||||||
...(options.environment?.map((e) => `Environment=${e}`) ?? []),
|
...(options.environment?.map((e) => `Environment=${e}`) ?? []),
|
||||||
|
...(options.home ? [`Environment=HOME=${options.home}`] : []),
|
||||||
|
...(options.logfile
|
||||||
|
? [
|
||||||
|
`StandardOutput=append:${options.logfile}`,
|
||||||
|
`StandardError=append:${options.logfile}`,
|
||||||
|
]
|
||||||
|
: []),
|
||||||
|
...(options.runAs && !options.user ? [`User=${options.runAs}`] : []),
|
||||||
];
|
];
|
||||||
|
|
||||||
if (options.logfile) {
|
|
||||||
unitParts.push(`StandardOutput=append:${options.logfile}`);
|
|
||||||
unitParts.push(`StandardError=append:${options.logfile}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const serviceUnit = unitParts.join('\n');
|
const serviceUnit = unitParts.join('\n');
|
||||||
|
|
||||||
const timerParts = [
|
const timerParts = [
|
||||||
@@ -70,7 +74,7 @@ export function generateUnits(name: string, options: TimerOptions): {
|
|||||||
`Persistent=true`,
|
`Persistent=true`,
|
||||||
``,
|
``,
|
||||||
`[Install]`,
|
`[Install]`,
|
||||||
`WantedBy=timers.target`,
|
`WantedBy=${options.user ? 'default.target' : 'timers.target'}`,
|
||||||
];
|
];
|
||||||
|
|
||||||
const timerUnit = timerParts.join('\n');
|
const timerUnit = timerParts.join('\n');
|
||||||
|
@@ -4,6 +4,9 @@ export interface TimerOptions {
|
|||||||
calendar: string;
|
calendar: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
user?: boolean;
|
user?: boolean;
|
||||||
|
runAs?: string;
|
||||||
|
home?: string;
|
||||||
|
cwd?: string;
|
||||||
output?: string;
|
output?: string;
|
||||||
after?: string[];
|
after?: string[];
|
||||||
environment?: string[];
|
environment?: string[];
|
||||||
|
Reference in New Issue
Block a user