%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /lib/python2.7/site-packages/salt/states/
Upload File :
Create Path :
Current File : //lib/python2.7/site-packages/salt/states/smartos.pyo

�
���^c@@sPdZddlmZmZmZddlZddlZddlZddlZ	ddl
Z	ddlZ	ddlm
Z
eje�ZdZd�Zd�Zd�Zd	�Zd
�Zd�Zd�Zd
�Zd�Zd�Zd�Zdd�Zd�Zd�Zd�Z d�Z!e"d�Z#e$d�Z%d�Z&d�Z'dS(u�
Management of SmartOS Standalone Compute Nodes

:maintainer:    Jorge Schrauwen <sjorge@blackdot.be>
:maturity:      new
:depends:       vmadm, imgadm
:platform:      smartos

.. versionadded:: 2016.3.0

.. code-block:: yaml

    vmtest.example.org:
      smartos.vm_present:
        - config:
            reprovision: true
        - vmconfig:
            image_uuid: c02a2044-c1bd-11e4-bd8c-dfc1db8b0182
            brand: joyent
            alias: vmtest
            quota: 5
            max_physical_memory: 512
            tags:
              label: 'test vm'
              owner: 'sjorge'
            nics:
              "82:1b:8e:49:e9:12":
                nic_tag: trunk
                mtu: 1500
                ips:
                  - 172.16.1.123/16
                  - 192.168.2.123/24
                vlan_id: 10
              "82:1b:8e:49:e9:13":
                nic_tag: trunk
                mtu: 1500
                ips:
                  - dhcp
                vlan_id: 30
            filesystems:
              "/bigdata":
                source: "/bulk/data"
                type: lofs
                options:
                  - ro
                  - nodevices

    kvmtest.example.org:
      smartos.vm_present:
        - vmconfig:
            brand: kvm
            alias: kvmtest
            cpu_type: host
            ram: 512
            vnc_port: 9
            tags:
              label: 'test kvm'
              owner: 'sjorge'
            disks:
              disk0
                size: 2048
                model: virtio
                compression: lz4
                boot: true
            nics:
              "82:1b:8e:49:e9:15":
                nic_tag: trunk
                mtu: 1500
                ips:
                  - dhcp
                vlan_id: 30

    docker.example.org:
      smartos.vm_present:
        - config:
            auto_import: true
            reprovision: true
        - vmconfig:
            image_uuid: emby/embyserver:latest
            brand: lx
            alias: mydockervm
            quota: 5
            max_physical_memory: 1024
            tags:
              label: 'my emby docker'
              owner: 'sjorge'
            resolvers:
              - 172.16.1.1
            nics:
              "82:1b:8e:49:e9:18":
                nic_tag: trunk
                mtu: 1500
                ips:
                  - 172.16.1.118/24
                vlan_id: 10
            filesystems:
              "/config:
                source: "/vmdata/emby_config"
                type: lofs
                options:
                  - nodevices

    cleanup_images:
      smartos.image_vacuum

.. note::

    Keep in mind that when removing properties from vmconfig they will not get
    removed from the vm's current configuration, except for nics, disk, tags, ...
    they get removed via add_*, set_*, update_*, and remove_*. Properties must
    be manually reset to their default value.
    The same behavior as when using 'vmadm update'.
i(tabsolute_importtunicode_literalstprint_functionN(tsixusmartoscC@s3dtkrdtkrtStdjt�fSdS(u5
    Provides smartos state provided for SmartOS
    uvmadm.createuimgadm.listu<{0} state module can only be loaded on SmartOS compute nodesN(t__salt__tTruetFalsetformatt__virtualname__(((s7/usr/lib/python2.7/site-packages/salt/states/smartos.pyt__virtual__�s
cC@sj|rf|jd�}t|�dkrf|d}|d}t|jd��dkrc||fSqfndS(u7
    Split a smartos docker uuid into repo and tag
    u:iiiu/N(NN(tsplittlentNone(tuuidttagtrepo((s7/usr/lib/python2.7/site-packages/salt/states/smartos.pyt_split_docker_uuid�s

cC@sB|r>td�|jd�D��dddddgkr>tStS(ub
    Check if uuid is a valid smartos uuid

    Example: e69a0918-055d-11e5-8912-e3ceb6df4cf8
    cs@s|]}t|�VqdS(N(R(t.0tx((s7/usr/lib/python2.7/site-packages/salt/states/smartos.pys	<genexpr>�su-iii(tlistR
RR(R
((s7/usr/lib/python2.7/site-packages/salt/states/smartos.pyt_is_uuid�s:cC@st|�\}}|o|S(u_
    Check if uuid is a valid smartos docker uuid

    Example plexinc/pms-docker:plexpass
    (R(R
RR((s7/usr/lib/python2.7/site-packages/salt/states/smartos.pyt_is_docker_uuid�sc	C@s�i}tjjd�r�tjjjdd���}x�|D]y}tjjj|�}|ddkrkq:nd|kr}q:n|j	d�}|dj
�j
d�||dj�<q:WWdQXntj
d	|�|S(
u)
    Loads and parses /usbkey/config
    u/usbkey/configuriu#u=iu"Nu(smartos.config - read /usbkey/config: %s(tostpathtisfiletsalttutilstfilestfopentstringutilst
to_unicodeR
tstriptlowertlogtdebug(tconfigtconfig_filetoptval((s7/usr/lib/python2.7/site-packages/salt/states/smartos.pyt_load_config�s
4cC@sy�tjjjdd���}|jd�x�tjjjt|j���D]�}dt	j
||�kr�||jd�s�||jd�r�dj
||�||<q�n|jtjjjdj
|||���qMWWdQXtjd	|�Wntk
rtSXtS(
u
    writes /usbkey/config
    u/usbkey/configuwu&#
# This file was generated by salt
#
u u"u"{0}"u{0}={1}
Nu)smartos.config - wrote /usbkey/config: %s(RRt
atomicfiletatomic_opentwritetodicttOrderedDicttsortedtitemsRt	text_typet
startswithtendswithRRtto_strR!R"tIOErrorRR(R#R$tprop((s7/usr/lib/python2.7/site-packages/salt/states/smartos.pyt
_write_config�s
(($
cC@sd}t|tjjj�r�tjjj�}x�|D]�}||krZ||||<q7t||tjjj�s|q7ng||<xb||D]V}|||}||||<d|kr�|dj�|d<n||j|�q�Wq7Wn
tj	d�|S(u$
    Parse vm_present vm config
    umacu4smartos.vm_present::parse_vmconfig - failed to parseN(
Rt
isinstanceRRR*R+R tappendR!terror(R#t	instancestvmconfigR3tinstancetinstance_config((s7/usr/lib/python2.7/site-packages/salt/states/smartos.pyt_parse_vmconfig�s"


cC@s�t|j��}t|j��}tjjj||�}xttjjj||�D]Z}||kr�||ddkr�||=n||krU||ddkrU||=qUqUW|S(u!
    get modified properties
    uolduunew(tsettkeysRRtdatat
compare_dicts(tcurrenttstatetcurrent_keyst
state_keystchangedtchange((s7/usr/lib/python2.7/site-packages/salt/states/smartos.pyt_get_instance_changess 
 c
C@s@d|kr<td|d�jdi�}|jdd�}|jdi�}d|kryd|kry|d|d<n|dkr<t|d<|jdd	�|d<d
|kr�i|d
<nxx|jdi�D]a}|d|}dj|j��}|sq�n|d
kr�y#tj|d
j|d��}Wntk
rP}g}nXx�t|t	�ri|ntj|�D]h}|j
d�}x:|D]2}	|	jdj|d��r�|j|	�q�q�W|j
dj|��qvWn||d
kr�q�nt|t	�r$tj|�|d
|<q�||d
|<q�Wq<n|S(Nu
image_uuidu
imgadm.getumanifestutypeuzone-datasetutagsukernel_versionudockeru4.3.0uinternal_metadatau
docker:configu
docker:{0}u
docker:envuu=u{0}=i(RtgetRRR tjsontloadst
ValueErrorR5RR
R/tremoveR6tjointdumps(
R9t	imgconfigtimgtypetimgtagstvartvalt
val_configtetconfig_env_vartimg_env_var((s7/usr/lib/python2.7/site-packages/salt/states/smartos.pyt
_copy_lx_varssD 


+
cC@sZ|j�}i|d6id6dd6dd6}t�}t|t�r[|rRdnd}n|sjd}n||kr�tj||�tj|�kr�t|d<dj||�|d<q.t|d<d	j||�|d<||d|<|||<n8t|d<d
j||�|d<||d|<|||<t	drV|drVt
|�|d<n|S(
u�
    Ensure configuration property is set to value in /usbkey/config

    name : string
        name of property
    value : string
        value of property

    unameuchangesuresultuucommentutrueufalseu$property {0} already has value "{1}"u%updated property {0} with value "{1}"u#added property {0} with value "{1}"utestN(R RR&R5tboolRR.RRt__opts__R4(tnametvaluetretR#((s7/usr/lib/python2.7/site-packages/salt/states/smartos.pytconfig_presentJs2


		"




cC@s�|j�}i|d6id6d	d6dd6}t�}||krxt|d<dj|�|d<d	|d|<||=nt|d<dj|�|d<tdr�|dr�t|�|d<n|S(
up
    Ensure configuration property is absent in /usbkey/config

    name : string
        name of property

    unameuchangesuresultuucommentuproperty {0} deleteduproperty {0} is absentutestN(R RR&RRRZR4(R[R]R#((s7/usr/lib/python2.7/site-packages/salt/states/smartos.pyt
config_absent|s 

	


uimgapicC@si|d6id6dd6dd6}|td�krUt|d<dj|�|d<n�tdrri}t|d<n#td	||�}||k|d<|dr�d
j|�|d<d|d|<n@dj|�|d<d
|krdj|d|d
�|d<n|S(u�
    Ensure an image source is present on the computenode

    name : string
        source url
    source_type : string
        source type (imgapi or docker)
    unameuchangesuresultuucommentuimgadm.sourcesuimage source {0} is presentutestuimgadm.source_adduimage source {0} addeduaddeduimage source {0} not addeduErroru{0}: {1}N(RRRRRZ(R[tsource_typeR]tres((s7/usr/lib/python2.7/site-packages/salt/states/smartos.pytsource_present�s&	





!cC@si|d6id6dd6dd6}|td�krUt|d<dj|�|d<n�tdrri}t|d<n td	|�}||k|d<|dr�d
j|�|d<d|d|<n@dj|�|d<d
|krdj|d|d
�|d<n|S(uc
    Ensure an image source is absent on the computenode

    name : string
        source url
    unameuchangesuresultuucommentuimgadm.sourcesuimage source {0} is absentutestuimgadm.source_deleteuimage source {0} deletedudeleteduimage source {0} not deleteduErroru{0}: {1}N(RRRRRZ(R[R]Ra((s7/usr/lib/python2.7/site-packages/salt/states/smartos.pyt
source_absent�s&





!cC@s�i|d6id6dd6dd6}t|�rktd|�rkt|d<dj|td|��|d<n]|td�kr�t|d<d	j|�|d<n*t|�r�|g}n
td
�}||kr�tdrt|d<i}t|�r||d<qk||||<nXtd
|�}t|�rB||k|d<n)t|�rktd|�dk	|d<n|dr�dj|�|d<||d<q�dj|�|d<nt|d<dj|�|d<|S(u]
    Ensure image is present on the computenode

    name : string
        uuid of image
    unameuchangesuresultuucommentuimgadm.docker_to_uuiduimage {0} ({1}) is presentuimgadm.listuimage {0} is presentuimgadm.availutestu$00000000-0000-0000-0000-000000000000u
imgadm.importuimage {0} importedu#image {0} was unable to be importeduimage {0} does not existsN(RRRRRRZRR(R[R]tavailable_imagesRa((s7/usr/lib/python2.7/site-packages/salt/states/smartos.pyt
image_present�sD










cC@s�i|d6id6dd6dd6}d}t|�r=|}nt|�r\td|�}n|sv|td�kr�t|d<dj|�|d<n@|td	d
d�kr�t|d<dj|�|d<ntd
r�t|d<n�td|�}d}|dddkrqxl|rm|d7}td|dd�d|dkrdtd|dd�}qd}qWntd|�|td�k|d<|r�dj||�|d<ndj|�|d<d|d|<|S(u�
    Ensure image is absent on the computenode

    name : string
        uuid of image

    .. note::

        computenode.image_absent will only remove the image if it is not used
        by a vm.
    unameuchangesuresultuucommentuimgadm.docker_to_uuiduimgadm.listuimage {0} is absentu
vmadm.listtorderu
image_uuidu"image {0} currently in use by a vmutestu
imgadm.getiumanifestudocker-layeriu
imgadm.deleteuuuiduoriginu"image {0} and {1} children deleteduimage {0} deletedN(RRRRRRRRZ(R[R]R
timagetimage_count((s7/usr/lib/python2.7/site-packages/salt/states/smartos.pytimage_absent"sB

	



	

cC@s�|j�}i|d6id6dd6dd6}g}x�td�D]�}d|krZqBn|dtkrpqBn|ddkr�qBnd|krBt|d�r�|j|d�qt|d�rtd
|d�|d<|ds�qBn|j|d�qqBqBWx7tddd
�D]"}||kr|j|�qqWt|d<xtd�D]}||krsq[ntd|�}|dddkr!x�|r|dd}|td|�kr�d|d|<nt|d<d|d<d|dkrtd|dd�}q�d}q�Wq[|td|�krHd|d|<q[t|d<d|d<q[W|dr�|dr�d|d<n!|dr�|dr�d|d<n|S(u�
    Delete images not in use or installed via image_present

    .. warning::

        Only image_present states that are included via the
        top file will be detected.
    unameuchangesuresultuucommentustate.show_lowstateustateufunu
image_presentuimgadm.docker_to_uuidu
vmadm.listRfu
image_uuiduimgadm.listu
imgadm.getumanifestudocker-layeruuuidu
imgadm.deleteufailed to delete imagesuoriginuno images deleteduimages deletedN(u
image_present(	R RRRRR6RRR(R[R]timagesRBt
image_uuidRg((s7/usr/lib/python2.7/site-packages/salt/states/smartos.pytimage_vacuum`s`	



	





cC@sG|j�}i|d6id6dRd6dd6}|r:|ni}itd6td6td6td	6td
6td6td6td
6}|j|�tjd||�iddddgd6idd6dd6dd6d6dgd6}ddg}ddd g}t||d�}tjd!||�d"|kr7||d"<nd#|kr)td$|d#�}|rc|n|d#|d#<|d#td%�kr)|drt	d&s#td'|d#�}	td$|d#�|d#<|d#|	kr�t|d<d(j
|d#�|d<q�q#q&t|d<d)j
|d#�|d<q)nd|kr�x`|D]U}
|
|dkrXq<nt|d|
t�r<t
j|d|
�|d|
<q<q<Wn|d*d+kr�|dr�t|�}n|dtkr�|S|d"td,d-d"�krBt|d<i|d.6td/|d"d0d"�d16id26dRd36}d#|d.krm|d.d#|d3<|d1d#|d.d#<nd|d.kr+g}x�|d.dD]�}t}
d|d1kr�x>|d1dD]+}|dj|d�r�|d}
Pq�q�Wn|
s�|d=n
|
|d<|j|�q�W||d.d<nx�|d.D]�}||dks6||dks6||dkrrq6n||d1krt|d1|t�s�t|d1|t�r�|d1||d.|kr	q6q	qd4j
|d1|�d4j
|d.|�krq6qn|d.||d2|<q6Wx�|dD]�}||dkrMq1n|d5j
|�}tjd6||�|dkr
|d.jd7t�r
d|d.kr�i|d.d<nxT|D]I}
|d1j|i�j|
dR�}|dRk	r�||d.d|
<q�q�Wn||d.kr|d.|dRk	rx�|d.|D]�}||d1|kr�|d1|||d.||kr�q@n|r�||d1|kr�q@nd8j
|�|d2kr�i|d2d8j
|�<n|d.|||d2d8j
|�|<q@Wn|r1||d1kr1|d1|dRk	r1x�|d1|D]�}||d.kr�|d.|dRk	r�||d.|kr�q?q�nd9j
|�|d2kr�g|d2d9j
|�<n|d2d9j
|�j|�q?Wq1q1WxY|dD]M}||dkr	q�n||d.kr
|d.|dRk	r
x�|d.|D]�}t}x[|d1|D]K}|d||krwqWn||d|||d|krWt}t||�}i}x|D]}||||<q�WxO|D]G}t||t�r	||r	q�n||kr�||||<q�q�W|r�	d:j
|�|d2kr`	g|d2d:j
|�<n||d|||d|<|d2d:j
|�j|�q�	qWqWW|r<d;j
|�|d2kr�	g|d2d;j
|�<n|d2d;j
|�j|�q<q<Wn||d1kr�|d1|dRk	r�x|d1|D]�}t}||d.kr�
|d.|dRk	r�
x`|d.|D]M}|d||kr�
qy
n||d|||d|kry
t}qy
qy
Wn|r:
d9j
|�|d2krg|d2d9j
|�<n|d2d9j
|�j||d|�q:
q:
Wq�q�Wt}t	d&r�|d2r�|d1d*d<kr�|dr�d=|d2ks�d>|d2ks�d?|d2kr�|d.d"td,d-d"d@dA�kr�t}tdBdC|d.d"d0d"�q�q�ntdDdC|d.d"d0d"|d2�}t|t�rddE|krdt|d<d4j
|dE�|d<q�t|d<|d2|d|d.d"<n|dr�t	d&r�|d2|d|d.d"<n|d.d"|dkr�
|d|d.d"r�
dFj
|d.d"�|d<|dr�
|d1d*d<kr�
t	d&r�
|d.d"td,d-d"d@dA�krw
tdGdC|d.d"d0d"�n|r�
tdHdC|d.d"d0d"�q�
q�
n%i|d<dIj
|d.d"�|d<d#|d1kr?|d3|d1d#kr?|d	r�tdJdC|d.d"d0d"dK|d3�}t|t�rkdE|krkt|d<dLj
|d.d"�|d<q�dMj
|d.d"�|d<|d.d"|dkr�i|d|d.d"<n|d3|d|d.d"d#<q�tjdN|�q?qCdOj
|d.d"�|d<t|t�rCdE|krCd4j
|dE�|d<qCnt|d<d|kr�g}x5|dD])}d|kr�|d=n|j|�qiW||d<n|drCt	d&s�tdP|�nt}t|t�r
dE|kr
t|d<d4j
|dE�|d<qCt|d<||d|d"<dQj
|d"�|d<n|S(Su�
    Ensure vm is present on the computenode

    name : string
        hostname of vm
    vmconfig : dict
        options to set for the vm
    config : dict
        fine grain control over vm_present

    .. note::

        The following configuration properties can be toggled in the config parameter.
          - kvm_reboot (true)                - reboots of kvm zones if needed for a config update
          - auto_import (false)              - automatic importing of missing images
          - auto_lx_vars (true)              - copy kernel_version and docker:* variables from image
          - reprovision (false)              - reprovision on image_uuid changes
          - enforce_tags (true)              - false = add tags only, true =  add, update, and remove tags
          - enforce_routes (true)            - false = add tags only, true =  add, update, and remove routes
          - enforce_internal_metadata (true) - false = add metadata only, true =  add, update, and remove metadata
          - enforce_customer_metadata (true) - false = add metadata only, true =  add, update, and remove metadata

    .. note::

        State ID is used as hostname. Hostnames must be unique.

    .. note::

        If hostname is provided in vmconfig this will take president over the State ID.
        This allows multiple states to be applied to the same vm.

    .. note::

        The following instances should have a unique ID.
          - nic : mac
          - filesystem: target
          - disk : path or diskN for zvols

        e.g. disk0 will be the first disk added, disk1 the 2nd,...

    .. versionchanged:: 2019.2.0

        Added support for docker image uuids, added auto_lx_vars configuration, documented some missing configuration options.

    unameuchangesuresultuucommentu
kvm_rebootuauto_importuauto_lx_varsureprovisionuenforce_tagsuenforce_routesuenforce_internal_metadatauenforce_customer_metadatau#smartos.vm_present::%s::config - %sutagsucustomer_metadatauinternal_metadatauroutesu
collectionumacunicsupathudisksutargetufilesystemsuinstanceucreate_onlyu	docker:idudocker:restartcountu
docker:envu
docker:cmdudocker:entrypointu%smartos.vm_present::%s::vmconfig - %suhostnameu
image_uuiduimgadm.docker_to_uuiduimgadm.listutestu
imgadm.importufailed to import image {0}uimage {0} not installedubrandulxu
vmadm.listRfustateu	vmadm.gettkeyucurrentuchangedureprovision_uuidu{0}uenforce_{0}u#smartos.vm_present::enforce_%s = %sudockeruset_{0}u
remove_{0}u
update_{0}uadd_{0}ukvmu	add_disksuupdate_disksuremove_diskstsearchu
state=runningu
vmadm.stoptvmuvmadm.updateuErroruvm {0} updateduvmadm.rebootuvmadm.startuvm {0} is up to dateuvmadm.reprovisionRgu"vm {0} updated, reprovision failedu vm {0} updated and reprovisioneduismartos.vm_present::%s::reprovision - image_uuid in state does not match current, reprovision not alloweduvm {0} failed to be updateduvmadm.createuvm {0} createdN(R RRRtupdateR!R"R<RRZRR5RRIRNRXR0R6tdictRHRGRYtwarning(R[R9R#R]tstate_configt
vmconfig_typetvmconfig_docker_keeptvmconfig_docker_arraytdocker_uuidRaRRt	new_diskstdiskRtcdiskR3t
collectiontenforceRSR:t	state_cfgtadd_instancetcurrent_cfgREt
update_cfgtremove_instancetkvm_needs_starttrretR
((s7/usr/lib/python2.7/site-packages/salt/states/smartos.pyt
vm_present�s�.





		



 

#




.	.	"
"$$.*$	)$$

(($$$!'((



.)'"(
(



!	




 

cC@s*|j�}i|d6id6dd6dd6}|tddd�krgt|d<d	j|�|d<n�td
s�|r�tdd|d
ddt�ntd|d
d�|d<n
t|d<t|dt�r|djd�rt	|d<dj|�|d<n!dj|�|d<d|d|<|S(u�
    Ensure vm is absent on the computenode

    name : string
        hostname of vm
    archive : boolean
        toggle archiving of vm on removal

    .. note::

        State ID is used as hostname. Hostnames must be unique.

    unameuchangesuresultuucommentu
vmadm.listRfuhostnameuvm {0} is absentutestuvmadm.updateRoRmtarchive_on_deleteuvmadm.deleteuErrorufailed to delete vm {0}uvm {0} deletedN(
R RRRRRZR5RYRHR(R[tarchiveR]((s7/usr/lib/python2.7/site-packages/salt/states/smartos.pyt	vm_absentWs&



 
'
cC@s|j�}i|d6id6dd6dd6}|tdddd	d
�krmt|d<dj|�|d<n�tdr}tntd
|dd�|d<t|dt�r�|djd�r�t	|d<dj|�|d<n!d|d|<dj|�|d<|S(u�
    Ensure vm is in the running state on the computenode

    name : string
        hostname of vm

    .. note::

        State ID is used as hostname. Hostnames must be unique.

    unameuchangesuresultuucommentu
vmadm.listRfuhostnameRnu
state=runninguvm {0} already runningutestuvmadm.startRmuErrorufailed to start {0}urunninguvm {0} startedN(
R RRRRRZR5RYRHR(R[R]((s7/usr/lib/python2.7/site-packages/salt/states/smartos.pyt
vm_running�s


*'
cC@s|j�}i|d6id6dd6dd6}|tdddd	d
�krmt|d<dj|�|d<n�tdr}tntd
|dd�|d<t|dt�r�|djd�r�t	|d<dj|�|d<n!d|d|<dj|�|d<|S(u�
    Ensure vm is in the stopped state on the computenode

    name : string
        hostname of vm

    .. note::

        State ID is used as hostname. Hostnames must be unique.

    unameuchangesuresultuucommentu
vmadm.listRfuhostnameRnu
state=stoppeduvm {0} already stoppedutestu
vmadm.stopRmuErrorufailed to stop {0}ustoppeduvm {0} stoppedN(
R RRRRRZR5RYRHR(R[R]((s7/usr/lib/python2.7/site-packages/salt/states/smartos.pyt
vm_stopped�s


*'
((t__doc__t
__future__RRRtloggingRIRtsalt.utils.atomicfileRtsalt.utils.datatsalt.utils.filestsalt.extRt	getLoggert__name__R!RR	RRRR&R4R<RGRXR^R_RbRcReRiRlRR�RR�R�R�(((s7/usr/lib/python2.7/site-packages/salt/states/smartos.pyt<module>rs>				
					6	2	#&	$	9	>	Q��-	#

Zerion Mini Shell 1.0