Ansible源码分析之svn模块
Ansible的svn模块代码路径
/usr/lib/python2.6/site-packages/ansible/modules/core/source_control
模块使用:
#ansiblelocalhost-msubversion-a"repo=https://code.svn.com/project1/patch_04dest=~/testusername=testpassword=test123export=yesforce=yes"
-m subversion表示指定subversion模块,这里的模块名称都是modules目录下的脚本名称
-a 指定模块参数,每个模块的参数不同
repo 指定svn的URL
dest 指定代码checkout或者export的绝对路径
username 指定用户名
password 指定密码
export 指定导出而不是checkout或者update
force 强制执行
如果执行过程有以下错误
"msg":"svn:Can'tconvertstringfrom'UTF-8'tonativeencoding:\nsvn:/root/john/test/web/WebRoot/html/?\\230?\\181?\\160?\\239?\\189?\\135?\\230?\\130?\\138",
解决办法就是:
将系统的字符编号和ansible的字符编号都设置成en_US.UTF-8
#echo$LANGen_US.UTF-8#cat/etc/ansible/ansible.cfg|grepmodule_langmodule_lang=en_US.UTF-8
同时在subversion.py中设置的默认字符编码就是C
os.environ['LANG']='C'
classSubversion(object):def__init__(self,module,dest,repo,revision,username,password,svn_path):self.module=moduleself.dest=destself.repo=repoself.revision=revisionself.username=usernameself.password=passwordself.svn_path=svn_path
定义一个Python类Subversion和一些类参数
def_exec(self,args):bits=[self.svn_path,'--non-interactive','--trust-server-cert','--no-auth-cache',]ifself.username:bits.extend(["--username",self.username])ifself.password:bits.extend(["--password",self.password])bits.extend(args)rc,out,err=self.module.run_command(bits,check_rc=True)returnout.splitlines()
定义类函数_exec,调用module_utils/basic.py中的run_command 函数
defcheckout(self):'''Createsnewsvnworkingdirectoryifitdoesnotalreadyexist.'''self._exec(["checkout","-r",self.revision,self.repo,self.dest])defexport(self,force=False):'''Exportsvnrepotodirectory'''cmd=["export"]ifforce:cmd.append("--force")cmd.extend(["-r",self.revision,self.repo,self.dest])self._exec(cmd)
定义checkout和export函数,分别执行svn checkout 或者svn export
defswitch(self):'''Changeworkingdirectory'srepo.'''#switchtoensurewearepointingatcorrectrepo.self._exec(["switch",self.repo,self.dest])defupdate(self):'''Updateexistingsvnworkingdirectory.'''self._exec(["update","-r",self.revision,self.dest])defrevert(self):'''Revertsvnworkingdirectory.'''self._exec(["revert","-R",self.dest])defget_revision(self):'''RevisionandURLofsubversionworkingdirectory.'''text='\n'.join(self._exec(["info",self.dest]))rev=re.search(r'^Revision:.*$',text,re.MULTILINE).group(0)url=re.search(r'^URL:.*$',text,re.MULTILINE).group(0)returnrev,url
定义svn switch, svn update,svn revert,svn get_revision相关的函数
defhas_local_mods(self):'''Trueifrevisionedfileshavebeenaddedormodified.Unrevisionedfilesareignored.'''lines=self._exec(["status",self.dest])#Matchonlyrevisionedfiles,i.e.ignorestatus'?'.regex=re.compile(r'^[^?]')#Haslocalmodsifmorethan0modifedrevisionedfiles.returnlen(filter(regex.match,lines))>0defneeds_update(self):curr,url=self.get_revision()out2='\n'.join(self._exec(["info","-r","HEAD",self.dest]))head=re.search(r'^Revision:.*$',out2,re.MULTILINE).group(0)rev1=int(curr.split(':')[1].strip())rev2=int(head.split(':')[1].strip())change=Falseifrev1<rev2:change=Truereturnchange,curr,head
两个函数执行svn status 和svn info
defmain():module=AnsibleModule(argument_spec=dict(dest=dict(required=True),repo=dict(required=True,aliases=['name','repository']),revision=dict(default='HEAD',aliases=['rev','version']),force=dict(default='no',type='bool'),username=dict(required=False),password=dict(required=False),executable=dict(default=None),export=dict(default=False,required=False,type='bool'),),supports_check_mode=True)dest=os.path.expanduser(module.params['dest'])repo=module.params['repo']revision=module.params['revision']force=module.params['force']username=module.params['username']password=module.params['password']svn_path=module.params['executable']ormodule.get_bin_path('svn',True)export=module.params['export']os.environ['LANG']='C'svn=Subversion(module,dest,repo,revision,username,password,svn_path)ifexportornotos.path.exists(dest):before=Nonelocal_mods=Falseifmodule.check_mode:module.exit_json(changed=True)ifnotexport:svn.checkout()else:svn.export(force=force)elifos.path.exists("%s/.svn"%(dest,)):#Ordermatters.Needtogetlocalmodsbeforeswitchtoavoidfalse#positives.Needtoswitchbeforereverttoensurewearerevertingto#correctrepo.ifmodule.check_mode:check,before,after=svn.needs_update()module.exit_json(changed=check,before=before,after=after)before=svn.get_revision()local_mods=svn.has_local_mods()svn.switch()iflocal_mods:ifforce:svn.revert()else:module.fail_json(msg="ERROR:modifiedfilesexistintherepository.")svn.update()else:module.fail_json(msg="ERROR:%sfolderalreadyexists,butitsnotasubversionrepository."%(dest,))ifexport:module.exit_json(changed=True)else:after=svn.get_revision()changed=before!=afterorlocal_modsmodule.exit_json(changed=changed,before=before,after=after)#importmodulesnippetsfromansible.module_utils.basicimport*main()
这里就是svn模块的main函数,先判断是export还是checkout,再判断dest指定的目录是否存在,再判断版本有没有更新
参考文档:
https://github.com/ansible/ansible/issues/6737#ref-commit-42aa6ff
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。