Commit 9c3a7f33 authored by Romain Olivo's avatar Romain Olivo
Browse files

pep8

parent a76fb697
Pipeline #85736 passed with stages
in 2 minutes and 12 seconds
import requests
import os
import json
import copy
import requests
class Distem():
def __init__(self, serveraddr="localhost",port=4567):
def __init__(self, serveraddr="localhost", port=4567):
self.serveraddr = serveraddr
self.port = port
self.client = requests.Session()
def vnetwork_create(self, name, address, opts =[]):
def vnetwork_create(self, name, address, opts=None):
"""
Create a new virtual network
......@@ -23,8 +23,11 @@ class Distem():
options(dict) used to store vxlan_id and number of PNODES (should not be used directly)
Returns:
{Dictionnary} The virtual network description (see {file:files/resources_desc.md#Virtual_Networks Resource Description - VNetworks})
{Dictionnary} The virtual network description
see {file:files/resources_desc.md#Virtual_Networks Resource Description - VNetworks}
"""
if opts is None:
opts = []
self.post_json('/vnetworks', data={'name': name, 'address': address})
......@@ -32,14 +35,16 @@ class Distem():
def vnetwork_remove(self, vnetname):
"""
Remove a virtual network, that will disconnect every virtual node connected on it and remove it's virtual routes.
Remove a virtual network, that will disconnect every
virtual node connected on it and remove it's virtual routes.
Args:
vnetname(str) The name of the virtual network
Returns:
{Dictionnary} The virtual network description (see {file:files/resources_desc.md#Virtual_Networks Resource Description - VNetworks})
{Dictionnary} The virtual network description
see {file:files/resources_desc.md#Virtual_Networks Resource Description - VNetworks}
"""
self.delete_json('/vnetworks/%s' %(str(vnetname)), data={'type': "remove"})
......@@ -54,7 +59,8 @@ class Distem():
vnetname(str) The name of the virtual network
Returns:
{Dictionnary} The virtual network description (see {file:files/resources_desc.md#Virtual_Networks Resource Description - VNetworks})
{Dictionnary} The virtual network description
see {file:files/resources_desc.md#Virtual_Networks Resource Description - VNetworks}
"""
self.get_json('/vnetworks/%s' %(str(vnetname)))
......@@ -69,18 +75,20 @@ class Distem():
vnodename(str) The name of the virtual node
Returns:
{Dictionnary} The virtual node description (see {file:files/resources_desc.md#Virtual_Nodes Resource Description - VNodes})
{Dictionnary} The virtual node description
see {file:files/resources_desc.md#Virtual_Nodes Resource Description - VNodes}
"""
self.get_json('/vnodes/%s' %(str(vnodename)))
def vnode_create(self, name, desc = {}, ssh_key={}):
def vnode_create(self, name, desc=None, ssh_key=None):
"""
Create a new virtual node
Args:
name(str): The name of the virtual node which should be unique
desc(dict): Hash structured as described in {file:files/resources_desc.md#Virtual_Nodes Resource Description - VNodes}.
desc(dict): Hash structured as described in
{file:files/resources_desc.md#Virtual_Nodes Resource Description - VNodes}.
ssh_key(dict): SSH key pair to be copied on the virtual node (also
adding the public key to .ssh/authorized_keys). Note that every SSH
keys located on the physical node which hosts this virtual node are
......@@ -97,17 +105,26 @@ class Distem():
"private" : "KEYHASH"
}
Both of +public+ and +private+ parameters are optional
async(Boolean) Asynchronious mode, check virtual node status to know when node is configured (see {#vnode_info})
async(Boolean) Asynchronious mode, check virtual node status
to know when node is configured (see {#vnode_info})
Returns:
{Dictionnary} The virtual node description (see {file:files/resources_desc.md#Virtual_Nodes Resource Description - VNodes})
{Dictionnary} The virtual node description
see {file:files/resources_desc.md#Virtual_Nodes Resource Description - VNodes}
"""
if desc is None:
desc = {}
if ssh_key is None:
ssh_key = {}
data = {
"desc": desc,
"ssh_key": ssh_key,
'async': False
}
"desc": desc,
"ssh_key": ssh_key,
'async': False
}
self.post_json('/vnodes/%s' %(name), data=data)
......@@ -115,25 +132,29 @@ class Distem():
"""
Start a virtual node.
@note A physical node (that have enought physical resources (CPU,...)) will be automatically allocated if there is none set as +host+ at the moment
@note The filesystem archive will be copied on the hosting physical node.
@note A filesystem image *must* have been set (see {#vnode_create} or {#vfilesystem_create}/{#vfilesystem_update}).
A physical node (that have enought physical resources (CPU,...))
will be automatically allocated if there is none set as +host+ at the moment
The filesystem archive will be copied on the hosting physical node.
A filesystem image *must* have been set (see {#vnode_create}
or {#vfilesystem_create}/{#vfilesystem_update}).
Args:
vnodename(str) The name of the virtual node
async(Boolean) Asynchronious mode, check virtual node status to know when node is configured (see {#vnode_info})
async(Boolean) Asynchronious mode, check virtual node status
to know when node is configured (see {#vnode_info})
Returns:
{Dictionnary} The virtual node description (see {file:files/resources_desc.md#Virtual_Nodes Resource Description - VNodes})
{Dictionnary} The virtual node description
see {file:files/resources_desc.md#Virtual_Nodes Resource Description - VNodes}
"""
desc = {
'desc': {'name': str(vnodename),
'status': "RUNNING"},
'type': "update",
'async': False
}
'desc': {'name': str(vnodename),
'status': "RUNNING"},
'type': "update",
'async': False
}
self.put_json('/vnodes/%s' % (str(vnodename)), data=desc)
......@@ -141,22 +162,27 @@ class Distem():
def vnode_stop(self, vnodename):
"""
Stopping a virtual node, deleting it's data from the hosting physical node.
@note The +host+ association for this virtual node will be cancelled, if you start the virtual node directcly after stopping it, the hosting physical node will be chosen randomly (to set it manually, see host field, {#vnode_update})
The +host+ association for this virtual node will be cancelled,
if you start the virtual node directcly after stopping it,
the hosting physical node will be chosen randomly
(to set it manually, see host field, {#vnode_update})
Args:
vnodename(str) The name of the virtual node
async(Boolean) Asynchronious mode, check virtual node status to know when node is configured (see {#vnode_info})
async(Boolean) Asynchronious mode, check virtual node status
to know when node is configured (see {#vnode_info})
Returns:
{Dictionnary} The virtual node description (see {file:files/resources_desc.md#Virtual_Nodes Resource Description - VNodes})
{Dictionnary} The virtual node description
see {file:files/resources_desc.md#Virtual_Nodes Resource Description - VNodes}
"""
desc = {
'desc': {'status': "DOWN"}
, 'type': "stop"
, 'async': False
}
'desc': {'status': "DOWN"},
'type': "stop",
'async': False
}
self.put_json('/vnodes/%s' %(vnodename), data=desc)
......@@ -165,14 +191,15 @@ class Distem():
"""
Remove the virtual node
@note "Cascade" removing: remove all the vroutes in which this virtual node apears as gateway
"Cascade" removing: remove all the vroutes in which this virtual node apears as gateway
Args:
vnodename(str) The name of the virtual node
Returns:
{Dictionnary} The virtual node description (see {file:files/resources_desc.md#Virtual_Nodes Resource Description - VNodes})
{Dictionnary} The virtual node description
see {file:files/resources_desc.md#Virtual_Nodes Resource Description - VNodes}
"""
self.put_json('/vnodes/%s' %(vnodename), data={'type': "remove"})
......@@ -186,13 +213,15 @@ class Distem():
Args:
vnodename(str) The name of the virtual node
async(Boolean) Asynchronious mode, check virtual node status to know when node is configured (see {#vnode_info})
async(Boolean) Asynchronious mode, check virtual node status
to know when node is configured (see {#vnode_info})
Returns:
{Dictionnary} The virtual node description (see {file:files/resources_desc.md#Virtual_Nodes Resource Description - VNodes})
{Dictionnary} The virtual node description
see {file:files/resources_desc.md#Virtual_Nodes Resource Description - VNodes}
"""
self.put_json('/vnodes/%s' %(str(vnodename)), {'async':False, 'type': 'freeze'})
self.put_json('/vnodes/%s' %(str(vnodename)), {'async': False, 'type': 'freeze'})
def vnode_unfreeze(self, vnodename):
......@@ -203,13 +232,15 @@ class Distem():
Args:
vnodename(str) The name of the virtual node
async(Boolean) Asynchronious mode, check virtual node status to know when node is configured (see {#vnode_info})
async(Boolean) Asynchronious mode, check virtual node status
to know when node is configured (see {#vnode_info})
Returns:
{Dictionnary} The virtual node description (see {file:files/resources_desc.md#Virtual_Nodes Resource Description - VNodes})
{Dictionnary} The virtual node description
see {file:files/resources_desc.md#Virtual_Nodes Resource Description - VNodes}
"""
self.put_json('/vnodes/%s' %(str(vnodename)), {'async':False, 'type':'unfreeze'})
self.put_json('/vnodes/%s' %(str(vnodename)), {'async': False, 'type': 'unfreeze'})
def vnode_execute(self, vnodename, command):
......@@ -229,34 +260,50 @@ class Distem():
self.post_json('/vnodes/%s/commands/' %(str(vnodename)), data={'command': str(command)})
def vnodes_info():
def vnodes_info(self):
"""
Retrieve informations about every virtual nodes currently set on the platform
Returns:
[Array] Array of virtual nodes description (see {file:files/resources_desc.md#Virtual_Nodes Resource Description - VNodes})
[Array] Array of virtual nodes description
see {file:files/resources_desc.md#Virtual_Nodes Resource Description - VNodes}
"""
self.get_json("/vnodes")
def vnodes_create(self, names, desc = {}, ssh_key={}):
def vnodes_create(self, names, desc=None, ssh_key=None):
"""
Create new virtual nodes
Args:
names(Array) The names of the virtual nodes which should be unique
desc(dict) Hash structured as described in {file:files/resources_desc.md#Virtual_Nodes Resource Description - VNodes}.
ssh_key(dict) SSH key pair to be copied on the virtual node (also adding the public key to .ssh/authorized_keys). Note that every SSH keys located on the physical node which hosts this virtual node are also copied in .ssh/ directory of the node (copied key have a specific filename prefix). The key are copied in .ssh/ directory of SSH user (see {Distem::Daemon::Admin#SSH_USER} and Distem::Node::Container::SSH_KEY_FILENAME)
async(Boolean) Asynchronious mode, check virtual node status to know when node is configured (see {#vnode_info})
desc(dict) Hash structured as described in
{file:files/resources_desc.md#Virtual_Nodes Resource Description - VNodes}.
ssh_key(dict) SSH key pair to be copied on the virtual node
(also adding the public key to .ssh/authorized_keys).
Note that every SSH keys located on the physical node
which hosts this virtual node are also copied in .ssh/ directory of the node
(copied key have a specific filename prefix).
The key are copied in .ssh/ directory of SSH user
(see {Distem::Daemon::Admin#SSH_USER} and Distem::Node::Container::SSH_KEY_FILENAME)
async(Boolean) Asynchronious mode, check virtual node status
to know when node is configured (see {#vnode_info})
Returns:
[Array] The virtual nodes description (see {file:files/resources_desc.md#Virtual_Nodes Resource Description - VNodes})
[Array] The virtual nodes description
see {file:files/resources_desc.md#Virtual_Nodes Resource Description - VNodes}
"""
if desc is None:
desc = {}
if ssh_key is None:
ssh_key = {}
data = {
"names": names,
"desc": desc,
......@@ -267,15 +314,18 @@ class Distem():
self.post_json('/vnodes/', data=data)
def vnodes_remove(self, names = []):
def vnodes_remove(self, names=None):
"""
Remove the virtual vnodes, or every if names is nil
Returns:
[Array] Array of virtual nodes description (see {file:files/resources_desc.md#Virtual_Nodes Resource Description - VNodes})
[Array] Array of virtual nodes description
(see {file:files/resources_desc.md#Virtual_Nodes Resource Description - VNodes})
"""
if names is None:
names = []
self.put_json("/vnodes", data={'names': names, 'type': 'delete', 'async': False})
......@@ -285,40 +335,48 @@ class Distem():
"""
Start several virtual nodes
@note A physical node (that have enought physical resources (CPU,...)) will be automatically allocated if there is none set as +host+ at the moment
@note The filesystem archive will be copied on the hosting physical node.
@note A filesystem image *must* have been set (see {#vnode_create} or {#vfilesystem_create}/{#vfilesystem_update}).
A physical node (that have enought physical resources (CPU,...))
will be automatically allocated if there is none set as +host+ at the moment
The filesystem archive will be copied on the hosting physical node.
A filesystem image *must* have been set
(see {#vnode_create} or {#vfilesystem_create}/{#vfilesystem_update}).
Args:
names(Array) The names of the virtual nodes
async(Boolean) Asynchronious mode, check virtual nodes status to know when node is configured (see {#vnode_info})
async(Boolean) Asynchronious mode, check virtual nodes status
to know when node is configured (see {#vnode_info})
Returns:
{Dictionnary} The virtual nodes description (see {file:files/resources_desc.md#Virtual_Nodes Resource Description - VNodes})
{Dictionnary} The virtual nodes description
see {file:files/resources_desc.md#Virtual_Nodes Resource Description - VNodes}
"""
desc = { 'status': 'RUNNING' }
self.put_json('/vnodes', { 'names': names, 'desc': desc, 'async': False, 'type': 'update' })
desc = {'status': 'RUNNING'}
self.put_json('/vnodes', {'names': names, 'desc': desc, 'async': False, 'type': 'update'})
def vnodes_stop(self, names = []):
def vnodes_stop(self, names=None):
"""
Stop given virtal nodes
Args:
names(Array) The name of the virtual nodes
async(Boolean) Asynchronious mode, check virtual node status to know when node is configured (see {#vnode_info})
async(Boolean) Asynchronious mode, check virtual node status
to know when node is configured (see {#vnode_info})
Returns:
{Dictionnary} The description of the virtual nodes
"""
self.put_json("/vnodes", { 'names': names, 'async': False, 'type': 'stop' })
if names is None:
names = []
self.put_json("/vnodes", {'names': names, 'async': False, 'type': 'stop'})
def vnodes_freeze(self, names = []):
def vnodes_freeze(self, names=None):
"""
Freeze some virtual nodes
......@@ -326,16 +384,21 @@ class Distem():
Args:
names(Array) The names of the virtual nodes
async(Boolean) Asynchronious mode, check virtual node status to know when node is configured (see {#vnode_info})
async(Boolean) Asynchronious mode, check virtual node status
to know when node is configured (see {#vnode_info})
Returns:
[Array] The virtual node descriptions (see {file:files/resources_desc.md#Virtual_Nodes Resource Description - VNodes})
[Array] The virtual node descriptions
see {file:files/resources_desc.md#Virtual_Nodes Resource Description - VNodes}
"""
self.put_json("/vnodes", { 'names': names, 'async': False, 'type': 'freeze' })
if names is None:
names = []
self.put_json("/vnodes", {'names': names, 'async': False, 'type': 'freeze'})
def vnodes_unfreeze(self, names = []):
def vnodes_unfreeze(self, names=None):
"""
Unfreeze some virtual nodes
......@@ -343,13 +406,18 @@ class Distem():
Args:
names(Array) The names of the virtual nodes
async(Boolean) Asynchronious mode, check virtual node status to know when node is configured (see {#vnode_info})
async(Boolean) Asynchronious mode, check virtual node status
to know when node is configured (see {#vnode_info})
Returns:
[Array] The virtual node descriptions (see {file:files/resources_desc.md#Virtual_Nodes Resource Description - VNodes})
[Array] The virtual node descriptions
see {file:files/resources_desc.md#Virtual_Nodes Resource Description - VNodes}
"""
put_json("/vnodes", { 'names': names, 'async': False, 'type': 'unfreeze' })
if names is None:
names = []
self.put_json("/vnodes", {'names': names, 'async': False, 'type': 'unfreeze'})
def vnodes_execute(self, names, command):
......@@ -366,7 +434,7 @@ class Distem():
{Dictionnary} The result of the command (one entry by vnode)
"""
self.post_json("/commands", { 'names': names, 'command': command })
self.post_json("/commands", {'names': names, 'command': command})
def vfilesystem_info(self, vnodename):
......@@ -384,6 +452,7 @@ class Distem():
self.get_json('/vnodes/%s/filesystem/' %(str(vnodename)))
def vfilesystem_create(self, vnodename, desc):
"""
......@@ -392,10 +461,12 @@ class Distem():
Args:
vnodename(str) The name of the virtual node
desc(dict) Hash structured as described in {file:files/resources_desc.md#File_System0 Resource Description - VFilesystem}.
desc(dict) Hash structured as described in
{file:files/resources_desc.md#File_System0 Resource Description - VFilesystem}.
Returns:
{Dictionnary} The virtual Filesystem description (see {file:files/resources_desc.md#File_System0 Resource Description - VFilesystem})
{Dictionnary} The virtual Filesystem description
see {file:files/resources_desc.md#File_System0 Resource Description - VFilesystem}
"""
self.post_json('/vnodes/%s/filesystem/' %(str(vnodename)), {"desc": desc})
......@@ -409,10 +480,12 @@ class Distem():
Args:
vnodename(str) The name of the virtual node
desc(dict) Hash structured as described in {file:files/resources_desc.md#File_System0 Resource Description - VFilesystem}.
desc(dict) Hash structured as described in
{file:files/resources_desc.md#File_System0 Resource Description - VFilesystem}.
Returns:
{Dictionnary} The virtual Filesystem description (see {file:files/resources_desc.md#File_System0 Resource Description - VFilesystem})
{Dictionnary} The virtual Filesystem description
see {file:files/resources_desc.md#File_System0 Resource Description - VFilesystem}
"""
self.put_json('/vnodes/%s/filesystem/' %(str(vnodename)), data=desc)
......@@ -429,7 +502,8 @@ class Distem():
vifacename(str) The name of the virtual network interface
Returns:
{Dictionnary} The virtual network interface description (see {file:files/resources_desc.md#Network_Interfaces Resource Description - VIfaces})
{Dictionnary} The virtual network interface description
see {file:files/resources_desc.md#Network_Interfaces Resource Description - VIfaces}
"""
self.get_json('/vnodes/%s/ifaces/%s' %(str(vnodename), str(vifacename)))
......@@ -443,17 +517,20 @@ class Distem():
Args:
vnodename(str) The name of the virtual node
name(str) The name of the virtual network interface to be created (have to be unique on that virtual node)
desc(dict) Hash structured as described in {file:files/resources_desc.md#Network_interface Resource Description - VIface}.
name(str) The name of the virtual network interface
to be created (have to be unique on that virtual node)
desc(dict) Hash structured as described in
{file:files/resources_desc.md#Network_interface Resource Description - VIface}.
Returns:
{Dictionnary} The virtual network interface description (see {file:files/resources_desc.md#Network_Interfaces Resource Description - VIfaces})
{Dictionnary} The virtual network interface description
see {file:files/resources_desc.md#Network_Interfaces Resource Description - VIfaces}
"""
self.post_json('/vnodes/%s/ifaces/' %(str(vnodename)), {'name': name, 'desc': desc})
def viface_remove(self, vnodename,vifacename):
def viface_remove(self, vnodename, vifacename):
"""
Remove a virtual network interface
......@@ -464,7 +541,8 @@ class Distem():
vifacename(str) The name of the network virtual interface
Returns:
{Dictionnary} The virtual network interface description (see {file:files/resources_desc.md#Network_Interfaces Resource Description - VIfaces})
{Dictionnary} The virtual network interface description
see {file:files/resources_desc.md#Network_Interfaces Resource Description - VIfaces}
"""
self.delete_json('/vnodes/%s/ifaces/%s/' %(str(vnodename), str(vifacename)), data={})
......@@ -478,16 +556,19 @@ class Distem():
Args:
vnodename(str): The name of the virtual node
val(Float): The frequency defined as a value in MHz or as a ratio (percentage of the physical core frequency).
val(Float): The frequency defined as a value in MHz
or as a ratio (percentage of the physical core frequency).
unit(str): Tell if val is a frequency or a ratio (allowed values are mhz and ration)
corenb(Integer): The number of cores to allocate (need to have enough free ones on the physical node)
corenb(Integer): The number of cores to allocate
(need to have enough free ones on the physical node)
Returns:
{Dictionnary} The virtual CPU description (see {file:files/resources_desc.md#CPU0 Resource Description - VCPU})
{Dictionnary} The virtual CPU description
see {file:files/resources_desc.md#CPU0 Resource Description - VCPU}
"""
desc = { 'corenb': corenb, 'val': val, 'unit': unit }
self.post_json("/vnodes/%s/cpu" %(vnodename), data={ 'desc': desc })
desc = {'corenb': corenb, 'val': val, 'unit': unit}
self.post_json("/vnodes/%s/cpu" %(vnodename), data={'desc': desc})
def vcpu_update(self, vnodename, val, unit='mhz'):
......@@ -498,15 +579,17 @@ class Distem():
Args:
vnodename(str) The name of the virtual node
val(Float) The frequency defined as a value in MHz or as a ratio (percentage of the physical core frequency).
val(Float) The frequency defined as a value in MHz
or as a ratio (percentage of the physical core frequency).
unit(str) Tell if val is a frequency or a ratio (allowed values are mhz and ration)
Returns:
{Dictionnary} The virtual CPU description (see {file:files/resources_desc.md#CPU0 Resource Description - VCPU})
{Dictionnary} The virtual CPU description
see {file:files/resources_desc.md#CPU0 Resource Description - VCPU}
"""
desc = { 'val': val, 'unit': unit }
self.put_json("/vnodes/%s/cpu" %(vnodename), { 'desc': desc })
desc = {'val': val, 'unit': unit}
self.put_json("/vnodes/%s/cpu" %(vnodename), {'desc': desc})
def vcpu_remove(self, vnodename):
......@@ -519,7 +602,8 @@ class Distem():
vnodename(str) The name of the virtual node
Returns:
{Dictionnary} The virtual CPU description (see {file:files/resources_desc.md#CPU0 Resource Description - VCPU})
{Dictionnary} The virtual CPU description
see {file:files/resources_desc.md#CPU0 Resource Description - VCPU}
"""
self.delete_json("/vnodes/%s/cpu" %(vnodename), data={})
......@@ -532,31 +616,37 @@ class Distem():
Returns:
{Dictionnary} The virtual CPU description (see {file:files/resources_desc.md#CPU0 Resource Description - VCPU})
{Dictionnary} The virtual CPU description
see {file:files/resources_desc.md#CPU0 Resource Description - VCPU}
"""
self.get_json("/vnodes/%s/cpu" %(vnodename))
def vinput_update(self, vnodename, vifacename, desc={}):
def vinput_update(self, vnodename, vifacename, desc=None):
"""
Update the traffic description on the input of a specified virtual network interface
@note The vtraffic description is updated on-the-fly (even if the virtual node is running)
@note Reset the vtraffic description if +desc+ is empty
The vtraffic description is updated on-the-fly (even if the virtual node is running)
Reset the vtraffic description if +desc+ is empty
Args:
vnodename(str) The name of the virtual node
vifacename(str) The name of the virtual network interface
desc(dict) Hash structured as described in {file:files/resources_desc.md#Virtual_Traffic Resource Description - VTraffic}.
desc(dict) Hash structured as described in
{file:files/resources_desc.md#Virtual_Traffic Resource Description - VTraffic}.
Returns:
{Dictionnary} The virtual traffic description (see {file:files/resources_desc.md#Traffic Resource Description - VTraffic})
{Dictionnary} The virtual traffic description
see {file:files/resources_desc.md#Traffic Resource Description - VTraffic}
"""
self.put_json("/vnodes/%s/ifaces/%s/input/" %(vnodename, vifacename)
, {'desc': desc})
if desc is None:
desc = {}
self.put_json("/vnodes/%s/ifaces/%s/input/" %(vnodename, vifacename),
{'desc': desc})
def vinput_info(self, vnodename, vifacename):
......@@ -570,30 +660,36 @@ class Distem():
vifacename(str) The name of the virtual network interface
Returns:
{Dictionnary} The virtual traffic description (see {file:files/resources_desc.md#Traffic Resource Description - VTraffic})
{Dictionnary} The virtual traffic description
see {file:files/resources_desc.md#Traffic Resource Description - VTraffic}
"""
self.get_json("/vnodes/%s/ifaces/%s/input" %(vnodename, vifacename))
def voutput_update(self, vnodename, vifacename, desc = {}):
def voutput_update(self, vnodename, vifacename, desc=None):
"""
Update the traffic description on the output of a specified virtual network interface
@note The vtraffic description is updated on-the-fly (even if the virtual node is running)
@note Reset the vtraffic description if +desc+ is empty
The vtraffic description is updated on-the-fly (even if the virtual node is running)
Reset the vtraffic description if +desc+ is empty