namespace MaksIT.LTO.Backup.Shared.Models;
public abstract class PathBase {
public required string Path { get; set; }
}
public class LocalPath : PathBase { }
public class PasswordCredentials {
public required string Username { get; set; }
public required string Password { get; set; }
}
public class RemotePath : PathBase {
public PasswordCredentials? PasswordCredentials { get; set; }
public required string Protocol { get; set; }
}
public class WorkingFolder {
public LocalPath? LocalPath { get; set; }
public RemotePath? RemotePath { get; set; }
}
///
/// UScheduler-compatible calendar (empty month/weekday = all; times are UTC HH:mm).
///
public class BackupSchedule {
public List RunMonth { get; set; } = [];
public List RunWeekday { get; set; } = [];
public List RunTime { get; set; } = [];
public int MinIntervalMinutes { get; set; } = 10;
}
///
/// Cartridge associated with a library backup job for rotation by last-used time.
///
public class BackupTape {
public required string Barcode { get; set; }
public DateTimeOffset? LastUsedUtc { get; set; }
}
///
/// Ordered wave of backup jobs sharing one schedule (Worker runs aggregations, not per-job calendars).
///
public class BackupAggregation {
public required string Name { get; set; }
public List JobNames { get; set; } = [];
public BackupSchedule? Schedule { get; set; }
public bool Disabled { get; set; }
public DateTimeOffset? LastRunUtc { get; set; }
}
public class BackupItem {
public required string Name { get; set; }
///
/// Standalone / single-tape MAM label. Library jobs use .
///
public string Barcode { get; set; } = string.Empty;
public required WorkingFolder Source { get; set; }
public required WorkingFolder Destination { get; set; }
public required string LTOGen { get; set; }
///
/// Overwrite replaces the cartridge from BOT. Append adds another FM-separated set.
///
public string WriteMode { get; set; } = BackupWriteModes.Overwrite.Name;
///
/// Library media pool (oldest first).
///
public List Tapes { get; set; } = [];
///
/// When true, aggregations skip this job.
///
public bool Disabled { get; set; }
}
public class EmulatorLibraryOptions {
public int SlotCount { get; set; } = 24;
public int DriveCount { get; set; } = 2;
public int IePortCount { get; set; } = 1;
}
public class EmulatorOptions {
public string DataDirectory { get; set; } = ".\\emulator-data";
public EmulatorLibraryOptions Library { get; set; } = new();
}
public class ServiceOptions {
public string ServiceName { get; set; } = "MaksIT.LTO.Backup";
public string Description { get; set; } = "Schedules LTO library backup aggregations using barcode media pools.";
///
/// Optional path to the Worker executable for UI lifecycle control. Empty = resolve next to UI / default name.
///
public string ExecutablePath { get; set; } = string.Empty;
}
public class Configuration {
public string DeviceMode { get; set; } = DeviceModes.Physical.Name;
///
/// StandaloneDrive = tape drive only. TapeLibrary = changer inventory/move + drive bays.
///
public string Topology { get; set; } = DeviceTopologies.StandaloneDrive.Name;
public string TapePath { get; set; } = "\\\\.\\Tape0";
public string LibraryPath { get; set; } = "\\\\.\\Changer0";
public int WriteDelay { get; set; } = 100;
///
/// When true, restore aborts on the first file checksum mismatch instead of only logging a warning.
///
public bool FailFastOnChecksumMismatch { get; set; } = true;
public List Backups { get; set; } = [];
public List Aggregations { get; set; } = [];
public EmulatorOptions Emulator { get; set; } = new();
public ServiceOptions Service { get; set; } = new();
public bool IsEmulated =>
DeviceModes.Matches(DeviceMode, DeviceModes.Emulated);
public bool IsTapeLibrary =>
DeviceTopologies.Matches(Topology, DeviceTopologies.TapeLibrary);
public bool IsStandaloneDrive =>
DeviceTopologies.Matches(Topology, DeviceTopologies.StandaloneDrive);
}