zhenorzz / goploy

Devops, Deploy, CI/CD, Terminal, Sftp, Server monitor, Crontab Manager, Nginx Manager.

Home Page:http://www.goploy.icu

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

期望改善Windows/Windows Server下使用OpenSSH Server时传输文件以及远程执行脚本的支持

xyzjl opened this issue · comments

特性描述
目标服务器环境: 常见的较新的windows环境(能支持安装OpenSSH Server即可,如Windows 10/11, Windows Server 2019等),且安装了OpenSSH Server

我需要在构建步骤中传输编译好的单个文件,在项目配置里面,传输文件的方式我尝试了几种方式(2和3可用):

  1. sftp: 由于goploy会自动加上src, dst参数,似乎不像rsync命令那样,没有比较好的方式能exclude掉其他的不需要的文件

  2. custom + 部署后运行脚本(bat): 为了规避方式1的问题,我使用了这个命令形式sshpass -p ${SERVER_PASSWORD} scp ${REPOSITORY_PATH}/app.jar ${REPOSITORY_PATH}/goploy-after-deploy-p${PROJECT_ID}-s${PROJECT_ENV}.bat ${SERVER_OWNER}@${SERVER_IP}:${PROJECT_PATH},可以先忽略sshpass这个暴露密码的槽点,我知道有其他更好的方式。这里想表达的问题其实是,官方的使用文档没有描述在custom的情况下,还需要传输脚本这个情况,我也是看了后台日志(不是构建日志)报错之后才看到的。这里还有一个问题,就是服务端暴露了"传输命令必须包含部署后运行脚本"这个逻辑到构建配置中,且脚本逻辑的名称也耦合到脚本中了,如果能增加一个${AFTER_DEPLOY_SCRIPT_NAME}之类的环境变量也许更好?

  3. custom + 部署后运行脚本(bash): 我将OpenSSH的默认终端改为了git的bash.exe(由于业务上的脚本运行原因),这时传输脚本也得相应修改sshpass -p ${SERVER_PASSWORD} scp ${REPOSITORY_PATH}/app.jar ${REPOSITORY_PATH}/goploy-after-deploy-p${PROJECT_ID}-s${PROJECT_ENV}.sh ${SERVER_OWNER}@${SERVER_IP}:${PROJECT_PATH},这也是结合第2点来讲体验不太好的一个点。这种方式使用还有一个bug,我配置了该服务器为windows服务器,服务端执行脚本的方式就是cmd /c ...,导致我的sh脚本实际使用的是cmd来执行,于是报错了。我觉得应该根据脚本的类型而不是服务器类型来判断?

另外,bat脚本内中文的支持似乎有问题,比如windows默认为gbk,构建就会报错,日志内容类似Incorrect string value: '\\xB2\\xBB\\xCA\\xC7\\xC4\\xDA...' for column 'detail' at row 1",我通过脚本内编写chcp 65001解决了这个问题,但是体验上不是很好,因为必须查日志文件才能知道问题,门槛还是略高,可以看怎么改善一下这个体验

附加
这个项目确实挺好的,我比较喜欢这种占用资源少,功能恰好够用的产品。可惜本人是多年的javaer,对go不太熟悉,不然我非常想自己贡献一下。上面的问题也是连续研究尝试了两天,才终于配置成功了在windows上使用。如果有其他人有类似场景的需要,希望也能从上面的描述中得到帮助~

你牛逼!

方式1
sftp
-v 详细模式输出
--delefe 删除所有文件
--exclude=FILE 指定排除不需要传输的文件
--include=FILE 指定不排除而需要传输的文件
--exclude-regexp=REGEXP 排除正则表达式中匹配的文件
--include-regexp=REGEXP 不排除正则表达式匹配的文件
https://docs.goploy.cn/#/dependency/sftp

方式2:叫这个${AFTER_DEPLOY_FILENAME},文档没写,是我的问题。

方式1 sftp -v 详细模式输出 --delefe 删除所有文件 --exclude=FILE 指定排除不需要传输的文件 --include=FILE 指定不排除而需要传输的文件 --exclude-regexp=REGEXP 排除正则表达式中匹配的文件 --include-regexp=REGEXP 不排除正则表达式匹配的文件 https://docs.goploy.cn/#/dependency/sftp

这个我看过官方文档了,我试了下通配符好像不好使,一个个exclude太麻烦,就尝试别的方式了。
sftp命令不是很熟悉,正则式当时没注意到,倒是可以再尝试一下。

方式3: 存在疑问,代码上写的是,只有bat的时候才用cmd,不清楚你是怎么出现的这个bug,详细描述一下。

方式1 sftp -v 详细模式输出 --delefe 删除所有文件 --exclude=FILE 指定排除不需要传输的文件 --include=FILE 指定不排除而需要传输的文件 --exclude-regexp=REGEXP 排除正则表达式中匹配的文件 --include-regexp=REGEXP 不排除正则表达式匹配的文件 https://docs.goploy.cn/#/dependency/sftp

这个我看过官方文档了,我试了下通配符好像不好使,一个个exclude太麻烦,就尝试别的方式了

我也觉得,确实有点麻烦。

方式3: 存在疑问,代码上写的是,只有bat的时候才用cmd,不清楚你是怎么出现的这个bug,详细描述一下。

我尝试切换服务器的linux/windows类型,观察构建日志里面的cmd/bash是正常的,但是观察后台日志(tail -f goploy.log) 好像没有及时刷新日志内容,可能是我之前通过看日志文件查问题,看到的并不是最新的日志,这个cmd/bash的问题确实不存在。

为啥日志不会实时刷新啊,这算是另一个问题?
关于这个问题,有几个线索,但是无法确定:

  1. 不是第一次观察到日志不刷新,猜测可能是我不断的尝试不同配置方式的构建,在有些配置下,构建的线程卡死未退出之类的
  2. 日志文件不刷新之后,后面再进行新的构建都不会再刷新,重启goploy服务之后,日志刷新正常,tail -f可观察到

另外,切换服务器类型确实会导致构建失败,我目前是方式3的配置,但是将服务器设置为linux类型,可以构建成功,切换成windows服务器类型之后会构建失败,排查到原因:
服务器为linux时:ssh exec: bash /path/to/my.sh && rm -f /path/to/my.sh
服务器为windows时:ssh exec: bash \\path\\to\\my.sh && rm -f \\path\\to\\my.sh

\\path\\to\\my.sh 这个脚本路径无法找到,导致了这个问题,因为git bash下不识别\路径

不会实时刷新,这个问题,不存在吧,我是writeFIle的。

线程卡死未退出,有些命令会卡死,例如直接 启动 程序,没有使用 nohup &,导致脚本一直在前台运行,就会这样。

线程卡死未退出,有些命令会卡死,例如直接 启动 程序,没有使用 nohup &,导致脚本一直在前台运行,就会这样。

这个我可以加个脚本运行超时参数。

你切换服务器类型,是指选择不同服务器吗?

不是的,切换服务器类型,是指在服务器设置页面,编辑已有的服务器,修改OS字段的单选: linux / windows

线程卡死未退出,有些命令会卡死,例如直接 启动 程序,没有使用 nohup &,导致脚本一直在前台运行,就会这样。

这个我可以加个脚本运行超时参数。

好的,谢谢作者。我后续再观察一下日志的情况

不是的,切换服务器类型,是指在服务器设置页面,编辑已有的服务器,修改OS字段的单选: linux / windows

看代码,确实有这种情况;
牛逼啊,兄弟;
用得比我还深入;

当你服务器类型是windows时,你的部署路径填的什么?
C:\path\to\project
还是
C:/path/to/project
还是
/C/path/to/project
还是
/path/to/project

我的部署路径,是按照需要远程执行的脚本类型来填写的

目前使用方式3(git bash),服务器配置为linux(实际为windows),git bash会将C:\、D:\之类的磁盘驱动器映射成/c/、/d/,所以部署路径是/d/path/to/project这种形式

之前使用方式2(cmd),服务器配置为windows(实际为windows),使用的部署路径是D:\path\to\project这种形式,这种形式也是能传输成功的,只是因为bat脚本执行的时候有奇怪的问题(与当前问题无关),才换成方式3的

我的建议就是,不管是运行bash还是cmd,在填写了远程执行脚本的情况下,就优先使用部署路径进行直接赋值(或者也可以按脚本的类型来自动进行路径转换),其次才按照OS类型进行路径转换

突然想到一个问题,按我刚刚说的方式,如果有人想在linux下执行powershell脚本,似乎又会出问题

我想到办法了,就是检测你的部署路径分隔符,然后我用你填的分隔符就行,这样你自己就能决定是什么。

更新了最新的1.16.3, 上文中的路径拼接的问题已经解决了,不过我将服务器类型切换为windows(实际为windows)还是构建失败了,原因是after-deploy脚本删除时使用的del命令无法识别。

我觉得这个不是goploy的问题,因为我的使用方式,不管是使用/拼接路径,还是使用git bash这种终端,毫无疑问都是linux的用法,并没有windows的痕迹,这种情况下,我觉得将服务器类型设置为linux反而更加贴切。可能之前啃bat的配置方式有点魔怔了,思路没走出来。

另外,之前的日志不刷新的问题也可以先忽略,我稍微对goploy进行了一点”压力测试“,没有出现这种情况,可能还是跟我之前的操作有关系(goployweb端操作构建、重置、初始化+服务器后台kill之类的,自己也有点混乱了)

感谢作者的耐心解答,这个问题我关闭咯~