using System; using System.Collections.Generic; using System.Data.Common; using System.IO; using System.Linq; using LeafWeb.Core.Utility; using Renci.SshNet; namespace LeafWeb.Core.Remote { public class PiscalSshClient : IPiscalClient { private const string BaseDirectory = "./LeafWeb"; private const string RemoteScriptPath = "./piscal_manager.sh"; private readonly PasswordConnectionInfo _connectionInfo; public PiscalSshClient(string connectionString) { var conn = new DbConnectionStringBuilder {ConnectionString = connectionString}; var host = conn["host"] as string; var username = conn["username"] as string; var password = conn["password"] as string; _connectionInfo = new PasswordConnectionInfo(host, username, password); } private SshClient GetSshClient() { return new SshClient(_connectionInfo); } private ScpClient GetScpClient() { return new ScpClient(_connectionInfo); } public void SubmitLeafInputFile(PiscalLeafInputFile file) { var inputPath = $"{BaseDirectory}/{file.DirectoryName}/{file.Filename}"; // copy file using (var scp = GetScpClient()) using (var stream = new MemoryStream(file.Contents)) { Console.WriteLine(inputPath); scp.Connect(); scp.Upload(stream, inputPath); scp.Disconnect(); } // begin processing using (var ssh = GetSshClient()) { ssh.Connect(); var commandText = $"{RemoteScriptPath} -d {file.DirectoryName} -f {file.Filename}"; var exeCommand = ssh.CreateCommand(commandText); exeCommand.Execute(); ssh.Disconnect(); Console.Write(exeCommand.Result); if (exeCommand.ExitStatus != 0) throw new PiscalClientException(exeCommand.Error); } } public PiscalStatus GetLeafInputStatus(PiscalLeafInputFile file) { using (var ssh = GetSshClient()) { ssh.Connect(); var commandText = $"{RemoteScriptPath} -d {file.DirectoryName} -s"; var exeCommand = ssh.CreateCommand(commandText); exeCommand.Execute(); ssh.Disconnect(); Console.Write(exeCommand.Result); } return PiscalStatus.Success; } public IEnumerable RetrieveLeafInputResult(PiscalLeafInputFile file) { var outputDirectory = $"{BaseDirectory}/{file.DirectoryName}"; string[] filenames; // get output files using (var ssh = GetSshClient()) { ssh.Connect(); var commandText = $"ls -1 {outputDirectory}"; var lsCommand = ssh.CreateCommand(commandText); lsCommand.Execute(); ssh.Disconnect(); filenames = lsCommand.Result.SplitNewLine().Where(s => s.Length > 0).Select(s => s.Trim()).ToArray(); Console.Write(lsCommand.Result); } using (var scp = GetScpClient()) { scp.Connect(); foreach (var filename in filenames) { using (var stream = new MemoryStream()) { var filePath = $"{BaseDirectory}/{file.DirectoryName}/{filename}"; scp.Download(filePath, stream); yield return new PiscalLeafOutputFile {Contents = stream.ToArray(), Filename = filename}; } } scp.Disconnect(); } } } }