fix(api): logrotate modification & permissions (#1145)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **Chores**
- Updated deployment and build commands to use a more efficient package
manager.
- **Refactor**
- Improved the internal file modification structure for enhanced
flexibility and maintainability.
- **New Features**
- Enhanced log management by adding functionality for proper permission
handling and cleanup after operations.
- Introduced a new log rotation configuration for managing log files
effectively.
- Updated timestamps for various components to reflect the latest
download times.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Pujit Mehrotra
2025-02-19 09:13:43 -05:00
committed by GitHub
parent 7539a3ed75
commit b970fd9e6c
10 changed files with 73 additions and 24 deletions

View File

@@ -5,12 +5,12 @@ default:
@just list-commands
setup:
npm install
npm run container:build
pnpm install
pnpm run container:build
# builds js files that can run on an unraid server
@build:
npm run build
pnpm run build
# deploys to an unraid server
@deploy:
@@ -18,4 +18,3 @@ setup:
# build & deploy
bd: build deploy

View File

@@ -27,7 +27,7 @@ export abstract class FileModification {
* Get the path to the applied patch file for the target filePath, saved after applying the patch
* @param targetFile - The path to the file that was patched
*/
private getPathToAppliedPatch(targetFile: string): string {
protected getPathToAppliedPatch(targetFile = this.filePath): string {
const dir = dirname(targetFile);
const filename = `${basename(targetFile)}.patch`;
return join(dir, filename);

View File

@@ -19,7 +19,9 @@ interface ModificationTestCase {
}
const getPathToFixture = (fileName: string) => resolve(__dirname, `__fixtures__/downloaded/${fileName}`);
const testCases: ModificationTestCase[] = [
/** Modifications that patch the content of an existing file in one or more places. */
const patchTestCases: ModificationTestCase[] = [
{
ModificationClass: DefaultPageLayoutModification,
fileUrl:
@@ -43,6 +45,10 @@ const testCases: ModificationTestCase[] = [
fileUrl: 'https://github.com/unraid/webgui/raw/refs/heads/master/emhttp/auth-request.php',
fileName: 'auth-request.php',
},
];
/** Modifications that simply add a new file & remove it on rollback. */
const simpleTestCases: ModificationTestCase[] = [
{
ModificationClass: LogRotateModification,
fileUrl: 'logrotate.conf',
@@ -131,16 +137,24 @@ async function testInvalidModification(testCase: ModificationTestCase, patcher:
await patcher.rollback();
}
const allTestCases = [...patchTestCases, ...simpleTestCases];
describe('File modifications', () => {
let patcher: FileModification;
test.each(testCases)(`$fileName modifier correctly applies to fresh install`, async (testCase) => {
await testModification(testCase, patcher);
});
test.each(allTestCases)(
`$fileName modifier correctly applies to fresh install`,
async (testCase) => {
await testModification(testCase, patcher);
}
);
test.each(testCases)(`$fileName modifier correctly handles invalid content`, async (testCase) => {
await testInvalidModification(testCase, patcher);
});
test.each(patchTestCases)(
`$fileName modifier correctly handles invalid content`,
async (testCase) => {
await testInvalidModification(testCase, patcher);
}
);
afterEach(async () => {
await patcher?.rollback();

View File

@@ -1,4 +1,3 @@
/var/log/unraid-api/*.log {
rotate 1
missingok
@@ -9,4 +8,13 @@
copytruncate
create 0640 root root
}
/var/log/graphql-api.log {
rotate 1
missingok
size 1M
su root root
compress
delaycompress
copytruncate
create 0640 root root
}

View File

@@ -1,5 +1,5 @@
import { Logger } from '@nestjs/common';
import { readFile } from 'node:fs/promises';
import { readFile, rm, writeFile } from 'node:fs/promises';
import { fileExists } from '@app/core/utils/files/file-exists';
import {
@@ -21,7 +21,17 @@ export class LogRotateModification extends FileModification {
copytruncate
create 0640 root root
}
`;
/var/log/graphql-api.log {
rotate 1
missingok
size 1M
su root root
compress
delaycompress
copytruncate
create 0640 root root
}
`.trimStart();
constructor(logger: Logger) {
super(logger);
@@ -46,4 +56,15 @@ export class LogRotateModification extends FileModification {
}
return { shouldApply: true, reason: 'No LogRotate config for the API configured yet' };
}
async apply(): Promise<string> {
await this.rollback();
await writeFile(this.filePath, this.logRotateConfig, { mode: 0o644 });
return this.logRotateConfig;
}
async rollback(): Promise<void> {
await rm(this.getPathToAppliedPatch(), { force: true });
await rm(this.filePath, { force: true });
}
}

View File

@@ -2,8 +2,7 @@ Index: /etc/logrotate.d/unraid-api
===================================================================
--- /etc/logrotate.d/unraid-api original
+++ /etc/logrotate.d/unraid-api modified
@@ -0,0 +1,12 @@
+
@@ -0,0 +1,20 @@
+/var/log/unraid-api/*.log {
+ rotate 1
+ missingok
@@ -14,5 +13,13 @@ Index: /etc/logrotate.d/unraid-api
+ copytruncate
+ create 0640 root root
+}
+
\ No newline at end of file
+/var/log/graphql-api.log {
+ rotate 1
+ missingok
+ size 1M
+ su root root
+ compress
+ delaycompress
+ copytruncate
+ create 0640 root root
+}