3 \me@sddlZddlZddlZddlZddlZddlZddlZddlm Z ddl m Z ddl m Z mZmZmZmZmZmZmZmZmZddljjjZddlmZmZmZmZmZm Z m!Z!m"Z"m#Z#ddl$m%Z%m&Z&ddl'm(Z(ddl)m*Z*dd l+m,Z,dd l-m.Z.dd l/m0Z0m1Z1m2Z2m3Z3m4Z4dd l5m6Z6dd l7m8Z8dZ9dgdgddgddgddgdgdgdddddddd d!d"d#d$d%g d&d'd(d)d*d+d,d-gd.gd/d0gd1 Z:ej;e<Z=ej>d2Z?d3d4d5d6gZ@ejAejBd7ZCeeeDeeeeeDeeeDeeDfeeeDeeDeffZEGd8d9d9eFZGGd:d;d;ejHejId<ZJeDeKd=d>d?ZLeDd@dAdBZMde#jNfdCdDZOdEdFZPeDeeJdGdHdIZQdPdLdMZRdNdOZSdS)QN) defaultdict)StringIO) AnyDictListMappingMutableMappingOptionalSetTupleTypeUnion) helpersimporternet persistencessh_utilsubp temp_utils type_utilsutil)LinuxNetworking Networking)PackageManager)known_package_managers)hosts)+ALLOW_EC2_MIRRORS_ON_NON_AWS_INSTANCE_TYPES) activatorsdhcpeni network_state renderers)parse_net_config_data)RendererallalpinearchdebianZubuntufreebsdZ dragonflygentooZcosnetbsdopenbsdZ almalinuxZamazonZcentosZ cloudlinuxZ eurolinuxZfedoraZmarinerZ miraclelinuxZ openmandrivaZphotonZrhelZrockyZ virtuozzoZopensusez opensuse-leapzopensuse-microoszopensuse-tumbleweedZsle_hpcz sle-microZslessuse openeuler OpenCloudOSZ TencentOS) r%r&r'r(r)r*r+Zredhatr,r-r.z#^[a-z][a-z]-(?:[a-z]+-)+[0-9][a-z]$Zchronyzsystemd-timesyncdZntpZntpdate-c@s eZdZdS)PackageInstallerErrorN)__name__ __module__ __qualname__r4r4/usr/lib/python3.6/__init__.pyr0{sr0c@sReZdZUdZdZdZdZdZdZdZ dZ d gZ iZ e eeeeff d ZeZeed d d dZejZdZdZdZeejej ej!gZ"ddZ#e$d dddZ%ddZ&e'e(e)ee*e+fe+fdddZ,e'dddZ-dd Z.e/e0ee1j2d!d"d#Z3e4d!d$d%Z5e4d&d'd(Z6d)d*Z7dd+d,Z8dd-d.Z9dd/d0Z:e;d1d2Zdd3d4Z?d5d6Z@d7d8ZAdd9d:ZBdd;d<ZCdd>d?ZDdd@dAZEdBdCZFdeGd!dDdEZHe=j>ddFdGZIe=j>dHdIZJdJdKZKdLdMZLe=j>ddNdOZMe=j>dPdQZNe=j>dRdSZOdTdUZPdVdWZQe;dXdYZRdZd[ZSd\d]ZTe/d^d_ZUd`daZVdbdcZWdddeZXdfdgZYdhdiZZdjdkZ[dldmZ\dndoZ]ddpdqZ^e_eGdrdsdtZ`dudvZaddwdxZbddzd{Zcdd|d}Zddd~dZeddZfegdddZhegd deeedddZieeeedddZjed!ddZkde_eedddZle;eeeeee_dddZmd S)Distroz python3-pipz/usr/libz /etc/hostsz/etc/doas.confz"/etc/sudoers.d/90-cloud-init-usersz /etc/hostnamez/usr/share/zoneinfoz root:rootserviceNz-Hz-Pz-r)ZhaltZpoweroffZrebootFz/etc/resolv.confcCsL||_||_||_|j|_tjtjtjg|_ t j |_ t j||_g|_dS)N)Z_paths_cfgnamenetworking_cls networkingr IscDhclientDhcpcdUdhcpcdhcp_client_priorityiproute2Iproute2net_opsrZRunners_runnerpackage_managers)selfr:Zcfgpathsr4r4r5__init__s   zDistro.__init__)ci_pkl_versionreturncCs"d|jks|jj r|j|_dS)z)Perform deserialization fixes for Distro.r<N)__dict__r<r;)rFrIr4r4r5 _unpickleszDistro._unpicklecCs<t|tr|St|ttfr0t|dkr0t|StddS)Nz?Invalid 'packages' yaml specification. Check schema definition.) isinstancestrlisttuplelen ValueError)rFentryr4r4r5_validate_entrys  zDistro._validate_entry)pkglistrJcCstt}t}x|D]}t|trxv|jD]X\}}xN|D]F}|j|}y|t|j|Wq:tk r~t j d|Yq:Xq:Wq,Wq|j|j|qWt||fS)zTransform the generic package list to package by package manager. Additionally, include list of generic packages zLCannot install packages under '%s' as it is not a supported package manager!) rsetrNdictitemsrUraddKeyErrorLOGerror)rFrVpackages_by_managergeneric_packagesrTZpackage_managerZ package_listZ definitionr4r4r5_extract_package_by_managers"      z"Distro._extract_package_by_manager)rVc sd}|j|\}g}x\|jD]R}|j|jtB}|s\}} |j dd|jDkrq~|j |j |j |j j| dq~W|rt||dS)NzcFailed to install the following packages: %s. See associated package manager logs for more details.csh|]}|kr|qSr4r4).0Zpkg)r_r4r5 sz*Distro.install_packages..cSsg|] }|jqSr4)r:)rapr4r4r5 sz+Distro.install_packages..)rV)r`rEget __class__rWinstall_packagesr\inforYr:extendZ from_configrDr9r0) rFrVZ error_messager^Z uninstalledmanagerZto_tryZfailedZ manager_typeZpackagesr4)r_r5rgs.      zDistro.install_packagescCstd|jdS)z=Deprecated. Remove if/when arch and gentoo support renderers.zhLegacy function '_write_network' was called in distro '%s'. _write_network_config needs implementation. N)NotImplementedErrorr:)rFsettingsr4r4r5_write_networkszDistro._write_network)rJc Cs8tj|jdd}y tj|dStjk r2dSXdS)z=Return the configured network activator for this environment.networkrN)priority)rnr)rget_cfg_by_pathr9rZselect_activatorZNoActivatorException)rFror4r4r5network_activator s   zDistro.network_activatorcCsDtj|jdd}tj|d\}}tjd||||jj|d}|S)Nrnr!)roz-Selected renderer '%s' from priority list: %s)config)rnr!) rrpr9r!Zselectr\debugrenderer_configsre)rFror:Z render_clsrendererr4r4r5 _get_renderers  zDistro._get_renderer)rucCs|j|dS)N)Zrender_network_state)rFr rur4r4r5_write_network_state$szDistro._write_network_statecCs4tjj|jt|}tjj|s0td||f|S)Nz(Invalid timezone %s, no file found at %s)ospathjoin tz_zone_dirrOisfileIOError)rFtztz_filer4r4r5 _find_tz_file's  zDistro._find_tz_filecCs|jj||S)N)r9re)rFopt_namedefaultr4r4r5 get_option/szDistro.get_optioncCs||j|<dS)N)r9)rFrvaluer4r4r5 set_option2szDistro.set_optioncCs(|j||}|j||j|j|dS)N)_select_hostname_write_hostnamehostname_conf_fn_apply_hostname)rFhostnamefqdnZwriteable_hostnamer4r4r5 set_hostname5s zDistro.set_hostnamecCstS)z?Wrapper to report whether this distro uses systemd or sysvinit.) uses_systemdr4r4r4r5r:szDistro.uses_systemdcCs tdS)N)rk)rFcommandargsZpkgsr4r4r5package_command?szDistro.package_commandcCsTxN|jD]D}y |jWqtk rJ}ztjd|j|WYdd}~XqXqWdS)Nz%Failed to update package using %s: %s)rEupdate_package_sources Exceptionr\r]r:)rFrjer4r4r5rFs   zDistro.update_package_sourcescCstjd}|dkrdS|S)Ni386i486i586i686)rrrr)rxuname)rFr&r4r4r5get_primary_archOs zDistro.get_primary_archcCs"|jdg}|s|j}t||S)Npackage_mirrors)rr_get_arch_package_mirror_info)rFr& mirror_infor4r4r5rUs z$Distro._get_arch_package_mirror_infocCs|j|}t||dS)N) data_sourcer)r_get_package_mirror_info)rFr&rZ arch_infor4r4r5get_package_mirror_info[s zDistro.get_package_mirror_infoTcCs|j|}|r|j|SdS)z=Deprecated. Remove if/when arch and gentoo support renderers.F)rm_bring_up_interfaces)rFrlbring_upZ dev_namesr4r4r5 apply_networkcs  zDistro.apply_networkcCsL|j}tjd|djd|dg}tj|}tj||dd}|j||dS)z=Deprecated. Remove if/when arch and gentoo support renderers.ziapply_network_config is not currently implemented for distribution '%s'. Attempting to use apply_network z-# Converted from network_config for distro %sz4# Implementation of _write_network_config is needed.T)headerZrender_hwaddress)r) rfr\warningrzr r"rZnetwork_state_to_enir)rF netconfigrZdistrornscontentsr4r4r5"_apply_network_from_network_configrs  z)Distro._apply_network_from_network_configcCstjS)N)rgenerate_fallback_config)rFr4r4r5rszDistro.generate_fallback_configc Csy |j}Wntk r*|j||dSXt||d}|j|||rvtjd|j}|sjtjddS|j |n tjddS)aApply the network config. If bring_up is True, attempt to bring up the passed in devices. If devices is None, attempt to bring up devices returned by _write_network_config. Returns True if any devices failed to come up, otherwise False. )r)ruz/Bringing up newly configured network interfacesz>No network activator found, not bringing up network interfacesTz3Not bringing up newly configured network interfacesF) rvrkrr"rwr\rsrqrZbring_up_all_interfaces)rFrrrur rqr4r4r5apply_network_configs"        zDistro.apply_network_configcCs tdS)N)rk)rFZlocaleZout_fnr4r4r5 apply_localeszDistro.apply_localecCs tdS)N)rk)rFr~r4r4r5 set_timezoneszDistro.set_timezonecCsdS)Nz 127.0.0.1r4)rFr4r4r5_get_localhost_ipszDistro._get_localhost_ipcCs tdS)N)rk)rFr4r4r5 get_localeszDistro.get_localecCs tdS)N)rk)rFfilenamerr4r4r5_read_hostnameszDistro._read_hostnamecCs tdS)N)rk)rFrrr4r4r5rszDistro._write_hostnamecCs tdS)N)rk)rFr4r4r5_read_system_hostnameszDistro._read_system_hostnamec CsHtjd|ytjd|gWn$tjk rBtjtd|YnXdS)Nz2Non-persistently setting the system hostname to %srz;Failed to non-persistently adjust the system hostname to %s)r\rsrZProcessExecutionErrorrlogexc)rFrr4r4r5rszDistro._apply_hostnamecCs&tj|jd|jr|r|S|s"|S|S)NZprefer_fqdn_over_hostname)rZget_cfg_option_boolr9 prefer_fqdn)rFrrr4r4r5rszDistro._select_hostnamecCs:g}x0|D](}|tkr$tdj||jt|q W|S)Nz&No distributions found for osfamily {}) OSFAMILIESrSformatri)Z family_listZdistrosZfamilyr4r4r5expand_osfamilys  zDistro.expand_osfamilyc Cs|}|j||}|r,tjj|r,|j|}nd}|j\}}g}| sN||krX|j|| sn||krx||krx|j||r|r||krtjd||dSt dd|D}tj d|t |xB|D]:} y|j || Wqt k rtjtd|| YqXqW||kr|j|dS)Nz6%s differs from %s, assuming user maintained hostname.cSsg|] }|r|qSr4r4)rafr4r4r5rdsz*Distro.update_hostname..z/Attempting to update hostname to %s in %s filesz!Failed to write hostname %s to %s)rrxryexistsrrappendr\rhrWrsrRrr}rrr) rFrrZprev_hostname_fnZapplying_hostnameZ prev_hostnameZsys_fnZ sys_hostnameZ update_filesfnr4r4r5update_hostnames>        zDistro.update_hostnamec Csd}tjj|jr&tjtj|j}ntjd}tjdd}|j }|j |}d}|sj|j |||d}nd}x\|D]T}d} g} t |dkr|d} t |dkr|dd} | dk rt| |krt|| krtd}qtW|r.rz created group '%s' for user '%s'rZREDACTEDZno_create_homerz-Mz-mzAdding user %s) logstringzFailed to create user %s)ris_userr\rhpopsystem_is_snappyrrerNrOsplitrX deprecaterzis_group create_grouprskeyssortedrYrirrr)rFr:kwargsrZ useradd_cmdZlog_useradd_cmdZ useradd_optsZ useradd_flagsZ redact_optsrrgroupkeyvalrr4r4r5add_userws                      zDistro.add_userc Ks|jd}|jdd}ddddg}|r0|jd|j|tjd |ytk rh}z"td|dd |Df|WYd d }~XnXytj|Wn4tk r}ztjtd ||WYd d }~XnXd S) zL Lock the password of a user, i.e., disable password logins rz-lusermodz--lockcss |]}tj|dr|VqdS)rN)rZwhich)raZtoolr4r4r5 nsz%Distro.lock_passwd..zBUnable to lock user account '%s'. No tools available. Tried: %s.cSsg|] }|dqS)rr4)racr4r4r5rdrsz&Distro.lock_passwd..Nz&Failed to disable password for user %s)next StopIteration RuntimeErrorrrrrr\)rFr:Z lock_toolscmdrr4r4r5rgszDistro.lock_passwdcCsNytjdd|gWn4tk rH}ztjtd||WYdd}~XnXdS)Nrz--expirezFailed to set 'expire' for %s)rrrrr\)rFuserrr4r4r5 expire_passwdzs zDistro.expire_passwdcCsrd||f}dg}|r |jdytj||d|dWn4tk rl}ztjtd||WYdd}~XnXdS)Nz%s:%schpasswdz-ezchpasswd for %s)datarzFailed to set password for %sT)rrrrrr\)rFrrrZ pass_stringrrr4r4r5rs  zDistro.set_passwd)plist_inrcCs>djdd|Dd}dg|r&dgng}tj||ddS)Nrcss |]\}}dj||gVqdS):N)rz)rar:Zpasswordr4r4r5rsz"Distro.chpasswd..rz-e)r)rzr)rFrrZpayloadrr4r4r5rs zDistro.chpasswdcCszd}tjd||tj||}|rhtjd|jd|jd|krPtjddStjd|jddSntjd dSdS) Nz^(?:permit|deny)(?:\s+(?:nolog|nopass|persist|keepenv|setenv \{[^}]+\})+)*\s+([a-zA-Z0-9_]+)+(?:\s+as\s+[a-zA-Z0-9_]+)*(?:\s+cmd\s+[^\s]+(?:\s+args\s+[^\s]+(?:\s*[^\s]+)*)*)*\s*$z3Checking if user '%s' is referenced in doas rule %rz!User '%s' referenced in doas ruler8z'Correct user is referenced in doas ruleTz.Incorrect user '%s' is referenced in doas ruleFz/doas rule does not appear to reference any user)r\rsresearchr)rFrruleZ rule_patternZ valid_matchr4r4r5is_doas_rule_valids      zDistro.is_doas_rule_validc Cs>|s |j}x2|D]*}|j||sd||f}tj|dSqWdd|g}x|D]}|jd|qPWdj|}|d7}tjj|st j |g}yt j |dj|ddWn4t k r} zt j td|| WYdd} ~ XnXnX|t j|kr:yt j||Wn6t k r8} zt j td || WYdd} ~ XnXdS) NzHInvalid doas rule %r for user '%s', not writing any doas rules for user!rz# cloud-init User rules for %sz%sri )rzFailed to write doas file %sz Failed to append to doas file %s)doas_fnr r\r]rrzrxryrrrrr}rr append_file) rFrrulesZ doas_filer msglinescontentrrr4r4r5rs6          zDistro.write_doas_rules /etc/sudoersc CsFd}d}tjj|r"tj|}d}d}xX|jD]L}|j}tjd|}|sNq0|j dj}|sbq0tjj |}||kr0d}Pq0W|s6yx|sddtj ddd |dg} d j | }tj ||d n.dtj ddd |dg} d j | }tj||tjd ||Wn6tk r4} ztjtd || WYdd} ~ XnXtj|ddS)NrFTz^[#|@]includedir\s+(.*)$r8z?# See sudoers(5) for more information on "#include" directives:r)rz#includedir %sri zAdded '#includedir %s' to %szFailed to write %si)rxryrrr splitlinesrr r rabspathrrzrrr\rsr}rZ ensure_dir) rFryZ sudo_baseZsudoers_contentsZ base_existsZ found_includelineZ include_matchZ included_dirrrr4r4r5ensure_sudo_dirsN         zDistro.ensure_sudo_dirc Csf|s |j}dd|g}t|ttfrFxT|D]}|jd||fq*Wn4t|trd|jd||fnd}t|tj|dj |}|d7}|j t j j |t j j|s tj|g}ytj|dj |dWn6tk r} ztjtd|| WYdd} ~ XnXnX|tj|krbytj||Wn6tk r`} ztjtd|| WYdd} ~ XnXdS) Nrz# User rules for %sz%s %sz1Can not create sudoers rule addition with type %rri zFailed to write sudoers file %sz#Failed to append to sudoers file %s) ci_sudoers_fnrNrPrQrrO TypeErrorrZobj_namerzrrxrydirnamerrrrr}rr\rr) rFrrZ sudo_filerr rrrrr4r4r5rs:     zDistro.write_sudo_rulescCsd|g}tjr|jd|s"g}tj|r:tjd|n>ytj|tjd|Wn"tk rvtj td|YnXt |dkrxH|D]@}tj |stjd||qtjdd d ||gtjd ||qWdS) NZgroupaddz --extrausersz(Skipping creation of existing group '%s'zCreated new group %szFailed to create group %srzCUnable to add group member '%s' to group '%s'; user does not exist.rz-az-GzAdded user '%s' to group '%s') rrrrr\rrrhrrrRr)rFr:membersZ group_add_cmdmemberr4r4r5r=s,      zDistro.create_groupcCsvd|j|g}y|dkr$dt|}Wn2tk rX}ztd|f|WYdd}~XnX||g}|rr|j||S)NZshutdownZnowz+%dz?power_state[delay] must be 'now' or '+m' (minutes). found '%s'.)shutdown_options_mapintrSrr)rFrZdelaymessagerrrr4r4r5shutdown_command]s  zDistro.shutdown_commandcCs2|j}|jsd|kr.|dg}tj|d|dSdS)zX Reload systemd startup daemon. May raise ProcessExecutionError systemctlz daemon-reloadT)rrcsN)init_cmdrr)clsr"r#rr4r4r5 reload_initmszDistro.reload_init)r")actionr7 extra_argsc Gs|j}|jsd|krTdg}d|gd|gd|gd|gd|gd|gd|gd |gd }n6|dg|dg|dg|dg|dg|dg|dg|d gd }t|t||}tj|d |d S) z Perform the requested action on a service. This handles the common 'systemctl' and 'service' cases and may be overridden in subclasses as necessary. May raise ProcessExecutionError r!stopstartenabledisablerestartzreload-or-restartzreload-or-try-restartstatus)r(r)r*r+r,reloadz try-reloadr-T)rr")r#rrPr)r$r&r7r"r'r#Zcmdsrr4r4r5manage_servicexs*  zDistro.manage_service)layoutmodelvariantrcCs*|jr tjdd||||gntdS)NZ localectlzset-x11-keymap)rrrk)rFr0r1r2rr4r4r5 set_keymaps zDistro.set_keymapcCs.tjdd}tj|ds|Stjj|jddS)NT)Z needs_exeZnoexecz cloud-initZclouddir)rZget_tmp_ancestorrZ has_mount_optrxryrz usr_lib_exec)rFZtmp_dirr4r4r5get_tmp_exec_paths  zDistro.get_tmp_exec_pathr)rrcwdcKs:|rd|dnd}tjdd|d|ddj|gf|S) a` Perform a command as the requested user. Behaves like subp() Note: We pass `PATH` to the user env by using `env`. This could be probably simplified after bionic EOL by using `su --whitelist-environment=PATH ...`, more info on: https://lore.kernel.org/all/20180815110445.4qefy5zx5gfgbqly@ws.net.home/T/ zcd z && rZsur/z-czenv PATH=$PATH  )rrz)rFrrr6rZ directoryr4r4r5do_ass z Distro.do_as)ry lease_filepid_file interface config_filerJc Cs*|ddd|d|ddg |r"d||gn|gS)Nz-1z-vz-lfz-pfz-sfz /bin/truez-cfr4)ryr9r:r;r<r4r4r5build_dhclient_cmds zDistro.build_dhclient_cmd)N)N)N)NN)N)NN)T)T)F)N)N)F)N)r)N)N)N)r)nr1r2r3Zpip_package_namer4rr rrr{Z default_ownerr#rtrrOrrrrr;r rrrArBrCZ_ci_pkl_versionrZresolve_conf_fnZosfamilyrr=r>r?r@rHrrLrU PackageListr rrr r`rgrmpropertyr rZNetworkActivatorrqr#rvrwrrrr staticmethodrabcabstractmethodrrrrrrrrboolrrrrrrrrrrrrrrrrrrrrrrrrPrr rrrrr  classmethodr%r/r3r5r8r=r4r4r4r5r6s     "-            %   A+  ta   $ 1 )  #r6) metaclass)urltransformationsc Csytjj|}Wntk r$dSX|j}|dkr8dSx |D]}||}|dkr>|Sq>W|}|jdk rvdj||j}tjj|j|dS)a Apply transformations to a URL's hostname, return transformed URL. This is a separate function because unwrapping and rewrapping only the hostname portion of a URL is complex. :param url: The URL to operate on. :param transformations: A list of ``(str) -> Optional[str]`` functions, which will be applied in order to the hostname portion of the URL. If any function (regardless of ordering) returns None, ``url`` will be returned without any modification. :return: A string whose value is ``url`` with the hostname ``transformations`` applied, or ``None`` if ``url`` is unparseable. Nz{}:{})Znetloc) urllibparseZurlsplitrSrZportrZ urlunsplit_replace)rFrGpartsZ new_hostnameZtransformationZ new_netlocr4r4r5&_apply_hostname_transformations_to_urls  rL)rFcs2tdddddfddddg}t||S)aH Given a mirror URL, replace or remove any invalid URI characters. This performs the following actions on the URL's hostname: * Checks if it is an IP address, returning the URL immediately if it is * Converts it to its IDN form (see below for details) * Replaces any non-Letters/Digits/Hyphen (LDH) characters in it with hyphens * Removes any leading/trailing hyphens from each domain name label Before we replace any invalid domain name characters, we first need to ensure that any valid non-ASCII characters in the hostname will not be replaced, by ensuring the hostname is in its Internationalized domain name (IDN) representation (see RFC 5890). This conversion has to be applied to the whole hostname (rather than just the substitution variables), because the Punycode algorithm used by IDNA transcodes each part of the hostname as a whole string (rather than encoding individual characters). It cannot be applied to the whole URL, because (a) the Punycode algorithm expects to operate on domain names so doesn't output a valid URL, and (b) non-ASCII characters in non-hostname parts of the URL aren't encoded via Punycode. To put this in RFC 5890's terminology: before we remove or replace any characters from our domain name (which we do to ensure that each label is a valid LDH Label), we first ensure each label is in its A-label form. (Note that Python's builtin idna encoding is actually IDNA2003, not IDNA2008. This changes the specifics of how some characters are encoded to ASCII, but doesn't affect the logic here.) :param url: The URL to operate on. :return: A sanitized version of the URL, which will have been IDNA encoded if necessary, or ``None`` if the generated string is not a parseable URL. .cSstj|rdS|S)N)rZ is_ip_address)rr4r4r51sz&_sanitize_mirror_url..cSs|jdjdS)NZidnaascii)encodedecode)rr4r4r5rN4scsdjfdd|DS)Nrc3s|]}|kr|ndVqdS)r/Nr4)rar)acceptable_charsr4r5r7sz9_sanitize_mirror_url....)rz)r)rRr4r5rN6scSsdjdd|jdDS)NrMcss|]}|jdVqdS)r/N)r)rapartr4r4r5r;sz9_sanitize_mirror_url....)rzr)rr4r4r5rN:s)LDH_ASCII_CHARSrL)rFrGr4)rRr5_sanitize_mirror_urls &  rUc Cs2|si}i}|rb|jrb|j|d<tj|jrb|jdd }trLd||d<n|jdkrbd||d<|rv|jrv|j|d<i}x$|jdijD]\}}|||<qWx|jd ijD]l\}}g} xJ|D]B} y | |}Wntk rwYnXt |}|dk r| j |qW|| } | r| ||<qWt j d ||S) Navailability_zonerr8z%s ec2_regionZec2regionZfailsafer zfiltered distro mirror info: %s) rV _EC2_AZ_REmatchrZ platform_typerXrerYr[rUrr\rs) rrZ mirror_filterZsubstrWresultsr:ZmirrorZ searchlistZmirrorsZtmplfoundr4r4r5rBs>            rcCs8d}x.|D]&}|jd}||kr$|Sd|kr |}q W|S)Narchesr)re)rr&ritemr^r4r4r5rus  r)r:rJcCsHtj|dtgdg\}}|s,td||ftj|d}t|d}|S)Nrr6z1No distribution found for distro %s (searched %s)r)r find_moduler1 ImportError import_modulegetattr)r:ZlocsZ looked_locsmodr$r4r4r5fetchs  re /etc/timezone/etc/localtimecCsjtj|t|jd|rf|rftjj|}|s>tjj| rZ|rLtj|tj ||n tj ||dS)Nr) rrrOrstriprxryislinkrZdel_filesymlinkcopy)r~rZtz_confZtz_localrir4r4r5set_etc_timezones   rlc Cs0ytjd}tj|jStk r*dSXdS)Nz/run/systemd/systemF)rxlstatstatS_ISDIRst_moder)resr4r4r5rs   r)Nrfrg)TrAZloggingrxr rnstringZ urllib.parserH collectionsriorZtypingrrrrrr r r r r Zcloudinit.net.netops.iproute2rZnetopsrAZ cloudinitrrrrrrrrZcloudinit.distros.networkingrrZ4cloudinit.distros.package_management.package_managerrZ*cloudinit.distros.package_management.utilsrZcloudinit.distros.parsersrZcloudinit.featuresrZ cloudinit.netrrrr r!Zcloudinit.net.network_stater"Zcloudinit.net.rendererr#Z ALL_DISTROSrZ getLoggerr1r\compilerZrZ ascii_lettersZdigitsrTrOr>rr0ZCloudInitPickleMixinABCMetar6rPrLrUZsearch_for_mirrorrrrerlrr4r4r4r5 s  0 ,            e+<2