def validate(self, attrs): target_hostname_or_uuid = attrs.get('target_hostname_or_uuid', None) target_disk_id = attrs.get('target_disk_id', None) if target_hostname_or_uuid and not target_disk_id: err_msg = _( 'This field is required when target_hostname_or_uuid is specified.' ) self._errors['target_disk_id'] = s.ErrorList([err_msg]) return attrs elif not target_hostname_or_uuid and target_disk_id: err_msg = _( 'This field is required when target_disk_id is specified.') self._errors['target_hostname_or_uuid'] = s.ErrorList([err_msg]) return attrs elif target_hostname_or_uuid and target_disk_id: try: self.target_vm = get_vm(self.request, target_hostname_or_uuid, exists_ok=True, noexists_fail=True, check_node_status=None) except ObjectNotFound as exc: self._errors['target_hostname_or_uuid'] = s.ErrorList( [exc.detail]) else: try: self.target_vm_disk_id, self.target_vm_real_disk_id, self.target_vm_disk_zfs_filesystem = \ get_disk_id(self.request, self.target_vm, disk_id=target_disk_id) except InvalidInput as exc: self._errors['target_disk_id'] = s.ErrorList([exc.detail]) return attrs
def validate_VMS_IMAGE_VM(self, attrs, source): try: value = attrs[source] except KeyError: pass else: if value: try: vm = get_vm(self.request, value, exists_ok=True, noexists_fail=True, dc_bound=False) except ObjectNotFound as exc: raise s.ValidationError(exc.detail) else: if vm.status not in (Vm.RUNNING, Vm.STOPPED): raise s.ValidationError( _('Invalid VM status; VM must be running or stopped.' )) if vm.ostype != Vm.SUNOS_ZONE: raise s.ValidationError( _('Invalid OS type; VM must be a SunOS Zone.')) attrs[source] = vm.uuid return attrs
def vm_define_nic_list(request, hostname_or_uuid, data=None): """ List (:http:get:`GET </vm/(hostname_or_uuid)/define/nic>`) VM NIC definitions. .. http:get:: /vm/(hostname_or_uuid)/define/nic :DC-bound?: * |dc-yes| :Permissions: * |VmOwner| :Asynchronous?: * |async-no| :arg hostname_or_uuid: **required** - Server hostname or uuid :type hostname_or_uuid: string :arg data.active: Display currently active VM NIC definitions on compute node (default: false) :type data.active: boolean :status 200: SUCCESS :status 403: Forbidden :status 404: VM not found """ vm = get_vm(request, hostname_or_uuid, exists_ok=True, noexists_fail=True, check_node_status=None) return VmDefineNicView(request).get(vm, None, None, many=True)
def vm_define_revert(request, hostname_or_uuid, data=None): """ Revert (:http:put:`PUT </vm/(hostname_or_uuid)/define/revert>`) whole VM definition (including disks and nics) to currently active VM definition on compute node. .. http:put:: /vm/(hostname_or_uuid)/define/revert .. warning:: The DNS settings for server's hostname and IP addresses won't be reverted. :DC-bound?: * |dc-yes| :Permissions: * |VmOwner| :Asynchronous?: * |async-no| :arg hostname_or_uuid: **required** - Server hostname or uuid :type hostname_or_uuid: string :status 200: SUCCESS :status 403: Forbidden :status 404: VM not found :status 409: VM has pending tasks :status 417: VM definition unchanged :status 423: VM is not operational / VM is not created / VM is locked or has slave VMs """ vm = get_vm(request, hostname_or_uuid, exists_ok=True, noexists_fail=True, sr=('node', 'owner', 'template', 'slavevm'), check_node_status=None) return VmDefineRevertView(request).put(vm, data)
def __init__(self, request, hostname_or_uuid, data): super(VmSnapshotList, self).__init__(request) self.data = data self.vm = get_vm(request, hostname_or_uuid, exists_ok=True, noexists_fail=True)
def __init__(self, request, hostname_or_uuid, data): super(VmMonitoringView, self).__init__(request) self.vm = get_vm(request, hostname_or_uuid, sr=('dc', ), exists_ok=True, noexists_fail=True) self.data = data
def __init__(self, request, hostname_or_uuid, data): super(VmMigrate, self).__init__(request) self.hostname_or_uuid = hostname_or_uuid self.data = data self.vm = get_vm(request, hostname_or_uuid, exists_ok=True, noexists_fail=True)
def __init__(self, request, hostname_or_uuid, bkpname, data): super(VmBackup, self).__init__(request) if request.method == 'POST': # Got bkpdef instead of bkpname vm = get_vm(request, hostname_or_uuid, exists_ok=True, noexists_fail=True) disk_id, real_disk_id, zfs_filesystem = get_disk_id(request, vm, data) # TODO: check indexes define = get_object(request, BackupDefine, {'name': bkpname, 'vm': vm, 'disk_id': real_disk_id}, exists_ok=True, noexists_fail=True, sr=('vm', 'node')) bkpname = define.generate_backup_name() bkp_get = {'name': bkpname, 'vm_hostname': vm.hostname, 'vm_disk_id': disk_id - 1, 'vm': vm} else: try: if 'hostname' in data: # Force original hostname raise ObjectNotFound # Only target VM status and backup node status are important vm = get_vm(request, hostname_or_uuid, exists_ok=True, noexists_fail=True, check_node_status=None) except ObjectNotFound: vm = None bkp_get = {'name': bkpname, 'vm_hostname': hostname_or_uuid} else: bkp_get = {'vm': vm, 'name': bkpname} define = None real_disk_id = None zfs_filesystem = None bkp_get = filter_disk_id(None, bkp_get, data, default=1) # vm_disk_id instead of disk_id bkp_get['dc'] = request.dc # Backup instance self.bkp = bkp = get_object(request, Backup, bkp_get, sr=('node', 'define', 'vm')) self.disk_id = bkp.array_disk_id self.hostname = bkp.vm_hostname_real self.define = define self.real_disk_id = real_disk_id self.zfs_filesystem = zfs_filesystem self.vm = vm self.data = data # Task type (a = automatic, e = manual) if getattr(request, 'define_id', None): self.tt = TT_AUTO else: self.tt = TT_EXEC
def __init__(self, request, hostname_or_uuid, yyyymm, data): super(VmSLAView, self).__init__(request) self.vm = get_vm(request, hostname_or_uuid, sr=(), exists_ok=True, noexists_fail=True) self.yyyymm = yyyymm self.data = data
def __init__(self, request, hostname_or_uuid, data): super(VmManage, self).__init__(request) self.hostname_or_uuid = hostname_or_uuid self.data = data if request.method == 'GET': # get() uses different methods for getting vm(s) object(s) self.vm = None else: self.vm = get_vm(request, hostname_or_uuid, exists_ok=True, noexists_fail=True)
def __init__(self, request, hostname_or_uuid, graph_type, data): super(VmHistoryView, self).__init__(request) self.vm = get_vm(request, hostname_or_uuid, sr=('dc', ), exists_ok=True, noexists_fail=True) self.graph_type = graph_type self.data = data
def __init__(self, request, hostname_or_uuid, action, data): super(VmStatus, self).__init__(request) self.hostname_or_uuid = hostname_or_uuid self.action = action self.data = data if hostname_or_uuid: self.vm = get_vm(request, hostname_or_uuid, exists_ok=True, noexists_fail=True, sr=('node', 'owner')) else: self.vm = get_vms(request, sr=('node', 'owner'), order_by=self.order_by)
def get(self, many=False): request = self.request active = self.data.get('active', False) sr = ['owner', 'node'] if self.extended: ser_class = ExtendedVmSerializer extra = {'select': ExtendedVmSerializer.extra_select} sr.append('slavevm') else: ser_class = VmSerializer extra = None def set_active(x): # Do not revert owner and template, because it could generate lots of queries otherwise x.revert_active(revert_owner=False, revert_template=False) return x if many: if self.full or self.extended: vms = get_vms(request, sr=sr, order_by=self.order_by) if self.extended: # noinspection PyArgumentList vms = vms.extra(**extra).prefetch_related('tags') if active: vms = [set_active(vm) for vm in vms] if vms: res = ser_class(request, vms, many=True).data else: res = [] else: res = list( get_vms(request, order_by=self.order_by).values_list('hostname', flat=True)) else: vm = get_vm(request, self.hostname_or_uuid, exists_ok=True, noexists_fail=True, sr=sr, extra=extra) if active: set_active(vm) res = ser_class(request, vm).data return SuccessTaskResponse(self.request, res)
def vm_define_user(request, hostname_or_uuid, data=None): """ vm_define alternative used only for updating hostname and alias. Used by non-admin VM owners from GUI. """ vm = get_vm(request, hostname_or_uuid, sr=('owner', 'node', 'template', 'slavevm'), check_node_status=None, exists_ok=True, noexists_fail=True) allowed = {'hostname', 'alias', 'installed'} for i in data.keys(): # A copy of keys, because dict can change during iteration if i not in allowed: del data[i] return VmDefineView(request).put(vm, data)
def vm_define_backup_list(request, hostname_or_uuid, data=None): """ List (:http:get:`GET </vm/(hostname_or_uuid)/define/backup>`) all VM backup definitions. .. http:get:: /vm/(hostname_or_uuid)/define/backup :DC-bound?: * |dc-yes| :Permissions: * |VmOwner| :Asynchronous?: * |async-no| :arg hostname_or_uuid: **required** - Server hostname or uuid :type hostname_or_uuid: string :arg data.full: Return list of objects with all backup definition details (default: false) :type data.full: boolean :arg data.disk_id: Filter by disk number/ID :type data.disk_id: integer :arg data.extended: Include total number of backups for each backup definition (default: false) :type data.extended: boolean :arg data.order_by: :ref:`Available fields for sorting <order_by>`: ``name``, ``disk_id``, ``created`` \ (default: ``-created``) :type data.order_by: string :status 200: SUCCESS :status 403: Forbidden :status 404: VM not found :status 412: Invalid disk_id """ vm = get_vm(request, hostname_or_uuid, exists_ok=True, noexists_fail=True, sr=('node', 'owner')) query_filter = {'vm': vm} query_filter = filter_disk_id(vm, query_filter, data) extra = output_extended_backup_count(request, data) # TODO: check indexes bkp_define = BackupDefine.objects.select_related('vm', 'vm__dc', 'node', 'zpool', 'periodic_task', 'periodic_task__crontab')\ .filter(**query_filter).order_by(*BackupDefineView.get_order_by(data)) if extra: bkp_define = bkp_define.extra(extra) return BackupDefineView(request, data=data).get(vm, bkp_define, many=True, extended=bool(extra))
def __init__(self, request, hostname_or_uuid, repname, data): super(VmReplicaBaseView, self).__init__(request) self.repname = repname self.data = data self._success = False self.vm = vm = get_vm(request, hostname_or_uuid, exists_ok=True, noexists_fail=True, check_node_status=self._check_node_status) if repname is None: # Exclude migration ghost VMs self.slave_vm = SlaveVm.objects.select_related('vm', 'master_vm', 'vm__node')\ .filter(master_vm=vm).exclude(name=u'').order_by('name') else: self.slave_vm = get_object(request, SlaveVm, {'master_vm': vm, 'name': repname}, sr=('vm', 'master_vm', 'vm__node'), create_attrs={'_master_vm': vm, 'name': repname})
def __init__(self, request, hostname_or_uuid, snapname, data): super(VmSnapshot, self).__init__(request) self.data = data self.vm = vm = get_vm( request, hostname_or_uuid, exists_ok=True, noexists_fail=True, check_node_status=('POST', 'DELETE')) # custom node check inside put() self.disk_id, real_disk_id, self.zfs_filesystem = get_disk_id( request, vm, data) self.snap = get_object(request, Snapshot, { 'name': snapname, 'vm': vm, 'disk_id': real_disk_id }, sr=('define', ))
def _init_vm(self): request, data, hostname_or_uuid = self.request, self.data, self.hostname_or_uuid bkp_filter = {'dc': request.dc} try: if 'hostname' in data: # Force original hostname raise ObjectNotFound # No need to check vm.node.status; only backup node status is important vm = get_vm(request, hostname_or_uuid, exists_ok=True, noexists_fail=True, check_node_status=None) except ObjectNotFound: vm = None bkp_filter['vm_hostname'] = hostname_or_uuid else: bkp_filter['vm'] = vm self.vm = vm self.bkp_filter = bkp_filter
def vm_define(request, hostname_or_uuid, data=None): """ Show (:http:get:`GET </vm/(hostname_or_uuid)/define>`), create (:http:post:`POST </vm/(hostname_or_uuid)/define>`), change (:http:put:`PUT </vm/(hostname_or_uuid)/define>`) or delete (:http:delete:`DELETE </vm/(hostname_or_uuid)/define>`) a VM definition. .. http:get:: /vm/(hostname_or_uuid)/define :DC-bound?: * |dc-yes| :Permissions: * |VmOwner| :Asynchronous?: * |async-no| :arg hostname_or_uuid: **required** - Server hostname or uuid :type hostname_or_uuid: string :arg data.full: Display full VM definition (including disk and nic lists) (default: false) :type data.full: boolean :arg data.active: Display currently active VM definition on compute node (default: false) :type data.active: boolean :arg data.diff: Display differences between active VM definition on compute node and current configuration \ (default: false) :type data.diff: boolean :status 200: SUCCESS :status 403: Forbidden :status 404: VM not found .. http:post:: /vm/(hostname_or_uuid)/define :DC-bound?: * |dc-yes| :Permissions: * |Admin| :Asynchronous?: * |async-no| :arg hostname_or_uuid: **required** - Server hostname :type hostname_or_uuid: string :arg data.alias: Short server name (default: ``hostname``) :type data.alias: string :arg data.template: VM template name (default: null) :type data.template: string :arg data.ostype: Operating system type (1 - Linux VM, 2 - SunOS VM, 3 - BSD VM, 4 - Windows VM, \ 5 - SunOS Zone, 6 - Linux Zone) (default: 1) :type data.ostype: integer :arg data.vcpus: **required** - Number of virtual CPUs inside VM (1 - 64) :type data.vcpus: integer :arg data.ram: **required** - Size of RAM inside VM (32 - 524288 MB) :type data.ram: integer :arg data.note: Text note visible to every user with access to this VM (default: "") :type data.note: string :arg data.owner: User that owns the VM (default: logged in user) :type data.owner: string :arg data.node: Name of the host system \ (default: null => will be chosen automatically just before the VM is created) :type data.node: string :arg data.tags: Custom VM tags (default: []) :type data.tags: array :arg data.monitored: Enable VM synchronization with monitoring system (default: true) :type data.monitored: boolean :arg data.monitored_internal: Enable VM synchronization with internal monitoring system \ (requires |SuperAdmin| permission) (default: true) :type data.monitored: boolean :arg data.installed: Mark the server as installed (default: false) :type data.installed: boolean :arg data.snapshot_limit_manual: Maximum number of manual snapshots for this VM (default: null [unlimited]) :type data.snapshot_limit_manual: integer :arg data.snapshot_size_limit: Maximum size of all snapshots for this VM (default: null [unlimited]) :type data.snapshot_size_limit: integer :arg data.zpool: The zpool used for the VM zone (default: zones) :type data.zpool: string :arg data.cpu_shares: Number of VM's CPU shares relative to other VMs (requires |SuperAdmin| permission) \ (default: 100) :type data.cpu_shares: integer :arg data.zfs_io_priority: IO throttle priority relative to other VMs (requires |SuperAdmin| permission) \ (default: 100) :type data.zfs_io_priority: integer :arg data.cpu_type: **KVM only**; Type of the virtual CPU exposed to the VM. One of qemu64, host \ (default: qemu64; except for Windows ``ostype`` where the default is host) :type data.cpu_type: string :arg data.vga: **KVM only**; VGA emulation driver. One of std, cirrus, vmware (default: std) :type data.vga: string :arg data.routes: Key-value object that maps destinations to gateways. \ Items will be set as static routes in the OS (SunOS Zone only, default: {}) :type data.routes: object :arg data.monitoring_hostgroups: Custom VM monitoring hostgroups (default: []) :type data.monitoring_hostgroups: array :arg data.monitoring_templates: Custom VM monitoring templates (default: []) :type data.monitoring_templates: array :arg data.mdata: Customer metadata accessible from within the VM (key=value string pairs) (default: {}) :type data.mdata: object :status 201: SUCCESS :status 400: FAILURE :status 403: Forbidden :status 406: VM already exists .. http:put:: /vm/(hostname_or_uuid)/define :DC-bound?: * |dc-yes| :Permissions: * |Admin| :Asynchronous?: * |async-no| :arg hostname_or_uuid: **required** - Server hostname or uuid :type hostname_or_uuid: string :arg data.alias: Short server name :type data.alias: string :arg data.template: VM template name :type data.template: string :arg data.vcpus: Number of virtual CPUs inside VM (1 - 64) :type data.vcpus: integer :arg data.ram: Size of RAM inside VM (32 - 524288 MB) :type data.ram: integer :arg data.note: Text note visible to every user with access to this VM :type data.note: string :arg data.owner: User that owns the VM :type data.owner: string :arg data.node: Name of the host system :type data.node: string :arg data.tags: Custom VM tags :type data.tags: array :arg data.monitored: Enable VM synchronization with monitoring system :type data.monitored: boolean :arg data.monitored_internal: Enable VM synchronization with internal monitoring system \ (requires |SuperAdmin| permission) :type data.monitored: boolean :arg data.installed: Mark the server as installed :type data.installed: boolean :arg data.snapshot_limit_manual: Maximum number of manual snapshots for this VM :type data.snapshot_limit_manual: integer :arg data.snapshot_size_limit: Maximum size of all snapshots for this VM :type data.snapshot_size_limit: integer :arg data.zpool: The zpool used for the VM zone :type data.zpool: string :arg data.cpu_shares: Number of VM's CPU shares relative to other VMs (requires |SuperAdmin| permission) :type data.cpu_shares: integer :arg data.zfs_io_priority: IO throttle priority relative to other VMs (requires |SuperAdmin| permission) :type data.zfs_io_priority: integer :arg data.cpu_type: **KVM only**; Type of the virtual CPU exposed to the VM. One of qemu64, host :type data.cpu_type: string :arg data.vga: **KVM only**; VGA emulation driver. One of std, cirrus, vmware :type data.vga: string :arg data.routes: Key-value object that maps destinations to gateways. \ Items will be set as static routes in the OS (SunOS Zone only) :type data.routes: object :arg data.monitoring_hostgroups: Custom VM monitoring hostgroups :type data.monitoring_hostgroups: array :arg data.monitoring_templates: Custom VM monitoring templates :type data.monitoring_templates: array :arg data.mdata: Customer metadata accessible from within the VM (key=value string pairs) :type data.mdata: object :status 200: SUCCESS :status 400: FAILURE :status 403: Forbidden :status 404: VM not found :status 423: VM is not operational / VM is locked or has slave VMs .. http:delete:: /vm/(hostname_or_uuid)/define :DC-bound?: * |dc-yes| :Permissions: * |Admin| :Asynchronous?: * |async-no| :arg hostname_or_uuid: **required** - Server hostname or uuid :type hostname_or_uuid: string :status 200: SUCCESS :status 400: FAILURE :status 403: Forbidden :status 404: VM not found :status 423: VM is not operational / VM is not notcreated / VM is locked or has slave VMs """ vm = get_vm(request, hostname_or_uuid, sr=('owner', 'node', 'template', 'slavevm'), check_node_status=None, noexists_fail=False, exists_ok=False) return VmDefineView(request).response(vm, data, hostname_or_uuid=hostname_or_uuid)
def vm_define_nic(request, hostname_or_uuid, nic_id=None, data=None): """ Show (:http:get:`GET </vm/(hostname_or_uuid)/define/nic/(nic_id)>`), create (:http:post:`POST </vm/(hostname_or_uuid)/define/nic/(nic_id)>`), change (:http:put:`PUT </vm/(hostname_or_uuid)/define/nic/(nic_id)>`) or delete (:http:delete:`DELETE </vm/(hostname_or_uuid)/define/nic/(nic_id)>`) a VM NIC definition. .. http:get:: /vm/(hostname_or_uuid)/define/nic/(nic_id) :DC-bound?: * |dc-yes| :Permissions: * |VmOwner| :Asynchronous?: * |async-no| :arg hostname_or_uuid: **required** - Server hostname or uuid :type hostname_or_uuid: string :arg nic_id: **required** - NIC number/ID (1 - 6) :type nic_id: integer :arg data.active: Display currently active VM NIC definition on compute node (default: false) :type data.active: boolean :arg data.diff: Display differences between active VM definition on compute node and current configuration \ (default: false) :type data.diff: boolean :status 200: SUCCESS :status 403: Forbidden :status 404: VM not found :status 406: VM NIC out of range .. http:post:: /vm/(hostname_or_uuid)/define/nic/(nic_id) :DC-bound?: * |dc-yes| :Permissions: * |Admin| :Asynchronous?: * |async-no| :arg hostname_or_uuid: **required** - Server hostname or uuid :type hostname_or_uuid: string :arg nic_id: **required** - NIC number/ID (1 - 6) :type nic_id: integer :arg data.net: **required** - Name of a virtual network :type data.net: string :arg data.ip: Virtual NIC IPv4 address. Must be part of net (default: auto select) :type data.ip: string :arg data.model: Virtual NIC Model. One of virtio, e1000, rtl8139 (default: virtio) :type data.model: string :arg data.dns: Create a DNS A record for VM's FQDN? (default: true for first NIC, otherwise false) :type data.dns: boolean :arg data.use_net_dns: Inherit DNS resolvers from network's resolvers setting (default: false) :type data.use_net_dns: boolean :arg data.mac: Virtual NIC MAC address (default: auto-generated) :type data.mac: string :arg data.primary: Use this NICs gateway as VM default gateway (default: true for first NIC, otherwise false) :type data.primary: boolean :arg data.allow_dhcp_spoofing: Allow packets required for DHCP server (requires |SuperAdmin| permission) \ (default: false) :type data.allow_dhcp_spoofing: boolean :arg data.allow_ip_spoofing: Allow sending and receiving packets for IP addresses other \ than specified in ``ip`` (requires |SuperAdmin| permission) (default: false) :type data.allow_ip_spoofing: boolean :arg data.allow_mac_spoofing: Allow sending packets with MAC addresses other than specified in ``mac`` \ (requires |SuperAdmin| permission) (default: false) :type data.allow_mac_spoofing: boolean :arg data.allow_restricted_traffic: Allow sending packets that are not IPv4, IPv6, or ARP \ (requires |SuperAdmin| permission) (default: false) :type data.allow_restricted_traffic: boolean :arg data.allow_unfiltered_promisc: Allow VM to have multiple MAC addresses. Use with caution! \ (requires |SuperAdmin| permission) (default: false) :type data.allow_unfiltered_promisc: boolean :arg data.allowed_ips: List of additional IP addresses that can be used by this VM's NIC and also by \ other VMs. Useful for floating/shared IPs (default: []) :type data.allowed_ips: array :arg data.monitoring: Use this NIC's IP address for external monitoring \ (default: true for first NIC, otherwise false) :type data.monitoring: boolean :arg data.set_gateway: Whether to set gateway from network (``data.net``) settings (default: true) :type data.set_gateway: boolean :status 201: SUCCESS :status 400: FAILURE :status 403: Forbidden :status 404: VM not found :status 406: VM NIC out of range / VM NIC already exists :status 423: VM is not operational / VM is locked or has slave VMs .. http:put:: /vm/(hostname_or_uuid)/define/nic/(nic_id) :DC-bound?: * |dc-yes| :Permissions: * |Admin| :Asynchronous?: * |async-no| :arg hostname_or_uuid: **required** - Server hostname or uuid :type hostname_or_uuid: string :arg nic_id: **required** - NIC number/ID (1 - 6) :type nic_id: integer :arg data.net: Name of a virtual network :type data.net: string :arg data.ip: Virtual NIC IPv4 address :type data.ip: string :arg data.model: Virtual NIC Model. One of virtio, e1000, rtl8139 :type data.model: string :arg data.dns: Create a DNS A record for VM's FQDN? :type data.dns: boolean :arg data.use_net_dns: Inherit DNS resolvers from network's resolvers setting :type data.use_net_dns: boolean :arg data.mac: Virtual NIC MAC address :type data.mac: string :arg data.primary: Use this NICs gateway as VM default gateway :type data.primary: boolean :arg data.allow_dhcp_spoofing: Allow packets required for DHCP server \ (requires |SuperAdmin| permission) :type data.allow_dhcp_spoofing: boolean :arg data.allow_ip_spoofing: Allow sending and receiving packets for IP addresses other \ than specified in ``ip`` (requires |SuperAdmin| permission) :type data.allow_ip_spoofing: boolean :arg data.allow_mac_spoofing: Allow sending packets with MAC addresses other than specified in ``mac`` \ (requires |SuperAdmin| permission) :type data.allow_mac_spoofing: boolean :arg data.allow_restricted_traffic: Allow sending packets that are not IPv4, IPv6, or ARP \ (requires |SuperAdmin| permission) :type data.allow_restricted_traffic: boolean :arg data.allow_unfiltered_promisc: Allow VM to have multiple MAC addresses. Use with caution! \ (requires |SuperAdmin| permission) :type data.allow_unfiltered_promisc: boolean :arg data.allowed_ips: List of additional IP addresses that can be used by this VM's NIC and also by \ other VMs. Useful for floating/shared IPs :type data.allowed_ips: array :arg data.monitoring: Use this NIC's IP address for external monitoring :type data.monitoring: boolean :arg data.set_gateway: Whether to set gateway from network (``data.net``) settings :type data.set_gateway: boolean :status 200: SUCCESS :status 400: FAILURE :status 403: Forbidden :status 404: VM not found :status 406: VM NIC out of range :status 423: VM is not operational / VM is locked or has slave VMs .. http:delete:: /vm/(hostname_or_uuid)/define/nic/(nic_id) :DC-bound?: * |dc-yes| :Permissions: * |Admin| :Asynchronous?: * |async-no| :arg hostname_or_uuid: **required** - Server hostname or uuid :type hostname_or_uuid: string :arg nic_id: **required** - NIC number/ID (1 - 6) :type nic_id: integer :status 200: SUCCESS :status 400: FAILURE :status 403: Forbidden :status 404: VM not found :status 406: VM NIC out of range :status 423: VM is not operational / VM is locked or has slave VMs """ vm = get_vm(request, hostname_or_uuid, exists_ok=True, noexists_fail=True, sr=('node', 'owner', 'template', 'slavevm'), check_node_status=None) try: nic_id = int(nic_id) - 1 except ValueError: raise BadRequest return VmDefineNicView(request).response(vm, nic_id, data)
def vm_define_disk(request, hostname_or_uuid, disk_id=None, data=None): """ Show (:http:get:`GET </vm/(hostname_or_uuid)/define/disk/(disk_id)>`), create (:http:post:`POST </vm/(hostname_or_uuid)/define/disk/(disk_id)>`), change (:http:put:`PUT </vm/(hostname_or_uuid)/define/disk/(disk_id)>`) or delete (:http:delete:`DELETE </vm/(hostname_or_uuid)/define/disk/(disk_id)>`) a VM disk definition. .. http:get:: /vm/(hostname_or_uuid)/define/disk/(disk_id) :DC-bound?: * |dc-yes| :Permissions: * |VmOwner| :Asynchronous?: * |async-no| :arg hostname_or_uuid: **required** - Server hostname or uuid :type hostname_or_uuid: string :arg disk_id: **required** - Disk number/ID (1 - 2) :type disk_id: integer :arg data.active: Display currently active VM disk definition on compute node (default: false) :type data.active: boolean :arg data.diff: Display differences between active VM definition on compute node and current configuration \ (default: false) :type data.diff: boolean :status 200: SUCCESS :status 403: Forbidden :status 404: VM not found :status 406: VM disk out of range .. http:post:: /vm/(hostname_or_uuid)/define/disk/(disk_id) :DC-bound?: * |dc-yes| :Permissions: * |Admin| :Asynchronous?: * |async-no| :arg hostname_or_uuid: **required** - Server hostname or uuid :type hostname_or_uuid: string :arg disk_id: **required** - Disk number/ID (1 - 2) :type disk_id: integer :arg data.size: **required** (if not specified in image) - Disk size (1 - 268435456 MB) :type data.size: integer :arg data.image: **required** (if size is not specified) - Disk image name :type data.image: string :arg data.model: Disk driver. One of virtio, ide, scsi (default: virtio) :type data.model: string :arg data.block_size: Block size for this disk (default: depends on OS Type) :type data.block_size: integer :arg data.compression: Disk compression algorithm. One of off, lzjb, gzip, gzip-N, zle, lz4 (default: off) :type data.compression: string :arg data.zpool: The zpool in which to create the disk (default: ``vm.zpool`` [zones]) :type data.zpool: string :arg data.boot: Whether this disk should be bootable (default: true for first disk, otherwise false) :type data.boot: boolean :arg data.refreservation: Minimum amount of space in MB reserved for this disk (KVM only, default: ``size``) :type data.refreservation: integer :arg data.image_tags_inherit: Whether to update VM tags from image tags (default: true) :type data.image_tags_inherit: boolean :status 201: SUCCESS :status 400: FAILURE :status 403: Forbidden :status 404: VM not found :status 406: VM disk out of range / VM disk already exists :status 423: VM is not operational / VM is locked or has slave VMs .. http:put:: /vm/(hostname_or_uuid)/define/disk/(disk_id) :DC-bound?: * |dc-yes| :Permissions: * |Admin| :Asynchronous?: * |async-no| :arg hostname_or_uuid: **required** - Server hostname or uuid :type hostname_or_uuid: string :arg disk_id: **required** - Disk number/ID (1 - 2) :type disk_id: integer :arg data.size: Disk size (1 - 268435456 MB) :type data.size: integer :arg data.model: Disk driver. One of virtio, ide, scsi :type data.model: string :arg data.block_size: Block size for this disk :type data.block_size: integer :arg data.compression: Disk compression algorithm. One of off, lzjb, gzip, gzip-N, zle, lz4 :type data.compression: string :arg data.zpool: The zpool in which to create the disk :type data.zpool: string :arg data.boot: Whether this disk should be bootable :type data.boot: boolean :arg data.refreservation: Minimum amount of space in MB reserved for this disk (KVM only) :type data.refreservation: integer :arg data.image_tags_inherit: Whether to update VM tags from image tags (default: true) :type data.image_tags_inherit: boolean :status 200: SUCCESS :status 400: FAILURE :status 403: Forbidden :status 404: VM not found :status 406: VM disk out of range :status 423: VM is not operational / VM is locked or has slave VMs .. http:delete:: /vm/(hostname_or_uuid)/define/disk/(disk_id) :DC-bound?: * |dc-yes| :Permissions: * |Admin| :Asynchronous?: * |async-no| :arg hostname_or_uuid: **required** - Server hostname or uuid :type hostname_or_uuid: string :arg disk_id: **required** - Disk number/ID (1 - 2) :type disk_id: integer :arg data.image_tags_inherit: Whether to update VM tags from image tags (default: true) :type data.image_tags_inherit: boolean :status 200: SUCCESS :status 400: FAILURE :status 403: Forbidden :status 404: VM not found :status 406: VM disk out of range :status 423: VM is not operational / VM is locked or has slave VMs """ vm = get_vm(request, hostname_or_uuid, exists_ok=True, noexists_fail=True, sr=('node', 'owner', 'template', 'slavevm'), check_node_status=None) try: disk_id = int(disk_id) - 1 except ValueError: raise BadRequest return VmDefineDiskView(request).response(vm, disk_id, data)
def put(self): if 'note' in self.data: # Changing backup note instead of restore (not logging!) return self.save_note() ser = BackupRestoreSerializer(data=self.data) if not ser.is_valid(): return FailureTaskResponse(self.request, ser.errors) self._check_bkp() self._check_bkp_node() # Prepare vm for restore request, bkp = self.request, self.bkp vm = get_vm(request, ser.data['target_hostname_or_uuid'], exists_ok=True, noexists_fail=True, check_node_status=None) if vm.node.status not in vm.node.STATUS_OPERATIONAL: raise NodeIsNotOperational if vm.locked: raise VmIsLocked if not vm.has_compatible_brand(bkp.vm_brand): raise PreconditionRequired('VM brand mismatch') disk_id, real_disk_id, zfs_filesystem = get_disk_id( request, vm, self.data, key='target_disk_id', default=None) tgt_disk = vm.json_active_get_disks()[disk_id - 1] if tgt_disk['size'] != bkp.disk_size: raise PreconditionRequired('Disk size mismatch') target_ns = vm.get_node_storage(real_disk_id) # The backup is first restored to a temporary dataset, so it is required to have as much free space # as the backup size (which we don't have -> so we use the backup disk size [pessimism]) if bkp.disk_size > target_ns.storage.size_free: raise PreconditionRequired( 'Not enough free space on target storage') if not ser.data['force'] and Snapshot.objects.only('id').filter( vm=vm, disk_id=real_disk_id).exists(): raise ExpectationFailed('VM has snapshots') if vm.status != vm.STOPPED: raise VmIsNotOperational(_('VM is not stopped')) if vm.tasks: raise VmHasPendingTasks self.msg = LOG_BKP_UPDATE self.obj = vm # Cache apiview and detail # noinspection PyUnusedLocal apiview = self.apiview # noqa: F841 # noinspection PyUnusedLocal detail = self.detail # noqa: F841 self._detail_ += ", target_hostname='%s', target_disk_id=%s" % ( vm.hostname, disk_id) self._apiview_['target_hostname'] = vm.hostname self._apiview_['target_disk_id'] = disk_id self._apiview_['force'] = ser.data['force'] if bkp.vm: self._apiview_['source_hostname'] = bkp.vm.hostname else: self._apiview_['source_hostname'] = '' vm.set_notready() if self.execute(get_backup_cmd('restore', bkp, zfs_filesystem=zfs_filesystem, vm=vm), lock=self.LOCK % (vm.uuid, disk_id)): bkp.save_status(bkp.RESTORE) return self.task_response vm.revert_notready() return self.error_response
def vm_define_snapshot(request, hostname_or_uuid, snapdef, data=None): """ Show (:http:get:`GET </vm/(hostname_or_uuid)/define/snapshot/(snapdef)>`), create (:http:post:`POST </vm/(hostname_or_uuid)/define/snapshot/(snapdef)>`), remove (:http:delete:`DELETE </vm/(hostname_or_uuid)/define/snapshot/(snapdef)>`) or update (:http:put:`PUT </vm/(hostname_or_uuid)/define/snapshot/(snapdef)>`) a VM snapshot definition and schedule. .. http:get:: /vm/(hostname_or_uuid)/define/snapshot/(snapdef) :DC-bound?: * |dc-yes| :Permissions: * |VmOwner| :Asynchronous?: * |async-no| :arg hostname_or_uuid: **required** - Server hostname or uuid :type hostname_or_uuid: string :arg snapdef: **required** - Snapshot definition name :type snapdef: string :arg data.disk_id: **required** - Disk number/ID (default: 1) :type data.disk_id: integer :arg data.extended: Include total number of snapshots (default: false) :type data.extended: boolean :status 200: SUCCESS :status 403: Forbidden :status 404: VM not found / Snapshot definition not found :status 412: Invalid disk_id .. http:post:: /vm/(hostname_or_uuid)/define/snapshot/(snapdef) :DC-bound?: * |dc-yes| :Permissions: * |Admin| :Asynchronous?: * |async-no| :arg hostname_or_uuid: **required** - Server hostname or uuid :type hostname_or_uuid: string :arg snapdef: **required** - Snapshot definition name (predefined: hourly, daily, weekly, monthly) :type snapdef: string :arg data.disk_id: **required** - Disk number/ID (default: 1) :type data.disk_id: integer :arg data.schedule: **required** - Schedule in UTC CRON format (e.g. 30 4 * * 6) :type data.schedule: string :arg data.retention: **required** - Maximum number of snapshots to keep :type data.retention: integer :arg data.active: Enable or disable snapshot schedule (default: true) :type data.active: boolean :arg data.desc: Snapshot definition description :type data.desc: string :arg data.fsfreeze: Whether to send filesystem freeze command to QEMU agent socket before \ creating snapshot (requires QEMU Guest Agent) (default: false) :type data.fsfreeze: boolean :status 200: SUCCESS :status 400: FAILURE :status 403: Forbidden :status 404: VM not found :status 406: Snapshot definition already exists :status 412: Invalid disk_id :status 423: Node is not operational / VM is not operational .. http:put:: /vm/(hostname_or_uuid)/define/snapshot/(snapdef) :DC-bound?: * |dc-yes| :Permissions: * |Admin| :Asynchronous?: * |async-no| :arg hostname_or_uuid: **required** - Server hostname or uuid :type hostname_or_uuid: string :arg snapdef: **required** - Snapshot definition name :type snapdef: string :arg data.disk_id: **required** - Disk number/ID (default: 1) :type data.disk_id: integer :arg data.schedule: Schedule in UTC CRON format (e.g. 30 4 * * 6) :type data.schedule: string :arg data.retention: Maximum number of snapshots to keep :type data.retention: integer :arg data.active: Enable or disable snapshot schedule :type data.active: boolean :arg data.desc: Snapshot definition description :type data.desc: string :status 200: SUCCESS :status 400: FAILURE :status 403: Forbidden :status 404: VM not found / Snapshot definition not found :status 412: Invalid disk_id :status 423: Node is not operational / VM is not operational .. http:delete:: /vm/(hostname_or_uuid)/define/snapshot/(snapdef) :DC-bound?: * |dc-yes| :Permissions: * |Admin| :Asynchronous?: * |async-no| :arg hostname_or_uuid: **required** - Server hostname or uuid :type hostname_or_uuid: string :arg snapdef: **required** - Snapshot definition name :type snapdef: string :arg data.disk_id: **required** - Disk number/ID (default: 1) :type data.disk_id: integer :status 200: SUCCESS :status 400: FAILURE :status 403: Forbidden :status 404: VM not found / Snapshot definition not found :status 412: Invalid disk_id :status 423: Node is not operational / VM is not operational """ vm = get_vm(request, hostname_or_uuid, exists_ok=True, noexists_fail=True) disk_id, real_disk_id, zfs_filesystem = get_disk_id(request, vm, data) extra = output_extended_snap_count(request, data) define = get_object(request, SnapshotDefine, { 'name': snapdef, 'vm': vm, 'disk_id': real_disk_id }, sr=('vm', 'periodic_task', 'periodic_task__crontab'), extra={'select': extra}) return SnapshotDefineView(request, data=data).response(vm, define, extended=bool(extra))
def vm_define_backup(request, hostname_or_uuid, bkpdef, data=None): """ Show (:http:get:`GET </vm/(hostname_or_uuid)/define/backup/(bkpdef)>`), create (:http:post:`POST </vm/(hostname_or_uuid)/define/backup/(bkpdef)>`), remove (:http:delete:`DELETE </vm/(hostname_or_uuid)/define/backup/(bkpdef)>`) or update (:http:put:`PUT </vm/(hostname_or_uuid)/define/backup/(bkpdef)>`) a VM backup definition and schedule. .. http:get:: /vm/(hostname_or_uuid)/define/backup/(bkpdef) :DC-bound?: * |dc-yes| :Permissions: * |VmOwner| :Asynchronous?: * |async-no| :arg hostname_or_uuid: **required** - Server hostname or uuid :type hostname_or_uuid: string :arg bkpdef: **required** - Backup definition name :type bkpdef: string :arg data.disk_id: **required** - Disk number/ID (default: 1) :type data.disk_id: integer :arg data.extended: Include total number of backups (default: false) :type data.extended: boolean :status 200: SUCCESS :status 403: Forbidden :status 404: VM not found / Backup definition not found :status 412: Invalid disk_id .. http:post:: /vm/(hostname_or_uuid)/define/backup/(bkpdef) :DC-bound?: * |dc-yes| :Permissions: * |Admin| :Asynchronous?: * |async-no| :arg hostname_or_uuid: **required** - Server hostname or uuid :type hostname_or_uuid: string :arg bkpdef: **required** - Backup definition name (predefined: hourly, daily, weekly, monthly) :type bkpdef: string :arg data.disk_id: **required** - Disk number/ID (default: 1) :type data.disk_id: integer :arg data.type: **required** - Backup type (1 - dataset, 2 - file) (default: 1) :type: data.type: integer :arg data.node: **required** - Name of the backup node :type data.node: string :arg data.zpool: **required** - The zpool used on the backup node (default: zones) :type data.zpool: string :arg data.schedule: **required** - Schedule in UTC CRON format (e.g. 30 4 * * 6) :type data.schedule: string :arg data.retention: **required** - Maximum number of backups to keep :type data.retention: integer :arg data.active: Enable or disable backup schedule (default: true) :type data.active: boolean :arg data.compression: Backup file compression algorithm (0 - none, 1 - gzip, 2 - bzip2) (default: 0) :type data.compression: integer :arg data.bwlimit: Transfer rate limit in bytes (default: null => no limit) :type data.bwlimit: integer :arg data.desc: Backup definition description :type data.desc: string :arg data.fsfreeze: Whether to send filesystem freeze command to QEMU agent socket before \ creating backup snapshot (requires QEMU Guest Agent) (default: false) :type data.fsfreeze: boolean :status 200: SUCCESS :status 400: FAILURE :status 403: Forbidden :status 404: VM not found :status 406: Backup definition already exists :status 412: Invalid disk_id :status 423: Node is not operational / VM is not operational .. http:put:: /vm/(hostname_or_uuid)/define/backup/(bkpdef) :DC-bound?: * |dc-yes| :Permissions: * |Admin| :Asynchronous?: * |async-no| :arg hostname_or_uuid: **required** - Server hostname or uuid :type hostname_or_uuid: string :arg bkpdef: **required** - Backup definition name :type bkpdef: string :arg data.disk_id: **required** - Disk number/ID (default: 1) :type data.disk_id: integer :arg data.schedule: Schedule in UTC CRON format (e.g. 30 4 * * 6) :type data.schedule: string :arg data.retention: Maximum number of backups to keep :type data.retention: integer :arg data.active: Enable or disable backup schedule :type data.active: boolean :arg data.compression: Backup file compression algorithm (0 - none, 1 - gzip, 2 - bzip2) :type data.compression: integer :arg data.bwlimit: Transfer rate limit in bytes :type data.bwlimit: integer :arg data.desc: Backup definition description :type data.desc: string :status 200: SUCCESS :status 400: FAILURE :status 403: Forbidden :status 404: VM not found / Backup definition not found :status 412: Invalid disk_id :status 423: Node is not operational / VM is not operational .. http:delete:: /vm/(hostname_or_uuid)/define/backup/(bkpdef) :DC-bound?: * |dc-yes| :Permissions: * |Admin| :Asynchronous?: * |async-no| :arg hostname_or_uuid: **required** - Server hostname or uuid :type hostname_or_uuid: string :arg bkpdef: **required** - Backup definition name :type bkpdef: string :arg data.disk_id: **required** - Disk number/ID (default: 1) :type data.disk_id: integer :status 200: SUCCESS :status 400: FAILURE :status 403: Forbidden :status 404: VM not found / Backup definition not found :status 412: Invalid disk_id :status 423: Node is not operational / VM is not operational """ vm = get_vm(request, hostname_or_uuid, exists_ok=True, noexists_fail=True) disk_id, real_disk_id, zfs_filesystem = get_disk_id(request, vm, data) extra = output_extended_backup_count(request, data) define = get_object(request, BackupDefine, { 'name': bkpdef, 'vm': vm, 'disk_id': real_disk_id }, sr=('vm', 'vm__dc', 'node', 'periodic_task', 'periodic_task__crontab'), extra={'select': extra}) return BackupDefineView(request, data=data).response(vm, define, extended=bool(extra))
def image_snapshot(request, hostname_or_uuid, snapname, name, data=None): """ Create (:http:post:`POST </vm/(hostname_or_uuid)/snapshot/(snapname)/image/(name)>`) a server disk image from a disk snapshot. .. note:: A global image server (:http:put:`VMS_IMAGE_VM </dc/(dc)/settings>`) must be configured in the system. .. http:post:: /vm/(hostname_or_uuid)/snapshot/(snapname)/image/(name) :DC-bound?: * |dc-yes| :Permissions: * |ImageAdmin| :Asynchronous?: * |async-yes| :arg name: **required** - Server disk image name :type name: string :arg hostname_or_uuid: **required** - Server hostname or uuid :type hostname_or_uuid: string :arg snapname: **required** - Snapshot name :type snapname: string :arg data.disk_id: **required** - Disk number/ID (default: 1) :type data.disk_id: integer :arg data.alias: Short image name (default: ``name``) :type data.alias: string :arg data.access: Access type (1 - Public, 3 - Private, 4 - Deleted) (default: 3) :type data.access: integer :arg data.owner: User that owns the image (default: logged in user) :type data.owner: string :arg data.desc: Image description :type data.desc: string :arg data.version: Image version (default: 1.0) :type data.version: string :arg data.resize: Whether the image is able to resize the disk during an initial start or deploy process \ (default: false) :type data.resize: boolean :arg data.deploy: Whether the image is able to shut down the server after an initial start (default: false) :type data.deploy: boolean :status 200: SUCCESS :status 201: PENDING :status 400: FAILURE :status 403: Forbidden :status 404: VM not found :status 406: Image already exists :status 412: Invalid disk_id :status 423: Node is not operational / VM is not operational :status 417: Image status is not OK / VM snapshot status is not OK :status 428: Image server is not available """ from api.utils.db import get_object from api.vm.utils import get_vm from api.vm.snapshot.utils import get_disk_id from vms.models import Snapshot vm = get_vm(request, hostname_or_uuid, exists_ok=True, noexists_fail=True) disk_id, real_disk_id, zfs_filesystem = get_disk_id(request, vm, data) snap = get_object(request, Snapshot, { 'name': snapname, 'vm': vm, 'disk_id': real_disk_id }, exists_ok=True, noexists_fail=True) assert zfs_filesystem == snap.zfs_filesystem return ImageView(request, name, data).create(vm, snap)
def vm_define(request, hostname_or_uuid, data=None): """ Show (:http:get:`GET </vm/(hostname_or_uuid)/define>`), create (:http:post:`POST </vm/(hostname_or_uuid)/define>`), change (:http:put:`PUT </vm/(hostname_or_uuid)/define>`) or delete (:http:delete:`DELETE </vm/(hostname_or_uuid)/define>`) a VM definition. .. http:get:: /vm/(hostname_or_uuid)/define :DC-bound?: * |dc-yes| :Permissions: * |VmOwner| :Asynchronous?: * |async-no| :arg hostname_or_uuid: **required** - Server hostname or uuid :type hostname_or_uuid: string :arg data.full: Display full VM definition (including disk and nic lists) (default: false) :type data.full: boolean :arg data.active: Display currently active VM definition on compute node (default: false) :type data.active: boolean :arg data.diff: Display differences between active VM definition on compute node and current configuration \ (default: false) :type data.diff: boolean :status 200: SUCCESS :status 403: Forbidden :status 404: VM not found .. http:post:: /vm/(hostname_or_uuid)/define :DC-bound?: * |dc-yes| :Permissions: * |Admin| :Asynchronous?: * |async-no| :arg hostname_or_uuid: **required** - Server hostname :type hostname_or_uuid: string :arg data.alias: Short server name (default: ``hostname``) :type data.alias: string :arg data.template: VM template name (default: null) :type data.template: string :arg data.ostype: Operating system type (1 - Linux VM, 2 - SunOS VM, 3 - BSD VM, 4 - Windows VM, \ 5 - SunOS Zone, 6 - Linux Zone) (default: 1) :type data.ostype: integer :arg data.vcpus: **required** - Number of virtual CPUs inside VM (1 - 1024); \ This number is used to calculate an internal compute node CPU limit for the VM (cpu_cap). \ When the :http:put:`VMS_VM_CPU_CAP_REQUIRED </dc/(dc)/settings>` DC setting is disabled, \ then the vcpus value can be 0, which will remove the compute node CPU limit entirely (SunOS and LX Zone only) :type data.vcpus: integer :arg data.ram: **required** - Size of RAM inside VM (1 - 1048576 MB) :type data.ram: integer :arg data.note: Text note visible to every user with access to this VM (default: "") :type data.note: string :arg data.owner: User that owns the VM (default: logged in user) :type data.owner: string :arg data.node: Name of the host system \ (default: null => will be chosen automatically just before the VM is created) :type data.node: string :arg data.tags: Custom VM tags (default: []) :type data.tags: array :arg data.monitored: Enable VM synchronization with monitoring system (default: true) :type data.monitored: boolean :arg data.monitored_internal: Enable VM synchronization with internal monitoring system \ (requires |SuperAdmin| permission) (default: true) :type data.monitored: boolean :arg data.installed: Mark the server as installed (default: false) :type data.installed: boolean :arg data.snapshot_limit_manual: Maximum number of manual snapshots for this VM (default: null [unlimited]) :type data.snapshot_limit_manual: integer :arg data.snapshot_size_percent_limit: Maximum size of all snapshots for this VM relative to size of all \ defined VM disks. Ignored if ``snapshot_size_limit`` is defined (default: null [unlimited]) :type data.snapshot_size_percent_limit: integer :arg data.snapshot_size_limit: Maximum absolute size of all snapshots for this VM in megabytes \ (default: null [unlimited]) :type data.snapshot_size_limit: integer :arg data.zpool: The zpool used for the VM (default: zones) :type data.zpool: string :arg data.cpu_shares: Number of VM's CPU shares relative to other VMs (requires |SuperAdmin| permission) \ (default: 100) :type data.cpu_shares: integer :arg data.zfs_io_priority: IO throttle priority relative to other VMs (requires |SuperAdmin| permission) \ (default: 100) :type data.zfs_io_priority: integer :arg data.cpu_type: **KVM only**; Type of the virtual CPU exposed to the VM. One of qemu64, host \ (default: qemu64; except for Windows ``ostype`` where the default is host) :type data.cpu_type: string :arg data.vga: **KVM only**; VGA emulation driver. One of std, cirrus, vmware (default: std) :type data.vga: string :arg data.bootrom: **BHYVE only**; Default VM boot firmware. One of bios, uefi (default: bios). \ Only uefi mode supports VNC. :type data.bootrom: string :arg data.dns_domain: Search domain set in /etc/hosts (SunOS Zone only, default: domain part of ``hostname``) :type data.dns_domain: string :arg data.routes: Key-value object that maps destinations to gateways. \ Items will be set as static routes in the OS (SunOS Zone only, default: {}) :type data.routes: object :arg data.monitoring_hostgroups: Custom VM monitoring hostgroups (default: []) :type data.monitoring_hostgroups: array :arg data.monitoring_templates: Custom VM monitoring templates (default: []) :type data.monitoring_templates: array :arg data.mdata: Customer metadata accessible from within the VM (key=value string pairs) (default: {}) :type data.mdata: object :status 201: SUCCESS :status 400: FAILURE :status 403: Forbidden :status 406: VM already exists .. note:: The **cpu_cap** defines a percentage of a single compute node CPU that can be used by the VM. \ It is calculated automatically based on this formula: \ ``(vcpus * VMS_VM_CPU_BURST_RATIO * 100) + VMS_VM_CPU_BURST_DEFAULT``, where \ *VMS_VM_CPU_BURST_RATIO* is by default 1.0 and \ *VMS_VM_CPU_BURST_DEFAULT* is by default 100 when ``vcpus > 1`` and 50 when ``vcpus == 1``. .. http:put:: /vm/(hostname_or_uuid)/define :DC-bound?: * |dc-yes| :Permissions: * |Admin| :Asynchronous?: * |async-no| :arg hostname_or_uuid: **required** - Server hostname or uuid :type hostname_or_uuid: string :arg data.alias: Short server name :type data.alias: string :arg data.template: VM template name :type data.template: string :arg data.vcpus: Number of virtual CPUs inside VM (1 - 1024); \ This number is used to calculate an internal compute node CPU limit for the VM (cpu_cap). \ When the :http:put:`VMS_VM_CPU_CAP_REQUIRED </dc/(dc)/settings>` DC setting is disabled, \ then the vcpus value can be 0, which will remove the compute node CPU limit entirely (SunOS and LX Zone only) :type data.vcpus: integer :arg data.ram: Size of RAM inside VM (1 - 1048576 MB) :type data.ram: integer :arg data.note: Text note visible to every user with access to this VM :type data.note: string :arg data.owner: User that owns the VM :type data.owner: string :arg data.node: Name of the host system :type data.node: string :arg data.tags: Custom VM tags :type data.tags: array :arg data.monitored: Enable VM synchronization with monitoring system :type data.monitored: boolean :arg data.monitored_internal: Enable VM synchronization with internal monitoring system \ (requires |SuperAdmin| permission) :type data.monitored: boolean :arg data.installed: Mark the server as installed :type data.installed: boolean :arg data.snapshot_limit_manual: Maximum number of manual snapshots for this VM :type data.snapshot_limit_manual: integer :type data.snapshot_limit_manual: integer :arg data.snapshot_size_percent_limit: Maximum size of all snapshots for this VM relative to size of all \ defined VM disks. Ignored if ``snapshot_size_limit`` is defined :arg data.snapshot_size_limit: Maximum absolute size of all snapshots for this VM in megabytes :type data.snapshot_size_limit: integer :arg data.zpool: The zpool used for the VM zone :type data.zpool: string :arg data.cpu_shares: Number of VM's CPU shares relative to other VMs (requires |SuperAdmin| permission) :type data.cpu_shares: integer :arg data.zfs_io_priority: IO throttle priority relative to other VMs (requires |SuperAdmin| permission) :type data.zfs_io_priority: integer :arg data.cpu_type: **KVM only**; Type of the virtual CPU exposed to the VM. One of qemu64, host :type data.cpu_type: string :arg data.vga: **KVM only**; VGA emulation driver. One of std, cirrus, vmware :type data.vga: string :arg data.bootrom: **BHYVE only**; Default VM boot firmware. One of bios, uefi (default: bios). \ Only uefi mode supports VNC. :type data.bootrom: string :arg data.dns_domain: Search domain set in /etc/hosts (SunOS Zone only) :type data.dns_domain: string :arg data.routes: Key-value object that maps destinations to gateways. \ Items will be set as static routes in the OS (SunOS Zone only) :type data.routes: object :arg data.monitoring_hostgroups: Custom VM monitoring hostgroups :type data.monitoring_hostgroups: array :arg data.monitoring_templates: Custom VM monitoring templates :type data.monitoring_templates: array :arg data.mdata: Customer metadata accessible from within the VM (key=value string pairs) :type data.mdata: object :status 200: SUCCESS :status 400: FAILURE :status 403: Forbidden :status 404: VM not found :status 409: VM has pending tasks :status 423: VM is not operational / VM is locked or has slave VMs .. http:delete:: /vm/(hostname_or_uuid)/define :DC-bound?: * |dc-yes| :Permissions: * |Admin| :Asynchronous?: * |async-no| :arg hostname_or_uuid: **required** - Server hostname or uuid :type hostname_or_uuid: string :status 200: SUCCESS :status 400: FAILURE :status 403: Forbidden :status 404: VM not found :status 409: VM has pending tasks :status 423: VM is not operational / VM is not notcreated / VM is locked or has slave VMs """ vm = get_vm(request, hostname_or_uuid, sr=('owner', 'node', 'template', 'slavevm'), check_node_status=None, noexists_fail=False, exists_ok=False) return VmDefineView(request).response(vm, data, hostname_or_uuid=hostname_or_uuid)