linting and SFTP volume support

This commit is contained in:
Jakub Trávník 2025-12-29 11:16:36 +01:00
parent 5cdec5cdaa
commit e4f66de447
3 changed files with 277 additions and 227 deletions

View file

@ -1,6 +1,6 @@
import crypto from "node:crypto"; import crypto from "node:crypto";
import { eq, or } from "drizzle-orm"; import { eq, or } from "drizzle-orm";
import { InternalServerError, NotFoundError } from "http-errors-enhanced"; import { ConflictError, InternalServerError, NotFoundError } from "http-errors-enhanced";
import { db } from "../../db/db"; import { db } from "../../db/db";
import { repositoriesTable } from "../../db/schema"; import { repositoriesTable } from "../../db/schema";
import { toMessage } from "../../utils/errors"; import { toMessage } from "../../utils/errors";
@ -74,7 +74,9 @@ const createRepository = async (name: string, config: RepositoryConfig, compress
where: eq(repositoriesTable.shortId, shortId), where: eq(repositoriesTable.shortId, shortId),
}); });
if (existingByShortId) { if (existingByShortId) {
throw new ConflictError(`A repository with shortId '${shortId}' already exists. The shortId is used as the subdirectory name for local repositories.`); throw new ConflictError(
`A repository with shortId '${shortId}' already exists. The shortId is used as the subdirectory name for local repositories.`,
);
} }
} else { } else {
shortId = generateShortId(); shortId = generateShortId();
@ -95,13 +97,13 @@ const createRepository = async (name: string, config: RepositoryConfig, compress
if (repoExists && !config.isExistingRepository) { if (repoExists && !config.isExistingRepository) {
throw new ConflictError( throw new ConflictError(
`A restic repository already exists at this location. ` + `A restic repository already exists at this location. ` +
`If you want to use the existing repository, set "isExistingRepository": true in the config.` `If you want to use the existing repository, set "isExistingRepository": true in the config.`,
); );
} }
if (!repoExists && config.isExistingRepository) { if (!repoExists && config.isExistingRepository) {
throw new InternalServerError( throw new InternalServerError(
`Cannot access existing repository. Verify the path/credentials are correct and the repository exists.` `Cannot access existing repository. Verify the path/credentials are correct and the repository exists.`,
); );
} }

View file

@ -264,6 +264,43 @@ This example is intended to be the primary, copy/paste-friendly reference for co
} }
``` ```
#### SFTP
```json
{
"name": "sftp-volume",
"config": {
"backend": "sftp",
"host": "sftp.example.com",
"port": 22,
"username": "user",
"password": "${SFTP_PASSWORD}",
"path": "/data",
"readOnly": false,
"skipHostKeyCheck": true
}
}
```
For key-based authentication:
```json
{
"name": "sftp-volume-key",
"config": {
"backend": "sftp",
"host": "sftp.example.com",
"port": 22,
"username": "user",
"privateKey": "${SFTP_PRIVATE_KEY}",
"path": "/data",
"readOnly": false,
"skipHostKeyCheck": false,
"knownHosts": "sftp.example.com ssh-ed25519 AAAA..."
}
}
```
### Repository types ### Repository types
#### Local #### Local

View file

@ -45,6 +45,19 @@
"readOnly": false, "readOnly": false,
"ssl": true "ssl": true
} }
},
{
"name": "sftp-volume",
"config": {
"backend": "sftp",
"host": "sftp.example.com",
"port": 22,
"username": "user",
"password": "${SFTP_PASSWORD}",
"path": "/data",
"readOnly": false,
"skipHostKeyCheck": true
}
} }
], ],
"repositories": [ "repositories": [
@ -129,9 +142,7 @@
"oneFileSystem": false, "oneFileSystem": false,
"enabled": true, "enabled": true,
"notifications": ["slack-alerts"], "notifications": ["slack-alerts"],
"mirrors": [ "mirrors": [{ "repository": "s3-repo" }]
{ "repository": "s3-repo" }
]
} }
], ],
"notificationDestinations": [ "notificationDestinations": [