1
0
mirror of https://github.com/GNS3/gns3-server synced 2024-11-13 20:08:55 +00:00

Renaming for VPCS.

This commit is contained in:
grossmj 2014-05-13 16:09:47 -06:00
parent 43fa46779f
commit 64e09a19d9
2 changed files with 93 additions and 98 deletions

View File

@ -61,7 +61,7 @@ class VPCS(IModule):
def __init__(self, name, *args, **kwargs):
# get the vpcs location
# get the VPCS location
config = Config.instance()
vpcs_config = config.get_section_config(name.upper())
self._vpcs = vpcs_config.get("vpcs")
@ -80,9 +80,9 @@ class VPCS(IModule):
continue
if not self._vpcs:
log.warning("vpcs binary couldn't be found!")
log.warning("VPCS binary couldn't be found!")
elif not os.access(self._vpcs, os.X_OK):
log.warning("vpcs is not executable")
log.warning("VPCS is not executable")
# a new process start when calling IModule
IModule.__init__(self, name, *args, **kwargs)
@ -111,7 +111,7 @@ class VPCS(IModule):
"""
self._vpcs_callback.stop()
# delete all vpcs instances
# delete all VPCS instances
for vpcs_id in self._vpcs_instances:
vpcs_instance = self._vpcs_instances[vpcs_id]
vpcs_instance.delete()
@ -120,8 +120,8 @@ class VPCS(IModule):
def _check_vpcs_is_alive(self):
"""
Periodic callback to check if vpcs and vpcs are alive
for each vpcs instance.
Periodic callback to check if VPCS is alive
for each VPCS instance.
Sends a notification to the client if not.
"""
@ -134,23 +134,23 @@ class VPCS(IModule):
"name": vpcs_instance.name}
if not vpcs_instance.is_running():
stdout = vpcs_instance.read_vpcs_stdout()
notification["message"] = "vpcs has stopped running"
notification["message"] = "VPCS has stopped running"
notification["details"] = stdout
self.send_notification("{}.vpcs_stopped".format(self.name), notification)
vpcs_instance.stop()
def get_vpcs_instance(self, vpcs_id):
"""
Returns an vpcs device instance.
Returns a VPCS device instance.
:param vpcs_id: vpcs device identifier
:param vpcs_id: VPCS device identifier
:returns: vpcsDevice instance
:returns: VPCSDevice instance
"""
if vpcs_id not in self._vpcs_instances:
log.debug("vpcs device ID {} doesn't exist".format(vpcs_id), exc_info=1)
self.send_custom_error("vpcs device ID {} doesn't exist".format(vpcs_id))
log.debug("VPCS device ID {} doesn't exist".format(vpcs_id), exc_info=1)
self.send_custom_error("VPCS device ID {} doesn't exist".format(vpcs_id))
return None
return self._vpcs_instances[vpcs_id]
@ -175,7 +175,7 @@ class VPCS(IModule):
self._current_console_port = self._console_start_port_range
self._current_udp_port = self._udp_start_port_range
log.info("vpcs module has been reset")
log.info("VPCS module has been reset")
@IModule.route("vpcs.settings")
def settings(self, request):
@ -199,7 +199,7 @@ class VPCS(IModule):
if "vpcs" in request and request["vpcs"]:
self._vpcs = request["vpcs"]
log.info("vpcs path set to {}".format(self._vpcs))
log.info("VPCS path set to {}".format(self._vpcs))
if "working_dir" in request:
new_working_dir = request["working_dir"]
@ -252,17 +252,17 @@ class VPCS(IModule):
@IModule.route("vpcs.create")
def vpcs_create(self, request):
"""
Creates a new vpcs instance.
Creates a new VPCS instance.
Mandatory request parameters:
- path (path to the vpcs executable)
- path (path to the VPCS executable)
Optional request parameters:
- name (vpcs name)
- name (VPCS name)
Response parameters:
- id (vpcs instance identifier)
- name (vpcs name)
- id (VPCS instance identifier)
- name (VPCS name)
- default settings
:param request: JSON request
@ -309,10 +309,10 @@ class VPCS(IModule):
@IModule.route("vpcs.delete")
def vpcs_delete(self, request):
"""
Deletes an vpcs instance.
Deletes a VPCS instance.
Mandatory request parameters:
- id (vpcs instance identifier)
- id (VPCS instance identifier)
Response parameter:
- True on success
@ -341,10 +341,10 @@ class VPCS(IModule):
@IModule.route("vpcs.update")
def vpcs_update(self, request):
"""
Updates an vpcs instance
Updates a VPCS instance
Mandatory request parameters:
- id (vpcs instance identifier)
- id (VPCS instance identifier)
Optional request parameters:
- any setting to update
@ -386,7 +386,7 @@ class VPCS(IModule):
self.send_custom_error(str(e))
return
# update the vpcs settings
# update the VPCS settings
for name, value in request.items():
if hasattr(vpcs_instance, name) and getattr(vpcs_instance, name) != value:
try:
@ -401,10 +401,10 @@ class VPCS(IModule):
@IModule.route("vpcs.start")
def vm_start(self, request):
"""
Starts an vpcs instance.
Starts a VPCS instance.
Mandatory request parameters:
- id (vpcs instance identifier)
- id (VPCS instance identifier)
Response parameters:
- True on success
@ -422,7 +422,7 @@ class VPCS(IModule):
return
try:
log.debug("starting vpcs with command: {}".format(vpcs_instance.command()))
log.debug("starting VPCS with command: {}".format(vpcs_instance.command()))
vpcs_instance.vpcs = self._vpcs
vpcs_instance.start()
except VPCSError as e:
@ -433,10 +433,10 @@ class VPCS(IModule):
@IModule.route("vpcs.stop")
def vm_stop(self, request):
"""
Stops an vpcs instance.
Stops a VPCS instance.
Mandatory request parameters:
- id (vpcs instance identifier)
- id (VPCS instance identifier)
Response parameters:
- True on success
@ -463,10 +463,10 @@ class VPCS(IModule):
@IModule.route("vpcs.reload")
def vm_reload(self, request):
"""
Reloads an vpcs instance.
Reloads a VPCS instance.
Mandatory request parameters:
- id (vpcs identifier)
- id (VPCS identifier)
Response parameters:
- True on success
@ -498,7 +498,7 @@ class VPCS(IModule):
Allocates a UDP port in order to create an UDP NIO.
Mandatory request parameters:
- id (vpcs identifier)
- id (VPCS identifier)
- port_id (unique port identifier)
Response parameters:
@ -543,7 +543,7 @@ class VPCS(IModule):
def _check_for_privileged_access(self, device):
"""
Check if vpcs can access Ethernet and TAP devices.
Check if VPCS can access Ethernet and TAP devices.
:param device: device name
"""
@ -552,7 +552,7 @@ class VPCS(IModule):
if os.geteuid() == 0:
return
# test if vpcs has the CAP_NET_RAW capability
# test if VPCS has the CAP_NET_RAW capability
if "security.capability" in os.listxattr(self._vpcs):
try:
caps = os.getxattr(self._vpcs, "security.capability")
@ -568,10 +568,10 @@ class VPCS(IModule):
@IModule.route("vpcs.add_nio")
def add_nio(self, request):
"""
Adds an NIO (Network Input/Output) for an vpcs instance.
Adds an NIO (Network Input/Output) for a VPCS instance.
Mandatory request parameters:
- id (vpcs instance identifier)
- id (VPCS instance identifier)
- slot (slot number)
- port (port number)
- port_id (unique port identifier)
@ -631,7 +631,7 @@ class VPCS(IModule):
Deletes an NIO (Network Input/Output).
Mandatory request parameters:
- id (vpcs instance identifier)
- id (VPCS instance identifier)
- slot (slot identifier)
- port (port identifier)

View File

@ -16,17 +16,12 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
vpcs device management (creates command line, processes, files etc.) in
order to run an vpcs instance.
VPCS device management (creates command line, processes, files etc.) in
order to run an VPCS instance.
"""
import os
import re
import signal
import subprocess
import argparse
import threading
import configparser
import sys
import socket
from .vpcs_error import VPCSError
@ -40,12 +35,12 @@ log = logging.getLogger(__name__)
class VPCSDevice(object):
"""
vpcs device implementation.
VPCS device implementation.
:param path: path to vpcs executable
:param path: path to VPCS executable
:param working_dir: path to a working directory
:param host: host/address to bind for console and UDP connections
:param name: name of this vpcs device
:param name: name of this VPCS device
"""
_instances = []
@ -54,7 +49,7 @@ class VPCSDevice(object):
# find an instance identifier (1 <= id <= 255)
# This 255 limit is due to a restriction on the number of possible
# mac addresses given in vpcs using the -m option
# mac addresses given in VPCS using the -m option
self._id = 0
for identifier in range(1, 256):
if identifier not in self._instances:
@ -63,12 +58,12 @@ class VPCSDevice(object):
break
if self._id == 0:
raise VPCSError("Maximum number of vpcs instances reached")
raise VPCSError("Maximum number of VPCS instances reached")
if name:
self._name = name
else:
self._name = "vpcs{}".format(self._id)
self._name = "VPCS{}".format(self._id)
self._path = path
self._console = None
self._working_dir = None
@ -78,35 +73,35 @@ class VPCSDevice(object):
self._host = "127.0.0.1"
self._started = False
# vpcs settings
# VPCS settings
self._script_file = ""
self._ethernet_adapters = [EthernetAdapter()] # one adapter = 1 interfaces
self._slots = self._ethernet_adapters
# update the working directory
self.working_dir = working_dir
log.info("vpcs device {name} [id={id}] has been created".format(name=self._name,
log.info("VPCS device {name} [id={id}] has been created".format(name=self._name,
id=self._id))
def defaults(self):
"""
Returns all the default attribute values for vpcs.
Returns all the default attribute values for VPCS.
:returns: default values (dictionary)
"""
vpcs_defaults = {"name": self._name,
"path": self._path,
"script_file": self._script_file,
"console": self._console}
"path": self._path,
"script_file": self._script_file,
"console": self._console}
return vpcs_defaults
@property
def id(self):
"""
Returns the unique ID for this vpcs device.
Returns the unique ID for this VPCS device.
:returns: id (integer)
"""
@ -124,7 +119,7 @@ class VPCSDevice(object):
@property
def name(self):
"""
Returns the name of this vpcs device.
Returns the name of this VPCS device.
:returns: name
"""
@ -134,22 +129,22 @@ class VPCSDevice(object):
@name.setter
def name(self, new_name):
"""
Sets the name of this vpcs device.
Sets the name of this VPCS device.
:param new_name: name
"""
self._name = new_name
log.info("vpcs {name} [id={id}]: renamed to {new_name}".format(name=self._name,
log.info("VPCS {name} [id={id}]: renamed to {new_name}".format(name=self._name,
id=self._id,
new_name=new_name))
@property
def path(self):
"""
Returns the path to the vpcs executable.
Returns the path to the VPCS executable.
:returns: path to vpcs
:returns: path to VPCS
"""
return(self._path)
@ -157,13 +152,13 @@ class VPCSDevice(object):
@path.setter
def path(self, path):
"""
Sets the path to the vpcs executable.
Sets the path to the VPCS executable.
:param path: path to vpcs
:param path: path to VPCS
"""
self._path = path
log.info("vpcs {name} [id={id}]: path changed to {path}".format(name=self._name,
log.info("VPCS {name} [id={id}]: path changed to {path}".format(name=self._name,
id=self._id,
path=path))
@ -180,7 +175,7 @@ class VPCSDevice(object):
@working_dir.setter
def working_dir(self, working_dir):
"""
Sets the working directory for vpcs.
Sets the working directory for VPCS.
:param working_dir: path to the working directory
"""
@ -195,7 +190,7 @@ class VPCSDevice(object):
raise VPCSError("Could not create working directory {}: {}".format(working_dir, e))
self._working_dir = working_dir
log.info("vpcs {name} [id={id}]: working directory changed to {wd}".format(name=self._name,
log.info("VPCS {name} [id={id}]: working directory changed to {wd}".format(name=self._name,
id=self._id,
wd=self._working_dir))
@ -218,33 +213,33 @@ class VPCSDevice(object):
"""
self._console = console
log.info("vpcs {name} [id={id}]: console port set to {port}".format(name=self._name,
log.info("VPCS {name} [id={id}]: console port set to {port}".format(name=self._name,
id=self._id,
port=console))
def command(self):
"""
Returns the vpcs command line.
Returns the VPCS command line.
:returns: vpcs command line (string)
:returns: VPCS command line (string)
"""
return " ".join(self._build_command())
def delete(self):
"""
Deletes this vpcs device.
Deletes this VPCS device.
"""
self.stop()
self._instances.remove(self._id)
log.info("vpcs device {name} [id={id}] has been deleted".format(name=self._name,
log.info("VPCS device {name} [id={id}] has been deleted".format(name=self._name,
id=self._id))
@property
def started(self):
"""
Returns either this vpcs device has been started or not.
Returns either this VPCS device has been started or not.
:returns: boolean
"""
@ -253,20 +248,20 @@ class VPCSDevice(object):
def start(self):
"""
Starts the vpcs process.
Starts the VPCS process.
"""
if not self.is_running():
if not os.path.isfile(self._path):
raise VPCSError("vpcs image '{}' is not accessible".format(self._path))
raise VPCSError("VPCS image '{}' is not accessible".format(self._path))
if not os.access(self._path, os.X_OK):
raise VPCSError("vpcs image '{}' is not executable".format(self._path))
raise VPCSError("VPCS image '{}' is not executable".format(self._path))
self._command = self._build_command()
try:
log.info("starting vpcs: {}".format(self._command))
log.info("starting VPCS: {}".format(self._command))
self._vpcs_stdout_file = os.path.join(self._working_dir, "vpcs.log")
log.info("logging to {}".format(self._vpcs_stdout_file))
with open(self._vpcs_stdout_file, "w") as fd:
@ -274,35 +269,35 @@ class VPCSDevice(object):
stdout=fd,
stderr=subprocess.STDOUT,
cwd=self._working_dir)
log.info("vpcs instance {} started PID={}".format(self._id, self._process.pid))
log.info("VPCS instance {} started PID={}".format(self._id, self._process.pid))
self._started = True
except OSError as e:
vpcs_stdout = self.read_vpcs_stdout()
log.error("could not start vpcs {}: {}\n{}".format(self._path, e, vpcs_stdout))
raise VPCSError("could not start vpcs {}: {}\n{}".format(self._path, e, vpcs_stdout))
log.error("could not start VPCS {}: {}\n{}".format(self._path, e, vpcs_stdout))
raise VPCSError("could not start VPCS {}: {}\n{}".format(self._path, e, vpcs_stdout))
def stop(self):
"""
Stops the vpcs process.
Stops the VPCS process.
"""
# stop the vpcs process
# stop the VPCS process
if self.is_running():
log.info("stopping vpcs instance {} PID={}".format(self._id, self._process.pid))
log.info("stopping VPCS instance {} PID={}".format(self._id, self._process.pid))
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((self._host, self._console))
sock.send(bytes("quit\n", 'UTF-8'))
sock.close()
except TypeError as e:
log.warn("vpcs instance {} PID={} is still running. Error: {}".format(self._id,
self._process.pid, e))
log.warn("VPCS instance {} PID={} is still running. Error: {}".format(self._id,
self._process.pid, e))
self._process = None
self._started = False
def read_vpcs_stdout(self):
"""
Reads the standard output of the vpcs process.
Reads the standard output of the VPCS process.
Only use when the process has been stopped or has crashed.
"""
@ -317,7 +312,7 @@ class VPCSDevice(object):
def is_running(self):
"""
Checks if the vpcs process is running
Checks if the VPCS process is running
:returns: True or False
"""
@ -346,7 +341,7 @@ class VPCSDevice(object):
try:
adapter = self._slots[slot_id]
except IndexError:
raise VPCSError("Slot {slot_id} doesn't exist on vpcs {name}".format(name=self._name,
raise VPCSError("Slot {slot_id} doesn't exist on VPCS {name}".format(name=self._name,
slot_id=slot_id))
if not adapter.port_exists(port_id):
@ -354,7 +349,7 @@ class VPCSDevice(object):
port_id=port_id))
adapter.add_nio(port_id, nio)
log.info("vpcs {name} [id={id}]: {nio} added to {slot_id}/{port_id}".format(name=self._name,
log.info("VPCS {name} [id={id}]: {nio} added to {slot_id}/{port_id}".format(name=self._name,
id=self._id,
nio=nio,
slot_id=slot_id,
@ -371,7 +366,7 @@ class VPCSDevice(object):
try:
adapter = self._slots[slot_id]
except IndexError:
raise VPCSError("Slot {slot_id} doesn't exist on vpcs {name}".format(name=self._name,
raise VPCSError("Slot {slot_id} doesn't exist on VPCS {name}".format(name=self._name,
slot_id=slot_id))
if not adapter.port_exists(port_id):
@ -380,7 +375,7 @@ class VPCSDevice(object):
nio = adapter.get_nio(port_id)
adapter.remove_nio(port_id)
log.info("vpcs {name} [id={id}]: {nio} removed from {slot_id}/{port_id}".format(name=self._name,
log.info("VPCS {name} [id={id}]: {nio} removed from {slot_id}/{port_id}".format(name=self._name,
id=self._id,
nio=nio,
slot_id=slot_id,
@ -388,10 +383,10 @@ class VPCSDevice(object):
def _build_command(self):
"""
Command to start the vpcs process.
Command to start the VPCS process.
(to be passed to subprocess.Popen())
vpcs command line:
VPCS command line:
usage: vpcs [options] [scriptfile]
Option:
-h print this help then exit
@ -413,7 +408,7 @@ class VPCSDevice(object):
hypervisor mode option:
-H port run as the hypervisor listening on the tcp 'port'
If no 'scriptfile' specified, vpcs will read and execute the file named
If no 'scriptfile' specified, VPCS will read and execute the file named
'startup.vpc' if it exsits in the current directory.
"""
@ -444,7 +439,7 @@ class VPCSDevice(object):
@property
def script_file(self):
"""
Returns the script-file for this vpcs instance.
Returns the script-file for this VPCS instance.
:returns: path to script-file file
"""
@ -454,12 +449,12 @@ class VPCSDevice(object):
@script_file.setter
def script_file(self, script_file):
"""
Sets the script-file for this vpcs instance.
Sets the script-file for this VPCS instance.
:param script_file: path to script-file file
"""
self._script_file = script_file
log.info("vpcs {name} [id={id}]: script_file set to {config}".format(name=self._name,
log.info("VPCS {name} [id={id}]: script_file set to {config}".format(name=self._name,
id=self._id,
config=self._script_file))