@ -58,16 +58,28 @@ options:
required : false
default : " no "
choices : [ " yes " , " no " ]
aliases : [ ]
refresh :
description :
- Enable autorefresh of the repository .
required : false
default : " yes "
choices : [ " yes " , " no " ]
aliases : [ ]
notes : [ ]
requirements : [ zypper ]
priority :
description :
- Set priority of repository . Packages will always be installed
from the repository with the smallest priority number .
required : false
version_added : " 2.1 "
overwrite_multiple :
description :
- Overwrite multiple repository entries , if repositories with both name and
URL already exist .
required : false
default : " no "
choices : [ " yes " , " no " ]
version_added : " 2.1 "
requirements :
- " zypper >= 1.0 # included in openSuSE >= 11.1 or SuSE Linux Enterprise Server/Desktop >= 11.0 "
'''
EXAMPLES = '''
@ -83,18 +95,10 @@ EXAMPLES = '''
REPO_OPTS = [ ' alias ' , ' name ' , ' priority ' , ' enabled ' , ' autorefresh ' , ' gpgcheck ' ]
def zypper_version ( module ) :
""" Return (rc, message) tuple """
cmd = [ ' /usr/bin/zypper ' , ' -V ' ]
rc , stdout , stderr = module . run_command ( cmd , check_rc = False )
if rc == 0 :
return rc , stdout
else :
return rc , stderr
def _parse_repos ( module ) :
""" parses the output of zypper -x lr and return s a parse repo dictionary"""
""" parses the output of zypper -x lr and return a parse repo dictionary """
cmd = [ ' /usr/bin/zypper ' , ' -x ' , ' lr ' ]
from xml . dom . minidom import parseString as parseXML
rc , stdout , stderr = module . run_command ( cmd , check_rc = False )
if rc == 0 :
@ -120,81 +124,81 @@ def _parse_repos(module):
d [ ' stdout ' ] = stdout
module . fail_json ( msg = ' Failed to execute " %s " ' % " " . join ( cmd ) , * * d )
def _parse_repos_old ( module ) :
""" parses the output of zypper sl and returns a parse repo dictionary """
cmd = [ ' /usr/bin/zypper ' , ' sl ' ]
repos = [ ]
rc , stdout , stderr = module . run_command ( cmd , check_rc = True )
for line in stdout . split ( ' \n ' ) :
matched = re . search ( r ' \ d+ \ s+ \ | \ s+(?P<enabled> \ w+) \ s+ \ | \ s+(?P<autorefresh> \ w+) \ s+ \ | \ s+(?P<type> \ w+) \ s+ \ | \ s+(?P<name> \ w+) \ s+ \ | \ s+(?P<url>.*) ' , line )
if matched == None :
continue
m = matched . groupdict ( )
m [ ' alias ' ] = m [ ' name ' ]
m [ ' priority ' ] = 100
m [ ' gpgcheck ' ] = 1
repos . append ( m )
return repos
def repo_exists ( module , old_zypper , * * kwargs ) :
def repo_subset ( realrepo , repocmp ) :
def _repo_changes ( realrepo , repocmp ) :
for k in repocmp :
if k not in realrepo :
return False
for k , v in realrepo . items ( ) :
if k in repocmp :
if v . rstrip ( " / " ) != repocmp [ k ] . rstrip ( " / " ) :
return False
if repocmp [ k ] and k not in realrepo :
return True
if old_zypper :
repos = _parse_repos_old ( module )
else :
repos = _parse_repos ( module )
for repo in repos :
if repo_subset ( repo , kwargs ) :
for k , v in realrepo . items ( ) :
if k in repocmp and repocmp [ k ] :
valold = str ( repocmp [ k ] or " " )
valnew = v or " "
if k == " url " :
valold , valnew = valold . rstrip ( " / " ) , valnew . rstrip ( " / " )
if valold != valnew :
return True
return False
def repo_exists ( module , repodata , overwrite_multiple ) :
existing_repos = _parse_repos ( module )
def add_repo ( module , repo , alias , description , disable_gpg_check , old_zypper , refresh ) :
if old_zypper :
cmd = [ ' /usr/bin/zypper ' , ' sa ' ]
# look for repos that have matching alias or url to the one searched
repos = [ ]
for kw in [ ' alias ' , ' url ' ] :
name = repodata [ kw ]
for oldr in existing_repos :
if repodata [ kw ] == oldr [ kw ] and oldr not in repos :
repos . append ( oldr )
if len ( repos ) == 0 :
# Repo does not exist yet
return ( False , False , None )
elif len ( repos ) == 1 :
# Found an existing repo, look for changes
has_changes = _repo_changes ( repos [ 0 ] , repodata )
return ( True , has_changes , repos )
elif len ( repos ) == 2 and overwrite_multiple :
# Found two repos and want to overwrite_multiple
return ( True , True , repos )
else :
# either more than 2 repos (shouldn't happen)
# or overwrite_multiple is not active
module . fail_json ( msg = ' More than one repo matched " %s " : " %s " ' % ( name , repos ) )
def modify_repo ( module , repodata , old_repos ) :
repo = repodata [ ' url ' ]
cmd = [ ' /usr/bin/zypper ' , ' ar ' , ' --check ' ]
if repodata [ ' name ' ] :
cmd . extend ( [ ' --name ' , repodata [ ' name ' ] ] )
if repo . startswith ( " file:/ " ) and old_zypper :
cmd . extend ( [ ' -t ' , ' Plaindir ' ] )
else :
cmd . extend ( [ ' -t ' , ' plaindir ' ] )
if repodata [ ' priority ' ] :
cmd . extend ( [ ' --priority ' , str ( repodata [ ' priority ' ] ) ] )
if description :
cmd . extend ( [ ' --name ' , description ] )
if repodata [ ' enabled ' ] == ' 0 ' :
cmd . append( ' --disable ' )
if disable_gpg_check and not old_zypper :
if repodata [ ' gpgcheck ' ] == ' 1 ' :
cmd . append ( ' --gpgcheck ' )
else :
cmd . append ( ' --no-gpgcheck ' )
if refresh :
if re podata[ ' autore fresh' ] == ' 1 ' :
cmd . append ( ' --refresh ' )
cmd . append ( repo )
if not repo . endswith ( ' .repo ' ) :
cmd . append ( alias )
cmd . append ( repodata [ ' alias ' ] )
if old_repos is not None :
for oldrepo in old_repos :
remove_repo ( module , oldrepo [ ' url ' ] )
rc , stdout , stderr = module . run_command ( cmd , check_rc = False )
changed = rc == 0
if rc == 0 :
changed = True
elif ' already exists. Please use another alias ' in stderr :
changed = False
else :
#module.fail_json(msg=stderr if stderr else stdout)
if stderr :
module . fail_json ( msg = stderr )
else :
@ -203,16 +207,8 @@ def add_repo(module, repo, alias, description, disable_gpg_check, old_zypper, re
return changed
def remove_repo ( module , repo , alias , old_zypper ) :
if old_zypper :
cmd = [ ' /usr/bin/zypper ' , ' sd ' ]
else :
cmd = [ ' /usr/bin/zypper ' , ' rr ' ]
if alias :
cmd . append ( alias )
else :
cmd . append ( repo )
def remove_repo ( module , repo ) :
cmd = [ ' /usr/bin/zypper ' , ' rr ' , repo ]
rc , stdout , stderr = module . run_command ( cmd , check_rc = True )
changed = rc == 0
@ -237,59 +233,68 @@ def main():
description = dict ( required = False ) ,
disable_gpg_check = dict ( required = False , default = ' no ' , type = ' bool ' ) ,
refresh = dict ( required = False , default = ' yes ' , type = ' bool ' ) ,
priority = dict ( required = False , type = ' int ' ) ,
enabled = dict ( required = False , default = ' yes ' , type = ' bool ' ) ,
overwrite_multiple = dict ( required = False , default = ' no ' , type = ' bool ' ) ,
) ,
supports_check_mode = False ,
)
repo = module . params [ ' repo ' ]
alias = module . params [ ' name ' ]
state = module . params [ ' state ' ]
name = module . params [ ' name ' ]
description = module . params [ ' description ' ]
disable_gpg_check = module . params [ ' disable_gpg_check ' ]
refresh = module . params [ ' refresh ' ]
overwrite_multiple = module . params [ ' overwrite_multiple ' ]
repodata = {
' url ' : repo ,
' alias ' : alias ,
' name ' : module . params [ ' description ' ] ,
' priority ' : module . params [ ' priority ' ] ,
}
# rewrite bools in the language that zypper lr -x provides for easier comparison
if module . params [ ' enabled ' ] :
repodata [ ' enabled ' ] = ' 1 '
else :
repodata [ ' enabled ' ] = ' 0 '
if module . params [ ' disable_gpg_check ' ] :
repodata [ ' gpgcheck ' ] = ' 0 '
else :
repodata [ ' gpgcheck ' ] = ' 1 '
if module . params [ ' refresh ' ] :
repodata [ ' autorefresh ' ] = ' 1 '
else :
repodata [ ' autorefresh ' ] = ' 0 '
def exit_unchanged ( ) :
module . exit_json ( changed = False , repo = repo , state = state , name = name )
rc , out = zypper_version ( module )
match = re . match ( r ' zypper \ s+( \ d+) \ .( \ d+) \ .( \ d+) ' , out )
if not match or int ( match . group ( 1 ) ) > 0 :
old_zypper = False
else :
old_zypper = True
module . exit_json ( changed = False , repodata = repodata , state = state )
# Check run-time module parameters
if state == ' present ' and not repo :
module . fail_json ( msg = ' Module option state=present requires repo ' )
if state == ' absent ' and not repo and not name :
if state == ' absent ' and not repo and not alias :
module . fail_json ( msg = ' Alias or repo parameter required when state=absent ' )
if repo and repo . endswith ( ' .repo ' ) :
if name :
module . fail_json ( msg = ' Incompatible option: \' name \' . Do not use name when adding repo files' )
if alias :
module . fail_json ( msg = ' Incompatible option: \' name \' . Do not use name when adding . repo files' )
else :
if not name and state == " present " :
module . fail_json ( msg = ' Name required when adding non-repo files : ' )
if not alias and state == " present " :
module . fail_json ( msg = ' Name required when adding non-repo files . ' )
if repo and repo . endswith ( ' .repo ' ) :
exists = repo_exists ( module , old_zypper , url = repo , alias = name )
elif repo :
exists = repo_exists ( module , old_zypper , url = repo )
else :
exists = repo_exists ( module , old_zypper , alias = name )
exists , mod , old_repos = repo_exists ( module , repodata , overwrite_multiple )
if state == ' present ' :
if exists :
if exists and not mod :
exit_unchanged ( )
changed = add_repo ( module , repo , name , description , disable_gpg_check , old_zypper , refresh )
changed = modify_repo ( module , repodata , old_repos )
elif state == ' absent ' :
if not exists :
exit_unchanged ( )
if not repo :
repo = alias
changed = remove_repo ( module , repo )
changed = remove_repo ( module , repo , name , old_zypper )
module . exit_json ( changed = changed , repo = repo , state = state )
module . exit_json ( changed = changed , repodata = repodata , state = state )
# import module snippets
from ansible . module_utils . basic import *