1
0
mirror of https://github.com/GNS3/gns3-server synced 2024-11-24 09:18:08 +00:00

Merge pull request #21 from planctechnologies/master

Create cloud server images
This commit is contained in:
Jeremy Grossmann 2014-06-27 11:04:17 -06:00
commit 47d43a91ff
5 changed files with 281 additions and 0 deletions

5
cloud-image/.novarc Normal file
View File

@ -0,0 +1,5 @@
export OS_USERNAME=username
export OS_PASSWORD=""
export OS_TENANT_NAME=000000
export OS_AUTH_URL=https://identity.api.rackspacecloud.com/v2.0/
export OS_REGION_NAME=ord

242
cloud-image/create_image.py Normal file
View File

@ -0,0 +1,242 @@
""" Create a new GNS3 Server Rackspace image with the provided options. """
import argparse
import getpass
import os
import sys
import uuid
from fabric.api import env
from fabric.contrib.files import exists
from github import Github
from novaclient.v1_1 import client
from string import Template
from time import sleep
POLL_SEC = 20
GNS3_REPO = 'gns3/gns3-server'
PLANC_REPO = 'planctechnologies/gns3-server'
OS_AUTH_URL = 'https://identity.api.rackspacecloud.com/v2.0/'
UBUNTU_BASE_ID = '5cc098a5-7286-4b96-b3a2-49f4c4f82537'
def main():
"""
Get the user options and perform the image creation.
Creates a new instance, installs the required software, creates an image
from the instance, and then deletes the instance.
"""
github = Github()
args = get_cli_args()
if args.username:
username = args.username
else:
if 'OS_USERNAME' in os.environ:
username = os.environ.get('OS_USERNAME')
else:
username = raw_input('Enter Rackspace username: ')
if args.password:
password = args.password
else:
if 'OS_PASSWORD' in os.environ:
password = os.environ.get('OS_PASSWORD')
else:
password = getpass.getpass('Enter Rackspace password: ')
if args.tenant:
tenant = args.tenant
else:
if 'OS_TENANT_NAME' in os.environ:
tenant = os.environ.get('OS_TENANT_NAME')
else:
tenant = raw_input('Enter Rackspace Tenant ID: ')
if args.region:
region = args.region
else:
if 'OS_REGION_NAME' in os.environ:
region = os.environ.get('OS_REGION_NAME')
else:
region = raw_input('Enter Rackspace Region Name: ')
if args.source == 'release':
# get the list of releases, present them to the user, save the url
repo = github.get_repo(GNS3_REPO)
keyword = "tag"
i = 1
branch_opts = {}
for tag in repo.get_tags():
branch_opts[i] = tag.name
i += 1
elif args.source == 'dev':
# get the list of dev branches, present them to the user, save the url
repo = github.get_repo(PLANC_REPO)
keyword = "branch"
i = 1
branch_opts = {}
for branch in repo.get_branches():
branch_opts[i] = branch.name
i += 1
prompt_text = "Select a %s" % keyword
selected_branch = prompt_user_select(branch_opts, prompt_text)
if args.image_name:
image_name = args.image_name
else:
image_name = "gns3-%s-%s-%s" % (args.source, selected_branch,
uuid.uuid4().hex[0:4])
if args.on_boot:
on_boot = True
else:
on_boot = False
startup_script = create_script(repo.svn_url, selected_branch, on_boot)
server_name = uuid.uuid4().hex
instance = create_instance(username, password, tenant, region, server_name,
startup_script)
passwd = uuid.uuid4().hex
instance.change_password(passwd)
# wait for the password change to be processed
sleep(POLL_SEC)
env.host_string = str(instance.accessIPv4)
env.user = "root"
env.password = passwd
sys.stdout.write("Installing software...")
sys.stdout.flush()
while True:
if exists('/tmp/gns-install-complete'):
break
sleep(POLL_SEC)
sys.stdout.write(".")
sys.stdout.flush()
print("Done.")
image_id = create_image(username, password, tenant, region, instance,
image_name)
instance.delete()
def prompt_user_select(opts, text="Please select"):
""" Ask the user to select an option from the provided list. """
print("%s" % text)
print("=" * len(text))
for o in opts:
print("(%s)\t%s" % (o, opts[o]))
while True:
selected = raw_input("Select: ")
try:
return opts[int(selected)]
except (KeyError, ValueError):
print("Invalid selection. Try again")
def create_instance(username, password, tenant, region, server_name, script,
auth_url=OS_AUTH_URL):
""" Create a new instance. """
sys.stdout.write("Creating instance...")
sys.stdout.flush()
nc = client.Client(username, password, tenant, auth_url,
region_name=region)
server = nc.servers.create(server_name, UBUNTU_BASE_ID, 2,
config_drive=True, userdata=script)
while True:
server = nc.servers.get(server.id)
if server.status == 'ACTIVE':
break
sleep(POLL_SEC)
sys.stdout.write(".")
sys.stdout.flush()
print("Done.")
return server
def create_script(git_url, git_branch, on_boot):
""" Create the start-up script. """
script_template = Template(open('script_template', 'r').read())
params = {'git_url': git_url, 'git_branch': git_branch, 'rc_local': ''}
if on_boot:
params['rc_local'] = "echo '/usr/local/bin/gns3-server' >> /etc/rc.local"
return script_template.substitute(params)
def create_image(username, password, tenant, region, server,
image_name, auth_url=OS_AUTH_URL):
""" Create a Rackspace image based on the server instance. """
nc = client.Client(username, password, tenant, auth_url,
region_name=region)
sys.stdout.write("Creating image %s..." % image_name)
sys.stdout.flush()
image_id = server.create_image(image_name)
while True:
server = nc.servers.get(server.id)
if getattr(server, 'OS-EXT-STS:task_state') is None:
break
sleep(POLL_SEC)
sys.stdout.write(".")
sys.stdout.flush()
print("Done.")
return image_id
def get_cli_args():
""" Parse the CLI input. """
parser = argparse.ArgumentParser(
description='Create a new GNS3 image',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument(
'--rackspace_username', dest='username', action='store')
parser.add_argument(
'--rackspace_password', dest='password', action='store')
parser.add_argument(
'--rackspace_tenant', dest='tenant', action='store')
parser.add_argument(
'--rackspace_region', dest='region', action='store')
parser.add_argument(
'--source', dest='source', action='store', choices=['release', 'dev'],
default='release', help='specify the gns3-server source location')
parser.add_argument(
'--branch', dest='branch', action='store',
help='specify the branch/tag')
parser.add_argument(
'--start-on-boot', dest='on_boot', action='store_true',
default=False, help='start the GNS3-server when the image boots')
parser.add_argument(
'--image-name', dest='image_name', action='store',
help='the name of the image to be created')
return parser.parse_args()
if __name__ == "__main__":
main()

View File

@ -0,0 +1,3 @@
fabric
pygithub
python-novaclient

10
cloud-image/readme.txt Normal file
View File

@ -0,0 +1,10 @@
create_image.py:
- uses fabric, which doesn't support Python 3
- prompts for Rackspace credentials if environment variables not set
- see .novarc for example env variables
- note that the novaclient library uses the Rackspace password and -not-
the API key
- use '--help' for help with arguments

View File

@ -0,0 +1,21 @@
#!/bin/bash
export DEBIAN_FRONTEND=noninteractive
apt-get -y update
apt-get -o Dpkg::Options::="--force-confnew" --force-yes -fuy dist-upgrade
apt-get -y install git
apt-get -y install python3-setuptools
apt-get -y install python3-netifaces
apt-get -y install python3-pip
mkdir -p /opt/gns3
pushd /opt/gns3
git clone --branch ${git_branch} ${git_url}
cd gns3-server
pip3 install tornado
pip3 install pyzmq
pip3 install jsonschema
python3 ./setup.py install
${rc_local}
touch /tmp/gns-install-complete