text: begin_unit
  comment|'# Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory'
  nl|'\n'
  comment|'# All Rights Reserved'
  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'
  nl|'\n'
  name|'import'
  name|'os'
  newline|'\n'
  nl|'\n'
  name|'from'
  name|'oslo_concurrency'
  name|'import'
  name|'processutils'
  newline|'\n'
  name|'from'
  name|'oslo_log'
  name|'import'
  name|'log'
  name|'as'
  name|'logging'
  newline|'\n'
  name|'from'
  name|'oslo_utils'
  name|'import'
  name|'excutils'
  newline|'\n'
  nl|'\n'
  name|'from'
  name|'nova'
  op|'.'
  name|'i18n'
  name|'import'
  name|'_LE'
  newline|'\n'
  name|'from'
  name|'nova'
  op|'.'
  name|'virt'
  op|'.'
  name|'libvirt'
  name|'import'
  name|'utils'
  newline|'\n'
  nl|'\n'
  nl|'\n'
  DECL|variable|LOG
  name|'LOG'
  op|'='
  name|'logging'
  op|'.'
  name|'getLogger'
  op|'('
  name|'__name__'
  op|')'
  newline|'\n'
  nl|'\n'
  DECL|variable|_dmcrypt_suffix
  name|'_dmcrypt_suffix'
  op|'='
  string|"'-dmcrypt'"
  newline|'\n'
  nl|'\n'
  nl|'\n'
  DECL|function|volume_name
  name|'def'
  name|'volume_name'
  op|'('
  name|'base'
  op|')'
  op|':'
  newline|'\n'
  indent|'    '
  string|'"""Returns the suffixed dmcrypt volume name.\n\n    This is to avoid collisions with similarly named device mapper names for\n    LVM volumes\n    """'
  newline|'\n'
  name|'return'
  name|'base'
  op|'+'
  name|'_dmcrypt_suffix'
  newline|'\n'
  nl|'\n'
  nl|'\n'
  DECL|function|is_encrypted
  dedent|''
  name|'def'
  name|'is_encrypted'
  op|'('
  name|'path'
  op|')'
  op|':'
  newline|'\n'
  indent|'    '
  string|'"""Returns true if the path corresponds to an encrypted disk."""'
  newline|'\n'
  name|'if'
  name|'path'
  op|'.'
  name|'startswith'
  op|'('
  string|"'/dev/mapper'"
  op|')'
  op|':'
  newline|'\n'
  indent|'        '
  name|'return'
  name|'path'
  op|'.'
  name|'rpartition'
  op|'('
  string|"'/'"
  op|')'
  op|'['
  number|'2'
  op|']'
  op|'.'
  name|'endswith'
  op|'('
  name|'_dmcrypt_suffix'
  op|')'
  newline|'\n'
  dedent|''
  name|'else'
  op|':'
  newline|'\n'
  indent|'        '
  name|'return'
  name|'False'
  newline|'\n'
  nl|'\n'
  nl|'\n'
  DECL|function|create_volume
  dedent|''
  dedent|''
  name|'def'
  name|'create_volume'
  op|'('
  name|'target'
  op|','
  name|'device'
  op|','
  name|'cipher'
  op|','
  name|'key_size'
  op|','
  name|'key'
  op|')'
  op|':'
  newline|'\n'
  indent|'    '
  string|'"""Sets up a dmcrypt mapping\n\n    :param target: device mapper logical device name\n    :param device: underlying block device\n    :param cipher: encryption cipher string digestible by cryptsetup\n    :param key_size: encryption key size\n    :param key: encryption key as an array of unsigned bytes\n    """'
  newline|'\n'
  name|'cmd'
  op|'='
  op|'('
  string|"'cryptsetup'"
  op|','
  nl|'\n'
  string|"'create'"
  op|','
  nl|'\n'
  name|'target'
  op|','
  nl|'\n'
  name|'device'
  op|','
  nl|'\n'
  string|"'--cipher='"
  op|'+'
  name|'cipher'
  op|','
  nl|'\n'
  string|"'--key-size='"
  op|'+'
  name|'str'
  op|'('
  name|'key_size'
  op|')'
  op|','
  nl|'\n'
  string|"'--key-file=-'"
  op|')'
  newline|'\n'
  name|'key'
  op|'='
  string|"''"
  op|'.'
  name|'join'
  op|'('
  name|'map'
  op|'('
  name|'lambda'
  name|'byte'
  op|':'
  string|'"%02x"'
  op|'%'
  name|'byte'
  op|','
  name|'key'
  op|')'
  op|')'
  newline|'\n'
  name|'try'
  op|':'
  newline|'\n'
  indent|'        '
  name|'utils'
  op|'.'
  name|'execute'
  op|'('
  op|'*'
  name|'cmd'
  op|','
  name|'process_input'
  op|'='
  name|'key'
  op|','
  name|'run_as_root'
  op|'='
  name|'True'
  op|')'
  newline|'\n'
  dedent|''
  name|'except'
  name|'processutils'
  op|'.'
  name|'ProcessExecutionError'
  name|'as'
  name|'e'
  op|':'
  newline|'\n'
  indent|'        '
  name|'with'
  name|'excutils'
  op|'.'
  name|'save_and_reraise_exception'
  op|'('
  op|')'
  op|':'
  newline|'\n'
  indent|'            '
  name|'LOG'
  op|'.'
  name|'error'
  op|'('
  name|'_LE'
  op|'('
  string|'"Could not start encryption for disk %(device)s: "'
  nl|'\n'
  string|'"%(exception)s"'
  op|')'
  op|','
  op|'{'
  string|"'device'"
  op|':'
  name|'device'
  op|','
  string|"'exception'"
  op|':'
  name|'e'
  op|'}'
  op|')'
  newline|'\n'
  nl|'\n'
  nl|'\n'
  DECL|function|delete_volume
  dedent|''
  dedent|''
  dedent|''
  name|'def'
  name|'delete_volume'
  op|'('
  name|'target'
  op|')'
  op|':'
  newline|'\n'
  indent|'    '
  string|'"""Deletes a dmcrypt mapping\n\n    :param target: name of the mapped logical device\n    """'
  newline|'\n'
  name|'try'
  op|':'
  newline|'\n'
  indent|'        '
  name|'utils'
  op|'.'
  name|'execute'
  op|'('
  string|"'cryptsetup'"
  op|','
  string|"'remove'"
  op|','
  name|'target'
  op|','
  name|'run_as_root'
  op|'='
  name|'True'
  op|')'
  newline|'\n'
  dedent|''
  name|'except'
  name|'processutils'
  op|'.'
  name|'ProcessExecutionError'
  name|'as'
  name|'e'
  op|':'
  newline|'\n'
  comment|'# cryptsetup returns 4 when attempting to destroy a non-existent'
  nl|'\n'
  comment|'# dm-crypt device. It indicates that the device is invalid, which'
  nl|'\n'
  comment|'# means that the device is invalid (i.e., it has already been'
  nl|'\n'
  comment|'# destroyed).'
  nl|'\n'
  indent|'        '
  name|'if'
  name|'e'
  op|'.'
  name|'exit_code'
  op|'=='
  number|'4'
  op|':'
  newline|'\n'
  indent|'            '
  name|'LOG'
  op|'.'
  name|'debug'
  op|'('
  string|'"Ignoring exit code 4, volume already destroyed"'
  op|')'
  newline|'\n'
  dedent|''
  name|'else'
  op|':'
  newline|'\n'
  indent|'            '
  name|'with'
  name|'excutils'
  op|'.'
  name|'save_and_reraise_exception'
  op|'('
  op|')'
  op|':'
  newline|'\n'
  indent|'                '
  name|'LOG'
  op|'.'
  name|'error'
  op|'('
  name|'_LE'
  op|'('
  string|'"Could not disconnect encrypted volume "'
  nl|'\n'
  string|'"%(volume)s. If dm-crypt device is still active "'
  nl|'\n'
  string|'"it will have to be destroyed manually for "'
  nl|'\n'
  string|'"cleanup to succeed."'
  op|')'
  op|','
  op|'{'
  string|"'volume'"
  op|':'
  name|'target'
  op|'}'
  op|')'
  newline|'\n'
  nl|'\n'
  nl|'\n'
  DECL|function|list_volumes
  dedent|''
  dedent|''
  dedent|''
  dedent|''
  name|'def'
  name|'list_volumes'
  op|'('
  op|')'
  op|':'
  newline|'\n'
  indent|'    '
  string|'"""Function enumerates encrypted volumes."""'
  newline|'\n'
  name|'return'
  op|'['
  name|'dmdev'
  name|'for'
  name|'dmdev'
  name|'in'
  name|'os'
  op|'.'
  name|'listdir'
  op|'('
  string|"'/dev/mapper'"
  op|')'
  nl|'\n'
  name|'if'
  name|'dmdev'
  op|'.'
  name|'endswith'
  op|'('
  string|"'-dmcrypt'"
  op|')'
  op|']'
  newline|'\n'
  dedent|''
  endmarker|''
  end_unit
  