Compare commits
4 commits
dd7b63fc24
...
9178cd5e14
Author | SHA1 | Date | |
---|---|---|---|
flash | 9178cd5e14 | ||
flash | 866bd93afa | ||
flash | b6656506ee | ||
flash | b793af9157 |
|
@ -6,7 +6,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MySql.Data" Version="8.0.26" />
|
||||
<PackageReference Include="MySql.Data" Version="8.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -2,19 +2,10 @@
|
|||
public class Config {
|
||||
public string FileSystemPathV2 { get; set; }
|
||||
|
||||
public string MySqlDumpPathWindows { get; set; } = @"C:\Program Files\MariaDB 10.3\bin\mysqldump.exe";
|
||||
public string MySqlDumpPath { get; set; } = @"mysqldump";
|
||||
public string MySqlHost { get; set; } = @"localhost";
|
||||
public string MySqlUser { get; set; }
|
||||
public string MySqlPass { get; set; }
|
||||
public string MySqlExcludeDatabases { get; set; } = @"mysql information_schema performance_schema";
|
||||
|
||||
public string MisuzuPath { get; set; }
|
||||
|
||||
public string SatoriHost { get; set; }
|
||||
public ushort SatoriPort { get; set; }
|
||||
public string SatoriSecret { get; set; }
|
||||
public string SatoriFormat { get; set; } = @"/msg flash {0}";
|
||||
public bool SatoriErrorsOnly { get; set; } = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,23 +5,17 @@ using System.Diagnostics;
|
|||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace BackupManager {
|
||||
namespace BackupManager
|
||||
{
|
||||
public static class Program {
|
||||
public readonly static Stopwatch sw = new();
|
||||
|
||||
private const string CONFIG_NAME = @"FlashiiBackupManager.v1.xml";
|
||||
|
||||
public static bool IsWindows
|
||||
=> RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||
|
||||
public readonly static DateTimeOffset Startup = DateTimeOffset.UtcNow;
|
||||
|
||||
public static string Basename
|
||||
|
@ -41,10 +35,6 @@ namespace BackupManager {
|
|||
|
||||
private static bool Headless;
|
||||
|
||||
public static string WindowsToUnixPath(this string path) {
|
||||
return IsWindows ? path.Replace('\\', '/') : path;
|
||||
}
|
||||
|
||||
public static Stream ToXml(this object obj, bool pretty = false) {
|
||||
MemoryStream ms = new();
|
||||
XmlSerializer xs = new(obj.GetType());
|
||||
|
@ -101,7 +91,7 @@ namespace BackupManager {
|
|||
UserID = Config.MySqlUser,
|
||||
Password = Config.MySqlPass,
|
||||
CharacterSet = @"utf8mb4",
|
||||
SslMode = MySqlSslMode.None,
|
||||
SslMode = MySqlSslMode.Disabled,
|
||||
};
|
||||
|
||||
List<string> databases = new();
|
||||
|
@ -149,22 +139,6 @@ namespace BackupManager {
|
|||
|
||||
Log($@"MariaDB dump done.");
|
||||
File.Delete(sqldefaults);
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(Config.MisuzuPath)
|
||||
&& Directory.Exists(Config.MisuzuPath)) {
|
||||
Log(@"Filesystem backup...");
|
||||
string mszConfig = Path.Combine(Config.MisuzuPath, @"config/config.ini");
|
||||
|
||||
if(!File.Exists(mszConfig))
|
||||
Error(@"Could not find Misuzu config.");
|
||||
|
||||
string mszStore = Path.Combine(Config.MisuzuPath, @"store");
|
||||
|
||||
if(!Directory.Exists(mszStore))
|
||||
Error(@"Could not find Misuzu storage directory.");
|
||||
|
||||
CreateMisuzuDataBackup(archive, mszConfig, mszStore);
|
||||
}
|
||||
}
|
||||
|
||||
string targetPath = Path.Combine(BackupStore, BackupName);
|
||||
|
@ -173,14 +147,14 @@ namespace BackupManager {
|
|||
|
||||
SaveConfig();
|
||||
sw.Stop();
|
||||
Log($@"Done! Took {sw.Elapsed}.", true);
|
||||
Log($@"Done! Took {sw.Elapsed}.");
|
||||
|
||||
#if DEBUG
|
||||
Console.ReadLine();
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void Log(object line, bool forceSatori = false) {
|
||||
public static void Log(object line) {
|
||||
if(!Headless) {
|
||||
if(sw?.IsRunning == true) {
|
||||
ConsoleColor fg = Console.ForegroundColor;
|
||||
|
@ -191,9 +165,6 @@ namespace BackupManager {
|
|||
|
||||
Console.WriteLine(line);
|
||||
}
|
||||
|
||||
if(forceSatori || (!Headless && !(Config?.SatoriErrorsOnly ?? true)))
|
||||
SatoriBroadcast(line.ToString());
|
||||
}
|
||||
|
||||
public static void Error(object line, int exit = 0x00DEAD00) {
|
||||
|
@ -203,8 +174,6 @@ namespace BackupManager {
|
|||
Console.ResetColor();
|
||||
}
|
||||
|
||||
SatoriBroadcast(line.ToString(), true);
|
||||
|
||||
#if DEBUG
|
||||
Console.ReadLine();
|
||||
#endif
|
||||
|
@ -212,21 +181,6 @@ namespace BackupManager {
|
|||
Environment.Exit(exit);
|
||||
}
|
||||
|
||||
public static void CreateMisuzuDataBackup(ZipArchive archive, string configPath, string storePath) {
|
||||
Log(@"Storing non-volatile Misuzu data...");
|
||||
|
||||
archive.CreateEntryFromFile(configPath, @"misuzu/config/config.ini", CompressionLevel.Optimal);
|
||||
|
||||
string[] storeFiles = Directory.GetFiles(storePath, @"*", SearchOption.AllDirectories);
|
||||
|
||||
foreach(string file in storeFiles)
|
||||
archive.CreateEntryFromFile(
|
||||
file,
|
||||
@"misuzu/store/" + file.Replace(storePath, string.Empty).WindowsToUnixPath().Trim('/'),
|
||||
CompressionLevel.Optimal
|
||||
);
|
||||
}
|
||||
|
||||
public static void CreateDbDump(ZipArchive archive, string defaults, string database) {
|
||||
Log($@"Dumping {database}...");
|
||||
|
||||
|
@ -248,7 +202,7 @@ namespace BackupManager {
|
|||
#endif
|
||||
|
||||
Process p = Process.Start(new ProcessStartInfo {
|
||||
FileName = IsWindows ? Config.MySqlDumpPathWindows : Config.MySqlDumpPath,
|
||||
FileName = Config.MySqlDumpPath,
|
||||
Arguments = mysqldumpArgs.ToString(),
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true,
|
||||
|
@ -260,61 +214,5 @@ namespace BackupManager {
|
|||
|
||||
File.Delete(sqldump);
|
||||
}
|
||||
|
||||
public static void SatoriBroadcast(string text, bool error = false) {
|
||||
if(string.IsNullOrEmpty(text)
|
||||
|| Config == null
|
||||
|| string.IsNullOrWhiteSpace(Config.SatoriHost)
|
||||
|| string.IsNullOrWhiteSpace(Config.SatoriSecret)
|
||||
|| Config.SatoriPort < 1)
|
||||
return;
|
||||
|
||||
IPAddress ip = null;
|
||||
|
||||
try {
|
||||
ip = IPAddress.Parse(Config.SatoriHost);
|
||||
} catch {
|
||||
try {
|
||||
// forcing IPv4 here, it seems to explode with IPv6 and i don't really want to figure out why
|
||||
ip = Dns.GetHostAddresses(Config.SatoriHost).FirstOrDefault(x => x.AddressFamily == AddressFamily.InterNetwork);
|
||||
} catch {
|
||||
ip = null;
|
||||
}
|
||||
}
|
||||
|
||||
if(ip == null)
|
||||
return;
|
||||
|
||||
EndPoint endPoint = new IPEndPoint(ip, Config.SatoriPort);
|
||||
|
||||
StringBuilder textBuilder = new();
|
||||
textBuilder.AppendFormat(@"[b]Backup System[/b] [{0}]: ", Environment.MachineName);
|
||||
|
||||
if(error)
|
||||
textBuilder.Append(@"[color=red]");
|
||||
|
||||
textBuilder.Append(text);
|
||||
|
||||
if(error)
|
||||
textBuilder.Append(@"[/color]");
|
||||
|
||||
text = string.Format(Config.SatoriFormat, textBuilder);
|
||||
|
||||
byte[] opcode = new byte[1] { 1 };
|
||||
byte[] hash;
|
||||
using(HMACSHA256 hmac = new(Encoding.UTF8.GetBytes(Config.SatoriSecret))) {
|
||||
hmac.TransformBlock(opcode, 0, opcode.Length, null, 0);
|
||||
hash = Encoding.UTF8.GetBytes(text);
|
||||
hmac.TransformFinalBlock(hash, 0, hash.Length);
|
||||
hash = hmac.Hash;
|
||||
}
|
||||
|
||||
using Socket sock = new(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
|
||||
sock.NoDelay = sock.Blocking = true;
|
||||
sock.Connect(endPoint);
|
||||
sock.Send(hash);
|
||||
sock.Send(opcode);
|
||||
sock.Send(Encoding.UTF8.GetBytes(text));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Reference in a new issue