172 lines
4.4 KiB
C#
172 lines
4.4 KiB
C#
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 = BaseDirectory + "/piscal_manager.sh";
|
|
private readonly PasswordConnectionInfo _connectionInfo;
|
|
|
|
private const string StatusSuccess = "success";
|
|
private const string StatusRunning = "running";
|
|
private const string StatusNotStarted = "not started";
|
|
private const string StatusError = "error";
|
|
|
|
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 RunLeafInputFile(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} -p {file.PhotosyntheticType}";
|
|
var command = ssh.CreateCommand(commandText);
|
|
command.Execute();
|
|
ssh.Disconnect();
|
|
|
|
if (command.ExitStatus != 0)
|
|
throw new PiscalClientException(command.Result);
|
|
|
|
Console.Write(command.Result);
|
|
}
|
|
}
|
|
|
|
public PiscalStatus GetLeafInputFileStatus(PiscalLeafInputFile file)
|
|
{
|
|
var statusRaw = GetLeafInputStatusRaw(file);
|
|
|
|
switch (statusRaw[0])
|
|
{
|
|
case StatusRunning:
|
|
return PiscalStatus.Running;
|
|
case StatusSuccess:
|
|
return PiscalStatus.Success;
|
|
case StatusNotStarted:
|
|
return PiscalStatus.NotStarted;
|
|
default:
|
|
return PiscalStatus.Error;
|
|
}
|
|
}
|
|
|
|
private string[] GetLeafInputStatusRaw(PiscalLeafInputFile file)
|
|
{
|
|
using (var ssh = GetSshClient())
|
|
{
|
|
ssh.Connect();
|
|
var commandText = $"{RemoteScriptPath} -d {file.DirectoryName} -s";
|
|
var command = ssh.CreateCommand(commandText);
|
|
command.Execute();
|
|
ssh.Disconnect();
|
|
|
|
if (command.ExitStatus != 0)
|
|
throw new PiscalClientException(command.Result);
|
|
|
|
return command.Result
|
|
.SplitNewLine()
|
|
.Where(s => s.Length > 0)
|
|
.Select(s => s.Trim()).ToArray();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the leaf output from piscal, only run on if result status is success
|
|
/// </summary>
|
|
public IEnumerable<PiscalLeafOutputFile> RetrieveLeafOutput(PiscalLeafInputFile file)
|
|
{
|
|
// get output files
|
|
var status = GetLeafInputStatusRaw(file);
|
|
if (status[0] != StatusSuccess)
|
|
throw new PiscalClientException("output not available, status is " + status[0]);
|
|
|
|
var filePaths = status.Skip(1);
|
|
|
|
using (var scp = GetScpClient())
|
|
{
|
|
scp.Connect();
|
|
foreach (var filePath in filePaths)
|
|
{
|
|
using (var stream = new MemoryStream())
|
|
{
|
|
scp.Download(filePath, stream);
|
|
yield return
|
|
new PiscalLeafOutputFile
|
|
{
|
|
Contents = stream.ToArray(),
|
|
Filename = filePath.FilenameFromPath(),
|
|
DirectoryName = file.DirectoryName
|
|
};
|
|
}
|
|
}
|
|
|
|
scp.Disconnect();
|
|
}
|
|
}
|
|
|
|
public string GetErrorMessage(PiscalLeafInputFile file)
|
|
{
|
|
var status = GetLeafInputStatusRaw(file);
|
|
if (status[0] != StatusError)
|
|
return string.Empty;
|
|
|
|
var errorLines = status.Skip(1).ToArray();
|
|
return errorLines.Join(Environment.NewLine);
|
|
}
|
|
|
|
public void CleanupLeafProcess(PiscalLeafInputFile file)
|
|
{
|
|
var status = GetLeafInputStatusRaw(file);
|
|
if (status[0] == StatusRunning)
|
|
throw new PiscalClientException("Trying to cleanup a running process");
|
|
|
|
using (var ssh = GetSshClient())
|
|
{
|
|
ssh.Connect();
|
|
var commandText = $"{RemoteScriptPath} -d {file.DirectoryName} -c";
|
|
var command = ssh.CreateCommand(commandText);
|
|
command.Execute();
|
|
ssh.Disconnect();
|
|
|
|
if (command.ExitStatus != 0)
|
|
throw new PiscalClientException(command.Error);
|
|
}
|
|
}
|
|
}
|
|
} |