mirror of
https://github.com/retspen/webvirtcloud
synced 2024-12-25 15:45:23 +00:00
commit
3da734e804
6 changed files with 264 additions and 36 deletions
|
@ -13,15 +13,15 @@
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
{% ifequal status 5 %}
|
{% if status == 5 %}
|
||||||
<span class="label label-danger">{% trans "Off" %}</span>
|
<span class="label label-danger">{% trans "Off" %}</span>
|
||||||
{% endifequal %}
|
{% endif %}
|
||||||
{% ifequal status 1 %}
|
{% if status == 1 %}
|
||||||
<span class="label label-success">{% trans "Active" %}</span>
|
<span class="label label-success">{% trans "Active" %}</span>
|
||||||
{% endifequal %}
|
{% endif %}
|
||||||
{% ifequal status 3 %}
|
{% if status == 3 %}
|
||||||
<span class="label label-warning">{% trans "Suspend" %}</span>
|
<span class="label label-warning">{% trans "Suspend" %}</span>
|
||||||
{% endifequal %}
|
{% endif %}
|
||||||
|
|
|
|
||||||
{% if cur_vcpu %}
|
{% if cur_vcpu %}
|
||||||
{{ cur_vcpu }} {% trans "Vcpu" %}
|
{{ cur_vcpu }} {% trans "Vcpu" %}
|
||||||
|
@ -34,6 +34,22 @@
|
||||||
{% for disk in disks %}
|
{% for disk in disks %}
|
||||||
{{ disk.size|filesizeformat }} {% trans "Disk" %} |
|
{{ disk.size|filesizeformat }} {% trans "Disk" %} |
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
<button
|
||||||
|
{% if guest_agent == True %}
|
||||||
|
{% if guest_agent_ready == True %}
|
||||||
|
class="btn btn-xs btn-success"
|
||||||
|
title="Guest Agent Enabled & Connected"
|
||||||
|
{% else %}
|
||||||
|
class="btn btn-xs btn-default"
|
||||||
|
title="Guest Agent Enabled but not Connected"
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
class="btn btn-xs btn-danger"
|
||||||
|
title="Guest Agent Not Enabled & Not Connected"
|
||||||
|
{% endif %} disabled>
|
||||||
|
<span class="glyphicon glyphicon-flash"></span>
|
||||||
|
</button>
|
||||||
|
|
|
||||||
<a href="{% url 'instance' compute.id vname %}" type="button" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-refresh"></span></a>
|
<a href="{% url 'instance' compute.id vname %}" type="button" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-refresh"></span></a>
|
||||||
<em>on</em>
|
<em>on</em>
|
||||||
<a href="{% url 'overview' compute.id %}"><span class="label label-primary">{{ compute.name }}{% if compute.name != compute.hostname %} - {{ compute.hostname }}{% endif %} </span></a>
|
<a href="{% url 'overview' compute.id %}"><span class="label label-primary">{{ compute.name }}{% if compute.name != compute.hostname %} - {{ compute.hostname }}{% endif %} </span></a>
|
||||||
|
@ -876,7 +892,9 @@
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans 'Name' %}</th>
|
<th>{% trans 'Name' %}</th>
|
||||||
<th>{% trans 'MAC' %}</th>
|
<th>{% trans 'MAC' %}</th>
|
||||||
<th>{% trans 'NIC' %}</th>
|
<th>{% trans 'IP Address' %}</th>
|
||||||
|
<th>{% trans 'Source' %}</th>
|
||||||
|
<th>{% trans 'LinkState' %}</th>
|
||||||
<th>{% trans 'Filter' %}</th>
|
<th>{% trans 'Filter' %}</th>
|
||||||
<th>{% trans 'Qos' %}</th>
|
<th>{% trans 'Qos' %}</th>
|
||||||
<th>{% trans 'Actions' %}</th>
|
<th>{% trans 'Actions' %}</th>
|
||||||
|
@ -885,10 +903,20 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for network in networks %}
|
{% for network in networks %}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="col-sm-2"><label>eth{{ forloop.counter0 }}({{ network.target|default:"no target" }})</label></td>
|
<td class="col-sm-1">eth{{ forloop.counter0 }}({{ network.target|default:"no target" }})</td>
|
||||||
<td><input class="form-control" type="text" value="{{ network.mac }}" readonly/></td>
|
<td>{{ network.mac }}</td>
|
||||||
<td><input class="form-control" type="text" value="{{ network.nic }}" readonly/></td>
|
<td>{{ network.ipv4|default:"unknown" }}</td>
|
||||||
<td><input class="form-control" type="text" value="{{ network.filterref }}" readonly/></td>
|
<td>{{ network.nic }}</td>
|
||||||
|
<td>
|
||||||
|
<form method="post">{% csrf_token %}
|
||||||
|
<input name="mac" value="{{ network.mac }}" hidden/>
|
||||||
|
<input name="set_link_state" value="{{ network.state }}" hidden/>
|
||||||
|
<input type="checkbox" {% if network.state == 'up' %} checked
|
||||||
|
{% endif %} onclick='submit();' />
|
||||||
|
{% trans 'active' %}
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
<td>{{ network.filterref|default:"None" }}</td>
|
||||||
<td>
|
<td>
|
||||||
<form class="form-horizontal" method="post" name="add_qos{{ forloop.counter0 }}" role="form">{% csrf_token %}
|
<form class="form-horizontal" method="post" name="add_qos{{ forloop.counter0 }}" role="form">{% csrf_token %}
|
||||||
<input type="text" name="net-mac-{{ forloop.counter0 }}" value="{{ network.mac }}" hidden/>
|
<input type="text" name="net-mac-{{ forloop.counter0 }}" value="{{ network.mac }}" hidden/>
|
||||||
|
@ -1403,7 +1431,7 @@
|
||||||
<p>{% trans "To set instance vCPUs hotpluggable" %}</p>
|
<p>{% trans "To set instance vCPUs hotpluggable" %}</p>
|
||||||
<form class="form-horizontal" method="post" role="form">{% csrf_token %}
|
<form class="form-horizontal" method="post" role="form">{% csrf_token %}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="video_model_select" class="col-sm-3 control-label">{% trans "vCPU Hot Plug" %}</label>
|
<label for="vcpu_hotplug" class="col-sm-3 control-label">{% trans "vCPU Hot Plug" %}</label>
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<select id="vcpu_hotplug" class="form-control" name="vcpu_hotplug">
|
<select id="vcpu_hotplug" class="form-control" name="vcpu_hotplug">
|
||||||
|
@ -1423,6 +1451,35 @@
|
||||||
</form>
|
</form>
|
||||||
<div class="clearfix"></div>
|
<div class="clearfix"></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="well">
|
||||||
|
<p>{% trans "To Enable/Disable Qemu Guest Agent. Status:" %}
|
||||||
|
{% if status == 1 %}
|
||||||
|
{% if guest_agent_ready %}
|
||||||
|
<label class="label label-success">{% trans 'Connected' %}</label>
|
||||||
|
{% else %}
|
||||||
|
<label class="label label-danger">{% trans 'Disconnected' %}</label>
|
||||||
|
{% endif %}</p>
|
||||||
|
{% else %}
|
||||||
|
<label class="label label-default">{% trans 'Unknown' %}</label>
|
||||||
|
{% endif %}
|
||||||
|
<form class="form-horizontal" method="post" role="form">{% csrf_token %}
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="guest_agent" class="col-sm-3 control-label">{% trans "Qemu Guest Agent" %}</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<div class="input-group">
|
||||||
|
<select id="guest_agent" class="form-control" name="guest_agent">
|
||||||
|
<option value="True" {% if guest_agent %} selected {% endif %}>{% trans 'Enabled' %}</option>
|
||||||
|
<option value="False" {% if not guest_agent %} selected {% endif %}>{% trans 'Disabled' %}</option>
|
||||||
|
</select>
|
||||||
|
<span class="input-group-btn">
|
||||||
|
<button type="submit" class="btn btn-success" name="set_guest_agent">{% trans "Set" %}</button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<div class="clearfix"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -266,6 +266,7 @@ def instance(request, compute_id, vname):
|
||||||
compute.password,
|
compute.password,
|
||||||
compute.type,
|
compute.type,
|
||||||
vname)
|
vname)
|
||||||
|
|
||||||
status = conn.get_status()
|
status = conn.get_status()
|
||||||
autostart = conn.get_autostart()
|
autostart = conn.get_autostart()
|
||||||
bootmenu = conn.get_bootmenu()
|
bootmenu = conn.get_bootmenu()
|
||||||
|
@ -282,7 +283,7 @@ def instance(request, compute_id, vname):
|
||||||
cur_memory = conn.get_cur_memory()
|
cur_memory = conn.get_cur_memory()
|
||||||
title = conn.get_title()
|
title = conn.get_title()
|
||||||
description = conn.get_description()
|
description = conn.get_description()
|
||||||
networks = conn.get_net_device()
|
networks = conn.get_net_devices()
|
||||||
qos = conn.get_all_qos()
|
qos = conn.get_all_qos()
|
||||||
disks = conn.get_disk_devices()
|
disks = conn.get_disk_devices()
|
||||||
media = conn.get_media_devices()
|
media = conn.get_media_devices()
|
||||||
|
@ -302,6 +303,8 @@ def instance(request, compute_id, vname):
|
||||||
console_port = conn.get_console_port()
|
console_port = conn.get_console_port()
|
||||||
console_keymap = conn.get_console_keymap()
|
console_keymap = conn.get_console_keymap()
|
||||||
console_listen_address = conn.get_console_listen_addr()
|
console_listen_address = conn.get_console_listen_addr()
|
||||||
|
guest_agent = False if conn.get_guest_agent() is None else True
|
||||||
|
guest_agent_ready = conn.is_agent_ready()
|
||||||
video_model = conn.get_video_model()
|
video_model = conn.get_video_model()
|
||||||
snapshots = sorted(conn.get_snapshot(), reverse=True, key=lambda k: k['date'])
|
snapshots = sorted(conn.get_snapshot(), reverse=True, key=lambda k: k['date'])
|
||||||
inst_xml = conn._XMLDesc(VIR_DOMAIN_XML_SECURE)
|
inst_xml = conn._XMLDesc(VIR_DOMAIN_XML_SECURE)
|
||||||
|
@ -342,10 +345,15 @@ def instance(request, compute_id, vname):
|
||||||
bus_host = conn.get_disk_bus_types(arch, machine)
|
bus_host = conn.get_disk_bus_types(arch, machine)
|
||||||
videos_host = conn.get_video_models(arch, machine)
|
videos_host = conn.get_video_models(arch, machine)
|
||||||
networks_host = sorted(conn.get_networks())
|
networks_host = sorted(conn.get_networks())
|
||||||
interfaces_host = sorted(conn.get_ifaces())
|
|
||||||
nwfilters_host = conn.get_nwfilters()
|
nwfilters_host = conn.get_nwfilters()
|
||||||
storages_host = sorted(conn.get_storages(True))
|
storages_host = sorted(conn.get_storages(True))
|
||||||
|
|
||||||
|
try:
|
||||||
|
interfaces_host = sorted(conn.get_ifaces())
|
||||||
|
except Exception as e:
|
||||||
|
addlogmsg(request.user.username, instance.name, e)
|
||||||
|
error_messages.append(e)
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
if 'poweron' in request.POST:
|
if 'poweron' in request.POST:
|
||||||
if instance.is_template:
|
if instance.is_template:
|
||||||
|
@ -616,7 +624,7 @@ def instance(request, compute_id, vname):
|
||||||
return HttpResponseRedirect(request.get_full_path() + '#disks')
|
return HttpResponseRedirect(request.get_full_path() + '#disks')
|
||||||
|
|
||||||
if 'add_cdrom' in request.POST and allow_admin_or_not_template:
|
if 'add_cdrom' in request.POST and allow_admin_or_not_template:
|
||||||
bus = request.POST.get('bus', 'ide')
|
bus = request.POST.get('bus', 'ide' if machine == 'pc' else 'sata')
|
||||||
target = get_new_disk_dev(media, disks, bus)
|
target = get_new_disk_dev(media, disks, bus)
|
||||||
conn.attach_disk("", target, device='cdrom', cache='none', targetbus=bus)
|
conn.attach_disk("", target, device='cdrom', cache='none', targetbus=bus)
|
||||||
msg = _('Add CD-ROM: ' + target)
|
msg = _('Add CD-ROM: ' + target)
|
||||||
|
@ -804,6 +812,17 @@ def instance(request, compute_id, vname):
|
||||||
return HttpResponseRedirect(request.get_full_path() + '#vncsettings')
|
return HttpResponseRedirect(request.get_full_path() + '#vncsettings')
|
||||||
|
|
||||||
if request.user.is_superuser:
|
if request.user.is_superuser:
|
||||||
|
if 'set_guest_agent' in request.POST:
|
||||||
|
status = request.POST.get('guest_agent')
|
||||||
|
if status == 'True':
|
||||||
|
conn.add_guest_agent()
|
||||||
|
if status == 'False':
|
||||||
|
conn.remove_guest_agent()
|
||||||
|
|
||||||
|
msg = _("Set Quest Agent {}".format(status))
|
||||||
|
addlogmsg(request.user.username, instance.name, msg)
|
||||||
|
return HttpResponseRedirect(request.get_full_path() + '#options')
|
||||||
|
|
||||||
if 'set_video_model' in request.POST:
|
if 'set_video_model' in request.POST:
|
||||||
video_model = request.POST.get('video_model', 'vga')
|
video_model = request.POST.get('video_model', 'vga')
|
||||||
conn.set_video_model(video_model)
|
conn.set_video_model(video_model)
|
||||||
|
@ -867,6 +886,15 @@ def instance(request, compute_id, vname):
|
||||||
addlogmsg(request.user.username, instance.name, msg)
|
addlogmsg(request.user.username, instance.name, msg)
|
||||||
return HttpResponseRedirect(request.get_full_path() + '#network')
|
return HttpResponseRedirect(request.get_full_path() + '#network')
|
||||||
|
|
||||||
|
if 'set_link_state' in request.POST:
|
||||||
|
mac_address = request.POST.get('mac', '')
|
||||||
|
state = request.POST.get('set_link_state')
|
||||||
|
state = 'down' if state == 'up' else 'up'
|
||||||
|
conn.set_link_state(mac_address, state)
|
||||||
|
msg = _("Set Link State: {}".format(state))
|
||||||
|
addlogmsg(request.user.username, instance.name, msg)
|
||||||
|
return HttpResponseRedirect(request.get_full_path() + '#network')
|
||||||
|
|
||||||
if 'set_qos' in request.POST:
|
if 'set_qos' in request.POST:
|
||||||
qos_dir = request.POST.get('qos_direction', '')
|
qos_dir = request.POST.get('qos_direction', '')
|
||||||
average = request.POST.get('qos_average') or 0
|
average = request.POST.get('qos_average') or 0
|
||||||
|
|
|
@ -30,7 +30,7 @@ def interfaces(request, compute_id):
|
||||||
compute.type)
|
compute.type)
|
||||||
ifaces = conn.get_ifaces()
|
ifaces = conn.get_ifaces()
|
||||||
try:
|
try:
|
||||||
netdevs = conn.get_net_device()
|
netdevs = conn.get_net_devices()
|
||||||
except:
|
except:
|
||||||
netdevs = ['eth0', 'eth1']
|
netdevs = ['eth0', 'eth1']
|
||||||
|
|
||||||
|
|
|
@ -351,7 +351,7 @@ class wvmConnect(object):
|
||||||
def get_dom_cap_xml(self, arch, machine):
|
def get_dom_cap_xml(self, arch, machine):
|
||||||
""" Return domain capabilities xml"""
|
""" Return domain capabilities xml"""
|
||||||
emulatorbin = self.get_emulator(arch)
|
emulatorbin = self.get_emulator(arch)
|
||||||
virttype = self.get_hypervisors_domain_types()[arch][0]
|
virttype = 'kvm' if 'kvm' in self.get_hypervisors_domain_types()[arch] else 'qemu'
|
||||||
|
|
||||||
machine_types = self.get_machine_types(arch)
|
machine_types = self.get_machine_types(arch)
|
||||||
if not machine or machine not in machine_types:
|
if not machine or machine not in machine_types:
|
||||||
|
@ -686,7 +686,7 @@ class wvmConnect(object):
|
||||||
instance.append(dom.name())
|
instance.append(dom.name())
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
def get_net_device(self):
|
def get_net_devices(self):
|
||||||
netdevice = []
|
netdevice = []
|
||||||
|
|
||||||
def get_info(doc):
|
def get_info(doc):
|
||||||
|
|
|
@ -11,6 +11,7 @@ try:
|
||||||
VIR_MIGRATE_COMPRESSED, \
|
VIR_MIGRATE_COMPRESSED, \
|
||||||
VIR_MIGRATE_AUTO_CONVERGE, \
|
VIR_MIGRATE_AUTO_CONVERGE, \
|
||||||
VIR_MIGRATE_POSTCOPY
|
VIR_MIGRATE_POSTCOPY
|
||||||
|
from libvirt import VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT
|
||||||
except:
|
except:
|
||||||
from libvirt import libvirtError, VIR_DOMAIN_XML_SECURE, VIR_MIGRATE_LIVE
|
from libvirt import libvirtError, VIR_DOMAIN_XML_SECURE, VIR_MIGRATE_LIVE
|
||||||
|
|
||||||
|
@ -148,6 +149,7 @@ class wvmInstances(wvmConnect):
|
||||||
class wvmInstance(wvmConnect):
|
class wvmInstance(wvmConnect):
|
||||||
def __init__(self, host, login, passwd, conn, vname):
|
def __init__(self, host, login, passwd, conn, vname):
|
||||||
wvmConnect.__init__(self, host, login, passwd, conn)
|
wvmConnect.__init__(self, host, login, passwd, conn)
|
||||||
|
self._ip_cache = None
|
||||||
self.instance = self.get_instance(vname)
|
self.instance = self.get_instance(vname)
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
|
@ -276,17 +278,72 @@ class wvmInstance(wvmConnect):
|
||||||
range_pcpus = xrange(1, int(pcpus + 1))
|
range_pcpus = xrange(1, int(pcpus + 1))
|
||||||
return range_pcpus
|
return range_pcpus
|
||||||
|
|
||||||
def get_net_device(self):
|
def get_interface_addresses(self, iface_mac):
|
||||||
def get_mac_ipaddr(net, mac_host):
|
if self._ip_cache is None:
|
||||||
def fixed(doc):
|
self.refresh_interface_addresses()
|
||||||
for net in doc.xpath('/network/ip/dhcp/host'):
|
|
||||||
mac = net.xpath('@mac')[0]
|
|
||||||
host = net.xpath('@ip')[0]
|
|
||||||
if mac == mac_host:
|
|
||||||
return host
|
|
||||||
return None
|
|
||||||
|
|
||||||
return util.get_xml_path(net.XMLDesc(0), func=fixed)
|
qemuga = self._ip_cache["qemuga"]
|
||||||
|
arp = self._ip_cache["arp"]
|
||||||
|
leases = []
|
||||||
|
|
||||||
|
def extract_dom(info):
|
||||||
|
ipv4 = None
|
||||||
|
ipv6 = None
|
||||||
|
for addrs in info.values():
|
||||||
|
if addrs["hwaddr"] != iface_mac:
|
||||||
|
continue
|
||||||
|
if not addrs["addrs"]:
|
||||||
|
continue
|
||||||
|
for addr in addrs["addrs"]:
|
||||||
|
if addr["type"] == 0:
|
||||||
|
ipv4 = addr["addr"]
|
||||||
|
elif (addr["type"] == 1 and
|
||||||
|
not str(addr["addr"]).startswith("fe80")):
|
||||||
|
ipv6 = addr["addr"] + "/" + str(addr["prefix"])
|
||||||
|
return ipv4, ipv6
|
||||||
|
|
||||||
|
def extract_lease(info):
|
||||||
|
ipv4 = None
|
||||||
|
ipv6 = None
|
||||||
|
if info["mac"] == iface_mac:
|
||||||
|
if info["type"] == 0:
|
||||||
|
ipv4 = info["ipaddr"]
|
||||||
|
elif info["type"] == 1:
|
||||||
|
ipv6 = info["ipaddr"]
|
||||||
|
return ipv4, ipv6
|
||||||
|
|
||||||
|
for ips in ([qemuga] + leases + [arp]):
|
||||||
|
if "expirytime" in ips:
|
||||||
|
ipv4, ipv6 = extract_lease(ips)
|
||||||
|
else:
|
||||||
|
ipv4, ipv6 = extract_dom(ips)
|
||||||
|
if ipv4 or ipv6:
|
||||||
|
return ipv4, ipv6
|
||||||
|
return None, None
|
||||||
|
|
||||||
|
def _get_interface_addresses(self, source):
|
||||||
|
#("Calling interfaceAddresses source=%s", source)
|
||||||
|
try:
|
||||||
|
return self.instance.interfaceAddresses(source)
|
||||||
|
except Exception as e:
|
||||||
|
#log.debug("interfaceAddresses failed: %s", str(e))
|
||||||
|
pass
|
||||||
|
return {}
|
||||||
|
|
||||||
|
def refresh_interface_addresses(self):
|
||||||
|
self._ip_cache = {"qemuga": {}, "arp": {}}
|
||||||
|
|
||||||
|
if not self.get_status() == 1:
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.is_agent_ready():
|
||||||
|
self._ip_cache["qemuga"] = self._get_interface_addresses(
|
||||||
|
VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT)
|
||||||
|
|
||||||
|
arp_flag = 3 # libvirt."VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_ARP"
|
||||||
|
self._ip_cache["arp"] = self._get_interface_addresses(arp_flag)
|
||||||
|
|
||||||
|
def get_net_devices(self):
|
||||||
|
|
||||||
def networks(ctx):
|
def networks(ctx):
|
||||||
result = []
|
result = []
|
||||||
|
@ -295,6 +352,7 @@ class wvmInstance(wvmConnect):
|
||||||
mac_inst = net.xpath('mac/@address')[0]
|
mac_inst = net.xpath('mac/@address')[0]
|
||||||
nic_inst = net.xpath('source/@network|source/@bridge|source/@dev')[0]
|
nic_inst = net.xpath('source/@network|source/@bridge|source/@dev')[0]
|
||||||
target_inst = '' if not net.xpath('target/@dev') else net.xpath('target/@dev')[0]
|
target_inst = '' if not net.xpath('target/@dev') else net.xpath('target/@dev')[0]
|
||||||
|
link_state = 'up' if not net.xpath('link') else net.xpath('link/@state')[0]
|
||||||
filterref_inst = '' if not net.xpath('filterref/@filter') else net.xpath('filterref/@filter')[0]
|
filterref_inst = '' if not net.xpath('filterref/@filter') else net.xpath('filterref/@filter')[0]
|
||||||
if net.xpath('bandwidth/inbound'):
|
if net.xpath('bandwidth/inbound'):
|
||||||
in_attr = net.xpath('bandwidth/inbound')[0]
|
in_attr = net.xpath('bandwidth/inbound')[0]
|
||||||
|
@ -310,14 +368,15 @@ class wvmInstance(wvmConnect):
|
||||||
outbound = {'average': out_av, 'peak': out_peak, 'burst': out_burst}
|
outbound = {'average': out_av, 'peak': out_peak, 'burst': out_burst}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
net = self.get_network(nic_inst)
|
ipv4, ipv6 = self.get_interface_addresses(mac_inst)
|
||||||
ip = get_mac_ipaddr(net, mac_inst)
|
except:
|
||||||
except libvirtError:
|
ipv4, ipv6 = None, None
|
||||||
ip = None
|
|
||||||
result.append({'mac': mac_inst,
|
result.append({'mac': mac_inst,
|
||||||
'nic': nic_inst,
|
'nic': nic_inst,
|
||||||
'target': target_inst,
|
'target': target_inst,
|
||||||
'ip': ip,
|
'state': link_state,
|
||||||
|
'ipv4': ipv4,
|
||||||
|
'ipv6': ipv6,
|
||||||
'filterref': filterref_inst,
|
'filterref': filterref_inst,
|
||||||
'inbound': inbound,
|
'inbound': inbound,
|
||||||
'outbound': outbound,
|
'outbound': outbound,
|
||||||
|
@ -709,7 +768,7 @@ class wvmInstance(wvmConnect):
|
||||||
tx_diff_usage = (tx_use_now - tx_use_ago) * 8
|
tx_diff_usage = (tx_use_now - tx_use_ago) * 8
|
||||||
dev_usage.append({'dev': i, 'rx': rx_diff_usage, 'tx': tx_diff_usage})
|
dev_usage.append({'dev': i, 'rx': rx_diff_usage, 'tx': tx_diff_usage})
|
||||||
else:
|
else:
|
||||||
for i, dev in enumerate(self.get_net_device()):
|
for i, dev in enumerate(self.get_net_devices()):
|
||||||
dev_usage.append({'dev': i, 'rx': 0, 'tx': 0})
|
dev_usage.append({'dev': i, 'rx': 0, 'tx': 0})
|
||||||
return dev_usage
|
return dev_usage
|
||||||
|
|
||||||
|
@ -1217,6 +1276,24 @@ class wvmInstance(wvmConnect):
|
||||||
new_xml = ElementTree.tostring(tree)
|
new_xml = ElementTree.tostring(tree)
|
||||||
self._defineXML(new_xml)
|
self._defineXML(new_xml)
|
||||||
|
|
||||||
|
def set_link_state(self, mac_address, state):
|
||||||
|
tree = etree.fromstring(self._XMLDesc(0))
|
||||||
|
for interface in tree.findall('devices/interface'):
|
||||||
|
source = interface.find('mac')
|
||||||
|
if source.get('address') == mac_address:
|
||||||
|
link = interface.find('link')
|
||||||
|
if link is not None:
|
||||||
|
interface.remove(link)
|
||||||
|
link_el = etree.Element("link")
|
||||||
|
link_el.attrib["state"] = state
|
||||||
|
interface.append(link_el)
|
||||||
|
new_xml = etree.tostring(interface)
|
||||||
|
if self.get_status() == 1:
|
||||||
|
self.instance.updateDeviceFlags(new_xml, VIR_DOMAIN_AFFECT_LIVE)
|
||||||
|
self.instance.updateDeviceFlags(new_xml, VIR_DOMAIN_AFFECT_CONFIG)
|
||||||
|
if self.get_status() == 5:
|
||||||
|
self.instance.updateDeviceFlags(new_xml, VIR_DOMAIN_AFFECT_CONFIG)
|
||||||
|
|
||||||
def _set_options(self, tree, options):
|
def _set_options(self, tree, options):
|
||||||
for o in ['title', 'description']:
|
for o in ['title', 'description']:
|
||||||
option = tree.find(o)
|
option = tree.find(o)
|
||||||
|
@ -1304,11 +1381,64 @@ class wvmInstance(wvmConnect):
|
||||||
tree = etree.fromstring(self._XMLDesc(0))
|
tree = etree.fromstring(self._XMLDesc(0))
|
||||||
for direct in tree.xpath("/domain/devices/interface/bandwidth/{}".format(direction)):
|
for direct in tree.xpath("/domain/devices/interface/bandwidth/{}".format(direction)):
|
||||||
band_el = direct.getparent()
|
band_el = direct.getparent()
|
||||||
interface_el = band_el.getparent() # parent bandwidth,it parent is interface
|
interface_el = band_el.getparent() # parent bandwidth,its parent is interface
|
||||||
parent_mac = interface_el.xpath('mac/@address')
|
parent_mac = interface_el.xpath('mac/@address')
|
||||||
if parent_mac[0] == mac:
|
if parent_mac[0] == mac:
|
||||||
band_el.remove(direct)
|
band_el.remove(direct)
|
||||||
|
|
||||||
self.wvm.defineXML(etree.tostring(tree))
|
self.wvm.defineXML(etree.tostring(tree))
|
||||||
|
|
||||||
|
def add_guest_agent(self):
|
||||||
|
channel_xml = """
|
||||||
|
<channel type='unix'>
|
||||||
|
<target type='virtio' name='org.qemu.guest_agent.0'/>
|
||||||
|
</channel>
|
||||||
|
"""
|
||||||
|
if self.get_status() == 1:
|
||||||
|
self.instance.attachDeviceFlags(channel_xml, VIR_DOMAIN_AFFECT_LIVE)
|
||||||
|
self.instance.attachDeviceFlags(channel_xml, VIR_DOMAIN_AFFECT_CONFIG)
|
||||||
|
if self.get_status() == 5:
|
||||||
|
self.instance.attachDeviceFlags(channel_xml, VIR_DOMAIN_AFFECT_CONFIG)
|
||||||
|
|
||||||
|
def remove_guest_agent(self):
|
||||||
|
tree = etree.fromstring(self._XMLDesc(0))
|
||||||
|
for target in tree.xpath("/domain/devices/channel[@type='unix']/target[@name='org.qemu.guest_agent.0']"):
|
||||||
|
parent = target.getparent()
|
||||||
|
channel_xml = etree.tostring(parent)
|
||||||
|
if self.get_status() == 1:
|
||||||
|
self.instance.detachDeviceFlags(channel_xml, VIR_DOMAIN_AFFECT_LIVE)
|
||||||
|
self.instance.detachDeviceFlags(channel_xml, VIR_DOMAIN_AFFECT_CONFIG)
|
||||||
|
if self.get_status() == 5:
|
||||||
|
self.instance.detachDeviceFlags(channel_xml, VIR_DOMAIN_AFFECT_CONFIG)
|
||||||
|
|
||||||
|
def get_guest_agent(self):
|
||||||
|
def _get_agent(doc):
|
||||||
|
"""
|
||||||
|
Return agent channel object if it is defined.
|
||||||
|
"""
|
||||||
|
for channel in doc.xpath('/domain/devices/channel'):
|
||||||
|
ch_type = channel.get("type")
|
||||||
|
target = channel.find("target")
|
||||||
|
target_name = target.get("name")
|
||||||
|
if ch_type == "unix" and target_name == "org.qemu.guest_agent.0":
|
||||||
|
return channel
|
||||||
|
return None
|
||||||
|
|
||||||
|
return util.get_xml_path(self._XMLDesc(0), func=_get_agent)
|
||||||
|
|
||||||
|
def is_agent_ready(self):
|
||||||
|
"""
|
||||||
|
Return connected state of an agent.
|
||||||
|
"""
|
||||||
|
# we need to get a fresh agent channel object on each call so it
|
||||||
|
# reflects the current state
|
||||||
|
dev = self.get_guest_agent()
|
||||||
|
if dev is not None:
|
||||||
|
states = dev.xpath("target/@state")
|
||||||
|
state = states[0] if len(states) > 0 else ''
|
||||||
|
if state == "connected":
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -89,6 +89,7 @@ class wvmNetworks(wvmConnect):
|
||||||
class wvmNetwork(wvmConnect):
|
class wvmNetwork(wvmConnect):
|
||||||
def __init__(self, host, login, passwd, conn, net):
|
def __init__(self, host, login, passwd, conn, net):
|
||||||
wvmConnect.__init__(self, host, login, passwd, conn)
|
wvmConnect.__init__(self, host, login, passwd, conn)
|
||||||
|
self.leases = None
|
||||||
self.net = self.get_network(net)
|
self.net = self.get_network(net)
|
||||||
self.parent_count = len(self.get_ip_networks())
|
self.parent_count = len(self.get_ip_networks())
|
||||||
|
|
||||||
|
@ -347,3 +348,15 @@ class wvmNetwork(wvmConnect):
|
||||||
|
|
||||||
def edit_network(self, new_xml):
|
def edit_network(self, new_xml):
|
||||||
self.wvm.networkDefineXML(new_xml)
|
self.wvm.networkDefineXML(new_xml)
|
||||||
|
|
||||||
|
def refresh_dhcp_leases(self):
|
||||||
|
try:
|
||||||
|
self.leases = self.net.DHCPLeases()
|
||||||
|
except Exception as e:
|
||||||
|
self.leases = []
|
||||||
|
raise "Error getting %s DHCP leases: %s" % self, str(e)
|
||||||
|
|
||||||
|
def get_dhcp_leases(self):
|
||||||
|
if self.leases is None:
|
||||||
|
self.refresh_dhcp_leases()
|
||||||
|
return self.leases
|
||||||
|
|
Loading…
Reference in a new issue