SVN+Ansible搭建自動化提交代碼
一、基本的SVN的服務配置
查看可使用的 svn 命令:
[root@wchongeweb ~]# svn
svn svndumpfilter svnrdump svnsync
svnadmin svnlook svnserve svnversion
1、新建一個目錄用於存儲SVN所有文件
[root@wchongeweb ~]# mkdir /home/svn
2、新建一個版本倉庫
[root@wchongeweb ~]# svnadmin create /home/svn/project
3、初始化版本倉庫中的目錄
[root@wchongeweb ~]# mkdir -p /root/project/{server,client,test} (建立臨時目錄) [root@wchongeweb ~]# svn import /root/project/ file:///home/svn/project/ -m "svn dir init" Adding /root/project/test Adding /root/project/server Adding /root/project/client Committed revision 1. [root@wchongeweb ~]# rm -rf /root/project/ (刪除臨時建立的目錄)
4、添加用戶
要添加SVN用戶非常簡單,只需在/home/svn/project/conf/passwd文件添加一個形如“username=password”的條目就可以了。為了測試,我添加了如下內容:
[users] # harry = harryssecret # sally = sallyssecret pm = pm_pw server_group = server_pw client_group = client_pw test_group = test_pw
5、修改用戶訪問策略
/home/svn/project/conf/authz記錄用戶的訪問策略,以下是參考:
[groups] project_p= pm project_s = server1,server2,server3 project_c = client1,client2,client3 project_t = test1,test1,test1 [project:/] @project_p = rw * = [project:/server] @project_p = rw @project_s = rw * = [project:/client] @project_p = rw @project_c = rw * = [project:/doc] @project_p = rw @project_s = r @project_c = r @project_t = r * =
說明:以上信息表示,只有project_p用戶組有根目錄的讀寫權。r表示對該目錄有讀權限,w表示對該目錄有寫權限,rw表示對該目錄有讀寫權限。
最後一行的*=表示,除了上面設置了權限的用戶組之外,其他任何人都被禁止訪問本目錄。這個很重要,一定要加上!
6、修改svnserve.conf文件,讓用戶和策略配置升效.
svnserve.conf內容如下:
[general] anon-access = none auth-access = write password-db = /home/svn/project/conf/passwd authz-db = /home/svn/project/conf/authz
7、啟動服務器
# svnserve -d -r /home/svn
註意:如果修改了svn配置,需要重啟svn服務,步驟如下:
# ps -aux|grep svnserve # kill -9 ID號 # svnserve -d -r /home/svn
8、測試服務器
# svn co svn://192.168.60.10/project Authentication realm: <svn://192.168.60.10:3690> 92731041-2dae-4c23-97fd-9e1ed7f0d18d Password for ‘root‘: Authentication realm: <svn://192.168.60.10:3690> 92731041-2dae-4c23-97fd-9e1ed7f0d18d Username: server_group Password for ‘server_group‘: svn: Authorization failed ( server_group沒用根目錄的訪問權 ) # svn co svn://192.168.60.10/project Authentication realm: <svn://192.168.60.10:3690> 92731041-2dae-4c23-97fd-9e1ed7f0d18d Password for ‘root’: Authentication realm: <svn://192.168.60.10:3690> 92731041-2dae-4c23-97fd-9e1ed7f0d18d Username: pm Password for ‘pm’: A project/test A project/server A project/client Checked out revision 1. ( 測試提取成功 ) # cd project/server # vim main.c # svn add main.c # svn commit main.c -m “測試一下我的C程序,看什麽看,不行啊??” Adding main.c Transmitting file data . Committed revision 2. ( 測試提交成功 )
二,結合 ansible 做代碼自動部署
實驗環境:
- svn服務器:192.168.0.120 (vm_mac.guli.com)
- 目標服務器:192.168.0.171 (lamp1.guli.com)
測試目標:使用 svn 提交代碼,如果提交時添加註釋中含有 "auto_deploy" 字符串,則自動部署到目標服務器中。
編輯 post-commit 腳本:
[root@vm_mac hooks]# vi /home/svn/project/hooks/post-commit #!bin/bash REPOS="$1" REV="$2" export LC_CTYPE=en_US.UTF-8 if (svnlook log -r $REV /home/svn/project | grep "auto_deploy"); then echo "`date` $REV auto deploy command received" >> /tmp/test_svnautocommit.txt ansible lamp -a "svn checkout "svn://192.168.0.120/project" /var/www/html/web1 --force --username="pm" --password="pm_pw" --non-interactive" fi
腳本說明:
如果提交時添加註釋中含有 "auto_deploy",則記錄一條簡單的日誌,並且執行一條 ansible 命令,意思是在 lamp 組的所有主機上(這裏只定義了一個 lamp1.guli.com),執行 svn checkout 操作,將目標 repo 檢出到本地 /var/www/html/web1。第一次執行時,如果目錄不存在,會自動創建目錄;否則進行檢出。
ansible 的用戶組配置:
[root@vm_mac hooks]# vi /etc/ansible/hosts
[lamp]
lamp1.guli.com
ansible 主機和 lamp1 建立 ssh 信任步驟等暫略,註意那是必要的。
測試:
1.lamp1 主機上,現在還沒有創建 web1 目錄:
[root@lamp1 html]# pwd /var/www/html [root@lamp1 html]# ll total 4 -rw-r--r-- 1 root root 24 Jul 16 14:54 index.html [root@lamp1 html]# hostname lamp1
2.在 svn 服務器上,現在 /root/project/test 目錄下有如下文件,
[root@vm_mac test]# pwd /root/project/test [root@vm_mac test]# ll total 0 -rw-r--r-- 1 root root 0 Aug 5 11:00 ccc -rw-r--r-- 1 root root 0 Aug 5 11:06 ddd -rw-r--r-- 1 root root 0 Aug 5 11:37 eee -rw-r--r-- 1 root root 0 Aug 5 12:31 fff
3.我們添加一個 ggg 文件,並且提交
[root@vm_mac test]# touch ggg [root@vm_mac test]# svn add ggg A ggg [root@vm_mac test]# svn commit -m "auto_deploy" Adding test/ggg Transmitting file data . Committed revision 47.
現在版本是 47
4.查看 lamp1 上是否同步過去了:
[root@lamp1 html]# ll total 8 -rw-r--r-- 1 root root 24 Jul 16 14:54 index.html drwxr-xr-x 6 root root 4096 Aug 5 13:29 web1 [root@lamp1 html]# ll web1/test/ total 0 -rw-r--r-- 1 root root 0 Aug 5 13:29 ccc -rw-r--r-- 1 root root 0 Aug 5 13:29 ddd -rw-r--r-- 1 root root 0 Aug 5 13:29 eee -rw-r--r-- 1 root root 0 Aug 5 13:29 fff -rw-r--r-- 1 root root 0 Aug 5 13:29 ggg
我們看到,在 /var/www/html 目錄下多了一個 web1 目錄,並且 test 子目錄的內容是同步的
5.現在到 lamp1 上刪除一個文件 ccc ,並提交:
[root@vm_mac test]# svn del ccc D ccc [root@vm_mac test]# svn commit -m "auto_deploy" Deleting test/ccc Committed revision 48. [root@vm_mac test]# ll total 0 -rw-r--r-- 1 root root 0 Aug 5 11:06 ddd -rw-r--r-- 1 root root 0 Aug 5 11:37 eee -rw-r--r-- 1 root root 0 Aug 5 12:31 fff -rw-r--r-- 1 root root 0 Aug 5 13:28 ggg
現在版本號到了 48
6.再查看 lamp1 上是否同步過去了:
[root@lamp1 html]# ll web1/test/ total 0 -rw-r--r-- 1 root root 0 Aug 5 13:29 ddd -rw-r--r-- 1 root root 0 Aug 5 13:29 eee -rw-r--r-- 1 root root 0 Aug 5 13:29 fff -rw-r--r-- 1 root root 0 Aug 5 13:29 ggg
可以看到 ccc 文件成功被刪除了。
好了,到了這裏已經基本實現了。這是使用 svn 檢出實現的方式。
後續需要完善的幾個方面:
1.實驗裏的檢出可能沒有加密,後面考慮使用 svn+ssh 協議,類似這樣,更為安全,這個等有時間再完善一下:
# Checkout subversion repository to specified folder. - subversion: repo=svn+ssh://192.168.0.120/project dest=/var/www/html/web1 ansible lamp -m subversion -a "repo=svn+ssh://192.168.0.120/project dest=/var/www/html/web1 username=pm password=pm_pw revision=$REV"
2.檢出時,加上 -r $REV 應該更好,因為默認是檢出 HEAD 版本,對於這一點待查
3.我們根據註釋裏的 auto_deploy 觸發自動部署線上環境,也可以使用其他字符串,如 auto_test_deploy 觸發自動部署測試環境。進一步設想,是開發一個 web 界面,手動選擇自動部署測試環境,或者部署線上環境,這樣比較直觀好看一些。
4.checkout 是每次都拷貝覆蓋,還是只更新需要更新的?
我們實驗一下 svn update:
ansible lamp -a "svn update "svn://192.168.0.120/project" /var/www/html/web1 --force --username="pm" --password="pm_pw" --non-interactive"
增加 hhh 文件,並提交,註釋為空,不要觸發自動部署:
[root@vm_mac test]# touch hhh [root@vm_mac test]# svn add hhh A hhh [root@vm_mac test]# svn commit -m "" Adding test/hhh Transmitting file data . Committed revision 49. [root@vm_mac test]# ansible lamp -a "svn update "svn://192.168.0.120/project" /var/www/html/web1 --force --username="pm" --password="pm_pw" --non-interactive" lamp1.guli.com | SUCCESS | rc=0 >> Skipped ‘svn://192.168.0.120/project‘ A /var/www/html/web1/test/hhh Updated to revision 49. Summary of conflicts: Skipped paths: 1
查看 lamp1 上是否同步過去了:
[root@lamp1 html]# ll web1/test/ total 0 -rw-r--r-- 1 root root 0 Aug 5 13:29 ddd -rw-r--r-- 1 root root 0 Aug 5 13:29 eee -rw-r--r-- 1 root root 0 Aug 5 13:29 fff -rw-r--r-- 1 root root 0 Aug 5 13:29 ggg -rw-r--r-- 1 root root 0 Aug 5 13:38 hhh
可以看到成功添加了 hhh
試一試刪除 ddd 文件,並且提交:
[root@vm_mac test]# ll total 0 -rw-r--r-- 1 root root 0 Aug 5 11:06 ddd -rw-r--r-- 1 root root 0 Aug 5 11:37 eee -rw-r--r-- 1 root root 0 Aug 5 12:31 fff -rw-r--r-- 1 root root 0 Aug 5 13:28 ggg -rw-r--r-- 1 root root 0 Aug 5 13:38 hhh [root@vm_mac test]# svn del ddd D ddd [root@vm_mac test]# svn commit -m "" Deleting test/ddd Committed revision 50. [root@vm_mac test]# ansible lamp -a "svn update "svn://192.168.0.120/project" /var/www/html/web1 --force --username="pm" --password="pm_pw" --non-interactive" lamp1.guli.com | SUCCESS | rc=0 >> Skipped ‘svn://192.168.0.120/project‘ D /var/www/html/web1/test/ddd Updated to revision 50. Summary of conflicts: Skipped paths: 1
查看 lamp1 上是否同步過去了:
[root@lamp1 html]# ll web1/test/ total 0 -rw-r--r-- 1 root root 0 Aug 5 13:29 eee -rw-r--r-- 1 root root 0 Aug 5 13:29 fff -rw-r--r-- 1 root root 0 Aug 5 13:29 ggg -rw-r--r-- 1 root root 0 Aug 5 13:38 hhh
已經刪除了 ddd 文件,證明是同步了
註,svn 非交互式:--non-interactive,第一次 checkout 不再問你是否需要保存密碼。
看來也是可行的。
到這裏為止,已經可以用一個實際的項目做部署測試,後面有時間再來補上這一部分。但是我想看了這整個的步驟,自己做實驗驗證一下也比較簡單了。
Nginx 反向代理配置
# svn update server server { listen 80; server_name dosvn.wljiashi.cn; #access_log off; access_log /tmp/dosvn.log; location / { include proxy.conf proxy_pass http://db01:8180; } }GOOD LUCK! 參考項目 https://github.com/ACHONGE/subversion.git
參考博客 https://www.jianshu.com/p/50b7dc07f1f1
SVN+Ansible搭建自動化提交代碼