܍~cM UdZddlZddlZddlZddlZddlZddlZddlZddlm Z m Z ddl m Z ddl mZddlmZddlmZddlmZdd lmZ dd lmZmZmZdd lmZdd lmZdd lmZm Z ddl!m"Z"m#Z#ddl$m%Z%dZ&e%Z'ddde&e"ge'ededggdZ(ee)d<e e(ZddgddZ*edZ+GddZ,e j-e.Z/de0d e#fd!Z1Gd"d#e2Z3Gd$d%e Z4Gd&d'e4Z5Gd(d)e4Z6d*Z7d+Z8d,Z9d-Z:d.e;fd/Zd2Z?d3e0d4ed5ed6ed7e@d.df d8ZAd9e5fd:e6ffZBdS);zGrowpart: Grow partitionsN)ABCabstractmethod)suppress)Logger)Path)dedent)Tuple)log)subp temp_utilsutil)Cloud)Config) MetaSchema get_meta_doc) ALL_DISTROSDistro) PER_ALWAYSaGrowpart resizes partitions to fill the available disk space. This is useful for cloud instances with a larger amount of disk space available than the pristine image uses, as it allows the instance to automatically make use of the extra space. The devices on which to run growpart are specified as a list under the ``devices`` key. There is some functionality overlap between this module and the ``growroot`` functionality of ``cloud-initramfs-tools``. However, there are some situations where one tool is able to function and the other is not. The default configuration for both should work for most cloud instances. To explicitly prevent ``cloud-initramfs-tools`` from running ``growroot``, the file ``/etc/growroot-disabled`` can be created. By default, both ``growroot`` and ``cc_growpart`` will check for the existence of this file and will not run if it is present. However, this file can be ignored for ``cc_growpart`` by setting ``ignore_growroot_disabled`` to ``true``. For more information on ``cloud-initramfs-tools`` see: https://launchpad.net/cloud-initramfs-tools Growpart is enabled by default on the root partition. The default config for growpart is:: growpart: mode: auto devices: ["/"] ignore_growroot_disabled: false cc_growpartGrowpartzGrow partitionsz growpart: mode: auto devices: ["/"] ignore_growroot_disabled: false z growpart: mode: growpart devices: - "/" - "/dev/vdb1" ignore_growroot_disabled: true )idnametitle descriptiondistros frequencyexamplesactivate_by_schema_keysmetaauto/F)modedevicesignore_growroot_disabledz/cc_growpart_keydataceZdZdZdZdZdZdS)RESIZESKIPPEDCHANGEDNOCHANGEFAILEDN)__name__ __module__ __qualname__r'r(r)r*>/usr/lib/python3/dist-packages/cloudinit/config/cc_growpart.pyr&r&fs"GGH FFFr/r&r"distrocdd}|dkrBtD](\}}||}|r|}n)|stdnei}tD] \}}|||< ||vrtd|z|||} | r| }|std|z|S)Nr zNo resizers availablezunknown resize mode %szmode %s not available)RESIZERS available ValueError TypeError) r"r1 resize_class_nameresizercurmmapkvmclasss r0resizer_factoryr?psL v~~ (   UG'&//C}} "   6455 5 6  FQDGG t  4t;<< <dF##      "!L =4t;<< < r/ceZdZdS)ResizeFailedExceptionN)r+r,r-r.r/r0rArAsDr/rAcLeZdZdefdZedefdZedZdS)Resizerr1c||_dSN)_distro)selfr1s r0__init__zResizer.__init__s  r/returncdSrEr.)rGs r0r4zResizer.available r/cdSrEr.)rGdiskdevpartnumpartdevs r0resizezResizer.resizerKr/N) r+r,r-rrHrboolr4rPr.r/r0rCrCsqv 4   ^   ^   r/rCceZdZdZdZdS)ResizeGrowPartctj}d|d< tjddg|\}}t jd|rdSn#tj$rYnwxYwdS) NCLANGgrowpartz--helpenvz --update\s+TFosenvironcopyr researchProcessExecutionError)rGmyenvout_errs r0r4zResizeGrowPart.availables !!f  )Z$:FFFKS$y-- t )    D us0AA*)A*ctj}d|d<t|}|j}t j|d5}tj |d}tj |stj |d||d< tj dd||g| nc#tj $rQ} | jd kr,tjt"d ||t%| | ||fcYd} ~ cdddSd} ~ wwxYw tj d||g| nC#tj $r1} tjt"d ||t%| | d} ~ wwxYw dddn #1swxYwY|t|fS) NrUrVT)dir needs_exerWiTMPDIRz --dry-runrXz&Failed growpart --dry-run for (%s, %s)zFailed: growpart %s %s)r[r\r]get_sizerFget_tmp_exec_pathr tempdirpathjoinexistsmkdirr r` exit_coder logexcLOGrA) rGrMrNrOrabeforetmp_dirtmpd growpart_tmpes r0rPzResizeGrowPart.resizesG !!f '"",0022  Gt < < < 67<<j99L7>>,// .u---*E(O ( gw?U- ( ( (;!##K@  0229''''''% 6 6 6 6 6 6 6 6 ( 6 :w8eDDDDD- 6 6 6 C!97GLLL+A..A5 6E+ 6 6 6 6 6 6 6 6 6 6 6 6 6 6 64))**sg"AF&=CF&D8':D3!D8"F&3D88F&<EF&F%,FFF&&F*-F*Nr+r,r-r4rPr.r/r0rSrSs2   "+"+"+"+"+r/rSceZdZdZdZdS) ResizeGpartctj}d|d< tjddg|ddg\}}t jd|rd Sn#tj$rYnwxYwd S) NrUrVgparthelprrh)rYrcszgpart recover TFrZ)rGra_outerrs r0r4zResizeGpart.availables !!f  )Wf$55q!fMMMKT3y*C00 t )    D us3AA-,A-c tjdd|gnR#tj$r@}|jdkr+tjt d|t ||Yd}~nd}~wwxYwt|} tjddd||gnC#tj$r1}tjt d||t ||d}~wwxYw|t|fS) 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. r|recoverrzFailed: gpart recover %sNrPz-izFailed: gpart resize -i %s %s)r r`rpr rqrrrAri)rGrMrNrOrwrss r0rPzResizeGpart.resizes 6 Iw 73 4 4 4 4) 6 6 6{a C!;WEEE+A..A5  6 '"" 2 Iw$A B B B B) 2 2 2 K ? ? AGGAJJ'' 7>>' " "HWWWgggFGGG W\\'; / /F 7>>& ! !8,w6777 N6 " " ) ) + +Ew((H'//(++K [% @ @AAHHJJJ'""?Z#?@@K  r/cr|dr|Stj|}|std|d}tj}|dkrY|sWtjtj}|0tj |r|Std|S)Nrz,Could not determine device of '%s' % dev_entrz /dev/rootz!Unable to find device '/dev/root') startswithr get_mount_infor5 is_containerrootdev_from_cmdline get_cmdliner[rlrn)deventresultr containers r0 devent2devr,s !! $V,, MKLL LQi!##I k)'(8(:(:;; ;w~~c""  @AA A Jr/ctj|}|drtd|||SdS)aReturns underlying block device for a mapped device. If it is mapped, blockdev will usually take the form of /dev/mapper/some_name If blockdev is a symlink pointing to a /dev/dm-* device, return the device pointed to. Otherwise, return None. z/dev/dm-z$%s is a mapped device pointing to %sN)r[rlrrrrdebug)blockdevrs r0get_mapped_devicerCsPw))H:&& 8(HMMM 4r/rIc*tjdstddS tjdd|gnd#tj$rR}|jdkrtd|n td|jYd}~dSd}~wwxYwttj5tjdd |gtd | dddd S#1swxYwYdS) 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 partitionsFstatusz#Determined that %s is not encryptedzZReceived unexpected exit code %s from cryptsetup status. Assuming no encrypted partitions.NisLukszDetermined that %s is encryptedT)r whichrrrr`rpwarningr)rrrws r0 is_encryptedrSsg :l # # JKKKu  <845555  %    ;!   II;X F F F F KKG     uuuuu  $, - - <95666 3X>>> 5s*A B+AB&&B+4DD D cRddd|g}tj|d}|dstd| d|dd d dS#t$r}td |d |d |d}~wwxYw)Ndmsetupdepsz--options=devnamerz1 dependz5Expecting '1 dependencies' from 'dmsetup'. Received: rz: (rhrzRan `z$`, but received unexpected stdout: ``)r r RuntimeErrorsplit IndexError)rcommanddeprws r0get_underlying_partitionrns&"5x@Gy!!!$C >>* % %  IC I I   :syy''*0055a8:::  GG G G G G G   s 6B B& B!!B&c ^tstjdfS t5}t j|}dddn #1swxYwY|d}tj|}|d}n"#t$r}td|d}~wwxYw tj dddd |g|  tj dd d |t|gn7#tj $r%}td |Yd}~nd}~wwxYw tn#t$rt#jtdYnwxYw# tj dd d |t|gn7#tj $r%}td |Yd}~nd}~wwxYw tw#t$rt#jtdYwwxYwxYwtjd|dfS)zUse '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} zNo encryption keyfile foundNkeyslotzZCould not load encryption key. This is expected if the volume has been previously resized.rz --key-file-rP)data luksKillSlotz --batch-modez>      #AillG # # # # # # # # # # # # # # #en&s++ v  6     <h A      I ""II     )    KKN               ! ! ! !    KO      #  I ""II     )    KKN               ! ! ! !    KO       =(=== sBA# B#A''B*A'+'B B2B--B26E5&C99D-D((D-1E $E21E25H7&FHG-G H GHG0/H0$HHHHc tj|}g}|r+|d} t|}n<#t$r/}||t jd|zfYd}~]d}~wwxYw tj|}n?#t$r2}||t jd|d|fYd}~d}~wwxYwtj |j s@tj |j s'||t jd|zft|}|r t|}t||rh|d|Dvr.|d||d|t#||\} } ||| | fn&||t jd|dfn?#t$$r2}||t jd |d |fYd}~nd}~wwxYw t)|\} } nG#t*tf$r3}||t jd |d |fYd}~gd}~wwxYw || | |\} }| |kr*||t jd | d | dfn.||t jd| d | d| d|fnB#t2$r5}||t jd| d| d|fYd}~nd}~wwxYw|+|S)Nrzunable to convert to device: %sz stat of 'z ' failed: zdevice '%s' not a block devicecg|] }|d S)rr.).0xs r0 z"resize_devices..s(<(<(>  3Y?? (<(>JS#czz :>$$F 44SS2%    KKMMttUUUAA'         c yv KsA A9 %A44A9=B C(C  C>JA8L L? +L::L?rcfgcloudr argsc d|vr'|dtzt|d<|d}t|ts|ddS|dd}t j|r9|dkr|d|d|d |zdSt j|d d rKtj d r,|d |ddSt j |ddg}t|s|ddS t||j}nB#tt f$r.} |d|d| |dkr| Yd} ~ dSd} ~ wwxYwt j|jdt$||f} | D]P\} } } | t&jkr|d| d| 2|d| d| d| QdS)NrWz.No 'growpart' entry in cfg. Using default: %sz#'growpart' in config was not a dictr"r offzDEPRECATED: growpart mode 'z#' is deprecated. Use 'off' instead.zgrowpart disabled: mode=%sr$Fz/etc/growroot-disabledz0growpart disabled: /etc/growroot-disabled existsz&use ignore_growroot_disabled to ignorer#r!zgrowpart: empty device listz%growpart unable to find resizer for 'z': r)logfuncmsgfuncrrz ' resized: z' r)rDEFAULT_CONFIGget isinstancedictrr is_falser[rlisfileget_cfg_option_listlenr?r1r5r6log_timerr&r(r)rrrr rmycfgr"r#r9rwresizedentryactionrs r0handler9s <~ M   )J GGJ  E eT " " 9::: 99VV $ $D }T 5== KK%d%%%    .5666 }UYY95AABB 7>>2 3 3  IIH I I I II> ? ? ? F&ui#??G w<< /000!$ 55  " DDD!!LMMM 6>>G  m  w  G !(<< V^ # # HHH555##6 7 7 7 7 IIIuuufffcc: ; ; ; ; <rs    ########$$$$$$,,,,,,,,,,!!!!!!######<<<<<<<<11111111))))))8    %}      ( "7j< ,t   u % t*++ g!!#v<     I         c    0+0+0+0+0+W0+0+0+f$+$+$+$+$+'$+$+$+N( ( ( V.    6"4U38_4444n@@@F5< 5<5<#(5