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 dic_module = new Dictionary(); bool isInit = false; PerformanceCounter cpuCounter; PerformanceCounter memoryCounter; CounterSample cpuSample1; public Action 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 CheckMask() { List lst = new List(); 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 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 recovery = new Dictionary(); 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 检测是否已经初始化完成 /// /// 检测webapi是否已经初始化完成 /// /// 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 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系统版本 /// /// 获取ihdis系统版本 /// /// 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; } /// /// 获取ihdis系统数据库版本 /// /// 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 创建网段 /// /// 创建一个网段 /// /// /// 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); } } } /// /// 匹配网段信息 /// /// 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 添加挂载目录 /// /// 添加挂载目录 /// /// /// 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(jsonString); IDictionary services = dynamicObject.services; // 获取volume路径集合 var volumeList = new List(); var volumes = services.Where(o => Const.DoesPropertyExist(o.Value, "volumes")).Select(o => o.Value.volumes).ToList(); volumes.ForEach(v => { var objList = (List)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 } }