Skip to content

Commit

Permalink
Make it so Backups can be prefixed by the container name. (#102)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kaiede authored Dec 6, 2024
1 parent 2dccc2f commit 30d550d
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 16 deletions.
2 changes: 2 additions & 0 deletions Sources/Bedrockifier/Model/BackupConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public struct BackupConfig: Codable {

public struct ContainerConfig: Codable {
public var name: String
public var prefixContainerName: Bool?
public var rcon: String?
public var ssh: String?
public var password: String?
Expand All @@ -60,6 +61,7 @@ public struct BackupConfig: Codable {
public var sshPath: String?
public var sshpassPath: String?
public var backupPath: String?
public var prefixContainerName: Bool?
public var servers: ServerConfig?
public var containers: ServerContainersConfig?
public var trim: TrimConfig?
Expand Down
16 changes: 12 additions & 4 deletions Sources/Bedrockifier/Model/ContainerConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ public enum ContainerConnectionConfigKind {
}

public protocol ContainerConnectionConfig {
var prefixContainerName: Bool { get }
var processPath: String { get }
var kind: ContainerConnectionConfigKind { get }
var newline: TerminalNewline { get }
Expand All @@ -92,15 +93,18 @@ public struct DockerConnectionConfig: ContainerConnectionConfig {
let containerName: String
public let password: ContainerPassword = .none
public let validator: SSHHostKeyValidator? = nil
public let prefixContainerName: Bool

init(dockerPath: String, config: BackupConfig.ContainerConfig) {
init(dockerPath: String, config: BackupConfig.ContainerConfig, prefixAllContainerNames: Bool) {
self.dockerPath = dockerPath
self.containerName = config.name
self.prefixContainerName = config.prefixContainerName == true || prefixAllContainerNames
}

init(dockerPath: String, containerName: String) {
init(dockerPath: String, containerName: String, prefixAllContainerNames: Bool) {
self.dockerPath = dockerPath
self.containerName = containerName
self.prefixContainerName = prefixAllContainerNames
}

public var kind: ContainerConnectionConfigKind { .docker }
Expand All @@ -121,8 +125,9 @@ public struct RCONConnectionConfig: ContainerConnectionConfig {
let address: String
public let password: ContainerPassword
public let validator: SSHHostKeyValidator? = nil
public let prefixContainerName: Bool

init?(rconPath: String, config: BackupConfig.ContainerConfig) {
init?(rconPath: String, config: BackupConfig.ContainerConfig, prefixAllContainerNames: Bool) {
guard let rconAddr = config.rcon else { return nil }
let password = config.containerPassword()
guard password != .none else {
Expand All @@ -135,6 +140,7 @@ public struct RCONConnectionConfig: ContainerConnectionConfig {
self.rconPath = rconPath
self.address = rconAddr
self.password = password
self.prefixContainerName = config.prefixContainerName == true || prefixAllContainerNames
}

public var kind: ContainerConnectionConfigKind { .rcon }
Expand Down Expand Up @@ -162,8 +168,9 @@ public struct SSHConnectionConfig: ContainerConnectionConfig {
let address: String
public let password: ContainerPassword
public let validator: SSHHostKeyValidator?
public let prefixContainerName: Bool

init?(validator: SSHHostKeyValidator, config: BackupConfig.ContainerConfig) {
init?(validator: SSHHostKeyValidator, config: BackupConfig.ContainerConfig, prefixAllContainerNames: Bool) {
guard let sshAddr = config.ssh else { return nil }
let password = config.containerPassword()
guard password != .none else {
Expand All @@ -176,6 +183,7 @@ public struct SSHConnectionConfig: ContainerConnectionConfig {
self.address = sshAddr
self.password = password
self.validator = validator
self.prefixContainerName = config.prefixContainerName == true || prefixAllContainerNames
}

public var kind: ContainerConnectionConfigKind { .ssh }
Expand Down
37 changes: 29 additions & 8 deletions Sources/Bedrockifier/Model/ContainerConnection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,10 @@ public class ContainerConnection {
for worldUrl in worlds {
do {
let world = try World(url: worldUrl)
let prefix = connectionConfig.prefixContainerName ? name : nil

Library.log.info("Backing Up: \(world.name)")
let backupWorld = try world.backup(to: destination)
let backupWorld = try world.backup(to: destination, prefixContainerName: prefix)
Library.log.info("Backed up as: \(backupWorld.location.lastPathComponent)")
} catch let error {
Library.log.error("Backup of world at \(worldUrl.path) failed.")
Expand Down Expand Up @@ -308,10 +309,11 @@ public class ContainerConnection {

extension ContainerConnection {
public static func loadContainers(from config: BackupConfig, tools: ToolConfig) throws -> [ContainerConnection] {
let prefixAllContainerNames = config.prefixContainerName ?? false
var containers: [ContainerConnection] = []
for container in config.containers?.bedrock ?? [] {
Library.log.debug("Creating Bedrock Container Connection. (container: \(container.name))")
let config = containerConfig(container: container, tools: tools)
let config = containerConfig(container: container, tools: tools, prefixAllContainerNames: prefixAllContainerNames)

Check warning on line 316 in Sources/Bedrockifier/Model/ContainerConnection.swift

View workflow job for this annotation

GitHub Actions / Swift 6.0.2 (ubuntu-22.04)

Line Length Violation: Line should be 120 characters or less; currently it has 126 characters (line_length)
let connection = try ContainerConnection(containerName: container.name,
config: config,
kind: .bedrock,
Expand All @@ -322,7 +324,7 @@ extension ContainerConnection {

for container in config.containers?.java ?? [] {
Library.log.debug("Creating Java Container Connection. (container: \(container.name)")
let config = containerConfig(container: container, tools: tools)
let config = containerConfig(container: container, tools: tools, prefixAllContainerNames: prefixAllContainerNames)

Check warning on line 327 in Sources/Bedrockifier/Model/ContainerConnection.swift

View workflow job for this annotation

GitHub Actions / Swift 6.0.2 (ubuntu-22.04)

Line Length Violation: Line should be 120 characters or less; currently it has 126 characters (line_length)
let connection = try ContainerConnection(containerName: container.name,
config: config,
kind: .java,
Expand All @@ -333,11 +335,17 @@ extension ContainerConnection {

// Offer Backwards Compatibility for Older Installs
for container in config.servers ?? [:] {
let prefixAllContainers = config.prefixContainerName ?? false
let containerName = container.key
let worldsFolder = URL(fileURLWithPath: container.value)
let worlds = try World.getWorlds(at: worldsFolder)
let worldPaths = worlds.map({ $0.location.path })
let config = DockerConnectionConfig(dockerPath: tools.dockerPath, containerName: containerName)
let config = DockerConnectionConfig(
dockerPath: tools.dockerPath,
containerName: containerName,
prefixAllContainerNames: prefixAllContainers
)

Check warning on line 348 in Sources/Bedrockifier/Model/ContainerConnection.swift

View workflow job for this annotation

GitHub Actions / Swift 6.0.2 (ubuntu-22.04)

Trailing Whitespace Violation: Lines should not have trailing whitespace (trailing_whitespace)
let connection = try ContainerConnection(containerName: containerName,
config: config,
kind: .bedrock,
Expand All @@ -351,14 +359,27 @@ extension ContainerConnection {

private static func containerConfig(
container: BackupConfig.ContainerConfig,
tools: ToolConfig
tools: ToolConfig,
prefixAllContainerNames: Bool
) -> ContainerConnectionConfig {
if let sshConfig = SSHConnectionConfig(validator: tools.hostKeyValidator, config: container) {
if let sshConfig = SSHConnectionConfig(
validator: tools.hostKeyValidator,
config: container,
prefixAllContainerNames: prefixAllContainerNames
) {
return sshConfig
} else if let rconConfig = RCONConnectionConfig(rconPath: tools.rconPath, config: container) {
} else if let rconConfig = RCONConnectionConfig(
rconPath: tools.rconPath,
config: container,
prefixAllContainerNames: prefixAllContainerNames
) {
return rconConfig
} else {
return DockerConnectionConfig(dockerPath: tools.dockerPath, config: container)
return DockerConnectionConfig(
dockerPath: tools.dockerPath,
config: container,
prefixAllContainerNames: prefixAllContainerNames
)
}
}
}
Expand Down
19 changes: 15 additions & 4 deletions Sources/Bedrockifier/Model/World.swift
Original file line number Diff line number Diff line change
Expand Up @@ -227,10 +227,9 @@ extension World {
return try World(url: finalFolder)
}

func backup(to folder: URL) throws -> World {
let timestamp = DateFormatter.backupDateFormatter.string(from: Date())
let backupExtension = fetchBackupExtension()
let fileName = "\(self.name).\(timestamp).\(backupExtension)"
func backup(to folder: URL, prefixContainerName: String?) throws -> World {
let timestamp = Date()
let fileName = makeFilename(timestamp: timestamp, prefixContainerName: prefixContainerName)
let targetFile = folder.appendingPathComponent(fileName)

try FileManager.default.createDirectory(atPath: folder.path, withIntermediateDirectories: true, attributes: nil)
Expand All @@ -247,6 +246,18 @@ extension World {
}
}

private func makeFilename(timestamp: Date, prefixContainerName: String?) -> String {
let timestampString = DateFormatter.backupDateFormatter.string(from: timestamp)
let backupExtension = fetchBackupExtension()
let filename = "\(self.name).\(timestampString).\(backupExtension)"

if let prefix = prefixContainerName {
return "\(prefix).\(filename)"
} else {
return filename
}
}

private func fetchBackupExtension() -> String {
switch self.type {
case .folder:
Expand Down

0 comments on commit 30d550d

Please sign in to comment.