需求场景
A commit B post-commit C
(workstation) --------------> (svn server) ---------------------> (major site)
(开发机) (线上站点)
开发机为A,有svn服务器B,以及线上站点所在服务器C。因为B硬盘不够等原因导致线上网站放在C上,不和svn服务器放在同一台机器B上。
现在,希望开发机A执行commit代码后,svn服务器B上自动同步代码到C服务器,使得线上网站自动更新。
我的方案
大体思路是用post-commit脚本,具体细节上有点麻烦,包括:
编写expect脚本->编写post-commit脚本->配置apache账户ssh-key->测试
下面是具体步骤
编写expect脚本
最先尝试用svn update root@xxx.xxx.xxx.xxx:/folder_name,但是命令不执行。考虑先ssh到C服务器,然后执行svn update。因为可以用ssh key,所以感觉不用密码登录C服务器,并执行后续操作,写到脚本中应该能行,做到自动化操作。
但是bash脚本中编写了ssh登录和svn update更新脚本,发现ssh登录后就不执行后续命令了。
发现expect这个解释器还是挺好用的,它是一种能够按照脚本内容里面设定的方式与交互式程序进行“会话”的程序。不多说,直接编写需要的脚本:
/var/svnroot/test/hooks/test.exp:
#!/usr/bin/expect -f
spawn ssh root@xxx.xxx.xxx.xxx #换成你的服务器ip或域名
expect "~"
send "svn update ~/workspace/test >> /tmp/svn_test_update.log 2>&1\r" #换成你的本地repo路径,记得先checkout过才行。日志文件名可修改。
send "exit\r"
expect eof
修改权限:
chown apache:apache test.exp
chown +x test.ext
编写post-commit脚本
就是去执行刚才的test.exp文件:
/var/svnroot/test/hooks/post-commit:
REPOS="$1"
REV="$2"
expect /var/svnroot/test/hooks/test.exp >> /tmp/svn_test_expect.log 2>&1 #/var/svnroot/test是svn服务器上repo的地址
修改权限:
chown apache:apache post-commit
chown +x post-commit
配置apache账户ssh-key
post-commit脚本是被apache用户执行的,那么脚本中ssh登录语句执行时,会查找/var/www/.ssh路径下的rsa密钥,那么现在来生成它。
创建.ssh目录
mkdir -p /var/www/.ssh
chown -R apache:apache /var/www/.ssh
修改apache账户为可登录:
vipw
#或者 vim /etc/passwd
找到apache所在行,修改最后面的/sbin/nologin为/bin/bash
用apache账号登录,生成ssh-key:
su apache
cd /var/www/
ssh-keygen
#然后各种回车
cat .ssh/id_rsa.pub
#用鼠标复制rsa公钥,并粘贴到服务器root目录下的.ssh/authorized_keys文件中(追加方式)
exit #退出apache账户
测试
测试用apache账户用ssh登录
ssh root@xxx.xxx.xxx.xxx
#按提示输入yes
这一步是必须的。因为初次用ssh登录,会提示验证同意,选择yes后,以后就不出这个提示了,就能正常执行post-commit脚本了。
好了,大概就是这个样子,希望对你有帮助。