Use the json format output of qemu-img info
Support for the human format by oslo_utils.imageutils.QemuImgInfo was deprecated since oslo.utils 4.9.1 [1]. This change replaces the human format with the json format which will be used by default. [1] 73eb0673f627aad382e08a816191b637af436465 Backport note: The json format is preferable because it allows access to format specific details (since oslo.utils 4.1.0). These details are not present when the default 'human' format is used. See change I133da07a5a9628b8a9 for details. Closes-Bug: #1940540 Change-Id: Ia0353204abf849467106ee08982d1271de23101a (cherry picked from commitc0d2e7ebd8
) (cherry picked from commit11b0f97a01
) (cherry picked from commit4cef5c0c42
) (cherry picked from commit9810c05e74
) (cherry picked from commit60a5de1f6d
) (cherry picked from commit6a1260ea80
) Conflicts: cinder/tests/unit/volume/drivers/test_nfs.py - patch changed QEMU_IMG_INFO_OUT5 test data which isn't present in ussuri cinder/volume/flows/manager/create_volume.py - parent patch of6a1260ea8
imported netutils, but that's not used in this file in ussuri (cherry picked from commit6df27994d9
)
This commit is contained in:
parent
14c2db209b
commit
9f9194d804
|
@ -108,7 +108,7 @@ def from_qemu_img_disk_format(disk_format):
|
||||||
|
|
||||||
def qemu_img_info(path, run_as_root=True, force_share=False):
|
def qemu_img_info(path, run_as_root=True, force_share=False):
|
||||||
"""Return an object containing the parsed output from qemu-img info."""
|
"""Return an object containing the parsed output from qemu-img info."""
|
||||||
cmd = ['env', 'LC_ALL=C', 'qemu-img', 'info']
|
cmd = ['env', 'LC_ALL=C', 'qemu-img', 'info', '--output=json']
|
||||||
if force_share:
|
if force_share:
|
||||||
if qemu_img_supports_force_share():
|
if qemu_img_supports_force_share():
|
||||||
cmd.append('--force-share')
|
cmd.append('--force-share')
|
||||||
|
@ -122,7 +122,7 @@ def qemu_img_info(path, run_as_root=True, force_share=False):
|
||||||
cmd = cmd[2:]
|
cmd = cmd[2:]
|
||||||
out, _err = utils.execute(*cmd, run_as_root=run_as_root,
|
out, _err = utils.execute(*cmd, run_as_root=run_as_root,
|
||||||
prlimit=QEMU_IMG_LIMITS)
|
prlimit=QEMU_IMG_LIMITS)
|
||||||
info = imageutils.QemuImgInfo(out)
|
info = imageutils.QemuImgInfo(out, format='json')
|
||||||
|
|
||||||
# From Cinder's point of view, any 'luks' formatted images
|
# From Cinder's point of view, any 'luks' formatted images
|
||||||
# should be treated as 'raw'.
|
# should be treated as 'raw'.
|
||||||
|
|
|
@ -41,7 +41,8 @@ class TestQemuImgInfo(test.TestCase):
|
||||||
|
|
||||||
output = image_utils.qemu_img_info(test_path)
|
output = image_utils.qemu_img_info(test_path)
|
||||||
mock_exec.assert_called_once_with('env', 'LC_ALL=C', 'qemu-img',
|
mock_exec.assert_called_once_with('env', 'LC_ALL=C', 'qemu-img',
|
||||||
'info', test_path, run_as_root=True,
|
'info', '--output=json', test_path,
|
||||||
|
run_as_root=True,
|
||||||
prlimit=image_utils.QEMU_IMG_LIMITS)
|
prlimit=image_utils.QEMU_IMG_LIMITS)
|
||||||
self.assertEqual(mock_info.return_value, output)
|
self.assertEqual(mock_info.return_value, output)
|
||||||
|
|
||||||
|
@ -58,7 +59,8 @@ class TestQemuImgInfo(test.TestCase):
|
||||||
force_share=False,
|
force_share=False,
|
||||||
run_as_root=False)
|
run_as_root=False)
|
||||||
mock_exec.assert_called_once_with('env', 'LC_ALL=C', 'qemu-img',
|
mock_exec.assert_called_once_with('env', 'LC_ALL=C', 'qemu-img',
|
||||||
'info', test_path, run_as_root=False,
|
'info', '--output=json', test_path,
|
||||||
|
run_as_root=False,
|
||||||
prlimit=image_utils.QEMU_IMG_LIMITS)
|
prlimit=image_utils.QEMU_IMG_LIMITS)
|
||||||
self.assertEqual(mock_info.return_value, output)
|
self.assertEqual(mock_info.return_value, output)
|
||||||
|
|
||||||
|
@ -73,8 +75,8 @@ class TestQemuImgInfo(test.TestCase):
|
||||||
mock_os.name = 'nt'
|
mock_os.name = 'nt'
|
||||||
|
|
||||||
output = image_utils.qemu_img_info(test_path)
|
output = image_utils.qemu_img_info(test_path)
|
||||||
mock_exec.assert_called_once_with('qemu-img', 'info', test_path,
|
mock_exec.assert_called_once_with('qemu-img', 'info', '--output=json',
|
||||||
run_as_root=True,
|
test_path, run_as_root=True,
|
||||||
prlimit=image_utils.QEMU_IMG_LIMITS)
|
prlimit=image_utils.QEMU_IMG_LIMITS)
|
||||||
self.assertEqual(mock_info.return_value, output)
|
self.assertEqual(mock_info.return_value, output)
|
||||||
|
|
||||||
|
|
|
@ -330,51 +330,52 @@ NFS_CONFIG4 = {'max_over_subscription_ratio': 20.0,
|
||||||
'nas_secure_file_permissions': 'false',
|
'nas_secure_file_permissions': 'false',
|
||||||
'nas_secure_file_operations': 'true'}
|
'nas_secure_file_operations': 'true'}
|
||||||
|
|
||||||
QEMU_IMG_INFO_OUT1 = """image: %(volid)s
|
QEMU_IMG_INFO_OUT1 = """{
|
||||||
file format: raw
|
"filename": "%(volid)s",
|
||||||
virtual size: %(size_gb)sG (%(size_b)s bytes)
|
"format": "raw",
|
||||||
disk size: 173K
|
"virtual-size": %(size_b)s,
|
||||||
"""
|
"actual-size": 173000
|
||||||
|
}"""
|
||||||
|
|
||||||
QEMU_IMG_INFO_OUT2 = """image: %(volid)s
|
QEMU_IMG_INFO_OUT2 = """{
|
||||||
file format: qcow2
|
"filename": "%(volid)s",
|
||||||
virtual size: %(size_gb)sG (%(size_b)s bytes)
|
"format": "qcow2",
|
||||||
disk size: 196K
|
"virtual-size": %(size_b)s,
|
||||||
cluster_size: 65536
|
"actual-size": 196000,
|
||||||
Format specific information:
|
"cluster-size": 65536,
|
||||||
compat: 1.1
|
"format-specific": {
|
||||||
lazy refcounts: false
|
"compat": "1.1",
|
||||||
refcount bits: 16
|
"lazy-refcounts": false,
|
||||||
corrupt: false
|
"refcount-bits": 16,
|
||||||
"""
|
"corrupt": false
|
||||||
|
}
|
||||||
|
}"""
|
||||||
|
|
||||||
QEMU_IMG_INFO_OUT3 = """image: volume-%(volid)s.%(snapid)s
|
QEMU_IMG_INFO_OUT3 = """{
|
||||||
file format: qcow2
|
"filename": "volume-%(volid)s.%(snapid)s",
|
||||||
virtual size: %(size_gb)sG (%(size_b)s bytes)
|
"format": "qcow2",
|
||||||
disk size: 196K
|
"virtual-size": %(size_b)s,
|
||||||
cluster_size: 65536
|
"actual-size": 196000,
|
||||||
backing file: volume-%(volid)s
|
"cluster-size": 65536,
|
||||||
backing file format: qcow2
|
"backing-filename": "volume-%(volid)s",
|
||||||
Format specific information:
|
"backing-filename-format": "qcow2",
|
||||||
compat: 1.1
|
"format-specific": {
|
||||||
lazy refcounts: false
|
"compat": "1.1",
|
||||||
refcount bits: 16
|
"lazy-refcounts": false,
|
||||||
corrupt: false
|
"refcount-bits": 16,
|
||||||
"""
|
"corrupt": false
|
||||||
|
}
|
||||||
|
}"""
|
||||||
|
|
||||||
QEMU_IMG_INFO_OUT4 = """image: volume-%(volid)s.%(snapid)s
|
QEMU_IMG_INFO_OUT4 = """{
|
||||||
file format: raw
|
"filename": "volume-%(volid)s.%(snapid)s",
|
||||||
virtual size: %(size_gb)sG (%(size_b)s bytes)
|
"format": "raw",
|
||||||
disk size: 196K
|
"virtual-size": %(size_b)s,
|
||||||
cluster_size: 65536
|
"actual-size": 196000,
|
||||||
backing file: volume-%(volid)s
|
"cluster-size": 65536,
|
||||||
backing file format: raw
|
"backing-filename": "volume-%(volid)s",
|
||||||
Format specific information:
|
"backing-filename-format": "raw"
|
||||||
compat: 1.1
|
}"""
|
||||||
lazy refcounts: false
|
|
||||||
refcount bits: 16
|
|
||||||
corrupt: false
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
@ddt.ddt
|
@ddt.ddt
|
||||||
|
@ -1191,7 +1192,7 @@ class NfsDriverTestCase(test.TestCase):
|
||||||
'size_gb': src_volume.size,
|
'size_gb': src_volume.size,
|
||||||
'size_b': src_volume.size * units.Gi}
|
'size_b': src_volume.size * units.Gi}
|
||||||
|
|
||||||
img_info = imageutils.QemuImgInfo(img_out)
|
img_info = imageutils.QemuImgInfo(img_out, format='json')
|
||||||
mock_img_info = self.mock_object(image_utils, 'qemu_img_info')
|
mock_img_info = self.mock_object(image_utils, 'qemu_img_info')
|
||||||
mock_img_info.return_value = img_info
|
mock_img_info.return_value = img_info
|
||||||
mock_convert_image = self.mock_object(image_utils, 'convert_image')
|
mock_convert_image = self.mock_object(image_utils, 'convert_image')
|
||||||
|
@ -1262,7 +1263,7 @@ class NfsDriverTestCase(test.TestCase):
|
||||||
'snapid': fake_snap.id,
|
'snapid': fake_snap.id,
|
||||||
'size_gb': src_volume.size,
|
'size_gb': src_volume.size,
|
||||||
'size_b': src_volume.size * units.Gi}
|
'size_b': src_volume.size * units.Gi}
|
||||||
img_info = imageutils.QemuImgInfo(img_out)
|
img_info = imageutils.QemuImgInfo(img_out, format='json')
|
||||||
mock_img_info = self.mock_object(image_utils, 'qemu_img_info')
|
mock_img_info = self.mock_object(image_utils, 'qemu_img_info')
|
||||||
mock_img_info.return_value = img_info
|
mock_img_info.return_value = img_info
|
||||||
|
|
||||||
|
@ -1328,7 +1329,8 @@ class NfsDriverTestCase(test.TestCase):
|
||||||
mock_img_utils = self.mock_object(image_utils, 'qemu_img_info')
|
mock_img_utils = self.mock_object(image_utils, 'qemu_img_info')
|
||||||
img_out = qemu_img_info % {'volid': volume.id, 'size_gb': volume.size,
|
img_out = qemu_img_info % {'volid': volume.id, 'size_gb': volume.size,
|
||||||
'size_b': volume.size * units.Gi}
|
'size_b': volume.size * units.Gi}
|
||||||
mock_img_utils.return_value = imageutils.QemuImgInfo(img_out)
|
mock_img_utils.return_value = imageutils.QemuImgInfo(img_out,
|
||||||
|
format='json')
|
||||||
self.mock_object(drv, '_read_info_file',
|
self.mock_object(drv, '_read_info_file',
|
||||||
return_value={'active': "volume-%s" % volume.id})
|
return_value={'active': "volume-%s" % volume.id})
|
||||||
|
|
||||||
|
@ -1348,12 +1350,14 @@ class NfsDriverTestCase(test.TestCase):
|
||||||
drv = self._driver
|
drv = self._driver
|
||||||
volume = self._simple_volume()
|
volume = self._simple_volume()
|
||||||
|
|
||||||
qemu_img_output = """image: %s
|
qemu_img_output = """{
|
||||||
file format: iso
|
"filename": "%s",
|
||||||
virtual size: 1.0G (1073741824 bytes)
|
"format": "iso",
|
||||||
disk size: 173K
|
"virtual-size": 1073741824,
|
||||||
""" % volume['name']
|
"actual-size": 173000
|
||||||
mock_img_info.return_value = imageutils.QemuImgInfo(qemu_img_output)
|
}""" % volume['name']
|
||||||
|
mock_img_info.return_value = imageutils.QemuImgInfo(qemu_img_output,
|
||||||
|
format='json')
|
||||||
|
|
||||||
self.assertRaises(exception.InvalidVolume,
|
self.assertRaises(exception.InvalidVolume,
|
||||||
drv.initialize_connection,
|
drv.initialize_connection,
|
||||||
|
|
|
@ -936,13 +936,14 @@ class QuobyteDriverTestCase(test.TestCase):
|
||||||
self.TEST_QUOBYTE_VOLUME),
|
self.TEST_QUOBYTE_VOLUME),
|
||||||
self.VOLUME_UUID)
|
self.VOLUME_UUID)
|
||||||
|
|
||||||
qemu_img_info_output = """image: volume-%s
|
qemu_img_info_output = """{
|
||||||
file format: qcow2
|
"filename": "volume-%s",
|
||||||
virtual size: 1.0G (1073741824 bytes)
|
"format": "qcow2",
|
||||||
disk size: 473K
|
"virtual-size": 1073741824,
|
||||||
""" % self.VOLUME_UUID
|
"actual-size": 473000
|
||||||
|
}""" % self.VOLUME_UUID
|
||||||
|
|
||||||
img_info = imageutils.QemuImgInfo(qemu_img_info_output)
|
img_info = imageutils.QemuImgInfo(qemu_img_info_output, format='json')
|
||||||
|
|
||||||
image_utils.qemu_img_info = mock.Mock(return_value=img_info)
|
image_utils.qemu_img_info = mock.Mock(return_value=img_info)
|
||||||
image_utils.resize_image = mock.Mock()
|
image_utils.resize_image = mock.Mock()
|
||||||
|
@ -975,13 +976,14 @@ class QuobyteDriverTestCase(test.TestCase):
|
||||||
|
|
||||||
size = dest_volume['size']
|
size = dest_volume['size']
|
||||||
|
|
||||||
qemu_img_output = """image: %s
|
qemu_img_output = """{
|
||||||
file format: raw
|
"filename": "%s",
|
||||||
virtual size: 1.0G (1073741824 bytes)
|
"format": "raw",
|
||||||
disk size: 173K
|
"virtual-size": 1073741824,
|
||||||
backing file: %s
|
"actual-size": 173000,
|
||||||
""" % (snap_file, src_volume['name'])
|
"backing-filename": "%s"
|
||||||
img_info = imageutils.QemuImgInfo(qemu_img_output)
|
}""" % (snap_file, src_volume['name'])
|
||||||
|
img_info = imageutils.QemuImgInfo(qemu_img_output, format='json')
|
||||||
|
|
||||||
# mocking and testing starts here
|
# mocking and testing starts here
|
||||||
image_utils.convert_image = mock.Mock()
|
image_utils.convert_image = mock.Mock()
|
||||||
|
@ -1031,13 +1033,14 @@ class QuobyteDriverTestCase(test.TestCase):
|
||||||
|
|
||||||
size = dest_volume['size']
|
size = dest_volume['size']
|
||||||
|
|
||||||
qemu_img_output = """image: %s
|
qemu_img_output = """{
|
||||||
file format: raw
|
"filename": "%s",
|
||||||
virtual size: 1.0G (1073741824 bytes)
|
"format": "raw",
|
||||||
disk size: 173K
|
"virtual-size": 1073741824,
|
||||||
backing file: %s
|
"actual-size": 173000,
|
||||||
""" % (snap_file, src_volume['name'])
|
"backing-filename": "%s"
|
||||||
img_info = imageutils.QemuImgInfo(qemu_img_output)
|
}""" % (snap_file, src_volume['name'])
|
||||||
|
img_info = imageutils.QemuImgInfo(qemu_img_output, format='json')
|
||||||
|
|
||||||
# mocking and testing starts here
|
# mocking and testing starts here
|
||||||
image_utils.convert_image = mock.Mock()
|
image_utils.convert_image = mock.Mock()
|
||||||
|
@ -1092,13 +1095,14 @@ class QuobyteDriverTestCase(test.TestCase):
|
||||||
|
|
||||||
size = dest_volume['size']
|
size = dest_volume['size']
|
||||||
|
|
||||||
qemu_img_output = """image: %s
|
qemu_img_output = """{
|
||||||
file format: raw
|
"filename": "%s",
|
||||||
virtual size: 1.0G (1073741824 bytes)
|
"format": "raw",
|
||||||
disk size: 173K
|
"virtual-size": 1073741824,
|
||||||
backing file: %s
|
"actual-size": 173000,
|
||||||
""" % (snap_file, src_volume['name'])
|
"backing-filename": "%s"
|
||||||
img_info = imageutils.QemuImgInfo(qemu_img_output)
|
}""" % (snap_file, src_volume['name'])
|
||||||
|
img_info = imageutils.QemuImgInfo(qemu_img_output, format='json')
|
||||||
|
|
||||||
# mocking and testing starts here
|
# mocking and testing starts here
|
||||||
image_utils.convert_image = mock.Mock()
|
image_utils.convert_image = mock.Mock()
|
||||||
|
@ -1156,13 +1160,14 @@ class QuobyteDriverTestCase(test.TestCase):
|
||||||
|
|
||||||
size = dest_volume['size']
|
size = dest_volume['size']
|
||||||
|
|
||||||
qemu_img_output = """image: %s
|
qemu_img_output = """{
|
||||||
file format: raw
|
"filename": "%s",
|
||||||
virtual size: 1.0G (1073741824 bytes)
|
"format": "raw",
|
||||||
disk size: 173K
|
"virtual-size": 1073741824,
|
||||||
backing file: %s
|
"actual-size": 173000,
|
||||||
""" % (snap_file, src_volume['name'])
|
"backing-filename": "%s"
|
||||||
img_info = imageutils.QemuImgInfo(qemu_img_output)
|
}""" % (snap_file, src_volume['name'])
|
||||||
|
img_info = imageutils.QemuImgInfo(qemu_img_output, format='json')
|
||||||
|
|
||||||
# mocking and testing starts here
|
# mocking and testing starts here
|
||||||
image_utils.convert_image = mock.Mock()
|
image_utils.convert_image = mock.Mock()
|
||||||
|
@ -1247,12 +1252,13 @@ class QuobyteDriverTestCase(test.TestCase):
|
||||||
drv._get_hash_str(self.TEST_QUOBYTE_VOLUME))
|
drv._get_hash_str(self.TEST_QUOBYTE_VOLUME))
|
||||||
vol_path = os.path.join(vol_dir, volume['name'])
|
vol_path = os.path.join(vol_dir, volume['name'])
|
||||||
|
|
||||||
qemu_img_output = """image: %s
|
qemu_img_output = """{
|
||||||
file format: raw
|
"filename": "%s",
|
||||||
virtual size: 1.0G (1073741824 bytes)
|
"format": "raw",
|
||||||
disk size: 173K
|
"virtual-size": 1073741824,
|
||||||
""" % volume['name']
|
"actual-size": 173000
|
||||||
img_info = imageutils.QemuImgInfo(qemu_img_output)
|
}""" % volume['name']
|
||||||
|
img_info = imageutils.QemuImgInfo(qemu_img_output, format='json')
|
||||||
|
|
||||||
drv.get_active_image_from_info = mock.Mock(return_value=volume['name'])
|
drv.get_active_image_from_info = mock.Mock(return_value=volume['name'])
|
||||||
image_utils.qemu_img_info = mock.Mock(return_value=img_info)
|
image_utils.qemu_img_info = mock.Mock(return_value=img_info)
|
||||||
|
@ -1293,12 +1299,13 @@ class QuobyteDriverTestCase(test.TestCase):
|
||||||
|
|
||||||
mock_create_temporary_file.return_value = self.TEST_TMP_FILE
|
mock_create_temporary_file.return_value = self.TEST_TMP_FILE
|
||||||
|
|
||||||
qemu_img_output = """image: %s
|
qemu_img_output = """{
|
||||||
file format: raw
|
"filename": "%s",
|
||||||
virtual size: 1.0G (1073741824 bytes)
|
"format": "raw",
|
||||||
disk size: 173K
|
"virtual-size": 1073741824,
|
||||||
""" % volume['name']
|
"actual-size": 173000
|
||||||
img_info = imageutils.QemuImgInfo(qemu_img_output)
|
}""" % volume['name']
|
||||||
|
img_info = imageutils.QemuImgInfo(qemu_img_output, format='json')
|
||||||
mock_qemu_img_info.return_value = img_info
|
mock_qemu_img_info.return_value = img_info
|
||||||
|
|
||||||
upload_path = volume_path
|
upload_path = volume_path
|
||||||
|
@ -1340,12 +1347,13 @@ class QuobyteDriverTestCase(test.TestCase):
|
||||||
|
|
||||||
mock_create_temporary_file.return_value = self.TEST_TMP_FILE
|
mock_create_temporary_file.return_value = self.TEST_TMP_FILE
|
||||||
|
|
||||||
qemu_img_output = """image: %s
|
qemu_img_output = """{
|
||||||
file format: qcow2
|
"filename": "%s",
|
||||||
virtual size: 1.0G (1073741824 bytes)
|
"format": "qcow2",
|
||||||
disk size: 173K
|
"virtual-size": 1073741824,
|
||||||
""" % volume['name']
|
"actual-size": 173000
|
||||||
img_info = imageutils.QemuImgInfo(qemu_img_output)
|
}""" % volume['name']
|
||||||
|
img_info = imageutils.QemuImgInfo(qemu_img_output, format='json')
|
||||||
mock_qemu_img_info.return_value = img_info
|
mock_qemu_img_info.return_value = img_info
|
||||||
|
|
||||||
upload_path = self.TEST_TMP_FILE
|
upload_path = self.TEST_TMP_FILE
|
||||||
|
@ -1390,13 +1398,14 @@ class QuobyteDriverTestCase(test.TestCase):
|
||||||
|
|
||||||
mock_create_temporary_file.return_value = self.TEST_TMP_FILE
|
mock_create_temporary_file.return_value = self.TEST_TMP_FILE
|
||||||
|
|
||||||
qemu_img_output = """image: volume-%s.%s
|
qemu_img_output = """{
|
||||||
file format: qcow2
|
"filename": "volume-%s.%s",
|
||||||
virtual size: 1.0G (1073741824 bytes)
|
"format": "qcow2",
|
||||||
disk size: 173K
|
"virtual-size": 1073741824,
|
||||||
backing file: %s
|
"actual-size": 173000,
|
||||||
""" % (self.VOLUME_UUID, self.SNAP_UUID, volume_filename)
|
"backing-filename": "%s"
|
||||||
img_info = imageutils.QemuImgInfo(qemu_img_output)
|
}""" % (self.VOLUME_UUID, self.SNAP_UUID, volume_filename)
|
||||||
|
img_info = imageutils.QemuImgInfo(qemu_img_output, format='json')
|
||||||
mock_qemu_img_info.return_value = img_info
|
mock_qemu_img_info.return_value = img_info
|
||||||
|
|
||||||
upload_path = self.TEST_TMP_FILE
|
upload_path = self.TEST_TMP_FILE
|
||||||
|
|
|
@ -20,6 +20,7 @@ from oslo_config import cfg
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
from oslo_utils import excutils
|
from oslo_utils import excutils
|
||||||
from oslo_utils import fileutils
|
from oslo_utils import fileutils
|
||||||
|
from oslo_utils import strutils
|
||||||
from oslo_utils import timeutils
|
from oslo_utils import timeutils
|
||||||
import six
|
import six
|
||||||
import taskflow.engines
|
import taskflow.engines
|
||||||
|
@ -551,7 +552,8 @@ class CreateVolumeFromSpecTask(flow_utils.CinderTask):
|
||||||
volume,
|
volume,
|
||||||
encryption)
|
encryption)
|
||||||
|
|
||||||
if image_info.encrypted == 'yes':
|
# see Bug #1942682 and Change I949f07582a708 for why we do this
|
||||||
|
if strutils.bool_from_string(image_info.encrypted):
|
||||||
key_str = source_pass + "\n" + new_pass + "\n"
|
key_str = source_pass + "\n" + new_pass + "\n"
|
||||||
del source_pass
|
del source_pass
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue