Skip to content

Commit

Permalink
feat: override server/origin address for tasks
Browse files Browse the repository at this point in the history
  • Loading branch information
Mirasaki committed Jan 10, 2024
1 parent 0d05279 commit aed5ea5
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 5 deletions.
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,36 @@ The following example creates a backup of the `/D:/DayZ/servers/1` directory on

> Hi there, and thank you for your interest in this project! This application could definitely do a lot more than what it currently offers, we'd love to hear about your use-cases so that we can support a variety of other workflows. [Request a feature here](https://github.com/Mirasaki/backup-manager/issues)

#### Multiple Server Backups

All of the server/authentication options can also be provided in task configurations to override the target server.

Take the following task as an example:

```yaml
- type: Directory
enabled: false
origin: /D:/DayZ/servers/1
destination: backups/DayZ/FullBackups
compress: true
interval: 1440 # Daily
keep-latest: 1 # 1 Day
```

Let's say we need to run this task on a different server than our default, origin server. We can simply override the ip/origin address, and provide different credentials:

```yaml
- type: Directory
# ... Existing task properties
keep-latest: 1 # 1 Day
# Auth/server options
remote:
host: 41.69.129.420
port: 9292
username: mirasaki
password: your-password-here
```

## Attribution

- <a href="https://www.flaticon.com/free-icons/backup" title="backup icons">Backup icon created by Freepik - Flaticon</a>
4 changes: 3 additions & 1 deletion src/lib/Backups/CreateBackupTask.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { CreateBackupTypes } from '../../types/backups'
import { type CreateBackupConfig } from '../../types/config'
import { type TaskServerConfig, type CreateBackupConfig } from '../../types/config'
import { MS_IN_ONE_SECOND, SECONDS_IN_ONE_MINUTE } from '../../magic-number'
import { allCreateBackupTypes, CreateBackupTaskError, type Client } from '..'
import { createWriteStream, readdirSync, rmSync, rmdirSync, statSync } from 'fs'
Expand All @@ -24,6 +24,7 @@ export class CreateBackupTask {
interval: number
keepLatest: number
runs = 0
server: TaskServerConfig | null = null

private _timerStart: number | null = null
get timerStart (): number | null {
Expand Down Expand Up @@ -74,6 +75,7 @@ export class CreateBackupTask {
this.interval = (config.interval ?? 3600) * MS_IN_ONE_SECOND * SECONDS_IN_ONE_MINUTE
this.keepLatest = config['keep-latest'] ?? 5
this.sendNotifications = config['desktop-notifications'] ?? true
this.server = config.server ?? null

// Always save in client tasks
client.tasks.create.push(this)
Expand Down
20 changes: 16 additions & 4 deletions src/lib/Client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ export class Client {

async connect (
task: CreateBackupTask | null,
onConnect: (sftpClient: SFTPClient) => any | Promise<any>,
onRefuse: (err: Error) => any | Promise<any> = (err) => {
onConnect: (sftpClient: SFTPClient, task: CreateBackupTask | null) => any | Promise<any>,
onRefuse: (err: Error, task: CreateBackupTask | null) => any | Promise<any> = (err) => {
console.error('Error encountered while connecting to remote:')
console.error(err)
console.error('Can\'t continue, exiting...')
Expand All @@ -69,16 +69,28 @@ export class Client {
}
}

// Override host/port if task has remote options
if ((task?.server) != null) {
const { server } = task
this.connectOptions.host = server.remote.host
this.connectOptions.port = server.remote.port
this.connectOptions.username = server.username
if (server.password != null) this.connectOptions.password = server.password
if (server['private-key'] != null) this.connectOptions.privateKey = server['private-key']
if (server.passphrase != null) this.connectOptions.passphrase = server.passphrase
if (server['ssh-auth-sock'] != null) this.connectOptions.agent = server['ssh-auth-sock']
}

const sftpClient = new SFTPClient()
try {
await sftpClient.connect(this.connectOptions)
if (task != null) console.info(`${task.identifier} SFTP connection established`)
this.connected = true
await onConnect(sftpClient)
await onConnect(sftpClient, task)
return true
} catch (err: unknown) {
if (task != null) console.error(`${task.identifier} SFTP connection couldn't be established`)
if (typeof onRefuse === 'function') await onRefuse(err as Error)
if (typeof onRefuse === 'function') await onRefuse(err as Error, task)
return false
} finally {
if (task != null) console.info(`${task.identifier} Closing/ending SFTP connection...`)
Expand Down
3 changes: 3 additions & 0 deletions src/types/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ export interface ClientConfig {
'create-backups': CreateBackupConfig[]
}

export type TaskServerConfig = Omit<ClientConfig, 'create-backups'>

export interface CreateBackupConfig {
type?: keyof typeof CreateBackupTypes
'desktop-notifications'?: boolean
Expand All @@ -23,6 +25,7 @@ export interface CreateBackupConfig {
compress?: boolean
interval?: number
'keep-latest'?: number
server?: TaskServerConfig
}

export interface CreateEntriesBackupConfig extends CreateBackupConfig {
Expand Down

0 comments on commit aed5ea5

Please sign in to comment.