private static async Task BackupHardLinks(BackupParams backupParams, IHardLinkHelper helper, SshClient sshClient) { Console.CursorVisible = false; var sw = System.Diagnostics.Stopwatch.StartNew(); try { using (var vssHelper = new VssHelper(new DirectoryInfo(backupParams.RootDit).Root.Name)) { Console.WriteLine("Creating VSS snapshot..."); var actualRoot = vssHelper.CreateSnapshot() ? vssHelper.GetSnapshotFilePath(backupParams.RootDit) : backupParams.RootDit; string[] TargetFilesEnumerator(string backupPathWin) { var backupPathUnix = PathHelpers.NormalizePathUnix(backupPathWin.Replace(backupParams.RemoteRootWin, backupParams.RemoteRootUnix)); var cmd = sshClient.RunCommand($"find \"{backupPathUnix}\" -type f"); var result = cmd.Result; var es = cmd.ExitStatus; if (es != 0 || string.IsNullOrEmpty(result)) { return(new string[0]); } var files = result.Split(new[] { "\r", "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries) .Where(x => !x.EndsWith(".bkp/info.txt")) .Select(x => PathHelpers.NormalizePathWin(x.Replace(backupParams.RemoteRootUnix, backupParams.RemoteRootWin))) .ToArray(); return(files); } var engine = new HardLinkBackupEngine(actualRoot, backupParams.Sources, backupParams.BackupRoots, backupParams.RemoteRootWin, true, helper, TargetFilesEnumerator); engine.Log += WriteLog; engine.LogExt += WriteLogExt; await engine.DoBackup(); } sw.Stop(); Console.WriteLine($"Done in {sw.Elapsed:hh\\:mm\\:ss}"); } catch (Exception e) { sw.Stop(); Console.WriteLine($"Failed (operation lasted {sw.Elapsed:hh\\:mm\\:ss})"); Console.WriteLine(e); } finally { sw.Stop(); Console.CursorVisible = true; } }
private static async Task Backup(BackupParams backupParams) { if (backupParams.Sources.Length == 0) { Console.WriteLine("Source folder is not specified"); return; } /*if (!Directory.Exists(backupParams.Source)) * { * Console.WriteLine("Source folder does not exist"); * return; * }*/ var targetWin = backupParams.RemoteRootWin; if (string.IsNullOrEmpty(targetWin)) { Console.WriteLine("Target folder is not specified"); return; } _logFileName = backupParams.LogFile; IHardLinkHelper hardLinkHelper; var networkConnection = Helpers.GetDummyDisposable(); SshClient sshClient = null; if (!backupParams.IsSshDefined) { hardLinkHelper = new WinHardLinkHelper(); } else { Console.WriteLine($"Connecting to {backupParams.SshLogin}@{backupParams.SshHost}:{backupParams.SshPort}..."); var ci = new ConnectionInfo(backupParams.SshHost, backupParams.SshPort ?? throw new Exception("SSH port not defined"), backupParams.SshLogin, new PasswordAuthenticationMethod(backupParams.SshLogin, backupParams.SshPassword)); sshClient = new SshClient(ci); sshClient.Connect(); hardLinkHelper = new NetShareSshHardLinkHelper(backupParams.RemoteRootWin, backupParams.RemoteRootUnix, sshClient); networkConnection = new NetworkConnection($@"\\{backupParams.SshHost}", new NetworkCredential(backupParams.SshLogin, backupParams.SshPassword)); } using (networkConnection) using (sshClient ?? Helpers.GetDummyDisposable()) { if (!Directory.Exists(targetWin)) { Console.WriteLine("Target folder does not exist"); return; } try { var testFile = Path.Combine(targetWin, "write_access_test.txt"); if (File.Exists(testFile)) { File.Delete(testFile); } File.WriteAllText(testFile, "Write access test file"); File.Delete(testFile); } catch (Exception e) { Console.WriteLine("Failed to write in target directory:\r\n" + e.Message); return; } await BackupHardLinks(backupParams, hardLinkHelper, sshClient); } }