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.
301 lines
14 KiB
301 lines
14 KiB
using Tiobon.Core.OPS.Tool.OPS.Tool.Helper;
|
|
using Tiobon.Core.OPS.Tool.OPS.Tool.Model;
|
|
using Tiobon.Core.OPS.Tool.OPS.Tool.View;
|
|
using ICSharpCode.SharpZipLib.Zip;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Web.Script.Serialization;
|
|
using System.Windows.Forms;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace Tiobon.Core.OPS.Tool.OPS.Tool.Src
|
|
{
|
|
public class Module_method
|
|
{
|
|
#region 全局变量
|
|
SSHHelper sSH = new SSHHelper(Const.config.ip, Const.config.ssh_port, Const.config.ssh_user, Const.config.ssh_passwd);
|
|
SFTPHelper sFTP = new SFTPHelper(Const.config.ip, Const.config.ssh_port, Const.config.ssh_user, Const.config.ssh_passwd);
|
|
bool isLinux = Const.config.system == "Linux";
|
|
public Action End_Init;
|
|
Module module_conf;
|
|
#endregion
|
|
|
|
#region 获取配置信息
|
|
public Module GetConf(string filepath)
|
|
{
|
|
Const.ExtractSpecifyZipFile(filepath, "Config/", "", new List<string> { "README.ihdis" });
|
|
string fm = File.ReadAllText("Config/README.ihdis");
|
|
JavaScriptSerializer js = new JavaScriptSerializer();
|
|
module_conf = js.Deserialize<Module>(fm);
|
|
return module_conf;
|
|
}
|
|
#endregion
|
|
|
|
#region 检测压缩包是否损坏
|
|
public bool Is_BadZip(string path)
|
|
{
|
|
try
|
|
{
|
|
ZipFile entry = new ZipFile(path);
|
|
return true;
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region 模块安装
|
|
public void Install(string filepath, Action<string> handle)
|
|
{
|
|
bool isLinux = Const.config.system == "Linux";
|
|
var hospital = Const.config.install_item_dir.Split('/').Last();
|
|
if (isLinux)
|
|
{
|
|
var installpath = $"/home/{Const.config.ssh_user}/ihdis/tools/{module_conf.Name}";
|
|
var webpath = $"/home/{Const.config.ssh_user}/ihdis/produse";
|
|
try
|
|
{
|
|
sSH.Connect();
|
|
var tmpdir = $"/tmp/{module_conf.Name}{new Random().Next(10000, 20000)}";
|
|
//1,上传文件
|
|
handle?.Invoke("正在上传文件...");
|
|
Upload(filepath, handle);
|
|
|
|
//2,解压到临时目录
|
|
handle?.Invoke("正在解压到临时目录...");
|
|
sSH.Excute_Longcmd($"unzip -qo /home/{Const.config.ssh_user}/ihdis/tools/{filepath.Split('\\')[filepath.Split('\\').Length - 1]} -d {tmpdir}");
|
|
|
|
if (File.Exists("Config/README.ihdis"))
|
|
{
|
|
sFTP.Connect();
|
|
sFTP.Put("Config/README.ihdis", $"{tmpdir}", "README.ihdis");
|
|
sFTP.Disconnect();
|
|
}
|
|
|
|
var tmp = Const.config.install_item_dir.Split('/');
|
|
var item = Const.MultiEnvs.Where(o => o.Ip == Const.config.ip && o.FileName == tmp[tmp.Length - 1]).FirstOrDefault();
|
|
|
|
//3,运行init.sh脚本
|
|
sSH.Excute_Longcmd_NoError($"cd {installpath} && sudo docker-compose down ");
|
|
sSH.Excute_Longcmd_NoError($"rm -rf {installpath}");
|
|
handle?.Invoke("运行init.sh脚本...");
|
|
sSH.Excute_Longcmd_NoError($"sudo sh {tmpdir}/init.sh {tmpdir} {installpath} {webpath}");
|
|
sSH.Excute_Longcmd($"sed -i \"s/JL_NETWORK=.*/JL_NETWORK={item.FileName}_oi_net/\" {installpath}/.env");
|
|
|
|
//4.启动docker
|
|
handle?.Invoke("启动插件...");
|
|
sSH.Excute_Longcmd_NoError($"cd {installpath} && sudo docker-compose up -d ");
|
|
|
|
// 5, 添加开机启动
|
|
handle?.Invoke("添加开机启动...");
|
|
PluginAutoRestart(installpath, module_conf.Name);
|
|
|
|
// 6,清理缓存
|
|
handle?.Invoke("清理缓存...");
|
|
sSH.Excute_Longcmd($"sudo bash -c 'echo 3 > /proc/sys/vm/drop_caches'");
|
|
|
|
//7.删除临时文件
|
|
sSH.Excute_Longcmd($"rm -r {tmpdir}");
|
|
var tmp1 = filepath.Split('\\');
|
|
string filename = tmp1[tmp1.Length - 1];
|
|
if (sFTP.Exists($"/home/{Const.config.ssh_user}/ihdis/tools/" + filename))
|
|
sFTP.Delete($"/home/{Const.config.ssh_user}/ihdis/tools/" + filename);
|
|
|
|
handle?.Invoke("安装完成...");
|
|
sSH.Disconnect();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show($"安装过程出错,请截图错误信息或复制日志后联系工程师!\r\n\r\n{ex.Message}");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
#region Windows
|
|
|
|
var tmpdir = $"{Path.GetTempPath()}{module_conf.Name}{new Random().Next(10000, 20000)}";
|
|
|
|
//1.解压目录
|
|
Const.write_task_log("正在解压安装包...");
|
|
if (!Directory.Exists(tmpdir))
|
|
Directory.CreateDirectory(tmpdir);
|
|
Const.ExtractZipFile(filepath, tmpdir, "", null);
|
|
|
|
//2.创建安装目录
|
|
var installpath = $"{Const.config.install_dir}\\tools\\{module_conf.Name}";
|
|
if (!Directory.Exists(installpath))
|
|
Directory.CreateDirectory(installpath);
|
|
|
|
//3.进行插件初始化
|
|
handle?.Invoke("正在初始化插件...");
|
|
Init(tmpdir, installpath, hospital, handle);
|
|
Const.DeleteADirectory(tmpdir + "\\");
|
|
handle?.Invoke("安装完成...");
|
|
Thread.Sleep(2000);
|
|
#endregion
|
|
}
|
|
End_Init();
|
|
}
|
|
#endregion
|
|
|
|
#region 插件开机启动
|
|
public void PluginAutoRestart(string installPath, string model)
|
|
{
|
|
try
|
|
{
|
|
sSH.Excute_Longcmd($"sudo cd {installPath}");
|
|
sSH.Excute_Longcmd($"sudo echo '#!/bin/bash' > autostart_{model}.sh");
|
|
sSH.Excute_Longcmd($"sudo echo '#chkconfig:345 95 95' >> autostart_{model}.sh");
|
|
sSH.Excute_Longcmd($"sudo echo '#description:开机自启脚本' >> autostart_{model}.sh");
|
|
sSH.Excute_Longcmd($"sudo echo 'cd {installPath}' >> autostart_{model}.sh");
|
|
sSH.Excute_Longcmd($"sudo echo 'sudo docker-compose restart' >> autostart_{model}.sh");
|
|
|
|
sSH.Excute_Longcmd($"sudo mv autostart_{model}.sh /etc/rc.d/init.d");
|
|
sSH.Excute_Longcmd($"sudo chmod +x /etc/rc.d/init.d/autostart_{model}.sh");
|
|
sSH.Excute_Longcmd($"cd /etc/rc.d/init.d");
|
|
|
|
sSH.Excute_Longcmd($"sudo chkconfig --add autostart_{model}.sh");
|
|
//sSH.Excute_Longcmd($"chkconfig --list");
|
|
|
|
sSH.Excute_Longcmd($"sudo chkconfig autostart_{model}.sh on");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show($"插件开机启动失败,请截图错误信息或复制日志后联系工程师!\r\n\r\n{ex.Message}");
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region 上传文件
|
|
public void Upload(string filepath, Action<string> handle)
|
|
{
|
|
try
|
|
{
|
|
var tmp = filepath.Split('\\');
|
|
string filename = tmp[tmp.Length - 1];
|
|
sFTP.Connect();
|
|
if (sFTP.Exists($"/home/{Const.config.ssh_user}/ihdis/tools/" + filename))
|
|
{
|
|
handle?.Invoke($"删除同名更新包...");
|
|
sFTP.Delete($"/home/{Const.config.ssh_user}/ihdis/tools/" + filename);
|
|
handle?.Invoke($"【{filename}】删除完成...");
|
|
}
|
|
handle?.Invoke($"开始上传更新包...");
|
|
sFTP.Put(filepath, $"/home/{Const.config.ssh_user}/ihdis/tools/", filename);
|
|
handle?.Invoke($"更新包上传完成...");
|
|
sFTP.Disconnect();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show($"上传文件失败,请截图错误信息或复制日志后联系工程师!\r\n\r\n{ex.Message}");
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// 初始化插件
|
|
/// </summary>
|
|
/// <param name="tmpdir"></param>
|
|
/// <param name="installPath"></param>
|
|
/// <param name="hospital"></param>
|
|
public void Init(string tmpdir, string installPath, string hospital, Action<string> handle)
|
|
{
|
|
var allOldLines = new List<string>();
|
|
if (File.Exists($"{installPath}\\.env"))
|
|
allOldLines = File.ReadAllLines($"{installPath}\\.env").ToList<string>();
|
|
|
|
Const.CopyDir(tmpdir, installPath);
|
|
var env = File.ReadAllText($"{tmpdir}\\.env").ToLower();
|
|
var tmp = Const.config.install_item_dir.Split('/');
|
|
var item = Const.MultiEnvs.Where(o => o.Ip == Const.config.ip && o.FileName == tmp[tmp.Length - 1]).FirstOrDefault();
|
|
|
|
// 判断安装插件类型
|
|
if (env.Contains("ts"))
|
|
{
|
|
Const.CopyDir($"{installPath}\\conf", $"{installPath}\\code");
|
|
CmdHelper.RunCmd($"docker load -i {installPath}\\ts.base.tar.gz\r\ndocker tag hh/ts:base hh/ts:1.33.0", out _);
|
|
}
|
|
else if (env.Contains("fsc"))
|
|
{
|
|
CmdHelper.RunCmd($"docker import {installPath}\\fsc.tar.gz hh/fsc:1.0.0", out _);
|
|
}
|
|
else if (env.Contains("hdis_qc")) // 质控插件
|
|
{
|
|
var allLines = File.ReadAllLines($"{tmpdir}\\.env").ToList<string>();
|
|
|
|
var projectNameStr = "PROJECT_NAME=";
|
|
var apiVersionStr = "API_VERSION=";
|
|
var webVersionStr = "WEB_VERSION=";
|
|
|
|
var projectName = allLines.Where(o => o.Contains(projectNameStr)).FirstOrDefault()?.Split('=')[1];
|
|
var apiVersion = allLines.Where(o => o.Contains(apiVersionStr)).FirstOrDefault()?.Split('=')[1];
|
|
var webVersion = allLines.Where(o => o.Contains(apiVersionStr)).FirstOrDefault()?.Split('=')[1];
|
|
|
|
#region 删除旧镜像
|
|
if (allOldLines.Any())
|
|
{
|
|
handle?.Invoke("开始删除旧镜像...");
|
|
var projectName1 = allOldLines.Where(o => o.Contains(projectNameStr)).FirstOrDefault()?.Split('=')[1];
|
|
var apiVersion1 = allOldLines.Where(o => o.Contains(apiVersionStr)).FirstOrDefault()?.Split('=')[1];
|
|
var webVersion1 = allOldLines.Where(o => o.Contains(apiVersionStr)).FirstOrDefault()?.Split('=')[1];
|
|
|
|
CmdHelper.RunCmd($"docker rmi {projectName1}/api:{apiVersion1}", out _);
|
|
CmdHelper.RunCmd($"docker rmi {projectName1}/web:{webVersion1}", out _);
|
|
handle?.Invoke("完成删除旧镜像...");
|
|
}
|
|
#endregion
|
|
|
|
handle?.Invoke("挂载镜像...");
|
|
|
|
#region 替换端口号、子网掩码
|
|
var newEnv = File.ReadAllText($"{tmpdir}\\.env").Replace("produce_oi_net", $"{item.FileName}_oi_net");
|
|
File.WriteAllText($"{installPath}/.env", newEnv);
|
|
|
|
var yml = File.ReadAllText($"{installPath}/docker-compose.yml");
|
|
yml = yml.Replace("produce_oi_net", $"{item.FileName}_oi_net");
|
|
File.WriteAllText($"{installPath}/docker-compose.yml", yml);
|
|
|
|
#endregion
|
|
|
|
//生成Docker Desktop挂载目录
|
|
Main_method.AddDockerMountPath(yml, installPath);
|
|
|
|
CmdHelper.RunCmd($"docker images --format \"{{{{.Repository}}}}:{{{{.Tag}}}}\"", out string res);
|
|
if (!res.Contains($"{projectName}/api:{apiVersion}"))
|
|
CmdHelper.RunCmd($"docker load -i {installPath}\\images\\{projectName}_api_{apiVersion}.tar", out _);
|
|
|
|
if (!res.Contains($"{projectName}/web:{apiVersion}"))
|
|
CmdHelper.RunCmd($"docker load -i {installPath}\\images\\{projectName}_web_{webVersion}.tar", out _);
|
|
handle?.Invoke("挂载镜像完成...");
|
|
}
|
|
var resultLog = string.Empty;
|
|
handle?.Invoke("正在启动容器...");
|
|
CmdHelper.RunCmd($"{installPath.Split(':')[0].Trim()}: \r\ncd {$"{installPath}/"}" +
|
|
$"\r\ndocker-compose up -d \r\nexit", out resultLog);
|
|
|
|
if (env.Contains("ts"))
|
|
{
|
|
var webPath = $"{Const.config.install_dir}\\{hospital}";
|
|
var webConf = $"{webPath}\\conf\\nginx\\site\\web.conf";
|
|
var webConfLines = File.ReadAllLines(webConf).ToList<string>();
|
|
if (!webConfLines.Any(o => o.Contains("ts/ts")))
|
|
{
|
|
webConfLines.Insert(6, " location /ts/ {");
|
|
webConfLines.Insert(7, " proxy_pass http://ts/ts/;");
|
|
webConfLines.Insert(8, " }");
|
|
File.WriteAllLines(webConf, webConfLines);
|
|
handle?.Invoke("正在重启nginx...");
|
|
CmdHelper.RunCmd($"{webPath.Split(':')[0].Trim()}: \r\ncd {$"{webPath}/"}" +
|
|
$"\r\ndocker-compose restart nginx \r\nexit", out _);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|