def update_task(self, environ, start_response, task_id): """ Update data configuration for an existing task """ if validators.validate_task_id(task_id) != task_id: self.log.error("Failed to pass validation: '%s'" % task_id) return response.send_error(start_response, 400, constants.ERROR_TASK_INVALID_ID) if not os.path.isdir(self._task_dir(task_id)): self.log.debug("Task not found '%s'" % task_id) return response.send_error(start_response, 404, constants.ERROR_TASK_NOT_FOUND) try: new_task_description = json.loads( request.read_request_data(environ)) except ValueError: self.log.error("Decoding task data failed '%s'" % task_id) return response.send_error(start_response, 400, constants.ERROR_TASK_INVALID_PAYLOAD) if self.zknodes: lock = distlocks.ZooKeeperLock(self.zknodes, 'task-lock-%s' % task_id) if lock.try_lock() != True: lock.close() self.log.debug("Task locked '%s'" % task_id) return response.send_response(start_response, 409, constants.ERROR_TASK_LOCKED) else: lock = None try: old_task_description = self._load_task_config(task_id) except: if lock: lock.unlock() lock.close() self.log.error("Failed to read task data '%s'" % task_id) return response.send_response(start_response, 500) if old_task_description.has_key( 'assignee') and new_task_description.has_key( 'assignee') and old_task_description[ 'assignee'] != new_task_description['assignee']: if lock: lock.unlock() lock.close() self.log.debug("Task assignment conflict '%s'" % task_id) return response.send_response(start_response, 409, constants.ERROR_TASK_WRONG_ACTOR) self._save_task_config(task_id, new_task_description) if lock: lock.unlock() lock.close() return response.send_response( start_response, 200, json.dumps({ 'id': task_id, 'data': new_task_description }))
def create_new_task(self, environ, start_response): """ Post a new task """ try: task_description = json.loads(request.read_request_data(environ)) except ValueError: self.log.debug('Failed to load task data') return response.send_error(start_response, 400, constants.ERROR_TASK_INVALID_PAYLOAD) task_id_candidate = str(uuid.uuid4()) os.mkdir(self._task_dir(task_id_candidate)) self._save_task_config(task_id_candidate, task_description) return response.send_response(start_response, 201, json.dumps({'id': task_id_candidate, 'data': task_description}))
def create_or_update_job(self, environ, start_response, job_id_param = None): """ Create a new job """ try: job_config = json.loads(request.read_request_data(environ)) except ValueError: self.log.debug('Failed to load job config') return response.send_error(start_response, 400, constants.ERROR_JOB_INVALID_PAYLOAD) job_id = job_config.get('job_id') if job_id == None: self.log.debug('Missing job_id') return response.send_error(start_response, 400, constants.ERROR_JOB_INVALID_PAYLOAD) if job_id_param and job_id_param != job_id: self.log.debug('Job ID mismatch: %r vs %r' % (job_id, job_id_param)) return response.send_error(start_response, 400, constants.ERROR_JOB_INVALID_ID) if validators.validate_job_id(job_id) == None: self.log.debug('Invalid job_id: %r' % job_id) return response.send_error(start_response, 400, constants.ERROR_JOB_INVALID_ID) if self.zknodes: lock = distlocks.ZooKeeperLock(self.zknodes, 'job-lock-%s' % job_id) if lock.try_lock() != True: lock.close() self.log.debug("Job locked '%s'" % job_id) return response.send_error(start_response, 400, constants.ERROR_JOB_LOCKED) else: lock = None if job_id_param is None: try: os.mkdir(self._job_dir(job_id)) except OSError: if lock: lock.unlock() lock.close() return response.send_error(start_response, 500, constants.ERROR_JOB_CONFIG_WRITE_FAILED) try: file(self._job_config_file(job_id), 'wb').write(json.dumps(job_config)) except IOError: self.log.debug('Failed to write job config, job_id %s' % job_id) if lock: lock.unlock() lock.close() return response.send_error(start_response, 500, constants.ERROR_JOB_CONFIG_WRITE_FAILED) if lock: lock.unlock() lock.close() return response.send_response(start_response, 200 if job_id_param else 201, json.dumps({'job_id':job_id, 'config':job_config}))
def update_console_log(self, environ, start_response, job_id, build_id): """ Append content to the console log """ if validators.validate_job_id(job_id) == None: self.log.error("Job_id validation failure, '%s'", job_id) return response.send_error(start_response, 400, constants.ERROR_JOB_INVALID_ID) if validators.validate_build_id(build_id) != build_id: self.log.error("Build_id validation failure, '%s'", build_id) return response.send_error(start_response, 400, constants.ERROR_BUILD_INVALID_ID) if not os.path.isdir(self._build_dir(job_id, build_id)): return response.send_error(start_response, 404, constants.ERROR_BUILD_NOT_FOUND) try: file(self._console_log_file(job_id, build_id), 'ab').write(request.read_request_data(environ)) except IOError: # can be ignored, we just return empty log pass return response.send_response(start_response, 204)
def create_new_task(self, environ, start_response): """ Post a new task """ try: task_description = json.loads(request.read_request_data(environ)) except ValueError: self.log.debug('Failed to load task data') return response.send_error(start_response, 400, constants.ERROR_TASK_INVALID_PAYLOAD) task_id_candidate = str(uuid.uuid4()) os.mkdir(self._task_dir(task_id_candidate)) self._save_task_config(task_id_candidate, task_description) return response.send_response( start_response, 201, json.dumps({ 'id': task_id_candidate, 'data': task_description }))
def update_task(self, environ, start_response, task_id): """ Update data configuration for an existing task """ if validators.validate_task_id(task_id) != task_id: self.log.error("Failed to pass validation: '%s'" % task_id) return response.send_error(start_response, 400, constants.ERROR_TASK_INVALID_ID) if not os.path.isdir(self._task_dir(task_id)): self.log.debug("Task not found '%s'" % task_id) return response.send_error(start_response, 404, constants.ERROR_TASK_NOT_FOUND) try: new_task_description = json.loads(request.read_request_data(environ)) except ValueError: self.log.error("Decoding task data failed '%s'" % task_id) return response.send_error(start_response, 400, constants.ERROR_TASK_INVALID_PAYLOAD) if self.zknodes: lock = distlocks.ZooKeeperLock(self.zknodes, 'task-lock-%s' % task_id) if lock.try_lock() != True: lock.close() self.log.debug("Task locked '%s'" % task_id) return response.send_response(start_response, 409, constants.ERROR_TASK_LOCKED) else: lock = None try: old_task_description = self._load_task_config(task_id) except: if lock: lock.unlock() lock.close() self.log.error("Failed to read task data '%s'" % task_id) return response.send_response(start_response, 500) if old_task_description.has_key('assignee') and new_task_description.has_key('assignee') and old_task_description['assignee'] != new_task_description['assignee']: if lock: lock.unlock() lock.close() self.log.debug("Task assignment conflict '%s'" % task_id) return response.send_response(start_response, 409, constants.ERROR_TASK_WRONG_ACTOR) self._save_task_config(task_id, new_task_description) if lock: lock.unlock() lock.close() return response.send_response(start_response, 200, json.dumps({'id': task_id, 'data': new_task_description}))
def update_build_state(self, environ, start_response, job_id, build_id): """ Update build state """ try: build_state = json.loads(request.read_request_data(environ)) except ValueError: self.log.error('Failed to load build state') return response.send_error(start_response, 400, constants.ERROR_BUILD_INVALID_PAYLOAD) if validators.validate_job_id(job_id) == None: self.log.error("Job_id validation failure, '%s'", job_id) return response.send_error(start_response, 400, constants.ERROR_JOB_INVALID_ID) if validators.validate_build_id(build_id) != build_id: self.log.error("Build_id validation failure, '%s'", build_id) return response.send_error(start_response, 400, constants.ERROR_BUILD_INVALID_ID) if not os.path.isdir(self._build_dir(job_id, build_id)): return response.send_error(start_response, 404, constants.ERROR_BUILD_NOT_FOUND) try: file(self._build_state_file(job_id, build_id), 'wb').write(json.dumps(build_state)) except IOError: self.log.debug('Failed to write build state, job_id %s, build %s', job_id, build_id) return response.send_error(start_response, 500, constants.ERROR_BUILD_WRITE_FAILED) return response.send_response(start_response, 200, json.dumps({'job_id': job_id, 'build_number': int(build_id), 'state': build_state}))
def update_build_state(self, environ, start_response, job_id, build_id): """ Update build state """ try: build_state = json.loads(request.read_request_data(environ)) except ValueError: self.log.error('Failed to load build state') return response.send_error(start_response, 400, constants.ERROR_BUILD_INVALID_PAYLOAD) if validators.validate_job_id(job_id) == None: self.log.error("Job_id validation failure, '%s'", job_id) return response.send_error(start_response, 400, constants.ERROR_JOB_INVALID_ID) if validators.validate_build_id(build_id) != build_id: self.log.error("Build_id validation failure, '%s'", build_id) return response.send_error(start_response, 400, constants.ERROR_BUILD_INVALID_ID) if not os.path.isdir(self._build_dir(job_id, build_id)): return response.send_error(start_response, 404, constants.ERROR_BUILD_NOT_FOUND) try: file(self._build_state_file(job_id, build_id), 'wb').write(json.dumps(build_state)) except IOError: self.log.debug('Failed to write build state, job_id %s, build %s', job_id, build_id) return response.send_error(start_response, 500, constants.ERROR_BUILD_WRITE_FAILED) return response.send_response( start_response, 200, json.dumps({ 'job_id': job_id, 'build_number': int(build_id), 'state': build_state }))