예제 #1
0
파일: tasks.py 프로젝트: Emergya/gecoscc-ui
def object_deleted(user, objtype, obj, computers=None):
    self = object_changed
    func = getattr(self, '{0}_deleted'.format(objtype), None)
    if func is not None:
        try:
            return func(user, obj, computers=computers)
        except Exception as e:
            self.report_unknown_error(e, user, obj, 'deleted')
            invalidate_jobs(self.request, user)
    else:
        self.log('error',
                 'The method {0}_deleted does not exist'.format(objtype))
예제 #2
0
파일: tasks.py 프로젝트: Emergya/gecoscc-ui
def object_deleted(user, objtype, obj, computers=None):
    self = object_changed
    func = getattr(self, '{0}_deleted'.format(objtype), None)
    if func is not None:
        try:
            return func(user, obj, computers=computers)
        except Exception as e:
            self.report_unknown_error(e, user, obj, 'deleted')
            invalidate_jobs(self.request, user)
    else:
        self.log('error', 'The method {0}_deleted does not exist'.format(
            objtype))
예제 #3
0
    def put(self):
        node_id = self.request.POST.get('node_id')
        username = self.request.POST.get('gcc_username')
        if not node_id:
            return {'ok': False,
                    'message': 'Please set a node id (node_id)'}
        if not username:
            return {'ok': False,
                    'message': 'Please set a admin username (gcc_username)'}
        self.request.user = self.request.db.adminusers.find_one({'username': username})
        if not self.request.user:
            return {'ok': False,
                    'message': 'The admin user %s does not exists' % username}
        settings = get_current_registry().settings
        api = get_chef_api(settings, self.request.user)
        node = Node(node_id, api)
        job_status = node.attributes.get('job_status')
        reserve_node = False
        if job_status:
            node = reserve_node_or_raise(node_id, api, 'gcc-chef-status-%s' % random.random(), attempts=3)
            reserve_node = True
            chef_client_error = False

            for job_id, job_status in job_status.to_dict().items():
                job = self.collection.find_one({'_id': ObjectId(job_id)})
                if not job:
                    continue
                if job_status['status'] == 0:
                    self.collection.update({'_id': job['_id']},
                                           {'$set': {'status': 'finished',
                                                     'last_update': datetime.datetime.utcnow()}})
                else:
                    chef_client_error = True
                    self.collection.update({'_id': job['_id']},
                                           {'$set': {'status': 'errors',
                                                     'message': job_status.get('message', 'Error'),
                                                     'last_update': datetime.datetime.utcnow()}})
            self.request.db.nodes.update({'node_chef_id': node_id}, {'$set': {'error_last_chef_client': chef_client_error}})
            invalidate_jobs(self.request)
            node.attributes.set_dotted('job_status', {})

        users_old = self.get_attr(node, USERS_OLD)
        users = self.get_attr(node, USERS_OHAI)
        if not users_old or users_old != users:
            if not reserve_node:
                node = reserve_node_or_raise(node_id, api, 'gcc-chef-status-%s' % random.random(), attempts=3)
            return self.check_users(node)
        if job_status:
            save_node_and_free(node)
        return {'ok': True}
예제 #4
0
파일: tasks.py 프로젝트: Emergya/gecoscc-ui
 def object_action(self, user, obj, objold=None, action=None, computers=None):
     api = get_chef_api(self.app.conf, user)
     cookbook = get_cookbook(api, self.app.conf.get('chef.cookbook_name'))
     computers = computers or self.get_related_computers(obj)
     are_new_jobs = False
     for computer in computers:
         try:
             job_ids_by_computer = []
             node_chef_id = computer.get('node_chef_id', None)
             node = reserve_node_or_raise(node_chef_id, api, 'gcc-tasks-%s-%s' % (obj['_id'], random.random()), 10)
             if not node.get(self.app.conf.get('chef.cookbook_name')):
                 raise NodeNotLinked("Node %s is not linked" % node_chef_id)
             error_last_saved = computer.get('error_last_saved', False)
             error_last_chef_client = computer.get('error_last_chef_client', False)
             force_update = error_last_saved or error_last_chef_client
             node, updated = self.update_node(user, computer, obj, objold, node, action, job_ids_by_computer, force_update)
             if not updated:
                 save_node_and_free(node)
                 continue
             are_new_jobs = True
             self.validate_data(node, cookbook, api)
             save_node_and_free(node)
             if error_last_saved:
                 self.db.nodes.update({'_id': computer['_id']},
                                      {'$set': {'error_last_saved': False}})
         except NodeNotLinked as e:
             self.report_node_not_linked(computer, user, obj, action)
             are_new_jobs = True
             save_node_and_free(node, api, refresh=True)
         except NodeBusyException as e:
             self.report_node_busy(computer, user, obj, action)
             are_new_jobs = True
         except ValidationError as e:
             if not job_ids_by_computer:
                 self.report_unknown_error(e, user, obj, action, computer)
             self.report_error(e, job_ids_by_computer, computer, 'Validation error: ')
             save_node_and_free(node, api, refresh=True)
             are_new_jobs = True
         except Exception as e:
             if not job_ids_by_computer:
                 self.report_unknown_error(e, user, obj, action, computer)
             self.report_error(e, job_ids_by_computer, computer)
             try:
                 save_node_and_free(node, api, refresh=True)
             except:
                 pass
             are_new_jobs = True
     if are_new_jobs:
         invalidate_jobs(self.request, user)
예제 #5
0
파일: tasks.py 프로젝트: Emergya/gecoscc-ui
 def object_action(self,
                   user,
                   obj,
                   objold=None,
                   action=None,
                   computers=None):
     api = get_chef_api(self.app.conf, user)
     cookbook = get_cookbook(api, self.app.conf.get('chef.cookbook_name'))
     computers = computers or self.get_related_computers(obj)
     are_new_jobs = False
     for computer in computers:
         try:
             job_ids_by_computer = []
             node_chef_id = computer.get('node_chef_id', None)
             node = reserve_node_or_raise(
                 node_chef_id, api,
                 'gcc-tasks-%s-%s' % (obj['_id'], random.random()), 10)
             if not node.get(self.app.conf.get('chef.cookbook_name')):
                 raise NodeNotLinked("Node %s is not linked" % node_chef_id)
             error_last_saved = computer.get('error_last_saved', False)
             error_last_chef_client = computer.get('error_last_chef_client',
                                                   False)
             force_update = error_last_saved or error_last_chef_client
             node, updated = self.update_node(user, computer, obj, objold,
                                              node, action,
                                              job_ids_by_computer,
                                              force_update)
             if not updated:
                 save_node_and_free(node)
                 continue
             are_new_jobs = True
             self.validate_data(node, cookbook, api)
             save_node_and_free(node)
             if error_last_saved:
                 self.db.nodes.update({'_id': computer['_id']},
                                      {'$set': {
                                          'error_last_saved': False
                                      }})
         except NodeNotLinked as e:
             self.report_node_not_linked(computer, user, obj, action)
             are_new_jobs = True
             save_node_and_free(node, api, refresh=True)
         except NodeBusyException as e:
             self.report_node_busy(computer, user, obj, action)
             are_new_jobs = True
         except ValidationError as e:
             if not job_ids_by_computer:
                 self.report_unknown_error(e, user, obj, action, computer)
             self.report_error(e, job_ids_by_computer, computer,
                               'Validation error: ')
             save_node_and_free(node, api, refresh=True)
             are_new_jobs = True
         except Exception as e:
             if not job_ids_by_computer:
                 self.report_unknown_error(e, user, obj, action, computer)
             self.report_error(e, job_ids_by_computer, computer)
             try:
                 save_node_and_free(node, api, refresh=True)
             except:
                 pass
             are_new_jobs = True
     if are_new_jobs:
         invalidate_jobs(self.request, user)
예제 #6
0
    def put(self):
        node_id = self.request.POST.get('node_id')
        username = self.request.POST.get('gcc_username')
        if not node_id:
            return {'ok': False,
                    'message': 'Please set a node id (node_id)'}
        if not username:
            return {'ok': False,
                    'message': 'Please set a admin username (gcc_username)'}
        self.request.user = self.request.db.adminusers.find_one({'username': username})
        if not self.request.user:
            return {'ok': False,
                    'message': 'The admin user %s does not exists' % username}
        settings = get_current_registry().settings
        api = get_chef_api(settings, self.request.user)
        node = Node(node_id, api)
        job_status = node.attributes.get('job_status')

        # After chef-client run, a report handler calls /api/chef_status
        # Previously, gcc_link attribute of chef node is updated by network policies
        gcc_link = node.attributes.get('gcc_link')
        self.request.db.nodes.update({'node_chef_id':node_id},{'$set': {'gcc_link':gcc_link}})

        reserve_node = False
        if job_status:
            node = reserve_node_or_raise(node_id, api, 'gcc-chef-status-%s' % random.random(), attempts=3)
            reserve_node = True
            chef_client_error = False

            for job_id, job_status in job_status.to_dict().items():
                job = self.collection.find_one({'_id': ObjectId(job_id)})
                if not job:
                    continue
                # Parent
                macrojob = self.collection.find_one({'_id': ObjectId(job['parent'])}) if 'parent' in job else None
                if job_status['status'] == 0:
                    self.collection.update({'_id': job['_id']},
                                           {'$set': {'status': 'finished',
                                                     'last_update': datetime.datetime.utcnow()}})
                    # Decrement number of children in parent
                    if macrojob and 'counter' in macrojob:
                        macrojob['counter'] -= 1
                elif job_status['status'] == 2:
                    self.collection.update({'_id': job['_id']},
                                           {'$set': {'status': 'warnings',
                                                     'message': job_status.get('message', 'Warning'),
                                                     'last_update': datetime.datetime.utcnow()}})
                    if macrojob:                                
                        macrojob['status'] = 'warnings'
                else:
                    chef_client_error = True
                    self.collection.update({'_id': job['_id']},
                                           {'$set': {'status': 'errors',
                                                     'message': job_status.get('message', 'Error'),
                                                     'last_update': datetime.datetime.utcnow()}})
                    if macrojob:                                
                        macrojob['status'] = 'errors'
                # Update parent                                 
                if macrojob:
                    self.collection.update({'_id': macrojob['_id']},                                                                
                                           {'$set': {'counter': macrojob['counter'],
                                                     'message': self._("Pending: %d") % macrojob['counter'],
                                                     'status': 'finished' if macrojob['counter'] == 0 else macrojob['status']}})
            self.request.db.nodes.update({'node_chef_id': node_id}, {'$set': {'error_last_chef_client': chef_client_error}})
            invalidate_jobs(self.request)
            node.attributes.set_dotted('job_status', {})

        users_old = self.get_attr(node, USERS_OLD)
        users = self.get_attr(node, USERS_OHAI)
        if not users_old or users_old != users:
            if not reserve_node:
                node = reserve_node_or_raise(node_id, api, 'gcc-chef-status-%s' % random.random(), attempts=3)
            return self.check_users(node, api)
        if job_status:
            save_node_and_free(node)
        return {'ok': True}