2.6. 使用服务

找到服务后,您可以调用其服务方法,后者向服务器发送请求并执行实际工作。

管理单个对象的服务通常支持 获取更新和删除 方法。

管理对象集合的服务通常支持 列表和 添加 方法。

这两种服务(特别是管理单个对象的服务)都可以支持其他操作方法。

2.6.1. 使用 get 方法

这些服务方法用于检索单个对象的表示。以下示例检索带有 123 的虚拟机的表示:

# Find the service that manages the virtual machine:
vms_service = system_service.vms_service()
vm_service = vms_service.vm_service('123')

# Retrieve the representation of the virtual machine:
vm = vm_service.get()

响应是对应类型的实例,本例中为 Python 类 ovirtsdk4.types.Vm 的实例。

某些服务的 get 方法支持额外的参数,它们控制了如何检索对象的表示,或者检索对象的内容(如果存在多个参数)。例如,您可能要检索虚拟机的当前状态,或者下次启动时的状态,因为它们可能有所不同。管理虚拟机的服务的 get 方法支持 next_run 布尔值参数:

# Retrieve the representation of the virtual machine, not the
# current one, but the one that will be used after the next
# boot:
vm = vm_service.get(next_run=True)

详情请参阅 SDK 的 参考文档

如果因为某种原因无法检索对象,则 SDK 会引发 ovirtsdk4.Error 异常,详细信息失败。这包括对象实际上不存在的情况。请注意,调用 get 服务方法时会引发异常。调用 service locator 方法永远不会失败,即使对象不存在,因为该调用不会向服务器发送请求。例如:

# Call the service that manages a non-existent virtual machine.
# This call will succeed.
vm_service = vms_service.vm_service('junk')

# Retrieve the virtual machine. This call will raise an exception.
vm = vm_service.get()

2.6.2. 使用 列表 方法

这些服务方法检索集合对象的表示。本例检索系统的虚拟机的完整集合:

# Find the service that manages the collection of virtual
# machines:
vms_service = system_service.vms_service()

# List the virtual machines in the collection
vms = vms_service.list()

结果将是包含相应类型的实例的 Python 列表。例如,在这种情况下,结果将是类 ovirtsdk4.types.Vm 的实例列表。

一些 服务列表 方法支持额外的参数。例如,几乎所有顶级集合都支持 search 参数,用于过滤结果或 max 参数,以限制服务器返回的结果数。这个示例检索从 my 开始的虚拟机的名称,其上限为 10 个结果:

vms = vms_service.list(search='name=my*', max=10)
注意

并非所有 列表 方法都支持这些参数。些 列表 方法支持其他参数。详情请参阅 SDK 的 参考文档

如果因任何原因而返回的结果列表为空,则返回的值将是一个空列表。它绝不是 "无 "。

如果在尝试检索结果时出现错误,则 SDK 将引发一个 ovirtsdk4.Error 异常,其中包含失败的详细信息。

2.6.3. 使用 添加 方法

这些服务方法为集合添加新元素。它们收到描述要添加的对象的相关类型实例,发送请求来添加它,以及返回描述添加对象的类型实例。

此示例添加名为 vm1 的新虚拟机:

from ovirtsdk4 import types

# Add the virtual machine:
vm = vms_service.add(
    vm=types.Vm(
        name='vm1',
        cluster=types.Cluster(
            name='Default'
        ),
        template=types.Template(
            name='mytemplate'
        )
    )
)

如果因为某种原因无法创建对象,则 SDK 引发 ovirtsdk4.Error 异常,其中包含失败详情。它永远不会返回 "无 "。

重要

这个 add 方法返回的 Python 对象是相关类型的实例。它不是服务,而是数据容器。在这个特定示例中,返回的对象是 ovirtsdk4.types.Vm 类的实例。如果创建虚拟机后,您需要执行一个操作,如检索或启动它,您首先需要找到管理该服务,并调用对应的服务 locator:

# Add the virtual machine:
vm = vms_service.add(
  ...
)

# Find the service that manages the virtual machine:
vm_service = vms_service.vm_service(vm.id)

# Start the virtual machine
vm_service.start()

对象异步创建。在创建新虚拟机时,添加 方法将在虚拟机完全创建并准备好使用前返回响应。最好轮询对象的状态,以确保它完全创建。对于虚拟机,您应该检查其状态,直至状态为 DOWN

# Add the virtual machine:
vm = vms_service.add(
  ...
)

# Find the service that manages the virtual machine:
vm_service = vms_service.vm_service(vm.id)

# Wait until the virtual machine is down, indicating that it is
# completely created:
while True:
    time.sleep(5)
    vm = vm_service.get()
    if vm.status == types.VmStatus.DOWN:
        break

使用循环通过 get 方法检索对象状态,确保 status 属性已更新。

2.6.4. 使用 更新 方法

这些服务方法更新现有的对象。它们收到描述要执行更新的相关类型的实例,发送请求更新,再返回描述更新对象的类型实例。

这个示例将虚拟机的名称从 vm1 更新到 newvm

from ovirtsdk4 import types

# Find the virtual machine, and then the service that
# manages it:
vm = vms_service.list(search='name=vm1')[0]
vm_service = vm_service.vm_service(vm.id)

# Update the name:
updated_vm = vm_service.update(
    vm=types.Vm(
        name='newvm'
    )
)

执行更新时,请避免发送对象 的完整 表示。仅发送您要更新的属性。不要:

# Retrieve the complete representation:
vm = vm_service.get()

# Update the representation, in memory, without sending a request
# to the server:
vm.name = 'newvm'

# Send the update. Do *not* do this.
vms_service.update(vm)

发送完整的表示会导致两个问题:

  • 您发送的信息比服务器需求多得多,因此浪费资源。
  • 服务器将尝试更新对象的所有属性,即使您没有更改对象的属性。这可能会导致服务器端的错误。

有些服务的 更新 方法支持额外的参数,它们控制如何或要更新的内容。例如,您可能想要更新虚拟机的当前状态,或者虚拟机下次启动时使用的状态。管理虚拟机的服务的更新 方法支持 next_run 布尔值参数:

# Update the memory of the virtual machine to 1 GiB,
# not during the current run, but after next boot:
vm = vm_service.update(
    vm=types.Vm(
        memory=1073741824
    ),
    next_run=True
)

如果因为某种原因无法更新,则 SDK 引发 ovirtsdk4.Error 异常,其中包含失败详情。它永远不会返回 "无 "。

此更新方法返回的 Python 对象是相关类型的实例。它不是服务,而是数据的一个容器。在这个特定示例中,返回的对象将是 ovirtsdk4.types.Vm 类的实例。

2.6.5. 使用 删除 方法

这些服务方法移除现有的对象。它们通常不使用参数,因为它们是管理单个对象的服务的方法。因此,该服务已经知道要删除的对象。

本例删除 ID 为 123 的虚拟机:

# Find the virtual machine by name:
vm = vms_service.list(search='name=123')[0]

# Find the service that manages the virtual machine using the ID:
vm_service = vms_service.vm_service(vm.id)

# Remove the virtual machine:
vm_service.remove()

删除 某些服务的方法支持额外的参数,它们控制如何删除。例如,可以在保留其磁盘的同时删除虚拟机,使用 detach_only 布尔值参数:

# Remove the virtual machine while preserving the disks:
vm_service.remove(detach_only=True)

如果对象成功 移除,则删除方法会返回 None。它不会返回移除的对象。如果因为某种原因无法删除对象,则 SDK 引发 ovirtsdk4.Error 异常,其中包含失败详情。

2.6.6. 使用其他操作方法

还有其他服务方法执行各种操作,如停止和启动虚拟机:

# Start the virtual machine:
vm_service.start()

其中许多方法包括修改操作的参数。例如,如果想要使用 cloud-init 启动虚拟机,则启动虚拟机的方法支持 use_cloud_init 参数:

# Start the virtual machine:
vm_service.start(cloud_init=True)

大多数操作方法都会在成功时返回 None,并在失败时引发 ovirtsdk4.Error。少数操作方法返回值。例如,管理存储域的服务具有 is_attached 操作方法,用于检查存储域是否已附加到数据中心并返回布尔值:

# Check if the storage domain is attached to a data center:
sds_service = system_service.storage_domains_service()
sd_service = sds_service.storage_domain_service('123')
if sd_service.is_attached():
    ...

检查 SDK 的 参考文档,以查看每个服务支持的操作方法、它们所使用的参数,以及它们返回的值。