From 7c564575459e2780d65cc617212047776dc5f5be Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Thu, 3 Sep 2015 10:28:38 +0200 Subject: [PATCH] Add a script for helping people to create a new appliance --- README.rst | 16 +++++-- new_appliance.py | 117 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+), 3 deletions(-) create mode 100644 new_appliance.py diff --git a/README.rst b/README.rst index c2c409f..ca13015 100644 --- a/README.rst +++ b/README.rst @@ -4,13 +4,15 @@ GNS3-registry This is the GNS3 registry. - - Add a new appliance ################### -Copy paste a JSON from the appliances directory and send a pull request. +Two way to create a new appliance: +* Copy paste a JSON from the appliances directory +* Use the new_appliance.py + +After that you can send us a pull request on Github. In schemas/appliance.json you have a JSON with a schema for controlling the file. @@ -49,3 +51,11 @@ Check appliance files python3 check.py + +Create a new appliance +----------------------- + +.. code:: bash + + python3 new_appliance.py + diff --git a/new_appliance.py b/new_appliance.py new file mode 100644 index 0000000..a7130c3 --- /dev/null +++ b/new_appliance.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python +# +# Copyright (C) 2015 GNS3 Technologies Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +""" +Create a new appliance from the terminal +""" + +import json +import os +import sys + + +def ask_multiple(question, options, optional=False): + while True: + for i, option in enumerate(options): + question += '\n{}) {}'.format(i + 1, option) + question += '\n' + answer = ask(question, type='integer', optional=optional) + if answer is None: + if optional: + return None + else: + if answer > 0 and answer <= len(options): + return options[answer - 1] + + +def yesno(question): + while True: + answer = ask(question + '[y/n]') + if answer in ['y', 'Y', 'yes']: + return True + if answer in ['n', 'N', 'no']: + return False + + +def ask(question, type='string', optional=False): + while True: + if optional: + sys.stdout.write(question + "(optional leave blank for skip) : ") + else: + sys.stdout.write(question + ": ") + val = sys.stdin.readline().strip() + if len(val) == 0: + if optional: + return None + continue + if type == 'integer': + try: + val = int(val) + except ValueError: + continue + sys.stdout.write("\n") + return val + + +def ask_from_schema(schema): + data = {} + for key,val in schema['properties'].items(): + optional = not key in schema['required'] + result = None + + if 'enum' in val: + result = ask_multiple(val['title'], val['enum'], optional=optional) + elif val['type'] in ('integer', 'string'): + result = ask(val['title'], type=val['type'], optional=optional) + + if result: + data[key] = result + return data + + +with open(os.path.join('schemas', 'appliance.json')) as f: + schema = json.load(f) + + +appliance_name = ask('Appliance id (example: cisco-asav)') + +# TODO check if file exists +with open(os.path.join('appliances', appliance_name + '.json'), 'w+') as f: + appliance = {} + appliance = ask_from_schema(schema) + appliance['qemu'] = ask_from_schema(schema['properties']['qemu']) + + appliance['images'] = [] + files = [] + while yesno('Add image?'): + image = ask_from_schema(schema['properties']['images']['items']) + appliance['images'].append(image) + files.append(image['filename']) + + appliance['versions'] = [] + while yesno('Add appliance version?'): + version = {'images': {}} + version['name'] = ask('Appliance version name') + for disk in ['hda_disk_image', 'hdb_disk_image', 'hdc_disk_image', 'hdd_disk_image', 'cdrom_image', 'initrd_image', 'kernel_image']: + img = ask_multiple('Image for ' + disk, files, optional=True) + if img: + version['images'][disk] = img + + appliance['versions'].append(version) + + json.dump(appliance, f, indent=4)