mirror of
				https://github.com/retspen/webvirtcloud
				synced 2025-07-31 12:41:08 +00:00 
			
		
		
		
	
						commit
						3da734e804
					
				
					 6 changed files with 264 additions and 36 deletions
				
			
		| 
						 | 
				
			
			@ -13,15 +13,15 @@
 | 
			
		|||
        </div>
 | 
			
		||||
        <div>
 | 
			
		||||
            <div>
 | 
			
		||||
                {% ifequal status 5 %}
 | 
			
		||||
                {% if status == 5 %}
 | 
			
		||||
                   <span class="label label-danger">{% trans "Off" %}</span>
 | 
			
		||||
                {% endifequal %}
 | 
			
		||||
                {% ifequal status 1 %}
 | 
			
		||||
                {% endif %}
 | 
			
		||||
                {% if status == 1 %}
 | 
			
		||||
                    <span class="label label-success">{% trans "Active" %}</span>
 | 
			
		||||
                {% endifequal %}
 | 
			
		||||
                {% ifequal status 3 %}
 | 
			
		||||
                {% endif %}
 | 
			
		||||
                {% if status == 3 %}
 | 
			
		||||
                    <span class="label label-warning">{% trans "Suspend" %}</span>
 | 
			
		||||
                {% endifequal %}
 | 
			
		||||
                {% endif %}
 | 
			
		||||
                |
 | 
			
		||||
                {% if cur_vcpu %}
 | 
			
		||||
                    {{ cur_vcpu }} {% trans "Vcpu" %}
 | 
			
		||||
| 
						 | 
				
			
			@ -34,6 +34,22 @@
 | 
			
		|||
                {% for disk in disks %}
 | 
			
		||||
                    {{ disk.size|filesizeformat }} {% trans "Disk" %} |
 | 
			
		||||
                {% 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>
 | 
			
		||||
                <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>
 | 
			
		||||
| 
						 | 
				
			
			@ -876,7 +892,9 @@
 | 
			
		|||
                                    <tr>
 | 
			
		||||
                                        <th>{% trans 'Name' %}</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 'Qos' %}</th>
 | 
			
		||||
                                        <th>{% trans 'Actions' %}</th>
 | 
			
		||||
| 
						 | 
				
			
			@ -885,10 +903,20 @@
 | 
			
		|||
                                    <tbody>
 | 
			
		||||
                                        {% for network in networks %}
 | 
			
		||||
                                        <tr>
 | 
			
		||||
                                            <td class="col-sm-2"><label>eth{{ forloop.counter0 }}({{ network.target|default:"no target" }})</label></td>
 | 
			
		||||
                                            <td><input class="form-control" type="text" value="{{ network.mac }}" readonly/></td>
 | 
			
		||||
                                            <td><input class="form-control" type="text" value="{{ network.nic }}" readonly/></td>
 | 
			
		||||
                                            <td><input class="form-control" type="text" value="{{ network.filterref }}" readonly/></td>
 | 
			
		||||
                                            <td class="col-sm-1">eth{{ forloop.counter0 }}({{ network.target|default:"no target" }})</td>
 | 
			
		||||
                                            <td>{{ network.mac }}</td>
 | 
			
		||||
                                            <td>{{ network.ipv4|default:"unknown" }}</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>
 | 
			
		||||
                                                <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/>
 | 
			
		||||
| 
						 | 
				
			
			@ -1399,11 +1427,11 @@
 | 
			
		|||
                            </form>
 | 
			
		||||
                            <div class="clearfix"></div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                         <div class="well">
 | 
			
		||||
                        <div class="well">
 | 
			
		||||
                            <p>{% trans "To set instance vCPUs hotpluggable" %}</p>
 | 
			
		||||
                            <form class="form-horizontal" method="post" role="form">{% csrf_token %}
 | 
			
		||||
                                <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="input-group">
 | 
			
		||||
                                        <select id="vcpu_hotplug" class="form-control" name="vcpu_hotplug">
 | 
			
		||||
| 
						 | 
				
			
			@ -1423,6 +1451,35 @@
 | 
			
		|||
                            </form>
 | 
			
		||||
                            <div class="clearfix"></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>
 | 
			
		||||
                    {% endif %}
 | 
			
		||||
                </div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -266,6 +266,7 @@ def instance(request, compute_id, vname):
 | 
			
		|||
                           compute.password,
 | 
			
		||||
                           compute.type,
 | 
			
		||||
                           vname)
 | 
			
		||||
 | 
			
		||||
        status = conn.get_status()
 | 
			
		||||
        autostart = conn.get_autostart()
 | 
			
		||||
        bootmenu = conn.get_bootmenu()
 | 
			
		||||
| 
						 | 
				
			
			@ -282,7 +283,7 @@ def instance(request, compute_id, vname):
 | 
			
		|||
        cur_memory = conn.get_cur_memory()
 | 
			
		||||
        title = conn.get_title()
 | 
			
		||||
        description = conn.get_description()
 | 
			
		||||
        networks = conn.get_net_device()
 | 
			
		||||
        networks = conn.get_net_devices()
 | 
			
		||||
        qos = conn.get_all_qos()
 | 
			
		||||
        disks = conn.get_disk_devices()
 | 
			
		||||
        media = conn.get_media_devices()
 | 
			
		||||
| 
						 | 
				
			
			@ -302,6 +303,8 @@ def instance(request, compute_id, vname):
 | 
			
		|||
        console_port = conn.get_console_port()
 | 
			
		||||
        console_keymap = conn.get_console_keymap()
 | 
			
		||||
        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()
 | 
			
		||||
        snapshots = sorted(conn.get_snapshot(), reverse=True, key=lambda k: k['date'])
 | 
			
		||||
        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)
 | 
			
		||||
        videos_host = conn.get_video_models(arch, machine)
 | 
			
		||||
        networks_host = sorted(conn.get_networks())
 | 
			
		||||
        interfaces_host = sorted(conn.get_ifaces())
 | 
			
		||||
        nwfilters_host = conn.get_nwfilters()
 | 
			
		||||
        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 'poweron' in request.POST:
 | 
			
		||||
                if instance.is_template:
 | 
			
		||||
| 
						 | 
				
			
			@ -616,7 +624,7 @@ def instance(request, compute_id, vname):
 | 
			
		|||
                return HttpResponseRedirect(request.get_full_path() + '#disks')
 | 
			
		||||
 | 
			
		||||
            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)
 | 
			
		||||
                conn.attach_disk("", target, device='cdrom', cache='none', targetbus=bus)
 | 
			
		||||
                msg = _('Add CD-ROM: ' + target)
 | 
			
		||||
| 
						 | 
				
			
			@ -804,6 +812,17 @@ def instance(request, compute_id, vname):
 | 
			
		|||
                    return HttpResponseRedirect(request.get_full_path() + '#vncsettings')
 | 
			
		||||
 | 
			
		||||
            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:
 | 
			
		||||
                    video_model = request.POST.get('video_model', 'vga')
 | 
			
		||||
                    conn.set_video_model(video_model)
 | 
			
		||||
| 
						 | 
				
			
			@ -867,6 +886,15 @@ def instance(request, compute_id, vname):
 | 
			
		|||
                    addlogmsg(request.user.username, instance.name, msg)
 | 
			
		||||
                    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:
 | 
			
		||||
                    qos_dir = request.POST.get('qos_direction', '')
 | 
			
		||||
                    average = request.POST.get('qos_average') or 0
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,7 +30,7 @@ def interfaces(request, compute_id):
 | 
			
		|||
                             compute.type)
 | 
			
		||||
        ifaces = conn.get_ifaces()
 | 
			
		||||
        try:
 | 
			
		||||
            netdevs = conn.get_net_device()
 | 
			
		||||
            netdevs = conn.get_net_devices()
 | 
			
		||||
        except:
 | 
			
		||||
            netdevs = ['eth0', 'eth1']
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -351,7 +351,7 @@ class wvmConnect(object):
 | 
			
		|||
    def get_dom_cap_xml(self, arch, machine):
 | 
			
		||||
        """ Return domain capabilities xml"""
 | 
			
		||||
        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)
 | 
			
		||||
        if not machine or machine not in machine_types:
 | 
			
		||||
| 
						 | 
				
			
			@ -686,7 +686,7 @@ class wvmConnect(object):
 | 
			
		|||
                instance.append(dom.name())
 | 
			
		||||
        return instance
 | 
			
		||||
 | 
			
		||||
    def get_net_device(self):
 | 
			
		||||
    def get_net_devices(self):
 | 
			
		||||
        netdevice = []
 | 
			
		||||
 | 
			
		||||
        def get_info(doc):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,6 +11,7 @@ try:
 | 
			
		|||
        VIR_MIGRATE_COMPRESSED, \
 | 
			
		||||
        VIR_MIGRATE_AUTO_CONVERGE, \
 | 
			
		||||
        VIR_MIGRATE_POSTCOPY
 | 
			
		||||
    from libvirt import VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT
 | 
			
		||||
except:
 | 
			
		||||
    from libvirt import libvirtError, VIR_DOMAIN_XML_SECURE, VIR_MIGRATE_LIVE
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -148,6 +149,7 @@ class wvmInstances(wvmConnect):
 | 
			
		|||
class wvmInstance(wvmConnect):
 | 
			
		||||
    def __init__(self, host, login, passwd, conn, vname):
 | 
			
		||||
        wvmConnect.__init__(self, host, login, passwd, conn)
 | 
			
		||||
        self._ip_cache = None
 | 
			
		||||
        self.instance = self.get_instance(vname)
 | 
			
		||||
 | 
			
		||||
    def start(self):
 | 
			
		||||
| 
						 | 
				
			
			@ -276,17 +278,72 @@ class wvmInstance(wvmConnect):
 | 
			
		|||
        range_pcpus = xrange(1, int(pcpus + 1))
 | 
			
		||||
        return range_pcpus
 | 
			
		||||
 | 
			
		||||
    def get_net_device(self):
 | 
			
		||||
        def get_mac_ipaddr(net, mac_host):
 | 
			
		||||
            def fixed(doc):
 | 
			
		||||
                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
 | 
			
		||||
    def get_interface_addresses(self, iface_mac):
 | 
			
		||||
        if self._ip_cache is None:
 | 
			
		||||
            self.refresh_interface_addresses()
 | 
			
		||||
 | 
			
		||||
            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):
 | 
			
		||||
            result = []
 | 
			
		||||
| 
						 | 
				
			
			@ -295,6 +352,7 @@ class wvmInstance(wvmConnect):
 | 
			
		|||
                mac_inst = net.xpath('mac/@address')[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]
 | 
			
		||||
                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]
 | 
			
		||||
                if net.xpath('bandwidth/inbound'):
 | 
			
		||||
                    in_attr = net.xpath('bandwidth/inbound')[0]
 | 
			
		||||
| 
						 | 
				
			
			@ -310,14 +368,15 @@ class wvmInstance(wvmConnect):
 | 
			
		|||
                    outbound = {'average': out_av, 'peak': out_peak, 'burst': out_burst}
 | 
			
		||||
 | 
			
		||||
                try:
 | 
			
		||||
                    net = self.get_network(nic_inst)
 | 
			
		||||
                    ip = get_mac_ipaddr(net, mac_inst)
 | 
			
		||||
                except libvirtError:
 | 
			
		||||
                    ip = None
 | 
			
		||||
                    ipv4, ipv6 = self.get_interface_addresses(mac_inst)
 | 
			
		||||
                except:
 | 
			
		||||
                    ipv4, ipv6 = None, None
 | 
			
		||||
                result.append({'mac': mac_inst,
 | 
			
		||||
                               'nic': nic_inst,
 | 
			
		||||
                               'target': target_inst,
 | 
			
		||||
                               'ip': ip,
 | 
			
		||||
                               'state': link_state,
 | 
			
		||||
                               'ipv4': ipv4,
 | 
			
		||||
                               'ipv6': ipv6,
 | 
			
		||||
                               'filterref': filterref_inst,
 | 
			
		||||
                               'inbound': inbound,
 | 
			
		||||
                               'outbound': outbound,
 | 
			
		||||
| 
						 | 
				
			
			@ -709,7 +768,7 @@ class wvmInstance(wvmConnect):
 | 
			
		|||
                tx_diff_usage = (tx_use_now - tx_use_ago) * 8
 | 
			
		||||
                dev_usage.append({'dev': i, 'rx': rx_diff_usage, 'tx': tx_diff_usage})
 | 
			
		||||
        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})
 | 
			
		||||
        return dev_usage
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1217,6 +1276,24 @@ class wvmInstance(wvmConnect):
 | 
			
		|||
        new_xml = ElementTree.tostring(tree)
 | 
			
		||||
        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):
 | 
			
		||||
        for o in ['title', 'description']:
 | 
			
		||||
            option = tree.find(o)
 | 
			
		||||
| 
						 | 
				
			
			@ -1304,11 +1381,64 @@ class wvmInstance(wvmConnect):
 | 
			
		|||
        tree = etree.fromstring(self._XMLDesc(0))
 | 
			
		||||
        for direct in tree.xpath("/domain/devices/interface/bandwidth/{}".format(direction)):
 | 
			
		||||
            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')
 | 
			
		||||
            if parent_mac[0] == mac:
 | 
			
		||||
                band_el.remove(direct)
 | 
			
		||||
 | 
			
		||||
        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):
 | 
			
		||||
    def __init__(self, host, login, passwd, conn, net):
 | 
			
		||||
        wvmConnect.__init__(self, host, login, passwd, conn)
 | 
			
		||||
        self.leases = None
 | 
			
		||||
        self.net = self.get_network(net)
 | 
			
		||||
        self.parent_count = len(self.get_ip_networks())
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -347,3 +348,15 @@ class wvmNetwork(wvmConnect):
 | 
			
		|||
 | 
			
		||||
    def edit_network(self, 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…
	
	Add table
		Add a link
		
	
		Reference in a new issue