begin_unit
comment|'# Copyright 2011 Red Hat, Inc.'
nl|'\n'
comment|'#'
nl|'\n'
comment|'# Licensed under the Apache License, Version 2.0 (the "License"); you may'
nl|'\n'
comment|'# not use this file except in compliance with the License. You may obtain'
nl|'\n'
comment|'# a copy of the License at'
nl|'\n'
comment|'#'
nl|'\n'
comment|'# http://www.apache.org/licenses/LICENSE-2.0'
nl|'\n'
comment|'#'
nl|'\n'
comment|'# Unless required by applicable law or agreed to in writing, software'
nl|'\n'
comment|'# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT'
nl|'\n'
comment|'# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the'
nl|'\n'
comment|'# License for the specific language governing permissions and limitations'
nl|'\n'
comment|'# under the License.'
nl|'\n'
string|'"""Support for mounting virtual image files."""'
newline|'\n'
nl|'\n'
name|'import'
name|'os'
newline|'\n'
name|'import'
name|'time'
newline|'\n'
nl|'\n'
name|'from'
name|'oslo_log'
name|'import'
name|'log'
name|'as'
name|'logging'
newline|'\n'
name|'from'
name|'oslo_service'
name|'import'
name|'loopingcall'
newline|'\n'
name|'from'
name|'oslo_utils'
name|'import'
name|'importutils'
newline|'\n'
nl|'\n'
name|'from'
name|'nova'
name|'import'
name|'exception'
newline|'\n'
name|'from'
name|'nova'
op|'.'
name|'i18n'
name|'import'
name|'_'
op|','
name|'_LI'
op|','
name|'_LW'
newline|'\n'
name|'from'
name|'nova'
name|'import'
name|'utils'
newline|'\n'
name|'from'
name|'nova'
op|'.'
name|'virt'
op|'.'
name|'image'
name|'import'
name|'model'
name|'as'
name|'imgmodel'
newline|'\n'
nl|'\n'
DECL|variable|LOG
name|'LOG'
op|'='
name|'logging'
op|'.'
name|'getLogger'
op|'('
name|'__name__'
op|')'
newline|'\n'
nl|'\n'
DECL|variable|MAX_DEVICE_WAIT
name|'MAX_DEVICE_WAIT'
op|'='
number|'30'
newline|'\n'
DECL|variable|MAX_FILE_CHECKS
name|'MAX_FILE_CHECKS'
op|'='
number|'6'
newline|'\n'
DECL|variable|FILE_CHECK_INTERVAL
name|'FILE_CHECK_INTERVAL'
op|'='
number|'0.25'
newline|'\n'
nl|'\n'
nl|'\n'
DECL|class|Mount
name|'class'
name|'Mount'
op|'('
name|'object'
op|')'
op|':'
newline|'\n'
indent|'    '
string|'"""Standard mounting operations, that can be overridden by subclasses.\n\n    The basic device operations provided are get, map and mount,\n    to be called in that order.\n    """'
newline|'\n'
nl|'\n'
DECL|variable|mode
name|'mode'
op|'='
name|'None'
comment|'# to be overridden in subclasses'
newline|'\n'
nl|'\n'
op|'@'
name|'staticmethod'
newline|'\n'
DECL|member|instance_for_format
name|'def'
name|'instance_for_format'
op|'('
name|'image'
op|','
name|'mountdir'
op|','
name|'partition'
op|')'
op|':'
newline|'\n'
indent|'        '
string|'"""Get a Mount instance for the image type\n\n        :param image: instance of nova.virt.image.model.Image\n        :param mountdir: path to mount the image at\n        :param partition: partition number to mount\n        """'
newline|'\n'
name|'LOG'
op|'.'
name|'debug'
op|'('
string|'"Instance for format image=%(image)s "'
nl|'\n'
string|'"mountdir=%(mountdir)s partition=%(partition)s"'
op|','
nl|'\n'
op|'{'
string|"'image'"
op|':'
name|'image'
op|','
string|"'mountdir'"
op|':'
name|'mountdir'
op|','
nl|'\n'
string|"'partition'"
op|':'
name|'partition'
op|'}'
op|')'
newline|'\n'
nl|'\n'
name|'if'
name|'isinstance'
op|'('
name|'image'
op|','
name|'imgmodel'
op|'.'
name|'LocalFileImage'
op|')'
op|':'
newline|'\n'
indent|'            '
name|'if'
name|'image'
op|'.'
name|'format'
op|'=='
name|'imgmodel'
op|'.'
name|'FORMAT_RAW'
op|':'
newline|'\n'
indent|'                '
name|'LOG'
op|'.'
name|'debug'
op|'('
string|'"Using LoopMount"'
op|')'
newline|'\n'
name|'return'
name|'importutils'
op|'.'
name|'import_object'
op|'('
nl|'\n'
string|'"nova.virt.disk.mount.loop.LoopMount"'
op|','
nl|'\n'
name|'image'
op|','
name|'mountdir'
op|','
name|'partition'
op|')'
newline|'\n'
dedent|''
name|'else'
op|':'
newline|'\n'
indent|'                '
name|'LOG'
op|'.'
name|'debug'
op|'('
string|'"Using NbdMount"'
op|')'
newline|'\n'
name|'return'
name|'importutils'
op|'.'
name|'import_object'
op|'('
nl|'\n'
string|'"nova.virt.disk.mount.nbd.NbdMount"'
op|','
nl|'\n'
name|'image'
op|','
name|'mountdir'
op|','
name|'partition'
op|')'
newline|'\n'
dedent|''
dedent|''
name|'elif'
name|'isinstance'
op|'('
name|'image'
op|','
name|'imgmodel'
op|'.'
name|'LocalBlockImage'
op|')'
op|':'
newline|'\n'
indent|'            '
name|'LOG'
op|'.'
name|'debug'
op|'('
string|'"Using BlockMount"'
op|')'
newline|'\n'
name|'return'
name|'importutils'
op|'.'
name|'import_object'
op|'('
nl|'\n'
string|'"nova.virt.disk.mount.block.BlockMount"'
op|','
nl|'\n'
name|'image'
op|','
name|'mountdir'
op|','
name|'partition'
op|')'
newline|'\n'
dedent|''
name|'else'
op|':'
newline|'\n'
comment|'# TODO(berrange) We could mount RBDImage directly'
nl|'\n'
comment|'# using kernel RBD block dev support.'
nl|'\n'
comment|'#'
nl|'\n'
comment|'# This is left as an enhancement for future'
nl|'\n'
comment|'# motivated developers todo, since raising'
nl|'\n'
comment|'# an exception is on par with what this'
nl|'\n'
comment|'# code did historically'
nl|'\n'
indent|'            '
name|'raise'
name|'exception'
op|'.'
name|'UnsupportedImageModel'
op|'('
nl|'\n'
name|'image'
op|'.'
name|'__class__'
op|'.'
name|'__name__'
op|')'
newline|'\n'
nl|'\n'
dedent|''
dedent|''
op|'@'
name|'staticmethod'
newline|'\n'
DECL|member|instance_for_device
name|'def'
name|'instance_for_device'
op|'('
name|'image'
op|','
name|'mountdir'
op|','
name|'partition'
op|','
name|'device'
op|')'
op|':'
newline|'\n'
indent|'        '
string|'"""Get a Mount instance for the device type\n\n        :param image: instance of nova.virt.image.model.Image\n        :param mountdir: path to mount the image at\n        :param partition: partition number to mount\n        :param device: mounted device path\n        """'
newline|'\n'
nl|'\n'
name|'LOG'
op|'.'
name|'debug'
op|'('
string|'"Instance for device image=%(image)s "'
nl|'\n'
string|'"mountdir=%(mountdir)s partition=%(partition)s "'
nl|'\n'
string|'"device=%(device)s"'
op|','
nl|'\n'
op|'{'
string|"'image'"
op|':'
name|'image'
op|','
string|"'mountdir'"
op|':'
name|'mountdir'
op|','
nl|'\n'
string|"'partition'"
op|':'
name|'partition'
op|','
string|"'device'"
op|':'
name|'device'
op|'}'
op|')'
newline|'\n'
nl|'\n'
name|'if'
string|'"loop"'
name|'in'
name|'device'
op|':'
newline|'\n'
indent|'            '
name|'LOG'
op|'.'
name|'debug'
op|'('
string|'"Using LoopMount"'
op|')'
newline|'\n'
name|'return'
name|'importutils'
op|'.'
name|'import_object'
op|'('
nl|'\n'
string|'"nova.virt.disk.mount.loop.LoopMount"'
op|','
nl|'\n'
name|'image'
op|','
name|'mountdir'
op|','
name|'partition'
op|','
name|'device'
op|')'
newline|'\n'
dedent|''
name|'elif'
string|'"nbd"'
name|'in'
name|'device'
op|':'
newline|'\n'
indent|'            '
name|'LOG'
op|'.'
name|'debug'
op|'('
string|'"Using NbdMount"'
op|')'
newline|'\n'
name|'return'
name|'importutils'
op|'.'
name|'import_object'
op|'('
nl|'\n'
string|'"nova.virt.disk.mount.nbd.NbdMount"'
op|','
nl|'\n'
name|'image'
op|','
name|'mountdir'
op|','
name|'partition'
op|','
name|'device'
op|')'
newline|'\n'
dedent|''
name|'else'
op|':'
newline|'\n'
indent|'            '
name|'LOG'
op|'.'
name|'debug'
op|'('
string|'"Using BlockMount"'
op|')'
newline|'\n'
name|'return'
name|'importutils'
op|'.'
name|'import_object'
op|'('
nl|'\n'
string|'"nova.virt.disk.mount.block.BlockMount"'
op|','
nl|'\n'
name|'image'
op|','
name|'mountdir'
op|','
name|'partition'
op|','
name|'device'
op|')'
newline|'\n'
nl|'\n'
DECL|member|__init__
dedent|''
dedent|''
name|'def'
name|'__init__'
op|'('
name|'self'
op|','
name|'image'
op|','
name|'mount_dir'
op|','
name|'partition'
op|'='
name|'None'
op|','
name|'device'
op|'='
name|'None'
op|')'
op|':'
newline|'\n'
indent|'        '
string|'"""Create a new Mount instance\n\n        :param image: instance of nova.virt.image.model.Image\n        :param mount_dir: path to mount the image at\n        :param partition: partition number to mount\n        :param device: mounted device path\n        """'
newline|'\n'
nl|'\n'
comment|'# Input'
nl|'\n'
name|'self'
op|'.'
name|'image'
op|'='
name|'image'
newline|'\n'
name|'self'
op|'.'
name|'partition'
op|'='
name|'partition'
newline|'\n'
name|'self'
op|'.'
name|'mount_dir'
op|'='
name|'mount_dir'
newline|'\n'
nl|'\n'
comment|'# Output'
nl|'\n'
name|'self'
op|'.'
name|'error'
op|'='
string|'""'
newline|'\n'
nl|'\n'
comment|'# Internal'
nl|'\n'
name|'self'
op|'.'
name|'linked'
op|'='
name|'self'
op|'.'
name|'mapped'
op|'='
name|'self'
op|'.'
name|'mounted'
op|'='
name|'self'
op|'.'
name|'automapped'
op|'='
name|'False'
newline|'\n'
name|'self'
op|'.'
name|'device'
op|'='
name|'self'
op|'.'
name|'mapped_device'
op|'='
name|'device'
newline|'\n'
nl|'\n'
comment|'# Reset to mounted dir if possible'
nl|'\n'
name|'self'
op|'.'
name|'reset_dev'
op|'('
op|')'
newline|'\n'
nl|'\n'
DECL|member|reset_dev
dedent|''
name|'def'
name|'reset_dev'
op|'('
name|'self'
op|')'
op|':'
newline|'\n'
indent|'        '
string|'"""Reset device paths to allow unmounting."""'
newline|'\n'
name|'if'
name|'not'
name|'self'
op|'.'
name|'device'
op|':'
newline|'\n'
indent|'            '
name|'return'
newline|'\n'
nl|'\n'
dedent|''
name|'self'
op|'.'
name|'linked'
op|'='
name|'self'
op|'.'
name|'mapped'
op|'='
name|'self'
op|'.'
name|'mounted'
op|'='
name|'True'
newline|'\n'
nl|'\n'
name|'device'
op|'='
name|'self'
op|'.'
name|'device'
newline|'\n'
name|'if'
name|'os'
op|'.'
name|'path'
op|'.'
name|'isabs'
op|'('
name|'device'
op|')'
name|'and'
name|'os'
op|'.'
name|'path'
op|'.'
name|'exists'
op|'('
name|'device'
op|')'
op|':'
newline|'\n'
indent|'            '
name|'if'
name|'device'
op|'.'
name|'startswith'
op|'('
string|"'/dev/mapper/'"
op|')'
op|':'
newline|'\n'
indent|'                '
name|'device'
op|'='
name|'os'
op|'.'
name|'path'
op|'.'
name|'basename'
op|'('
name|'device'
op|')'
newline|'\n'
name|'if'
string|"'p'"
name|'in'
name|'device'
op|':'
newline|'\n'
indent|'                    '
name|'device'
op|','
name|'self'
op|'.'
name|'partition'
op|'='
name|'device'
op|'.'
name|'rsplit'
op|'('
string|"'p'"
op|','
number|'1'
op|')'
newline|'\n'
name|'self'
op|'.'
name|'device'
op|'='
name|'os'
op|'.'
name|'path'
op|'.'
name|'join'
op|'('
string|"'/dev'"
op|','
name|'device'
op|')'
newline|'\n'
nl|'\n'
DECL|member|get_dev
dedent|''
dedent|''
dedent|''
dedent|''
name|'def'
name|'get_dev'
op|'('
name|'self'
op|')'
op|':'
newline|'\n'
indent|'        '
string|'"""Make the image available as a block device in the file system."""'
newline|'\n'
name|'self'
op|'.'
name|'device'
op|'='
name|'None'
newline|'\n'
name|'self'
op|'.'
name|'linked'
op|'='
name|'True'
newline|'\n'
name|'return'
name|'True'
newline|'\n'
nl|'\n'
DECL|member|_get_dev_retry_helper
dedent|''
name|'def'
name|'_get_dev_retry_helper'
op|'('
name|'self'
op|')'
op|':'
newline|'\n'
indent|'        '
string|'"""Some implementations need to retry their get_dev."""'
newline|'\n'
comment|'# NOTE(mikal): This method helps implement retries. The implementation'
nl|'\n'
comment|'# simply calls _get_dev_retry_helper from their get_dev, and implements'
nl|'\n'
comment|'# _inner_get_dev with their device acquisition logic. The NBD'
nl|'\n'
comment|'# implementation has an example.'
nl|'\n'
name|'start_time'
op|'='
name|'time'
op|'.'
name|'time'
op|'('
op|')'
newline|'\n'
name|'device'
op|'='
name|'self'
op|'.'
name|'_inner_get_dev'
op|'('
op|')'
newline|'\n'
name|'while'
name|'not'
name|'device'
op|':'
newline|'\n'
indent|'            '
name|'LOG'
op|'.'
name|'info'
op|'('
name|'_LI'
op|'('
string|"'Device allocation failed. Will retry in 2 seconds.'"
op|')'
op|')'
newline|'\n'
name|'time'
op|'.'
name|'sleep'
op|'('
number|'2'
op|')'
newline|'\n'
name|'if'
name|'time'
op|'.'
name|'time'
op|'('
op|')'
op|'-'
name|'start_time'
op|'>'
name|'MAX_DEVICE_WAIT'
op|':'
newline|'\n'
indent|'                '
name|'LOG'
op|'.'
name|'warning'
op|'('
name|'_LW'
op|'('
string|"'Device allocation failed after repeated '"
nl|'\n'
string|"'retries.'"
op|')'
op|')'
newline|'\n'
name|'return'
name|'False'
newline|'\n'
dedent|''
name|'device'
op|'='
name|'self'
op|'.'
name|'_inner_get_dev'
op|'('
op|')'
newline|'\n'
dedent|''
name|'return'
name|'True'
newline|'\n'
nl|'\n'
DECL|member|_inner_get_dev
dedent|''
name|'def'
name|'_inner_get_dev'
op|'('
name|'self'
op|')'
op|':'
newline|'\n'
indent|'        '
name|'raise'
name|'NotImplementedError'
op|'('
op|')'
newline|'\n'
nl|'\n'
DECL|member|unget_dev
dedent|''
name|'def'
name|'unget_dev'
op|'('
name|'self'
op|')'
op|':'
newline|'\n'
indent|'        '
string|'"""Release the block device from the file system namespace."""'
newline|'\n'
name|'self'
op|'.'
name|'linked'
op|'='
name|'False'
newline|'\n'
nl|'\n'
DECL|member|map_dev
dedent|''
name|'def'
name|'map_dev'
op|'('
name|'self'
op|')'
op|':'
newline|'\n'
indent|'        '
string|'"""Map partitions of the device to the file system namespace."""'
newline|'\n'
name|'assert'
op|'('
name|'os'
op|'.'
name|'path'
op|'.'
name|'exists'
op|'('
name|'self'
op|'.'
name|'device'
op|')'
op|')'
newline|'\n'
name|'LOG'
op|'.'
name|'debug'
op|'('
string|'"Map dev %s"'
op|','
name|'self'
op|'.'
name|'device'
op|')'
newline|'\n'
name|'automapped_path'
op|'='
string|"'/dev/%sp%s'"
op|'%'
op|'('
name|'os'
op|'.'
name|'path'
op|'.'
name|'basename'
op|'('
name|'self'
op|'.'
name|'device'
op|')'
op|','
nl|'\n'
name|'self'
op|'.'
name|'partition'
op|')'
newline|'\n'
nl|'\n'
name|'if'
name|'self'
op|'.'
name|'partition'
op|'=='
op|'-'
number|'1'
op|':'
newline|'\n'
indent|'            '
name|'self'
op|'.'
name|'error'
op|'='
name|'_'
op|'('
string|"'partition search unsupported with %s'"
op|')'
op|'%'
name|'self'
op|'.'
name|'mode'
newline|'\n'
dedent|''
name|'elif'
name|'self'
op|'.'
name|'partition'
name|'and'
name|'not'
name|'os'
op|'.'
name|'path'
op|'.'
name|'exists'
op|'('
name|'automapped_path'
op|')'
op|':'
newline|'\n'
indent|'            '
name|'map_path'
op|'='
string|"'/dev/mapper/%sp%s'"
op|'%'
op|'('
name|'os'
op|'.'
name|'path'
op|'.'
name|'basename'
op|'('
name|'self'
op|'.'
name|'device'
op|')'
op|','
nl|'\n'
name|'self'
op|'.'
name|'partition'
op|')'
newline|'\n'
name|'assert'
op|'('
name|'not'
name|'os'
op|'.'
name|'path'
op|'.'
name|'exists'
op|'('
name|'map_path'
op|')'
op|')'
newline|'\n'
nl|'\n'
comment|'# Note kpartx can output warnings to stderr and succeed'
nl|'\n'
comment|'# Also it can output failures to stderr and "succeed"'
nl|'\n'
comment|'# So we just go on the existence of the mapped device'
nl|'\n'
name|'_out'
op|','
name|'err'
op|'='
name|'utils'
op|'.'
name|'trycmd'
op|'('
string|"'kpartx'"
op|','
string|"'-a'"
op|','
name|'self'
op|'.'
name|'device'
op|','
nl|'\n'
name|'run_as_root'
op|'='
name|'True'
op|','
name|'discard_warnings'
op|'='
name|'True'
op|')'
newline|'\n'
nl|'\n'
op|'@'
name|'loopingcall'
op|'.'
name|'RetryDecorator'
op|'('
nl|'\n'
name|'max_retry_count'
op|'='
name|'MAX_FILE_CHECKS'
op|'-'
number|'1'
op|','
nl|'\n'
name|'max_sleep_time'
op|'='
name|'FILE_CHECK_INTERVAL'
op|','
nl|'\n'
name|'exceptions'
op|'='
name|'IOError'
op|')'
newline|'\n'
DECL|function|recheck_path
name|'def'
name|'recheck_path'
op|'('
name|'map_path'
op|')'
op|':'
newline|'\n'
indent|'                '
name|'if'
name|'not'
name|'os'
op|'.'
name|'path'
op|'.'
name|'exists'
op|'('
name|'map_path'
op|')'
op|':'
newline|'\n'
indent|'                    '
name|'raise'
name|'IOError'
op|'('
op|')'
newline|'\n'
nl|'\n'
comment|'# Note kpartx does nothing when presented with a raw image,'
nl|'\n'
comment|'# so given we only use it when we expect a partitioned image, fail'
nl|'\n'
dedent|''
dedent|''
name|'try'
op|':'
newline|'\n'
indent|'                '
name|'recheck_path'
op|'('
name|'map_path'
op|')'
newline|'\n'
name|'self'
op|'.'
name|'mapped_device'
op|'='
name|'map_path'
newline|'\n'
name|'self'
op|'.'
name|'mapped'
op|'='
name|'True'
newline|'\n'
dedent|''
name|'except'
name|'IOError'
op|':'
newline|'\n'
indent|'                '
name|'if'
name|'not'
name|'err'
op|':'
newline|'\n'
indent|'                    '
name|'err'
op|'='
name|'_'
op|'('
string|"'partition %s not found'"
op|')'
op|'%'
name|'self'
op|'.'
name|'partition'
newline|'\n'
dedent|''
name|'self'
op|'.'
name|'error'
op|'='
name|'_'
op|'('
string|"'Failed to map partitions: %s'"
op|')'
op|'%'
name|'err'
newline|'\n'
dedent|''
dedent|''
name|'elif'
name|'self'
op|'.'
name|'partition'
name|'and'
name|'os'
op|'.'
name|'path'
op|'.'
name|'exists'
op|'('
name|'automapped_path'
op|')'
op|':'
newline|'\n'
comment|"# Note auto mapping can be enabled with the 'max_part' option"
nl|'\n'
comment|'# to the nbd or loop kernel modules. Beware of possible races'
nl|'\n'
comment|'# in the partition scanning for _loop_ devices though'
nl|'\n'
comment|'# (details in bug 1024586), which are currently uncatered for.'
nl|'\n'
indent|'            '
name|'self'
op|'.'
name|'mapped_device'
op|'='
name|'automapped_path'
newline|'\n'
name|'self'
op|'.'
name|'mapped'
op|'='
name|'True'
newline|'\n'
name|'self'
op|'.'
name|'automapped'
op|'='
name|'True'
newline|'\n'
dedent|''
name|'else'
op|':'
newline|'\n'
indent|'            '
name|'self'
op|'.'
name|'mapped_device'
op|'='
name|'self'
op|'.'
name|'device'
newline|'\n'
name|'self'
op|'.'
name|'mapped'
op|'='
name|'True'
newline|'\n'
nl|'\n'
dedent|''
name|'return'
name|'self'
op|'.'
name|'mapped'
newline|'\n'
nl|'\n'
DECL|member|unmap_dev
dedent|''
name|'def'
name|'unmap_dev'
op|'('
name|'self'
op|')'
op|':'
newline|'\n'
indent|'        '
string|'"""Remove partitions of the device from the file system namespace."""'
newline|'\n'
name|'if'
name|'not'
name|'self'
op|'.'
name|'mapped'
op|':'
newline|'\n'
indent|'            '
name|'return'
newline|'\n'
dedent|''
name|'LOG'
op|'.'
name|'debug'
op|'('
string|'"Unmap dev %s"'
op|','
name|'self'
op|'.'
name|'device'
op|')'
newline|'\n'
name|'if'
name|'self'
op|'.'
name|'partition'
name|'and'
name|'not'
name|'self'
op|'.'
name|'automapped'
op|':'
newline|'\n'
indent|'            '
name|'utils'
op|'.'
name|'execute'
op|'('
string|"'kpartx'"
op|','
string|"'-d'"
op|','
name|'self'
op|'.'
name|'device'
op|','
name|'run_as_root'
op|'='
name|'True'
op|')'
newline|'\n'
dedent|''
name|'self'
op|'.'
name|'mapped'
op|'='
name|'False'
newline|'\n'
name|'self'
op|'.'
name|'automapped'
op|'='
name|'False'
newline|'\n'
nl|'\n'
DECL|member|mnt_dev
dedent|''
name|'def'
name|'mnt_dev'
op|'('
name|'self'
op|')'
op|':'
newline|'\n'
indent|'        '
string|'"""Mount the device into the file system."""'
newline|'\n'
name|'LOG'
op|'.'
name|'debug'
op|'('
string|'"Mount %(dev)s on %(dir)s"'
op|','
nl|'\n'
op|'{'
string|"'dev'"
op|':'
name|'self'
op|'.'
name|'mapped_device'
op|','
string|"'dir'"
op|':'
name|'self'
op|'.'
name|'mount_dir'
op|'}'
op|')'
newline|'\n'
name|'_out'
op|','
name|'err'
op|'='
name|'utils'
op|'.'
name|'trycmd'
op|'('
string|"'mount'"
op|','
name|'self'
op|'.'
name|'mapped_device'
op|','
name|'self'
op|'.'
name|'mount_dir'
op|','
nl|'\n'
name|'discard_warnings'
op|'='
name|'True'
op|','
name|'run_as_root'
op|'='
name|'True'
op|')'
newline|'\n'
name|'if'
name|'err'
op|':'
newline|'\n'
indent|'            '
name|'self'
op|'.'
name|'error'
op|'='
name|'_'
op|'('
string|"'Failed to mount filesystem: %s'"
op|')'
op|'%'
name|'err'
newline|'\n'
name|'LOG'
op|'.'
name|'debug'
op|'('
name|'self'
op|'.'
name|'error'
op|')'
newline|'\n'
name|'return'
name|'False'
newline|'\n'
nl|'\n'
dedent|''
name|'self'
op|'.'
name|'mounted'
op|'='
name|'True'
newline|'\n'
name|'return'
name|'True'
newline|'\n'
nl|'\n'
DECL|member|unmnt_dev
dedent|''
name|'def'
name|'unmnt_dev'
op|'('
name|'self'
op|')'
op|':'
newline|'\n'
indent|'        '
string|'"""Unmount the device from the file system."""'
newline|'\n'
name|'if'
name|'not'
name|'self'
op|'.'
name|'mounted'
op|':'
newline|'\n'
indent|'            '
name|'return'
newline|'\n'
dedent|''
name|'self'
op|'.'
name|'flush_dev'
op|'('
op|')'
newline|'\n'
name|'LOG'
op|'.'
name|'debug'
op|'('
string|'"Umount %s"'
op|','
name|'self'
op|'.'
name|'mapped_device'
op|')'
newline|'\n'
name|'utils'
op|'.'
name|'execute'
op|'('
string|"'umount'"
op|','
name|'self'
op|'.'
name|'mapped_device'
op|','
name|'run_as_root'
op|'='
name|'True'
op|')'
newline|'\n'
name|'self'
op|'.'
name|'mounted'
op|'='
name|'False'
newline|'\n'
nl|'\n'
DECL|member|flush_dev
dedent|''
name|'def'
name|'flush_dev'
op|'('
name|'self'
op|')'
op|':'
newline|'\n'
indent|'        '
name|'pass'
newline|'\n'
nl|'\n'
DECL|member|do_mount
dedent|''
name|'def'
name|'do_mount'
op|'('
name|'self'
op|')'
op|':'
newline|'\n'
indent|'        '
string|'"""Call the get, map and mnt operations."""'
newline|'\n'
name|'status'
op|'='
name|'False'
newline|'\n'
name|'try'
op|':'
newline|'\n'
indent|'            '
name|'status'
op|'='
name|'self'
op|'.'
name|'get_dev'
op|'('
op|')'
name|'and'
name|'self'
op|'.'
name|'map_dev'
op|'('
op|')'
name|'and'
name|'self'
op|'.'
name|'mnt_dev'
op|'('
op|')'
newline|'\n'
dedent|''
name|'finally'
op|':'
newline|'\n'
indent|'            '
name|'if'
name|'not'
name|'status'
op|':'
newline|'\n'
indent|'                '
name|'LOG'
op|'.'
name|'debug'
op|'('
string|'"Fail to mount, tearing back down"'
op|')'
newline|'\n'
name|'self'
op|'.'
name|'do_teardown'
op|'('
op|')'
newline|'\n'
dedent|''
dedent|''
name|'return'
name|'status'
newline|'\n'
nl|'\n'
DECL|member|do_umount
dedent|''
name|'def'
name|'do_umount'
op|'('
name|'self'
op|')'
op|':'
newline|'\n'
indent|'        '
string|'"""Call the unmnt operation."""'
newline|'\n'
name|'if'
name|'self'
op|'.'
name|'mounted'
op|':'
newline|'\n'
indent|'            '
name|'self'
op|'.'
name|'unmnt_dev'
op|'('
op|')'
newline|'\n'
nl|'\n'
DECL|member|do_teardown
dedent|''
dedent|''
name|'def'
name|'do_teardown'
op|'('
name|'self'
op|')'
op|':'
newline|'\n'
indent|'        '
string|'"""Call the umnt, unmap, and unget operations."""'
newline|'\n'
name|'if'
name|'self'
op|'.'
name|'mounted'
op|':'
newline|'\n'
indent|'            '
name|'self'
op|'.'
name|'unmnt_dev'
op|'('
op|')'
newline|'\n'
dedent|''
name|'if'
name|'self'
op|'.'
name|'mapped'
op|':'
newline|'\n'
indent|'            '
name|'self'
op|'.'
name|'unmap_dev'
op|'('
op|')'
newline|'\n'
dedent|''
name|'if'
name|'self'
op|'.'
name|'linked'
op|':'
newline|'\n'
indent|'            '
name|'self'
op|'.'
name|'unget_dev'
op|'('
op|')'
newline|'\n'
dedent|''
dedent|''
dedent|''
endmarker|''
end_unit
