mirror of
https://github.com/GNS3/gns3-server
synced 2024-11-28 11:18:11 +00:00
Update the remote IOU initial config
This commit is contained in:
parent
83edc649d2
commit
e082cd8b1a
@ -56,7 +56,8 @@ class IOUHandler:
|
|||||||
ethernet_adapters=request.json.get("ethernet_adapters"),
|
ethernet_adapters=request.json.get("ethernet_adapters"),
|
||||||
ram=request.json.get("ram"),
|
ram=request.json.get("ram"),
|
||||||
nvram=request.json.get("nvram"),
|
nvram=request.json.get("nvram"),
|
||||||
l1_keepalives=request.json.get("l1_keepalives")
|
l1_keepalives=request.json.get("l1_keepalives"),
|
||||||
|
initial_config=request.json.get("initial_config")
|
||||||
)
|
)
|
||||||
vm.path = request.json.get("path", vm.path)
|
vm.path = request.json.get("path", vm.path)
|
||||||
vm.iourc_path = request.json.get("iourc_path", vm.iourc_path)
|
vm.iourc_path = request.json.get("iourc_path", vm.iourc_path)
|
||||||
@ -112,6 +113,7 @@ class IOUHandler:
|
|||||||
vm.ram = request.json.get("ram", vm.ram)
|
vm.ram = request.json.get("ram", vm.ram)
|
||||||
vm.nvram = request.json.get("nvram", vm.nvram)
|
vm.nvram = request.json.get("nvram", vm.nvram)
|
||||||
vm.l1_keepalives = request.json.get("l1_keepalives", vm.l1_keepalives)
|
vm.l1_keepalives = request.json.get("l1_keepalives", vm.l1_keepalives)
|
||||||
|
vm.initial_config = request.json.get("initial_config", vm.initial_config)
|
||||||
|
|
||||||
response.json(vm)
|
response.json(vm)
|
||||||
|
|
||||||
|
@ -62,7 +62,8 @@ class IOUVM(BaseVM):
|
|||||||
:params serial_adapters: Number of serial adapters
|
:params serial_adapters: Number of serial adapters
|
||||||
:params ram: Ram MB
|
:params ram: Ram MB
|
||||||
:params nvram: Nvram KB
|
:params nvram: Nvram KB
|
||||||
:params l1_keepalives: Always up ethernet interface
|
:params l1_keepalives: Always up ethernet interface:
|
||||||
|
:params initial_config: Content of the initial configuration file
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, name, vm_id, project, manager,
|
def __init__(self, name, vm_id, project, manager,
|
||||||
@ -72,7 +73,8 @@ class IOUVM(BaseVM):
|
|||||||
nvram=None,
|
nvram=None,
|
||||||
ethernet_adapters=None,
|
ethernet_adapters=None,
|
||||||
serial_adapters=None,
|
serial_adapters=None,
|
||||||
l1_keepalives=None):
|
l1_keepalives=None,
|
||||||
|
initial_config=None):
|
||||||
|
|
||||||
super().__init__(name, vm_id, project, manager)
|
super().__init__(name, vm_id, project, manager)
|
||||||
|
|
||||||
@ -98,6 +100,9 @@ class IOUVM(BaseVM):
|
|||||||
self._ram = 256 if ram is None else ram # Megabytes
|
self._ram = 256 if ram is None else ram # Megabytes
|
||||||
self._l1_keepalives = False if l1_keepalives is None else l1_keepalives # used to overcome the always-up Ethernet interfaces (not supported by all IOSes).
|
self._l1_keepalives = False if l1_keepalives is None else l1_keepalives # used to overcome the always-up Ethernet interfaces (not supported by all IOSes).
|
||||||
|
|
||||||
|
if initial_config is not None:
|
||||||
|
self.initial_config = initial_config
|
||||||
|
|
||||||
if self._console is not None:
|
if self._console is not None:
|
||||||
self._console = self._manager.port_manager.reserve_console_port(self._console)
|
self._console = self._manager.port_manager.reserve_console_port(self._console)
|
||||||
else:
|
else:
|
||||||
@ -212,7 +217,7 @@ class IOUVM(BaseVM):
|
|||||||
"serial_adapters": len(self._serial_adapters),
|
"serial_adapters": len(self._serial_adapters),
|
||||||
"ram": self._ram,
|
"ram": self._ram,
|
||||||
"nvram": self._nvram,
|
"nvram": self._nvram,
|
||||||
"l1_keepalives": self._l1_keepalives
|
"l1_keepalives": self._l1_keepalives,
|
||||||
}
|
}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -303,6 +308,21 @@ class IOUVM(BaseVM):
|
|||||||
new_nvram=nvram))
|
new_nvram=nvram))
|
||||||
self._nvram = nvram
|
self._nvram = nvram
|
||||||
|
|
||||||
|
@BaseVM.name.setter
|
||||||
|
def name(self, new_name):
|
||||||
|
"""
|
||||||
|
Sets the name of this IOU vm.
|
||||||
|
|
||||||
|
:param new_name: name
|
||||||
|
"""
|
||||||
|
|
||||||
|
if self.initial_config_file:
|
||||||
|
content = self.initial_config
|
||||||
|
content = content.replace(self._name, new_name)
|
||||||
|
self.initial_config = content
|
||||||
|
|
||||||
|
super(IOUVM, IOUVM).name.__set__(self, new_name)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def application_id(self):
|
def application_id(self):
|
||||||
return self._manager.get_application_id(self.id)
|
return self._manager.get_application_id(self.id)
|
||||||
@ -614,8 +634,10 @@ class IOUVM(BaseVM):
|
|||||||
command.extend(["-n", str(self._nvram)])
|
command.extend(["-n", str(self._nvram)])
|
||||||
command.extend(["-m", str(self._ram)])
|
command.extend(["-m", str(self._ram)])
|
||||||
command.extend(["-L"]) # disable local console, use remote console
|
command.extend(["-L"]) # disable local console, use remote console
|
||||||
if self._initial_config:
|
|
||||||
command.extend(["-c", self._initial_config])
|
initial_config_file = self.initial_config_file
|
||||||
|
if initial_config_file:
|
||||||
|
command.extend(["-c", initial_config_file])
|
||||||
if self._l1_keepalives:
|
if self._l1_keepalives:
|
||||||
self._enable_l1_keepalives(command)
|
self._enable_l1_keepalives(command)
|
||||||
command.extend([str(self.application_id)])
|
command.extend([str(self.application_id)])
|
||||||
@ -813,3 +835,50 @@ class IOUVM(BaseVM):
|
|||||||
raise IOUError("layer 1 keepalive messages are not supported by {}".format(os.path.basename(self._path)))
|
raise IOUError("layer 1 keepalive messages are not supported by {}".format(os.path.basename(self._path)))
|
||||||
except (OSError, subprocess.SubprocessError) as e:
|
except (OSError, subprocess.SubprocessError) as e:
|
||||||
log.warn("could not determine if layer 1 keepalive messages are supported by {}: {}".format(os.path.basename(self._path), e))
|
log.warn("could not determine if layer 1 keepalive messages are supported by {}: {}".format(os.path.basename(self._path), e))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def initial_config(self):
|
||||||
|
"""Return the content of the current initial-config file"""
|
||||||
|
|
||||||
|
config_file = self.initial_config_file
|
||||||
|
if config_file is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(config_file) as f:
|
||||||
|
return f.read()
|
||||||
|
except OSError as e:
|
||||||
|
raise VPCSError("Can't read configuration file '{}'".format(config_file))
|
||||||
|
|
||||||
|
@initial_config.setter
|
||||||
|
def initial_config(self, initial_config):
|
||||||
|
"""
|
||||||
|
Update the initial config
|
||||||
|
|
||||||
|
:param initial_config: The content of the initial configuration file
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
script_file = os.path.join(self.working_dir, "initial-config.cfg")
|
||||||
|
with open(script_file, 'w+') as f:
|
||||||
|
if initial_config is None:
|
||||||
|
f.write('')
|
||||||
|
else:
|
||||||
|
initial_config = initial_config.replace("%h", self._name)
|
||||||
|
f.write(initial_config)
|
||||||
|
except OSError as e:
|
||||||
|
raise VPCSError("Can't write initial configuration file '{}'".format(self.script_file))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def initial_config_file(self):
|
||||||
|
"""
|
||||||
|
Returns the initial config file for this IOU instance.
|
||||||
|
|
||||||
|
:returns: path to config file. None if the file doesn't exist
|
||||||
|
"""
|
||||||
|
|
||||||
|
path = os.path.join(self.working_dir, 'initial-config.cfg')
|
||||||
|
if os.path.exists(path):
|
||||||
|
return path
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
@ -69,6 +69,10 @@ IOU_CREATE_SCHEMA = {
|
|||||||
"l1_keepalives": {
|
"l1_keepalives": {
|
||||||
"description": "Always up ethernet interface",
|
"description": "Always up ethernet interface",
|
||||||
"type": ["boolean", "null"]
|
"type": ["boolean", "null"]
|
||||||
|
},
|
||||||
|
"initial_config": {
|
||||||
|
"description": "Initial configuration of the IOU",
|
||||||
|
"type": ["string", "null"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": False,
|
"additionalProperties": False,
|
||||||
@ -122,6 +126,10 @@ IOU_UPDATE_SCHEMA = {
|
|||||||
"l1_keepalives": {
|
"l1_keepalives": {
|
||||||
"description": "Always up ethernet interface",
|
"description": "Always up ethernet interface",
|
||||||
"type": ["boolean", "null"]
|
"type": ["boolean", "null"]
|
||||||
|
},
|
||||||
|
"initial_config": {
|
||||||
|
"description": "Initial configuration of the IOU",
|
||||||
|
"type": ["string", "null"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": False,
|
"additionalProperties": False,
|
||||||
@ -180,7 +188,7 @@ IOU_OBJECT_SCHEMA = {
|
|||||||
"l1_keepalives": {
|
"l1_keepalives": {
|
||||||
"description": "Always up ethernet interface",
|
"description": "Always up ethernet interface",
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
"additionalProperties": False,
|
"additionalProperties": False,
|
||||||
"required": ["name", "vm_id", "console", "project_id", "path", "serial_adapters", "ethernet_adapters", "ram", "nvram", "l1_keepalives"]
|
"required": ["name", "vm_id", "console", "project_id", "path", "serial_adapters", "ethernet_adapters", "ram", "nvram", "l1_keepalives"]
|
||||||
|
@ -46,6 +46,9 @@ def vm(server, project, base_params):
|
|||||||
return response.json
|
return response.json
|
||||||
|
|
||||||
|
|
||||||
|
def initial_config_file(project, vm):
|
||||||
|
return os.path.join(project.path, "project-files", "iou", vm["vm_id"], "initial-config.cfg")
|
||||||
|
|
||||||
def test_iou_create(server, project, base_params):
|
def test_iou_create(server, project, base_params):
|
||||||
response = server.post("/projects/{project_id}/iou/vms".format(project_id=project.id), base_params)
|
response = server.post("/projects/{project_id}/iou/vms".format(project_id=project.id), base_params)
|
||||||
assert response.status == 201
|
assert response.status == 201
|
||||||
@ -66,6 +69,7 @@ def test_iou_create_with_params(server, project, base_params):
|
|||||||
params["serial_adapters"] = 4
|
params["serial_adapters"] = 4
|
||||||
params["ethernet_adapters"] = 0
|
params["ethernet_adapters"] = 0
|
||||||
params["l1_keepalives"] = True
|
params["l1_keepalives"] = True
|
||||||
|
params["initial_config"] = "hostname test"
|
||||||
|
|
||||||
response = server.post("/projects/{project_id}/iou/vms".format(project_id=project.id), params, example=True)
|
response = server.post("/projects/{project_id}/iou/vms".format(project_id=project.id), params, example=True)
|
||||||
assert response.status == 201
|
assert response.status == 201
|
||||||
@ -77,6 +81,8 @@ def test_iou_create_with_params(server, project, base_params):
|
|||||||
assert response.json["ram"] == 1024
|
assert response.json["ram"] == 1024
|
||||||
assert response.json["nvram"] == 512
|
assert response.json["nvram"] == 512
|
||||||
assert response.json["l1_keepalives"] == True
|
assert response.json["l1_keepalives"] == True
|
||||||
|
with open(initial_config_file(project, response.json)) as f:
|
||||||
|
assert f.read() == params["initial_config"]
|
||||||
|
|
||||||
|
|
||||||
def test_iou_get(server, project, vm):
|
def test_iou_get(server, project, vm):
|
||||||
@ -120,7 +126,7 @@ def test_iou_delete(server, vm):
|
|||||||
assert response.status == 204
|
assert response.status == 204
|
||||||
|
|
||||||
|
|
||||||
def test_iou_update(server, vm, tmpdir, free_console_port):
|
def test_iou_update(server, vm, tmpdir, free_console_port, project):
|
||||||
params = {
|
params = {
|
||||||
"name": "test",
|
"name": "test",
|
||||||
"console": free_console_port,
|
"console": free_console_port,
|
||||||
@ -128,7 +134,8 @@ def test_iou_update(server, vm, tmpdir, free_console_port):
|
|||||||
"nvram": 2048,
|
"nvram": 2048,
|
||||||
"ethernet_adapters": 4,
|
"ethernet_adapters": 4,
|
||||||
"serial_adapters": 0,
|
"serial_adapters": 0,
|
||||||
"l1_keepalives": True
|
"l1_keepalives": True,
|
||||||
|
"initial_config": "hostname test"
|
||||||
}
|
}
|
||||||
response = server.put("/projects/{project_id}/iou/vms/{vm_id}".format(project_id=vm["project_id"], vm_id=vm["vm_id"]), params)
|
response = server.put("/projects/{project_id}/iou/vms/{vm_id}".format(project_id=vm["project_id"], vm_id=vm["vm_id"]), params)
|
||||||
assert response.status == 200
|
assert response.status == 200
|
||||||
@ -139,7 +146,8 @@ def test_iou_update(server, vm, tmpdir, free_console_port):
|
|||||||
assert response.json["ram"] == 512
|
assert response.json["ram"] == 512
|
||||||
assert response.json["nvram"] == 2048
|
assert response.json["nvram"] == 2048
|
||||||
assert response.json["l1_keepalives"] == True
|
assert response.json["l1_keepalives"] == True
|
||||||
|
with open(initial_config_file(project, response.json)) as f:
|
||||||
|
assert f.read() == "hostname test"
|
||||||
|
|
||||||
def test_iou_nio_create_udp(server, vm):
|
def test_iou_nio_create_udp(server, vm):
|
||||||
response = server.post("/projects/{project_id}/iou/vms/{vm_id}/adapters/1/ports/0/nio".format(project_id=vm["project_id"], vm_id=vm["vm_id"]), {"type": "nio_udp",
|
response = server.post("/projects/{project_id}/iou/vms/{vm_id}/adapters/1/ports/0/nio".format(project_id=vm["project_id"], vm_id=vm["vm_id"]), {"type": "nio_udp",
|
||||||
|
@ -69,6 +69,12 @@ def test_vm(project, manager):
|
|||||||
assert vm.id == "00010203-0405-0607-0809-0a0b0c0d0e0f"
|
assert vm.id == "00010203-0405-0607-0809-0a0b0c0d0e0f"
|
||||||
|
|
||||||
|
|
||||||
|
def test_vm_initial_config(project, manager):
|
||||||
|
vm = IOUVM("test", "00010203-0405-0607-0808-0a0b0c0d0e0f", project, manager, initial_config="hostname %h")
|
||||||
|
assert vm.name == "test"
|
||||||
|
assert vm.initial_config == "hostname test"
|
||||||
|
assert vm.id == "00010203-0405-0607-0808-0a0b0c0d0e0f"
|
||||||
|
|
||||||
@patch("gns3server.config.Config.get_section_config", return_value={"iouyap_path": "/bin/test_fake"})
|
@patch("gns3server.config.Config.get_section_config", return_value={"iouyap_path": "/bin/test_fake"})
|
||||||
def test_vm_invalid_iouyap_path(project, manager, loop):
|
def test_vm_invalid_iouyap_path(project, manager, loop):
|
||||||
with pytest.raises(IOUError):
|
with pytest.raises(IOUError):
|
||||||
@ -179,4 +185,48 @@ def test_create_netmap_config(vm):
|
|||||||
|
|
||||||
def test_build_command(vm):
|
def test_build_command(vm):
|
||||||
|
|
||||||
assert vm._build_command() == [vm.path, '-L', str(vm.application_id)]
|
assert vm._build_command() == [vm.path, "-L", str(vm.application_id)]
|
||||||
|
|
||||||
|
|
||||||
|
def test_build_command_initial_config(vm):
|
||||||
|
|
||||||
|
filepath = os.path.join(vm.working_dir, "initial-config.cfg")
|
||||||
|
with open(filepath, "w+") as f:
|
||||||
|
f.write("service timestamps debug datetime msec\nservice timestamps log datetime msec\nno service password-encryption")
|
||||||
|
|
||||||
|
assert vm._build_command() == [vm.path, "-L", "-c", vm.initial_config_file, str(vm.application_id)]
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_initial_config(vm):
|
||||||
|
|
||||||
|
content = "service timestamps debug datetime msec\nservice timestamps log datetime msec\nno service password-encryption"
|
||||||
|
vm.initial_config = content
|
||||||
|
assert vm.initial_config == content
|
||||||
|
|
||||||
|
|
||||||
|
def test_update_initial_config(vm):
|
||||||
|
content = "service timestamps debug datetime msec\nservice timestamps log datetime msec\nno service password-encryption"
|
||||||
|
vm.initial_config = content
|
||||||
|
filepath = os.path.join(vm.working_dir, "initial-config.cfg")
|
||||||
|
assert os.path.exists(filepath)
|
||||||
|
with open(filepath) as f:
|
||||||
|
assert f.read() == content
|
||||||
|
|
||||||
|
|
||||||
|
def test_update_initial_config_h(vm):
|
||||||
|
content = "hostname %h\n"
|
||||||
|
vm.name = "pc1"
|
||||||
|
vm.initial_config = content
|
||||||
|
with open(vm.initial_config_file) as f:
|
||||||
|
assert f.read() == "hostname pc1\n"
|
||||||
|
|
||||||
|
|
||||||
|
def test_change_name(vm, tmpdir):
|
||||||
|
path = os.path.join(vm.working_dir, "initial-config.cfg")
|
||||||
|
vm.name = "world"
|
||||||
|
with open(path, 'w+') as f:
|
||||||
|
f.write("hostname world")
|
||||||
|
vm.name = "hello"
|
||||||
|
assert vm.name == "hello"
|
||||||
|
with open(path) as f:
|
||||||
|
assert f.read() == "hostname hello"
|
||||||
|
Loading…
Reference in New Issue
Block a user