1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-08 11:16:47 +00:00

fix(instances): a clone's TPM is a new one, never the VM's state

A shut-off clone kept the VM's TPM element as it was: an emulated TPM
with a state path of its own, a host's TPM or an external one would be
shared with the VM, not the new, empty TPM the clone form promises. An
emulated TPM loses its state path, and the others are refused.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kk4h2TcUiaWmU5MUszYSea
This commit is contained in:
catborise 2026-11-07 23:45:22 +03:00
parent d49db11e78
commit 3fd9148b67
6 changed files with 93 additions and 64 deletions

Binary file not shown.

View file

@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-11-07 20:44+0000\n"
"POT-Creation-Date: 2026-11-07 20:45+0000\n"
"PO-Revision-Date: 2020-11-04 12:00+0000\n"
"Last-Translator: catborise <muhammetalisag@gmail.com>, 2020\n"
"Language-Team: Turkish (https://www.transifex.com/catborise/teams/110663/tr/)\n"
@ -3036,7 +3036,7 @@ msgstr "cloud-init tohumu, disk için bir dizin depolama havuzu gerektirir"
msgid "This host offers no firmware %(firmware)s"
msgstr "Bu sunucu %(firmware)s firmware'ini sunmuyor"
#: instances/jobs.py:852 vrtManager/instance.py:3049
#: instances/jobs.py:852 vrtManager/instance.py:3057
msgid "This host offers no TPM 2.0: install swtpm on it"
msgstr "Bu sunucu TPM 2.0 sunmuyor: üzerine swtpm kurun"
@ -9371,59 +9371,65 @@ msgstr ""
msgid "Shut the VM down to revert to an internal snapshot"
msgstr "Dahili bir anlık görüntüye geri dönmek için sanal makineyi kapatın"
#: vrtManager/instance.py:2420
#: vrtManager/instance.py:2406
msgid "A VM with a host's or an external TPM is not cloned; remove it first"
msgstr ""
"Ana makinenin ya da harici bir TPM'i olan sanal makine klonlanmaz; önce onu "
"kaldırın"
#: vrtManager/instance.py:2428
msgid "Cannot clone a VM whose NVRAM is not a file"
msgstr "NVRAM'i dosya olmayan bir sanal makine klonlanamaz"
#: vrtManager/instance.py:2488
#: vrtManager/instance.py:2496
#, python-format
msgid "Clone failed (%(err)s); remove these copies by hand: %(path)s"
msgstr ""
"Klonlama başarısız oldu (%(err)s); bu kopyaları elle kaldırın: %(path)s"
#: vrtManager/instance.py:2498
#: vrtManager/instance.py:2506
msgid "Shut the VM down before cloning it"
msgstr "Klonlamadan önce sanal makineyi kapatın"
#: vrtManager/instance.py:2552
#: vrtManager/instance.py:2560
#, python-format
msgid "Clone failed (%(err)s); remove these copies by hand: %(leftovers)s"
msgstr ""
"Klonlama başarısız oldu (%(err)s); bu kopyaları elle kaldırın: %(leftovers)s"
#: vrtManager/instance.py:2563
#: vrtManager/instance.py:2571
msgid "Live clone needs libvirt 11.10 or later; shut the VM down to clone it"
msgstr ""
"Canlı klonlama libvirt 11.10 veya sonrasını gerektirir; klonlamak için sanal "
"makineyi kapatın"
#: vrtManager/instance.py:2566
#: vrtManager/instance.py:2574
msgid "A VM with a TPM is cloned only shut down"
msgstr "TPM'i olan bir sanal makine yalnızca kapalıyken klonlanır"
#: vrtManager/instance.py:2569
#: vrtManager/instance.py:2577
#, python-format
msgid "Disk %(dev)s is not a local file; shut the VM down to clone it"
msgstr ""
"Disk %(dev)s yerel bir dosya değil; klonlamak için sanal makineyi kapatın"
#: vrtManager/instance.py:2571
#: vrtManager/instance.py:2579
#, python-format
msgid "Disk %(dev)s is shareable; shut the VM down to clone it"
msgstr "Disk %(dev)s paylaşılabilir; klonlamak için sanal makineyi kapatın"
#: vrtManager/instance.py:2576
#: vrtManager/instance.py:2584
#, python-format
msgid "Disk %(dev)s changes at the next start; shut the VM down to clone it"
msgstr ""
"Disk %(dev)s sonraki başlatmada değişiyor; klonlamak için sanal makineyi "
"kapatın"
#: vrtManager/instance.py:2578
#: vrtManager/instance.py:2586
msgid "Another job is running on the VM; clone it when that ends"
msgstr "Sanal makinede başka bir iş çalışıyor; o bittiğinde klonlayın"
#: vrtManager/instance.py:2604
#: vrtManager/instance.py:2612
#, python-format
msgid ""
"Storage pool %(pool)s has %(free).1f GiB free; the clone needs %(size).1f GiB"
@ -9433,25 +9439,25 @@ msgstr ""
"gerektiriyor (kopyalanan diskler, artı bunların %%%(percent)g kadarı, en az "
"%(minimum)g GiB)"
#: vrtManager/instance.py:2621
#: vrtManager/instance.py:2629
#, python-format
msgid "Volume %(name)s already exists in storage pool %(pool)s"
msgstr "%(name)s birimi %(pool)s depolama havuzunda zaten var"
#: vrtManager/instance.py:2766
#: vrtManager/instance.py:2774
msgid "A network interface that is a host device is removed in the XML editor"
msgstr "Sunucu aygıtı olan bir ağ arabirimi XML düzenleyicide kaldırılır"
#: vrtManager/instance.py:2782
#: vrtManager/instance.py:2790
#, python-format
msgid "No network interface with MAC %(old_mac)s"
msgstr "MAC adresi %(old_mac)s olan ağ arabirimi yok"
#: vrtManager/instance.py:2785
#: vrtManager/instance.py:2793
msgid "A network interface that is a host device is changed in the XML editor"
msgstr "Sunucu aygıtı olan bir ağ arabirimi XML düzenleyicide değiştirilir"
#: vrtManager/instance.py:2876
#: vrtManager/instance.py:2884
msgid ""
"A VM changes its PCI devices while it runs, or is shut off without a saved "
"state"
@ -9459,14 +9465,14 @@ msgstr ""
"Sanal makine PCI aygıtlarını çalışırken veya kaydedilmiş durumu olmadan "
"kapalıyken değiştirir"
#: vrtManager/instance.py:2888
#: vrtManager/instance.py:2896
#, python-format
msgid "%(err)s; whether the VM has PCI device %(address)s now is not known"
msgstr ""
"%(err)s; sanal makinede şu anda %(address)s PCI aygıtının olup olmadığı "
"bilinmiyor"
#: vrtManager/instance.py:2890
#: vrtManager/instance.py:2898
#, python-format
msgid ""
"%(err)s; PCI device %(address)s: the VM is not running, its next start has it"
@ -9474,7 +9480,7 @@ msgstr ""
"%(err)s; PCI aygıtı %(address)s: sanal makine çalışmıyor, sonraki başlatmada "
"var"
#: vrtManager/instance.py:2892
#: vrtManager/instance.py:2900
#, python-format
msgid ""
"%(err)s; PCI device %(address)s: the VM is not running, its next start does "
@ -9483,7 +9489,7 @@ msgstr ""
"%(err)s; PCI aygıtı %(address)s: sanal makine çalışmıyor, sonraki başlatmada "
"yok"
#: vrtManager/instance.py:2893
#: vrtManager/instance.py:2901
#, python-format
msgid ""
"%(err)s; PCI device %(address)s: the running VM has it, its next start has it"
@ -9491,7 +9497,7 @@ msgstr ""
"%(err)s; PCI aygıtı %(address)s: çalışan sanal makinede var, sonraki "
"başlatmada var"
#: vrtManager/instance.py:2895
#: vrtManager/instance.py:2903
#, python-format
msgid ""
"%(err)s; PCI device %(address)s: the running VM has it, its next start does "
@ -9500,7 +9506,7 @@ msgstr ""
"%(err)s; PCI aygıtı %(address)s: çalışan sanal makinede var, sonraki "
"başlatmada yok"
#: vrtManager/instance.py:2897
#: vrtManager/instance.py:2905
#, python-format
msgid ""
"%(err)s; PCI device %(address)s: the running VM does not have it, its next "
@ -9509,7 +9515,7 @@ msgstr ""
"%(err)s; PCI aygıtı %(address)s: çalışan sanal makinede yok, sonraki "
"başlatmada var"
#: vrtManager/instance.py:2899
#: vrtManager/instance.py:2907
#, python-format
msgid ""
"%(err)s; PCI device %(address)s: the running VM does not have it, its next "
@ -9518,34 +9524,34 @@ msgstr ""
"%(err)s; PCI aygıtı %(address)s: çalışan sanal makinede yok, sonraki "
"başlatmada yok"
#: vrtManager/instance.py:2933
#: vrtManager/instance.py:2941
#, python-format
msgid "The VM has no PCI device %(address)s"
msgstr "Sanal makinede %(address)s PCI aygıtı yok"
#: vrtManager/instance.py:2951
#: vrtManager/instance.py:2959
msgid "The VM has no USB controller"
msgstr "Sanal makinede USB denetleyicisi yok"
#: vrtManager/instance.py:2970
#: vrtManager/instance.py:2978
msgid "The VM has no such USB device"
msgstr "Sanal makinede böyle bir USB aygıtı yok"
#: vrtManager/instance.py:2984
#: vrtManager/instance.py:2992
#, python-format
msgid "The VM has no network interface %(mac)s"
msgstr "Sanal makinede %(mac)s ağ arabirimi yok"
#: vrtManager/instance.py:3015
#: vrtManager/instance.py:3023
msgid "The VM has its own RNG device: change it in the XML editor"
msgstr ""
"Sanal makinenin kendi RNG aygıtı var: bunu XML düzenleyicide değiştirin"
#: vrtManager/instance.py:3042
#: vrtManager/instance.py:3050
msgid "The VM has its own TPM: change it in the XML editor"
msgstr "Sanal makinenin kendi TPM'i var: bunu XML düzenleyicide değiştirin"
#: vrtManager/instance.py:3061
#: vrtManager/instance.py:3069
#, python-format
msgid "Unknown crash action %(action)s"
msgstr "Bilinmeyen çökme eylemi %(action)s"

Binary file not shown.

View file

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-11-07 20:44+0000\n"
"POT-Creation-Date: 2026-11-07 20:45+0000\n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: \n"
@ -2911,7 +2911,7 @@ msgstr "cloud-init 种子需要为磁盘使用目录类型的存储池"
msgid "This host offers no firmware %(firmware)s"
msgstr "此主机不提供固件 %(firmware)s"
#: instances/jobs.py:852 vrtManager/instance.py:3049
#: instances/jobs.py:852 vrtManager/instance.py:3057
msgid "This host offers no TPM 2.0: install swtpm on it"
msgstr "此主机不提供 TPM 2.0:请在主机上安装 swtpm"
@ -8849,52 +8849,56 @@ msgstr "此虚拟机上仍有快照任务在运行;请在其结束后重试"
msgid "Shut the VM down to revert to an internal snapshot"
msgstr "请关闭虚拟机后再还原到内部快照"
#: vrtManager/instance.py:2420
#: vrtManager/instance.py:2406
msgid "A VM with a host's or an external TPM is not cloned; remove it first"
msgstr "带有主机 TPM 或外部 TPM 的虚拟机无法克隆;请先将其移除"
#: vrtManager/instance.py:2428
msgid "Cannot clone a VM whose NVRAM is not a file"
msgstr "NVRAM 不是文件的虚拟机无法克隆"
#: vrtManager/instance.py:2488
#: vrtManager/instance.py:2496
#, python-format
msgid "Clone failed (%(err)s); remove these copies by hand: %(path)s"
msgstr "克隆失败(%(err)s);请手动删除这些副本:%(path)s"
#: vrtManager/instance.py:2498
#: vrtManager/instance.py:2506
msgid "Shut the VM down before cloning it"
msgstr "请先关闭虚拟机再克隆"
#: vrtManager/instance.py:2552
#: vrtManager/instance.py:2560
#, python-format
msgid "Clone failed (%(err)s); remove these copies by hand: %(leftovers)s"
msgstr "克隆失败(%(err)s);请手动删除这些副本:%(leftovers)s"
#: vrtManager/instance.py:2563
#: vrtManager/instance.py:2571
msgid "Live clone needs libvirt 11.10 or later; shut the VM down to clone it"
msgstr "在线克隆需要 libvirt 11.10 或更高版本;请关闭虚拟机后再克隆"
#: vrtManager/instance.py:2566
#: vrtManager/instance.py:2574
msgid "A VM with a TPM is cloned only shut down"
msgstr "带 TPM 的虚拟机只能在关机时克隆"
#: vrtManager/instance.py:2569
#: vrtManager/instance.py:2577
#, python-format
msgid "Disk %(dev)s is not a local file; shut the VM down to clone it"
msgstr "磁盘 %(dev)s 不是本地文件;请关闭虚拟机后再克隆"
#: vrtManager/instance.py:2571
#: vrtManager/instance.py:2579
#, python-format
msgid "Disk %(dev)s is shareable; shut the VM down to clone it"
msgstr "磁盘 %(dev)s 是可共享的;请关闭虚拟机后再克隆"
#: vrtManager/instance.py:2576
#: vrtManager/instance.py:2584
#, python-format
msgid "Disk %(dev)s changes at the next start; shut the VM down to clone it"
msgstr "磁盘 %(dev)s 在下次启动时会改变;请关闭虚拟机后再克隆"
#: vrtManager/instance.py:2578
#: vrtManager/instance.py:2586
msgid "Another job is running on the VM; clone it when that ends"
msgstr "虚拟机上有另一个任务正在运行;请在其结束后再克隆"
#: vrtManager/instance.py:2604
#: vrtManager/instance.py:2612
#, python-format
msgid ""
"Storage pool %(pool)s has %(free).1f GiB free; the clone needs %(size).1f GiB"
@ -8903,102 +8907,102 @@ msgstr ""
"存储池 %(pool)s 可用 %(free).1f GiB;克隆需要 %(size).1f GiB(复制的磁盘,再加其 %(percent)g%%,至少"
" %(minimum)g GiB)"
#: vrtManager/instance.py:2621
#: vrtManager/instance.py:2629
#, python-format
msgid "Volume %(name)s already exists in storage pool %(pool)s"
msgstr "卷 %(name)s 已存在于存储池 %(pool)s 中"
#: vrtManager/instance.py:2766
#: vrtManager/instance.py:2774
msgid "A network interface that is a host device is removed in the XML editor"
msgstr "作为主机设备的网络接口需在 XML 编辑器中删除"
#: vrtManager/instance.py:2782
#: vrtManager/instance.py:2790
#, python-format
msgid "No network interface with MAC %(old_mac)s"
msgstr "没有 MAC 为 %(old_mac)s 的网络接口"
#: vrtManager/instance.py:2785
#: vrtManager/instance.py:2793
msgid "A network interface that is a host device is changed in the XML editor"
msgstr "作为主机设备的网络接口需在 XML 编辑器中修改"
#: vrtManager/instance.py:2876
#: vrtManager/instance.py:2884
msgid ""
"A VM changes its PCI devices while it runs, or is shut off without a saved "
"state"
msgstr "虚拟机只能在运行时或无保存的状态的关机时更改其 PCI 设备"
#: vrtManager/instance.py:2888
#: vrtManager/instance.py:2896
#, python-format
msgid "%(err)s; whether the VM has PCI device %(address)s now is not known"
msgstr "%(err)s;虚拟机现在是否有 PCI 设备 %(address)s 未知"
#: vrtManager/instance.py:2890
#: vrtManager/instance.py:2898
#, python-format
msgid ""
"%(err)s; PCI device %(address)s: the VM is not running, its next start has it"
msgstr "%(err)s;PCI 设备 %(address)s:虚拟机未运行,下次启动时有它"
#: vrtManager/instance.py:2892
#: vrtManager/instance.py:2900
#, python-format
msgid ""
"%(err)s; PCI device %(address)s: the VM is not running, its next start does "
"not have it"
msgstr "%(err)s;PCI 设备 %(address)s:虚拟机未运行,下次启动时没有它"
#: vrtManager/instance.py:2893
#: vrtManager/instance.py:2901
#, python-format
msgid ""
"%(err)s; PCI device %(address)s: the running VM has it, its next start has it"
msgstr "%(err)s;PCI 设备 %(address)s:运行中的虚拟机有它,下次启动时有它"
#: vrtManager/instance.py:2895
#: vrtManager/instance.py:2903
#, python-format
msgid ""
"%(err)s; PCI device %(address)s: the running VM has it, its next start does "
"not have it"
msgstr "%(err)s;PCI 设备 %(address)s:运行中的虚拟机有它,下次启动时没有它"
#: vrtManager/instance.py:2897
#: vrtManager/instance.py:2905
#, python-format
msgid ""
"%(err)s; PCI device %(address)s: the running VM does not have it, its next "
"start has it"
msgstr "%(err)s;PCI 设备 %(address)s:运行中的虚拟机没有它,下次启动时有它"
#: vrtManager/instance.py:2899
#: vrtManager/instance.py:2907
#, python-format
msgid ""
"%(err)s; PCI device %(address)s: the running VM does not have it, its next "
"start does not have it"
msgstr "%(err)s;PCI 设备 %(address)s:运行中的虚拟机没有它,下次启动时没有它"
#: vrtManager/instance.py:2933
#: vrtManager/instance.py:2941
#, python-format
msgid "The VM has no PCI device %(address)s"
msgstr "虚拟机没有 PCI 设备 %(address)s"
#: vrtManager/instance.py:2951
#: vrtManager/instance.py:2959
msgid "The VM has no USB controller"
msgstr "虚拟机没有 USB 控制器"
#: vrtManager/instance.py:2970
#: vrtManager/instance.py:2978
msgid "The VM has no such USB device"
msgstr "虚拟机没有此 USB 设备"
#: vrtManager/instance.py:2984
#: vrtManager/instance.py:2992
#, python-format
msgid "The VM has no network interface %(mac)s"
msgstr "虚拟机没有网络接口 %(mac)s"
#: vrtManager/instance.py:3015
#: vrtManager/instance.py:3023
msgid "The VM has its own RNG device: change it in the XML editor"
msgstr "虚拟机有自己的 RNG 设备:请在 XML 编辑器中修改"
#: vrtManager/instance.py:3042
#: vrtManager/instance.py:3050
msgid "The VM has its own TPM: change it in the XML editor"
msgstr "虚拟机有自己的 TPM:请在 XML 编辑器中修改"
#: vrtManager/instance.py:3061
#: vrtManager/instance.py:3069
#, python-format
msgid "Unknown crash action %(action)s"
msgstr "未知的崩溃操作 %(action)s"

View file

@ -2399,6 +2399,14 @@ class wvmInstance(wvmConnect):
raise ValueError("Cannot clone a disk without a supported source and destination")
disks.append((source, dev))
# the clone gets a new, empty TPM (the clone form says so): an emulated
# one without the VM's state path; a host's or another process's would be shared
for backend in tree.xpath("devices/tpm/backend"):
if backend.get("type") != "emulator":
raise util.OperationError(gettext_noop("A VM with a host's or an external TPM is not cloned; remove it first"))
for source in backend.findall("source"):
backend.remove(source)
# a host device is one VM's: the clone gets none (the clone form says so)
for hostdev in tree.findall("devices/hostdev"):
hostdev.getparent().remove(hostdev)

View file

@ -290,6 +290,17 @@ class DefineCloneTestCase(unittest.TestCase):
self.assertEqual(tree.find("devices/interface/mac").get("address"), "52:54:00:00:00:02")
p.vol.storagePoolLookupByVolume.return_value.createXMLFrom.assert_not_called()
def test_the_clone_s_tpm_is_new(self):
state = "<tpm model='tpm-crb'><backend type='emulator' version='2.0'><source type='dir' path='/srv/tpm/src'/></backend></tpm>"
p = proxy(domain(extra=state))
tree, _disks = p._clone_definition(FORM, UUID)
self.assertEqual(tree.xpath("devices/tpm/backend/source"), [])
for backend in ("<backend type='passthrough'><device path='/dev/tpm0'/></backend>",
"<backend type='external'><source type='unix' path='/run/tpm.sock'/></backend>"):
with self.subTest(backend=backend):
with self.assertRaisesRegex(util.OperationError, "external TPM is not cloned"):
proxy(domain(extra=f"<tpm model='tpm-crb'>{backend}</tpm>"))._clone_definition(FORM, UUID)
def test_a_missing_mac_is_refused(self):
p = proxy()
p._defineXML = MagicMock()