• 首页
  • IT技术
  • 生活
  • ISSUE
  • SVN
Bernie Yu

复刻生活

迁移VPS上的SVN到Synology,并实现增量备份和邮件通知

Posted on 2015年4月12日

之前的SVN服务器部署在VPS上,主要功能包括:

  1. nginx+apache+svn,可以通过http访问;
  2. 自定义了post-commit,在每次收到版本提交时
    • 自动发送邮件通知更新内容;
    • 自动增量备份版本库,并把备份文件上传到指定的FTP

post-commit的内容如下:

#!/bin/sh

REPOS="$1"
REV="$2"

export LANG="en_US.UTF-8"

#"$REPOS"/hooks/mailer.py commit "$REPOS" $REV "$REPOS"/mailer.conf
/usr/local/bin/svnnotify --repos-path "$1" --revision "$2" --to someone@bernieyu.com,someone2@bernieyu.com --from svn@bernieyu.com --handler "HTML::ColorDiff" --smtp smtp.bernieyu.com --smtp-user svn@bernieyu.com --smtp-pass password  --svnlook /usr/bin/svnlook --subject-prefix '[SVN Update]'

svnadmin dump "$REPOS" --revision "$REV" --incremental >/home/svn/dev/export/rev_$REV.dump

ftp -n<<!
open bernieyoo.bernieyu.com
user ftpuser password
binary
cd /svnbak
lcd /home/svn/dev/export
prompt
put rev_$REV.dump
close
bye
!

rm -f /home/svn/dev/export/rev_$REV.dump

 

考虑到数据安全性,以及连接SVN的速度,决定把SVN迁移到家里的Synology上。

1. 在Synology的套件中心里安装SVN;

安装好后有一个问题,就是SVN的存储目录不能指定放在哪块硬盘,比如我想放在/volume2/svn,而安装后会自动安装在/volume4/svn. 于是将/volume4/svn删除,然后再建立到/volume2/svn的软连接

rm -rf /volume4/svn
ln -s /volume2/svn /volume4/svn

 

2. 建立repository

在Synology中打开Svn管理页面,创建名为dev的repository,并创建用户。

 

3. 导出VPS上的SVN版本库, 并复制到Synology

#!/bin/sh

cd ~/svnbak

svndump(){
	file_name=rev_$1.dump
	svnadmin dump /home/svn/dev -r $1 --incremental > $file_name
}

ver=`svnlook youngest /home/svn/dev`

svndump 0;

for i in `seq $ver`; do
	svndump $i;
done;


exit 0

 

4. 导入SVN数据到Synology

#!/bin/sh

svnadmin load /volume2/svn/dev < /volume2/doc/projects/svnbak/dev/rev_0.dump;

for i in `seq 184`; do
  svnadmin load /volume2/svn/dev < /volume2/doc/projects/svnbak/dev/rev_$i.dump;
done;


exit 0

 

5. 修改post-commit,以实现邮件通知和自动备份功能

  • mailer.py需要安装python-svn,但ipkg里的版本与Synology套件中心提供的python版本不一样,于是不考虑了
  • svnnotify没有在ipkg里找到

于是考虑用curl把版本库信息提交到一个web页面,再由这个页面发送邮件。但是一查curl的帮助,发现最新版的已经可以直接使用Smtp发送邮件了,大喜,一试发现竟然真的可以,而且还支持SMTPS

#!/bin/sh

REPOS="$1"
REV="$2"

export LANG="en_US.UTF-8"
#生成备份
svnadmin dump "$REPOS" --revision "$REV" --incremental >/volume2/doc/projects/svnbak/dev/rev_$REV.dump
#复制到baidu云的自动备份目录
cp /volume2/doc/projects/svnbak/dev/rev_$REV.dump /volume2/doc/baidu/svn_bak/dev/rev_$REV.dump

#得到版本更新相关信息
svnuid=`svnlook uuid $REPOS`
author=`svnlook author -r $REV $REPOS`
date=`svnlook date -r $REV $REPOS`
log=`svnlook log -r $REV $REPOS`
changed=`svnlook changed -r $REV $REPOS`

file="content.txt"

smtpserver="smtps://smtp.bernieyu.com:465"
mailfrom="svn@bernieyu.com"
mailrcpt="someone@bernieyu.com"
smtpuser="svn@bernieyu.com"
smtppwd="password"

#HTML邮件的CSS,从svnnotify复制来的
css="<style type=\"text/css\"> <!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff;}
 #msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
 #msg dt:after { content:':';}
 #msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg{ font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
 #msg dl a { font-weight: bold}
 #msg dl a:link    { color:#fc3; }
 #msg dl a:active  { color:#ff0; }
 #msg dl a:visited { color:#cc6; }
 #msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
 #logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
 #logmsg p, #logmsg pre, #logmsg blockquote{ margin: 0 0 1em 0; }
 #logmsg p, #logmsg li, #logmsg dt, #logmsg dd{ line-height: 14pt; }
 #logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6{ margin: .5em 0; }
 #logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child{ margin-top: 0; }
 #logmsg ul, #logmsg ol{ padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
 #logmsg ul { text-indent: -1em; padding-left: 1em; }
 #logmsg ol { text-indent: -1.5em; padding-left: 1.5em;}
 #logmsg &gt; ul, #logmsg &gt; ol{ margin: 0 0 1em 0; }
 #logmsg pre { background: #eee; padding: 1em; }
 #logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
 #logmsg dl { margin: 0; }
 #logmsg dt { font-weight: bold; }
 #logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
 #logmsg dd:before { content:'�';}
 #logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
 #logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
 #logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
 #logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
 #logmsg table th.Corner { text-align: left; }
 #logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
 #header, #footer{ color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
 #patch { width: 100%; }
 #patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
 #patch .propset h4, #patch .binary h4{margin:0;}
 #patch pre {padding:0;line-height:1.2em;margin:0;}
 #patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
 #patch .propset .diff, #patch .binary .diff{padding:10px 0;}
 #patch span {display:block;padding:0 10px;}
 #patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile{border:1px solid #ccc;margin:10px 0;}
 #patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
 #patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
 #patch .lines, .info{color:#888;background:#fff;}
 -->}
</style>"

echo "From: \"SVN\" <$mailfrom>
To: \"Bernie Yu\" <$mailrcpt>
Subject: [SVN Update][$REV] $log
Content-Type: text/html; charset=\"us-ascii\"

<html> <head>$css</head> <body>
<div id=\"msg\">
    <dl class=\"meta\">
      <dt>Revision</dt> <dd>$REV</dd>
      <dt>Author</dt> <dd>$author</dd>
      <dt>Date</dt> <dd>$date</dd>
    </dl>

<h3>Log Message</h3>
<pre>$log</pre>

<h3>Change Detail</h3>
<ul>" > $file

OLDIFS=$IFS
IFS=$'\n'
for line in $changed
do
    echo "<li>$line</li>" >> $file
done
IFS=$OLDIFS

echo "</ul>

</div>
</body> </html>" >> $file

curl --url "$smtpserver" --ssl-reqd --mail-from "$mailfrom" --mail-rcpt "$mailrcpt" --upload-file $file --user "$smtpuser:$smtppwd" --insecure

 

测试成功,搞定!

 

PS:

目前遗留的问题一是Synology自带的SVN不支持HTTP访问,只能通过SVN协议访问。在路由器添加了端口映射后,用SVN协议访问影响不大。安装SVN后需要重启一下Synology,我当时没重启,结果端口映射后怎么也访问不到。二是SSH+SVN还没有搞定,因为SVN添加的用户只是SVN的用户而不是SSH用户,暂时还找不到解决办法。

Posted in: IT技术, SVN, Synology | Tagged: SVN, Synology
← svnlook命令集
必须收藏的一些ZF网站 →
2015年4月
一 二 三 四 五 六 日
« 三   五 »
 12345
6789101112
13141516171819
20212223242526
27282930  

标签

Android awstats bug tracking chrome database EXSi ffmpeg ffplay fpm GeoIP git hls HTML5 iOS ipkg JavaScript JSON linux lsyncd mantis MariaDB mysql N54l nginx php rtmp SVN svnlook Synology Video vps WordPress yamdi 同步 字幕 安全控件 安装 实用信息 录制 摄像头 浏览器 生活 直播 迅雷 黑群晖

近期文章

  • VPS从DirectSpace迁移到vultr
  • 查看阻止电脑进入休眠的程序
  • HDCN,纪念
  • [转] lsyncd实时同步搭建指南——取代rsync+inotify
  • 在群晖NAS上搭建MantisBT Bug跟踪系统

分类目录

  • Android
  • Database
  • Git
  • IT技术
  • Linux
  • SVN
  • Synology
  • WEB
  • WordPress
  • 未分类
  • 生活

文章归档

  • 2016年5月
  • 2015年12月
  • 2015年10月
  • 2015年7月
  • 2015年6月
  • 2015年5月
  • 2015年4月
  • 2015年3月

链接·工具

  • 百度云观测
  • 360云监控
  • 草料网二维码生成
  • 工信部投诉
  • 快递投诉
  • 北京社保查询
  • 北京公积金查询
  • 执业医师查询
  • 在线查毒:VirusTotal
  • 在线查毒:VirSCAN

Copyright © 2025 Bernie Yu.

Theme by ThemeHall.