背景简介: 目前对SVN配置库已经部署了svn sync同步机制,通过定时任务定期对主备配置库进行同步。但同步结果需要到服务器上去检查执行情况,或者连接到配置库查看最新的更新,在配置库比较大的情况下也不方便。
思路:svn info命令可以连接到svn配置库获取配置库的情况,其中包含revision 信息。通过python 调用svn info命令来获取主备配置库的revision信息,如果两者相同,则处于同步状态,或同步任务正常完成。否则,发送邮件通知两者不匹配。
python可以使用popen() 方法调用cmd 命令,或通过 read和readline 方法获取命令执行的结果。
方法:
1. 在执行检查任务的服务器上安装 svn ,这里使用的是visualsvn server,安装时可以只安装 admin tools和修改PATH环境变量即可。
2. 主备配置库的URL 写在一个文本文件中,建议另存为UTF-8编码格式,便于后续的处理
3. 编写代码
origin_vm_list=[]
source_vm_list=[]
with open(r"E:\backup-config\svnserver.txt", 'r') as f:
for line in f.readlines():
line = line.strip('\n').replace('\xef\xbb\xbf', '')
print(line)
origin_vm_list.append(line)
for svndb in origin_vm_list:
s_url = svndb.split(',')[0].strip()
d_url = svndb.split(',')[1].strip()
s_cmd="svn info " + str(s_url) + " --username a@zz.com --password *******"
d_cmd="svn info " + str(d_url) + " --username a@zz.com --password *******"
s_inst = os.popen(s_cmd.decode('utf-8').encode('GB2312'))
d_inst = os.popen(d_cmd.decode('utf-8').encode('GB2312'))
s_con = s_inst.readlines()
d_con = d_inst.readlines()
s_version=''
d_version=''
for line in s_con:
#print(line)
if "Revision" in line:
s_version = line.split(':')[1].strip()
#print(s_version)
for line in d_con:
#print(line)
if "Revision" in line:
d_version = line.split(':')[1].strip()
#print(d_version)
logtext=‘’
if s_version == d_version and s_version !='':
log="配置库 " + s_url + " 与备份库的版本匹配,源库版本号:"+s_version.strip('\n') +",备份库版本号 :"+d_version.strip('\n')
logtext = logtext + log + "\n"
print(log)
else:
log="配置库 " + s_url + " 与备份库的版本#### 不 ##### 匹配, 源库版本号:"+s_version.strip('\n') +",备份库版本号 :"+d_version.strip('\n')
logtext = logtext + log + "\n"
print(log)
4. 遇到的问题
(1)编码问题
通过文本文件读取的字符串默认是utf-8编码格式,而fopen执行的命令字符串,或者说cmd 命令行默认是gb2312编码格式(cp936)。这种情况下,如果SVN 的URL都是英文字符,倒也不会影响执行。但如果URL包含中文字符,就需要对命令字符串进行处理。基于从文件中获取的URL拼凑玩命令字符串之后,在送给popen执行前对此字符串进行解码和编码处理。
s_cmd.decode('utf-8').encode('gb2312')
(2) svn.exe执行文件位置
测试发现,使用popen执行ipconfig、netstat -r等系统常规命令都可以正常执行和返回结果。但执行svn命令时系统没有反馈结果,此时,在服务器上打开cmd 手动执行svn info 探测命令是可以的。但通过程序就是不行,在命令行中加入svn的绝对路径也不行。基于ipconfig等命令可以执行的情况,将svn以及目录下相关的dll文件都复制到 c:\windows\system32目录下,popen调用可以正常完成。