예제 #1
0
        /// <summary>
        /// 保存配置
        /// </summary>
        /// <returns></returns>
        public static string SaveConfiguration()
        {
            // Validate
            if (!ValidateUtil.ValidateIp(ConfigurationDto.DataSource))
            {
                return("连接数据库的数据源地址格式有误!");
            }
            if (!ValidateUtil.ValidateIp(ConfigurationDto.ServerIp))
            {
                return("连接数据中心的地址格式有误!");
            }
            if (!ValidateUtil.ValidatePort(ConfigurationDto.ServerPort))
            {
                return("连接数据中心的端口设置有误!");
            }

            bool          configParameterBlured = false;
            List <string> tagNames  = new List <string>();
            List <string> newValues = new List <string>();

            /// CloseMainwindowToExit
            if (CloseMainwindowToExit != ConfigurationDto.CloseMainwindowToExit)
            {
                tagNames.Add("CloseMainwindowToExit");
                newValues.Add(ConfigurationDto.CloseMainwindowToExit.ToString());
                CloseMainwindowToExit = ConfigurationDto.CloseMainwindowToExit;
            }

            /// DataBase Parameters
            if (!DataSource.Equals(ConfigurationDto.DataSource))
            {
                configParameterBlured = true;
                tagNames.Add("DataSource");
                newValues.Add(ConfigurationDto.DataSource);
                DataSource = ConfigurationDto.DataSource;
            }
            if (!InitialCatalog.Equals(ConfigurationDto.InitialCatalog))
            {
                configParameterBlured = true;
                tagNames.Add("InitialCatalog");
                newValues.Add(ConfigurationDto.InitialCatalog);
                InitialCatalog = ConfigurationDto.InitialCatalog;
            }
            if (!UserId.Equals(ConfigurationDto.UserId))
            {
                configParameterBlured = true;
                tagNames.Add("UserId");
                newValues.Add(ConfigurationDto.UserId);
                UserId = ConfigurationDto.UserId;
            }
            if (!Password.Equals(ConfigurationDto.Password))
            {
                configParameterBlured = true;
                tagNames.Add("Password");
                newValues.Add(EncryptionDecryption.Encrypt(ConfigurationDto.Password));
                Password = ConfigurationDto.Password;
            }
            if (configParameterBlured)
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback((obj) =>
                {
                    AppEventsManager.UpdateConnectionString();
                }), null);
            }

            configParameterBlured = false;
            /// Data Server Parameter
            if (!ServerIp.Equals(ConfigurationDto.ServerIp))
            {
                configParameterBlured = true;
                tagNames.Add("DataServerIP");
                newValues.Add(ConfigurationDto.ServerIp);
                ServerIp = ConfigurationDto.ServerIp;
            }
            if (!ServerPort.Equals(ConfigurationDto.ServerPort))
            {
                configParameterBlured = true;
                tagNames.Add("DataServerPort");
                newValues.Add(ConfigurationDto.ServerPort);
                ServerPort = ConfigurationDto.ServerPort;
            }
            if (configParameterBlured)
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback((obj) =>
                {
                    AppEventsManager.UpdateDataServer();
                }), null);
            }

            configParameterBlured = false;
            if (OuterDiameterUpper != ConfigurationDto.OuterDiameterUpper)
            {
                tagNames.Add("Upper");
                configParameterBlured = true;
                newValues.Add("" + ConfigurationDto.OuterDiameterUpper);
                OuterDiameterUpper = ConfigurationDto.OuterDiameterUpper;
            }

            if (OuterDiameterLower != ConfigurationDto.OuterDiameterLower)
            {
                tagNames.Add("Lower");
                configParameterBlured = true;
                newValues.Add("" + ConfigurationDto.OuterDiameterLower);
                OuterDiameterLower = ConfigurationDto.OuterDiameterLower;
            }

            if (configParameterBlured)
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback((obj) =>
                {
                    AppEventsManager.UpdateOuterDiameterUpperAndLower();
                }), null);
            }


            if (tagNames.Count > 0)
            {
                XmlUtil.ChangeXmlByTagNames(AppConfig, tagNames, newValues);
            }

            return(null);
        }
예제 #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="publishFolder">deploy文件目录</param>
        /// <param name="isrollBack"></param>
        /// <param name="isDefaultDockfile">上传的时候没有DockerFile要创建</param>
        public void DoDockerCommand(string publishFolder, bool isrollBack = false, bool isDefaultDockfile = false, string publishName = "publish")
        {
            string port        = string.Empty;
            string server_port = string.Empty;

            if (!publishFolder.EndsWith("/"))
            {
                publishFolder = publishFolder + "/";
            }
            //先查看本地是否有dockerFile
            var dockFilePath  = publishFolder + "Dockerfile";
            var dockFilePath2 = $"{(string.IsNullOrEmpty(publishName)?"": publishName+"/")}Dockerfile";
            // ReSharper disable once SimplifyConditionalTernaryExpression
            var isExistDockFile = isDefaultDockfile? false: _sftpClient.Exists(dockFilePath2);

            //如果本地存在dockerfile 那么就根据此创建image
            //如果不存在的话 就根据当前的netcore sdk的版本 进行创建相对应的 dockfile

            if (!isExistDockFile)
            {
                if (isrollBack)
                {
                    _logger($"dockerFile is not exist: {dockFilePath}", NLog.LogLevel.Error);
                    return;
                }


                if (!isDefaultDockfile)
                {
                    var createDockerFileResult = CreateDockerFile(dockFilePath);
                    if (!createDockerFileResult)
                    {
                        return;
                    }
                }
            }
            else
            {
                //如果项目中存在dockerFile 那么check 该DockerFile的Expose是否配置了 没有配置就报错
                try
                {
                    var dockerFileText = _sftpClient.ReadAllText(dockFilePath);
                    if (string.IsNullOrEmpty(dockerFileText))
                    {
                        _logger($"dockerFile is empty: {dockFilePath}", NLog.LogLevel.Error);
                        return;
                    }

                    var newPortA = dockerFileText.Split(new string[] { "EXPOSE " }, StringSplitOptions.None);
                    if (newPortA.Length != 2)
                    {
                        _logger($"EXPOSE param in dockerFile is empty: {dockFilePath}", NLog.LogLevel.Error);
                        return;
                    }
                    var newPort = string.Empty;
                    foreach (var item in newPortA[1].Trim())
                    {
                        if (Char.IsDigit(item))
                        {
                            newPort += item;
                        }
                        else
                        {
                            break;
                        }
                    }
                    if (string.IsNullOrEmpty(newPort))
                    {
                        _logger($"EXPOSE in dockerFile is invalid: {dockFilePath}", NLog.LogLevel.Error);
                        return;
                    }
                    else
                    {
                        if (!string.IsNullOrEmpty(NetCorePort) && !this.ContainerPort.Equals(newPort))
                        {
                            _logger($"EXPOSE in dockerFile is defined,will use【{newPort}】replace【{ContainerPort}】", NLog.LogLevel.Warn);
                        }
                        else
                        {
                            _logger($"EXPOSE in dockerFile is : 【{newPort}】", NLog.LogLevel.Info);
                        }
                    }

                    port = newPort;

                    var volumeInDockerFile = string.Empty;
                    var volumeExist        = dockerFileText.Split(new string[] { volumeProfix }, StringSplitOptions.None);
                    if (volumeExist.Length == 2)
                    {
                        var temp2 = volumeExist[1].Split('@');
                        if (temp2.Length == 2)
                        {
                            volumeInDockerFile = temp2[0];
                        }
                    }

                    if (!string.IsNullOrEmpty(volumeInDockerFile))
                    {
                        //dockerFIle里面有配置 volume
                        if (!string.IsNullOrEmpty(Volume) && !Volume.Equals(volumeInDockerFile))
                        {
                            _logger($"Volume in dockerFile is defined,will use【{volumeInDockerFile}】replace【{Volume}】", NLog.LogLevel.Warn);
                        }
                        else
                        {
                            _logger($"Volume in dockerFile is : 【{volumeInDockerFile}】", NLog.LogLevel.Info);
                        }

                        Volume = volumeInDockerFile;
                    }

                    var serverPostDockerFile      = string.Empty;
                    var serverPostDockerFileExist = dockerFileText.Split(new string[] { serverPortProfix }, StringSplitOptions.None);
                    if (serverPostDockerFileExist.Length == 2)
                    {
                        var temp2 = serverPostDockerFileExist[1].Split('@');
                        if (temp2.Length > 0)
                        {
                            serverPostDockerFile = temp2[0];
                        }
                    }

                    if (!string.IsNullOrEmpty(serverPostDockerFile))
                    {
                        //dockerFIle里面有配置 ServerPort
                        if (!string.IsNullOrEmpty(NetCorePort) && !ServerPort.Equals(serverPostDockerFile))
                        {
                            _logger($"ServerPort in dockerFile is defined,will use【{serverPostDockerFile}】replace【{ServerPort}】", NLog.LogLevel.Warn);
                        }
                        else
                        {
                            _logger($"ServerPort in dockerFile is : 【{serverPostDockerFile}】", NLog.LogLevel.Info);
                        }

                        server_port = serverPostDockerFile;
                    }
                    else
                    {
                        server_port = port;
                    }
                }
                catch (Exception)
                {
                    _logger($"Get EXPOSE param in dockerFile fail: {dockFilePath}", NLog.LogLevel.Error);
                    return;
                }
            }

            //执行docker build 生成一个镜像
            var dockerBuildResult = RunSheell($"docker build --no-cache --rm -t {PorjectName}:{ClientDateTimeFolderName} -f {dockFilePath} {publishFolder} ");

            if (!dockerBuildResult)
            {
                _logger($"build image fail", NLog.LogLevel.Error);
                return;
            }

            var continarName = "d_" + PorjectName;


            //先发送退出命令
            //https://stackoverflow.com/questions/40742192/how-to-do-gracefully-shutdown-on-dotnet-with-docker

            SshCommand r1 = null;

            try
            {
                r1 = _sshClient.RunCommand($"docker stop -t 10 {continarName}");
                if (r1.ExitStatus == 0)
                {
                    _logger($"docker stop -t 10 {continarName}", LogLevel.Info);
                }

                Thread.Sleep(5000);
            }
            catch (Exception)
            {
                //ignore
            }

            try
            {
                //查看容器有没有在runing 如果有就干掉它
                r1 = _sshClient.RunCommand($"docker rm -f {continarName}");
                if (r1.ExitStatus == 0)
                {
                    _logger($"docker rm -f {continarName}", LogLevel.Info);
                }
            }
            catch (Exception)
            {
                //ignore
            }


            if (string.IsNullOrEmpty(port))
            {
                port = ContainerPort;
            }

            if (string.IsNullOrEmpty(server_port))
            {
                server_port = ServerPort;
            }

            string volume = GetVolume();

            // 根据image启动一个容器
            var dockerRunRt = RunSheell($"docker run --name {continarName}{volume} -d --restart=always -p {server_port}:{port} {PorjectName}:{ClientDateTimeFolderName}");

            if (!dockerRunRt)
            {
                _logger($"docker run fail", NLog.LogLevel.Error);
                return;
            }

            //把旧的image给删除
            r1 = _sshClient.RunCommand("docker images --format '{{.Repository}}:{{.Tag}}:{{.ID}}' | grep '^" + PorjectName + ":'");
            if (r1.ExitStatus == 0 && !string.IsNullOrEmpty(r1.Result))
            {
                var deleteImageArr = r1.Result.Split('\n');
                var clearOldImages = false;
                foreach (var imageName in deleteImageArr)
                {
                    if (imageName.StartsWith($"{PorjectName}:{ClientDateTimeFolderName}:"))
                    {
                        //当前版本
                        continue;
                    }

                    var imageArr = imageName.Split(':');
                    if (imageArr.Length == 3)
                    {
                        var r2 = _sshClient.RunCommand($"docker rmi {imageArr[2]}");
                        if (r2.ExitStatus == 0)
                        {
                            if (!clearOldImages)
                            {
                                _logger($"start to clear old images of name:{PorjectName}", LogLevel.Info);
                                clearOldImages = true;
                            }
                            _logger($"docker rmi {imageArr[2]} [{imageName}]", LogLevel.Info);
                        }
                    }
                }
            }


            try
            {
                //查看是否有<none>的image 把它删掉 因为我们创建image的时候每次都会覆盖所以会产生一些没有的image
                _sshClient.RunCommand($"if docker images -f \"dangling=true\" | grep ago --quiet; then docker rmi -f $(docker images -f \"dangling=true\" -q); fi");
            }
            catch (Exception)
            {
                //igore
            }

            ClearOldHistroy();
        }
예제 #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="publishFolder">deploy文件目录</param>
        /// <param name="isrollBack"></param>
        /// <param name="isDefaultDockfile">上传的时候没有DockerFile要创建</param>
        public bool DoDockerCommand(string publishFolder, bool isrollBack = false, bool isDefaultDockfile = false, string publishName = "publish", string fromFolder = null)
        {
            string port        = string.Empty;
            string server_port = string.Empty;

            if (!publishFolder.EndsWith("/"))
            {
                publishFolder = publishFolder + "/";
            }
            //先查看本地是否有dockerFile
            var dockFilePath  = publishFolder + "Dockerfile";
            var dockFilePath2 = $"{(string.IsNullOrEmpty(publishName) ? "" : publishName + "/")}Dockerfile";
            // ReSharper disable once SimplifyConditionalTernaryExpression
            var isExistDockFile = isDefaultDockfile ? false : _sftpClient.Exists(dockFilePath2);

            //如果本地存在dockerfile 那么就根据此创建image
            //如果不存在的话 就根据当前的netcore sdk的版本 进行创建相对应的 dockfile

            if (!isExistDockFile)
            {
                if (isrollBack)
                {
                    _logger($"dockerFile is not exist: {dockFilePath}", LogLevel.Error);
                    return(false);
                }


                if (!isDefaultDockfile)
                {
                    var createDockerFileResult = CreateDockerFile(dockFilePath);
                    if (!createDockerFileResult)
                    {
                        return(false);
                    }
                }
            }
            else
            {
                //如果项目中存在dockerFile 那么check 该DockerFile的Expose是否配置了 没有配置就报错
                try
                {
                    var dockerFileText = _sftpClient.ReadAllText(dockFilePath);
                    if (string.IsNullOrEmpty(dockerFileText))
                    {
                        _logger($"dockerFile is empty: {dockFilePath}", LogLevel.Error);
                        return(false);
                    }
                    var needAddPort = false;
                    var newPort     = string.Empty;
                    var newPortA    = dockerFileText.Split(new string[] { "EXPOSE " }, StringSplitOptions.None);
                    if (newPortA.Length != 2)
                    {
                        needAddPort = true;
                    }
                    else
                    {
                        if (!newPortA[0].EndsWith("#"))
                        {
                            foreach (var item in newPortA[1].Trim())
                            {
                                if (Char.IsDigit(item))
                                {
                                    newPort += item;
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                    }

                    if (string.IsNullOrEmpty(newPort))
                    {
                        needAddPort = true;
                    }
                    else
                    {
                        if (!string.IsNullOrEmpty(NetCorePort) && !this.ContainerPort.Equals(newPort))
                        {
                            _logger($"EXPOSE in dockerFile is defined,will use【{newPort}】replace【{ContainerPort}】", LogLevel.Warning);
                        }
                        else
                        {
                            _logger($"EXPOSE in dockerFile is : 【{newPort}】", LogLevel.Info);
                        }
                    }

                    //如果dockfile里面没有配置EXPOST 就用界面上提供的
                    port = needAddPort ? ContainerPort : newPort;

                    var volumeInDockerFile = string.Empty;
                    var volumeExist        = dockerFileText.Split(new string[] { volumeProfix }, StringSplitOptions.None);
                    if (volumeExist.Length == 2)
                    {
                        var temp2 = volumeExist[1].Split('@');
                        if (temp2.Length > 0)
                        {
                            volumeInDockerFile = temp2[0];
                        }
                    }

                    if (!string.IsNullOrEmpty(volumeInDockerFile))
                    {
                        //dockerFIle里面有配置 volume
                        if (!string.IsNullOrEmpty(Volume) && !Volume.Equals(volumeInDockerFile))
                        {
                            _logger($"Volume in dockerFile is defined,will use【{volumeInDockerFile}】replace【{Volume}】", LogLevel.Warning);
                        }
                        else
                        {
                            _logger($"Volume in dockerFile is : 【{volumeInDockerFile}】", LogLevel.Info);
                        }

                        Volume = volumeInDockerFile;
                    }

                    var serverPostDockerFile      = string.Empty;
                    var serverPostDockerFileExist = dockerFileText.Split(new string[] { serverPortProfix }, StringSplitOptions.None);
                    if (serverPostDockerFileExist.Length == 2)
                    {
                        var temp2 = serverPostDockerFileExist[1].Split('@');
                        if (temp2.Length > 0)
                        {
                            serverPostDockerFile = temp2[0];
                        }
                    }

                    if (!string.IsNullOrEmpty(serverPostDockerFile))
                    {
                        //dockerFIle里面有配置 ServerPort
                        if (!string.IsNullOrEmpty(NetCorePort) && !ServerPort.Equals(serverPostDockerFile))
                        {
                            _logger($"ServerPort in dockerFile is defined,will use【{serverPostDockerFile}】replace【{ServerPort}】", LogLevel.Warning);
                        }
                        else
                        {
                            _logger($"ServerPort in dockerFile is : 【{serverPostDockerFile}】", LogLevel.Info);
                        }

                        server_port = serverPostDockerFile;
                    }
                    else
                    {
                        server_port = needAddPort ? ServerPort : port;
                    }

                    if (!string.IsNullOrEmpty(NetCoreEnvironment) || needAddPort)
                    {
                        var allLines        = _sftpClient.ReadAllLines(dockFilePath).ToList();
                        var entryPointIndex = 0;
                        var haveEnv         = false;
                        for (int i = 0; i < allLines.Count; i++)
                        {
                            var line = allLines[i];
                            if (line.Trim().StartsWith("ENTRYPOINT"))
                            {
                                entryPointIndex = i;
                            }

                            if (line.Trim().StartsWith("ENV ASPNETCORE_ENVIRONMENT"))
                            {
                                haveEnv = true;
                            }
                        }


                        if (entryPointIndex > 0)
                        {
                            var add = false;
                            if (needAddPort)
                            {
                                add = true;
                                allLines.Insert(entryPointIndex, "EXPOSE " + port);
                                _logger($"Add EXPOSE " + port + $" to dockerFile  : 【{dockFilePath}】", LogLevel.Info);
                            }

                            if (!haveEnv && !string.IsNullOrEmpty(NetCoreEnvironment))
                            {
                                add = true;
                                allLines.Insert(entryPointIndex, "ENV ASPNETCORE_ENVIRONMENT " + NetCoreEnvironment);
                                _logger($"Add ENV ASPNETCORE_ENVIRONMENT " + NetCoreEnvironment + $" to dockerFile  : 【{dockFilePath}】", LogLevel.Info);
                            }

                            if (add)
                            {
                                //没有发现包含环境变量 就添加进去

                                _sshClient.RunCommand($"set -e;cd ~;\\rm -rf \"{dockFilePath}\";");


                                using (var writer = _sftpClient.CreateText(dockFilePath))
                                {
                                    foreach (var line in allLines)
                                    {
                                        writer.WriteLine(line);
                                    }
                                    //发布的时候界面上有填volume 也存在dockerfile 要记录到dockerfile中 不然回滚的时候就没了
                                    if (string.IsNullOrEmpty(volumeInDockerFile) && !string.IsNullOrEmpty(this.Volume))
                                    {
                                        writer.WriteLine(volumeProfix + this.Volume + "@");
                                        _logger(volumeProfix + this.Volume + "@", LogLevel.Info);
                                    }
                                    writer.Flush();
                                }
                            }
                        }
                    }
                    else if (string.IsNullOrEmpty(volumeInDockerFile) && !string.IsNullOrEmpty(this.Volume))
                    {
                        //发布的时候界面上有填volume 也存在dockerfile 要记录到dockerfile中 不然回滚的时候就没了
                        var allLines = _sftpClient.ReadAllLines(dockFilePath).ToList();
                        _sshClient.RunCommand($"set -e;cd ~;\\rm -rf \"{dockFilePath}\";");
                        using (var writer = _sftpClient.CreateText(dockFilePath))
                        {
                            foreach (var line in allLines)
                            {
                                writer.WriteLine(line);
                            }

                            writer.WriteLine(volumeProfix + this.Volume + "@");
                            _logger(volumeProfix + this.Volume + "@", LogLevel.Info);
                            writer.Flush();
                        }
                    }

                    if (!string.IsNullOrEmpty(fromFolder))
                    {
                        //需要将修改过的DockerFile 移动到 发布文件夹的publish 目录下 不然会导致回滚的时候失败
                        var command = $"\\cp -rf {dockFilePath} {fromFolder}";
                        _logger($"Update DockerFile 【{command}】", LogLevel.Warning);
                        _sshClient.RunCommand(command);
                    }
                }
                catch (Exception ex)
                {
                    _logger($"parse param in dockerFile fail: {dockFilePath},err:{ex.Message}", LogLevel.Error);
                    return(false);
                }
            }

            //执行docker build 生成一个镜像
            var dockerBuildResult = RunSheell($"docker build --no-cache --rm -t {PorjectName}:{ClientDateTimeFolderName} -f {dockFilePath} {publishFolder} ");

            if (!dockerBuildResult)
            {
                _logger($"build image fail", LogLevel.Error);
                return(false);
            }

            var continarName = "d_" + PorjectName;


            //先发送退出命令
            //https://stackoverflow.com/questions/40742192/how-to-do-gracefully-shutdown-on-dotnet-with-docker

            SshCommand r1 = null;

            try
            {
                r1 = _sshClient.RunCommand($"docker stop -t 10 {continarName}");
                if (r1.ExitStatus == 0)
                {
                    _logger($"docker stop -t 10 {continarName}", LogLevel.Info);
                }

                Thread.Sleep(5000);
            }
            catch (Exception)
            {
                //ignore
            }

            try
            {
                //查看容器有没有在runing 如果有就干掉它
                r1 = _sshClient.RunCommand($"docker rm -f {continarName}");
                if (r1.ExitStatus == 0)
                {
                    _logger($"docker rm -f {continarName}", LogLevel.Info);
                }
            }
            catch (Exception)
            {
                //ignore
            }


            if (string.IsNullOrEmpty(port))
            {
                port = ContainerPort;
            }

            if (string.IsNullOrEmpty(server_port))
            {
                server_port = ServerPort;
            }

            string volume = GetVolume();

            // 根据image启动一个容器
            var dockerRunRt = RunSheell($"docker run --name {continarName}{volume} -d --restart=always -p {server_port}:{port} {PorjectName}:{ClientDateTimeFolderName}");

            if (!dockerRunRt)
            {
                _logger($"docker run fail", LogLevel.Error);
                return(false);
            }

            //把旧的image给删除
            r1 = _sshClient.RunCommand("docker images --format '{{.Repository}}:{{.Tag}}:{{.ID}}' | grep '^" + PorjectName + ":'");
            if (r1.ExitStatus == 0 && !string.IsNullOrEmpty(r1.Result))
            {
                var deleteImageArr = r1.Result.Split('\n');
                var clearOldImages = false;
                foreach (var imageName in deleteImageArr)
                {
                    if (imageName.StartsWith($"{PorjectName}:{ClientDateTimeFolderName}:"))
                    {
                        //当前版本
                        continue;
                    }

                    var imageArr = imageName.Split(':');
                    if (imageArr.Length == 3)
                    {
                        var r2 = _sshClient.RunCommand($"docker rmi {imageArr[2]}");
                        if (r2.ExitStatus == 0)
                        {
                            if (!clearOldImages)
                            {
                                _logger($"start to clear old images of name:{PorjectName}", LogLevel.Info);
                                clearOldImages = true;
                            }
                            _logger($"docker rmi {imageArr[2]} [{imageName}]", LogLevel.Info);
                        }
                    }
                }
            }


            try
            {
                //查看是否有<none>的image 把它删掉 因为我们创建image的时候每次都会覆盖所以会产生一些没有的image
                _sshClient.RunCommand($"if docker images -f \"dangling=true\" | grep ago --quiet; then docker rmi -f $(docker images -f \"dangling=true\" -q); fi");
            }
            catch (Exception)
            {
                //igore
            }

            ClearOldHistroy();
            return(true);
        }