Install remote image

This commit is contained in:
Julien Duponchelle 2015-05-21 18:51:43 +02:00
parent 78542eee40
commit 43a10887c3
6 changed files with 100 additions and 19 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
__pycache__
*.pyc

View File

@ -10,3 +10,21 @@ Add an image
************
python3.4 gns3repository/main.py --add ~/Downloads/linux-microcore-3.4.1.img
Search an image
****************
python3.4 gns3repository/main.py --search core
Micro Core Linux:
* 3.4.1 linux-microcore-3.4.1.img: 5f42d71b30bc682e44ccf7340e20ea7ea8967ef5
* 4.0.2 linux-microcore-4.0.2-clean.img: 0252f2c913519c993b812325bbd553af2d77218a
Install a remote image
**************************
If the image is available from the internet you can download it:
python3.4 gns3repository/main.py --install 0252f2c913519c993b812325bbd553af2d77218a
Download http://downloads.sourceforge.net/project/gns-3/Qemu%20Appliances/linux-microcore-4.0.2-clean.img to /Users/noplay/GNS3/images/linux-microcore-4.0.2-clean.img

View File

@ -41,6 +41,13 @@ class Config:
with open(self.path) as f:
self._config = json.load(f)
@property
def images_dir(self):
"""
:returns: Localion of the images directory on the server
"""
return self._config["LocalServer"]["images_path"]
def _get_standard_config_file_path(self):
if sys.platform.startswith("win"):
filename = "gns3_gui.ini"
@ -111,5 +118,5 @@ class Config:
Save the configuration file
"""
with open(self.path, "w+") as f:
json.dump(self._config, f)
json.dump(self._config, f, indent=4)

View File

@ -26,6 +26,10 @@ sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
from gns3repository.repository import Repository
from gns3repository.config import Config
repository = Repository()
config = Config()
def yes_no(message):
while True:
try:
@ -33,27 +37,42 @@ def yes_no(message):
except ValueError:
pass
def add_image(image):
confs = repository.detect_image(image)
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)
config.save()
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Manage GNS3 repository')
parser.add_argument('--add', dest='add_image', action='store',
help='Add an image to GNS')
parser = argparse.ArgumentParser(description="Manage GNS3 repository")
parser.add_argument("--add", dest="add_image", action="store",
help="Add an image to GNS3")
parser.add_argument("--search", dest="search", action="store",
help="Search an image for GNS3")
parser.add_argument("--install", dest="install", action="store",
help="Download and install an image for GNS3")
args = parser.parse_args()
print("WARNING WARNING WARNING")
print("It's experimental")
print("Please close the GUI before using it")
repository = Repository()
config = Config()
print("")
if args.add_image:
confs = repository.detect_image(args.add_image)
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)
config.save()
add_image(args.add_image)
elif args.search:
for res in repository.search_device(args.search):
print("{}: ".format(res["name"]))
for file in res["hda_disk_image"]:
print(" * {} {}: {}".format(file["version"], file["filename"], file["sha1sum"]))
elif args.install:
image = repository.download_image(args.install, config.images_dir)
add_image(image)
else:
parser.print_help()
sys.exit(1)

View File

@ -20,6 +20,8 @@
import hashlib
import json
import os
import re
import urllib.request
from gns3repository.image import Image
@ -36,16 +38,44 @@ class Repository:
configurations = []
#TODO: Manage open error
for config in self._all_configs():
if self._image_match(image, config):
configurations.append(config)
return configurations
def download_image(self, sha1sum, images_dir):
for config in self._all_configs():
for file in config.get("hda_disk_image", []):
if file["sha1sum"] == sha1sum:
path = os.path.join(images_dir, file["filename"])
print("Download {} to {}".format(file["direct_download_url"], path))
#TODO: Skip download if file already exist with same sha1
urllib.request.urlretrieve(file["direct_download_url"], path)
return path
def search_device(self, query):
results = []
for config in self._all_configs():
if re.match(r".*{}.*".format(query), config["name"], flags=re.IGNORECASE):
results.append(config)
return results
def _all_configs(self):
"""
Iterate on all configs available on devices
"""
devices_path = self._get_devices_path()
for (dirpath, dirnames, filenames) in os.walk(devices_path):
for filename in filenames:
file = os.path.join(dirpath, filename)
with open(os.path.join(devices_path, file)) as f:
config = json.load(f)
if self._image_match(image, config):
configurations.append(config)
return configurations
if file.endswith(".json"):
with open(os.path.join(devices_path, file)) as f:
config = json.load(f)
config["filename"] = file[:-5]
yield config
def _image_match(self, image, config):
"""

View File

@ -37,3 +37,9 @@ def test_detect_image(linux_microcore_img):
def test_detect_unknow_image(empty_file):
repository = Repository()
assert repository.detect_image(empty_file) == []
def test_search_device():
repository = Repository()
results = repository.search_device("Micro Core Linux")
assert len(results) == 1