diff --git a/gns3dms/main.py b/gns3dms/main.py index 94e412d7..50c012db 100644 --- a/gns3dms/main.py +++ b/gns3dms/main.py @@ -77,6 +77,7 @@ Options: --cloud_user_name --instance_id ID of the Rackspace instance to terminate + --region Region of instance --deadtime How long in seconds can the communication lose exist before we shutdown this instance. @@ -111,6 +112,7 @@ def parse_cmd_line(argv): "cloud_user_name=", "cloud_api_key=", "instance_id=", + "region=", "deadtime=", "init-wait=", "check-interval=", @@ -130,6 +132,7 @@ def parse_cmd_line(argv): cmd_line_option_list["cloud_user_name"] = None cmd_line_option_list["cloud_api_key"] = None cmd_line_option_list["instance_id"] = None + cmd_line_option_list["region"] = None cmd_line_option_list["deadtime"] = 60 * 60 #minutes cmd_line_option_list["check-interval"] = None cmd_line_option_list["init-wait"] = 5 * 60 @@ -145,7 +148,8 @@ def parse_cmd_line(argv): else: cmd_line_option_list['syslog'] = ('localhost',514) - get_gns3config(cmd_line_option_list) + + get_gns3secrets(cmd_line_option_list) for opt, val in opts: if (opt in ("-h", "--help")): @@ -161,6 +165,8 @@ def parse_cmd_line(argv): cmd_line_option_list["cloud_api_key"] = val elif (opt in ("--instance_id")): cmd_line_option_list["instance_id"] = val + elif (opt in ("--region")): + cmd_line_option_list["region"] = val elif (opt in ("--deadtime")): cmd_line_option_list["deadtime"] = int(val) elif (opt in ("--check-interval")): @@ -199,9 +205,15 @@ def parse_cmd_line(argv): print(usage) sys.exit(2) + if cmd_line_option_list["region"] is None: + print("You need to specify a region") + print(usage) + sys.exit(2) + + return cmd_line_option_list -def get_gns3config(cmd_line_option_list): +def get_gns3secrets(cmd_line_option_list): """ Load cloud credentials from .gns3secrets """ @@ -224,17 +236,6 @@ def get_gns3config(cmd_line_option_list): except configparser.NoSectionError: pass - cloud_config_file = "%s/.config/GNS3/cloud.conf" % ( - os.path.expanduser("~/")) - - if os.path.isfile(cloud_config_file): - config.read(cloud_config_file) - - try: - for key, value in config.items("CLOUD_SERVER"): - cmd_line_option_list[key] = value.strip() - except configparser.NoSectionError: - pass def set_logging(cmd_options): """ @@ -351,9 +352,8 @@ def main(): log.info("Received shutdown signal") options["shutdown"] = True - sys.exit(0) - pid_file = "%s/.gns3ias.pid" % (expanduser("~")) + pid_file = "%s/.gns3dms.pid" % (expanduser("~")) if options["shutdown"]: send_shutdown(pid_file) diff --git a/gns3dms/modules/daemon.py b/gns3dms/modules/daemon.py index d10d8d2e..c7245335 100644 --- a/gns3dms/modules/daemon.py +++ b/gns3dms/modules/daemon.py @@ -7,38 +7,38 @@ class daemon: Usage: subclass the daemon class and override the run() method.""" - def __init__(self, pidfile, options): + def __init__(self, pidfile, options): self.pidfile = pidfile self.options = options - + def daemonize(self): """Deamonize class. UNIX double fork mechanism.""" - try: - pid = os.fork() + try: + pid = os.fork() if pid > 0: # exit first parent - sys.exit(0) - except OSError as err: + sys.exit(0) + except OSError as err: sys.stderr.write('fork #1 failed: {0}\n'.format(err)) sys.exit(1) - + # decouple from parent environment - os.chdir('/') - os.setsid() - os.umask(0) - + os.chdir('/') + os.setsid() + os.umask(0) + # do second fork - try: - pid = os.fork() + try: + pid = os.fork() if pid > 0: # exit from second parent - sys.exit(0) - except OSError as err: + sys.exit(0) + except OSError as err: sys.stderr.write('fork #2 failed: {0}\n'.format(err)) - sys.exit(1) - + sys.exit(1) + # redirect standard file descriptors sys.stdout.flush() sys.stderr.flush() @@ -49,17 +49,26 @@ class daemon: os.dup2(si.fileno(), sys.stdin.fileno()) os.dup2(so.fileno(), sys.stdout.fileno()) os.dup2(se.fileno(), sys.stderr.fileno()) - + # write pidfile atexit.register(self.delpid) pid = str(os.getpid()) with open(self.pidfile,'w+') as f: f.write(pid + '\n') - + def delpid(self): os.remove(self.pidfile) + def check_pid(self, pid): + """ Check For the existence of a unix pid. """ + try: + os.kill(pid, 0) + except OSError: + return False + else: + return True + def start(self): """Start the daemon.""" @@ -70,13 +79,19 @@ class daemon: pid = int(pf.read().strip()) except IOError: pid = None - + if pid: - message = "pidfile {0} already exist. " + \ - "Daemon already running?\n" + pid_exist = self.check_pid(pid) + + if pid_exist: + message = "Already running: %s\n" % (pid) + sys.stderr.write(message) + sys.exit(1) + else: + message = "pidfile {0} already exist. " + \ + "but process is dead\n" sys.stderr.write(message.format(self.pidfile)) - sys.exit(1) - + # Start the daemon self.daemonize() self.run() @@ -90,14 +105,14 @@ class daemon: pid = int(pf.read().strip()) except IOError: pid = None - + if not pid: message = "pidfile {0} does not exist. " + \ "Daemon not running?\n" sys.stderr.write(message.format(self.pidfile)) return # not an error in a restart - # Try killing the daemon process + # Try killing the daemon process try: while 1: os.kill(pid, signal.SIGTERM) @@ -118,6 +133,6 @@ class daemon: def run(self): """You should override this method when you subclass Daemon. - - It will be called after the process has been daemonized by + + It will be called after the process has been daemonized by start() or restart().""" diff --git a/gns3dms/modules/rackspace_cloud.py b/gns3dms/modules/rackspace_cloud.py index 4b1d6c0f..00059047 100644 --- a/gns3dms/modules/rackspace_cloud.py +++ b/gns3dms/modules/rackspace_cloud.py @@ -41,6 +41,7 @@ class Rackspace(object): self.authenticated = False self.hostname = socket.gethostname() self.instance_id = options["instance_id"] + self.region = options["region"] log.debug("Authenticating with Rackspace") log.debug("My hostname: %s" % (self.hostname)) @@ -51,16 +52,17 @@ class Rackspace(object): if self.authenticated == False: log.critical("Not authenticated against rackspace!!!!") - for region_dict in self.rksp.list_regions(): - region_k, region_v = region_dict.popitem() - log.debug("Checking region: %s" % (region_k)) - self.rksp.set_region(region_v) - for server in self.rksp.list_instances(): - log.debug("Checking server: %s" % (server.name)) - if server.name.lower() == self.hostname.lower() and server.id == self.instance_id: - log.info("Found matching instance: %s" % (server.id)) - log.info("Startup id: %s" % (self.instance_id)) - return server + for region in self.rksp.list_regions(): + log.debug("Rackspace regions: %s" % (region)) + + log.debug("Checking region: %s" % (self.region)) + self.rksp.set_region(self.region) + for server in self.rksp.list_instances(): + log.debug("Checking server: %s" % (server.name)) + if server.name.lower() == self.hostname.lower() and server.id == self.instance_id: + log.info("Found matching instance: %s" % (server.id)) + log.info("Startup id: %s" % (self.instance_id)) + return server def terminate(self): server = self._find_my_instance()