Exemplo n.º 1
0
 def process_request(self, req):
     """Process AJAX request.  Args are:
     
       path - contents should be returned as JSON
       set_time - 0 (default) or 1 sets 'now' in contents to current epoch
     """
     try:
         progress = Progress(req.args['path'])
         data = progress.get()
         if int(req.args.get('restart',0)) == 1:
             progress.restart()
             progress.error('') # clear error
         elif int(req.args.get('stop',0)) == 1:
             progress.kill()
             progress.error("Stopped on user request.")
         if int(req.args.get('set_time',0)) == 1:
             data['now'] = time.time()
         msg = json.dumps(data)
         req.send_response(200)
         req.send_header('Content-Type', 'application/json')
     except Exception:
         import traceback;
         msg = "Oops...\n" + traceback.format_exc()+"\n"
         req.send_response(500)
         req.send_header('Content-Type', 'text/plain')
     req.send_header('Content-Length', len(msg))
     req.end_headers()
     req.write(msg);
Exemplo n.º 2
0
 def execute(self, req, id):
     """Deploy to an environment."""
     launch_data, attributes, exe = self._get_data(req, id)
     launch_data['cmd_envs'] = [attributes['name']]
     launch_data['command_id'] = 'deploy'
     deploy = self._get_command('deploy')
     attributes['command'] = deploy['command']
     progress_file = Progress.get_file()
     self._set_deploying(id, progress_file)
     self._spawn(req, exe, launch_data, attributes, progress_file)
Exemplo n.º 3
0
 def execute(self, req, id):
     """Deploy to an environment."""
     launch_data, attributes, exe = self._get_data(req, id)
     launch_data['cmd_envs'] = [attributes['name']]
     launch_data['command_id'] = 'deploy'
     deploy = self._get_command('deploy')
     attributes['command'] = deploy['command']
     progress_file = Progress.get_file()
     self._set_deploying(id, progress_file)
     self._spawn(req, exe, launch_data, attributes, progress_file)
Exemplo n.º 4
0
    def _spawn(self, req, exe, launch_data, attributes, progress_file=None):
        """Helper function to spawn processes with progress tracking."""
        if not progress_file:
            progress_file = Progress.get_file()

        # create the command
        cmd = [
            '/usr/bin/python',
            exe,
            '--daemonize',
            '--trac-base-url="%s"' % self.trac_base_url,
            '--progress-file="%s"' % progress_file,
            '--log-file="%s"' % self.log.handlers[0].stream.name,
            '--chef-base-path="%s"' % self.chefapi.base_path,
            '--aws-key="%s"' % self.cloudapi.key,
            '--aws-secret="%s"' % self.cloudapi.secret,
            '--aws-keypair="%s"' % self.cloudapi.keypair,
            '--aws-keypair-pem="%s"' % self.chefapi.keypair_pem,
            '--aws-username="******"' % self.chefapi.user,
            '--aws-security-groups="%s"' % self.cloudapi.security_groups,
            '--rds-username="******"' % self.cloudapi.username,
            '--rds-password="******"' % self.cloudapi.password,
            '--databag="%s"' % self.name,
            "--launch-data='%s'" % json.dumps(launch_data),
            "--attributes='%s'" % json.dumps(attributes),
            '--started-by="%s"' % req.authname,
            '--notify-jabber="%s"' % self.notify_jabber,
            '--jabber-server="%s"' % self.jabber_server,
            '--jabber-port="%s"' % self.jabber_port,
            '--jabber-server="%s"' % self.jabber_server,
            '--jabber-username="******"' % self.jabber_username,
            '--jabber-password="******"' % self.jabber_password,
            '--jabber-channel="%s"' % self.jabber_channel,
        ]
        cmd += ['--chef-boot-run-list="%s"' % \
            r for r in self.chefapi.boot_run_list]
        if self.chefapi.boot_sudo:
            cmd += ['--chef-boot-sudo']
        if self.chefapi.boot_version:
            cmd += ['--chef-boot-version="%s"' % self.chefapi.boot_version]
        cmd = ' '.join(cmd)

        # Spawn command as daemon to launch and bootstrap instance in background
        self.log.debug('Daemonizing command: %s' % cmd)
        if subprocess.call(cmd, shell=True):
            add_warning(req, _("Error daemonizing: %(cmd)s", cmd=cmd))
            req.redirect(req.href.cloud(self.name))
        req.redirect(
            req.href.cloud(self.name, action='progress', file=progress_file))
Exemplo n.º 5
0
 def _spawn(self, req, exe, launch_data, attributes, progress_file=None):
     """Helper function to spawn processes with progress tracking."""
     if not progress_file:
         progress_file = Progress.get_file()
     
     # create the command
     cmd = [
        '/usr/bin/python', exe, '--daemonize',
        '--trac-base-url="%s"' % self.trac_base_url,
        '--progress-file="%s"' % progress_file,
        '--log-file="%s"' %  self.log.handlers[0].stream.name,
        '--chef-base-path="%s"' % self.chefapi.base_path,
        '--aws-key="%s"' % self.cloudapi.key,
        '--aws-secret="%s"' % self.cloudapi.secret,
        '--aws-keypair="%s"' % self.cloudapi.keypair,
        '--aws-keypair-pem="%s"' % self.chefapi.keypair_pem,
        '--aws-username="******"' % self.chefapi.user,
        '--aws-security-groups="%s"' % self.cloudapi.security_groups,
        '--rds-username="******"' % self.cloudapi.username,
        '--rds-password="******"' % self.cloudapi.password,
        '--databag="%s"' % self.name,
        "--launch-data='%s'" % json.dumps(launch_data),
        "--attributes='%s'" % json.dumps(attributes),
        '--started-by="%s"' % req.authname,
        '--notify-jabber="%s"' % self.notify_jabber,
        '--jabber-server="%s"' % self.jabber_server,
        '--jabber-port="%s"' % self.jabber_port,
        '--jabber-server="%s"' % self.jabber_server,
        '--jabber-username="******"' % self.jabber_username,
        '--jabber-password="******"' % self.jabber_password,
        '--jabber-channel="%s"' % self.jabber_channel,
     ]
     cmd += ['--chef-boot-run-list="%s"' % \
         r for r in self.chefapi.boot_run_list]
     if self.chefapi.boot_sudo:
         cmd += ['--chef-boot-sudo']
     if self.chefapi.boot_version:
         cmd += ['--chef-boot-version="%s"' % self.chefapi.boot_version]
     cmd = ' '.join(cmd)
     
     # Spawn command as daemon to launch and bootstrap instance in background
     self.log.debug('Daemonizing command: %s' % cmd)
     if subprocess.call(cmd, shell=True):
         add_warning(req, _("Error daemonizing: %(cmd)s", cmd=cmd))
         req.redirect(req.href.cloud(self.name))
     req.redirect(req.href.cloud(self.name, action='progress',
                                            file=progress_file))
Exemplo n.º 6
0
    def _is_deploying(self, env):
        """Determines whether there's an active deployment for the given
        environment and if so returns its progress file, else False."""
        deploy_file = '/tmp/deploy-%s' % env
        if not os.path.exists(deploy_file):
            return False

        # extract progress file
        f = open(deploy_file, 'r')
        progress_file = f.read().strip()
        f.close()

        # check if progress file exists
        if not os.path.exists(progress_file):
            return False

        # check if done deploying
        if Progress(progress_file).is_done():
            return False
        return progress_file
Exemplo n.º 7
0
 def process_request(self, req):
     """Process AJAX request.  Args are:
     
       path - contents should be returned as JSON
       set_time - 0 (default) or 1 sets 'now' in contents to current epoch
     """
     try:
         progress = Progress(req.args['path'])
         data = progress.get()
         if int(req.args.get('restart', 0)) == 1:
             progress.restart()
             progress.error('')  # clear error
         elif int(req.args.get('stop', 0)) == 1:
             progress.kill()
             progress.error("Stopped on user request.")
         if int(req.args.get('set_time', 0)) == 1:
             data['now'] = time.time()
         msg = json.dumps(data)
         req.send_response(200)
         req.send_header('Content-Type', 'application/json')
     except Exception:
         import traceback
         msg = "Oops...\n" + traceback.format_exc() + "\n"
         req.send_response(500)
         req.send_header('Content-Type', 'text/plain')
     req.send_header('Content-Length', len(msg))
     req.end_headers()
     req.write(msg)
Exemplo n.º 8
0
 def __init__(self, steps, title, description='', can_continue=False):
     # setup command line parsing
     parser = OptionParser()
     parser.add_option("-d","--daemonize",default=False,action="store_true")
     parser.add_option("--trac-base-url")
     parser.add_option("--progress-file")
     parser.add_option("--log-file")
     parser.add_option("--log-level", default=logging.DEBUG)
     parser.add_option("--chef-base-path")
     parser.add_option("--chef-boot-run-list", default=[], action='append')
     parser.add_option("--chef-boot-sudo",default=False, action="store_true")
     parser.add_option("--chef-boot-version")
     parser.add_option("--aws-key")
     parser.add_option("--aws-secret")
     parser.add_option("--aws-keypair")
     parser.add_option("--aws-keypair-pem")
     parser.add_option("--aws-username")
     parser.add_option("--aws-security-groups")
     parser.add_option("--rds-username")
     parser.add_option("--rds-password")
     parser.add_option("--databag")
     parser.add_option("--launch-data", default='{}', help="JSON dict")
     parser.add_option("--attributes", default='{}', help="JSON dict")
     parser.add_option("--started-by")
     parser.add_option("--notify-jabber")
     parser.add_option("--jabber-server")
     parser.add_option("--jabber-port")
     parser.add_option("--jabber-username")
     parser.add_option("--jabber-password")
     parser.add_option("--jabber-channel")
     (self.options, _args) = parser.parse_args()
     
     # setup logging (presumes something else will rotate it)
     self.log = logging.getLogger(self.__class__.__name__)
     self.log.setLevel(self.options.log_level)
     self.handler = logging.FileHandler(self.options.log_file)
     self.handler.setLevel(self.options.log_level)
     format = "%(asctime)s %(name)s[%(process)d] %(levelname)s: %(message)s"
     self.handler.setFormatter(logging.Formatter(format))
     self.log.addHandler(self.handler)
     
     # setup apis
     self.chefapi = Chef(self.options.chef_base_path,
                            self.options.aws_keypair_pem,
                            self.options.aws_username,
                            self.options.chef_boot_run_list,
                            self.options.chef_boot_sudo,
                            self.options.chef_boot_version,
                            self.log)
     
     self.cloudapi = Aws(self.options.aws_key,
                            self.options.aws_secret,
                            self.options.aws_keypair,
                            self.options.aws_security_groups,
                            self.options.rds_username,
                            self.options.rds_password,
                            self.log)
     
     # prepare the data
     self.databag = self.options.databag
     self.launch_data = json.loads(self.options.launch_data)
     self.attributes = json.loads(self.options.attributes)
     
     # prepare progress
     command = ''
     if can_continue:
         command = ['/usr/bin/python'] + sys.argv
     self.pidfile = tempfile.NamedTemporaryFile(delete=False).name
     self.progress = Progress(self.options.progress_file,
                              self.pidfile, steps, title, description,
                              {'0':(time.time(),None)},
                              started_by=self.options.started_by,
                              command=command)
     self.progress.pidfile(self.pidfile) # in case this is a restart
Exemplo n.º 9
0
class Daemon(object):
    """
    A generic daemon class with added support for chef/cloud apis and
    communicating with other processes via a progress file.
    
    Usage: subclass the Daemon class and override the run() method
    """
    def __init__(self, steps, title, description='', can_continue=False):
        # setup command line parsing
        parser = OptionParser()
        parser.add_option("-d","--daemonize",default=False,action="store_true")
        parser.add_option("--trac-base-url")
        parser.add_option("--progress-file")
        parser.add_option("--log-file")
        parser.add_option("--log-level", default=logging.DEBUG)
        parser.add_option("--chef-base-path")
        parser.add_option("--chef-boot-run-list", default=[], action='append')
        parser.add_option("--chef-boot-sudo",default=False, action="store_true")
        parser.add_option("--chef-boot-version")
        parser.add_option("--aws-key")
        parser.add_option("--aws-secret")
        parser.add_option("--aws-keypair")
        parser.add_option("--aws-keypair-pem")
        parser.add_option("--aws-username")
        parser.add_option("--aws-security-groups")
        parser.add_option("--rds-username")
        parser.add_option("--rds-password")
        parser.add_option("--databag")
        parser.add_option("--launch-data", default='{}', help="JSON dict")
        parser.add_option("--attributes", default='{}', help="JSON dict")
        parser.add_option("--started-by")
        parser.add_option("--notify-jabber")
        parser.add_option("--jabber-server")
        parser.add_option("--jabber-port")
        parser.add_option("--jabber-username")
        parser.add_option("--jabber-password")
        parser.add_option("--jabber-channel")
        (self.options, _args) = parser.parse_args()
        
        # setup logging (presumes something else will rotate it)
        self.log = logging.getLogger(self.__class__.__name__)
        self.log.setLevel(self.options.log_level)
        self.handler = logging.FileHandler(self.options.log_file)
        self.handler.setLevel(self.options.log_level)
        format = "%(asctime)s %(name)s[%(process)d] %(levelname)s: %(message)s"
        self.handler.setFormatter(logging.Formatter(format))
        self.log.addHandler(self.handler)
        
        # setup apis
        self.chefapi = Chef(self.options.chef_base_path,
                               self.options.aws_keypair_pem,
                               self.options.aws_username,
                               self.options.chef_boot_run_list,
                               self.options.chef_boot_sudo,
                               self.options.chef_boot_version,
                               self.log)
        
        self.cloudapi = Aws(self.options.aws_key,
                               self.options.aws_secret,
                               self.options.aws_keypair,
                               self.options.aws_security_groups,
                               self.options.rds_username,
                               self.options.rds_password,
                               self.log)
        
        # prepare the data
        self.databag = self.options.databag
        self.launch_data = json.loads(self.options.launch_data)
        self.attributes = json.loads(self.options.attributes)
        
        # prepare progress
        command = ''
        if can_continue:
            command = ['/usr/bin/python'] + sys.argv
        self.pidfile = tempfile.NamedTemporaryFile(delete=False).name
        self.progress = Progress(self.options.progress_file,
                                 self.pidfile, steps, title, description,
                                 {'0':(time.time(),None)},
                                 started_by=self.options.started_by,
                                 command=command)
        self.progress.pidfile(self.pidfile) # in case this is a restart
        
    
    def daemonize(self):
        """
        do the UNIX double-fork magic, see Stevens' "Advanced 
        Programming in the UNIX Environment" for details (ISBN 0201563177)
        http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
        """
        try: 
            pid = os.fork() 
            if pid > 0:
                # exit first parent
                sys.exit(0)
        except OSError, e: 
            self.log.critical("fork 1 failed: %d (%s)\n" %(e.errno, e.strerror))
            sys.exit(1)
    
        # decouple from parent environment
        os.chdir("/") 
        os.setsid() 
        os.umask(0) 
    
        # do second fork
        try: 
            pid = os.fork() 
            if pid > 0:
                # exit from second parent
                sys.exit(0) 
        except OSError, e: 
            self.log.critical("fork 2 failed: %d (%s)\n" %(e.errno, e.strerror))
            sys.exit(1) 
Exemplo n.º 10
0
    def __init__(self, steps, title, description='', can_continue=False):
        # setup command line parsing
        parser = OptionParser()
        parser.add_option("-d",
                          "--daemonize",
                          default=False,
                          action="store_true")
        parser.add_option("--trac-base-url")
        parser.add_option("--progress-file")
        parser.add_option("--log-file")
        parser.add_option("--log-level", default=logging.DEBUG)
        parser.add_option("--chef-base-path")
        parser.add_option("--chef-boot-run-list", default=[], action='append')
        parser.add_option("--chef-boot-sudo",
                          default=False,
                          action="store_true")
        parser.add_option("--chef-boot-version")
        parser.add_option("--aws-key")
        parser.add_option("--aws-secret")
        parser.add_option("--aws-keypair")
        parser.add_option("--aws-keypair-pem")
        parser.add_option("--aws-username")
        parser.add_option("--aws-security-groups")
        parser.add_option("--rds-username")
        parser.add_option("--rds-password")
        parser.add_option("--databag")
        parser.add_option("--launch-data", default='{}', help="JSON dict")
        parser.add_option("--attributes", default='{}', help="JSON dict")
        parser.add_option("--started-by")
        parser.add_option("--notify-jabber")
        parser.add_option("--jabber-server")
        parser.add_option("--jabber-port")
        parser.add_option("--jabber-username")
        parser.add_option("--jabber-password")
        parser.add_option("--jabber-channel")
        (self.options, _args) = parser.parse_args()

        # setup logging (presumes something else will rotate it)
        self.log = logging.getLogger(self.__class__.__name__)
        self.log.setLevel(self.options.log_level)
        self.handler = logging.FileHandler(self.options.log_file)
        self.handler.setLevel(self.options.log_level)
        format = "%(asctime)s %(name)s[%(process)d] %(levelname)s: %(message)s"
        self.handler.setFormatter(logging.Formatter(format))
        self.log.addHandler(self.handler)

        # setup apis
        self.chefapi = Chef(self.options.chef_base_path,
                            self.options.aws_keypair_pem,
                            self.options.aws_username,
                            self.options.chef_boot_run_list,
                            self.options.chef_boot_sudo,
                            self.options.chef_boot_version, self.log)

        self.cloudapi = Aws(self.options.aws_key, self.options.aws_secret,
                            self.options.aws_keypair,
                            self.options.aws_security_groups,
                            self.options.rds_username,
                            self.options.rds_password, self.log)

        # prepare the data
        self.databag = self.options.databag
        self.launch_data = json.loads(self.options.launch_data)
        self.attributes = json.loads(self.options.attributes)

        # prepare progress
        command = ''
        if can_continue:
            command = ['/usr/bin/python'] + sys.argv
        self.pidfile = tempfile.NamedTemporaryFile(delete=False).name
        self.progress = Progress(self.options.progress_file,
                                 self.pidfile,
                                 steps,
                                 title,
                                 description, {'0': (time.time(), None)},
                                 started_by=self.options.started_by,
                                 command=command)
        self.progress.pidfile(self.pidfile)  # in case this is a restart
Exemplo n.º 11
0
class Daemon(object):
    """
    A generic daemon class with added support for chef/cloud apis and
    communicating with other processes via a progress file.
    
    Usage: subclass the Daemon class and override the run() method
    """
    def __init__(self, steps, title, description='', can_continue=False):
        # setup command line parsing
        parser = OptionParser()
        parser.add_option("-d",
                          "--daemonize",
                          default=False,
                          action="store_true")
        parser.add_option("--trac-base-url")
        parser.add_option("--progress-file")
        parser.add_option("--log-file")
        parser.add_option("--log-level", default=logging.DEBUG)
        parser.add_option("--chef-base-path")
        parser.add_option("--chef-boot-run-list", default=[], action='append')
        parser.add_option("--chef-boot-sudo",
                          default=False,
                          action="store_true")
        parser.add_option("--chef-boot-version")
        parser.add_option("--aws-key")
        parser.add_option("--aws-secret")
        parser.add_option("--aws-keypair")
        parser.add_option("--aws-keypair-pem")
        parser.add_option("--aws-username")
        parser.add_option("--aws-security-groups")
        parser.add_option("--rds-username")
        parser.add_option("--rds-password")
        parser.add_option("--databag")
        parser.add_option("--launch-data", default='{}', help="JSON dict")
        parser.add_option("--attributes", default='{}', help="JSON dict")
        parser.add_option("--started-by")
        parser.add_option("--notify-jabber")
        parser.add_option("--jabber-server")
        parser.add_option("--jabber-port")
        parser.add_option("--jabber-username")
        parser.add_option("--jabber-password")
        parser.add_option("--jabber-channel")
        (self.options, _args) = parser.parse_args()

        # setup logging (presumes something else will rotate it)
        self.log = logging.getLogger(self.__class__.__name__)
        self.log.setLevel(self.options.log_level)
        self.handler = logging.FileHandler(self.options.log_file)
        self.handler.setLevel(self.options.log_level)
        format = "%(asctime)s %(name)s[%(process)d] %(levelname)s: %(message)s"
        self.handler.setFormatter(logging.Formatter(format))
        self.log.addHandler(self.handler)

        # setup apis
        self.chefapi = Chef(self.options.chef_base_path,
                            self.options.aws_keypair_pem,
                            self.options.aws_username,
                            self.options.chef_boot_run_list,
                            self.options.chef_boot_sudo,
                            self.options.chef_boot_version, self.log)

        self.cloudapi = Aws(self.options.aws_key, self.options.aws_secret,
                            self.options.aws_keypair,
                            self.options.aws_security_groups,
                            self.options.rds_username,
                            self.options.rds_password, self.log)

        # prepare the data
        self.databag = self.options.databag
        self.launch_data = json.loads(self.options.launch_data)
        self.attributes = json.loads(self.options.attributes)

        # prepare progress
        command = ''
        if can_continue:
            command = ['/usr/bin/python'] + sys.argv
        self.pidfile = tempfile.NamedTemporaryFile(delete=False).name
        self.progress = Progress(self.options.progress_file,
                                 self.pidfile,
                                 steps,
                                 title,
                                 description, {'0': (time.time(), None)},
                                 started_by=self.options.started_by,
                                 command=command)
        self.progress.pidfile(self.pidfile)  # in case this is a restart

    def daemonize(self):
        """
        do the UNIX double-fork magic, see Stevens' "Advanced 
        Programming in the UNIX Environment" for details (ISBN 0201563177)
        http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
        """
        try:
            pid = os.fork()
            if pid > 0:
                # exit first parent
                sys.exit(0)
        except OSError, e:
            self.log.critical("fork 1 failed: %d (%s)\n" %
                              (e.errno, e.strerror))
            sys.exit(1)

        # decouple from parent environment
        os.chdir("/")
        os.setsid()
        os.umask(0)

        # do second fork
        try:
            pid = os.fork()
            if pid > 0:
                # exit from second parent
                sys.exit(0)
        except OSError, e:
            self.log.critical("fork 2 failed: %d (%s)\n" %
                              (e.errno, e.strerror))
            sys.exit(1)