Current File : //lib/python2.7/site-packages/cloudinit/config/cc_growpart.pyo
�
oB�]c@sCdZddlZddlZddlZddlZddlmZddlm	Z	ddlm
Z
e	Zidd6dgd	6ed
6Z
defd��YZeje�Zd
�Zdefd��YZdefd��YZdefd��YZd�Zd�Zd�Zd�Zd�ZdefdeffZdS(s�
Growpart
--------
**Summary:** grow partitions

Growpart 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 run growpart on are specified as a list under the ``devices`` key.
Each entry in the devices list can be either the path to the device's
mountpoint in the filesystem or a path to the block device in ``/dev``.

The utility to use for resizing can be selected using the ``mode`` config key.
If ``mode`` key is set to ``auto``, then any available utility (either
``growpart`` or ``gpart``) will be used. If neither utility is available, no
error will be raised. If ``mode`` is set to ``growpart``, then the ``growpart``
utility will be used. If this utility is not available on the system, this will
result in an error. If ``mode`` is set to ``off`` or ``false``, then
``cc_growpart`` will take no action.

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 existance 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

**Internal name:** ``cc_growpart``

**Module frequency:** per always

**Supported distros:** all

**Config keys**::

    growpart:
        mode: <auto/growpart/off/false>
        devices:
            - "/"
            - "/dev/vdb1"
        ignore_growroot_disabled: <true/false>
i����N(tlog(t
PER_ALWAYS(tutiltautotmodet/tdevicestignore_growroot_disabledtRESIZEcBs eZdZdZdZdZRS(tSKIPPEDtCHANGEDtNOCHANGEtFAILED(t__name__t
__module__R	R
RR(((s@/usr/lib/python2.7/site-packages/cloudinit/config/cc_growpart.pyRTsc	Cs�d}|dkr`x3tD]+\}}|�}|j�r|}PqqW|s�td��q�n�i}xtD]\}}|||<qmW||kr�td|��n||�}|j�r�|}n|s�td|��n|S(NRsNo resizers availablesunknown resize mode %ssmode %s not available(tNonetRESIZERSt	availablet
ValueErrort	TypeError(	Rtresize_classt_nametresizertcurtmmaptktvtmclass((s@/usr/lib/python2.7/site-packages/cloudinit/config/cc_growpart.pytresizer_factory^s(	
	tResizeFailedExceptioncBseZRS((R
R(((s@/usr/lib/python2.7/site-packages/cloudinit/config/cc_growpart.pyR|stResizeGrowPartcBseZd�Zd�ZRS(cCsutjj�}d|d<yAtjddgd|�\}}tjd|tj�rYtSWntj	k
rpnXt
S(NtCtLANGtgrowparts--helptenvs--update\s+(tostenvirontcopyRtsubptretsearchtDOTALLtTruetProcessExecutionErrortFalse(tselftmyenvtoutt_err((s@/usr/lib/python2.7/site-packages/cloudinit/config/cc_growpart.pyR�s
!cCs�t|�}ytjdd||g�WnQtjk
r|}|jdkrrtjtd||�t|��n||fSXytjd||g�Wn8tjk
r�}tjtd||�t|��nX|t|�fS(NR!s	--dry-runis&Failed growpart --dry-run for (%s, %s)sFailed: growpart %s %s(tget_sizeRR&R+t	exit_codetlogexctLOGR(R-tdiskdevtpartnumtpartdevtbeforete((s@/usr/lib/python2.7/site-packages/cloudinit/config/cc_growpart.pytresize�s
(R
RRR:(((s@/usr/lib/python2.7/site-packages/cloudinit/config/cc_growpart.pyR�s	
tResizeGpartcBseZd�Zd�ZRS(cCstjd�stStS(Ntgpart(RtwhichR,R*(R-((s@/usr/lib/python2.7/site-packages/cloudinit/config/cc_growpart.pyR�scCs�ytjdd|g�WnGtjk
rc}|jdkrdtjtd|�t|��qdnXt|�}y tjddd||g�Wn8tjk
r�}tjtd||�t|��nXtdd	�j	�|t|�fS(
s9
        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<trecoverisFailed: gpart recover %sR:s-isFailed: gpart resize -i %s %ss/var/run/reboot-requiredta(
RR&R+R2R3R4RR1topentclose(R-R5R6R7R9R8((s@/usr/lib/python2.7/site-packages/cloudinit/config/cc_growpart.pyR:�s (R
RRR:(((s@/usr/lib/python2.7/site-packages/cloudinit/config/cc_growpart.pyR;�s	cCsDtj|tj�}ztj|dtj�SWdtj|�XdS(Ni(R#R@tO_RDONLYtlseektSEEK_ENDRA(tfilenametfd((s@/usr/lib/python2.7/site-packages/cloudinit/config/cc_growpart.pyR1�scCs]tjj|�}tjj|�}d|}tj�r{dtj|�}tjd|�}|j	d�|j	d�fStjj
|�s�td||f��ntjj|d�}tjj
|�s�t
d|��ntj|�j�}tjj|�}tjj|�}	tjtjj|	d	��j�}
tjjd
|
�}||fS(Ns/sys/class/block/%ss/dev/s^(/dev/.+)p([0-9])$iis%s had no syspath (%s)t	partitions%s not a partitiontdevs
/dev/block/%s(R#tpathtrealpathtbasenameRt
is_FreeBSDtfind_freebsd_partR'R(tgrouptexistsRtjoinRt	load_filetrstriptdirname(tdevpathtrpathtbnametsyspathtfreebsd_parttmtptpathtptnumtrsyspathtdisksyspatht
diskmajmintdiskdevpath((s@/usr/lib/python2.7/site-packages/cloudinit/config/cc_growpart.pytdevice_part_info�s$
$cCs�|jd�r|Stj|�}|s7td��n|d}tj�}|dkr�|r�tjtj��}|dkr�tj	j
|�r�|Std��q�n|S(Ns/dev/s,Could not determine device of '%s' % dev_entis	/dev/roots!Unable to find device '/dev/root'(t
startswithRtget_mount_infoRtis_containertrootdev_from_cmdlinetget_cmdlineRR#RIRO(tdeventtresultRHt	container((s@/usr/lib/python2.7/site-packages/cloudinit/config/cc_growpart.pyt
devent2dev�s
c
Csg}x�|D]�}yt|�}Wn3tk
rX}|j|tjd|f�q
nXytj|�}Wn9tk
r�}|j|tjd||ff�q
nXtj|j	�r�tj
|j	�r�|j|tjd|f�q
nyt|�\}}Wn?ttfk
rH}|j|tjd||ff�q
nXyz|j
|||�\}	}
|	|
kr�|j|tjd||ff�n)|j|tjd|||	|
ff�Wq
tk
r�}|j|tjd|||ff�q
Xq
W|S(Nsunable to convert to device: %ssstat of '%s' failed: %ssdevice '%s' not a block devicesdevice_part_info(%s) failed: %ssno change necessary (%s, %s)schanged (%s, %s) from %s to %ss'failed to resize: disk=%s, ptnum=%s: %s(RiRtappendRR	R#tstattOSErrortS_ISBLKtst_modetS_ISCHRR`RR:RR
RR(RRtinfoRftblockdevR9tstatrettdiskR[toldtnew((s@/usr/lib/python2.7/site-packages/cloudinit/config/cc_growpart.pytresize_devicessL
c
Cs�d|kr*|jdt�t|d<n|jd�}t|t�sY|jd�dS|jdd�}tj|�r�|jd|�dStj|jdt��r�t	j
jd�r�|jd	�|jd
�dSntj|ddg�}t
|�s|jd
�dSyt|�}WnFttfk
rj}	|jd||	f�|dkrf|	�ndSXtjd|jdddtd||f�}
xZ|
D]R\}}}
|tjkr�|jd||
f�q�|jd|||
f�q�WdS(NR!s.No 'growpart' entry in cfg.  Using default: %ss#'growpart' in config was not a dictRRsgrowpart disabled: mode=%sRs/etc/growroot-disableds0growpart disabled: /etc/growroot-disabled existss&use ignore_growroot_disabled to ignoreRRsgrowpart: empty device lists,growpart unable to find resizer for '%s': %stlogfunctmsgRvtfunctargss'%s' resized: %ss'%s' %s: %s(tdebugtDEFAULT_CONFIGtgett
isinstancetdicttwarningRtis_falseR,R#RItisfiletget_cfg_option_listtlenRRRtlog_timeRvRR
Rp(Rtcfgt_cloudRt_argstmycfgRRRR9tresizedtentrytactionRx((s@/usr/lib/python2.7/site-packages/cloudinit/config/cc_growpart.pythandle<sD	




	R!R<(t__doc__R#tos.pathR'Rkt	cloudinitRtloggingtcloudinit.settingsRRt	frequencyR,R|tobjectRt	getLoggerR
R4Rt	ExceptionRRR;R1R`RiRvR�R(((s@/usr/lib/python2.7/site-packages/cloudinit/config/cc_growpart.pyt<module>@s0

	"#		'		1	,