blob: 18cf0879ef5a9e2b4f426aacc29c44444b650413 [file] [log] [blame]
#!/usr/bin/python3
#
# Copyright 2016 RIFT.IO Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Author(s): Anil Gunturu
# Creation Date: 07/24/2014
#
"""
This is a skeletal python tool that invokes the rwcal plugin
to perform cloud operations.
"""
import argparse
import os
import socket
import sys
import logging
from gi import require_version
require_version('RwCal', '1.0')
from gi.repository import GObject, Peas, GLib, GIRepository
from gi.repository import RwCal, RwTypes
def resource_list_subcommand(rwcloud, cmdargs):
status, flavorinfo = rwcloud.get_flavor_list()
status, vminfo = rwcloud.get_vm_list()
if vminfo is None:
return
hosts = {}
# no yaml module installed for Python3, hack for now
if cmdargs.hostinfo_file_name:
with open(cmdargs.hostinfo_file_name, 'r') as f:
lines = f.readlines()
host = None
for l in lines:
l = l.strip()
if l == 'hosts:':
continue
if l == '-':
if host:
hosts[host['name']] = host
#hosts.append(host)
host = {}
continue
k,v = l.split(':')
host[k.strip()] = v.strip()
# Collect the unique Top of Rack (TOR) swithes
tors = set(hosts[vm.host_name]['tor'].lower() for vm in vminfo.vminfo_list)
print("resources:")
for vm in vminfo.vminfo_list:
_, __, host_ip_list = socket.gethostbyaddr(vm.host_name)
print(" -")
print(" name: {}".format(vm.vm_name))
print(" osid: {}".format(vm.vm_id))
print(" host_name: {}".format(vm.host_name))
print(" host_ip: {}".format(host_ip_list[0]))
controller, scratch = cmdargs.auth_url[7:].split(':')
print(" controller: {}".format(controller))
print(" tor: {}".format(hosts[vm.host_name]['tor']))
print(" image_name: {}".format(vm.image_name))
print(" flavor_name: {}".format(vm.flavor_name))
print(" availability_zone: {}".format(vm.availability_zone))
print(" private_ip_list: {}".format(
sorted(v.ip_address for v in vm.private_ip_list)
))
# select the 10.0 network for management ip
for p in vm.private_ip_list:
if p.ip_address.startswith('10.0.'):
print(" ip_address: {}".format(p.ip_address))
break;
print(" public_ip_list: {}".format(
[v.ip_address for v in vm.public_ip_list]
))
for flavor in flavorinfo.flavorinfo_list:
if flavor.name == vm.flavor_name:
print(" vcpu: {}".format(flavor.vcpus))
print(" ram: {}".format(flavor.memory))
print(" disk: {}".format(flavor.disk))
print(" host_aggregate_list: {}".format(
[a.name for a in flavor.host_aggregate_list]
))
print(" pci_passthrough_device_list: {}".format(
[(d.alias,d.count) for d in flavor.pci_passthrough_device_list]
))
# Number of openflow switches this resource connects to are the
# number of TOR switches for the pool for demos
print(" num_openflow_switches: {}".format(len(tors)))
# The number of legacy switches are 0 for demos
print(" num_legacy_switches: 0")
print(" epa_attributes:")
# HACK: rw_wag* VMs trusted_execution is always TRUE
if vm.vm_name.startswith('rw_wag'):
trusted_execution = 'TRUE'
else:
trusted_execution = str(flavor.trusted_host_only).upper()
print(" trusted_execution: {}".format(trusted_execution))
print(" ddio: {}".format(hosts[vm.host_name]['ddio']))
print(" cat: {}".format(hosts[vm.host_name]['cat']))
print(" ovs_acceleration: {}".format(hosts[vm.host_name]['ovs_acceleration']))
print(" mem_page_size: {}".format(flavor.mem_page_size))
if flavor.cpu_threads:
print(" cpu_threads: {}".format(flavor.cpu_threads))
print(" cpu_pinning_policy: {}".format(flavor.cpu_policy))
# print(" numa_policy: {{ node_cnt: {} }}".format(flavor.numa_node_cnt))
print(" numa_node_cnt: {}".format(flavor.numa_node_cnt))
# if any of the PCI passthrough devices are Coleto Creek
# set qat to accel
qat=False
passthrough=False
rrc=False
for d in flavor.pci_passthrough_device_list:
if 'COLETO' in d.alias:
qat=True
break
elif '10G' in d.alias:
passthrough=True
elif '100G' in d.alias:
passthrough=True
rrc=True
# NOTE: The following can break if SRIOV is used
# But for the demos 1,2,3 SRIOV is not used
# This is updated logic to set the nic to default to Niantic
# if 100G is not in the devise list.
if rrc:
print(" nic: RRC")
else:
print(" nic: NIANTIC")
if passthrough or hosts[vm.host_name]['ovs_acceleration'].upper() != 'DISABLED':
print(" dpdk_accelerated: TRUE")
else:
print(" dpdk_accelerated: FALSE")
if passthrough:
print(" pci_passthrough: TRUE")
else:
print(" pci_passthrough: FALSE")
if qat:
print(" quick_assist_policy: MANDATORY")
else:
print(" quick_assist_policy: NOACCEL")
break
def resource_subcommand(rwcloud, cmdargs):
"""Process the resources subcommand"""
if cmdargs.which == 'list':
resource_list_subcommand(rwcloud, cmdargs)
def vm_list_subcommand(rwcloud, cmdargs):
status, vminfo = rwcloud.get_vm_list()
for vm in vminfo.vminfo_list:
print(vm)
def vm_show_subcommand(rwcloud, cmdargs):
status, vm = rwcloud.get_vm(cmdargs.id)
print(vm)
def vm_create_subcommand(cmdargs):
pass
def vm_destroy_subcommand(cmdargs):
pass
def vm_reboot_subcommand(cmdargs):
pass
def vm_start_subcommand(cmdargs):
pass
def vm_subcommand(rwcloud, cmdargs):
"""Process the vm subcommand"""
if cmdargs.which == 'list':
vm_list_subcommand(rwcloud, cmdargs)
elif cmdargs.which == 'show':
vm_show_subcommand(rwcloud, cmdargs)
elif cmdargs.which == 'create':
vm_create_subcommand(cmdargs)
elif cmdargs.which == 'reboot':
vm_reboot_subcommand(cmdargs)
elif cmdargs.which == 'start':
vm_start_subcommand(cmdargs)
elif cmdargs.which == 'destroy':
vm_destroy_subcommand(cmdargs)
def flavor_list_subcommand(rwcloud, cmdargs):
status, flavorinfo = rwcloud.get_flavor_list()
for flavor in flavorinfo.flavorinfo_list:
print(flavor)
def flavor_show_subcommand(rwcloud, cmdargs):
status, flavor = rwcloud.get_flavor(cmdargs.id)
print(flavor)
def flavor_subcommand(rwcloud, cmdargs):
"""Process the flavor subcommand"""
if cmdargs.which == 'list':
flavor_list_subcommand(rwcloud, cmdargs)
elif cmdargs.which == 'show':
flavor_show_subcommand(rwcloud, cmdargs)
def main(args=sys.argv[1:]):
logging.basicConfig(format='RWCAL %(message)s')
##
# Command line argument specification
##
desc="""This tool is used to manage the VMs"""
parser = argparse.ArgumentParser(description=desc)
subparsers = parser.add_subparsers()
# ipaddr = socket.gethostbyname(socket.getfqdn())
# default_auth_url = 'http://%s:35357/v2.0/tokens' % ipaddr
default_auth_url = "http://10.64.1.31:35357/v2.0/tokens"
parser.add_argument('-t', '--provider-type', dest='provider_type',
type=str, default='OPENSTACK',
help='Cloud provider type (default: %(default)s)')
parser.add_argument('-u', '--user-name', dest='user',
type=str, default='demo',
help='User name (default: %(default)s)')
parser.add_argument('-p', '--password', dest='passwd',
type=str, default='mypasswd',
help='Password (default: %(default)s)')
parser.add_argument('-n', '--tenant-name', dest='tenant',
type=str, default='demo',
help='User name (default: %(default)s)')
parser.add_argument('-a', '--auth-url', dest='auth_url',
type=str, default=default_auth_url,
help='Password (default: %(default)s)')
##
# Subparser for Resources
##
resource_parser = subparsers.add_parser('resource')
resource_subparsers = resource_parser.add_subparsers()
# List resource subparser
resource_list_parser = resource_subparsers.add_parser('list')
resource_list_parser.set_defaults(which='list')
resource_list_parser.add_argument('-f', '--hostinfo-file-name',
dest='hostinfo_file_name',
required=True,
type=str,
help='name of the static yaml file containing host information')
resource_parser.set_defaults(func=resource_subcommand)
##
# Subparser for Flavor
##
flavor_parser = subparsers.add_parser('flavor')
flavor_subparsers = flavor_parser.add_subparsers()
# List flavor subparser
flavor_list_parser = flavor_subparsers.add_parser('list')
flavor_list_parser.set_defaults(which='list')
# Show flavor subparser
flavor_show_parser = flavor_subparsers.add_parser('show')
flavor_show_parser.add_argument('id', type=str)
flavor_show_parser.set_defaults(which='show')
flavor_parser.set_defaults(func=flavor_subcommand)
##
# Subparser for VM
##
vm_parser = subparsers.add_parser('vm')
vm_subparsers = vm_parser.add_subparsers()
# Create VM subparser
vm_create_parser = vm_subparsers.add_parser('create')
vm_create_parser.add_argument('-c', '--count',
type=int, default=1,
help='The number of VMs to launch '
'(default: %(default)d)')
vm_create_parser.add_argument('-i', '--image',
default='rwopenstack_vm',
help='Specify the image for the VM')
vm_create_parser.add_argument('-n', '--name',
help='Specify the name of the VM')
vm_create_parser.add_argument('-f', '--flavor',
help='Specify the flavor for the VM')
vm_create_parser.add_argument('-R', '--reserve', dest='reserve_new_vms',
action='store_true', help='reserve any newly created VMs')
vm_create_parser.add_argument('-s', '--single', dest='wait_after_create',
action='store_true',
help='wait for each VM to start before creating the next')
vm_create_parser.set_defaults(which='create')
# Reboot VM subparser
vm_reboot_parser = vm_subparsers.add_parser('reboot')
group = vm_reboot_parser.add_mutually_exclusive_group()
group.add_argument('-n', '--vm-name', dest='vm_name',
type=str,
help='Specify the name of the VM')
group.add_argument('-a', '--reboot-all',
dest='reboot_all', action='store_true',
help='Reboot all VMs')
vm_reboot_parser.add_argument('-s', '--sleep',
dest='sleep_time',
type=int, default=4,
help='time in seconds to sleep between reboots')
vm_reboot_parser.set_defaults(which='reboot')
# Destroy VM subparser
vm_destroy_parser = vm_subparsers.add_parser('destroy')
group = vm_destroy_parser.add_mutually_exclusive_group()
group.add_argument('-n', '--vm-name', dest='vm_name',
type=str,
help='Specify the name of the VM (accepts regular expressions)')
group.add_argument('-a', '--destroy-all',
dest='destroy_all', action='store_true',
help='Delete all VMs')
group.add_argument('-w', '--wait',
dest='wait', action='store_true',
help='destroy all and wait until all VMs have exited')
vm_destroy_parser.set_defaults(which='destroy')
# List VM subparser
vm_list_parser = vm_subparsers.add_parser('list')
vm_list_parser.set_defaults(which='list')
vm_list_parser.add_argument('-i', '--ips_only', dest='ipsonly',
action='store_true',
help='only list IP addresses')
# Show vm subparser
vm_show_parser = vm_subparsers.add_parser('show')
vm_show_parser.add_argument('id', type=str)
vm_show_parser.set_defaults(which='show')
vm_parser.set_defaults(func=vm_subcommand)
cmdargs = parser.parse_args(args)
# Open the peas engine
engine = Peas.Engine.get_default()
# Load our plugin proxy into the g_irepository namespace
default = GIRepository.Repository.get_default()
GIRepository.Repository.require(default, "RwCal", "1.0", 0)
# Enable python language loader
engine.enable_loader("python3");
# Set the search path for peas engine,
# rift-shell sets the PLUGINDIR and GI_TYPELIB_PATH
paths = set([])
paths = paths.union(os.environ['PLUGINDIR'].split(":"))
for path in paths:
engine.add_search_path(path, path)
# Load the rwcal python plugin and create the extension.
info = engine.get_plugin_info("rwcal-plugin")
if info is None:
print("Error loading rwcal-python plugin")
sys.exit(1)
engine.load_plugin(info)
rwcloud = engine.create_extension(info, RwCal.Cloud, None)
# For now cloud credentials are hard coded
if cmdargs.provider_type == 'OPENSTACK':
provider_type = RwCal.CloudType.OPENSTACK_AUTH_URL
elif cmdargs.provider_type == 'EC2_US_EAST':
provider_type = RwCal.CloudType.EC2_US_EAST
elif cmdargs.provider_type == 'VSPHERE':
provider_type = RwCal.CloudType.VSPHERE
else:
sys.exit("Cloud provider %s is NOT supported yet" % cmdargs.provider_type)
if not 'RIFT_SHELL' in os.environ:
sys.stderr.write("This tool should be run from inside a rift-shell")
status = rwcloud.init(provider_type,
cmdargs.user,
cmdargs.passwd,
cmdargs.auth_url,
cmdargs.tenant);
assert status == RwTypes.RwStatus.SUCCESS
cmdargs.func(rwcloud, cmdargs)
if __name__ == "__main__":
main()