You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
906 lines
40 KiB
906 lines
40 KiB
using Tiobon.Core.OPS.Tool.OPS.Tool.Helper;
|
|
using Tiobon.Core.OPS.Tool.OPS.Tool.Model;
|
|
using Tiobon.Core.OPS.Tool.OPS.Tool.src;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Diagnostics;
|
|
using System.Windows.Forms;
|
|
using Microsoft.Win32;
|
|
using System.Text.RegularExpressions;
|
|
using System.Data;
|
|
using System.Xml;
|
|
using ICSharpCode.SharpZipLib.Zip;
|
|
using ICSharpCode.SharpZipLib.Core;
|
|
using System.Threading.Tasks;
|
|
using Renci.SshNet;
|
|
using YamlDotNet.Serialization;
|
|
using System.Dynamic;
|
|
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
namespace Tiobon.Core.OPS.Tool.OPS.Tool.Src
|
|
{
|
|
public class Main_method
|
|
{
|
|
#region 全局变量
|
|
public SSHHelper sSH;
|
|
public SFTPHelper sFTP;
|
|
bool isupdate = false;
|
|
bool isLinux = Const.config.system == "Linux";
|
|
Dictionary<string, Module> dic_module = new Dictionary<string, Module>();
|
|
bool isInit = false;
|
|
PerformanceCounter cpuCounter;
|
|
PerformanceCounter memoryCounter;
|
|
CounterSample cpuSample1;
|
|
public Action<bool> End_Init;
|
|
private string defaultSubnet = "172.210.238.0";
|
|
#endregion
|
|
|
|
#region 获取系统状态
|
|
public string Get_sysstatus()
|
|
{
|
|
if (isInit)
|
|
{
|
|
try
|
|
{
|
|
|
|
if (Const.config.system == "Linux")
|
|
{
|
|
if (!sSH.Connected)
|
|
{
|
|
Init();
|
|
}
|
|
var flag = sSH.Excute_Longcmd("cpu=`vmstat | awk 'NR==3{print $15}'`\n total_mem=`vmstat -s | awk 'NR==1{print $1}'` \n free_mem=`vmstat -s | awk 'NR==5{print $1}'` \n disk=`df --block-size 1g -h / | sed -n \"2, 1p\" |awk '{{print $5}}'` \n echo \"$cpu,$total_mem,$free_mem,$disk\"", out string result);
|
|
if (!flag)
|
|
{
|
|
return $"获取系统状态失败:{result}";
|
|
}
|
|
var tmp = result.Split(',');
|
|
var mem = (Math.Round((double.Parse(tmp[1]) - double.Parse(tmp[2])) / double.Parse(tmp[1]), 4) * 100).ToString();
|
|
return $" CPU使用:{100 - int.Parse(tmp[0].Trim())}% 内存使用:{mem}% 硬盘使用:{tmp[3].Trim()}";
|
|
}
|
|
else
|
|
{
|
|
return GetCpuUsage();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return $"获取系统状态失败";
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
#endregion
|
|
|
|
#region 获取Windows系统状态
|
|
public string GetCpuUsage()
|
|
{
|
|
double dist = 0;
|
|
double distsum = 0;
|
|
DriveInfo[] drive = DriveInfo.GetDrives();//获取所有驱动器
|
|
foreach (DriveInfo df in drive)//遍历驱动器
|
|
{
|
|
dist += ((df.TotalSize - df.TotalFreeSpace) / 1024 / 1024 / 1024.0);
|
|
distsum += (df.TotalSize / 1024 / 1024 / 1024.0);
|
|
}
|
|
var distinfo = (dist / distsum).ToString("0.00" + "%");
|
|
|
|
//float cpusum = 0;
|
|
//foreach (var item in counters)
|
|
//{
|
|
// cpusum += item.NextValue();
|
|
//}
|
|
var cpuinfo = CounterSampleCalculator.ComputeCounterValue(cpuSample1, cpuCounter.NextSample()).ToString("0.00");
|
|
cpuSample1 = cpuCounter.NextSample();
|
|
return $"CPU使用:{cpuinfo}% 内存使用:{(memoryCounter.NextValue() / 1024 / 1024 / 100).ToString("0.00")}% 硬盘使用:{distinfo}";
|
|
}
|
|
#endregion
|
|
|
|
#region 初始化
|
|
public Main_method()
|
|
{
|
|
Init();
|
|
}
|
|
|
|
public void Init()
|
|
{
|
|
if (isLinux)
|
|
{
|
|
sSH = new SSHHelper(Const.config.ip, Const.config.ssh_port, Const.config.ssh_user, Const.config.ssh_passwd);
|
|
sSH.Connect();
|
|
sFTP = new SFTPHelper(Const.config.ip, Const.config.ssh_port, Const.config.ssh_user, Const.config.ssh_passwd);
|
|
}
|
|
else
|
|
{
|
|
cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
|
|
memoryCounter = new PerformanceCounter("Process", "Working Set - Private", "_Total");
|
|
cpuCounter.NextValue();
|
|
memoryCounter.NextValue();
|
|
//counters = new PerformanceCounter[System.Environment.ProcessorCount];
|
|
//for (int i = 0; i < counters.Length; i++)
|
|
//{
|
|
// counters[i] = new PerformanceCounter("Processor", "% Processor Time", "_Total");
|
|
// counters[i].NextValue();
|
|
//}
|
|
}
|
|
isInit = true;
|
|
}
|
|
#endregion
|
|
|
|
#region 2.0一键安装
|
|
public void New_Install(bool Clear_Image, string fileName = null)
|
|
{
|
|
var installpath = Const.config.install_item_dir;
|
|
var flag = true;
|
|
var tmp = installpath.Split('/');
|
|
var item = Const.MultiEnvs.Where(o => o.Ip == Const.config.ip && o.FileName == tmp[tmp.Length - 1]).FirstOrDefault();
|
|
var ihdis_port = item.DefaultPort;
|
|
var mask = item.DefaultMask;
|
|
try
|
|
{
|
|
|
|
if (isLinux)
|
|
{
|
|
#region Linux
|
|
//检测mask
|
|
Const.write_task_log("正在检测网络...");
|
|
var masks = CheckMask();
|
|
if (masks.Contains(item.DefaultPort))
|
|
{
|
|
item.DefaultMask = GetMask(masks);
|
|
Const.write_task_log($"网络已存在,自动生成新的mask = {item.DefaultMask}...");
|
|
Const.SaveMultiEnv();
|
|
}
|
|
Const.Port = ihdis_port;
|
|
var version = tmp[tmp.Length - 1];
|
|
var filepath = Const.config.localfile_path;
|
|
var fi = new FileInfo(filepath);
|
|
file_lenth = fi.Length;
|
|
//1,上传文件
|
|
Const.write_task_log("正在准备上传文件...");
|
|
Upload(Upload_Info);
|
|
|
|
//2,安装unzip,解压文件,删除旧文件,旧容器
|
|
Const.write_task_log("正在安装系统组件和初始化...");
|
|
sSH.Excute_Longcmd_NoError($"sudo rpm -ivh {Const.Script_path}/script/other/unzip-6.0-19.el7.x86_64.rpm");
|
|
Const.write_task_log("正在解压文件...");
|
|
sSH.Excute_Longcmd_NoError($"cd {installpath} ; sudo docker-compose down");
|
|
sSH.Excute_Longcmd_NoError($"rm -rf {installpath}");
|
|
sSH.Excute_Longcmd($"unzip -qo /home/{Const.config.ssh_user}/ihdis/{filepath.Split('\\')[filepath.Split('\\').Length - 1]} -d {installpath}");
|
|
|
|
//3,初始化,安装docker,docker-compose等
|
|
sSH.Excute_Longcmd_NoError($"sudo sh {Const.Script_path}/script/init.sh {installpath}");
|
|
|
|
//4.加载镜像
|
|
Const.write_task_log("正在加载镜像...");
|
|
sSH.Excute_Longcmd($"sh {installpath}/load_images.sh {installpath}");
|
|
|
|
//5.替换端口号
|
|
sSH.Excute_Longcmd($"sed -i \"s/IHDIS_PORT=.*/IHDIS_PORT={ihdis_port}/\" {installpath}/.env");
|
|
sSH.Excute_Longcmd($"sed -i \"s/mask=.*/mask={mask}/\" {installpath}/.env");
|
|
|
|
//6,创建启动容器
|
|
Const.write_task_log("正在创建并启动容器...");
|
|
sSH.Excute_Longcmd_NoError($"cd {installpath} ;sudo docker-compose up -d ");
|
|
Thread.Sleep(1000 * 80);
|
|
|
|
//7,数据库初始化
|
|
Const.write_task_log("数据库初始化...");
|
|
sSH.Excute_Longcmd_NoError($"sudo sh {Const.Script_path}/script/mysql_init.sh {installpath}");
|
|
|
|
//8.按照顺序重启
|
|
Restart_Server(installpath);
|
|
Thread.Sleep(1000 * 40);
|
|
|
|
//9,创建开机启动,数据库初始化等收尾工作
|
|
Const.write_task_log("正在添加开机启动...");
|
|
sSH.Excute_Longcmd($"sudo sh {Const.Script_path}/script/end.sh {installpath} {Const.config.ssh_user}");
|
|
|
|
// 10,删除多余镜像
|
|
if (Clear_Image)
|
|
{
|
|
Const.write_task_log("正在删除多余镜像 文件....");
|
|
sSH.Excute_Longcmd($"sudo docker image prune -a -f");
|
|
sSH.Excute_Longcmd($"sudo rm -rf {installpath}/app/images/*");
|
|
sSH.Excute_Longcmd($"sudo rm -rf /home/{Const.config.ssh_user}/ihdis/{filepath.Split('\\')[filepath.Split('\\').Length - 1]}");
|
|
}
|
|
Const.write_task_log("正在清理缓存...");
|
|
sSH.Excute_Longcmd($"sudo bash -c 'echo 3 > /proc/sys/vm/drop_caches'");
|
|
|
|
//11.等待webapi
|
|
AppInitCompleted(ihdis_port);
|
|
#endregion
|
|
}
|
|
else
|
|
{
|
|
var output = string.Empty;
|
|
#region Windows
|
|
var filepath = Const.config.localfile_path;
|
|
var mask1 = $"172.210.{item.DefaultMask}.0";
|
|
|
|
//1.删除旧文件
|
|
Const.write_task_log("正在删除旧文件...");
|
|
CmdHelper.RunCmd($"{installpath.Split(':')[0].Trim()}: \r\ncd {$"{installpath}/"}" +
|
|
$"\r\ndocker-compose down \r\nexit", out output);
|
|
Const.DeleteADirectory(installpath + "\\");
|
|
|
|
//2.解压
|
|
Const.write_task_log("正在解压安装包...");
|
|
if (!Directory.Exists(installpath))
|
|
Directory.CreateDirectory(installpath);
|
|
Const.ExtractZipFile(filepath, installpath, "", ProcessFile);
|
|
|
|
//copy appsettings.json
|
|
File.Copy($"{installpath}\\conf\\app\\webapi\\appsettings.json", $"{installpath}\\code\\webapi\\appsettings.json", true);
|
|
File.Copy($"{installpath}\\conf\\app\\hfs\\appsettings.json", $"{installpath}\\code\\hfs\\appsettings.json", true);
|
|
File.Copy($"{installpath}\\conf\\app\\rtm\\appsettings.json", $"{installpath}\\code\\rtm\\appsettings.json", true);
|
|
File.Copy($"{installpath}\\conf\\app\\job\\appsettings.json", $"{installpath}\\code\\job\\appsettings.json", true);
|
|
File.Copy($"{installpath}\\conf\\app\\iot\\appsettings.json", $"{installpath}\\code\\iot\\appsettings.json", true);
|
|
File.Copy($"{installpath}\\conf\\app\\ts\\appsettings.json", $"{installpath}\\code\\ts\\appsettings.json", true);
|
|
|
|
//3.加载镜像
|
|
Const.write_task_log("正在加载镜像...");
|
|
CmdHelper.RunCmd($"{installpath.Split(':')[0].Trim()}: \r\ncd {$"{installpath}/"}" +
|
|
$"\r\n.\\load_images.cmd\r\nexit", out _);
|
|
|
|
//4.替换端口号、子网掩码
|
|
var env = File.ReadAllText($"{installpath}/.env");
|
|
var newEnv = Regex.Replace(env, @"IHDIS_PORT=\d*", $"IHDIS_PORT={ihdis_port}");
|
|
newEnv = Regex.Replace(newEnv, @"mask=\d*", $"mask={mask}");
|
|
File.WriteAllText($"{installpath}/.env", newEnv);
|
|
|
|
var yml = File.ReadAllText($"{installpath}/docker-compose.yml");
|
|
yml = yml.Replace(defaultSubnet, mask1);
|
|
File.WriteAllText($"{installpath}/docker-compose.yml", yml);
|
|
|
|
//5.生成Docker Desktop挂载目录
|
|
AddDockerMountPath(yml, installpath);
|
|
|
|
//6.启动容器
|
|
Const.write_task_log("正在启动容器...");
|
|
CmdHelper.RunCmd($"{installpath.Split(':')[0].Trim()}: \r\ncd {$"{installpath}/"}" +
|
|
$"\r\ndocker-compose up -d \r\nexit", out _);
|
|
Thread.Sleep(1000 * 80);
|
|
|
|
//7.数据库初始化
|
|
Const.write_task_log("正在进行数据库初始化...");
|
|
CmdHelper.RunCmd($"{installpath.Split(':')[0].Trim()}: \r\ncd {$"{installpath}/"}" +
|
|
$"\r\ndocker-compose exec -T mysql mysql -uroot -hlocalhost mysql --default-character-set=utf8 < conf/mysql/hdis_db.sql" +
|
|
$"\r\ndocker-compose exec -T mysql mysql -uroot -hlocalhost hdis --default-character-set=utf8 < conf/mysql/hdis_table.sql" +
|
|
$"\r\ndocker-compose exec -T mysql mysql -uroot -hlocalhost mysql --default-character-set=utf8 < conf/mysql/hdis_user.sql" +
|
|
//$"\r\ndocker-compose exec -T mysql mysql -uroot -hlocalhost -e \"use mysql;update user set authentication_string = password('jlmed#123'), password_expired = 'N', password_last_changed = now() where user = 'root';flush privileges;\"" +
|
|
$"\r\n", out _);
|
|
|
|
Thread.Sleep(1000 * 40);
|
|
|
|
CmdHelper.RunCmd($"{installpath.Split(':')[0].Trim()}: \r\ncd {$"{installpath}/"}" +
|
|
$"\r\ndocker-compose exec -T mysql mysql -uroot -hlocalhost -e \"ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'jlmed#123'; flush privileges;\"" +
|
|
$"\r\n", out _);
|
|
|
|
Thread.Sleep(1000 * 10);
|
|
|
|
Const.write_task_log("正在进行重启容器...");
|
|
|
|
CmdHelper.RunCmd($"{installpath.Split(':')[0].Trim()}: \r\ncd {$"{installpath}/"}" +
|
|
$"\r\ndocker-compose down" +
|
|
$"\r\n", out _);
|
|
|
|
Thread.Sleep(1000 * 10);
|
|
|
|
CmdHelper.RunCmd($"{installpath.Split(':')[0].Trim()}: \r\ncd {$"{installpath}/"}" +
|
|
$"\r\ndocker-compose up -d \r\nexit", out _);
|
|
Thread.Sleep(1000 * 10);
|
|
|
|
//8.重启rtm,job,防止连接不上
|
|
Restart_Server(installpath);
|
|
Thread.Sleep(1000 * 10);
|
|
|
|
#endregion
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Const.write_task_log($"StackTrace:{ex.StackTrace}");
|
|
MessageBox.Show($"安装过程出错,请截图错误信息或复制日志后联系工程师!\r\n\r\n{ex.Message}");
|
|
flag = false;
|
|
}
|
|
End_Init(flag);
|
|
}
|
|
|
|
private List<string> CheckMask()
|
|
{
|
|
List<string> lst = new List<string>();
|
|
try
|
|
{
|
|
var b_suc = ExecSsh("sudo ip route", out string result);
|
|
result
|
|
.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).Where(o => o.StartsWith("172."))
|
|
.ToList()
|
|
.ForEach(s =>
|
|
{
|
|
lst.Add(s.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries)[2]);
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Const.write_task_log("检测子网掩码失败:" + ex);
|
|
}
|
|
return lst;
|
|
}
|
|
private string GetMask(List<string> lst)
|
|
{
|
|
while (true)
|
|
{
|
|
var r = new Random().Next(1, 255).ToString();
|
|
if (!lst.Contains(r))
|
|
{
|
|
return r.ToString();
|
|
}
|
|
System.Threading.Thread.Sleep(1);
|
|
}
|
|
}
|
|
private bool ExecSsh(string command, out string result)
|
|
{
|
|
bool b_suc = false;
|
|
result = string.Empty;
|
|
try
|
|
{
|
|
using (SshClient ssh = new SshClient(Const.config.ip, 22, "root", Const.config.supasswd))
|
|
{
|
|
ssh.Connect();
|
|
|
|
var cmd = ssh.RunCommand(command);
|
|
if (cmd.ExitStatus != 0)
|
|
{
|
|
result = cmd.Error;
|
|
}
|
|
else
|
|
{
|
|
b_suc = true;
|
|
result = $"{cmd.Result}{cmd.Error}";
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
result = ex.Message;
|
|
}
|
|
Const.write_log(result);
|
|
return b_suc;
|
|
}
|
|
#endregion
|
|
|
|
#region 2.0 一键升级
|
|
public void New_Update(bool Clear_Image, string comment)
|
|
{
|
|
var installpath = Const.config.install_item_dir;
|
|
var flag = true;
|
|
var tmp = installpath.Split('/');
|
|
var item = Const.MultiEnvs.Where(o => o.Ip == Const.config.ip && o.FileName == tmp[tmp.Length - 1]).FirstOrDefault();
|
|
var ihdis_port = item.DefaultPort;
|
|
var mask = item.DefaultMask;
|
|
Dictionary<string, string> recovery = new Dictionary<string, string>();
|
|
try
|
|
{
|
|
var apps = comment.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
|
|
.ToList()
|
|
.Where(str => str.Trim().StartsWith("Moudule: "))
|
|
.FirstOrDefault()
|
|
?.Replace("Moudule: ", "")
|
|
.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
|
|
.ToList();
|
|
var filepath = Const.config.localfile_path;
|
|
var recoverypath = $"/tmp/{DateTime.Now.ToString("yyyyMMddHHmmss")}";
|
|
if (isLinux)
|
|
{
|
|
Const.Port = ihdis_port;
|
|
var fi = new FileInfo(filepath);
|
|
file_lenth = fi.Length;
|
|
|
|
//1 上传文件
|
|
Const.write_task_log("正在准备上传文件...");
|
|
Upload(Upload_Info);
|
|
|
|
//2 创建备份路径
|
|
Const.write_task_log("正在创建备份路径...");
|
|
sSH.Excute_Longcmd($"sudo mkdir {recoverypath}");
|
|
|
|
//3 更新容器
|
|
Const.write_task_log("正在更新容器...");
|
|
apps.ForEach(m =>
|
|
{
|
|
Const.write_task_log($"正在更新模块 {m}...");
|
|
switch (m)
|
|
{
|
|
case "web":
|
|
case "pad":
|
|
{
|
|
Const.write_task_log($"正在备份 {m}...");
|
|
sSH.Excute_Longcmd($"sudo cp -r {installpath}/app/www/{m} {recoverypath}");
|
|
sSH.Excute_Longcmd($"sudo rm -rf {installpath}/app/www/{m}/*");
|
|
if (!recovery.ContainsKey(m))
|
|
recovery.Add(m, $"sudo cp -r {recoverypath}/{m} {installpath}/app/www");
|
|
break;
|
|
}
|
|
case "ts":
|
|
case "hfs":
|
|
case "job":
|
|
case "iot":
|
|
case "rtm":
|
|
case "webapi":
|
|
{
|
|
Const.write_task_log($"正在备份 {m}...");
|
|
sSH.Excute_Longcmd($"sudo cp -r {installpath}/code/{m} {recoverypath}");
|
|
sSH.Excute_Longcmd($"sudo rm -rf {installpath}/code/{m}/*");
|
|
if (!recovery.ContainsKey(m))
|
|
recovery.Add(m, $"sudo cp -r {recoverypath}/{m} {installpath}/code");
|
|
break;
|
|
}
|
|
case "andriod":
|
|
//不处理
|
|
break;
|
|
default:
|
|
Const.write_task_log($"模块不支持 {m}...");
|
|
return;
|
|
}
|
|
});
|
|
sSH.Excute_Longcmd($"unzip -qo /home/{Const.config.ssh_user}/ihdis/{filepath.Split('\\')[filepath.Split('\\').Length - 1]} -d {installpath}");
|
|
//4 启动容器
|
|
Const.write_task_log("正在重新启动容器...");
|
|
sSH.Excute_Longcmd_NoError($"cd {installpath} ;sudo docker-compose restart ");
|
|
//5 按照顺序重启
|
|
Restart_Server(installpath);
|
|
//6 清理缓存
|
|
if (Clear_Image)
|
|
{
|
|
Const.write_task_log("正在删除多余镜像 文件....");
|
|
sSH.Excute_Longcmd($"sudo docker image prune -a -f");
|
|
sSH.Excute_Longcmd($"sudo rm -rf {installpath}/app/images/*");
|
|
sSH.Excute_Longcmd($"sudo rm -rf /home/{Const.config.ssh_user}/ihdis/{filepath.Split('\\')[filepath.Split('\\').Length - 1]}");
|
|
}
|
|
Const.write_task_log("正在清理缓存...");
|
|
sSH.Excute_Longcmd_NoError($"sudo rm -rf {recoverypath}");
|
|
sSH.Excute_Longcmd_NoError($"sudo bash -c 'echo 3 > /proc/sys/vm/drop_caches'");
|
|
//6.等待webapi
|
|
AppInitCompleted(ihdis_port);
|
|
}
|
|
else
|
|
{
|
|
#region Windows
|
|
|
|
foreach (var app in apps)
|
|
{
|
|
Const.write_task_log($"正在备份 {app}...");
|
|
|
|
var appPath = $"{recoverypath}\\{app}";
|
|
|
|
if (!Directory.Exists(appPath))
|
|
Directory.CreateDirectory(appPath);
|
|
|
|
switch (app)
|
|
{
|
|
case "web":
|
|
case "pad":
|
|
{
|
|
Const.CopyDir($"{installpath}\\app\\www\\{app}", appPath);
|
|
break;
|
|
}
|
|
case "hfs":
|
|
case "job":
|
|
case "rtm":
|
|
case "webapi":
|
|
{
|
|
Const.CopyDir($"{installpath}\\code\\{app}", appPath);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
//6,创建启动容器
|
|
Const.write_task_log("正在停止服务...");
|
|
CmdHelper.RunCmd($"{installpath.Split(':')[0].Trim()}: \r\ncd {$"{installpath}/"}" +
|
|
$"\r\ndocker-compose down \r\nexit", out _);
|
|
|
|
//1.删除旧版前端文件
|
|
Const.write_task_log("正在删除旧文件...");
|
|
Const.DeleteADirectory(installpath + "\\app\\www");
|
|
|
|
//2.备份旧版本tag及nginx配置文件
|
|
File.Copy($"{installpath}\\.env", $"{installpath}\\.env.back", true);
|
|
|
|
var nginxConfig = $"{installpath}/conf/nginx/site/web.conf";
|
|
File.Copy(nginxConfig, $"{nginxConfig}.back", true);
|
|
|
|
var webapiConfig = $"{installpath}/conf/app/webapi/appsettings.json";
|
|
File.Copy(webapiConfig, $"{webapiConfig}.back", true);
|
|
|
|
var jobConfig = $"{installpath}/conf/app/job/appsettings.json";
|
|
File.Copy(jobConfig, $"{jobConfig}.back", true);
|
|
|
|
//3.解压
|
|
Const.write_task_log("正在解压安装包...");
|
|
if (!Directory.Exists(installpath))
|
|
Directory.CreateDirectory(installpath);
|
|
|
|
Const.ExtractZipFile(filepath, installpath, "", ProcessFile);
|
|
|
|
//copy appsettings.json
|
|
File.Copy($"{installpath}\\conf\\app\\webapi\\appsettings.json", $"{installpath}\\code\\webapi\\appsettings.json", true);
|
|
File.Copy($"{installpath}\\conf\\app\\hfs\\appsettings.json", $"{installpath}\\code\\hfs\\appsettings.json", true);
|
|
File.Copy($"{installpath}\\conf\\app\\rtm\\appsettings.json", $"{installpath}\\code\\rtm\\appsettings.json", true);
|
|
File.Copy($"{installpath}\\conf\\app\\job\\appsettings.json", $"{installpath}\\code\\job\\appsettings.json", true);
|
|
File.Copy($"{installpath}\\conf\\app\\iot\\appsettings.json", $"{installpath}\\code\\iot\\appsettings.json", true);
|
|
File.Copy($"{installpath}\\conf\\app\\ts\\appsettings.json", $"{installpath}\\code\\ts\\appsettings.json", true);
|
|
|
|
//4.加载镜像
|
|
Const.write_task_log("正在加载镜像...");
|
|
CmdHelper.RunCmd($"{installpath.Split(':')[0].Trim()}: \r\ncd {$"{installpath}/"}" +
|
|
$"\r\n.\\load_images.cmd\r\nexit", out _);
|
|
|
|
//5.替换端口号
|
|
var env = File.ReadAllText($"{installpath}/.env");
|
|
string pattern = @"IHDIS_PORT=\d*";
|
|
var new_env = Regex.Replace(env, pattern, $"IHDIS_PORT={ihdis_port}");
|
|
new_env = Regex.Replace(new_env, @"mask=\d*", $"mask={mask}");
|
|
File.WriteAllText($"{installpath}/.env", new_env);
|
|
|
|
//6.替换网段
|
|
CreateNework(mask, installpath);
|
|
|
|
//7.创建启动容器
|
|
Const.write_task_log("正在更新容器...");
|
|
CmdHelper.RunCmd($"{installpath.Split(':')[0].Trim()}: \r\ncd {$"{installpath}/"}" +
|
|
$"\r\ndocker-compose up -d \r\nexit", out _);
|
|
|
|
// 删除nginx、webapi、job配置文件
|
|
File.Copy($"{nginxConfig}.back", $"{nginxConfig}", true);
|
|
File.Delete($"{nginxConfig}.back");
|
|
|
|
File.Copy($"{webapiConfig}.back", $"{webapiConfig}", true);
|
|
File.Delete($"{webapiConfig}.back");
|
|
|
|
File.Copy($"{jobConfig}.back", $"{jobConfig}", true);
|
|
File.Delete($"{jobConfig}.back");
|
|
|
|
Thread.Sleep(1000 * 20);
|
|
|
|
Restart_Server(installpath);
|
|
Thread.Sleep(1000 * 10);
|
|
#endregion
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
var log = $"升级过程出错,请截图错误信息或复制日志后联系工程师!\r\n\r\n{ex.Message}";
|
|
Const.write_task_log(log);
|
|
MessageBox.Show(log);
|
|
Const.write_task_log("开始恢复数据");
|
|
recovery.Keys.ForEach(r =>
|
|
{
|
|
try
|
|
{
|
|
Const.write_task_log($"开始恢复 {r}");
|
|
sSH.Excute_Longcmd_NoError(recovery[r]);
|
|
}
|
|
catch { }
|
|
});
|
|
Const.write_task_log("数据恢复完毕");
|
|
flag = false;
|
|
}
|
|
End_Init(flag);
|
|
}
|
|
#endregion
|
|
|
|
#region 重启系统容器
|
|
public void Restart_Server(string server_path)
|
|
{
|
|
if (isLinux)
|
|
{
|
|
Thread.Sleep(2000);
|
|
sSH.Excute_Longcmd_NoError($"cd {server_path};sudo docker-compose restart rtm");
|
|
Thread.Sleep(5000);
|
|
sSH.Excute_Longcmd_NoError($"cd {server_path};sudo docker-compose restart job");
|
|
Thread.Sleep(2000);
|
|
sSH.Excute_Longcmd_NoError($"cd {server_path};sudo docker-compose restart hfs");
|
|
Thread.Sleep(2000);
|
|
sSH.Excute_Longcmd_NoError($"cd {server_path};sudo docker-compose restart iot");
|
|
Thread.Sleep(2000);
|
|
sSH.Excute_Longcmd_NoError($"cd {server_path};sudo docker-compose restart ts");
|
|
Thread.Sleep(2000);
|
|
sSH.Excute_Longcmd_NoError($"cd {server_path};sudo docker-compose restart webapi");
|
|
Thread.Sleep(10000);
|
|
sSH.Excute_Longcmd_NoError($"cd {server_path};sudo docker-compose restart nginx");
|
|
}
|
|
else
|
|
{
|
|
CmdHelper.RunCmd($"docker-compose -f {server_path}\\docker-compose.yml restart rtm", out _);
|
|
Thread.Sleep(2000);
|
|
CmdHelper.RunCmd($"docker-compose -f {server_path}\\docker-compose.yml restart job", out _);
|
|
Thread.Sleep(10000);
|
|
|
|
CmdHelper.RunCmd($"docker-compose -f {server_path}\\docker-compose.yml restart hfs", out _);
|
|
Thread.Sleep(2000);
|
|
|
|
CmdHelper.RunCmd($"docker-compose -f {server_path}\\docker-compose.yml restart iot", out _);
|
|
Thread.Sleep(2000);
|
|
|
|
CmdHelper.RunCmd($"docker-compose -f {server_path}\\docker-compose.yml restart ts", out _);
|
|
Thread.Sleep(2000);
|
|
|
|
CmdHelper.RunCmd($"docker-compose -f {server_path}\\docker-compose.yml restart webapi", out _);
|
|
Thread.Sleep(10000);
|
|
|
|
CmdHelper.RunCmd($"docker-compose -f {server_path}\\docker-compose.yml restart nginx", out _);
|
|
Thread.Sleep(10000);
|
|
|
|
CmdHelper.RunCmd($"{server_path.Split(':')[0].Trim()}: \r\ncd {$"{server_path}/"}" +
|
|
$"\r\ndocker-compose restart rtm\r\nexit", out _);
|
|
Thread.Sleep(2000);
|
|
CmdHelper.RunCmd($"{server_path.Split(':')[0].Trim()}: \r\ncd {$"{server_path}/"}" +
|
|
$"\r\ndocker-compose restart job\r\nexit", out _);
|
|
Thread.Sleep(2000);
|
|
CmdHelper.RunCmd($"{server_path.Split(':')[0].Trim()}: \r\ncd {$"{server_path}/"}" +
|
|
$"\r\ndocker-compose restart hfs\r\nexit", out _);
|
|
Thread.Sleep(2000);
|
|
CmdHelper.RunCmd($"{server_path.Split(':')[0].Trim()}: \r\ncd {$"{server_path}/"}" +
|
|
$"\r\ndocker-compose restart iot\r\nexit", out _);
|
|
Thread.Sleep(2000);
|
|
CmdHelper.RunCmd($"{server_path.Split(':')[0].Trim()}: \r\ncd {$"{server_path}/"}" +
|
|
$"\r\ndocker-compose restart ts\r\nexit", out _);
|
|
Thread.Sleep(2000);
|
|
CmdHelper.RunCmd($"{server_path.Split(':')[0].Trim()}: \r\ncd {$"{server_path}/"}" +
|
|
$"\r\ndocker-compose restart webapi\r\nexit", out _);
|
|
Thread.Sleep(10000);
|
|
CmdHelper.RunCmd($"{server_path.Split(':')[0].Trim()}: \r\ncd {$"{server_path}/"}" +
|
|
$"\r\ndocker-compose restart nginx\r\nexit", out _);
|
|
Thread.Sleep(10000);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region 检测是否已经初始化完成
|
|
/// <summary>
|
|
/// 检测webapi是否已经初始化完成
|
|
/// </summary>
|
|
/// <param name="ihdis_port"></param>
|
|
private void AppInitCompleted(string ihdis_port)
|
|
{
|
|
Const.write_task_log("正在等待webapi初始化...");
|
|
int count = 20;
|
|
while (count-- > 0)
|
|
{
|
|
try
|
|
{
|
|
var res = HttpHelper.GetHttpResult($"http://{Const.config.ip}:{ihdis_port}00/api/Assistant/HospitalRoomList");
|
|
if (res.Contains("\"Code\":10000,\"Message\":\"查询成功\",\"Success\":true"))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
catch
|
|
{ }
|
|
System.Threading.Thread.Sleep(10000);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region 停止测试环境
|
|
public void stop_test()
|
|
{
|
|
try
|
|
{
|
|
if (isLinux)
|
|
sSH.Excute_cmd($"sudo docker-compose -f /home/{Const.config.ssh_user}/ihdis/test1/docker-compose.yml stop", out _);
|
|
}
|
|
catch { }
|
|
}
|
|
#endregion
|
|
|
|
#region 上传文件
|
|
public void Upload(Action<ulong> flash_upload)
|
|
{
|
|
var tmp = Const.config.localfile_path.Split('\\');
|
|
string filename = tmp[tmp.Length - 1];
|
|
SFTPHelper sFTP = new SFTPHelper(Const.config.ip, Const.config.ssh_port, Const.config.ssh_user, Const.config.ssh_passwd);
|
|
sFTP.Connect();
|
|
sFTP.Put(Const.config.localfile_path, $"/home/{Const.config.ssh_user}/ihdis/", filename, flash_upload);
|
|
sFTP.Disconnect();
|
|
}
|
|
private long file_lenth;
|
|
public void Upload_Info(ulong curr)
|
|
{
|
|
double bb = Convert.ToInt32(curr / 1024 / 1024) / Convert.ToDouble(file_lenth / 1024 / 1024);
|
|
Const.write_task_log($"正在上传文件,当前进度{(bb * 100).ToString("f2")}%...");
|
|
}
|
|
#endregion
|
|
|
|
#region 刷新解压进度文件
|
|
void ProcessFile(object sender, ScanEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
Const.write_task_log($"正在解压:{Path.GetFileName(e.Name)}");
|
|
}
|
|
catch
|
|
{
|
|
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region 获取hdis系统版本
|
|
/// <summary>
|
|
/// 获取ihdis系统版本
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public string Get_Version()
|
|
{
|
|
string version = "未安装";
|
|
try
|
|
{
|
|
if (isLinux)
|
|
{
|
|
if (sSH.Excute_cmd($"cat {Const.config.install_item_dir}/Version", out string result))
|
|
{
|
|
version = result;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (File.Exists($"{Const.config.install_item_dir}/Version"))
|
|
{
|
|
version = File.ReadAllText($"{Const.config.install_item_dir}/Version");
|
|
}
|
|
}
|
|
}
|
|
catch { }
|
|
return version;
|
|
}
|
|
/// <summary>
|
|
/// 获取ihdis系统数据库版本
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public (bool, string) Get_DbVersion()
|
|
{
|
|
bool suc = false;
|
|
string version = "未安装";
|
|
try
|
|
{
|
|
if (isLinux)
|
|
{
|
|
if (sSH.Excute_cmd($"cat {Const.config.install_item_dir}/DbVersion", out string result))
|
|
{
|
|
suc = true;
|
|
version = result.Trim();
|
|
}
|
|
else
|
|
{
|
|
if (sSH.Excute_cmd($"cat {Const.config.install_item_dir}/Version", out result))
|
|
{
|
|
suc = true;
|
|
version = result.Trim();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (File.Exists($"{Const.config.install_item_dir}/Version"))
|
|
{
|
|
suc = true;
|
|
version = File.ReadAllText($"{Const.config.install_item_dir}/Version");
|
|
version = version.TrimEnd(new char[] { '\r', '\n' });
|
|
}
|
|
}
|
|
}
|
|
catch { }
|
|
return (suc, version);
|
|
}
|
|
#endregion
|
|
|
|
#region 创建网段
|
|
|
|
/// <summary>
|
|
/// 创建一个网段
|
|
/// </summary>
|
|
/// <param name="paths"></param>
|
|
/// <returns></returns>
|
|
public void CreateNework(string subnet, string installPath)
|
|
{
|
|
if (isLinux)
|
|
{
|
|
if (subnet != defaultSubnet)
|
|
{
|
|
string cmd = $"sudo sed -i \"s/{defaultSubnet}/{subnet}/g\" {installPath}/docker-compose.yml";
|
|
sSH.Excute_Longcmd_NoError(cmd);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (subnet != defaultSubnet)
|
|
{
|
|
string path = $"{installPath}\\docker-compose.yml";
|
|
string tem = File.ReadAllText(path);
|
|
tem = tem.Replace(defaultSubnet, subnet);
|
|
File.WriteAllText(path, tem);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 匹配网段信息
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public (string code, string installPath) MatchNetwork(string installPath)
|
|
{
|
|
string temp = string.Empty;
|
|
if (isLinux)
|
|
{
|
|
string path = $"sudo cat {Const.config.install_dir}/{installPath}/docker-compose.yml";
|
|
sSH.Excute_cmd(path, out temp);
|
|
}
|
|
else
|
|
{
|
|
string path = $"{Const.config.install_dir}\\{installPath}\\docker-compose.yml";
|
|
temp = File.ReadAllText(path);
|
|
}
|
|
string result = Regex.Match(temp, "((25[0-5]|2[0-4]\\d|((1\\d{2})|([1-9]?\\d)))\\.){3}(25[0-5]|2[0-4]\\d|((1\\d{2})|([1-9]?\\d)))").Value;
|
|
return (result, installPath);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 添加挂载目录
|
|
|
|
/// <summary>
|
|
/// 添加挂载目录
|
|
/// </summary>
|
|
/// <param name="yml"></param>
|
|
/// <param name="installPath"></param>
|
|
public static void AddDockerMountPath(string yml, string installPath)
|
|
{
|
|
var sReader = new StringReader(yml);
|
|
var deserializer = new DeserializerBuilder().Build();
|
|
var yamlObject = deserializer.Deserialize(sReader);
|
|
var serializer = new SerializerBuilder().JsonCompatible().Build();
|
|
|
|
var jsonString = serializer.Serialize(yamlObject);
|
|
dynamic dynamicObject = JsonConvert.DeserializeObject<ExpandoObject>(jsonString);
|
|
IDictionary<string, dynamic> services = dynamicObject.services;
|
|
|
|
// 获取volume路径集合
|
|
var volumeList = new List<string>();
|
|
var volumes = services.Where(o => Const.DoesPropertyExist(o.Value, "volumes")).Select(o => o.Value.volumes).ToList();
|
|
volumes.ForEach(v =>
|
|
{
|
|
var objList = (List<object>)v;
|
|
var list = objList.ConvertAll(c => { return c.ToString(); }).ToList();
|
|
volumeList.AddRange(list);
|
|
});
|
|
|
|
// 添加filesharing目录
|
|
var settingPath = $"{Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)}\\Docker\\settings.json";
|
|
var setting = File.ReadAllText(settingPath);
|
|
var json = JObject.Parse(setting);
|
|
if (json.ContainsKey("filesharingDirectories"))
|
|
{
|
|
JArray fileSharing = (JArray)json["filesharingDirectories"];
|
|
volumeList.ForEach(volume =>
|
|
{
|
|
var path = volume.Replace("\"", "").Replace("./", "").Split(':')[0];
|
|
var fullPath = Path.GetFullPath(Path.Combine(installPath, path));
|
|
fileSharing.Add(fullPath);
|
|
});
|
|
File.WriteAllText(settingPath, JsonConvert.SerializeObject(json, Newtonsoft.Json.Formatting.Indented));
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|
|
|