diff --git a/Jenkinsfile b/Jenkinsfile
index e554cf4..98d7c36 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -31,7 +31,7 @@ node {
stage('Build') {
currentBuild.description = bat(returnStdout: true, script: '@powershell -File Versioning/version.ps1').trim()
- if (env.BRANCH_NAME == "master") {
+ if (env.BRANCH_NAME == "master" || enb.BRANCH_NAME == "Patron") {
buildMode = "Release"
} else {
buildMode = "Debug"
diff --git a/Torch.API/InformationalVersion.cs b/Torch.API/InformationalVersion.cs
index 5310234..ef80213 100644
--- a/Torch.API/InformationalVersion.cs
+++ b/Torch.API/InformationalVersion.cs
@@ -7,36 +7,36 @@ using System.Threading.Tasks;
namespace Torch.API
{
///
- /// Version in the form v#.#.#.#-info
+ /// Version in the form v#.#.#.#-branch
///
public class InformationalVersion
{
public Version Version { get; set; }
- public string[] Information { get; set; }
+ public string Branch { get; set; }
public static bool TryParse(string input, out InformationalVersion version)
{
version = default(InformationalVersion);
var trim = input.TrimStart('v');
- var info = trim.Split('-');
+ var info = trim.Split(new[]{'-'}, 2);
if (!Version.TryParse(info[0], out Version result))
return false;
version = new InformationalVersion { Version = result };
if (info.Length > 1)
- version.Information = info.Skip(1).ToArray();
-
+ version.Branch = info[1];
+
return true;
}
///
public override string ToString()
{
- if (Information == null || Information.Length == 0)
+ if (Branch == null)
return $"v{Version}";
- return $"v{Version}-{string.Join("-", Information)}";
+ return $"v{Version}-{string.Join("-", Branch)}";
}
public static explicit operator InformationalVersion(Version v)
@@ -48,5 +48,15 @@ namespace Torch.API
{
return v.Version;
}
+
+ public static bool operator >(InformationalVersion lhs, InformationalVersion rhs)
+ {
+ return lhs.Version > rhs.Version;
+ }
+
+ public static bool operator <(InformationalVersion lhs, InformationalVersion rhs)
+ {
+ return lhs.Version < rhs.Version;
+ }
}
}
diff --git a/Torch.API/Torch.API.csproj b/Torch.API/Torch.API.csproj
index 987b979..aa0dea8 100644
--- a/Torch.API/Torch.API.csproj
+++ b/Torch.API/Torch.API.csproj
@@ -193,6 +193,7 @@
+
diff --git a/Torch.API/WebAPI/JenkinsQuery.cs b/Torch.API/WebAPI/JenkinsQuery.cs
new file mode 100644
index 0000000..5c9ea1c
--- /dev/null
+++ b/Torch.API/WebAPI/JenkinsQuery.cs
@@ -0,0 +1,133 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using NLog;
+
+namespace Torch.API.WebAPI
+{
+ public class JenkinsQuery
+ {
+ private const string BRANCH_QUERY = "https://build.torchapi.net/job/Torch/job/Torch/job/{0}/" + API_PATH;
+ private const string ARTIFACT_PATH = "artifact/bin/torch-server.zip";
+ private const string API_PATH = "api/json";
+
+ private static readonly Logger Log = LogManager.GetCurrentClassLogger();
+
+ private static JenkinsQuery _instance;
+ public static JenkinsQuery Instance => _instance ?? (_instance = new JenkinsQuery());
+ private HttpClient _client;
+
+ private JenkinsQuery()
+ {
+ _client = new HttpClient();
+ }
+
+ public async Task GetLatestVersion(string branch)
+ {
+#if DEBUG
+ branch = "master";
+#endif
+ var h = await _client.GetAsync(string.Format(BRANCH_QUERY, branch));
+ if (!h.IsSuccessStatusCode)
+ {
+ Log.Error($"Branch query failed with code {h.StatusCode}");
+ if(h.StatusCode == HttpStatusCode.NotFound)
+ Log.Error("This likely means you're trying to update a branch that is not public on Jenkins. Sorry :(");
+ return null;
+ }
+
+ string r = await h.Content.ReadAsStringAsync();
+
+ BranchResponse response;
+ try
+ {
+ response = JsonConvert.DeserializeObject(r);
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Failed to deserialize branch response!");
+ return null;
+ }
+
+ h = await _client.GetAsync($"{response.LastStableBuild.URL}{API_PATH}");
+ if (!h.IsSuccessStatusCode)
+ {
+ Log.Error($"Job query failed with code {h.StatusCode}");
+ return null;
+ }
+
+ r = await h.Content.ReadAsStringAsync();
+
+ Job job;
+ try
+ {
+ job = JsonConvert.DeserializeObject(r);
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Failed to deserialize job response!");
+ return null;
+ }
+ return job;
+ }
+
+ public async Task DownloadRelease(Job job, string path)
+ {
+ var h = await _client.GetAsync(job.URL + ARTIFACT_PATH);
+ if (!h.IsSuccessStatusCode)
+ {
+ Log.Error($"Job download failed with code {h.StatusCode}");
+ return false;
+ }
+ var s = await h.Content.ReadAsStreamAsync();
+ using (var fs = new FileStream(path, FileMode.Create))
+ {
+ await s.CopyToAsync(fs);
+ await fs.FlushAsync();
+ }
+ return true;
+ }
+
+ }
+
+ public class BranchResponse
+ {
+ public string Name;
+ public string URL;
+ public Build LastBuild;
+ public Build LastStableBuild;
+ }
+
+ public class Build
+ {
+ public int Number;
+ public string URL;
+ }
+
+ public class Job
+ {
+ public int Number;
+ public bool Building;
+ public string Description;
+ public string Result;
+ public string URL;
+ private InformationalVersion _version;
+
+ public InformationalVersion Version
+ {
+ get
+ {
+ if (_version == null)
+ InformationalVersion.TryParse(Description, out _version);
+
+ return _version;
+ }
+ }
+ }
+}
diff --git a/Torch/Managers/FilesystemManager.cs b/Torch/Managers/FilesystemManager.cs
index b0fdcb1..254c9a0 100644
--- a/Torch/Managers/FilesystemManager.cs
+++ b/Torch/Managers/FilesystemManager.cs
@@ -22,9 +22,8 @@ namespace Torch.Managers
public FilesystemManager(ITorchBase torchInstance) : base(torchInstance)
{
- var temp = Path.Combine(Path.GetTempPath(), "Torch");
- TempDirectory = Directory.CreateDirectory(temp).FullName;
var torch = new FileInfo(typeof(FilesystemManager).Assembly.Location).Directory.FullName;
+ TempDirectory = Directory.CreateDirectory(Path.Combine(torch, "tmp")).FullName;
TorchDirectory = torch;
ClearTemp();
@@ -39,13 +38,16 @@ namespace Torch.Managers
///
/// Move the given file (if it exists) to a temporary directory that will be cleared the next time the application starts.
///
- public void SoftDelete(string file)
+ public void SoftDelete(string path, string file)
{
- if (!File.Exists(file))
+ string source = Path.Combine(path, file);
+ if (!File.Exists(source))
return;
var rand = Path.GetRandomFileName();
var dest = Path.Combine(TempDirectory, rand);
- File.Move(file, dest);
+ File.Move(source, rand);
+ string rsource = Path.Combine(path, rand);
+ File.Move(rsource, dest);
}
}
}
diff --git a/Torch/Managers/UpdateManager.cs b/Torch/Managers/UpdateManager.cs
index bdaaf32..de2e73c 100644
--- a/Torch/Managers/UpdateManager.cs
+++ b/Torch/Managers/UpdateManager.cs
@@ -10,8 +10,8 @@ using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using NLog;
-using Octokit;
using Torch.API;
+using Torch.API.WebAPI;
namespace Torch.Managers
{
@@ -21,12 +21,11 @@ namespace Torch.Managers
public class UpdateManager : Manager
{
private Timer _updatePollTimer;
- private GitHubClient _gitClient = new GitHubClient(new ProductHeaderValue("Torch"));
private string _torchDir = new FileInfo(typeof(UpdateManager).Assembly.Location).DirectoryName;
private Logger _log = LogManager.GetCurrentClassLogger();
[Dependency]
private FilesystemManager _fsManager;
-
+
public UpdateManager(ITorchBase torchInstance) : base(torchInstance)
{
//_updatePollTimer = new Timer(TimerElapsed, this, TimeSpan.Zero, TimeSpan.FromMinutes(5));
@@ -42,49 +41,36 @@ namespace Torch.Managers
{
CheckAndUpdateTorch();
}
-
- private async Task> TryGetLatestArchiveUrl(string owner, string name)
- {
- try
- {
- var latest = await _gitClient.Repository.Release.GetLatest(owner, name).ConfigureAwait(false);
- if (latest == null)
- return new Tuple(new Version(), null);
-
- var zip = latest.Assets.FirstOrDefault(x => x.Name.Contains(".zip"));
- if (zip == null)
- _log.Error($"Latest release of {owner}/{name} does not contain a zip archive.");
- if (!latest.TagName.TryExtractVersion(out Version version))
- _log.Error($"Unable to parse version tag for {owner}/{name}");
- return new Tuple(version, zip?.BrowserDownloadUrl);
- }
- catch (Exception e)
- {
- _log.Error($"An error occurred getting release information for '{owner}/{name}'");
- _log.Error(e);
- return default(Tuple);
- }
- }
-
+
private async void CheckAndUpdateTorch()
{
- // Doesn't work properly or reliably, TODO update when Jenkins is fully configured
- return;
-
if (!Torch.Config.GetTorchUpdates)
return;
try
{
- var releaseInfo = await TryGetLatestArchiveUrl("TorchAPI", "Torch").ConfigureAwait(false);
- if (releaseInfo.Item1 > Torch.TorchVersion)
+ var job = await JenkinsQuery.Instance.GetLatestVersion(Torch.TorchVersion.Branch);
+ if (job == null)
{
- _log.Warn($"Updating Torch from version {Torch.TorchVersion} to version {releaseInfo.Item1}");
+ _log.Info("Failed to fetch latest version.");
+ return;
+ }
+
+ _log.Info($"Clearing tmp directory at {_fsManager.TempDirectory}");
+
+ if (job.Version > Torch.TorchVersion)
+ {
+ _log.Warn($"Updating Torch from version {Torch.TorchVersion} to version {job.Version}");
var updateName = Path.Combine(_fsManager.TempDirectory, "torchupdate.zip");
- new WebClient().DownloadFile(new Uri(releaseInfo.Item2), updateName);
+ //new WebClient().DownloadFile(new Uri(releaseInfo.Item2), updateName);
+ if (!await JenkinsQuery.Instance.DownloadRelease(job, updateName))
+ {
+ _log.Warn("Failed to download new release!");
+ return;
+ }
UpdateFromZip(updateName, _torchDir);
File.Delete(updateName);
- _log.Warn($"Torch version {releaseInfo.Item1} has been installed, please restart Torch to finish the process.");
+ _log.Warn($"Torch version {job.Version} has been installed, please restart Torch to finish the process.");
}
else
{
@@ -106,10 +92,11 @@ namespace Torch.Managers
{
_log.Debug($"Unzipping {file.FullName}");
var targetFile = Path.Combine(extractPath, file.FullName);
- _fsManager.SoftDelete(targetFile);
+ _fsManager.SoftDelete(extractPath, file.FullName);
+ file.ExtractToFile(targetFile, true);
}
- zip.ExtractToDirectory(extractPath);
+ //zip.ExtractToDirectory(extractPath); //throws exceptions sometimes?
}
}
diff --git a/Torch/Plugins/PluginManager.cs b/Torch/Plugins/PluginManager.cs
index df10ef2..85d00e9 100644
--- a/Torch/Plugins/PluginManager.cs
+++ b/Torch/Plugins/PluginManager.cs
@@ -10,7 +10,6 @@ using System.Reflection;
using System.Threading.Tasks;
using System.Xml.Serialization;
using NLog;
-using Octokit;
using Torch.API;
using Torch.API.Managers;
using Torch.API.Plugins;
@@ -24,7 +23,6 @@ namespace Torch.Managers
///
public class PluginManager : Manager, IPluginManager
{
- private GitHubClient _gitClient = new GitHubClient(new ProductHeaderValue("Torch"));
private static Logger _log = LogManager.GetCurrentClassLogger();
private const string MANIFEST_NAME = "manifest.xml";
public readonly string PluginDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins");
@@ -145,45 +143,45 @@ namespace Torch.Managers
Parallel.ForEach(pluginItems, async item =>
{
PluginManifest manifest = null;
- try
- {
- var path = Path.Combine(PluginDir, item);
- var isZip = item.EndsWith(".zip", StringComparison.CurrentCultureIgnoreCase);
- manifest = isZip ? GetManifestFromZip(path) : GetManifestFromDirectory(path);
- if (manifest == null)
- {
- _log.Warn($"Item '{item}' is missing a manifest, skipping update check.");
- return;
- }
+ //try
+ //{
+ // var path = Path.Combine(PluginDir, item);
+ // var isZip = item.EndsWith(".zip", StringComparison.CurrentCultureIgnoreCase);
+ // manifest = isZip ? GetManifestFromZip(path) : GetManifestFromDirectory(path);
+ // if (manifest == null)
+ // {
+ // _log.Warn($"Item '{item}' is missing a manifest, skipping update check.");
+ // return;
+ // }
- manifest.Version.TryExtractVersion(out Version currentVersion);
- var latest = await GetLatestArchiveAsync(manifest.Repository).ConfigureAwait(false);
+ // manifest.Version.TryExtractVersion(out Version currentVersion);
+ // var latest = await GetLatestArchiveAsync(manifest.Repository).ConfigureAwait(false);
- if (currentVersion == null || latest.Item1 == null)
- {
- _log.Error($"Error parsing version from manifest or GitHub for plugin '{manifest.Name}.'");
- return;
- }
+ // if (currentVersion == null || latest.Item1 == null)
+ // {
+ // _log.Error($"Error parsing version from manifest or GitHub for plugin '{manifest.Name}.'");
+ // return;
+ // }
- if (latest.Item1 <= currentVersion)
- {
- _log.Debug($"{manifest.Name} {manifest.Version} is up to date.");
- return;
- }
+ // if (latest.Item1 <= currentVersion)
+ // {
+ // _log.Debug($"{manifest.Name} {manifest.Version} is up to date.");
+ // return;
+ // }
- _log.Info($"Updating plugin '{manifest.Name}' from {currentVersion} to {latest.Item1}.");
- await UpdatePluginAsync(path, latest.Item2).ConfigureAwait(false);
- count++;
- }
- catch (NotFoundException)
- {
- _log.Warn($"GitHub repository not found for {manifest.Name}");
- }
- catch (Exception e)
- {
- _log.Warn($"An error occurred updating the plugin {manifest.Name}.");
- _log.Warn(e);
- }
+ // _log.Info($"Updating plugin '{manifest.Name}' from {currentVersion} to {latest.Item1}.");
+ // await UpdatePluginAsync(path, latest.Item2).ConfigureAwait(false);
+ // count++;
+ //}
+ //catch (NotFoundException)
+ //{
+ // _log.Warn($"GitHub repository not found for {manifest.Name}");
+ //}
+ //catch (Exception e)
+ //{
+ // _log.Warn($"An error occurred updating the plugin {manifest.Name}.");
+ // _log.Warn(e);
+ //}
});
_log.Info($"Updated {count} plugins.");
@@ -193,20 +191,21 @@ namespace Torch.Managers
{
try
{
- var split = repository.Split('/');
- var latest = await _gitClient.Repository.Release.GetLatest(split[0], split[1]).ConfigureAwait(false);
- if (!latest.TagName.TryExtractVersion(out Version latestVersion))
- {
- _log.Error($"Unable to parse version tag for the latest release of '{repository}.'");
- }
+ //var split = repository.Split('/');
+ //var latest = await _gitClient.Repository.Release.GetLatest(split[0], split[1]).ConfigureAwait(false);
+ //if (!latest.TagName.TryExtractVersion(out Version latestVersion))
+ //{
+ // _log.Error($"Unable to parse version tag for the latest release of '{repository}.'");
+ //}
- var zipAsset = latest.Assets.FirstOrDefault(x => x.Name.Contains(".zip", StringComparison.CurrentCultureIgnoreCase));
- if (zipAsset == null)
- {
- _log.Error($"Unable to find archive for the latest release of '{repository}.'");
- }
+ //var zipAsset = latest.Assets.FirstOrDefault(x => x.Name.Contains(".zip", StringComparison.CurrentCultureIgnoreCase));
+ //if (zipAsset == null)
+ //{
+ // _log.Error($"Unable to find archive for the latest release of '{repository}.'");
+ //}
- return new Tuple(latestVersion, zipAsset?.BrowserDownloadUrl);
+ //return new Tuple(latestVersion, zipAsset?.BrowserDownloadUrl);
+ return null;
}
catch (Exception e)
{
diff --git a/Torch/Torch.csproj b/Torch/Torch.csproj
index 6254956..928ddce 100644
--- a/Torch/Torch.csproj
+++ b/Torch/Torch.csproj
@@ -36,7 +36,9 @@
1591
-
+
+
+
..\packages\ControlzEx.3.0.2.4\lib\net45\ControlzEx.dll
@@ -61,9 +63,6 @@
..\packages\NLog.4.4.12\lib\net45\NLog.dll
True
-
- ..\packages\Octokit.0.24.0\lib\net45\Octokit.dll
-
diff --git a/Torch/packages.config b/Torch/packages.config
index 3bc7aff..e77c03c 100644
--- a/Torch/packages.config
+++ b/Torch/packages.config
@@ -5,7 +5,6 @@
-