Current File : //lib/python2.7/site-packages/cloudinit/config/cc_disk_setup.pyo
�
oB�]c@s�dZddlmZddlmZddlZddlZddlZeZej	d�Z
ej	d�Zej	d�Zej	d�Z
ej	d	�Zej	d
�Zej	d�Zidd
6Zeje�Zd�Zd�Zd�Zdd�Zed�Zd�Zed�Zd�Zd�Zddde dd�Z!d�Z"d�Z#d�Z$d�Z%d�Z&d�Z'd�Z(d�Z)d �Z*d!�Z+d"�Z,d#�Z-d$�Z.d%�Z/d&�Z0d'�Z1d(�Z2d)�Z3d*�Z4dS(+s�
Disk Setup
----------
**Summary:** configure partitions and filesystems

This module is able to configure simple partition tables and filesystems.

.. note::
    for more detail about configuration options for disk setup, see the disk
    setup example

For convenience, aliases can be specified for disks using the
``device_aliases`` config key, which takes a dictionary of alias: path
mappings. There are automatic aliases for ``swap`` and ``ephemeral<X>``, where
``swap`` will always refer to the active swap partition and ``ephemeral<X>``
will refer to the block device of the ephemeral image.

Disk partitioning is done using the ``disk_setup`` directive. This config
directive accepts a dictionary where each key is either a path to a block
device or an alias specified in ``device_aliases``, and each value is the
configuration options for the device. The ``table_type`` option specifies the
partition table type, either ``mbr`` or ``gpt``. The ``layout`` option
specifies how partitions on the device are to be arranged. If ``layout`` is set
to ``true``, a single partition using all the space on the device will be
created. If set to ``false``, no partitions will be created. Partitions can be
specified by providing a list to ``layout``, where each entry in the list is
either a size or a list containing a size and the numerical value for a
partition type. The size for partitions is specified in **percentage** of disk
space, not in bytes (e.g. a size of 33 would take up 1/3 of the disk space).
The ``overwrite`` option controls whether this module tries to be safe about
writing partition talbes or not. If ``overwrite: false`` is set, the device
will be checked for a partition table and for a file system and if either is
found, the operation will be skipped. If ``overwrite: true`` is set, no checks
will be performed.

.. note::
    Using ``overwrite: true`` is dangerous and can lead to data loss, so double
    check that the correct device has been specified if using this option.

File system configuration is done using the ``fs_setup`` directive. This config
directive accepts a list of filesystem configs. The device to create the
filesystem on may be specified either as a path or as an alias in the format
``<alias name>.<y>`` where ``<y>`` denotes the partition number on the device.
The partition can also be specified by setting ``partition`` to the desired
partition number. The ``partition`` option may also be set to ``auto``, in
which this module will search for the existance of a filesystem matching the
``label``, ``type`` and ``device`` of the ``fs_setup`` entry and will skip
creating the filesystem if one is found. The ``partition`` option may also be
set to ``any``, in which case any file system that matches ``type`` and
``device`` will cause this module to skip filesystem creation for the
``fs_setup`` entry, regardless of ``label`` matching or not. To write a
filesystem directly to a device, use ``partition: none``. A label can be
specified for the filesystem using ``label``, and the filesystem type can be
specified using ``filesystem``.

.. note::
    If specifying device using the ``<device name>.<partition number>`` format,
    the value of ``partition`` will be overwritten.

.. note::
    Using ``overwrite: true`` for filesystems is dangerous and can lead to data
    loss, so double check the entry in ``fs_setup``.

.. note::
    ``replace_fs`` is ignored unless ``partition`` is ``auto`` or ``any``.

**Internal name:** ``cc_disk_setup``

**Module frequency:** per instance

**Supported distros:** all

**Config keys**::

    device_aliases:
        <alias name>: <device path>
    disk_setup:
        <alias name/path>:
            table_type: <'mbr'/'gpt'>
            layout:
                - [33,82]
                - 66
            overwrite: <true/false>
    fs_setup:
        - label: <label>
          filesystem: <filesystem type>
          device: <device>
          partition: <"auto"/"any"/"none"/<partition number>>
          overwrite: <true/false>
          replace_fs: <filesystem type>
i����(tPER_INSTANCE(tutilNtudevadmtsfdisktsgdisktlsblktblkidtblockdevtwipefstCtLANGcCs�|jd�}t|t�r�t||j�|jdt|��x�|j�D]�\}}t|t�s�|jd|�qQny@|jd�t	j
dtjdd|dtd	||f�WqQt
k
r�}t	jtd
|�qQXqQWn|jd�}	t|	t�r�|jdt|	��t|	|j�x�|	D]�}t|t�sk|jd
|�q?nyL|jd�|jd�}
t	j
dtjdd|
dtd	|f�Wq?t
k
r�}t	jtd|�q?Xq?WndS(s[
    See doc/examples/cloud-config-disk-setup.txt for documentation on the
    format.
    t
disk_setupsPartitioning disks: %ssInvalid disk definition for %ss!Creating new partition table/disktlogfunctmsgsCreating partition on %stfunctargss Failed partitioning operation
%stfs_setupssetting up filesystems: %ss"Invalid file system definition: %ssCreating new filesystem.tdevicesCreating fs for %ss%Failed during filesystem operation
%sN(tgett
isinstancetdicttupdate_disk_setup_devicestdevice_name_to_devicetdebugtstrtitemstwarningRtlog_timetLOGtmkpartt	Exceptiontlogexctlisttupdate_fs_setup_devicestmkfs(t_nametcfgtcloudtlogt_argsRtdiskt
definitionteRR((sB/usr/lib/python2.7/site-packages/cloudinit/config/cc_disk_setup.pythandlezs>




cCs�x�|j�D]�}||�}|dks
||kr=q
n||krftjd||�||=n||||<|||d<||=tjd||�q
WdS(Ns0Replacing %s in disk_setup for translation of %st	_orignames,updated disk_setup device entry '%s' to '%s'(tkeystNoneRtinfoR(Rttformertorignamettransformed((sB/usr/lib/python2.7/site-packages/cloudinit/config/cc_disk_setup.pyR�s	

	cCsx�|D]�}t|t�s2tjd|�qn|jd�}|dkrSqntj|�\}}||�}|dk	r�|}tjd|||�||d<||d<n|rd|kr�tjd|||�|d|d<n||d<qqWdS(Ns"entry in disk_setup not a dict: %sRs%s is mapped to disk=%s part=%sR,t	partitionsKPartition '%s' from dotted device name '%s' overrides 'partition' key in %st
_partition(	RRRRRR.Rtexpand_dotted_devnameR(RR0R)R1tdevtpartttformed((sB/usr/lib/python2.7/site-packages/cloudinit/config/cc_disk_setup.pyR!�s,
	


	ccsdtj|�}|r"||}nx;g|D]}|jd�^q,D]\}}||fVqEWdS(sd
    Returns the key/value pairs of output sent as string
    like:  FOO='BAR' HOME='127.0.0.1'
    t=N(tshlextsplit(tvalueststartt_valuestxtkeytvalue((sB/usr/lib/python2.7/site-packages/cloudinit/config/cc_disk_setup.pytvalue_splitter�s

/ccstddd|g}|r+|jd�nd}ytj|�\}}Wn)tk
ru}td||f��nXg|j�j�D]$}t|j	��dkr�|^q�}xb|D]Z}idd6dd6dd	6dd
6}	x*t
|�D]\}
}||	|
j�<q�W|	Vq�WdS(s�
    Enumerate the elements of a child device.

    Parameters:
        device: the kernel device name
        nodeps <BOOL>: don't enumerate children devices

    Return a dict describing the disk:
        type: the entry type, i.e disk or part
        fstype: the filesystem type, if it exists
        label: file system label, if it exists
        name: the device name, i.e. sda
    s--pairss--outputsNAME,TYPE,FSTYPE,LABELs--nodepss"Failed during disk check for %s
%sitnamettypetfstypetlabelN(t	LSBLK_CMDtappendR.RtsubpRtstript
splitlinestlenR;RBtlower(Rtnodepst	lsblk_cmdR/t_errR*R?tpartsR7tdR@RA((sB/usr/lib/python2.7/site-packages/cloudinit/config/cc_disk_setup.pytenumerate_disk�s&	=

cCs;x4t|dt�D] }d|kr|dj�SqWdS(s@
    Return the device type of the device by calling lsblk.
    RNRDN(RStTrueRMR.(RRR((sB/usr/lib/python2.7/site-packages/cloudinit/config/cc_disk_setup.pytdevice_typescCsld}yt|�}Wn"tk
r:tjd|�tSX|rQ|dkrQtS|rh|dkrhtStS(s0
    Check if the device is a valid device.
    tsQuery against device %s failedR7R((RURRRtFalseRT(RCR3td_type((sB/usr/lib/python2.7/site-packages/cloudinit/config/cc_disk_setup.pytis_device_valids
c
Csd
\}}}}tdd|g}y%tj|dddg�\}}Wn)tk
rt}td||f��nX|r
t|j��dkr
xtt|dd�D]]\}}	|j�d	kr�|	}q�|j�d
kr�|	}q�|j�dkr�|	}q�q�Wq
n|||fS(s�
    Check if the device has a filesystem on it

    Output of blkid is generally something like:
    /dev/sda: LABEL="Backup500G" UUID="..." TYPE="ext4"

    Return values are device, label, type, uuid
    s-cs	/dev/nulltrcsiis"Failed during disk check for %s
%siR=RFRDtuuidN(NNNN(	R.t	BLKID_CMDRRIRRLRKRBRM(
RtoutRFtfs_typeR[t	blkid_cmdRPR*R@RA((sB/usr/lib/python2.7/site-packages/cloudinit/config/cc_disk_setup.pytcheck_fs,s 	%		cCst|�\}}}|S(s7
    Returns true if the device has a file system.
    (R`(Rt_R^((sB/usr/lib/python2.7/site-packages/cloudinit/config/cc_disk_setup.pyt
is_filesystemJsc	Cs@|d
krd}n|s*ddg}nt}x�t|�D]�}|d|krq|tkrqd|dtfS|d|kr�|r�|d|ks�|r�d|dtfS|d|kr=|ddks�|dr�t}n|ddkr�q|dsd|dtfSq=q=W|s)|tfStjd	�d
tfS(s
    Find a device that is either matches the spec, or the first

    The return is value is (<device>, <bool>) where the device is the
    device to use and the bool is whether the device matches the
    fs_type and label.

    Note: This works with GPT partition tables!
    RVR(R7REs/dev/%sRCRFRDs5Failed to find device during available device search.N(R.RWRSRTRR(RR^RFt
valid_targetstlabel_matcht
replace_fstraw_device_usedRR((sB/usr/lib/python2.7/site-packages/cloudinit/config/cc_disk_setup.pytfind_device_nodeRs,		


cCsEttt|���dkr"tSt|�\}}}|rAtStS(s�
    Check if the device is currently used. Returns true if the device
    has either a file system or a partition entry
    is no filesystem found on the disk.
    i(RLR RSRTR`RW(RRatcheck_fstype((sB/usr/lib/python2.7/site-packages/cloudinit/config/cc_disk_setup.pytis_disk_used�s	cGs�t|�dkr!td��n|d|d}|d}y&|rWt�||�St�|SWn!tk
r�td|��nXdS(s-
    Call the appropriate function.

    The first value is the template for function name
    The second value is the template replacement
    The remain values are passed to the function

    For example: get_dyn_func("foo_%s", 'bar', 1, 2, 3,)
        would call "foo_bar" with args of 1, 2, 3
    is*Unable to determine dynamic funcation nameiisNo such function %s to call!N(RLRtglobalstKeyError(Rt	func_namet	func_args((sB/usr/lib/python2.7/site-packages/cloudinit/config/cc_disk_setup.pytget_dyn_func�s

cCs�y@tjtd|g�\}}tjtd|g�\}}Wn)tk
rk}td||f��nXt|�t|�S(Ns--getsize64s--getsssFailed to get %s size
%s(RRIt
BLKDEV_CMDRtint(Rt
size_in_bytesRatsector_sizeR*((sB/usr/lib/python2.7/site-packages/cloudinit/config/cc_disk_setup.pytget_hdd_size�s"cCsIt|�td|g}y#tj|dd|�\}}Wn)tk
rg}td||f��nXg}x�|j�D]�}|j�}t|�dkr�q{n||dkr{|dj�dkr�q{nd
}	xWt
td	t|��d
t�D]4}
||
j
�r�||
dkr�||
}	Pq�q�W|j|	�q{q{W|S(s�
    Returns true if the partition layout matches the one on the disk

    Layout should be a list of values. At this time, this only
    verifies that the number of partitions and their labels is correct.
    s-ltdatas%s
s(Error running partition command on %s
%sii����textendedtemptyitreverset/(RuRvN(tread_parttblt
SFDISK_CMDRRIRRKR;RLRMR.tsortedtrangeRTtisdigitRH(Rtlayouttprt_cmdR]RPR*tfound_layouttlinet_linet
type_labelR?((sB/usr/lib/python2.7/site-packages/cloudinit/config/cc_disk_setup.pytcheck_partition_mbr_layout�s,
#( 
cCstd|g}ytj|dt�\}}Wn)tk
rY}td||f��nXt|j��}x'|D]}|j�jd�rsPqsqsWg|D]}|j�j	�d^q�}g}	xL|D]D}
t
|
�dkr|
jd�r|
dd	!}
n|	j|
�q�W|	S(
Ns-pt
update_envs(Error running partition command on %s
%stNumberiit00ii(
t
SGDISK_CMDRRIt
LANG_C_ENVRtiterRKRJt
startswithR;RLtendswithRH(RR~RR]RPR*t	out_linesR�tcodestcleanedtcode((sB/usr/lib/python2.7/site-packages/cloudinit/config/cc_disk_setup.pytcheck_partition_gpt_layout�s"
)
!cCstd|||�}tjd||||�t|t�r]|rYt|�dkrYtStSt|�t|�krg|D]1}t|tt	f�r�t
|d�nd^q|}tjd||�xEt||�D]4\}}|dk	r�t
|�t
|�kr�tSq�WtStS(s�
    See if the partition lay out matches.

    This is future a future proofing function. In order
    to add support for other disk layout schemes, add a
    function called check_partition_%s_layout
    scheck_partition_%s_layouts6called check_partition_%s_layout(%s, %s), returned: %sisLayout types=%s. Found types=%sN(
RnRRRtboolRLRTRWttupleR RR.tzip(t
table_typeRR~R�R?tlayout_typestitypetftype((sB/usr/lib/python2.7/site-packages/cloudinit/config/cc_disk_setup.pytcheck_partition_layout
s$	;	
$c
Cs�t|t�r#t|t�r#dSt|�dkrDt|t�sTt|t�rctd��nt|�}|dkr�td��ng}d}x�|D]�}d}|}|d7}t|t�r�t|�dkr�td	|��n|\}}ntt|�t|�d
�}||kr<|jd|�q�|jd||f�q�Wd
j|�}	t|�dkr�td|	��n|	S(s@
    Calculate the layout of the partition table. Partition sizes
    are defined as percentage values or a tuple of percentage and
    partition type.

    For example:
        [ 33, [66: 82] ]

    Defines the first partition to be a size of 1/3 the disk,
    while the remaining 2/3's will be of type Linux Swap.
    s0,isPartition layout is invalidis$Only simply partitioning is allowed.iSiis%Partition was incorrectly defined: %sids,,%ss,%s,%ss
s-Calculated partition definition is too big
%s(	RR R�RLRRptfloatRHtjoin(
tsizeR~t
last_part_numtpart_definitiontpart_numR7t	part_typetpercentt	part_sizetsfdisk_definition((sB/usr/lib/python2.7/site-packages/cloudinit/config/cc_disk_setup.pytget_partition_mbr_layout-s6
!

 
cCs�t|t�r"dddgfgSg}x�|D]�}t|t�rxt|�dkritd|��n|\}}n|}d}tt|�t|�d�}|j|ddj	|�gf�q/Wd|ddd<|S(Niis%Partition was incorrectly defined: %sids+{}i����(
RR�R.R RLRRpR�RHtformat(R�R~tpartition_specsR3R�tpartition_typeR�((sB/usr/lib/python2.7/site-packages/cloudinit/config/cc_disk_setup.pytget_partition_gpt_layoutas
 &cCsxd}d}d}t|d��G}|j||�|j|tj�|j||�|j�WdQXt|�dS(Ntisrb+ii(topentwritetseektostSEEK_ENDtflushRy(Rtnullt	start_lentend_lentfp((sB/usr/lib/python2.7/site-packages/cloudinit/config/cc_disk_setup.pytpurge_disk_ptablexscCs�x�t|�D]}}|dd
kr
tdd|dg}y%tjd|d�tj|�Wq�tk
r�td|d��q�Xq
q
Wt|�d	S(s'
    Remove parition table entries
    RDR(tcrypts--alls/dev/%sRCsPurging filesystem on /dev/%ssFailed FS purge of /dev/%sN(sdiskR�(RSt
WIPEFS_CMDRR/RRIRR�(RRRt
wipefs_cmd((sB/usr/lib/python2.7/site-packages/cloudinit/config/cc_disk_setup.pyt
purge_disk�s
cCstd|||�S(s�
    Call the appropriate function for creating the table
    definition. Returns the table definition

    This is a future proofing function. To add support for
    other layouts, simply add a "get_partition_%s_layout"
    function.
    sget_partition_%s_layout(Rn(R�R�R~((sB/usr/lib/python2.7/site-packages/cloudinit/config/cc_disk_setup.pytget_partition_layout�s	cCsbtd|g}tj�ytj|�Wn'tk
rS}tjtd|�nXtj�dS(sr
    Use partprobe instead of 'udevadm'. Partprobe is the only
    reliable way to probe the partition table.
    s
--rereadpts%Failed reading the partition table %sN(RoRtudevadm_settleRIRRR(Rt
blkdev_cmdR*((sB/usr/lib/python2.7/site-packages/cloudinit/config/cc_disk_setup.pyRy�s
cCsjtddd|g}ytj|dd|�Wn)tk
r[}td||f��nXt|�dS(sV
    Break out of mbr partition to allow for future partition
    types, i.e. gpt
    s--Linuxs--unit=Ss--forceRts%s
s Failed to partition device %s
%sN(RzRRIRRy(RR~RR*((sB/usr/lib/python2.7/site-packages/cloudinit/config/cc_disk_setup.pytexec_mkpart_mbr�scCs�y�tjtd|g�x�t|�D]�\}\}\}}|d7}tjtddj|||�|g�|dk	r&t|�jdd�}tjtddj||�|g�q&q&WWn$tk
r�t	j
d	|��nXt|�dS(
Ns-Zis-ns{}:{}:{}it0s-ts{}:{}sFailed to partition device %s(RRIR�t	enumerateR�R.RtljustRRRRy(RR~tindexR�R=tendtpinput((sB/usr/lib/python2.7/site-packages/cloudinit/config/cc_disk_setup.pytexec_mkpart_gpt�s%
	*
cCstd|||�S(s
    Fetches the function for creating the table type.
    This allows to dynamically find which function to call.

    Paramaters:
        table_type: type of partition table to use
        device: the device to work on
        layout: layout definition specific to partition table
    sexec_mkpart_%s(Rn(R�RR~((sB/usr/lib/python2.7/site-packages/cloudinit/config/cc_disk_setup.pytexec_mkpart�s
cCsRtjj|�sDtj�tjj|�sDtd|��qDntj�dS(s?Assert that device exists and settle so it is fully recognized.sBDevice %s did not exist and was not created with a udevadm settle.N(R�tpathtexistsRR�tRuntimeError(R((sB/usr/lib/python2.7/site-packages/cloudinit/config/cc_disk_setup.pytassert_and_settle_device�s
c	Cs�t|�tjj|�}tjd|�|jdt�}|jdt�}|jdd�}tjd�t|t	�r�|s�|r�tjd�dStjd	|�t
|�s�td
jd|���nt|t
�r|j�dkrtjd
�t|�dStjd�t|||�r@tjd�tStjd�|r�t|�slt|�r�tjd|�dStjd|�t|�}tjd�t|||�}tjd|�tjd|�t|||�tjd|�dS(s�
    Creates the partition table.

    Parameters:
        definition: dictionary describing how to create the partition.

            The following are supported values in the dict:
                overwrite: Should the partition table be created regardless
                            of any pre-exisiting data?
                layout: the layout of the partition table
                table_type: Which partition table to use, defaults to MBR
                device: the device to work on.
    s!Checking values for %s definitiont	overwriteR~R�tmbrs Checking against default devicess)Device is not to be partitioned, skippingNs'Checking if device %s is a valid devices%Device {device} is not a disk device!Rtremoves,Instructed to remove partition table entriess!Checking if device layout matchess"Device partitioning layout matchess'Checking if device is safe to partitions-Skipping partitioning on configured device %ssChecking for device size of %ssCalculating partition layouts   Layout is: %ssCreating partition table on %ssPartition table created for %s(R�R�R�trealpathRRRRWRR�RYRR�RRMR�R�RTRiRbRsR�R�(RR)R�R~R�tdevice_sizeR�((sB/usr/lib/python2.7/site-packages/cloudinit/config/cc_disk_setup.pyR�sD


!





cCskidd6dd6dd6dd6}d|j�kr=d}n|j�|krW||Stjd|�dS(	s9
    A force flag might be -F or -F, this look it up
    s-Ftexts-ftbtrfstxfstreiserfssForce flag for %s is unknown.RV(RMRR(tfstflags((sB/usr/lib/python2.7/site-packages/cloudinit/config/cc_disk_setup.pytlookup_force_flag3s
	cCs�|jd�}|jd�}t|jdd��}|jd�}|jdg�}|jdg�}|jdt�}|jd	t�}t|�tjj|�}tjd
|�|s�|j	�r�|j	�r�d||f}tjd||�ntjd
|�t
|�\}	}
}tjd||	|
�|	|kr�|
|kr�tjd|�|s{tjd|�dStjd|�q�tjd|�n/|r�t|�j�d-kr�|}tjd|�t
}
|j�dkr�t}
nt|d|d|d|
d|�\}}tjd||�|rJtjd�dS|rp|rp|rptjd|�n|s�tjd|�dSnC|s�t|�j�dkr�tjd|�ntjd�dStjd|||�|stjd |�dS|p	|s'td!jd|���nt}|r�|di|d6|d6|d6}t
}|rutjd"|�n|rItjd#|�qIn�tjd$|�}|s�tjd%|�}n|s�tjd&||�dS||g}|r|jd'|g�n|st|�d(kr3|jt|��n|rI|j|�ntjd)||�tjd*t|��ytj|d+|�Wn)tk
r�}td,||f��nXdS(.s�
    Create a file system on the device.

        label: defines the label to use on the device
        fs_cfg: defines how the filesystem is to look
            The following values are required generally:
                device: which device or cloud defined default_device
                filesystem: which file system type
                overwrite: indiscriminately create the file system
                partition: when device does not define a partition,
                            setting this to a number will mean
                            device + partition. When set to 'auto', the
                            first free device or the first device which
                            matches both label and type will be used.

                            'any' means the first filesystem that matches
                            on the device.

            When 'cmd' is provided then no other parameter is required.
    RFRR3tanyt
filesystemtcmdt
extra_optsReR�s#Checking %s against default devicess%s%ss%Manual request of partition %s for %ssChecking device %ss0Device '%s' has check_label='%s' check_fstype=%ss Existing file system found at %ss"Device %s has required file systemNsDestroying filesystem on %ss"Device %s is cleared for formatingtautos,Identifying device to create %s filesytem onR^Rds(Automatic device for %s identified as %ss+Found filesystem match, skipping formating.s*Replacing file system on %s as instructed.sCNo device aviable that matches request. Skipping fs creation for %stnones.Using the raw device to place filesystem %s ons(Error in device identification handling.s;File system type '%s' with label '%s' will be created on %ssDevice is not known: %ssENo way to create filesystem '{label}'. fs_type or fs_cmd must be set.s8fs_setup:overwrite ignored because cmd was specified: %ss9fs_setup:extra_opts ignored because cmd was specified: %ssmkfs.%ssmk%ss.Cannot create fstype '%s'.  No mkfs.%s commands-LR(sCreating file system %s on %ss     Using cmd: %stshellsFailed to exec of '%s':
%s(R�sany(RRRWR�R�R�R�RRR}R`RRMRTRgRR�RtwhichtextendRURHR�RI(tfs_cfgRFRR3R^tfs_cmdtfs_optst
fs_replaceR�tcheck_labelRhRatodeviceRdtreuseR�tmkfs_cmdR*((sB/usr/lib/python2.7/site-packages/cloudinit/config/cc_disk_setup.pyR"Hs�
	
	
	
	
	
	


	
(5t__doc__tcloudinit.settingsRt	cloudinitRtloggingR�R:t	frequencyR�tUDEVADM_CMDRzR�RGR\RoR�R�t	getLoggert__name__RR+RR!R.RBRWRSRURYR`RbRTRgRiRnRsR�R�R�R�R�R�R�R�RyR�R�R�R�RR�R"(((sB/usr/lib/python2.7/site-packages/cloudinit/config/cc_disk_setup.pyt<module>bsZ
	)		!
+				0			
	&	(	#	4								
		A