先添加更新程序用于更新IoTNode,完成后再在IoTNode中添加手动调用的更新"更新程序"的方法

更新"更新程序"时,确保IoTNode的版本和服务端上iotnode.xml里的版本号是一致的,这样可以避免冲突;开始检测更新时就关闭更新程序,更新结束后再启动


Former-commit-id: 67d6137cc0ac6b1a46f4b72201daf8b5e84e8c41
Former-commit-id: 7c752e3a9b1cd1775d43acd8e1dc17ee356b3afa
TSXN
wanggang 5 years ago
parent 6fb2dc5a6e
commit 3b7924d122

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<app>
<version>1.0.0.20082401</version>
<checksum></checksum>
</app>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8" ?>
<app>
<version>1.0.0.20082501</version>
<checksum>b67172948390b8594382cec333498b0905bbdf0fa70f32c3882d7dbc07d745ed899be55bf90f460d63caf12d3924d7384bb0722a264f7b2184e167b1b63397c0</checksum>
</app>

@ -1,43 +1,13 @@
using CookComputing.XmlRpc;
using Microsoft.AspNetCore.Mvc;
using System.Net;
using System.Net.Http;
using Microsoft.AspNetCore.Mvc;
using System.Reflection;
namespace IoTDameon.Controllers
{
public class HomeController : Controller
{
private IHttpClientFactory _httpClientFactory;
public HomeController(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
public IActionResult Index()
{
this.Process();
return Content("");
}
private void Process(bool stop = false)
{
try
{
var proxy = XmlRpcProxyGen.Create<ISupervisorService>();
proxy.Url = "http://192.168.1.3:9001/RPC2";
proxy.Credentials = new NetworkCredential("usr", "pwd");
var result = stop ? proxy.stopProcess("iotnode") : proxy.startProcess("iotnode");
}
catch (XmlRpcFaultException ex)
{
//start:60 stop:70
if (ex.FaultCode != 60 && ex.FaultCode != 70)
{
throw ex;
}
}
return GetVersion();
}
public IActionResult GetVersion()

@ -1,19 +0,0 @@
using CookComputing.XmlRpc;
namespace IoTDameon.Controllers
{
public interface ISupervisorService : IXmlRpcProxy
{
[XmlRpcMethod("supervisor.getAllProcessInfo")]
XmlRpcStruct getAllProcessInfo();
[XmlRpcMethod("supervisor.getProcessInfo")]//result["statename"]: "RUNNING" or "STOPPED"
XmlRpcStruct getProcessInfo(string name);
[XmlRpcMethod("supervisor.startProcess")]
bool startProcess(string name);
[XmlRpcMethod("supervisor.stopProcess")]
bool stopProcess(string name);
}
}

@ -1,6 +1,6 @@
using CookComputing.XmlRpc;
namespace IoTNode.Services
namespace IoTDameon
{
public interface ISupervisorService : IXmlRpcProxy
{

@ -25,7 +25,7 @@ namespace IoTDameon
builder.SetIsOriginAllowed(o => true).AllowAnyMethod().AllowAnyHeader().AllowCredentials();
})
);
services.AddHostedService<UpdateIoTNodeService>();
services.AddHttpClient();
services.AddControllersWithViews();

@ -15,17 +15,18 @@ using System.Threading;
using System.Threading.Tasks;
using System.Xml;
namespace IoTNode.Services
namespace IoTDameon
{
public class UpdateDameonService : BackgroundService
public class UpdateIoTNodeService : BackgroundService
{
private readonly ILogger<UpdateDameonService> _logger;
private readonly ILogger<UpdateIoTNodeService> _logger;
private readonly IWebHostEnvironment _env;
private readonly IConfiguration _cfg;
private readonly IHttpClientFactory _httpClientFactory;
private bool _isUpdating;
public UpdateDameonService(ILogger<UpdateDameonService> logger, IWebHostEnvironment env, IConfiguration cfg, IHttpClientFactory httpClientFactory)
public bool IsUpdating { get; set; }
public UpdateIoTNodeService(ILogger<UpdateIoTNodeService> logger, IWebHostEnvironment env, IConfiguration cfg, IHttpClientFactory httpClientFactory)
{
this._logger = logger;
this._env = env;
@ -47,13 +48,13 @@ namespace IoTNode.Services
private void Update()
{
if (this._isUpdating)
if (this.IsUpdating)
{
return;
}
else
{
this._isUpdating = true;
this.IsUpdating = true;
}
try
{
@ -63,23 +64,26 @@ namespace IoTNode.Services
{
this._logger.LogError(ex, "update error");
}
this._isUpdating = false;
this.IsUpdating = false;
}
private void UpdateInternal()
{
var processName = "iotnode";
var appFolder = "IoTNode";
var port = 8002;
var proxyUrl = "http://localhost:9001/RPC2";
var processName = "iotdaemon";
var root = Directory.GetParent(_env.ContentRootPath).FullName;
var appPath = Path.Combine(root, "IoTDameon");
var name = "dameon.zip";
var backupName = Path.Combine(root, "iotdameon.bk.zip");
var appPath = Path.Combine(root, appFolder);
var name = $"{appFolder}.zip";
var backupName = Path.Combine(root, $"{appFolder}.bk.zip");
var file = Path.Combine(root, name);
var currentCheckSum = string.Empty;
//检查是否有更新
this._logger.LogInformation("check dameon version");
var currentVersion = this._httpClientFactory.CreateClient().GetAsync("http://localhost:8003/Home/GetVersion").Result.Content.ReadAsStringAsync().Result;
var info = this._httpClientFactory.CreateClient().GetAsync($"{this._cfg["notify:host"]}/dameon.xml").Result.Content.ReadAsStringAsync().Result;
this._logger.LogInformation("check version");
var currentVersion = this._httpClientFactory.CreateClient().GetAsync($"http://localhost:{port}/Home/GetVersion").Result.Content.ReadAsStringAsync().Result;
var server = this._httpClientFactory.CreateClient().GetAsync($"http://localhost:{port}/Home/GetServer").Result.Content.ReadAsStringAsync().Result;
var info = this._httpClientFactory.CreateClient().GetAsync($"{server}/{processName}.xml").Result.Content.ReadAsStringAsync().Result;
var doc = new XmlDocument();
doc.LoadXml(info);
var lastVersion = doc.GetElementsByTagName("version")[0].InnerText.Trim();
@ -131,15 +135,14 @@ namespace IoTNode.Services
try
{
ZipFile.CreateFromDirectory(appPath, backupName);
Directory.Delete(appPath, true);
Directory.CreateDirectory(appPath);
}
catch (Exception ex)
{
this._logger.LogError(ex, ex.Message);
throw new Exception("备份程序失败", ex);
}
Directory.Delete(appPath, true);
Directory.CreateDirectory(appPath);
//更新程序
try
{
@ -154,7 +157,9 @@ namespace IoTNode.Services
//设置权限
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
Process.Start("/bin/bash", $"-c \"chmod 755 {Path.Combine(appPath, "IoTDameon")}\"");
var updateScript = Path.Combine(appPath, "update.sh");
Process.Start("/bin/bash", $"-c \"chmod 755 {file}\"");
Process.Start(updateScript);
}
//启动更新程序
proxy.startProcess(processName);

@ -1,24 +1,27 @@
using Application.Domain.Entities;
using Infrastructure.Application.Services.Settings;
using Infrastructure.Data;
using Infrastructure.Web;
using IoT.Shared.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using System.Reflection;
namespace IoTNode.Controllers
{
//[Device]
public class HomeController : BaseController
{
private readonly ISettingService _settingService;
private readonly IRepository<Node> _nodeRepo;
private readonly IRepository<Scene> _sceneRepo;
private readonly IoTNodeClient _ioTNodeClient;
public HomeController(IRepository<Node> nodeRepo, IRepository<Scene> sceneRepo,IoTNodeClient ioTNodeClient)
public HomeController(ISettingService settingService, IRepository<Node> nodeRepo, IRepository<Scene> sceneRepo, IoTNodeClient ioTNodeClient)
{
this._settingService = settingService;
this._nodeRepo = nodeRepo;
this._sceneRepo = sceneRepo;
this._ioTNodeClient = ioTNodeClient;
@ -36,8 +39,8 @@ namespace IoTNode.Controllers
var model = this._sceneRepo.ReadOnlyTable()
.Include(o => o.SceneTimers)
.Include(o => o.SceneTiggers)
.Include(o => o.SceneCommands).ThenInclude(o=>o.Command).ThenInclude(o=>o.Device)
.Include(o=>o.SceneCommands).ThenInclude(o=>o.Command).ThenInclude(o=>o.Api)
.Include(o => o.SceneCommands).ThenInclude(o => o.Command).ThenInclude(o => o.Device)
.Include(o => o.SceneCommands).ThenInclude(o => o.Command).ThenInclude(o => o.Api)
.ToList();
return View(model);
}
@ -47,5 +50,15 @@ namespace IoTNode.Controllers
this._ioTNodeClient.OnConnected();
return RedirectTo();
}
public IActionResult GetVersion()
{
return Content(Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion);
}
public IActionResult GetServer()
{
return Content(this._settingService.GetSetting("notify:host").Value?.Trim());
}
}
}
Loading…
Cancel
Save