o
    x[hyI  ã                
   @   s8  U d Z ddlZddlZddlZddlZddlZddlZddlZddlZddl	m
Z
mZ ddlmZ ddlmZ ddlmZmZ ddlmZmZmZmZmZ ddlmZ dd	lmZ dd
lmZ ddlm Z m!Z! ddl"m#Z# e#Z$de ge$g dœZ%ee&d< ddgddœZ'edƒZ(G dd„ dƒZ)e *e+¡Z,G dd„ de-ƒZ.G dd„ de
ƒZ/G dd„ de/ƒZ0G dd„ de/ƒZ1G dd „ d e/ƒZ2d!e3d"e!d#e4d$e/fd%d&„Z5d$ee6 fd'd(„Z7d$ee6 fd)d*„Z8d+d,„ Z9d$e:fd-d.„Z;d/d0„ Z<d$ee3e3f fd1d2„Z=d3d4„ Z>d5e/d"e!fd6d7„Z?d8e3d9ed:ed;e4d$df
d<d=„Z@d>e0fd?e1fd@e2ffZAdS )AzGrowpart: Grow partitionsé    N)ÚABCÚabstractmethod)Úsuppress)ÚPath)ÚOptionalÚTuple)Ú	lifecycleÚperformanceÚsubpÚ
temp_utilsÚutil)ÚCloud)ÚConfig)Ú
MetaSchema)ÚALL_DISTROSÚDistro)Ú
PER_ALWAYSÚcc_growpart)ÚidÚdistrosÚ	frequencyÚactivate_by_schema_keysÚmetaÚautoú/F)ÚmodeÚdevicesÚignore_growroot_disabledz/cc_growpart_keydatac                   @   s   e Zd ZdZdZdZdZdS )ÚRESIZEÚSKIPPEDÚCHANGEDÚNOCHANGEÚFAILEDN)Ú__name__Ú
__module__Ú__qualname__r   r    r!   r"   © r&   r&   ú>/usr/lib/python3/dist-packages/cloudinit/config/cc_growpart.pyr   /   s
    r   c                   @   s   e Zd ZdS )ÚResizeFailedExceptionN)r#   r$   r%   r&   r&   r&   r'   r(   9   s    r(   c                   @   s<   e Zd Zdefdd„Zededefdd„ƒZedd	„ ƒZ	d
S )ÚResizerÚdistroc                 C   s
   || _ d S ©N)Ú_distro)Úselfr*   r&   r&   r'   Ú__init__>   s   
zResizer.__init__r   Úreturnc                 C   ó   d S r+   r&   ©r-   r   r&   r&   r'   Ú	availableA   ó   zResizer.availablec                 C   r0   r+   r&   )r-   ÚdiskdevÚpartnumÚpartdevÚfsr&   r&   r'   ÚresizeD   r3   zResizer.resizeN)
r#   r$   r%   r   r.   r   ÚlistÚboolr2   r8   r&   r&   r&   r'   r)   =   s    r)   c                   @   ó"   e Zd Zdefdd„Zdd„ ZdS )ÚResizeGrowPartr   c                 C   sH   zt j ddgddid�j}t d|¡rW dS W dS  t jy#   Y dS w )	NÚgrowpartz--helpÚLANGÚC©Ú
update_envz--update\s+TF)r
   ÚstdoutÚreÚsearchÚProcessExecutionError)r-   r   Úoutr&   r&   r'   r2   I   s   ÿþÿþþzResizeGrowPart.availablec                 C   sJ  t ||ƒ}| j ¡ }tj|dd��…}tj |d¡}d|dœ}	tj |¡s*t 	|d¡ zt
j
dd||g|	d� W n0 t
jyg }
 z#|
jd	krRt td
||¡ t|
ƒ|
‚||fW  Y d }
~
W  d   ƒ S d }
~
ww zt
j
d||g|	d� W n t
jyŽ }
 zt td||¡ t|
ƒ|
‚d }
~
ww W d   ƒ n1 s™w   Y  |t ||ƒfS )NT)ÚdirÚ	needs_exer=   r?   )r>   ÚTMPDIRiÀ  z	--dry-runr@   é   z&Failed growpart --dry-run for (%s, %s)zFailed: growpart %s %s)Úget_sizer,   Úget_tmp_exec_pathr   ÚtempdirÚosÚpathÚjoinÚexistsÚmkdirr
   rE   Ú	exit_coder   ÚlogexcÚLOGr(   )r-   r4   r5   r6   r7   ÚbeforeÚtmp_dirÚtmpdÚgrowpart_tmpÚmy_envÚer&   r&   r'   r8   U   sF   




þ
ü
í€

€þÿêzResizeGrowPart.resizeN©r#   r$   r%   r9   r2   r8   r&   r&   r&   r'   r<   H   ó    r<   c                   @   s&   e Zd ZdZdefdd„Zdd„ ZdS )ÚResizeGrowFSaÃ  
    Use FreeBSD ``growfs`` service to grow root partition to fill available
    space, optionally adding a swap partition at the end.

    Note that the service file warns us that it uses ``awk(1)``, and as
    such requires ``/usr`` to be present. However, cloud-init is installed
    into ``/usr/local``, so we should be fine.

    We invoke the ``growfs`` with ``service growfs onestart``, so it
    doesn't need to be enabled in ``rc.conf``.
    r   c                 C   s   t j d¡o
|dgkS )z'growfs only works on the root partitionz/etc/rc.d/growfsr   )rN   rO   Úisfiler1   r&   r&   r'   r2   †   s   zResizeGrowFS.availablec              
   C   s^   t ||ƒ}z
| jjddd� W n tjy' } zt td¡ t|ƒ|‚d }~ww |t ||ƒfS )NÚonestartÚgrowfs)ÚactionÚservicezFailed: service growfs onestart)	rK   r,   Úmanage_servicer
   rE   r   rT   rU   r(   )r-   r4   r5   r6   r7   rV   r[   r&   r&   r'   r8   Š   s   

€þzResizeGrowFS.resizeN)r#   r$   r%   Ú__doc__r9   r2   r8   r&   r&   r&   r'   r^   y   s    r^   c                   @   r;   )ÚResizeGpartr   c                 C   sN   zt j ddgddiddgd�j}t d|¡rW d	S W d
S  t jy&   Y d
S w )NÚgpartÚhelpr>   r?   r   rJ   )rA   Úrcszgpart recover TF)r
   ÚstderrrC   rD   rE   )r-   r   Úerrr&   r&   r'   r2   –   s   ÿþÿþþzResizeGpart.availablec              
   C   sÄ   z
t   dd|g¡ W n$ t jy. } z|jdkr$t td|¡ t|ƒ|‚W Y d}~nd}~ww t||ƒ}zt   ddd||g¡ W n t jyZ } zt td||¡ t|ƒ|‚d}~ww |t||ƒfS )	a9  
        GPT disks store metadata at the beginning (primary) and at the
        end (secondary) of the disk. When launching an image with a
        larger disk compared to the original image, the secondary copy
        is lost. Thus, the metadata will be marked CORRUPT, and need to
        be recovered.
        rg   Úrecoverr   zFailed: gpart recover %sNr8   z-izFailed: gpart resize -i %s %s)r
   rE   rS   r   rT   rU   r(   rK   )r-   r4   r5   r6   r7   r[   rV   r&   r&   r'   r8   ¢   s$   

þ€ÿ

€þzResizeGpart.resizeNr\   r&   r&   r&   r'   rf   •   r]   rf   r   r*   r   r/   c                 C   s¤   d }| dkr#t D ]\}}||ƒ}|j|d�r|} nq|s!tdƒ‚|S i }t D ]\}}	|	||< q'| |vr:td|  ƒ‚||  |ƒ}
|
j|d�rH|
}|sPtd|  ƒ‚|S )Nr   )r   zNo resizers availablezunknown resize mode %szmode %s not available)ÚRESIZERSr2   Ú
ValueErrorÚ	TypeError)r   r*   r   Úresize_classÚ_nameÚresizerÚcurÚmmapÚkÚvÚmclassr&   r&   r'   Úresizer_factory»   s,   þò
rx   c              	   C   sš   d }zAzt  | t j¡}t  |dt j¡W W |rt  |¡ S S  tyC   |dkr6t| ƒ Y W |r5t  |¡ S S Y W |rAt  |¡ d S d S w |rLt  |¡ w w )Nr   Úzfs)rN   ÚopenÚO_RDONLYÚlseekÚSEEK_ENDÚcloseÚFileNotFoundErrorÚget_zfs_size)Úfilenamer7   Úfdr&   r&   r'   rK   Ù   s*   ÿûÿþÿûÿrK   c              
   C   sn   |   d¡d }zt dddd|g¡\}}W n tjy0 } zt d||¡ W Y d }~d S d }~ww t| ¡ ƒS )Nr   r   ÚzpoolÚgetz	-HpovalueÚsizezFailed: zpool get size %s: %s)Úsplitr
   rE   rU   ÚdebugÚintÚstrip)Údatasetrƒ   r…   Ú_r[   r&   r&   r'   r€   ç   s   €þr€   c                 C   s†   |   d¡r	| d fS t | ¡}|stdƒ‚|d }|d }t ¡ }|dkr?|s?t t ¡ ¡}|d u r?tj 	|¡r;|d fS tdƒ‚||fS )Nú/dev/z,Could not determine device of '%s' % dev_entr   rJ   z	/dev/rootz!Unable to find device '/dev/root')
Ú
startswithr   Úget_mount_inforn   Úis_containerÚrootdev_from_cmdlineÚget_cmdlinerN   rO   rQ   )ÚdeventÚresultÚdevr7   Ú	containerr&   r&   r'   Ú
devent2devñ   s   

r–   c              
   C   sÊ   t  d¡st d¡ dS z
t   dd| g¡ W n' t jy= } z|jdkr+t d| ¡ nt d|j¡ W Y d}~dS d}~ww tt jƒ� t   dd	|g¡ t d
| ¡ 	 W d  ƒ dS 1 s^w   Y  dS )zŒ
    Check if a device is an encrypted device. blockdev should have
    a /dev/dm-* path whereas partition is something like /dev/sda1.
    Ú
cryptsetupz6cryptsetup not found. Assuming no encrypted partitionsFÚstatusé   z#Determined that %s is not encryptedzZReceived unexpected exit code %s from cryptsetup status. Assuming no encrypted partitions.NÚisLukszDetermined that %s is encryptedT)r
   ÚwhichrU   r‡   rE   rS   Úwarningr   )ÚblockdevÚ	partitionr[   r&   r&   r'   Úis_encrypted	  s*   


ý€÷
 ýrŸ   c              
   C   s„   ddd| g}t   |¡d }| d¡std|› �ƒ‚zd| d¡d	  d
¡d › �W S  tyA } ztd|› d|› d�ƒ|‚d }~ww )NÚdmsetupÚdepsz--options=devnamer   z1 dependz5Expecting '1 dependencies' from 'dmsetup'. Received: rŒ   z: (rJ   ú)zRan `z$`, but received unexpected stdout: `ú`)r
   r�   ÚRuntimeErrorr†   Ú
IndexError)r�   ÚcommandÚdepr[   r&   r&   r'   Úget_underlying_partition$  s    
ÿ ÿþ€ÿr¨   c                 C   sÜ  t  ¡ s	tjdfS z@t dt › �¡�! t  ¡ �}t |¡}W d  ƒ n1 s'w   Y  W d  ƒ n1 s6w   Y  |d }t	 
|¡}|d }W n tyZ } ztdƒ|‚d}~ww zKtjddd	d
| g|d� W zt ddd|t|ƒg¡ W n tjy� } zt d|¡ W Y d}~nd}~ww zt  ¡  W nM ty¦   t td¡ Y n?w zt ddd|t|ƒg¡ W n tjyÎ } zt d|¡ W Y d}~nd}~ww zt  ¡  W w  tyä   t td¡ Y w w tjd| › d�fS )záUse 'cryptsetup resize' to resize LUKS volume.

    The loaded keyfile is json formatted with 'key' and 'slot' keys.
    key is base64 encoded. Example:
    {"key":"XFmCwX2FHIQp0LBWaLEMiHIyfxt1SGm16VvUAVledlY=","slot":5}
    zNo encryption keyfile foundzReading NÚkeyÚslotzZCould not load encryption key. This is expected if the volume has been previously resized.r—   z
--key-fileú-r8   )ÚdataÚluksKillSlotz--batch-modez<Failed to kill luks slot after resizing encrypted volume: %sz8Failed to remove keyfile after resizing encrypted volumez'Successfully resized encrypted volume 'ú')ÚKEYDATA_PATHrQ   r   r   r	   ÚTimedrz   ÚjsonÚloadÚbase64Ú	b64decodeÚ	Exceptionr¤   r
   ÚstrrE   rU   rœ   Úunlinkr   rT   r    )r�   rž   ÚfÚkeydatar©   Údecoded_keyrª   r[   r&   r&   r'   Úresize_encrypted5  sœ   
ÿþý€ 
ÿý€ÿþûÿ	þ€ÿÿÿïûÿ	þ€ÿÿÿ
þr»   c                 C   s"  g }zm|   ||||¡\}}||kr!| |tjd||f f¡ W |S |d u s)|d u rJd}	|d ur:|d u r:d||f }	nd| }	| |tj|	f¡ W |S d}	|d ur]|d u r]d||||f }	nd|||f }	| |tj|	f¡ W |S  ty� }
 z| |tjd|||
f f¡ W Y d }
~
|S d }
~
ww )Nzno change necessary (%s, %s)Ú z*changed (%s, %s) size, new size is unknownz&changed (%s) size, new size is unknownzchanged (%s, %s) from %s to %szchanged (%s) from %s to %sz'failed to resize: disk=%s, ptnum=%s: %s)r8   Úappendr   r!   r    r(   r"   )rr   r’   ÚdiskÚptnumr�   r7   ÚinfoÚoldÚnewÚmsgr[   r&   r&   r'   Ú_call_resizern  sT   
ýÿ&áþìü
øýÿ€ørÄ   rr   c                 C   sn  t   |¡}g }|�r5| d¡}d }d }zt|ƒ\}}W n ty8 }	 z| |tjd|	 f¡ W Y d }	~	qd }	~	ww t d|¡ |dkrTt	| t
ƒrT|t| |||||ƒ7 }qzt |¡}
W n tyz }	 z| |tjd||	f f¡ W Y d }	~	qd }	~	ww t |
j¡s“t |
j¡s“| |tjd| f¡ q| |¡}|rüz?t|ƒ}t||ƒrË|dd„ |D ƒvr»| d|¡ | d|¡ W qt||ƒ\}}| |||f¡ n| |tjd	|› d
�f¡ W n! tyú }	 z| |tjd|› d|	› �f¡ W Y d }	~	nd }	~	ww qz	| |¡\}}W n" ttf�y' }	 z| |tjd||	f f¡ W Y d }	~	qd }	~	ww |t| |||||ƒ7 }|s
|S )Nr   zunable to convert to device: %szgrowpart found fs=%sry   zstat of '%s' failed: %szdevice '%s' not a block devicec                 S   s   g | ]}|d  ‘qS )r   r&   )Ú.0Úxr&   r&   r'   Ú
<listcomp>Ú  s    z"resize_devices.<locals>.<listcomp>zResizing mapped device (z!) skipped as it is not encrypted.zResizing encrypted device (z
) failed: zdevice_part_info(%s) failed: %s)ÚcopyÚpopr–   rn   r½   r   r   rU   r‡   Ú
isinstancer^   rÄ   rN   ÚstatÚOSErrorÚS_ISBLKÚst_modeÚS_ISCHRÚget_mapped_devicer¨   rŸ   Úinsertr»   rµ   r"   Údevice_part_inforo   )rr   r   r*   rÀ   r’   r¾   r¿   r�   r7   r[   ÚstatretÚunderlying_blockdevrž   r˜   Úmessager&   r&   r'   Úresize_devicesœ  s¸   

ýÿ€ø

ýÿ€ø
ÿýÿ

ýÿ
ýÿ€ýÿ€ÿ

ýÿ€ø
–lrÖ   ÚnameÚcfgÚcloudÚargsc              
   C   s°  d|vrt  dt¡ t|d< | d¡}t|tƒst  d¡ d S | dd¡}t |¡rB|dkr:t	j
d|› d�d	d
d� t  d|¡ d S t | dd¡¡r]tj d¡r]t  d¡ t  d¡ d S t |ddg¡}t|ƒspt  d¡ d S z
t||j|d�}W n" ttfyœ } zt  d||¡ |dkr‘|‚W Y d }~d S d }~ww t d¡� t|||jƒ}	W d   ƒ n1 s´w   Y  |	D ]\}
}}|tjkrÍt  d|
|¡ q»t  d|
||¡ q»d S )Nr=   z.No 'growpart' entry in cfg.  Using default: %sz#'growpart' in config was not a dictr   r   Úoffz"Growpart's 'mode' key with value 'r®   z22.2zUse 'off' instead.)Ú
deprecatedÚdeprecated_versionÚextra_messagezgrowpart disabled: mode=%sr   Fz/etc/growroot-disabledz0growpart disabled: /etc/growroot-disabled existsz&use ignore_growroot_disabled to ignorer   r   zgrowpart: empty device list)r*   r   z,growpart unable to find resizer for '%s': %szResizing devicesz'%s' resized: %sz'%s' %s: %s)rU   r‡   ÚDEFAULT_CONFIGr„   rÊ   Údictrœ   r   Úis_falser   Ú	deprecaterN   rO   r_   Úget_cfg_option_listÚlenrx   r*   rn   ro   r	   r°   rÖ   r   r    rÀ   )r×   rØ   rÙ   rÚ   Úmycfgr   r   rr   r[   ÚresizedÚentryrb   rÃ   r&   r&   r'   Úhandle  sZ   ÿ




ý


€üÿ
ürè   r=   ra   rg   )Bre   r³   rÈ   r±   ÚloggingrN   Úos.pathrC   rË   Úabcr   r   Ú
contextlibr   Úpathlibr   Útypingr   r   Ú	cloudinitr   r	   r
   r   r   Úcloudinit.cloudr   Úcloudinit.configr   Úcloudinit.config.schemar   Úcloudinit.distrosr   r   Úcloudinit.settingsr   r   r   Ú__annotations__rß   r¯   r   Ú	getLoggerr#   rU   rµ   r(   r)   r<   r^   rf   r¶   r9   rx   rˆ   rK   r€   r–   r:   rŸ   r¨   r»   rÄ   rÖ   rè   rm   r&   r&   r&   r'   Ú<module>   sf   üý
1&
9.t4ý