Send a warning notification if there is not enough RAM left to start a VM. Implements #329.

This commit is contained in:
grossmj 2015-10-12 15:57:37 -06:00
parent c700804014
commit ac75977ae0
8 changed files with 38 additions and 1 deletions

View File

@ -21,6 +21,8 @@ import aiohttp
import shutil import shutil
import asyncio import asyncio
import tempfile import tempfile
import psutil
import platform
from pkg_resources import parse_version from pkg_resources import parse_version
from ..utils.asyncio import wait_run_in_executor from ..utils.asyncio import wait_run_in_executor
@ -309,3 +311,20 @@ class BaseVM:
""" """
return self._hw_virtualization return self._hw_virtualization
def check_available_ram(self, requested_ram):
"""
Sends a warning notification if there is not enough RAM on the system to allocate requested RAM.
:param requested_ram: requested amount of RAM in MB
"""
available_ram = int(psutil.virtual_memory().available / (1024 * 1024))
percentage_left = psutil.virtual_memory().percent
if requested_ram > available_ram:
message = '"{}" requires {}MB of RAM to run but there is only {}MB - {}% of RAM left on "{}"'.format(self.name,
requested_ram,
available_ram,
percentage_left,
platform.node())
self.project.emit("log.warning", {"message": message})

View File

@ -247,6 +247,10 @@ class Router(BaseVM):
if elf_header_start != b'\x7fELF\x01\x02\x01': if elf_header_start != b'\x7fELF\x01\x02\x01':
raise DynamipsError('"{}" is not a valid IOS image'.format(self._image)) raise DynamipsError('"{}" is not a valid IOS image'.format(self._image))
# check if there is enough RAM to run
if not self._ghost_flag:
self.check_available_ram(self.ram)
yield from self._hypervisor.send('vm start "{name}"'.format(name=self._name)) yield from self._hypervisor.send('vm start "{name}"'.format(name=self._name))
self.status = "started" self.status = "started"
log.info('router "{name}" [{id}] has been started'.format(name=self._name, id=self._id)) log.info('router "{name}" [{id}] has been started'.format(name=self._name, id=self._id))

View File

@ -492,6 +492,9 @@ class IOUVM(BaseVM):
self._create_netmap_config() self._create_netmap_config()
self._push_configs_to_nvram() self._push_configs_to_nvram()
# check if there is enough RAM to run
self.check_available_ram(self.ram)
# created a environment variable pointing to the iourc file. # created a environment variable pointing to the iourc file.
env = os.environ.copy() env = os.environ.copy()

View File

@ -849,6 +849,9 @@ class QemuVM(BaseVM):
except OSError as e: except OSError as e:
raise QemuError("Could not find free port for the Qemu monitor: {}".format(e)) raise QemuError("Could not find free port for the Qemu monitor: {}".format(e))
# check if there is enough RAM to run
self.check_available_ram(self.ram)
self._command = yield from self._build_command() self._command = yield from self._build_command()
command_string = " ".join(shlex.quote(s) for s in self._command) command_string = " ".join(shlex.quote(s) for s in self._command)
try: try:

View File

@ -202,6 +202,9 @@ class VirtualBoxVM(BaseVM):
yield from self._set_network_options() yield from self._set_network_options()
yield from self._set_serial_console() yield from self._set_serial_console()
# check if there is enough RAM to run
self.check_available_ram(self.ram)
args = [self._vmname] args = [self._vmname]
if self._headless: if self._headless:
args.extend(["--type", "headless"]) args.extend(["--type", "headless"])

View File

@ -419,6 +419,9 @@ class VMwareVM(BaseVM):
yield from self._start_ubridge() yield from self._start_ubridge()
self._read_vmx_file() self._read_vmx_file()
# check if there is enough RAM to run
if "memsize" in self._vmx_pairs:
self.check_available_ram(int(self._vmx_pairs["memsize"]))
self._set_network_options() self._set_network_options()
self._set_serial_console() self._set_serial_console()
self._write_vmx_file() self._write_vmx_file()

View File

@ -4,3 +4,4 @@ Jinja2>=2.7.3
raven>=5.2.0 raven>=5.2.0
gns3-netifaces==0.10.4.1 gns3-netifaces==0.10.4.1
docker-py==1.4.0 docker-py==1.4.0
psutil>=2.2.1

View File

@ -43,7 +43,8 @@ dependencies = [
"aiohttp>=0.15.1", "aiohttp>=0.15.1",
"Jinja2>=2.7.3", "Jinja2>=2.7.3",
"raven>=5.2.0", "raven>=5.2.0",
"docker-py>=1.4.0" "docker-py>=1.4.0",
"psutil>=2.2.1"
] ]
if not sys.platform.startswith("win"): if not sys.platform.startswith("win"):