Support adding two images

This commit is contained in:
Julien Duponchelle 2015-05-22 15:28:25 +02:00
parent 7048d9a9b0
commit efb3381607
5 changed files with 151 additions and 37 deletions

View File

@ -23,6 +23,10 @@ import os
from gns3registry.image import Image
class ConfigException(Exception):
pass
class Config:
"""
GNS3 config file
@ -66,9 +70,9 @@ class Config:
home = os.path.expanduser("~")
return os.path.join(home, ".config", appname, filename)
def add_image(self, device_config):
def add_images(self, device_config):
"""
Add an image to the user configuration
Add images to the user configuration
"""
new_config = {
"server": "local",
@ -76,6 +80,9 @@ class Config:
}
if device_config["category"] == "guest":
new_config["category"] = 2
elif device_config["category"] == "router":
new_config["category"] = 0
if "qemu" in device_config:
self._add_qemu_config(new_config, device_config)
@ -99,19 +106,32 @@ class Config:
#TODO: Manage Windows
if device_config["qemu"]["processor"] == "i386":
new_config["qemu_path"] = "qemu-system-i386"
elif device_config["qemu"]["processor"] == "x64":
new_config["qemu_path"] = "qemu-system-x86_64"
if device_config["category"] == "guest":
new_config["default_symbol"] = ":/symbols/qemu_guest.normal.svg"
new_config["hover_symbol"] = ":/symbols/qemu_guest.selected.svg"
elif device_config["category"] == "router":
new_config["default_symbol"] = ":/symbols/router.normal.svg"
new_config["hover_symbol"] = ":/symbols/router.selected.svg"
if isinstance(device_config["images"]["hda_disk_image"], Image):
new_config["name"] += " {}".format(device_config["images"]["hda_disk_image"].version)
new_config["hda_disk_image"] = device_config["images"]["hda_disk_image"].path
disks = ["hda_disk_image", "hdb_disk_image", "hdc_disk_image", "hdd_disk_image"]
for disk in disks:
if disk in device_config["images"]:
if isinstance(device_config["images"][disk], list):
require_images = ""
for image in device_config["images"][disk]:
require_images += "* {}\n".format(image["filename"])
raise ConfigException("Missing image for {} you should provide one of the following images:\n{}".format(disk, require_images))
else:
new_config["name"] += " {}".format(device_config["images"][disk].version)
new_config[disk] = device_config["images"][disk].path
# Remove VM with the same Name
self._config["Qemu"]["vms"] = [item for item in self._config["Qemu"]["vms"] if item["name"] != new_config["name"]]
self._config["Qemu"]["vms"] .append(new_config)
self._config["Qemu"]["vms"].append(new_config)
def save(self):
"""

View File

@ -24,7 +24,7 @@ from distutils.util import strtobool
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
from gns3registry.registry import Registry
from gns3registry.config import Config
from gns3registry.config import Config, ConfigException
registry = Registry()
config = Config()
@ -37,25 +37,29 @@ def yes_no(message):
except ValueError:
pass
def add_image(image):
def add_images(images):
print("WARNING WARNING WARNING")
print("It's experimental")
print("Please close the GUI before using it")
print("")
confs = registry.detect_image(image)
confs = registry.detect_images(images)
if len(confs) > 0:
print("Found: {} devices configuration".format(len(confs)))
for conf in confs:
if yes_no("Add {}?".format(conf["name"])):
config.add_image(conf)
try:
config.add_images(conf)
except ConfigException as e:
print(e, file=sys.stderr)
sys.exit(1)
config.save()
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Manage GNS3 registry")
parser.add_argument("--add", dest="add_image", action="store",
help="Add an image to GNS3")
parser.add_argument("--add", dest="add_images", action="store", nargs='+',
help="Add images to GNS3")
parser.add_argument("--search", dest="search", action="store",
help="Search an image for GNS3")
parser.add_argument("--install", dest="install", action="store",
@ -68,8 +72,8 @@ if __name__ == "__main__":
if args.test:
sys.exit(0)
if args.add_image:
add_image(args.add_image)
if args.add_images:
add_images(args.add_images)
elif args.search:
print("Available images\n")
for res in registry.search_device(args.search):
@ -81,7 +85,7 @@ if __name__ == "__main__":
elif args.install:
image = registry.download_image(args.install, config.images_dir)
if image:
add_image(image)
add_images([image])
else:
parser.print_help()
sys.exit(1)

View File

@ -25,21 +25,31 @@ import urllib.request
from gns3registry.image import Image
class Registry:
def __init__(self):
pass
def detect_image(self, image_path):
def detect_images(self, images_path):
"""
:returns: Array of configuration corresponding to the image
"""
image = Image(image_path)
images = []
for path in images_path:
images.append(Image(path))
configurations = []
#TODO: Manage open error
for config in self._all_configs():
if self._image_match(image, config):
matched = False
for image in images:
if self._image_match(image, config):
matched = True
if matched:
configurations.append(config)
return configurations
@ -85,11 +95,16 @@ class Registry:
:returns: True if image is present in configuration
"""
for image_type in config.get("images", {}):
for file in config["images"].get(image_type, []):
if file.get("sha1sum", None) == image.sha1sum:
image.version = file["version"]
config["images"][image_type] = image
return True
images = config["images"].get(image_type, [])
# If it's not a list it's mean we have already detect the image
if not isinstance(images, list):
continue
for file in images:
if isinstance(file, dict):
if file.get("sha1sum", None) == image.sha1sum:
image.version = file["version"]
config["images"][image_type] = image
return True
return False
def _get_devices_path(self):
@ -98,5 +113,3 @@ class Registry:
"""
path = os.path.abspath(os.path.dirname(__file__))
return os.path.join(path, "..", "devices")

View File

@ -19,12 +19,13 @@
import pytest
import json
from unittest.mock import MagicMock
from gns3registry.config import Config
from gns3registry.config import Config, ConfigException
from gns3registry.image import Image
@pytest.fixture
@pytest.fixture(scope="function")
def empty_config(tmpdir):
config = {
"LocalServer": {
@ -75,13 +76,13 @@ def empty_config(tmpdir):
return Config(path)
def test_add_image(empty_config, linux_microcore_img):
def test_add_images_guest(empty_config, linux_microcore_img):
with open("devices/qemu/microcore-linux.json") as f:
config = json.load(f)
image = Image(linux_microcore_img)
image.version = "3.4.1"
config["images"]["hda_disk_image"] = image
empty_config.add_image(config)
empty_config.add_images(config)
assert empty_config._config["Qemu"]["vms"][0] == {
"adapter_type": "e1000",
"adapters": 1,
@ -106,23 +107,88 @@ def test_add_image(empty_config, linux_microcore_img):
}
def test_add_image_uniq(empty_config, linux_microcore_img):
def test_add_images_router_two_disk(empty_config):
with open("devices/qemu/arista-veos.json") as f:
config = json.load(f)
image = MagicMock()
image.version = "2.1.0"
image.sha1sum = "ea9dc1989764fc6db1d388b061340743016214a7"
image.path = "/a"
config["images"]["hda_disk_image"] = image
image = MagicMock()
image.version = "4.13.8M"
image.sha1sum = "ff50656fe817c420e9f7fbb0c0ee41f1ca52fee2"
image.path = "/b"
config["images"]["hdb_disk_image"] = image
empty_config.add_images(config)
assert empty_config._config["Qemu"]["vms"][0]["name"] == "Arista vEOS 2.1.0 4.13.8M"
assert empty_config._config["Qemu"]["vms"][0] == {
"adapter_type": "e1000",
"adapters": 8,
"category": 0,
"cpu_throttling": 0,
"default_symbol": ":/symbols/router.normal.svg",
"hda_disk_image": "/a",
"hdb_disk_image": "/b",
"hdc_disk_image": "",
"hdd_disk_image": "",
"hover_symbol": ":/symbols/router.selected.svg",
"initrd": "",
"kernel_command_line": "",
"kernel_image": "",
"legacy_networking": False,
"name": "Arista vEOS 2.1.0 4.13.8M",
"options": "",
"process_priority": "normal",
"qemu_path": "qemu-system-x86_64",
"ram": 2048,
"server": "local"
}
def test_add_images_uniq(empty_config, linux_microcore_img):
with open("devices/qemu/microcore-linux.json") as f:
config = json.load(f)
image = Image(linux_microcore_img)
image.version = "3.4.1"
config["hda_disk_image"] = image
empty_config.add_image(config)
config["adapters"] = 2
empty_config.add_image(config)
config["images"]["hda_disk_image"] = image
empty_config.add_images(config)
config["qemu"]["adapters"] = 2
empty_config.add_images(config)
assert len(empty_config._config["Qemu"]["vms"]) == 1
assert empty_config._config["Qemu"]["vms"][0]["adapters"] == 2
def test_add_images_two_disk_one_missing(empty_config):
with open("devices/qemu/arista-veos.json") as f:
config = json.load(f)
image = MagicMock()
image.version = "2.1.0"
image.sha1sum = "ea9dc1989764fc6db1d388b061340743016214a7"
config["images"]["hda_disk_image"] = image
with pytest.raises(ConfigException):
empty_config.add_images(config)
assert len(empty_config._config["Qemu"]["vms"]) == 0
def test_save(empty_config, linux_microcore_img):
with open("devices/qemu/microcore-linux.json") as f:
config = json.load(f)
empty_config.add_image(config)
image = Image(linux_microcore_img)
image.version = "3.4.1"
config["images"]["hda_disk_image"] = image
empty_config.add_images(config)
empty_config.save()
with open(empty_config.path) as f:
assert "Micro Core" in f.read()

View File

@ -29,14 +29,25 @@ def test_detect_image(linux_microcore_img):
config = json.load(f)
registry = Registry()
detected = registry.detect_image(linux_microcore_img)
detected = registry.detect_images([linux_microcore_img])
assert detected[0]["name"] == "Micro Core Linux"
assert detected[0]["images"]["hda_disk_image"].version == "3.4.1"
def test_detect_two_image(linux_microcore_img):
with open("devices/qemu/microcore-linux.json") as f:
config = json.load(f)
registry = Registry()
detected = registry.detect_images([linux_microcore_img])
assert detected[0]["name"] == "Micro Core Linux"
assert detected[0]["images"]["hda_disk_image"].version == "3.4.1"
def test_detect_unknow_image(empty_file):
registry = Registry()
assert registry.detect_image(empty_file) == []
assert registry.detect_images([empty_file]) == []
def test_search_device():