mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-08 19:26:48 +00:00
feat(instances): a CD-ROM is added on the bus chosen, with its ISO
A running VM got its new CD-ROM on SCSI, the one bus the panel could plug in then, and Windows does not see a virtio-scsi drive before the driver on that ISO is installed. Add CD-ROM is now a dialog that chooses the bus and the ISO: a running VM takes USB, first, which every guest sees and which hot-plugs, or SCSI; a shut-off one SATA (IDE on pc), SCSI or USB. libvirt has no empty USB drive, so a USB CD-ROM takes its ISO when it is added and is detached instead of ejected, also while the VM runs. A USB CD-ROM is a CD drive on QEMU's usb-bot only. Where QEMU has none (RHEL 9), libvirt took usb-storage, which shows the guest a hard disk that Windows does not read; the drive now asks for usb-bot, and such a host refuses it with libvirt's message.
This commit is contained in:
parent
0cd687e035
commit
2a05576e18
9 changed files with 313 additions and 165 deletions
43
instances/templates/add_instance_cdrom.html
Normal file
43
instances/templates/add_instance_cdrom.html
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
{% load i18n %}
|
||||
{% load bootstrap_icons %}
|
||||
<button type="button" class="btn btn-sm btn-secondary" data-bs-toggle="modal" data-bs-target="#addInstanceCdrom"{% if not cdrom_buses %} disabled{% endif %}>{% bs_icon 'plus' %} {% trans "Add CD-ROM" %}</button>
|
||||
|
||||
<div class="modal fade" id="addInstanceCdrom" tabindex="-1" role="dialog" aria-labelledby="addInstanceCdromLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<form class="modal-content" action="{% url 'instances:add_cdrom' instance.id %}" method="post" aria-label="{% trans "Add CD-ROM form" %}">{% csrf_token %}
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="addInstanceCdromLabel">{% trans "Add CD-ROM" %}</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{% trans "Close" %}"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row g-3">
|
||||
<div class="col-sm-4">
|
||||
<label class="form-label" for="add-cdrom-bus">{% trans "Bus" %}</label>
|
||||
<select class="form-select" id="add-cdrom-bus" name="bus" aria-describedby="add-cdrom-help">
|
||||
{% for bus in cdrom_buses %}
|
||||
<option value="{{ bus }}">{{ bus }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-sm-8">
|
||||
<label class="form-label" for="add-cdrom-media">{% trans "ISO image" %}</label>
|
||||
<select class="form-select" id="add-cdrom-media" name="media">
|
||||
{% for iso in instance.media_iso %}
|
||||
<option value="{{ iso }}">{{ iso }}</option>
|
||||
{% endfor %}
|
||||
<option value="">{% trans "No media" %}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-12 form-text mt-2" id="add-cdrom-help">
|
||||
{% trans "Windows sees USB, SATA and IDE drives without a driver; SCSI ones need the virtio driver." %}
|
||||
{% trans "A running VM takes USB and SCSI drives. A USB drive needs an ISO image, is detached instead of ejected, and needs a QEMU with usb-bot (not RHEL 9's)." %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">{% trans "Cancel" %}</button>
|
||||
<button type="submit" class="btn btn-primary">{% trans "Add" %}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -147,14 +147,12 @@
|
|||
<div role="tabpanel" class="tab-pane" id="disks">
|
||||
{# its CD-ROM drives, then its disks as list rows; the forms are those of the actions #}
|
||||
{% if instance.status != 5 %}
|
||||
<p class="small text-body-secondary">{% bs_icon 'lock' %} {% trans "The VM is running: CD-ROM drives added now use the SCSI bus. Shut it down to detach other CD-ROM drives, or to detach or delete disks." %}</p>
|
||||
<p class="small text-body-secondary">{% bs_icon 'lock' %} {% trans "The VM is running: CD-ROM drives added now use the USB or SCSI bus. Shut it down to detach a SATA or IDE CD-ROM drive, or to detach or delete disks." %}</p>
|
||||
{% endif %}
|
||||
<section class="mb-4" aria-labelledby="media-heading">
|
||||
<div class="d-flex flex-wrap justify-content-between align-items-center gap-2 mb-2">
|
||||
<h2 class="h6 mb-0" id="media-heading">{% trans "Removable media" %}</h2>
|
||||
<form action="{% url 'instances:add_cdrom' instance.id %}" method="post" aria-label="{% trans "Add CD-ROM form" %}">{% csrf_token %}
|
||||
<button class="btn btn-sm btn-secondary" type="submit">{% bs_icon 'plus' %} {% trans "Add CD-ROM" %}</button>
|
||||
</form>
|
||||
{% include 'add_instance_cdrom.html' %}
|
||||
</div>
|
||||
{% for cd in instance.media %}
|
||||
<div class="card mb-2">
|
||||
|
|
@ -168,11 +166,13 @@
|
|||
<div class="small text-body-secondary">{{ cd.dev }} · {{ cd.bus }} · {% if cd.image %}{{ cd.image }}{% else %}{% trans "No media" %}{% endif %}</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if not cd.image %}
|
||||
<button type="submit" class="btn btn-sm btn-secondary" formaction="{% url 'instances:detach_cdrom' instance.id cd.dev %}" formmethod="post"{% if instance.status != 5 and cd.bus != "scsi" %} disabled{% endif %}>{% trans "Detach" %}</button>
|
||||
{% if not cd.image or cd.bus == "usb" %}
|
||||
<button type="submit" class="btn btn-sm btn-secondary" formaction="{% url 'instances:detach_cdrom' instance.id cd.dev %}" formmethod="post"{% if instance.status != 5 and cd.bus != "scsi" and cd.bus != "usb" %} disabled{% endif %}>{% trans "Detach" %}</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if cd.image %}
|
||||
{% if cd.bus == "usb" %}
|
||||
{# libvirt has no empty USB drive: it is detached, not ejected #}
|
||||
{% elif cd.image %}
|
||||
<input type="hidden" name="path" value="{{ cd.path }}">
|
||||
<button type="submit" class="btn btn-sm btn-primary" value="{{ cd.dev }}" name="umount_iso">{% bs_icon 'eject' %} {% trans "Unmount" %}</button>
|
||||
{% else %}
|
||||
|
|
|
|||
|
|
@ -601,6 +601,33 @@ class LiveDataLossTestCase(TestCase):
|
|||
tree = etree.fromstring(dom.XMLDesc(flags))
|
||||
self.assertEqual(tree.xpath("devices/disk[@device='cdrom']/target/@dev"), ["sda"])
|
||||
|
||||
def test_a_usb_cdrom_with_its_iso_is_plugged_into_a_running_vm_and_detached(self):
|
||||
from lxml import etree
|
||||
|
||||
pool = self.conn.storagePoolLookupByName(livetest.POOL)
|
||||
iso = pool.createXML(f"<volume><name>{P}usb.iso</name><capacity unit='MiB'>1</capacity>"
|
||||
"<target><format type='raw'/></target></volume>", 0)
|
||||
dom, inst = self.vm("cdrom-usb", [], extra_devices="<controller type='usb' model='qemu-xhci'/>")
|
||||
dom.create()
|
||||
|
||||
def cdroms(flags):
|
||||
tree = etree.fromstring(dom.XMLDesc(flags))
|
||||
return [(d.find("target").get("bus"), d.get("model"), d.xpath("string(source/@file)"))
|
||||
for d in tree.xpath("devices/disk[@device='cdrom']")]
|
||||
|
||||
response = self.client.post(reverse("instances:add_cdrom", args=[inst.id]),
|
||||
{"bus": "usb", "media": f"{P}usb.iso"}, follow=True)
|
||||
if not cdroms(0): # a QEMU without usb-bot (RHEL 9): refused, nothing added
|
||||
self.assertIn("usb-bot", " ".join(str(m) for m in response.context["messages"]))
|
||||
self.assertEqual(cdroms(libvirt.VIR_DOMAIN_XML_INACTIVE), [])
|
||||
return
|
||||
for flags in (0, libvirt.VIR_DOMAIN_XML_INACTIVE):
|
||||
self.assertEqual(cdroms(flags), [("usb", "usb-bot", iso.path())])
|
||||
self.client.post(reverse("instances:detach_cdrom", args=[inst.id, "sda"]),
|
||||
HTTP_REFERER=reverse("instances:instance", args=[inst.id]))
|
||||
for flags in (0, libvirt.VIR_DOMAIN_XML_INACTIVE):
|
||||
self.assertEqual(cdroms(flags), [])
|
||||
|
||||
def test_pending_qos_change_is_shown_and_kept_by_the_next_edit(self):
|
||||
from lxml import etree, html
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@ class NewDiskNameTestCase(TestCase):
|
|||
proxy = wvm.return_value
|
||||
proxy.get_disk_devices.side_effect = lambda **kw: list((config if kw.get("config") else live)[0])
|
||||
proxy.get_media_devices.side_effect = lambda **kw: list((config if kw.get("config") else live)[1])
|
||||
proxy.get_disk_bus_types.return_value = ["virtio", "sata", "scsi"]
|
||||
proxy.get_disk_bus_types.return_value = ["virtio", "sata", "scsi", "usb"]
|
||||
proxy.get_iso_path.side_effect = lambda image: f"/iso/{image}"
|
||||
proxy.get_cache_modes.return_value = {"default": "", "none": ""}
|
||||
proxy.get_machine_type.return_value = "q35"
|
||||
proxy.get_status.return_value = status
|
||||
|
|
@ -39,14 +40,14 @@ class NewDiskNameTestCase(TestCase):
|
|||
storage.return_value.get_volume_type.return_value = "file"
|
||||
storage.return_value.get_volume_format_type.return_value = "qcow2"
|
||||
create.return_value.create_volume.return_value = "/pool/data.qcow2"
|
||||
self.client.post(reverse(f"instances:{view}", args=[self.instance.id]), data)
|
||||
proxy.attach_disk.assert_called_once()
|
||||
self.response = self.client.post(reverse(f"instances:{view}", args=[self.instance.id]), data, follow=True)
|
||||
self.proxy = proxy
|
||||
return proxy.attach_disk.call_args
|
||||
|
||||
VIEWS = (
|
||||
("add_new_vol", {"storage": "default", "name": "data", "format": "qcow2", "size": "1", "cache": "default"}),
|
||||
("add_existing_vol", {"selected_storage": "default", "vols": "data.qcow2", "cache": "default"}),
|
||||
("add_cdrom", {}),
|
||||
("add_new_vol", {"storage": "default", "name": "data", "format": "qcow2", "size": "1", "cache": "default"}, 1),
|
||||
("add_existing_vol", {"selected_storage": "default", "vols": "data.qcow2", "cache": "default"}, 1),
|
||||
("add_cdrom", {}, 5), # shut off: a running VM takes USB and SCSI CD-ROMs only
|
||||
)
|
||||
|
||||
def test_a_name_either_definition_uses_is_not_given_again(self):
|
||||
|
|
@ -58,12 +59,28 @@ class NewDiskNameTestCase(TestCase):
|
|||
("virtio", ([vda, dev("vdb", "virtio")], []), ([vda], []), "vdc"), # not yet released by the guest
|
||||
("virtio", ([vda], []), ([vda], []), "vdb"), # both the same, as on a stopped VM
|
||||
)
|
||||
for view, data in self.VIEWS:
|
||||
for view, data, status in self.VIEWS:
|
||||
for bus, live, config, expected in cases:
|
||||
if view == "add_cdrom" and bus == "virtio": # no virtio CD-ROM
|
||||
continue
|
||||
with self.subTest(view=view, bus=bus, expected=expected):
|
||||
self.assertEqual(self.attach(view, {**data, "bus": bus}, live, config).args[0], expected)
|
||||
call = self.attach(view, {**data, "bus": bus}, live, config, status=status)
|
||||
self.assertEqual(call.args[0], expected)
|
||||
|
||||
def test_a_cdrom_of_a_running_vm_is_on_the_bus_that_can_be_hotplugged(self):
|
||||
for status, bus in ((1, "scsi"), (3, "scsi"), (5, "sata")): # running, paused, shut off
|
||||
def test_a_cdrom_of_a_running_vm_is_on_a_bus_that_can_be_hotplugged(self):
|
||||
# running, paused: USB first, which every guest sees; shut off: SATA
|
||||
for status, bus in ((1, "usb"), (3, "usb"), (5, "sata")):
|
||||
with self.subTest(status=status):
|
||||
self.assertEqual(self.attach("add_cdrom", {}, status=status).kwargs["target_bus"], bus)
|
||||
call = self.attach("add_cdrom", {"media": "virtio-win.iso"}, status=status)
|
||||
self.assertEqual((call.kwargs["target_bus"], call.args[1]), (bus, "/iso/virtio-win.iso"))
|
||||
|
||||
def test_a_running_vm_refuses_a_sata_cdrom_and_a_usb_one_without_media(self):
|
||||
for data in ({"bus": "sata", "media": "virtio-win.iso"}, {"bus": "usb", "media": ""}):
|
||||
with self.subTest(data):
|
||||
self.attach("add_cdrom", data, status=1)
|
||||
self.proxy.attach_disk.assert_not_called()
|
||||
self.assertTrue(list(self.response.context["messages"]))
|
||||
|
||||
def test_a_cdrom_without_media_is_empty(self):
|
||||
call = self.attach("add_cdrom", {"bus": "scsi", "media": ""}, status=1)
|
||||
self.assertEqual((call.kwargs["target_bus"], call.args[1]), ("scsi", ""))
|
||||
|
|
|
|||
|
|
@ -307,6 +307,7 @@ def _instance_page(request, pk, instance, compute):
|
|||
vcpu_host = len(instance.vcpu_range)
|
||||
memory_host = instance.proxy.get_max_memory()
|
||||
bus_host = instance.proxy.get_disk_bus_types(instance.arch, instance.machine)
|
||||
cdrom_buses = cdrom_bus_choices(instance)
|
||||
networks_host = sorted(instance.proxy.get_networks())
|
||||
interfaces_host = sorted(instance.proxy.get_ifaces())
|
||||
nwfilters_host = instance.proxy.get_nwfilters()
|
||||
|
|
@ -1575,31 +1576,49 @@ def detach_vol(request, pk):
|
|||
@serialize_instance_mutation
|
||||
def add_cdrom(request, pk):
|
||||
instance = get_instance(request.user, pk, perm_type="change")
|
||||
if instance.status == 5:
|
||||
default_bus = "ide" if instance.machine == "pc" else "sata"
|
||||
else: # IDE and SATA drives cannot be plugged into a running VM, SCSI ones can
|
||||
default_bus = "scsi"
|
||||
bus = request.POST.get("bus", default_bus)
|
||||
invalid = invalid_disk_options(instance, bus=bus)
|
||||
if invalid:
|
||||
return reject_disk_options(request, pk, invalid)
|
||||
buses = cdrom_bus_choices(instance)
|
||||
bus = request.POST.get("bus", buses[0] if buses else "")
|
||||
image = request.POST.get("media", "")
|
||||
if bus not in buses:
|
||||
messages.error(request, _("This VM cannot take a CD-ROM on the %(bus)s bus now") % {"bus": bus})
|
||||
return _back(request, pk, "disks")
|
||||
if bus == "usb" and not image:
|
||||
messages.error(request, _("A USB CD-ROM needs an ISO image: libvirt has no empty USB drive"))
|
||||
return _back(request, pk, "disks")
|
||||
|
||||
target = utils.get_new_disk_dev(
|
||||
instance.media + instance.config_media, instance.disks + instance.config_disks, bus
|
||||
)
|
||||
with audit_vm(request, instance, f"add CD-ROM {target}"):
|
||||
instance.proxy.attach_disk(
|
||||
target,
|
||||
"",
|
||||
disk_device="cdrom",
|
||||
cache_mode="none",
|
||||
target_bus=bus,
|
||||
readonly=True,
|
||||
)
|
||||
try:
|
||||
with audit_vm(request, instance, f"add CD-ROM {target}" + (f" with {image}" if image else "")):
|
||||
instance.proxy.attach_disk(
|
||||
target,
|
||||
instance.proxy.get_iso_path(image) if image else "",
|
||||
disk_device="cdrom",
|
||||
cache_mode="none",
|
||||
target_bus=bus,
|
||||
readonly=True,
|
||||
)
|
||||
except (libvirtError, util.OperationError) as err:
|
||||
messages.error(request, err)
|
||||
|
||||
return _back(request, pk, "disks")
|
||||
|
||||
|
||||
def cdrom_bus_choices(instance):
|
||||
"""The buses a CD-ROM can be added on now, the default first. A running VM
|
||||
takes USB and SCSI drives only; Windows sees USB, SATA and IDE ones
|
||||
without a driver."""
|
||||
if instance.status != 5:
|
||||
order = ("usb", "scsi")
|
||||
elif instance.machine == "pc":
|
||||
order = ("ide", "sata", "scsi", "usb")
|
||||
else:
|
||||
order = ("sata", "scsi", "usb")
|
||||
offered = instance.proxy.get_disk_bus_types(instance.arch, instance.machine)
|
||||
return [bus for bus in order if bus in offered]
|
||||
|
||||
|
||||
@require_POST
|
||||
@superuser_only
|
||||
@serialize_instance_mutation
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -11,7 +11,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-11-01 10:56+0000\n"
|
||||
"POT-Creation-Date: 2026-11-01 13:18+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/"
|
||||
|
|
@ -271,6 +271,7 @@ msgstr "Parola Değiştir"
|
|||
#: admin/templates/admin/user_form.html:137
|
||||
#: computes/templates/computes/form.html:45
|
||||
#: console/templates/console-vnc.html:86
|
||||
#: instances/templates/add_instance_cdrom.html:38
|
||||
#: instances/templates/add_instance_network_block.html:55
|
||||
#: instances/templates/add_instance_owner_block.html:29
|
||||
#: instances/templates/add_instance_volume.html:108
|
||||
|
|
@ -504,6 +505,7 @@ msgid "Add key to user form"
|
|||
msgstr "Kullanıcıya anahtar ekleme formu"
|
||||
|
||||
#: accounts/templates/profile.html:55
|
||||
#: instances/templates/add_instance_cdrom.html:39
|
||||
#: instances/templates/add_instance_network_block.html:56
|
||||
#: instances/templates/add_instance_owner_block.html:30
|
||||
#: instances/templates/create_flavors.html:20
|
||||
|
|
@ -2465,6 +2467,7 @@ msgid "Connect"
|
|||
msgstr "Bağlan"
|
||||
|
||||
#: console/templates/console-vnc.html:98
|
||||
#: instances/templates/add_instance_cdrom.html:10
|
||||
#: instances/templates/add_instance_network_block.html:11
|
||||
#: instances/templates/add_instance_owner_block.html:11
|
||||
#: instances/templates/add_instance_volume.html:15
|
||||
|
|
@ -2728,7 +2731,7 @@ msgstr "libvirt diskleri hâlâ kopyalıyor"
|
|||
msgid "Create VM"
|
||||
msgstr "Sanal makine oluştur"
|
||||
|
||||
#: instances/jobs.py:685 instances/views.py:2408
|
||||
#: instances/jobs.py:685 instances/views.py:2427
|
||||
msgid "A virtual machine with this name already exists"
|
||||
msgstr "Bu isimde bir sanal makine mevcut"
|
||||
|
||||
|
|
@ -2865,7 +2868,7 @@ msgid "Disk"
|
|||
msgstr "Disk"
|
||||
|
||||
#: instances/models.py:223 instances/templates/create_instance_w2.html:309
|
||||
#: instances/templates/instances/settings_tab.html:167
|
||||
#: instances/templates/instances/settings_tab.html:165
|
||||
msgid "CD-ROM"
|
||||
msgstr "CD-ROM"
|
||||
|
||||
|
|
@ -2946,6 +2949,45 @@ msgstr "Çöktü"
|
|||
msgid "PM suspended"
|
||||
msgstr "Güç yönetimiyle askıya alındı"
|
||||
|
||||
#: instances/templates/add_instance_cdrom.html:3
|
||||
#: instances/templates/add_instance_cdrom.html:9
|
||||
msgid "Add CD-ROM"
|
||||
msgstr "CD-ROM Ekle"
|
||||
|
||||
#: instances/templates/add_instance_cdrom.html:7
|
||||
msgid "Add CD-ROM form"
|
||||
msgstr "CD-ROM ekleme formu"
|
||||
|
||||
#: instances/templates/add_instance_cdrom.html:15
|
||||
#: instances/templates/add_instance_volume.html:90
|
||||
#: instances/templates/create_instance_w2.html:181
|
||||
#: instances/templates/instances/edit_instance_volume.html:82
|
||||
#: instances/templates/instances/edit_instance_volume.html:87
|
||||
msgid "Bus"
|
||||
msgstr "Veriyolu"
|
||||
|
||||
#: instances/templates/add_instance_cdrom.html:23
|
||||
#: instances/templates/instances/settings_tab.html:179
|
||||
msgid "ISO image"
|
||||
msgstr "ISO imajı"
|
||||
|
||||
#: instances/templates/add_instance_cdrom.html:28
|
||||
#: instances/templates/instances/settings_tab.html:166
|
||||
msgid "No media"
|
||||
msgstr "Ortam yok"
|
||||
|
||||
#: instances/templates/add_instance_cdrom.html:32
|
||||
msgid ""
|
||||
"Windows sees USB, SATA and IDE drives without a driver; SCSI ones need the "
|
||||
"virtio driver."
|
||||
msgstr "Windows USB, SATA ve IDE sürücüleri sürücü yazılımı olmadan görür; SCSI olanlar için virtio sürücüsü gerekir."
|
||||
|
||||
#: instances/templates/add_instance_cdrom.html:33
|
||||
msgid ""
|
||||
"A running VM takes USB and SCSI drives. A USB drive needs an ISO image, is "
|
||||
"detached instead of ejected, and needs a QEMU with usb-bot (not RHEL 9's)."
|
||||
msgstr "Çalışan bir sanal makineye USB ve SCSI sürücüler eklenebilir. USB sürücü bir ISO imajı ister, çıkarılmaz, ayrılır ve usb-bot destekli bir QEMU gerektirir (RHEL 9'unki desteklemez)."
|
||||
|
||||
#: instances/templates/add_instance_network_block.html:4
|
||||
#: instances/templates/add_instance_network_block.html:10
|
||||
msgid "Add network device"
|
||||
|
|
@ -3016,7 +3058,7 @@ msgid "Disk source"
|
|||
msgstr "Disk kaynağı"
|
||||
|
||||
#: instances/templates/add_instance_volume.html:21
|
||||
#: instances/templates/create_instance_w2.html:131 instances/views.py:2427
|
||||
#: instances/templates/create_instance_w2.html:131 instances/views.py:2446
|
||||
msgid "New disk"
|
||||
msgstr "Yeni disk"
|
||||
|
||||
|
|
@ -3076,13 +3118,6 @@ msgstr "Birim"
|
|||
msgid "Choose a pool first"
|
||||
msgstr "Önce bir havuz seçin"
|
||||
|
||||
#: instances/templates/add_instance_volume.html:90
|
||||
#: instances/templates/create_instance_w2.html:181
|
||||
#: instances/templates/instances/edit_instance_volume.html:82
|
||||
#: instances/templates/instances/edit_instance_volume.html:87
|
||||
msgid "Bus"
|
||||
msgstr "Veriyolu"
|
||||
|
||||
#: instances/templates/add_instance_volume.html:98
|
||||
#: instances/templates/instances/edit_instance_volume.html:45
|
||||
msgid "Cache mode"
|
||||
|
|
@ -3385,7 +3420,7 @@ msgstr "Özel CPU modelleri"
|
|||
msgid "Size (GiB)"
|
||||
msgstr "Boyut (GiB)"
|
||||
|
||||
#: instances/templates/create_instance_w2.html:158 instances/views.py:2428
|
||||
#: instances/templates/create_instance_w2.html:158 instances/views.py:2447
|
||||
msgid "Existing volumes"
|
||||
msgstr "Mevcut birimler"
|
||||
|
||||
|
|
@ -3420,7 +3455,7 @@ msgstr "Aygıt"
|
|||
msgid "Remove"
|
||||
msgstr "Kaldır"
|
||||
|
||||
#: instances/templates/create_instance_w2.html:191 instances/views.py:2429
|
||||
#: instances/templates/create_instance_w2.html:191 instances/views.py:2448
|
||||
msgid "Clone from template"
|
||||
msgstr "Şablondan klonla"
|
||||
|
||||
|
|
@ -3755,7 +3790,7 @@ msgstr ""
|
|||
msgid "Start the VM to open its console."
|
||||
msgstr "Konsolunu açmak için sanal makineyi başlatın."
|
||||
|
||||
#: instances/templates/instances/access_tab.html:41 instances/views.py:1075
|
||||
#: instances/templates/instances/access_tab.html:41 instances/views.py:1076
|
||||
msgid "Reset root password"
|
||||
msgstr "Root parolasını sıfırla"
|
||||
|
||||
|
|
@ -4538,30 +4573,15 @@ msgstr "Sırayı uygula"
|
|||
|
||||
#: instances/templates/instances/settings_tab.html:150
|
||||
msgid ""
|
||||
"The VM is running: CD-ROM drives added now use the SCSI bus. Shut it down to "
|
||||
"detach other CD-ROM drives, or to detach or delete disks."
|
||||
msgstr ""
|
||||
"Sanal makine çalışıyor: şimdi eklenen CD-ROM sürücüleri SCSI veri yolunu "
|
||||
"kullanır. Diğer CD-ROM sürücülerini ayırmak ya da diskleri ayırmak veya "
|
||||
"silmek için sanal makineyi kapatın."
|
||||
"The VM is running: CD-ROM drives added now use the USB or SCSI bus. Shut it "
|
||||
"down to detach a SATA or IDE CD-ROM drive, or to detach or delete disks."
|
||||
msgstr "Sanal makine çalışıyor: şimdi eklenen CD-ROM sürücüleri USB veya SCSI veri yolunu kullanır. SATA veya IDE bir CD-ROM sürücüsünü ayırmak ya da diskleri ayırmak veya silmek için sanal makineyi kapatın."
|
||||
|
||||
#: instances/templates/instances/settings_tab.html:154
|
||||
msgid "Removable media"
|
||||
msgstr "Çıkarılabilir ortam"
|
||||
|
||||
#: instances/templates/instances/settings_tab.html:155
|
||||
msgid "Add CD-ROM form"
|
||||
msgstr "CD-ROM ekleme formu"
|
||||
|
||||
#: instances/templates/instances/settings_tab.html:156
|
||||
msgid "Add CD-ROM"
|
||||
msgstr "CD-ROM Ekle"
|
||||
|
||||
#: instances/templates/instances/settings_tab.html:168
|
||||
msgid "No media"
|
||||
msgstr "Ortam yok"
|
||||
|
||||
#: instances/templates/instances/settings_tab.html:172
|
||||
#: instances/templates/instances/settings_tab.html:170
|
||||
#: instances/templates/instances/settings_tab.html:249
|
||||
msgid "Detach"
|
||||
msgstr "Ayır"
|
||||
|
|
@ -4570,10 +4590,6 @@ msgstr "Ayır"
|
|||
msgid "Unmount"
|
||||
msgstr "Ayır"
|
||||
|
||||
#: instances/templates/instances/settings_tab.html:179
|
||||
msgid "ISO image"
|
||||
msgstr "ISO imajı"
|
||||
|
||||
#: instances/templates/instances/settings_tab.html:191
|
||||
msgid "Mount"
|
||||
msgstr "Bağla"
|
||||
|
|
@ -5542,16 +5558,16 @@ msgstr "'%(name)s' sanal makinesinin sunucusuna şu anda erişilemiyor."
|
|||
msgid " Jobs on it can be followed under Jobs in the menu."
|
||||
msgstr " Üzerindeki işler menüdeki İşler bölümünden izlenebilir."
|
||||
|
||||
#: instances/views.py:333
|
||||
#: instances/views.py:334
|
||||
msgid "There is no other host to migrate to."
|
||||
msgstr "Taşınacak başka bir sunucu yok."
|
||||
|
||||
#: instances/views.py:335
|
||||
#: instances/views.py:336
|
||||
msgid "A VM migrates when it is running, paused or shut off."
|
||||
msgstr ""
|
||||
"Sanal makine çalışırken, duraklatılmışken ya da kapalıyken taşınabilir."
|
||||
|
||||
#: instances/views.py:337
|
||||
#: instances/views.py:338
|
||||
msgid ""
|
||||
"A VM with snapshots cannot be migrated: its snapshots stay on this host. "
|
||||
"Delete them first."
|
||||
|
|
@ -5559,7 +5575,7 @@ msgstr ""
|
|||
"Anlık görüntüsü olan bir sanal makine taşınamaz: anlık görüntüleri bu "
|
||||
"sunucuda kalır. Önce onları silin."
|
||||
|
||||
#: instances/views.py:339
|
||||
#: instances/views.py:340
|
||||
msgid ""
|
||||
"A VM with host devices cannot be migrated: the destination may not have "
|
||||
"them. Remove them first."
|
||||
|
|
@ -5567,11 +5583,11 @@ msgstr ""
|
|||
"Sunucu aygıtları olan bir sanal makine taşınamaz: hedefte bu aygıtlar "
|
||||
"olmayabilir. Önce onları kaldırın."
|
||||
|
||||
#: instances/views.py:605
|
||||
#: instances/views.py:606
|
||||
msgid "The VM was moved meanwhile; try again."
|
||||
msgstr "Sanal makine bu arada taşındı; yeniden deneyin."
|
||||
|
||||
#: instances/views.py:636
|
||||
#: instances/views.py:637
|
||||
msgid ""
|
||||
"The quota cannot be checked because a host of your virtual machines cannot "
|
||||
"be reached. Nothing was changed."
|
||||
|
|
@ -5579,7 +5595,7 @@ msgstr ""
|
|||
"Sanal makinelerinizin bir sunucusuna erişilemediği için kota denetlenemiyor. "
|
||||
"Hiçbir şey değiştirilmedi."
|
||||
|
||||
#: instances/views.py:717
|
||||
#: instances/views.py:718
|
||||
msgid ""
|
||||
"The running VM has no free PCI slot for another disk on this bus: choose the "
|
||||
"scsi bus if the VM has a SCSI controller, or shut the VM down and add the "
|
||||
|
|
@ -5592,7 +5608,7 @@ msgstr ""
|
|||
"yuvaları ekle, sonraki başlatmadan itibaren ona boş yuvalar verir. Yeni bir "
|
||||
"birim havuzunda kalır, mevcut birim olarak eklenebilir."
|
||||
|
||||
#: instances/views.py:721
|
||||
#: instances/views.py:722
|
||||
msgid ""
|
||||
"The running VM has no free PCI slot for the SCSI controller the disk needs: "
|
||||
"shut the VM down and add the disk then; Add PCIe slots on the Disks tab "
|
||||
|
|
@ -5604,82 +5620,82 @@ msgstr ""
|
|||
"PCIe yuvaları ekle, sonraki başlatmadan itibaren ona boş yuvalar verir. Yeni "
|
||||
"bir birim havuzunda kalır, mevcut birim olarak eklenebilir."
|
||||
|
||||
#: instances/views.py:739
|
||||
#: instances/views.py:740
|
||||
#, python-format
|
||||
msgid "Invalid disk options: %(options)s"
|
||||
msgstr "Geçersiz disk seçenekleri: %(options)s"
|
||||
|
||||
#: instances/views.py:749 instances/views.py:764
|
||||
#: instances/views.py:750 instances/views.py:765
|
||||
msgid "Templates cannot be started."
|
||||
msgstr "Şablon makineler başlatılamaz."
|
||||
|
||||
#: instances/views.py:860
|
||||
#: instances/views.py:861
|
||||
#, python-format
|
||||
msgid "Disk %(path)s was kept: a disk file that stays needs it"
|
||||
msgstr "%(path)s diski korundu: kalan bir disk dosyası ona ihtiyaç duyuyor"
|
||||
|
||||
#: instances/views.py:866
|
||||
#: instances/views.py:867
|
||||
#, python-format
|
||||
msgid "The VM is removed, but disk %(path)s was not deleted: %(err)s"
|
||||
msgstr "Sanal makine kaldırıldı, ancak %(path)s diski silinmedi: %(err)s"
|
||||
|
||||
#: instances/views.py:875
|
||||
#: instances/views.py:876
|
||||
#, python-format
|
||||
msgid "Disk %(path)s is used by another VM and was kept"
|
||||
msgstr ""
|
||||
"%(path)s diski başka bir sanal makine tarafından kullanılıyor ve korundu"
|
||||
|
||||
#: instances/views.py:997
|
||||
#: instances/views.py:998
|
||||
#, python-format
|
||||
msgid "Set the gstfsd key of %(compute)s first (Computes, edit the host)"
|
||||
msgstr ""
|
||||
"Önce %(compute)s sunucusunun gstfsd anahtarını ayarlayın (Sunucular, "
|
||||
"sunucuyu düzenle)"
|
||||
|
||||
#: instances/views.py:1003 instances/views.py:1017 instances/views.py:1026
|
||||
#: instances/views.py:1004 instances/views.py:1018 instances/views.py:1027
|
||||
#, python-format
|
||||
msgid "gstfsd error: %(err)s"
|
||||
msgstr "gstfsd hatası: %(err)s"
|
||||
|
||||
#: instances/views.py:1027
|
||||
#: instances/views.py:1028
|
||||
msgid "the reply is not signed with the key"
|
||||
msgstr "yanıt anahtarla imzalanmamış"
|
||||
|
||||
#: instances/views.py:1035
|
||||
#: instances/views.py:1036
|
||||
msgid "Shut the VM down, or start its QEMU guest agent, and try again"
|
||||
msgstr ""
|
||||
"Sanal makineyi kapatın ya da QEMU konuk ajanını başlatın ve yeniden deneyin"
|
||||
|
||||
#: instances/views.py:1048
|
||||
#: instances/views.py:1049
|
||||
msgid "The change may still be made when the agent answers again."
|
||||
msgstr "Ajan yeniden yanıt verdiğinde değişiklik yine de yapılabilir."
|
||||
|
||||
#: instances/views.py:1079
|
||||
#: instances/views.py:1080
|
||||
msgid "Enter a password"
|
||||
msgstr "Bir parola girin"
|
||||
|
||||
#: instances/views.py:1093
|
||||
#: instances/views.py:1094
|
||||
msgid "Select an SSH public key"
|
||||
msgstr "Bir SSH açık anahtarı seçin"
|
||||
|
||||
#: instances/views.py:1115
|
||||
#: instances/views.py:1116
|
||||
#, python-format
|
||||
msgid "Installed new SSH public key %(keyname)s"
|
||||
msgstr "Yeni %(keyname)s SSH açık anahtarı yüklendi"
|
||||
|
||||
#: instances/views.py:1135
|
||||
#: instances/views.py:1136
|
||||
msgid "Enter a whole number of vCPUs"
|
||||
msgstr "vCPU sayısı için bir tam sayı girin"
|
||||
|
||||
#: instances/views.py:1139
|
||||
#: instances/views.py:1140
|
||||
msgid "Shut off the VM to change its vCPUs"
|
||||
msgstr "vCPU'larını değiştirmek için sanal makineyi kapatın"
|
||||
|
||||
#: instances/views.py:1142
|
||||
#: instances/views.py:1143
|
||||
msgid "The current vCPUs cannot be more than the maximum"
|
||||
msgstr "Geçerli vCPU sayısı en fazla değerden büyük olamaz"
|
||||
|
||||
#: instances/views.py:1150
|
||||
#: instances/views.py:1151
|
||||
#, python-format
|
||||
msgid ""
|
||||
"User %(quota_msg)s quota reached, cannot resize CPU of '%(instance_name)s'!"
|
||||
|
|
@ -5687,20 +5703,20 @@ msgstr ""
|
|||
"%(quota_msg)s kullanıcısı kotası doldu, '%(instance_name)s' in CPU su "
|
||||
"yeniden boyutlandırılamıyor!"
|
||||
|
||||
#: instances/views.py:1161
|
||||
#: instances/views.py:1162
|
||||
#, python-format
|
||||
msgid "vCPUs set to %(cur)s (maximum %(max)s)"
|
||||
msgstr "vCPU sayısı %(cur)s olarak ayarlandı (en fazla %(max)s)"
|
||||
|
||||
#: instances/views.py:1180
|
||||
#: instances/views.py:1181
|
||||
msgid "Enter a whole number for memory"
|
||||
msgstr "Bellek için bir tam sayı girin"
|
||||
|
||||
#: instances/views.py:1183
|
||||
#: instances/views.py:1184
|
||||
msgid "The current memory cannot be more than the maximum"
|
||||
msgstr "Geçerli bellek en fazla değerden büyük olamaz"
|
||||
|
||||
#: instances/views.py:1188
|
||||
#: instances/views.py:1189
|
||||
#, python-format
|
||||
msgid ""
|
||||
"User %(quota_msg)s quota reached, cannot resize memory of "
|
||||
|
|
@ -5709,25 +5725,25 @@ msgstr ""
|
|||
"%(quota_msg)s kullanıcı kotası doldu, '%(instance_name)s' in belleği yeniden "
|
||||
"boyutlandırılamıyor!"
|
||||
|
||||
#: instances/views.py:1197
|
||||
#: instances/views.py:1198
|
||||
#, python-format
|
||||
msgid "Memory set to %(cur)s MiB (maximum %(max)s MiB)"
|
||||
msgstr "Bellek %(cur)s MiB olarak ayarlandı (en fazla %(max)s MiB)"
|
||||
|
||||
#: instances/views.py:1217
|
||||
#: instances/views.py:1218
|
||||
msgid "Enter disk sizes as whole GiB"
|
||||
msgstr "Disk boyutlarını tam GiB olarak girin"
|
||||
|
||||
#: instances/views.py:1221
|
||||
#: instances/views.py:1222
|
||||
#, python-format
|
||||
msgid "%(dev)s is %(size)s: a disk cannot shrink"
|
||||
msgstr "%(dev)s boyutu %(size)s: disk küçültülemez"
|
||||
|
||||
#: instances/views.py:1229
|
||||
#: instances/views.py:1230
|
||||
msgid "No disks were selected or valid for resizing."
|
||||
msgstr "Boyutlandırma için seçilmiş ya da geçerli disk yok."
|
||||
|
||||
#: instances/views.py:1239
|
||||
#: instances/views.py:1240
|
||||
#, python-format
|
||||
msgid ""
|
||||
"User %(quota_msg)s quota reached, cannot resize disks of '%(instance_name)s'!"
|
||||
|
|
@ -5735,61 +5751,61 @@ msgstr ""
|
|||
"%(quota_msg)s kullanıcı kotası doldu, '%(instance_name)s' in diski yeniden "
|
||||
"boyutlandırılamıyor!"
|
||||
|
||||
#: instances/views.py:1254
|
||||
#: instances/views.py:1255
|
||||
#, python-format
|
||||
msgid "The storage pool of %(dev)s cannot resize its volumes"
|
||||
msgstr "%(dev)s diskinin depolama havuzu birimlerini boyutlandıramaz"
|
||||
|
||||
#: instances/views.py:1256
|
||||
#: instances/views.py:1257
|
||||
#, python-format
|
||||
msgid "Disk is resized: %(dev)s"
|
||||
msgstr "Disk boyutu değiştirildi: %(dev)s"
|
||||
|
||||
#: instances/views.py:1350
|
||||
#: instances/views.py:1351
|
||||
msgid "The VM's machine has no PCIe slots to add"
|
||||
msgstr "Sanal makinenin makine tipinde eklenecek PCIe yuvası yok"
|
||||
|
||||
#: instances/views.py:1355
|
||||
#: instances/views.py:1356
|
||||
#, python-format
|
||||
msgid "%(count)s PCIe slots added"
|
||||
msgstr "%(count)s PCIe yuvası eklendi"
|
||||
|
||||
#: instances/views.py:1357
|
||||
#: instances/views.py:1358
|
||||
#, python-format
|
||||
msgid "%(count)s PCIe slots added: the VM gets them at its next start"
|
||||
msgstr ""
|
||||
"%(count)s PCIe yuvası eklendi: sanal makine bunları sonraki başlatmasında "
|
||||
"alır"
|
||||
|
||||
#: instances/views.py:1488
|
||||
#: instances/views.py:1489
|
||||
msgid "Volume changes are applied. But it will be activated after shutdown"
|
||||
msgstr ""
|
||||
"Birim değişiklikleri uygulandı. Ama yeniden başlatıldıktan sonra uygulanacak"
|
||||
|
||||
#: instances/views.py:1493
|
||||
#: instances/views.py:1494
|
||||
msgid "Volume is changed successfully."
|
||||
msgstr "Birim başarıyla değiştirildi."
|
||||
|
||||
#: instances/views.py:1511
|
||||
#: instances/views.py:1512
|
||||
#, python-format
|
||||
msgid "Disk %(dev)s is not a storage volume of this instance"
|
||||
msgstr "%(dev)s diski bu sanal makinenin bir depolama birimi değil"
|
||||
|
||||
#: instances/views.py:1518
|
||||
#: instances/views.py:1519
|
||||
#, python-format
|
||||
msgid "Disk %(dev)s has a pending change; delete it once the VM is shut down"
|
||||
msgstr ""
|
||||
"%(dev)s diskinin bekleyen bir değişikliği var; sanal makine kapatıldığında "
|
||||
"silin"
|
||||
|
||||
#: instances/views.py:1533
|
||||
#: instances/views.py:1534
|
||||
#, python-format
|
||||
msgid "Volume %(vol)s is used by another VM; detach it instead"
|
||||
msgstr ""
|
||||
"%(vol)s birimi başka bir sanal makine tarafından kullanılıyor; onun yerine "
|
||||
"ayırın"
|
||||
|
||||
#: instances/views.py:1545
|
||||
#: instances/views.py:1546
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The guest has not released disk %(dev)s yet; volume %(vol)s was kept. Delete "
|
||||
|
|
@ -5798,43 +5814,52 @@ msgstr ""
|
|||
"Konuk sistem %(dev)s diskini henüz bırakmadı; %(vol)s birimi korundu. Sanal "
|
||||
"makine kapatıldığında depolama havuzundan silin."
|
||||
|
||||
#: instances/views.py:1556
|
||||
#: instances/views.py:1557
|
||||
#, python-format
|
||||
msgid "Disk %(dev)s was detached, but its volume was kept: %(err)s"
|
||||
msgstr "%(dev)s diski ayrıldı, ancak birimi korundu: %(err)s"
|
||||
|
||||
#: instances/views.py:1660
|
||||
#: instances/views.py:1583
|
||||
#, python-format
|
||||
msgid "This VM cannot take a CD-ROM on the %(bus)s bus now"
|
||||
msgstr "Bu sanal makineye şu anda %(bus)s veri yolunda CD-ROM eklenemez"
|
||||
|
||||
#: instances/views.py:1586
|
||||
msgid "A USB CD-ROM needs an ISO image: libvirt has no empty USB drive"
|
||||
msgstr "USB CD-ROM bir ISO imajı ister: libvirt boş USB sürücü desteklemiyor"
|
||||
|
||||
#: instances/views.py:1679
|
||||
#, python-format
|
||||
msgid "Snapshot was not deleted: %(err)s"
|
||||
msgstr "Anlık görüntü silinmedi: %(err)s"
|
||||
|
||||
#: instances/views.py:1775
|
||||
#: instances/views.py:1794
|
||||
msgid "Check at least one device to boot from."
|
||||
msgstr "Önyükleme için en az bir aygıt işaretleyin."
|
||||
|
||||
#: instances/views.py:1789
|
||||
#: instances/views.py:1808
|
||||
msgid "Boot order changed. It applies at the next start."
|
||||
msgstr "Ön yükleme sırası değiştirildi. Sonraki başlatmada uygulanır."
|
||||
|
||||
#: instances/views.py:1791
|
||||
#: instances/views.py:1810
|
||||
msgid "Boot order changed successfully."
|
||||
msgstr "Ön yükleme sırası başarıyla değiştirildi."
|
||||
|
||||
#: instances/views.py:1811
|
||||
#: instances/views.py:1830
|
||||
msgid "The XML is empty"
|
||||
msgstr "XML boş"
|
||||
|
||||
#: instances/views.py:1815 instances/views.py:2418
|
||||
#: instances/views.py:1834 instances/views.py:2437
|
||||
#, python-format
|
||||
msgid "The XML is not well-formed: %(error)s"
|
||||
msgstr "XML düzgün biçimlendirilmemiş: %(error)s"
|
||||
|
||||
#: instances/views.py:1817
|
||||
#: instances/views.py:1836
|
||||
#, python-format
|
||||
msgid "The XML must keep the VM's UUID %(uuid)s."
|
||||
msgstr "XML, sanal makinenin %(uuid)s UUID'sini korumalıdır."
|
||||
|
||||
#: instances/views.py:1821
|
||||
#: instances/views.py:1840
|
||||
msgid ""
|
||||
"The definition has changed since the editor was opened. Reload the page to "
|
||||
"edit the current one."
|
||||
|
|
@ -5842,35 +5867,35 @@ msgstr ""
|
|||
"Düzenleyici açıldığından beri tanım değişti. Geçerli tanımı düzenlemek için "
|
||||
"sayfayı yeniden yükleyin."
|
||||
|
||||
#: instances/views.py:1833
|
||||
#: instances/views.py:1852
|
||||
msgid "The XML definition was saved."
|
||||
msgstr "XML tanımı kaydedildi."
|
||||
|
||||
#: instances/views.py:1835
|
||||
#: instances/views.py:1854
|
||||
msgid "The XML definition was saved; the VM uses it from its next start."
|
||||
msgstr ""
|
||||
"XML tanımı kaydedildi; sanal makine onu sonraki başlatmasından itibaren "
|
||||
"kullanır."
|
||||
|
||||
#: instances/views.py:1902
|
||||
#: instances/views.py:1921
|
||||
msgid "Select one network interface to change"
|
||||
msgstr "Değiştirilecek bir ağ arabirimi seçin"
|
||||
|
||||
#: instances/views.py:1940
|
||||
#: instances/views.py:1959
|
||||
msgid "Network Device Config is changed. Please shutdown instance to activate."
|
||||
msgstr ""
|
||||
"Ağ aygıtı yapılandırması değiştirildi. Aktifleştirmek için lütfen sanal "
|
||||
"makineyi kapatın."
|
||||
|
||||
#: instances/views.py:1942
|
||||
#: instances/views.py:1961
|
||||
msgid "Network device changed"
|
||||
msgstr "Ağ aygıtı değiştirildi"
|
||||
|
||||
#: instances/views.py:1954
|
||||
#: instances/views.py:1973
|
||||
msgid "No network selected"
|
||||
msgstr "Ağ seçilmedi"
|
||||
|
||||
#: instances/views.py:1974
|
||||
#: instances/views.py:1993
|
||||
msgid ""
|
||||
"The running VM has no free PCI slot for another network device: shut it down "
|
||||
"and add the device then; Add PCIe slots on the Disks tab gives it free ones "
|
||||
|
|
@ -5880,21 +5905,21 @@ msgstr ""
|
|||
"aygıtı sonra ekleyin; Diskler sekmesindeki PCIe yuvaları ekle, sonraki "
|
||||
"başlatmadan itibaren ona boş yuvalar verir."
|
||||
|
||||
#: instances/views.py:2011 instances/views.py:2017
|
||||
#: instances/views.py:2030 instances/views.py:2036
|
||||
msgid "The VM has it"
|
||||
msgstr "Sanal makinede var"
|
||||
|
||||
#: instances/views.py:2048
|
||||
#: instances/views.py:2067
|
||||
#, python-format
|
||||
msgid "The host has no USB device %(device)s"
|
||||
msgstr "Sunucuda %(device)s USB aygıtı yok"
|
||||
|
||||
#: instances/views.py:2069
|
||||
#: instances/views.py:2088
|
||||
#, python-format
|
||||
msgid "The host has no PCI device %(device)s"
|
||||
msgstr "Sunucuda %(device)s PCI aygıtı yok"
|
||||
|
||||
#: instances/views.py:2087
|
||||
#: instances/views.py:2106
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Removal of PCI device %(address)s requested: the guest has not let it go "
|
||||
|
|
@ -5904,20 +5929,20 @@ msgstr ""
|
|||
"bırakmadı; bırakana ya da sanal makine durana kadar çalışan sanal makinede "
|
||||
"kalır."
|
||||
|
||||
#: instances/views.py:2132 instances/views.py:2162
|
||||
#: instances/views.py:2151 instances/views.py:2181
|
||||
msgid "Select a network interface and a QoS direction"
|
||||
msgstr "Bir ağ arabirimi ve bir QoS yönü seçin"
|
||||
|
||||
#: instances/views.py:2135
|
||||
#: instances/views.py:2154
|
||||
msgid "QoS rates must be whole numbers"
|
||||
msgstr "QoS hızları tam sayı olmalıdır"
|
||||
|
||||
#: instances/views.py:2142 networks/views.py:229
|
||||
#: instances/views.py:2161 networks/views.py:229
|
||||
#, python-format
|
||||
msgid "%(qos_dir)s QoS is set"
|
||||
msgstr "%(qos_dir)s QoS ayarlandı"
|
||||
|
||||
#: instances/views.py:2147
|
||||
#: instances/views.py:2166
|
||||
#, python-format
|
||||
msgid ""
|
||||
"%(qos_dir)s QoS is set. A running VM gets it after it is powered off and on."
|
||||
|
|
@ -5925,12 +5950,12 @@ msgstr ""
|
|||
"%(qos_dir)s QoS ayarlandı. Çalışan bir sanal makine, kapatılıp açıldıktan "
|
||||
"sonra bunu alır."
|
||||
|
||||
#: instances/views.py:2169 networks/views.py:255
|
||||
#: instances/views.py:2188 networks/views.py:255
|
||||
#, python-format
|
||||
msgid "%(qos_dir)s QoS is deleted"
|
||||
msgstr "%(qos_dir)s QoS silindi"
|
||||
|
||||
#: instances/views.py:2174
|
||||
#: instances/views.py:2193
|
||||
#, python-format
|
||||
msgid ""
|
||||
"%(qos_dir)s QoS is deleted. A running VM keeps the old limit until it is "
|
||||
|
|
@ -5939,21 +5964,21 @@ msgstr ""
|
|||
"%(qos_dir)s QoS silindi. Çalışan bir sanal makine, kapatılıp açılana kadar "
|
||||
"eski sınırı korur."
|
||||
|
||||
#: instances/views.py:2202
|
||||
#: instances/views.py:2221
|
||||
msgid "Only one owner is allowed and the one already added"
|
||||
msgstr "Sadece bir sahibe izin verilmiştir ve bir sahip zaten eklenmiş"
|
||||
|
||||
#: instances/views.py:2204
|
||||
#: instances/views.py:2223
|
||||
#, python-format
|
||||
msgid "%(user)s is already an owner"
|
||||
msgstr "%(user)s zaten bir sahip"
|
||||
|
||||
#: instances/views.py:2248
|
||||
#: instances/views.py:2267
|
||||
#, python-format
|
||||
msgid "Console settings were not saved: %(errors)s"
|
||||
msgstr "Konsol ayarları kaydedilmedi: %(errors)s"
|
||||
|
||||
#: instances/views.py:2270
|
||||
#: instances/views.py:2289
|
||||
msgid ""
|
||||
"Error setting console password. You should check that your instance have an "
|
||||
"graphic device."
|
||||
|
|
@ -5961,67 +5986,67 @@ msgstr ""
|
|||
"Konsol parolası ayarlanırken hata oluştu. Sanal makinenin bir grafik "
|
||||
"aygıtına sahip olduğundan emin olunuz."
|
||||
|
||||
#: instances/views.py:2317
|
||||
#: instances/views.py:2336
|
||||
msgid "Shut the VM down to change whether it is a template."
|
||||
msgstr "Şablon olup olmadığını değiştirmek için sanal makineyi kapatın."
|
||||
|
||||
#: instances/views.py:2324
|
||||
#: instances/views.py:2343
|
||||
#, python-format
|
||||
msgid "User %(quota_msg)s quota reached, '%(instance_name)s' stays a template!"
|
||||
msgstr ""
|
||||
"Kullanıcının %(quota_msg)s kotası doldu, '%(instance_name)s' şablon olarak "
|
||||
"kalıyor!"
|
||||
|
||||
#: instances/views.py:2406
|
||||
#: instances/views.py:2425
|
||||
msgid "The XML has no name"
|
||||
msgstr "XML'de ad yok"
|
||||
|
||||
#: instances/views.py:2420 webvirtcloud/middleware.py:75
|
||||
#: instances/views.py:2439 webvirtcloud/middleware.py:75
|
||||
#, python-format
|
||||
msgid "libvirt Error - %(exception)s"
|
||||
msgstr "libvirt Hatası - %(exception)s"
|
||||
|
||||
#: instances/views.py:2427
|
||||
#: instances/views.py:2446
|
||||
msgid "An empty disk of the size you set"
|
||||
msgstr "Belirlediğiniz boyutta boş bir disk"
|
||||
|
||||
#: instances/views.py:2428
|
||||
#: instances/views.py:2447
|
||||
msgid "Volumes already in a pool"
|
||||
msgstr "Bir havuzda zaten bulunan birimler"
|
||||
|
||||
#: instances/views.py:2429
|
||||
#: instances/views.py:2448
|
||||
msgid "A copy of a template volume"
|
||||
msgstr "Bir şablon biriminin kopyası"
|
||||
|
||||
#: instances/views.py:2518
|
||||
#: instances/views.py:2537
|
||||
msgid "You haven't defined any storage pools"
|
||||
msgstr "Hiç bir depolama havuzu tanımlamadınız"
|
||||
|
||||
#: instances/views.py:2520
|
||||
#: instances/views.py:2539
|
||||
msgid "You haven't defined any network pools"
|
||||
msgstr "Hiç bir ağ havuzu tanımlamadınız"
|
||||
|
||||
#: instances/views.py:2583
|
||||
#: instances/views.py:2602
|
||||
msgid "Flavor Created"
|
||||
msgstr "Flavor Oluşturuldu"
|
||||
|
||||
#: instances/views.py:2591
|
||||
#: instances/views.py:2610
|
||||
msgid "Create Flavor"
|
||||
msgstr "Kullanıcı Oluştur"
|
||||
|
||||
#: instances/views.py:2606
|
||||
#: instances/views.py:2625
|
||||
msgid "Flavor Updated"
|
||||
msgstr "Flavor Güncellendi"
|
||||
|
||||
#: instances/views.py:2612
|
||||
#: instances/views.py:2631
|
||||
msgid "Update Flavor"
|
||||
msgstr "Flavor Güncelle"
|
||||
|
||||
#: instances/views.py:2624
|
||||
#: instances/views.py:2643
|
||||
msgid "Flavor Deleted"
|
||||
msgstr "Flavor Silindi"
|
||||
|
||||
#: instances/views.py:2630
|
||||
#: instances/views.py:2649
|
||||
msgid "Only the size template goes; VMs made from it keep their size."
|
||||
msgstr ""
|
||||
"Yalnızca boyut şablonu silinir; ondan oluşturulan sanal makineler "
|
||||
|
|
|
|||
|
|
@ -1141,7 +1141,8 @@ class wvmInstance(wvmConnect):
|
|||
raise util.OperationError(f"Media of {dev} changed in the running VM only: {err}") from err
|
||||
raise
|
||||
|
||||
def mount_iso(self, dev, image):
|
||||
def get_iso_path(self, image):
|
||||
"""The path of the ISO image of that name, in one of the active pools."""
|
||||
paths = []
|
||||
for storage in self.get_storages(only_actives=True):
|
||||
stg = self.get_storage(storage)
|
||||
|
|
@ -1151,7 +1152,10 @@ class wvmInstance(wvmConnect):
|
|||
raise util.OperationError(f"ISO image {image} was not found")
|
||||
if len(paths) > 1:
|
||||
raise util.OperationError(f"ISO image {image} is in more than one storage pool")
|
||||
self._set_cdrom_media(dev, paths[0])
|
||||
return paths[0]
|
||||
|
||||
def mount_iso(self, dev, image):
|
||||
self._set_cdrom_media(dev, self.get_iso_path(image))
|
||||
|
||||
def umount_iso(self, dev, image=None):
|
||||
self._set_cdrom_media(dev, None)
|
||||
|
|
@ -1199,7 +1203,10 @@ class wvmInstance(wvmConnect):
|
|||
if detect_zeroes_mode is not None and detect_zeroes_mode != "default":
|
||||
additionals += f"detect_zeroes='{detect_zeroes_mode}' "
|
||||
|
||||
xml_disk = f"<disk type='{disk_type}' device='{disk_device}'>"
|
||||
# a USB CD-ROM is a CD drive on usb-bot only: usb-storage, which libvirt
|
||||
# takes where QEMU has no usb-bot (RHEL 9), shows the guest a hard disk
|
||||
usb_cd = " model='usb-bot'" if disk_device == "cdrom" and target_bus == "usb" else ""
|
||||
xml_disk = f"<disk type='{disk_type}' device='{disk_device}'{usb_cd}>"
|
||||
if disk_device == "cdrom":
|
||||
xml_disk += f"<driver name='{driver_name}' type='{format_type}'/>"
|
||||
elif disk_device == "disk":
|
||||
|
|
|
|||
|
|
@ -91,6 +91,16 @@ class DeviceEditsTestCase(unittest.TestCase):
|
|||
xml, _ = p.instance.attachDeviceFlags.call_args.args
|
||||
self.assertEqual(etree.fromstring(xml).find("source").attrib, {"dev": "/dev/vg/c"})
|
||||
|
||||
def test_a_usb_cdrom_is_a_cd_drive_on_usb_bot(self):
|
||||
# usb-storage, libvirt's choice where QEMU has no usb-bot, shows a hard disk
|
||||
for bus, model in (("usb", "usb-bot"), ("sata", None)):
|
||||
with self.subTest(bus=bus):
|
||||
p = proxy(active=False)
|
||||
p._definitions = lambda: [(PERSISTENT_XML, VIR_DOMAIN_AFFECT_CONFIG)]
|
||||
p.attach_disk("sdb", "/iso/virtio-win.iso", disk_device="cdrom", target_bus=bus, readonly=True)
|
||||
xml, _ = p.instance.attachDeviceFlags.call_args.args
|
||||
self.assertEqual(etree.fromstring(xml).get("model"), model)
|
||||
|
||||
def test_a_bridge_nic_can_be_a_boot_device(self):
|
||||
p = proxy()
|
||||
p.set_bootorder({0: {"type": "network", "dev": "52:54:10:00:00:02"}, 1: {"type": "disk", "dev": "vdb"}})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue