--- /dev/null
+#!/usr/bin/env python3
+
+import argparse
+import logging
+import os
+import sys
+
+import gi
+gi.require_version('RwcalYang', '1.0')
+gi.require_version('RwCal', '1.0')
+gi.require_version('RwLog', '1.0')
+
+import rift.cal.server as cal_server
+import rift.cal.client as cal_client
+import rift.cal.utils as cal_utils
+import rift.rwcal.cloudsim.lxc as lxc
+import rift.rwcal.cloudsim.lvm as lvm
+import rift.rwcal.cloudsim.shell as shell
+
+from prettytable import PrettyTable
+
+
+START_PARSER = "start"
+STOP_PARSER = "stop"
+CLEAN_PARSER = "clean"
+FCLEAN_PARSER = "force-clean"
+IMAGE_PARSER = "image-create"
+STATUS_PARSER = "status"
+
+
+class CloudsimOperations(cal_utils.CloudSimCalMixin):
+ def __init__(self, args):
+ super().__init__()
+ self.log = cal_utils.Logger(
+ daemon_mode=False,
+ log_name="Parser",
+ log_level=logging.getLevelName(args.log_level)).logger
+
+ self.args = args
+ self.operations = cal_server.CloudsimServerOperations(self.log)
+ self.client = cal_client.CloudsimClient(self.log)
+ self._cal, self._account = None, None
+
+ @property
+ def log_file(self):
+ return cal_utils.Logger.LOG_FILE
+
+ @cal_utils.check_and_create_bridge
+ def start_server(self):
+ self.operations.start_server(foreground=self.args.foreground)
+
+ @cal_utils.check_and_create_bridge
+ def stop_server(self):
+ self.operations.stop_server()
+
+ @cal_utils.check_and_create_bridge
+ def clean_resources(self):
+ """Clean all resource using rest APIs. """
+ self.operations.clean_server(images=self.args.all)
+
+ @cal_utils.check_and_create_bridge
+ def upload_image(self):
+ """Onboard image to cloudsim server."""
+ self.client.upload_image(self.args.location, name=self.args.name)
+
+ def force_clean_resources(self):
+ """Force clean up all resource. """
+ self.log.info("Cleaning up logs")
+ shell.command("rm -f {}".format(self.log_file))
+
+ self.log.info("Cleaning up PID file")
+ shell.command("rm -f {}".format(self.operations.PID_FILE))
+
+ try:
+ self.log.info("Purging LXC resources")
+ for container in lxc.containers():
+ lxc.stop(container)
+
+ for container in lxc.containers():
+ lxc.destroy(container)
+
+ lvm.destroy('rift')
+
+ except shell.ProcessError:
+ self.log.exception("Unable to purge resources. Trying a force clean now.")
+ lxc.force_clean()
+
+ @cal_utils.check_and_create_bridge
+ def show_status(self):
+
+ cld_tbl = PrettyTable(['PID', 'Status', 'Log file'])
+
+ pid = self.operations.pid
+ if pid:
+ cld_tbl.add_row([pid, "RUNNING", self.log_file])
+ else:
+ cld_tbl.add_row(["-", "STOPPED", self.log_file])
+
+ print ("Cloudsim server:")
+ print (cld_tbl)
+
+ if not pid:
+ return
+
+ # Images
+ img_tbl = PrettyTable(['ID', 'Name', 'Format'])
+ vlink_tbl = PrettyTable([
+ 'ID', 'Name', 'Bridge Name', 'State', 'Subnet', 'Ports', "IPs"])
+ vdu_tbl = PrettyTable([
+ 'ID', 'Name', 'LXC Name', 'IP', 'State', 'Ports', "VLink ID"])
+
+
+ images = self.client.images
+ if images:
+ for image in images:
+ img_tbl.add_row([image.id, image.name, image.disk_format])
+
+ print ("Images:")
+ print (img_tbl)
+
+ vlinks = self.client.vlinks
+ if vlinks:
+ for vlink in vlinks:
+
+ ports, ips = [], []
+ for cp in vlink.connection_points:
+ ports.append("{} ({})".format(cp.name, cp.connection_point_id))
+ ips.append(cp.ip_address)
+
+ vlink_tbl.add_row([
+ vlink.virtual_link_id,
+ vlink.name,
+ vlink.name[:15],
+ vlink.state,
+ vlink.subnet,
+ "\n".join(ports),
+ "\n".join(ips)])
+
+ print ("Vlink:")
+ print (vlink_tbl)
+
+
+ lxc_to_ip = lxc.ls_info()
+ def get_lxc_name(ip):
+ for lxc_name, ips in lxc_to_ip.items():
+ if str(ip) in ips:
+ return lxc_name
+
+ return ""
+
+ vdus = self.client.vdus
+ if vdus:
+ for vdu in vdus:
+ ports, links = [], []
+ for cp in vdu.connection_points:
+ ports.append("{} ({})".format(cp.name, cp.ip_address))
+ links.append(cp.virtual_link_id)
+
+ vdu_tbl.add_row([
+ vdu.vdu_id, vdu.name, get_lxc_name(vdu.public_ip), vdu.public_ip,
+ vdu.state, "\n".join(ports), "\n".join(links)])
+
+ print ("VDU:")
+ print (vdu_tbl)
+
+
+def parse(arguments):
+ parser = argparse.ArgumentParser(description=__doc__,
+ formatter_class=argparse.RawDescriptionHelpFormatter)
+ parser.add_argument(
+ '--log-level', '-l',
+ default="WARNING",
+ type=str,
+ choices=["INFO", "DEBUG", "WARNING", "ERROR"],
+ help="Set log level, defaults to warning and above.")
+
+ subparsers = parser.add_subparsers()
+
+ start_parser = subparsers.add_parser(START_PARSER, help="Start the server")
+ start_parser.add_argument(
+ '--foreground', "-f",
+ help="Run the server in the foreground. The logs are sent to console.",
+ default=False,
+ action="store_true")
+ start_parser.set_defaults(which=START_PARSER)
+
+ stop_parser = subparsers.add_parser(STOP_PARSER, help="Stop the server")
+ stop_parser.set_defaults(which=STOP_PARSER)
+
+ clean_parser = subparsers.add_parser(
+ CLEAN_PARSER,
+ help="Clean LXC resources. By default all resources except " + \
+ "images are cleared.")
+ clean_parser.add_argument(
+ '--all', '-a',
+ help="Cleans up all resources including images",
+ default=False,
+ action="store_true")
+ clean_parser.set_defaults(which=CLEAN_PARSER)
+
+ fclean_parser = subparsers.add_parser(
+ FCLEAN_PARSER,
+ help="Force clean all lxc resources")
+ fclean_parser.set_defaults(which=FCLEAN_PARSER)
+
+ image_parser = subparsers.add_parser(IMAGE_PARSER, help="Upload images")
+ image_parser.add_argument(
+ '--name', '-n',
+ help="(Optional) Name of the image")
+ image_parser.add_argument(
+ '--location', '-l',
+ help="Image location. If name is not specified the basename of " + \
+ "the image path is used.",
+ required=True)
+ image_parser.set_defaults(which=IMAGE_PARSER)
+
+ show_parser = subparsers.add_parser(
+ STATUS_PARSER,
+ help="Shows the current status of LXC")
+ show_parser.set_defaults(which=STATUS_PARSER)
+
+ args = parser.parse_args(arguments)
+
+ return args
+
+
+def main(args):
+
+ args = parse(args)
+
+ operations = CloudsimOperations(args)
+
+ if args.which == START_PARSER:
+ operations.start_server()
+ elif args.which == STOP_PARSER:
+ operations.stop_server()
+ elif args.which == FCLEAN_PARSER:
+ operations.force_clean_resources()
+ elif args.which == CLEAN_PARSER:
+ operations.clean_resources()
+ elif args.which == IMAGE_PARSER:
+ operations.upload_image()
+ elif args.which == STATUS_PARSER:
+ operations.show_status()
+
+
+if __name__ == "__main__":
+ main(sys.argv[1:])