Coverage for nova/virt/libvirt/storage/dmcrypt.py: 94%
29 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-04-24 11:16 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-04-24 11:16 +0000
1# Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory
2# All Rights Reserved
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
16import os
18from oslo_concurrency import processutils
19from oslo_log import log as logging
20from oslo_utils import excutils
22import nova.privsep.libvirt
25LOG = logging.getLogger(__name__)
27_dmcrypt_suffix = '-dmcrypt'
30def volume_name(base):
31 """Returns the suffixed dmcrypt volume name.
33 This is to avoid collisions with similarly named device mapper names for
34 LVM volumes
35 """
36 return base + _dmcrypt_suffix
39def is_encrypted(path):
40 """Returns true if the path corresponds to an encrypted disk."""
41 if path.startswith('/dev/mapper'): 41 ↛ 44line 41 didn't jump to line 44 because the condition on line 41 was always true
42 return path.rpartition('/')[2].endswith(_dmcrypt_suffix)
43 else:
44 return False
47def create_volume(target, device, cipher, key_size, key):
48 """Sets up a dmcrypt mapping
50 :param target: device mapper logical device name
51 :param device: underlying block device
52 :param cipher: encryption cipher string digestible by cryptsetup
53 :param key_size: encryption key size
54 :param key: encoded encryption key bytestring
55 """
56 try:
57 nova.privsep.libvirt.dmcrypt_create_volume(
58 target, device, cipher, key_size, key)
59 except processutils.ProcessExecutionError as e:
60 with excutils.save_and_reraise_exception():
61 LOG.error("Could not start encryption for disk %(device)s: "
62 "%(exception)s", {'device': device, 'exception': e})
65def delete_volume(target):
66 """Deletes a dmcrypt mapping
68 :param target: name of the mapped logical device
69 """
70 try:
71 nova.privsep.libvirt.dmcrypt_delete_volume(target)
72 except processutils.ProcessExecutionError as e:
73 # cryptsetup returns 4 when attempting to destroy a non-existent
74 # dm-crypt device. It indicates that the device is invalid, which
75 # means that the device is invalid (i.e., it has already been
76 # destroyed).
77 if e.exit_code == 4:
78 LOG.debug("Ignoring exit code 4, volume already destroyed")
79 else:
80 with excutils.save_and_reraise_exception():
81 LOG.error("Could not disconnect encrypted volume "
82 "%(volume)s. If dm-crypt device is still active "
83 "it will have to be destroyed manually for "
84 "cleanup to succeed.", {'volume': target})
87def list_volumes():
88 """Function enumerates encrypted volumes."""
89 return [dmdev for dmdev in os.listdir('/dev/mapper')
90 if dmdev.endswith('-dmcrypt')]