def get_repo(repo): ''' Display a repo from the sources.list / sources.list.d The repo passwd in needs to be a complete repo entry. CLI Examples:: salt '*' pkg.get_repo "myrepo definition" ''' # we have to be clever about this since the repo definition formats # are a bit more "loose" than in some other distributions if repo.startswith('ppa:') and __grains__['os'] == 'Ubuntu': # This is a PPA definition meaning special handling is needed # to derive the name. if not ppa_format_support: error_str = 'cannot parse "ppa:" style repos definitions: {0}' raise Exception(error_str.format(repo)) repo = expand_ppa_line(repo, __grains__['lsb_codename'])[0] repos = list_repos() if repos: try: repo_type, repo_uri, repo_dist, repo_comps = _split_repo_str(repo) except SyntaxError, e: error_str = 'Error: repo "{0}" is not a well formatted definition' raise Exception(error_str.format(repo)) for source in repos.values(): for sub in source: if (sub['type'] == repo_type and sub['uri'] == repo_uri and sub['dist'] == repo_dist): if not repo_comps: return sub for comp in repo_comps: if comp in sub.get('comps', []): return sub
def mod_repo(repo, refresh=False, **kwargs): ''' Modify one or more values for a repo. If the repo does not exist, it will be created, so long as the definition is well formed. For Ubuntu the "ppa:<project>/repo" format is acceptable. "ppa:" format can only be used to create a new repository. The following options are available to modify a repo definition:: uri (the uri of the repo, e.g. deb http://archive.ubuntu.com/ubuntu) comps (a comma separated list of components for the repo, e.g. "main") file (a file name to be used) refresh (refresh the apt sources db when the mod is done) CLI Examples:: salt '*' pkg.mod_repo 'myrepo definition' uri=http://new/uri salt '*' pkg.mod_repo 'myrepo definition' comps=main,universe ''' # to ensure no one sets some key values that _shouldn't_ be changed on the # object itself, this is just a white-list of "ok" to set properties _MODIFY_OK = set(['uri', 'comps', 'architectures', 'disabled', 'file', 'dist']) if repo.startswith('ppa:') and __grains__['os'] == 'Ubuntu': if not ppa_format_support: error_str = 'cannot parse "ppa:" style repo definitions: {0}' return error_str.format(repo) ppa = expand_ppa_line(repo, __grains__['lsb_codename'])[0] cmd = 'apt-add-repository -y {0}'.format(repo) out = __salt__['cmd.run_stdout'](cmd) if refresh is True or str(refresh).lower() == 'true': refresh_db() return {repo: out} else: sources = sourceslist.SourcesList() repos = filter(lambda s: not s.invalid, sources) if repos: mod_source = None try: repo_type, repo_uri, repo_dist, repo_comps = _split_repo_str(repo) except SyntaxError: error_str = 'Error: repo "{0}" not a well formatted definition' return error_str.format(repo) for source in repos: if (source.type == repo_type and source.uri == repo_uri and source.dist == repo_dist): for comp in repo_comps: if comp in getattr(source, 'comps', []): mod_source = source if not source.comps: mod_source = source if mod_source: break if 'comps' in kwargs: kwargs['comps'] = kwargs['comps'].split(',') if 'architecturess' in kwargs: kwargs['architectures'] = kwargs['architectures'].split(',') if 'disabled' in kwargs: kw_disabled = kwargs['disabled'] if kw_disabled is True or str(kw_disabled).lower() == 'true': kwargs['disabled'] = True else: kwargs['disabled'] = False if not mod_source: mod_source = sourceslist.SourceEntry(repo) sources.list.append(mod_source) # if all comps aren't part of the disable # match, it is important we keep the comps # not destined to be disabled/enabled in # the original state if ('disabled' in kwargs and mod_source.disabled != kwargs['disabled']): s_comps = set(mod_source.comps) r_comps = set(repo_comps) if s_comps.symmetric_difference(r_comps): new_source = sourceslist.SourceEntry(source.line) new_source.file = source.file new_source.comps = list(r_comps.difference(s_comps)) source.comps = list(s_comps.difference(r_comps)) sources.insert(sources.index(source), new_source) sources.save() for key in kwargs: if key in _MODIFY_OK and hasattr(mod_source, key): if type(getattr(mod_source, key)) == type(kwargs[key]): setattr(mod_source, key, kwargs[key]) sources.save() if refresh is True or str(refresh).lower() == 'true': refresh_db() return { repo: { 'architectures': mod_source.architectures, 'comps': mod_source.comps, 'disabled': mod_source.disabled, 'file': mod_source.file, 'type': mod_source.type, 'uri': mod_source.uri, 'line': mod_source.line, } }
def del_repo(repo, refresh=False): ''' Delete a repo from the sources.list / sources.list.d If the .list file is in the sources.list.d directory and the file that the repo exists in does not contain any other repo configuration, the file itself will be deleted. The repo passed in must be a fully formed repository definition string. CLI Examples:: salt '*' pkg.del_repo "myrepo definition" salt '*' pkg.del_repo "myrepo definition" refresh=True ''' is_ppa = False if repo.startswith('ppa:') and __grains__['os'] == 'Ubuntu': # This is a PPA definition meaning special handling is needed # to derive the name. is_ppa = True if not ppa_format_support: error_str = 'Error: cannot parse "ppa:" style repo definition: {0}' return error_str.format(repo) repo = expand_ppa_line(repo, __grains__['lsb_codename'])[0] sources = sourceslist.SourcesList() repos = filter(lambda s: not s.invalid, sources.list) if repos: deleted_from = dict() try: repo_type, repo_uri, repo_dist, repo_comps = _split_repo_str(repo) except SyntaxError: error_str = 'Error: repo "{0}" not a well formatted definition' return error_str.format(repo) for source in repos: if (source.type == repo_type and source.uri == repo_uri and source.dist == repo_dist): s_comps = set(source.comps) r_comps = set(repo_comps) if s_comps.intersection(r_comps): deleted_from[source.file] = 0 source.comps = list(s_comps.difference(r_comps)) if not source.comps: try: sources.remove(source) except ValueError: pass # PPAs are special and can add deb-src where expand_ppa_line doesn't # always reflect this. Lets just cleanup here for good measure if (is_ppa and repo_type == 'deb' and source.type == 'deb-src' and source.uri == repo_uri and source.dist == repo_dist): s_comps = set(source.comps) r_comps = set(repo_comps) if s_comps.intersection(r_comps): deleted_from[source.file] = 0 source.comps = list(s_comps.difference(r_comps)) if not source.comps: try: sources.remove(source) except ValueError: pass sources.save() if deleted_from: ret = '' for source in sources: if deleted_from.has_key(source.file): deleted_from[source.file] += 1 for repo_file,c in deleted_from.iteritems(): msg = 'Repo "{0}" has been removed from {1}.\n' if c == 0 and 'sources.list.d/' in repo_file: if os.path.isfile(repo_file): msg = 'File {1} containing repo "{0}" has been removed.\n' try: os.remove(repo_file) except OSError, e: pass ret += msg.format(repo, repo_file) if refresh or str(refresh).lower() == 'true': refresh_db() return ret