o nnhbx@snddlmZdZdZdZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddl Z ddlmZddlmZddlmZmZmZdd lmZdd lmZdd lmZzddlZddlZddlm Z!e!"Z d Z#Wne$ydZZZ!Z d Z#YnwgdZ%dZ&ddZ'Gddde(Z)Gddde*Z+Gddde+Z,ddZ-ddZ.e/dkre.dSdS)) annotationsa1 --- module: apt_repository short_description: Add and remove APT repositories description: - Add or remove an APT repositories in Ubuntu and Debian. extends_documentation_fragment: action_common_attributes attributes: check_mode: support: full diff_mode: support: full platform: platforms: debian notes: - This module supports Debian Squeeze (version 6) as well as its successors and derivatives. seealso: - module: ansible.builtin.deb822_repository options: repo: description: - A source string for the repository. type: str required: true state: description: - A source string state. type: str choices: [ absent, present ] default: "present" mode: description: - The octal mode for newly created files in sources.list.d. - Default is what system uses (probably 0644). type: raw version_added: "1.6" update_cache: description: - Run the equivalent of C(apt-get update) when a change occurs. Cache updates are run after making changes. type: bool default: "yes" aliases: [ update-cache ] update_cache_retries: description: - Amount of retries if the cache update fails. Also see O(update_cache_retry_max_delay). type: int default: 5 version_added: '2.10' update_cache_retry_max_delay: description: - Use an exponential backoff delay for each retry (see O(update_cache_retries)) up to this max delay in seconds. type: int default: 12 version_added: '2.10' validate_certs: description: - If V(false), SSL certificates for the target repo will not be validated. This should only be used on personally controlled sites using self-signed certificates. type: bool default: 'yes' version_added: '1.8' filename: description: - Sets the name of the source list file in sources.list.d. Defaults to a file name based on the repository source url. The .list extension will be automatically added. type: str version_added: '2.1' codename: description: - Override the distribution codename to use for PPA repositories. Should usually only be set when working with a PPA on a non-Ubuntu target (for example, Debian or Mint). type: str version_added: '2.3' install_python_apt: description: - Whether to automatically try to install the Python apt library or not, if it is not already installed. Without this library, the module does not work. - Runs C(apt-get install python-apt) for Python 2, and C(apt-get install python3-apt) for Python 3. - Only works with the system Python 2 or Python 3. If you are using a Python on the remote that is not the system Python, set O(install_python_apt=false) and ensure that the Python apt library for your Python version is installed some other way. type: bool default: true author: - Alexander Saltanov (@sashka) version_added: "0.7" requirements: - python-apt (python 2) - python3-apt (python 3) - apt-key or gpg a - name: Add specified repository into sources list ansible.builtin.apt_repository: repo: deb http://archive.canonical.com/ubuntu hardy partner state: present - name: Add specified repository into sources list using specified filename ansible.builtin.apt_repository: repo: deb http://dl.google.com/linux/chrome/deb/ stable main state: present filename: google-chrome - name: Add source repository into sources list ansible.builtin.apt_repository: repo: deb-src http://archive.canonical.com/ubuntu hardy partner state: present - name: Remove specified repository from sources list ansible.builtin.apt_repository: repo: deb http://archive.canonical.com/ubuntu hardy partner state: absent - name: Add nginx stable repository from PPA and install its signing key on Ubuntu target ansible.builtin.apt_repository: repo: ppa:nginx/stable - name: Add nginx stable repository from PPA and install its signing key on Debian target ansible.builtin.apt_repository: repo: 'ppa:nginx/stable' codename: trusty - name: One way to avoid apt_key once it is removed from your distro block: - name: somerepo |no apt key ansible.builtin.get_url: url: https://download.example.com/linux/ubuntu/gpg dest: /etc/apt/keyrings/somerepo.asc - name: somerepo | apt source ansible.builtin.apt_repository: repo: "deb [arch=amd64 signed-by=/etc/apt/keyrings/myrepo.asc] https://download.example.com/linux/ubuntu {{ ansible_distribution_release }} stable" state: present aN repo: description: A source string for the repository returned: always type: str sample: "deb https://artifacts.elastic.co/packages/6.x/apt stable main" sources_added: description: List of sources added returned: success, sources were added type: list sample: ["/etc/apt/sources.list.d/artifacts_elastic_co_packages_6_x_apt.list"] version_added: "2.15" sources_removed: description: List of sources removed returned: success, sources were removed type: list sample: ["/etc/apt/sources.list.d/artifacts_elastic_co_packages_6_x_apt.list"] version_added: "2.15" N) AnsibleModule) S_IRWU_RG_RO) has_respawnedprobe_interpreters_for_modulerespawn_module) to_native) fetch_url)get_best_parsable_localeTF)z/etc/apt/keyringsz/etc/apt/trusted.gpg.dz/usr/share/keyrings)debzdeb-srccCs|jsG|d}|rC||dg\}}}|dkr$|jd||fd||d|ddg\}}}|dkrE|jd||fddSdSdS|jd |ddS) Nzapt-getupdaterz*Failed to auto-install %s. Error was: '%s'msginstallz-yz-qz&%s must be installed to use check mode) check_mode get_bin_path run_command fail_jsonstrip)module apt_pkg_name apt_get_pathrcsoserI/usr/local/lib/python3.10/dist-packages/ansible/modules/apt_repository.pyinstall_python_apts rc@s eZdZdS) InvalidSourceN)__name__ __module__ __qualname__rrrrrsrc@seZdZddZddZddZddZd$d d Zed d Z eddZ ddZ ddZ ddZ ddZd%ddZddZd&ddZd d!Zd"d#ZdS)' SourcesListcCs||_i|_i|_t|_|d|_tj |jr | |jt d| dD]}tj|r:t||j|<| |q*dS)NzDir::Etc::sourcelistz %s/*.listDir::Etc::sourceparts)rfiles files_mappingset new_repos _apt_cfg_file default_fileospathisfileloadglobiglob _apt_cfg_dirislinkreadlink)selfrfilerrr__init__s    zSourcesList.__init__ccsB|jD]\}}|D]\}}}}}|r|||||fVq qdS)zeSimple iterator to go over all sources. Empty, non-source, and other not valid lines will be skipped.N)r$items)r3r4sourcesnvalidenabledsourcecommentrrr__iter__szSourcesList.__iter__cCs(d|vr|Stjtj|d|S)N/r#)r*r+abspathjoinr0)r3filenamerrr _expand_pathszSourcesList._expand_pathcslfdd}dd}tdd|}tdd|}dd |D}||d |d <d |d |dd S)Ncs0jjd}|dur |Sdtdd|S)NrA_z [^a-zA-Z0-9] )rparamsr@resubsplit)srAr3rr_cleanup_filenames z8SourcesList._suggest_filename.._cleanup_filenamecSs d|vr|dd}|d}|S)N@)rH)rIrrr_strip_username_password s z?SourcesList._suggest_filename.._strip_username_passwordz \[[^\]]+\]z\w+://cSsg|]}|tvr|qSr)VALID_SOURCE_TYPES).0partrrr sz1SourcesList._suggest_filename..rz%s.listrDrM)rFrGrHr@)r3linerKrOpartsrrJr_suggest_filenames zSourcesList._suggest_filenameFc Csd}d}d}d}|}|drd}|dd}|d}|dkr2||dd}|d|}|}|rI|}|dtvrId}d|}|rS|rO|sSt|||||fS)NFTrP#rMrrD)r startswithfindrHrQr@r) r3rUraise_if_invalid_or_disabledr9r:r;r<ichunksrrr_parses*        zSourcesList._parsecC4z tj|}W|Stytj|}Y|SwzJ Wrapper for `apt_pkg` module for running with Python 2.5 )apt_pkgconfig find_fileAttributeErrorConfigFindFile)filespecresultrrrr(< zSourcesList._apt_cfg_filecCr_r`)rarbfind_dirrdreFindDir)dirspecrhrrrr0GrizSourcesList._apt_cfg_dirc CsTg}t|d}t|D]\}}||\}}}} |||||| fq ||j|<dS)Nr)open enumerater^appendr$) r3r4groupfr8rUr9r:r;r<rrrr-Rs  zSourcesList.loadc Cst|jD]\}}|rtj|\}}zt|Wn$tyA}ztj|s7|j d|t |fWYd}~nd}~wwz t j d||d\}}Wn!ttfyp}z|j j d|t |fdWYd}~nd}~wwt|d} |D]Q\} } } } }g}| s|d|| |r|d|||d d |}z| |Wqyty}z|j j d |t |fdWYd}~qyd}~ww||jvr|j ||j|n|j ||||jvr|j jd t}|j ||d q|j|=tj|rt|qdS)Nz!Failed to create directory %s: %sz.%s-)prefixdirz5Unable to create temp file at "%s" for apt source: %sr w#  #  rPzFailed to write to file %s: %smodeF)listr$r6r*r+rHmakedirsOSErrorisdirrrrtempfilemkstempIOErrorfdopenrpr@writer% atomic_mover'rEgetDEFAULT_SOURCES_PERMset_mode_if_differentexistsremove)r3rAr7dfnexfdtmp_patherrr8r9r:r;r<r]rU this_moderrrsaveZsZ &       &   zSourcesList.savec Csi}|jD]@\}}|rGg}|D].\}}}}} g} |s!| d| || r2| d| | | d|d| qd|||<q|S)NrvrwrxrP)r$r6rpr@) r3 dumpstructrAr7linesr8r9r:r;r<r]rrrdumps"     zSourcesList.dumpcCs|dur|S|SNr)r3newoldrrr_choiceszSourcesList._choiceNc CsR|j||dd\}}}} ||||||||||| f|j||<dS)z This function to be used with iterator, so we don't care of invalid sources. If source, enabled, or comment is None, original value from line ``n`` will be preserved. rMN)r$r) r3r4r8r:r;r<r9 enabled_old source_old comment_oldrrrmodifys4zSourcesList.modifyc Cs|jd|||fd}|D]\}}}}} ||kr$|j||ddd}q|sW|dur/|j}n||}||jvr>g|j|<|j|} | t| dd||f|j |dSdS)Nz adding source file: %s | %s | %sFT)r:) rlogrr)rBr$rplenr'add) r3 source_new comment_newr4foundrAr8r:r;r<r$rrr_add_valid_sources"    zSourcesList._add_valid_sourcerPcCs0|j|ddd}|j|||p||ddS)NTr[)r4)r^rrW)r3rUr<r4r;rrr add_sourceszSourcesList.add_sourcecCs4|D]\}}}}}||kr|r|j||qdSr)r$pop)r3r;rAr8r:srcr<rrr_remove_valid_sources  z SourcesList._remove_valid_sourcecCs |j|ddd}||dS)NTrr)r^rr3rUr;rrr remove_sourceszSourcesList.remove_source)F)NNNrPN)rr r!r5r=rBrWr^ staticmethodr(r0r-rrrrrrrrrrrrr"s&    .   r"csleZdZdZdZfddZdddZdd Zd d Zd d Z ddZ dddZ ddZ e ddZZS)UbuntuSourcesListz-https://api.launchpad.net/1.0/~%s/+archive/%sz https://ppa.launchpadcontent.netcsr||_|jdp tj|_tt|||jjddd|_|jjddd|_ |js5|j s7|jj dddSdSdS)Ncodenamezapt-keyF)requiredgpgzDEither apt-key or gpg binary is required, but neither could be foundr ) rrEdistrorsuperrr5r apt_key_bingpg_binr)r3r __class__rrr5s zUbuntuSourcesList.__init__NcCs t|jSr)rr)r3memorrr __deepcopy__s zUbuntuSourcesList.__deepcopy__cCs`|j||f}tdd}t|j||d\}}|ddkr'|jjd|ddtt|S) Nzapplication/json)Accept)headersstatusz.failed to fetch PPA information, error was: %srr ) LP_APIdictr rrjsonloadsrread)r3 owner_nameppa_namelp_apirresponseinforrr _get_ppa_infos   zUbuntuSourcesList._get_ppa_infocCsd|dd}|dd}z |dd}Wn ty"d}Ynwd|j|||jf}|||fS)N:rMr>rppazdeb %s/%s/%s/ubuntu %s main)rH IndexErrorPPA_URIr)r3r+r ppa_ownerrrUrrr _expand_ppas  zUbuntuSourcesList._expand_ppacCsj|jr.t|j}t||||d}||j_|jj|jd|gdd\}}}t| p*d|v}|S||}|S)N)LANGLC_ALL LC_MESSAGESLC_CTYPEexportT)check_rcznothing exported)rr rrrun_command_environ_updaterbool_gpg_key_exists)r3key_fingerprintlocaleAPT_ENVrouterrrrrr_key_already_existss  z%UbuntuSourcesList._key_already_existsc sd}dg}tD]|fddtDq|D]@}tj|r[z|j|jd|g\}}}Wnt t fyQ}z| d|t |fWYd}~qd}~ww||vr[d}|Sq|S)NFz/etc/apt/trusted.gpgcs$g|]}|dstj|qS).)rYr*r+r@)rRx other_dirrrrT s$z5UbuntuSourcesList._gpg_key_exists..z--list-packetsz#Could check key against file %s: %sT) APT_KEY_DIRSextendr*listdirr+rrrrrr|debugr) r3rrkeyfileskey_filerrrrrrrrs&   z!UbuntuSourcesList._gpg_key_existsrPc Cs|dr||\}}}||jvrdS|||}||dsd}|jjs|jr7|jddddd|dg} n3tD] } t j | rCn q9|j d d td | t j |d d ||f}|jdddd|dg} |jj| ddd\} } } |rt| dkr|jj d| | | dz(t|d }|| Wdn1swY|jd|d|fWn ttfy}z|jj d| | t|dWYd}~nd}~ww|p|d||jf}n|j|ddd}|p||}||||dS)Nppa:signing_key_fingerprintrPadvz --recv-keysz--no-ttyz --keyserverzhkp://keyserver.ubuntu.com:80zNUnable to find any existing apt gpgp repo directories, tried the following: %sz, z%s/%s-%s-%s.gpgrD-z--exportT)rencodingrz"Unable to get required signing key)rrstderrcommandwbz(Added repo key "%s" for apt to file "%s"z)Unable to add required signing key for%s )rrrerrorz%s_%srr)rYr repos_urlsrrrrrrr*r+rrr@basenamereplacerrrrnrrr|rrrWrr^r)r3rUr<r4r;rrrkeyfilerkeydirrstdoutrrrrrrrrsH        $zUbuntuSourcesList.add_sourcecCs:|dr ||d}n |j|ddd}||dS)NrrTrr)rYrr^rrrrrrNs zUbuntuSourcesList.remove_sourcec Cstg}|jD]0}|D]+}|d}|d}|d}|r|sq |dr1||\}}} ||q ||q q|S)NrMrr)r$valuesrYrrp) r3 _repositories parsed_repos parsed_repor9r: source_liner;rrrrrrUs   zUbuntuSourcesList.repos_urlsrr)rr r!rrr5rrrrrrrpropertyr __classcell__rrrrrs     2rcCs>t||D] }tj|rt|q |dS)z4Revert the sourcelist files to their previous state.N)r&keys differencer*r+rrr)sources_before sources_aftersourceslist_beforerArrrrevert_sources_listjs    rcCstttdddtddddgdtddtd dd gd td d dtd ddtddtd ddtd ddtddd dd}|j}|jd}|jd}|jd}d}tsd}trb|jd|tjdddg}t |d}|rqt ||j r||jd|d|drt ||n|jd|dt |d}|rt |n |jd|tjd|s|jddt ttjrt|}n|jddt|} |} z|dkr||n |dkr||Wnty} z|jd t| dWYd} ~ nd} ~ ww|} | | k} g}t}t}| rOt| | }t| | }|jrOt||D]!}|| |d!| |d!|d"f|| v|d"f|| vd#q-| r|j szs| |rd!}|jd$}|jd%}t!"d&d'd(}t#|D]<}z t$%}|&WnBt$j'j(y}z t|}WYd}~nd}~wwd)||}||kr||}t)*|qxt+| | | |jd*|r|nd+dWn#t,t-fy} zt+| | | |jt| dWYd} ~ nd} ~ ww|j.| |||||d,dS)-NstrT)typerpresentabsent)rdefaultchoicesraw)rrz update-cache)rraliasesint)rr ) repostatery update_cacheupdate_cache_retriesupdate_cache_retry_max_delayrArvalidate_certsr) argument_specsupports_check_moderrrz python3-aptz+{0} must be installed and visible from {1}.r z/usr/bin/python3z/usr/bin/pythonaptzX%s must be installed to use check mode. If run normally this module can auto-install it.rz4%s is not installed, and install_python_apt is Falsez/Please set argument 'repo' to a non-empty valuez1Module apt_repository is not supported on target.zInvalid repository string: %srPz /dev/null)beforeafter before_header after_headerrrrig@@rzFailed to update apt cache: %szunknown reason)changedr sources_addedsources_removedrdiff)/rrrEHAVE_PYTHON_APTrrformatsys executablerrrr isinstanceraptsources_distro Distributionrcopydeepcopyrrrrrr&rr_diffunionrprrrandomrandintrangerCacher cacheFetchFailedExceptiontimesleeprr|r exit_json)rrErrr sourceslistr interpreters interpreterrrrrrrrrrArrr randomizeretryr/rdelayrrrmainus                               r:__main__)0 __future__r DOCUMENTATIONEXAMPLESRETURNr'r.rr*rFr"r~r+r1ansible.module_utils.basicr ansible.module_utils.common.filerr#ansible.module_utils.common.respawnrrr+ansible.module_utils.common.text.convertersransible.module_utils.urlsr "ansible.module_utils.common.localer rraaptsources.distrorr% get_distror  ImportErrorrrQr Exceptionrobjectr"rrr:rrrrrsV ^,       l