mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-11-05 23:01:15 +02:00
Use black with -l 120 param.
This commit is contained in:
1 parent
f928738bd5
commit
c021e21309
194 files changed
+6034
-4564
No files matched your search
@@ -26,6 +26,7 @@ from .iou_error import IOUError
|
||||
from .iou_vm import IOUVM
|
||||
|
||||
import logging
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
||||
+230
-154
@@ -48,11 +48,12 @@ import gns3server.utils.images
|
||||
|
||||
import logging
|
||||
import sys
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class IOUVM(BaseNode):
|
||||
module_name = 'iou'
|
||||
module_name = "iou"
|
||||
|
||||
"""
|
||||
IOU VM implementation.
|
||||
@@ -65,13 +66,17 @@ class IOUVM(BaseNode):
|
||||
:param console_type: console type
|
||||
"""
|
||||
|
||||
def __init__(self, name, node_id, project, manager, application_id=None, path=None, console=None, console_type="telnet"):
|
||||
def __init__(
|
||||
self, name, node_id, project, manager, application_id=None, path=None, console=None, console_type="telnet"
|
||||
):
|
||||
|
||||
super().__init__(name, node_id, project, manager, console=console, console_type=console_type)
|
||||
|
||||
log.info('IOU "{name}" [{id}]: assigned with application ID {application_id}'.format(name=self._name,
|
||||
id=self._id,
|
||||
application_id=application_id))
|
||||
log.info(
|
||||
'IOU "{name}" [{id}]: assigned with application ID {application_id}'.format(
|
||||
name=self._name, id=self._id, application_id=application_id
|
||||
)
|
||||
)
|
||||
|
||||
self._iou_process = None
|
||||
self._telnet_server = None
|
||||
@@ -170,7 +175,9 @@ class IOUVM(BaseNode):
|
||||
"""
|
||||
|
||||
try:
|
||||
output = await gns3server.utils.asyncio.subprocess_check_output(self._path, "-h", cwd=self.working_dir, stderr=True)
|
||||
output = await gns3server.utils.asyncio.subprocess_check_output(
|
||||
self._path, "-h", cwd=self.working_dir, stderr=True
|
||||
)
|
||||
match = re.search(r"-n <n>\s+Size of nvram in Kb \(default ([0-9]+)KB\)", output)
|
||||
if match:
|
||||
self.nvram = int(match.group(1))
|
||||
@@ -206,7 +213,7 @@ class IOUVM(BaseNode):
|
||||
|
||||
# IOU images must start with the ELF magic number, be 32-bit or 64-bit, little endian
|
||||
# and have an ELF version of 1 normal IOS image are big endian!
|
||||
if elf_header_start != b'\x7fELF\x01\x01\x01' and elf_header_start != b'\x7fELF\x02\x01\x01':
|
||||
if elf_header_start != b"\x7fELF\x01\x01\x01" and elf_header_start != b"\x7fELF\x02\x01\x01":
|
||||
raise IOUError(f"'{self._path}' is not a valid IOU image")
|
||||
|
||||
if not os.access(self._path, os.X_OK):
|
||||
@@ -214,24 +221,26 @@ class IOUVM(BaseNode):
|
||||
|
||||
def __json__(self):
|
||||
|
||||
iou_vm_info = {"name": self.name,
|
||||
"usage": self.usage,
|
||||
"node_id": self.id,
|
||||
"node_directory": self.working_path,
|
||||
"console": self._console,
|
||||
"console_type": self._console_type,
|
||||
"status": self.status,
|
||||
"project_id": self.project.id,
|
||||
"path": self.path,
|
||||
"md5sum": gns3server.utils.images.md5sum(self.path),
|
||||
"ethernet_adapters": len(self._ethernet_adapters),
|
||||
"serial_adapters": len(self._serial_adapters),
|
||||
"ram": self._ram,
|
||||
"nvram": self._nvram,
|
||||
"l1_keepalives": self._l1_keepalives,
|
||||
"use_default_iou_values": self._use_default_iou_values,
|
||||
"command_line": self.command_line,
|
||||
"application_id": self.application_id}
|
||||
iou_vm_info = {
|
||||
"name": self.name,
|
||||
"usage": self.usage,
|
||||
"node_id": self.id,
|
||||
"node_directory": self.working_path,
|
||||
"console": self._console,
|
||||
"console_type": self._console_type,
|
||||
"status": self.status,
|
||||
"project_id": self.project.id,
|
||||
"path": self.path,
|
||||
"md5sum": gns3server.utils.images.md5sum(self.path),
|
||||
"ethernet_adapters": len(self._ethernet_adapters),
|
||||
"serial_adapters": len(self._serial_adapters),
|
||||
"ram": self._ram,
|
||||
"nvram": self._nvram,
|
||||
"l1_keepalives": self._l1_keepalives,
|
||||
"use_default_iou_values": self._use_default_iou_values,
|
||||
"command_line": self.command_line,
|
||||
"application_id": self.application_id,
|
||||
}
|
||||
|
||||
iou_vm_info["path"] = self.manager.get_relative_image_path(self.path, self.project.path)
|
||||
return iou_vm_info
|
||||
@@ -281,10 +290,11 @@ class IOUVM(BaseNode):
|
||||
if self._ram == ram:
|
||||
return
|
||||
|
||||
log.info('IOU "{name}" [{id}]: RAM updated from {old_ram}MB to {new_ram}MB'.format(name=self._name,
|
||||
id=self._id,
|
||||
old_ram=self._ram,
|
||||
new_ram=ram))
|
||||
log.info(
|
||||
'IOU "{name}" [{id}]: RAM updated from {old_ram}MB to {new_ram}MB'.format(
|
||||
name=self._name, id=self._id, old_ram=self._ram, new_ram=ram
|
||||
)
|
||||
)
|
||||
|
||||
self._ram = ram
|
||||
|
||||
@@ -309,10 +319,11 @@ class IOUVM(BaseNode):
|
||||
if self._nvram == nvram:
|
||||
return
|
||||
|
||||
log.info('IOU "{name}" [{id}]: NVRAM updated from {old_nvram}KB to {new_nvram}KB'.format(name=self._name,
|
||||
id=self._id,
|
||||
old_nvram=self._nvram,
|
||||
new_nvram=nvram))
|
||||
log.info(
|
||||
'IOU "{name}" [{id}]: NVRAM updated from {old_nvram}KB to {new_nvram}KB'.format(
|
||||
name=self._name, id=self._id, old_nvram=self._nvram, new_nvram=nvram
|
||||
)
|
||||
)
|
||||
self._nvram = nvram
|
||||
|
||||
@BaseNode.name.setter
|
||||
@@ -383,8 +394,11 @@ class IOUVM(BaseNode):
|
||||
p = re.compile(r"([\.\w]+)\s=>\s+not found")
|
||||
missing_libs = p.findall(output)
|
||||
if missing_libs:
|
||||
raise IOUError("The following shared library dependencies cannot be found for IOU image {}: {}".format(self._path,
|
||||
", ".join(missing_libs)))
|
||||
raise IOUError(
|
||||
"The following shared library dependencies cannot be found for IOU image {}: {}".format(
|
||||
self._path, ", ".join(missing_libs)
|
||||
)
|
||||
)
|
||||
|
||||
async def _check_iou_licence(self):
|
||||
"""
|
||||
@@ -422,9 +436,9 @@ class IOUVM(BaseNode):
|
||||
if len(hostname) > 15:
|
||||
log.warning(f"Older IOU images may not boot because hostname '{hostname}' length is above 15 characters")
|
||||
if hostname not in config["license"]:
|
||||
raise IOUError(f"Hostname \"{hostname}\" not found in iourc file {self.iourc_path}")
|
||||
raise IOUError(f'Hostname "{hostname}" not found in iourc file {self.iourc_path}')
|
||||
user_ioukey = config["license"][hostname]
|
||||
if user_ioukey[-1:] != ';':
|
||||
if user_ioukey[-1:] != ";":
|
||||
raise IOUError(f"IOU key not ending with ; in iourc file {self.iourc_path}")
|
||||
if len(user_ioukey) != 17:
|
||||
raise IOUError(f"IOU key length is not 16 characters in iourc file {self.iourc_path}")
|
||||
@@ -446,13 +460,15 @@ class IOUVM(BaseNode):
|
||||
raise IOUError(f"Invalid hostid detected: {hostid}")
|
||||
for x in hostname:
|
||||
ioukey += ord(x)
|
||||
pad1 = b'\x4B\x58\x21\x81\x56\x7B\x0D\xF3\x21\x43\x9B\x7E\xAC\x1D\xE6\x8A'
|
||||
pad2 = b'\x80' + 39 * b'\0'
|
||||
ioukey = hashlib.md5(pad1 + pad2 + struct.pack('!I', ioukey) + pad1).hexdigest()[:16]
|
||||
pad1 = b"\x4B\x58\x21\x81\x56\x7B\x0D\xF3\x21\x43\x9B\x7E\xAC\x1D\xE6\x8A"
|
||||
pad2 = b"\x80" + 39 * b"\0"
|
||||
ioukey = hashlib.md5(pad1 + pad2 + struct.pack("!I", ioukey) + pad1).hexdigest()[:16]
|
||||
if ioukey != user_ioukey:
|
||||
raise IOUError("Invalid IOU license key {} detected in iourc file {} for host {}".format(user_ioukey,
|
||||
self.iourc_path,
|
||||
hostname))
|
||||
raise IOUError(
|
||||
"Invalid IOU license key {} detected in iourc file {} for host {}".format(
|
||||
user_ioukey, self.iourc_path, hostname
|
||||
)
|
||||
)
|
||||
|
||||
def _nvram_file(self):
|
||||
"""
|
||||
@@ -545,14 +561,15 @@ class IOUVM(BaseNode):
|
||||
command = await self._build_command()
|
||||
try:
|
||||
log.info(f"Starting IOU: {command}")
|
||||
self.command_line = ' '.join(command)
|
||||
self.command_line = " ".join(command)
|
||||
self._iou_process = await asyncio.create_subprocess_exec(
|
||||
*command,
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stdin=asyncio.subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
cwd=self.working_dir,
|
||||
env=env)
|
||||
env=env,
|
||||
)
|
||||
log.info(f"IOU instance {self._id} started PID={self._iou_process.pid}")
|
||||
self._started = True
|
||||
self.status = "started"
|
||||
@@ -576,16 +593,20 @@ class IOUVM(BaseNode):
|
||||
"""
|
||||
|
||||
if self.console and self.console_type == "telnet":
|
||||
server = AsyncioTelnetServer(reader=self._iou_process.stdout, writer=self._iou_process.stdin, binary=True,
|
||||
echo=True)
|
||||
server = AsyncioTelnetServer(
|
||||
reader=self._iou_process.stdout, writer=self._iou_process.stdin, binary=True, echo=True
|
||||
)
|
||||
try:
|
||||
self._telnet_server = await asyncio.start_server(server.run, self._manager.port_manager.console_host,
|
||||
self.console)
|
||||
self._telnet_server = await asyncio.start_server(
|
||||
server.run, self._manager.port_manager.console_host, self.console
|
||||
)
|
||||
except OSError as e:
|
||||
await self.stop()
|
||||
raise IOUError(
|
||||
"Could not start Telnet server on socket {}:{}: {}".format(self._manager.port_manager.console_host,
|
||||
self.console, e))
|
||||
"Could not start Telnet server on socket {}:{}: {}".format(
|
||||
self._manager.port_manager.console_host, self.console, e
|
||||
)
|
||||
)
|
||||
|
||||
async def reset_console(self):
|
||||
"""
|
||||
@@ -618,17 +639,25 @@ class IOUVM(BaseNode):
|
||||
for unit in adapter.ports.keys():
|
||||
nio = adapter.get_nio(unit)
|
||||
if nio and isinstance(nio, NIOUDP):
|
||||
await self._ubridge_send("iol_bridge add_nio_udp {name} {iol_id} {bay} {unit} {lport} {rhost} {rport}".format(name=bridge_name,
|
||||
iol_id=self.application_id,
|
||||
bay=bay_id,
|
||||
unit=unit_id,
|
||||
lport=nio.lport,
|
||||
rhost=nio.rhost,
|
||||
rport=nio.rport))
|
||||
await self._ubridge_send(
|
||||
"iol_bridge add_nio_udp {name} {iol_id} {bay} {unit} {lport} {rhost} {rport}".format(
|
||||
name=bridge_name,
|
||||
iol_id=self.application_id,
|
||||
bay=bay_id,
|
||||
unit=unit_id,
|
||||
lport=nio.lport,
|
||||
rhost=nio.rhost,
|
||||
rport=nio.rport,
|
||||
)
|
||||
)
|
||||
if nio.capturing:
|
||||
await self._ubridge_send('iol_bridge start_capture {name} "{output_file}" {data_link_type}'.format(name=bridge_name,
|
||||
output_file=nio.pcap_output_file,
|
||||
data_link_type=re.sub(r"^DLT_", "", nio.pcap_data_link_type)))
|
||||
await self._ubridge_send(
|
||||
'iol_bridge start_capture {name} "{output_file}" {data_link_type}'.format(
|
||||
name=bridge_name,
|
||||
output_file=nio.pcap_output_file,
|
||||
data_link_type=re.sub(r"^DLT_", "", nio.pcap_data_link_type),
|
||||
)
|
||||
)
|
||||
|
||||
await self._ubridge_apply_filters(bay_id, unit_id, nio.filters)
|
||||
unit_id += 1
|
||||
@@ -646,11 +675,13 @@ class IOUVM(BaseNode):
|
||||
self._terminate_process_iou()
|
||||
if returncode != 0:
|
||||
if returncode == -11:
|
||||
message = 'IOU VM "{}" process has stopped with return code: {} (segfault). This could be an issue with the IOU image, using a different image may fix this.\n{}'.format(self.name,
|
||||
returncode,
|
||||
self.read_iou_stdout())
|
||||
message = 'IOU VM "{}" process has stopped with return code: {} (segfault). This could be an issue with the IOU image, using a different image may fix this.\n{}'.format(
|
||||
self.name, returncode, self.read_iou_stdout()
|
||||
)
|
||||
else:
|
||||
message = f'IOU VM "{self.name}" process has stopped with return code: {returncode}\n{self.read_iou_stdout()}'
|
||||
message = (
|
||||
f'IOU VM "{self.name}" process has stopped with return code: {returncode}\n{self.read_iou_stdout()}'
|
||||
)
|
||||
log.warning(message)
|
||||
self.project.emit("log.error", {"message": message})
|
||||
if self._telnet_server:
|
||||
@@ -764,12 +795,15 @@ class IOUVM(BaseNode):
|
||||
with open(netmap_path, "w", encoding="utf-8") as f:
|
||||
for bay in range(0, 16):
|
||||
for unit in range(0, 4):
|
||||
f.write("{ubridge_id}:{bay}/{unit}{iou_id:>5d}:{bay}/{unit}\n".format(ubridge_id=str(self.application_id + 512),
|
||||
bay=bay,
|
||||
unit=unit,
|
||||
iou_id=self.application_id))
|
||||
log.info("IOU {name} [id={id}]: NETMAP file created".format(name=self._name,
|
||||
id=self._id))
|
||||
f.write(
|
||||
"{ubridge_id}:{bay}/{unit}{iou_id:>5d}:{bay}/{unit}\n".format(
|
||||
ubridge_id=str(self.application_id + 512),
|
||||
bay=bay,
|
||||
unit=unit,
|
||||
iou_id=self.application_id,
|
||||
)
|
||||
)
|
||||
log.info("IOU {name} [id={id}]: NETMAP file created".format(name=self._name, id=self._id))
|
||||
except OSError as e:
|
||||
raise IOUError(f"Could not create {netmap_path}: {e}")
|
||||
|
||||
@@ -813,7 +847,7 @@ class IOUVM(BaseNode):
|
||||
command.extend(["-m", str(self._ram)])
|
||||
|
||||
# do not let IOU create the NVRAM anymore
|
||||
#startup_config_file = self.startup_config_file
|
||||
# startup_config_file = self.startup_config_file
|
||||
# if startup_config_file:
|
||||
# command.extend(["-c", os.path.basename(startup_config_file)])
|
||||
|
||||
@@ -863,9 +897,11 @@ class IOUVM(BaseNode):
|
||||
for _ in range(0, ethernet_adapters):
|
||||
self._ethernet_adapters.append(EthernetAdapter(interfaces=4))
|
||||
|
||||
log.info('IOU "{name}" [{id}]: number of Ethernet adapters changed to {adapters}'.format(name=self._name,
|
||||
id=self._id,
|
||||
adapters=len(self._ethernet_adapters)))
|
||||
log.info(
|
||||
'IOU "{name}" [{id}]: number of Ethernet adapters changed to {adapters}'.format(
|
||||
name=self._name, id=self._id, adapters=len(self._ethernet_adapters)
|
||||
)
|
||||
)
|
||||
|
||||
self._adapters = self._ethernet_adapters + self._serial_adapters
|
||||
|
||||
@@ -891,9 +927,11 @@ class IOUVM(BaseNode):
|
||||
for _ in range(0, serial_adapters):
|
||||
self._serial_adapters.append(SerialAdapter(interfaces=4))
|
||||
|
||||
log.info('IOU "{name}" [{id}]: number of Serial adapters changed to {adapters}'.format(name=self._name,
|
||||
id=self._id,
|
||||
adapters=len(self._serial_adapters)))
|
||||
log.info(
|
||||
'IOU "{name}" [{id}]: number of Serial adapters changed to {adapters}'.format(
|
||||
name=self._name, id=self._id, adapters=len(self._serial_adapters)
|
||||
)
|
||||
)
|
||||
|
||||
self._adapters = self._ethernet_adapters + self._serial_adapters
|
||||
|
||||
@@ -909,29 +947,39 @@ class IOUVM(BaseNode):
|
||||
try:
|
||||
adapter = self._adapters[adapter_number]
|
||||
except IndexError:
|
||||
raise IOUError('Adapter {adapter_number} does not exist for IOU "{name}"'.format(name=self._name,
|
||||
adapter_number=adapter_number))
|
||||
raise IOUError(
|
||||
'Adapter {adapter_number} does not exist for IOU "{name}"'.format(
|
||||
name=self._name, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
|
||||
if not adapter.port_exists(port_number):
|
||||
raise IOUError("Port {port_number} does not exist on adapter {adapter}".format(adapter=adapter,
|
||||
port_number=port_number))
|
||||
raise IOUError(
|
||||
"Port {port_number} does not exist on adapter {adapter}".format(
|
||||
adapter=adapter, port_number=port_number
|
||||
)
|
||||
)
|
||||
|
||||
adapter.add_nio(port_number, nio)
|
||||
log.info('IOU "{name}" [{id}]: {nio} added to {adapter_number}/{port_number}'.format(name=self._name,
|
||||
id=self._id,
|
||||
nio=nio,
|
||||
adapter_number=adapter_number,
|
||||
port_number=port_number))
|
||||
log.info(
|
||||
'IOU "{name}" [{id}]: {nio} added to {adapter_number}/{port_number}'.format(
|
||||
name=self._name, id=self._id, nio=nio, adapter_number=adapter_number, port_number=port_number
|
||||
)
|
||||
)
|
||||
|
||||
if self.ubridge:
|
||||
bridge_name = f"IOL-BRIDGE-{self.application_id + 512}"
|
||||
await self._ubridge_send("iol_bridge add_nio_udp {name} {iol_id} {bay} {unit} {lport} {rhost} {rport}".format(name=bridge_name,
|
||||
iol_id=self.application_id,
|
||||
bay=adapter_number,
|
||||
unit=port_number,
|
||||
lport=nio.lport,
|
||||
rhost=nio.rhost,
|
||||
rport=nio.rport))
|
||||
await self._ubridge_send(
|
||||
"iol_bridge add_nio_udp {name} {iol_id} {bay} {unit} {lport} {rhost} {rport}".format(
|
||||
name=bridge_name,
|
||||
iol_id=self.application_id,
|
||||
bay=adapter_number,
|
||||
unit=port_number,
|
||||
lport=nio.lport,
|
||||
rhost=nio.rhost,
|
||||
rport=nio.rport,
|
||||
)
|
||||
)
|
||||
await self._ubridge_apply_filters(adapter_number, port_number, nio.filters)
|
||||
|
||||
async def adapter_update_nio_binding(self, adapter_number, port_number, nio):
|
||||
@@ -955,15 +1003,10 @@ class IOUVM(BaseNode):
|
||||
:param filters: Array of filter dictionnary
|
||||
"""
|
||||
bridge_name = f"IOL-BRIDGE-{self.application_id + 512}"
|
||||
location = '{bridge_name} {bay} {unit}'.format(
|
||||
bridge_name=bridge_name,
|
||||
bay=adapter_number,
|
||||
unit=port_number)
|
||||
await self._ubridge_send('iol_bridge reset_packet_filters ' + location)
|
||||
location = "{bridge_name} {bay} {unit}".format(bridge_name=bridge_name, bay=adapter_number, unit=port_number)
|
||||
await self._ubridge_send("iol_bridge reset_packet_filters " + location)
|
||||
for filter in self._build_filter_list(filters):
|
||||
cmd = 'iol_bridge add_packet_filter {} {}'.format(
|
||||
location,
|
||||
filter)
|
||||
cmd = "iol_bridge add_packet_filter {} {}".format(location, filter)
|
||||
await self._ubridge_send(cmd)
|
||||
|
||||
async def adapter_remove_nio_binding(self, adapter_number, port_number):
|
||||
@@ -979,28 +1022,36 @@ class IOUVM(BaseNode):
|
||||
try:
|
||||
adapter = self._adapters[adapter_number]
|
||||
except IndexError:
|
||||
raise IOUError('Adapter {adapter_number} does not exist on IOU "{name}"'.format(name=self._name,
|
||||
adapter_number=adapter_number))
|
||||
raise IOUError(
|
||||
'Adapter {adapter_number} does not exist on IOU "{name}"'.format(
|
||||
name=self._name, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
|
||||
if not adapter.port_exists(port_number):
|
||||
raise IOUError("Port {port_number} does not exist on adapter {adapter}".format(adapter=adapter,
|
||||
port_number=port_number))
|
||||
raise IOUError(
|
||||
"Port {port_number} does not exist on adapter {adapter}".format(
|
||||
adapter=adapter, port_number=port_number
|
||||
)
|
||||
)
|
||||
|
||||
nio = adapter.get_nio(port_number)
|
||||
if isinstance(nio, NIOUDP):
|
||||
self.manager.port_manager.release_udp_port(nio.lport, self._project)
|
||||
adapter.remove_nio(port_number)
|
||||
log.info('IOU "{name}" [{id}]: {nio} removed from {adapter_number}/{port_number}'.format(name=self._name,
|
||||
id=self._id,
|
||||
nio=nio,
|
||||
adapter_number=adapter_number,
|
||||
port_number=port_number))
|
||||
log.info(
|
||||
'IOU "{name}" [{id}]: {nio} removed from {adapter_number}/{port_number}'.format(
|
||||
name=self._name, id=self._id, nio=nio, adapter_number=adapter_number, port_number=port_number
|
||||
)
|
||||
)
|
||||
|
||||
if self.ubridge:
|
||||
bridge_name = f"IOL-BRIDGE-{self.application_id + 512}"
|
||||
await self._ubridge_send("iol_bridge delete_nio_udp {name} {bay} {unit}".format(name=bridge_name,
|
||||
bay=adapter_number,
|
||||
unit=port_number))
|
||||
await self._ubridge_send(
|
||||
"iol_bridge delete_nio_udp {name} {bay} {unit}".format(
|
||||
name=bridge_name, bay=adapter_number, unit=port_number
|
||||
)
|
||||
)
|
||||
|
||||
return nio
|
||||
|
||||
@@ -1017,18 +1068,25 @@ class IOUVM(BaseNode):
|
||||
try:
|
||||
adapter = self._adapters[adapter_number]
|
||||
except IndexError:
|
||||
raise IOUError('Adapter {adapter_number} does not exist on IOU "{name}"'.format(name=self._name,
|
||||
adapter_number=adapter_number))
|
||||
raise IOUError(
|
||||
'Adapter {adapter_number} does not exist on IOU "{name}"'.format(
|
||||
name=self._name, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
|
||||
if not adapter.port_exists(port_number):
|
||||
raise IOUError("Port {port_number} does not exist on adapter {adapter}".format(adapter=adapter,
|
||||
port_number=port_number))
|
||||
raise IOUError(
|
||||
"Port {port_number} does not exist on adapter {adapter}".format(
|
||||
adapter=adapter, port_number=port_number
|
||||
)
|
||||
)
|
||||
|
||||
nio = adapter.get_nio(port_number)
|
||||
|
||||
if not nio:
|
||||
raise IOUError("NIO {port_number} does not exist on adapter {adapter}".format(adapter=adapter,
|
||||
port_number=port_number))
|
||||
raise IOUError(
|
||||
"NIO {port_number} does not exist on adapter {adapter}".format(adapter=adapter, port_number=port_number)
|
||||
)
|
||||
return nio
|
||||
|
||||
@property
|
||||
@@ -1066,13 +1124,17 @@ class IOUVM(BaseNode):
|
||||
if "IOURC" not in os.environ:
|
||||
env["IOURC"] = self.iourc_path
|
||||
try:
|
||||
output = await gns3server.utils.asyncio.subprocess_check_output(self._path, "-h", cwd=self.working_dir, env=env, stderr=True)
|
||||
output = await gns3server.utils.asyncio.subprocess_check_output(
|
||||
self._path, "-h", cwd=self.working_dir, env=env, stderr=True
|
||||
)
|
||||
if re.search(r"-l\s+Enable Layer 1 keepalive messages", output):
|
||||
command.extend(["-l"])
|
||||
else:
|
||||
raise IOUError(f"layer 1 keepalive messages are not supported by {os.path.basename(self._path)}")
|
||||
except (OSError, subprocess.SubprocessError) as e:
|
||||
log.warning(f"could not determine if layer 1 keepalive messages are supported by {os.path.basename(self._path)}: {e}")
|
||||
log.warning(
|
||||
f"could not determine if layer 1 keepalive messages are supported by {os.path.basename(self._path)}: {e}"
|
||||
)
|
||||
|
||||
@property
|
||||
def startup_config_content(self):
|
||||
@@ -1102,15 +1164,15 @@ class IOUVM(BaseNode):
|
||||
startup_config_path = os.path.join(self.working_dir, "startup-config.cfg")
|
||||
|
||||
if startup_config is None:
|
||||
startup_config = ''
|
||||
startup_config = ""
|
||||
|
||||
# We disallow erasing the startup config file
|
||||
if len(startup_config) == 0 and os.path.exists(startup_config_path):
|
||||
return
|
||||
|
||||
with open(startup_config_path, 'w+', encoding='utf-8') as f:
|
||||
with open(startup_config_path, "w+", encoding="utf-8") as f:
|
||||
if len(startup_config) == 0:
|
||||
f.write('')
|
||||
f.write("")
|
||||
else:
|
||||
startup_config = startup_config.replace("%h", self._name)
|
||||
f.write(startup_config)
|
||||
@@ -1153,15 +1215,15 @@ class IOUVM(BaseNode):
|
||||
private_config_path = os.path.join(self.working_dir, "private-config.cfg")
|
||||
|
||||
if private_config is None:
|
||||
private_config = ''
|
||||
private_config = ""
|
||||
|
||||
# We disallow erasing the private config file
|
||||
if len(private_config) == 0 and os.path.exists(private_config_path):
|
||||
return
|
||||
|
||||
with open(private_config_path, 'w+', encoding='utf-8') as f:
|
||||
with open(private_config_path, "w+", encoding="utf-8") as f:
|
||||
if len(private_config) == 0:
|
||||
f.write('')
|
||||
f.write("")
|
||||
else:
|
||||
private_config = private_config.replace("%h", self._name)
|
||||
f.write(private_config)
|
||||
@@ -1176,7 +1238,7 @@ class IOUVM(BaseNode):
|
||||
:returns: path to config file. None if the file doesn't exist
|
||||
"""
|
||||
|
||||
path = os.path.join(self.working_dir, 'startup-config.cfg')
|
||||
path = os.path.join(self.working_dir, "startup-config.cfg")
|
||||
if os.path.exists(path):
|
||||
return path
|
||||
else:
|
||||
@@ -1190,7 +1252,7 @@ class IOUVM(BaseNode):
|
||||
:returns: path to config file. None if the file doesn't exist
|
||||
"""
|
||||
|
||||
path = os.path.join(self.working_dir, 'private-config.cfg')
|
||||
path = os.path.join(self.working_dir, "private-config.cfg")
|
||||
if os.path.exists(path):
|
||||
return path
|
||||
else:
|
||||
@@ -1205,9 +1267,9 @@ class IOUVM(BaseNode):
|
||||
:returns: path to startup-config file. None if the file doesn't exist
|
||||
"""
|
||||
|
||||
path = os.path.join(self.working_dir, 'startup-config.cfg')
|
||||
path = os.path.join(self.working_dir, "startup-config.cfg")
|
||||
if os.path.exists(path):
|
||||
return 'startup-config.cfg'
|
||||
return "startup-config.cfg"
|
||||
else:
|
||||
return None
|
||||
|
||||
@@ -1219,9 +1281,9 @@ class IOUVM(BaseNode):
|
||||
:returns: path to private-config file. None if the file doesn't exist
|
||||
"""
|
||||
|
||||
path = os.path.join(self.working_dir, 'private-config.cfg')
|
||||
path = os.path.join(self.working_dir, "private-config.cfg")
|
||||
if os.path.exists(path):
|
||||
return 'private-config.cfg'
|
||||
return "private-config.cfg"
|
||||
else:
|
||||
return None
|
||||
|
||||
@@ -1288,7 +1350,7 @@ class IOUVM(BaseNode):
|
||||
except (binascii.Error, OSError) as e:
|
||||
raise IOUError(f"Could not save the startup configuration {config_path}: {e}")
|
||||
|
||||
if private_config_content and private_config_content != b'\nend\n':
|
||||
if private_config_content and private_config_content != b"\nend\n":
|
||||
config_path = os.path.join(self.working_dir, "private-config.cfg")
|
||||
try:
|
||||
config = private_config_content.decode("utf-8", errors="replace")
|
||||
@@ -1310,23 +1372,34 @@ class IOUVM(BaseNode):
|
||||
|
||||
nio = self.get_nio(adapter_number, port_number)
|
||||
if nio.capturing:
|
||||
raise IOUError("Packet capture is already activated on {adapter_number}/{port_number}".format(adapter_number=adapter_number,
|
||||
port_number=port_number))
|
||||
raise IOUError(
|
||||
"Packet capture is already activated on {adapter_number}/{port_number}".format(
|
||||
adapter_number=adapter_number, port_number=port_number
|
||||
)
|
||||
)
|
||||
|
||||
nio.start_packet_capture(output_file, data_link_type)
|
||||
log.info('IOU "{name}" [{id}]: starting packet capture on {adapter_number}/{port_number} to {output_file}'.format(name=self._name,
|
||||
id=self._id,
|
||||
adapter_number=adapter_number,
|
||||
port_number=port_number,
|
||||
output_file=output_file))
|
||||
log.info(
|
||||
'IOU "{name}" [{id}]: starting packet capture on {adapter_number}/{port_number} to {output_file}'.format(
|
||||
name=self._name,
|
||||
id=self._id,
|
||||
adapter_number=adapter_number,
|
||||
port_number=port_number,
|
||||
output_file=output_file,
|
||||
)
|
||||
)
|
||||
|
||||
if self.ubridge:
|
||||
bridge_name = f"IOL-BRIDGE-{self.application_id + 512}"
|
||||
await self._ubridge_send('iol_bridge start_capture {name} {bay} {unit} "{output_file}" {data_link_type}'.format(name=bridge_name,
|
||||
bay=adapter_number,
|
||||
unit=port_number,
|
||||
output_file=output_file,
|
||||
data_link_type=re.sub(r"^DLT_", "", data_link_type)))
|
||||
await self._ubridge_send(
|
||||
'iol_bridge start_capture {name} {bay} {unit} "{output_file}" {data_link_type}'.format(
|
||||
name=bridge_name,
|
||||
bay=adapter_number,
|
||||
unit=port_number,
|
||||
output_file=output_file,
|
||||
data_link_type=re.sub(r"^DLT_", "", data_link_type),
|
||||
)
|
||||
)
|
||||
|
||||
async def stop_capture(self, adapter_number, port_number):
|
||||
"""
|
||||
@@ -1340,12 +1413,15 @@ class IOUVM(BaseNode):
|
||||
if not nio.capturing:
|
||||
return
|
||||
nio.stop_packet_capture()
|
||||
log.info('IOU "{name}" [{id}]: stopping packet capture on {adapter_number}/{port_number}'.format(name=self._name,
|
||||
id=self._id,
|
||||
adapter_number=adapter_number,
|
||||
port_number=port_number))
|
||||
log.info(
|
||||
'IOU "{name}" [{id}]: stopping packet capture on {adapter_number}/{port_number}'.format(
|
||||
name=self._name, id=self._id, adapter_number=adapter_number, port_number=port_number
|
||||
)
|
||||
)
|
||||
if self.ubridge:
|
||||
bridge_name = f"IOL-BRIDGE-{self.application_id + 512}"
|
||||
await self._ubridge_send('iol_bridge stop_capture {name} {bay} {unit}'.format(name=bridge_name,
|
||||
bay=adapter_number,
|
||||
unit=port_number))
|
||||
await self._ubridge_send(
|
||||
"iol_bridge stop_capture {name} {bay} {unit}".format(
|
||||
name=bridge_name, bay=adapter_number, unit=port_number
|
||||
)
|
||||
)
|
||||
@@ -47,28 +47,28 @@ def uncompress_LZC(data):
|
||||
LZC_NUM_BITS_MIN = 9
|
||||
LZC_NUM_BITS_MAX = 16
|
||||
|
||||
in_data = bytearray(data)
|
||||
in_len = len(in_data)
|
||||
in_data = bytearray(data)
|
||||
in_len = len(in_data)
|
||||
out_data = bytearray()
|
||||
|
||||
if in_len == 0:
|
||||
return out_data
|
||||
if in_len < 3:
|
||||
raise ValueError('invalid length')
|
||||
raise ValueError("invalid length")
|
||||
if in_data[0] != 0x1F or in_data[1] != 0x9D:
|
||||
raise ValueError('invalid header')
|
||||
raise ValueError("invalid header")
|
||||
|
||||
max_bits = in_data[2] & 0x1F
|
||||
if max_bits < LZC_NUM_BITS_MIN or max_bits > LZC_NUM_BITS_MAX:
|
||||
raise ValueError('not supported')
|
||||
raise ValueError("not supported")
|
||||
num_items = 1 << max_bits
|
||||
blockmode = (in_data[2] & 0x80) != 0
|
||||
|
||||
in_pos = 3
|
||||
in_pos = 3
|
||||
start_pos = in_pos
|
||||
num_bits = LZC_NUM_BITS_MIN
|
||||
num_bits = LZC_NUM_BITS_MIN
|
||||
dict_size = 1 << num_bits
|
||||
head = 256
|
||||
head = 256
|
||||
if blockmode:
|
||||
head += 1
|
||||
first_sym = True
|
||||
@@ -89,7 +89,7 @@ def uncompress_LZC(data):
|
||||
buf, symbol = divmod(buf, dict_size)
|
||||
buf_bits -= num_bits
|
||||
except IndexError:
|
||||
raise ValueError('invalid data')
|
||||
raise ValueError("invalid data")
|
||||
|
||||
# re-initialize dictionary
|
||||
if blockmode and symbol == 256:
|
||||
@@ -108,7 +108,7 @@ def uncompress_LZC(data):
|
||||
if first_sym:
|
||||
first_sym = False
|
||||
if symbol >= 256:
|
||||
raise ValueError('invalid data')
|
||||
raise ValueError("invalid data")
|
||||
prev = symbol
|
||||
out_data.extend(comp_dict[symbol])
|
||||
continue
|
||||
@@ -124,7 +124,7 @@ def uncompress_LZC(data):
|
||||
elif symbol == head:
|
||||
comp_dict[head] = comp_dict[prev] + comp_dict[prev][0:1]
|
||||
else:
|
||||
raise ValueError('invalid data')
|
||||
raise ValueError("invalid data")
|
||||
prev = symbol
|
||||
|
||||
# output symbol
|
||||
@@ -148,42 +148,42 @@ def nvram_export(nvram):
|
||||
offset = 0
|
||||
# extract startup config
|
||||
try:
|
||||
(magic, data_format, _, _, _, _, length, _, _, _, _, _) = \
|
||||
struct.unpack_from('>HHHHIIIIIHHI', nvram, offset=offset)
|
||||
(magic, data_format, _, _, _, _, length, _, _, _, _, _) = struct.unpack_from(
|
||||
">HHHHIIIIIHHI", nvram, offset=offset
|
||||
)
|
||||
offset += 36
|
||||
if magic != 0xABCD:
|
||||
raise ValueError('no startup config')
|
||||
if len(nvram) < offset+length:
|
||||
raise ValueError('invalid length')
|
||||
startup = nvram[offset:offset+length]
|
||||
raise ValueError("no startup config")
|
||||
if len(nvram) < offset + length:
|
||||
raise ValueError("invalid length")
|
||||
startup = nvram[offset : offset + length]
|
||||
except struct.error:
|
||||
raise ValueError('invalid length')
|
||||
raise ValueError("invalid length")
|
||||
|
||||
# uncompress startup config
|
||||
if data_format == 2:
|
||||
try:
|
||||
startup = uncompress_LZC(startup)
|
||||
except ValueError as err:
|
||||
raise ValueError('uncompress startup: ' + str(err))
|
||||
raise ValueError("uncompress startup: " + str(err))
|
||||
|
||||
private = None
|
||||
try:
|
||||
# calculate offset of private header
|
||||
length += (4 - length % 4) % 4 # alignment to multiple of 4
|
||||
length += (4 - length % 4) % 4 # alignment to multiple of 4
|
||||
offset += length
|
||||
# check for additonal offset of 4
|
||||
(magic, data_format) = struct.unpack_from('>HH', nvram, offset=offset+4)
|
||||
(magic, data_format) = struct.unpack_from(">HH", nvram, offset=offset + 4)
|
||||
if magic == 0xFEDC and data_format == 1:
|
||||
offset += 4
|
||||
|
||||
# extract private config
|
||||
(magic, data_format, _, _, length) = \
|
||||
struct.unpack_from('>HHIII', nvram, offset=offset)
|
||||
(magic, data_format, _, _, length) = struct.unpack_from(">HHIII", nvram, offset=offset)
|
||||
offset += 16
|
||||
if magic == 0xFEDC and data_format == 1:
|
||||
if len(nvram) < offset+length:
|
||||
raise ValueError('invalid length')
|
||||
private = nvram[offset:offset+length]
|
||||
if len(nvram) < offset + length:
|
||||
raise ValueError("invalid length")
|
||||
private = nvram[offset : offset + length]
|
||||
|
||||
# missing private header is not an error
|
||||
except struct.error:
|
||||
@@ -192,22 +192,19 @@ def nvram_export(nvram):
|
||||
return (startup, private)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
# Main program
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
parser = argparse.ArgumentParser(description='%(prog)s exports startup/private configuration from IOU NVRAM file.')
|
||||
parser.add_argument('nvram', metavar='NVRAM',
|
||||
help='NVRAM file')
|
||||
parser.add_argument('startup', metavar='startup-config',
|
||||
help='startup configuration')
|
||||
parser.add_argument('private', metavar='private-config', nargs='?',
|
||||
help='private configuration')
|
||||
parser = argparse.ArgumentParser(description="%(prog)s exports startup/private configuration from IOU NVRAM file.")
|
||||
parser.add_argument("nvram", metavar="NVRAM", help="NVRAM file")
|
||||
parser.add_argument("startup", metavar="startup-config", help="startup configuration")
|
||||
parser.add_argument("private", metavar="private-config", nargs="?", help="private configuration")
|
||||
args = parser.parse_args()
|
||||
|
||||
try:
|
||||
fd = open(args.nvram, 'rb')
|
||||
fd = open(args.nvram, "rb")
|
||||
nvram = fd.read()
|
||||
fd.close()
|
||||
except OSError as err:
|
||||
@@ -221,14 +218,14 @@ if __name__ == '__main__':
|
||||
sys.exit(3)
|
||||
|
||||
try:
|
||||
fd = open(args.startup, 'wb')
|
||||
fd = open(args.startup, "wb")
|
||||
fd.write(startup)
|
||||
fd.close()
|
||||
if args.private is not None:
|
||||
if private is None:
|
||||
sys.stderr.write("Warning: No private config\n")
|
||||
else:
|
||||
fd = open(args.private, 'wb')
|
||||
fd = open(args.private, "wb")
|
||||
fd.write(private)
|
||||
fd.close()
|
||||
except OSError as err:
|
||||
|
||||
@@ -39,7 +39,7 @@ import struct
|
||||
|
||||
# calculate padding
|
||||
def padding(length, start_address):
|
||||
pad = -length % 4 # padding to alignment of 4
|
||||
pad = -length % 4 # padding to alignment of 4
|
||||
# extra padding if pad != 0 and big start_address
|
||||
if pad != 0 and (start_address & 0x80000000) != 0:
|
||||
pad += 4
|
||||
@@ -50,66 +50,64 @@ def padding(length, start_address):
|
||||
def checksum(data, start, end):
|
||||
chk = 0
|
||||
# calculate checksum of first two words
|
||||
for word in struct.unpack_from('>2H', data, start):
|
||||
for word in struct.unpack_from(">2H", data, start):
|
||||
chk += word
|
||||
|
||||
# add remaining words, ignoring old checksum at offset 4
|
||||
struct_format = f'>{(end - start - 6) // 2:d}H'
|
||||
for word in struct.unpack_from(struct_format, data, start+6):
|
||||
struct_format = f">{(end - start - 6) // 2:d}H"
|
||||
for word in struct.unpack_from(struct_format, data, start + 6):
|
||||
chk += word
|
||||
|
||||
# handle 16 bit overflow
|
||||
while chk >> 16:
|
||||
chk = (chk & 0xffff) + (chk >> 16)
|
||||
chk = chk ^ 0xffff
|
||||
chk = (chk & 0xFFFF) + (chk >> 16)
|
||||
chk = chk ^ 0xFFFF
|
||||
|
||||
# save checksum
|
||||
struct.pack_into('>H', data, start+4, chk)
|
||||
struct.pack_into(">H", data, start + 4, chk)
|
||||
|
||||
|
||||
# import IOU NVRAM
|
||||
# NVRAM format: https://github.com/ehlers/IOUtools/blob/master/NVRAM.md
|
||||
def nvram_import(nvram, startup, private, size):
|
||||
DEFAULT_IOS = 0x0F04 # IOS 15.4
|
||||
DEFAULT_IOS = 0x0F04 # IOS 15.4
|
||||
base_address = 0x10000000
|
||||
|
||||
# check size parameter
|
||||
if size is not None and (size < 8 or size > 1024):
|
||||
raise ValueError('invalid size')
|
||||
raise ValueError("invalid size")
|
||||
|
||||
# create new nvram if nvram is empty or has wrong size
|
||||
if nvram is None or (size is not None and len(nvram) != size*1024):
|
||||
nvram = bytearray([0] * (size*1024))
|
||||
if nvram is None or (size is not None and len(nvram) != size * 1024):
|
||||
nvram = bytearray([0] * (size * 1024))
|
||||
else:
|
||||
nvram = bytearray(nvram)
|
||||
|
||||
# check nvram size
|
||||
nvram_len = len(nvram)
|
||||
if nvram_len < 8*1024 or nvram_len > 1024*1024 or nvram_len % 1024 != 0:
|
||||
raise ValueError('invalid NVRAM length')
|
||||
if nvram_len < 8 * 1024 or nvram_len > 1024 * 1024 or nvram_len % 1024 != 0:
|
||||
raise ValueError("invalid NVRAM length")
|
||||
nvram_len = nvram_len // 2
|
||||
|
||||
# get size of current config
|
||||
config_len = 0
|
||||
try:
|
||||
(magic, _, _, ios, start_addr, _, length, _, _, _, _, _) = \
|
||||
struct.unpack_from('>HHHHIIIIIHHI', nvram, offset=0)
|
||||
(magic, _, _, ios, start_addr, _, length, _, _, _, _, _) = struct.unpack_from(">HHHHIIIIIHHI", nvram, offset=0)
|
||||
if magic == 0xABCD:
|
||||
base_address = start_addr - 36
|
||||
config_len = 36 + length + padding(length, base_address)
|
||||
(magic, _, _, _, length) = \
|
||||
struct.unpack_from('>HHIII', nvram, offset=config_len)
|
||||
(magic, _, _, _, length) = struct.unpack_from(">HHIII", nvram, offset=config_len)
|
||||
if magic == 0xFEDC:
|
||||
config_len += 16 + length
|
||||
else:
|
||||
ios = None
|
||||
except struct.error:
|
||||
raise ValueError('unknown nvram format')
|
||||
raise ValueError("unknown nvram format")
|
||||
if config_len > nvram_len:
|
||||
raise ValueError('unknown nvram format')
|
||||
raise ValueError("unknown nvram format")
|
||||
|
||||
# calculate max. config size
|
||||
max_config = nvram_len - 2*1024 # reserve 2k for files
|
||||
max_config = nvram_len - 2 * 1024 # reserve 2k for files
|
||||
idx = max_config
|
||||
empty_sector = bytearray([0] * 1024)
|
||||
while True:
|
||||
@@ -117,11 +115,10 @@ def nvram_import(nvram, startup, private, size):
|
||||
if idx < config_len:
|
||||
break
|
||||
# if valid file header:
|
||||
(magic, _, flags, length, _) = \
|
||||
struct.unpack_from('>HHHH24s', nvram, offset=idx)
|
||||
(magic, _, flags, length, _) = struct.unpack_from(">HHHH24s", nvram, offset=idx)
|
||||
if magic == 0xDCBA and flags < 8 and length <= 992:
|
||||
max_config = idx
|
||||
elif nvram[idx:idx+1024] != empty_sector:
|
||||
elif nvram[idx : idx + 1024] != empty_sector:
|
||||
break
|
||||
|
||||
# import startup config
|
||||
@@ -131,34 +128,46 @@ def nvram_import(nvram, startup, private, size):
|
||||
# the padding of a different version, the startup config is padded
|
||||
# with '\n' to the alignment of 4.
|
||||
ios = DEFAULT_IOS
|
||||
startup += b'\n' * (-len(startup) % 4)
|
||||
new_nvram.extend(struct.pack('>HHHHIIIIIHHI',
|
||||
0xABCD, # magic
|
||||
1, # raw data
|
||||
0, # checksum, not yet calculated
|
||||
ios, # IOS version
|
||||
base_address + 36, # start address
|
||||
base_address + 36 + len(startup), # end address
|
||||
len(startup), # length
|
||||
0, 0, 0, 0, 0))
|
||||
startup += b"\n" * (-len(startup) % 4)
|
||||
new_nvram.extend(
|
||||
struct.pack(
|
||||
">HHHHIIIIIHHI",
|
||||
0xABCD, # magic
|
||||
1, # raw data
|
||||
0, # checksum, not yet calculated
|
||||
ios, # IOS version
|
||||
base_address + 36, # start address
|
||||
base_address + 36 + len(startup), # end address
|
||||
len(startup), # length
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
)
|
||||
)
|
||||
new_nvram.extend(startup)
|
||||
new_nvram.extend([0] * padding(len(new_nvram), base_address))
|
||||
|
||||
# import private config
|
||||
if private is None:
|
||||
private = b''
|
||||
private = b""
|
||||
offset = len(new_nvram)
|
||||
new_nvram.extend(struct.pack('>HHIII',
|
||||
0xFEDC, # magic
|
||||
1, # raw data
|
||||
base_address + offset + 16, # start address
|
||||
base_address + offset + 16 + len(private), # end address
|
||||
len(private) )) # length
|
||||
new_nvram.extend(
|
||||
struct.pack(
|
||||
">HHIII",
|
||||
0xFEDC, # magic
|
||||
1, # raw data
|
||||
base_address + offset + 16, # start address
|
||||
base_address + offset + 16 + len(private), # end address
|
||||
len(private),
|
||||
)
|
||||
) # length
|
||||
new_nvram.extend(private)
|
||||
|
||||
# add rest
|
||||
if len(new_nvram) > max_config:
|
||||
raise ValueError('NVRAM size too small')
|
||||
raise ValueError("NVRAM size too small")
|
||||
new_nvram.extend([0] * (max_config - len(new_nvram)))
|
||||
new_nvram.extend(nvram[max_config:])
|
||||
|
||||
@@ -167,7 +176,7 @@ def nvram_import(nvram, startup, private, size):
|
||||
return new_nvram
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
# Main program
|
||||
import argparse
|
||||
import sys
|
||||
@@ -176,36 +185,32 @@ if __name__ == '__main__':
|
||||
try:
|
||||
value = int(string)
|
||||
except ValueError:
|
||||
raise argparse.ArgumentTypeError('invalid int value: ' + string)
|
||||
raise argparse.ArgumentTypeError("invalid int value: " + string)
|
||||
if value < 8 or value > 1024:
|
||||
raise argparse.ArgumentTypeError('size must be 8..1024')
|
||||
raise argparse.ArgumentTypeError("size must be 8..1024")
|
||||
return value
|
||||
|
||||
parser = argparse.ArgumentParser(description='%(prog)s imports startup/private configuration into IOU NVRAM file.')
|
||||
parser.add_argument('-c', '--create', metavar='size', type=check_size,
|
||||
help='create NVRAM file, size in kByte')
|
||||
parser.add_argument('nvram', metavar='NVRAM',
|
||||
help='NVRAM file')
|
||||
parser.add_argument('startup', metavar='startup-config',
|
||||
help='startup configuration')
|
||||
parser.add_argument('private', metavar='private-config', nargs='?',
|
||||
help='private configuration')
|
||||
parser = argparse.ArgumentParser(description="%(prog)s imports startup/private configuration into IOU NVRAM file.")
|
||||
parser.add_argument("-c", "--create", metavar="size", type=check_size, help="create NVRAM file, size in kByte")
|
||||
parser.add_argument("nvram", metavar="NVRAM", help="NVRAM file")
|
||||
parser.add_argument("startup", metavar="startup-config", help="startup configuration")
|
||||
parser.add_argument("private", metavar="private-config", nargs="?", help="private configuration")
|
||||
args = parser.parse_args()
|
||||
|
||||
try:
|
||||
if args.create is None:
|
||||
fd = open(args.nvram, 'rb')
|
||||
fd = open(args.nvram, "rb")
|
||||
nvram = fd.read()
|
||||
fd.close()
|
||||
else:
|
||||
nvram = None
|
||||
fd = open(args.startup, 'rb')
|
||||
fd = open(args.startup, "rb")
|
||||
startup = fd.read()
|
||||
fd.close()
|
||||
if args.private is None:
|
||||
private = None
|
||||
else:
|
||||
fd = open(args.private, 'rb')
|
||||
fd = open(args.private, "rb")
|
||||
private = fd.read()
|
||||
fd.close()
|
||||
except OSError as err:
|
||||
@@ -219,7 +224,7 @@ if __name__ == '__main__':
|
||||
sys.exit(3)
|
||||
|
||||
try:
|
||||
fd = open(args.nvram, 'wb')
|
||||
fd = open(args.nvram, "wb")
|
||||
fd.write(nvram)
|
||||
fd.close()
|
||||
except OSError as err:
|
||||
|
||||
Reference in new issue
Block a user