Beispiel #1
0
    def do_download(self, mclient, request):
        if self._invalid_project(mclient, request):
            raise StopIteration

        if not self.builder.has_file(request['project'], request['filepath']):
            yield gen.Task(mclient.write_response, ResponseMessage.error(
                request.id,
                reason="Invalid filepath",
                code=ErrorCodes.MISSING_FILEPATH,
            ))
            raise StopIteration
        contents = self.builder.read_file(request['project'], request['filepath'])
        if contents is None:
            yield gen.Task(mclient.write_response, ResponseMessage.error(
                request.id,
                reason="Invalid filepath",
                code=ErrorCodes.MISSING_FILEPATH,
            ))
            raise StopIteration
        yield gen.Task(mclient.write_response, ResponseMessage.success(
            request.id,
            project=request['project'],
            filepath=request['filepath'],
            contents=contents,
        ))
Beispiel #2
0
 def handle_login(self, request):
     "Log this client in."
     request = request.cast_to(LoginMessage)
     self.account = Account.create(request['username'], request['password'])
     if self.auth.verify(self.account):
         # TODO: verify machine & type values
         self.machine, self.type = request['machine'], request['type']
         self.namespace = request['username']
         print self.address_str(), "=>", self.id
         if not self.tracker.assign_namespace(self):
             yield gen.Task(self.stream.write, ResponseMessage.error(
                 request.id,
                 reason="Machine of name %r already connected." % self.machine,
                 code=ErrorCodes.MACHINE_CONFLICT
             ))
             self.close()
             raise StopIteration
         msg = ResponseMessage.success(request.id)
         yield gen.Task(self.stream.write, msg)
         print self.id, '<-', msg
         self.process_request()
     else:
         self.fail(request.id,
             reason='Invalid username or password',
             code=ErrorCodes.BAD_AUTH,
             close_stream=False)
Beispiel #3
0
 def wrapped(self, *args, **kwargs):
     mclient = args[mclient_index]
     request = args[request_index]
     if not validator(self, request[key]):
         yield gen.Task(mclient.write_response, ResponseMessage.error(request.id, reason=reason, code=code))
         raise StopIteration
     fn(self, *args, **kwargs)
Beispiel #4
0
 def handle_login(self, request):
     "Log this client in."
     request = request.cast_to(LoginMessage)
     self.account = Account.create(request['username'], request['password'])
     if self.auth.verify(self.account):
         # TODO: verify machine & type values
         self.machine, self.type = request['machine'], request['type']
         self.namespace = request['username']
         print self.address_str(), "=>", self.id
         if not self.tracker.assign_namespace(self):
             yield gen.Task(
                 self.stream.write,
                 ResponseMessage.error(
                     request.id,
                     reason="Machine of name %r already connected." %
                     self.machine,
                     code=ErrorCodes.MACHINE_CONFLICT))
             self.close()
             raise StopIteration
         msg = ResponseMessage.success(request.id)
         yield gen.Task(self.stream.write, msg)
         print self.id, '<-', msg
         self.process_request()
     else:
         self.fail(request.id,
                   reason='Invalid username or password',
                   code=ErrorCodes.BAD_AUTH,
                   close_stream=False)
Beispiel #5
0
 def do_request(self, request):
     # TODO: reject if sender or command is malformed
     print 'REQUEST: namespace =', self.namespace, '; machine =', request[
         'machine']
     target = self.tracker.get_client_in_namespace(self.namespace,
                                                   request['machine'])
     if target is None:
         print "No machine named:", request['machine']
         msg = ResponseMessage.error(request.id,
                                     reason="No machine exists named %r" %
                                     request['machine'],
                                     code=ErrorCodes.UNKNOWN_MACHINE)
         yield gen.Task(self.stream.write, msg)
         raise StopIteration
     msg = InvocationMessage.create(request['command'])
     if not msg:
         print "bad message:", repr(msg)
         raise StopIteration
     msg.sender = self.machine
     print target.id, '<-', msg.name, '[forwarding]'
     response = yield gen.Task(target.request, msg)
     print '[forwarding]', target.id, '->', response
     response.sender = target.machine
     print self.id, '<-', response, '[forwarding]'
     yield gen.Task(self.stream.write, response)
Beispiel #6
0
 def _invalid_project(self, mclient, request, callback=None):
     if request["project"] not in self.builder.project_names:
         mclient.write_response(
             ResponseMessage.error(request.id, reason="Invalid Project", code=ErrorCodes.MISSING_PROJECT),
             callback=callback,
         )
         return True
     return False
Beispiel #7
0
    def do_perform(self, mclient, request):
        if self._invalid_project(mclient, request):
            raise StopIteration
        project = self.builder.projects[request['project']]

        if project.is_busy:
            yield gen.Task(mclient.write_response, ResponseMessage.error(
                request.id,
                reason="Project is busy. Use cancel to stop existing command.",
                code=ErrorCodes.ACTION_CONFLICT,
            ))
            raise StopIteration

        if request['action'] not in project.actions:
            yield gen.Task(mclient.write_response, ResponseMessage.error(
                request.id,
                reason="Invalid Action",
                code=ErrorCodes.MISSING_ACTION,
            ))
            raise StopIteration

        self.process_query = project.perform_action(request['action'])

        target = request.sender
        yield gen.Task(mclient.write_response, ResponseMessage.success(request.id))

        # TODO: handle stdin
        while not self.process_query.has_terminated or self.process_query.can_read:
            if self.process_query.can_read:
                yield gen.Task(mclient.send, target, StreamNotification(
                    project=project.name,
                    contents=self.process_query.read(),
                ))
            else:
               # wait, to allow processing of other IO
               yield gen.Task(self.wait)

        yield gen.Task(mclient.send, target, StreamEOFNotification(
            project=project.name,
        ))
        yield gen.Task(mclient.send, target, ReturnCodeNotification(
            project=project.name,
            code=self.process_query.return_code,
        ))
        self.process_query = None
Beispiel #8
0
 def fail(self, id, **kwargs):
     close = kwargs.pop('close_stream', False)
     msg = ResponseMessage.error(id, **kwargs)
     if close:
         print self.id, '<-', msg, '+ close'
     else:
         print self.id, '<-', msg
     closefn = lambda: self.tracker.remove(self)
     self.stream.write(msg, callback=closefn if close else None)
Beispiel #9
0
 def fail(self, id, **kwargs):
     close = kwargs.pop('close_stream', False)
     msg = ResponseMessage.error(id, **kwargs)
     if close:
         print self.id, '<-', msg, '+ close'
     else:
         print self.id, '<-', msg
     closefn = lambda: self.tracker.remove(self)
     self.stream.write(msg, callback=closefn if close else None)
Beispiel #10
0
 def _invalid_project(self, mclient, request, callback=None):
     if request['project'] not in self.builder.project_names:
         mclient.write_response(ResponseMessage.error(
             request.id,
             reason="Invalid Project",
             code=ErrorCodes.MISSING_PROJECT,
         ), callback=callback)
         return True
     return False
Beispiel #11
0
    def do_perform(self, mclient, request):
        if self._invalid_project(mclient, request):
            raise StopIteration
        project = self.builder.projects[request["project"]]

        if project.is_busy:
            yield gen.Task(
                mclient.write_response,
                ResponseMessage.error(
                    request.id,
                    reason="Project is busy. Use cancel to stop existing command.",
                    code=ErrorCodes.ACTION_CONFLICT,
                ),
            )
            raise StopIteration

        if request["action"] not in project.actions:
            yield gen.Task(
                mclient.write_response,
                ResponseMessage.error(request.id, reason="Invalid Action", code=ErrorCodes.MISSING_ACTION),
            )
            raise StopIteration

        self.process_query = project.perform_action(request["action"])

        target = request.sender
        yield gen.Task(mclient.write_response, ResponseMessage.success(request.id))

        # TODO: handle stdin
        while not self.process_query.has_terminated or self.process_query.can_read:
            if self.process_query.can_read:
                yield gen.Task(
                    mclient.send, target, StreamNotification(project=project.name, contents=self.process_query.read())
                )
            else:
                # wait, to allow processing of other IO
                yield gen.Task(self.wait)

        yield gen.Task(mclient.send, target, StreamEOFNotification(project=project.name))
        yield gen.Task(
            mclient.send, target, ReturnCodeNotification(project=project.name, code=self.process_query.return_code)
        )
        self.process_query = None
Beispiel #12
0
 def handle_register(self, request):
     "Register a new user account fo this client."
     error = self.auth.create(request['username'], request['password'])
     if not error:
         msg = ResponseMessage.success(request.id)
         print self.id, '<-', msg
         yield gen.Task(self.stream.write, msg)
     else:
         msg = ResponseMessage.error(request.id, **error)
         print self.id, '<-', msg
         yield gen.Task(self.stream.write, msg)
Beispiel #13
0
 def handle_register(self, request):
     "Register a new user account fo this client."
     error = self.auth.create(request['username'], request['password'])
     if not error:
         msg = ResponseMessage.success(request.id)
         print self.id, '<-', msg
         yield gen.Task(self.stream.write, msg)
     else:
         msg = ResponseMessage.error(request.id, **error)
         print self.id, '<-', msg
         yield gen.Task(self.stream.write, msg)
Beispiel #14
0
 def wrapped(self, *args, **kwargs):
     mclient = args[mclient_index]
     request = args[request_index]
     if not validator(self, request[key]):
         yield gen.Task(mclient.write_response, ResponseMessage.error(
             request.id,
             reason=reason,
             code=code,
         ))
         raise StopIteration
     fn(self, *args, **kwargs)
Beispiel #15
0
    def do_upload(self, mclient, request):
        if self._invalid_project(mclient, request):
            raise StopIteration

        if request['contents'] is None:
            yield gen.Task(mclient.write_response, ResponseMessage.error(
                request.id,
                reason="Bad Request",
                code=ErrorCodes.BAD_REQUEST,
            ))
            raise StopIteration
        # no op for now
        try:
            self.builder.write_file(request['project'], request['filepath'], request['contents'] or '')
        except IOError:
            yield gen.Task(mclient.write_response, ResponseMessage.error(
                request.id, reason="Failed to write", code=ErrorCodes.INTERNAL_ERROR))
            raise StopIteration

        yield gen.Task(mclient.write_response, ResponseMessage.success(request.id))
Beispiel #16
0
    def do_upload(self, mclient, request):
        if self._invalid_project(mclient, request):
            raise StopIteration

        if request["contents"] is None:
            yield gen.Task(
                mclient.write_response,
                ResponseMessage.error(request.id, reason="Bad Request", code=ErrorCodes.BAD_REQUEST),
            )
            raise StopIteration
        # no op for now
        try:
            self.builder.write_file(request["project"], request["filepath"], request["contents"] or "")
        except IOError:
            yield gen.Task(
                mclient.write_response,
                ResponseMessage.error(request.id, reason="Failed to write", code=ErrorCodes.INTERNAL_ERROR),
            )
            raise StopIteration

        yield gen.Task(mclient.write_response, ResponseMessage.success(request.id))
Beispiel #17
0
    def do_input(self, mclient, request):
        if self._invalid_project(mclient, request):
            raise StopIteration

        if request["contents"] is None:
            yield gen.Task(
                mclient.write_response,
                ResponseMessage.error(request.id, reason="Bad Request", code=ErrorCodes.BAD_REQUEST),
            )
            raise StopIteration

        if not self.process_query:
            yield gen.Task(
                mclient.write_response,
                ResponseMessage.error(
                    request.id, reason="No process running for %r." % request["project"], code=ErrorCodes.NO_ACTIVITY
                ),
            )
            raise StopIteration

        self.process_query.write(str(request["contents"]))
        yield gen.Task(mclient.write_response, ResponseMessage.success(request.id))
Beispiel #18
0
    def do_input(self, mclient, request):
        if self._invalid_project(mclient, request):
            raise StopIteration

        if request['contents'] is None:
            yield gen.Task(mclient.write_response, ResponseMessage.error(
                request.id,
                reason="Bad Request",
                code=ErrorCodes.BAD_REQUEST,
            ))
            raise StopIteration

        if not self.process_query:
            yield gen.Task(mclient.write_response, ResponseMessage.error(
                request.id,
                reason="No process running for %r." % request['project'],
                code=ErrorCodes.NO_ACTIVITY,
            ))
            raise StopIteration

        self.process_query.write(str(request['contents']))
        yield gen.Task(mclient.write_response, ResponseMessage.success(request.id))
Beispiel #19
0
    def do_download(self, mclient, request):
        if self._invalid_project(mclient, request):
            raise StopIteration

        if not self.builder.has_file(request["project"], request["filepath"]):
            yield gen.Task(
                mclient.write_response,
                ResponseMessage.error(request.id, reason="Invalid filepath", code=ErrorCodes.MISSING_FILEPATH),
            )
            raise StopIteration
        contents = self.builder.read_file(request["project"], request["filepath"])
        if contents is None:
            yield gen.Task(
                mclient.write_response,
                ResponseMessage.error(request.id, reason="Invalid filepath", code=ErrorCodes.MISSING_FILEPATH),
            )
            raise StopIteration
        yield gen.Task(
            mclient.write_response,
            ResponseMessage.success(
                request.id, project=request["project"], filepath=request["filepath"], contents=contents
            ),
        )
Beispiel #20
0
 def handle_message(self, message, mclient):
     # dispatch
     if message.is_response and message.id in self.inbox:
         self.inbox[message.id]()
         del self.inbox[message.id]
     elif message.is_invocation:
         method = getattr(self, "do_" + message.name, None)
         if callable(method):
             print "invoking", "do_" + message.name
             method(mclient, message)
     else:
         yield gen.Task(
             mclient.write_response,
             ResponseMessage.error(message.id, reason="Malformed request", code=ErrorCodes.BAD_REQUEST),
         )
Beispiel #21
0
 def handle_message(self, message, mclient):
     # dispatch
     if message.is_response and message.id in self.inbox:
         self.inbox[message.id]()
         del self.inbox[message.id]
     elif message.is_invocation:
         method = getattr(self, 'do_' + message.name, None)
         if callable(method):
             print 'invoking', 'do_' + message.name
             method(mclient, message)
     else:
         yield gen.Task(mclient.write_response,
                 ResponseMessage.error(message.id,
                     reason="Malformed request",
                     code=ErrorCodes.BAD_REQUEST))
Beispiel #22
0
    def do_cancel(self, mclient, request):
        if self._invalid_project(mclient, request):
            raise StopIteration

        if not self.process_query:
            yield gen.Task(
                mclient.write_response,
                ResponseMessage.error(request.id, reason="No process running for %r." % request["project"]),
            )
            raise StopIteration

        self.process_query.terminate()
        yield gen.Task(mclient.write_response, ResponseMessage.success(request.id))

        # really kill it if we need to
        yield gen.Task(mclient.wait_for, seconds=1)
        self.process_query.kill()
        self.process_query = None
Beispiel #23
0
    def do_cancel(self, mclient, request):
        if self._invalid_project(mclient, request):
            raise StopIteration

        if not self.process_query:
            yield gen.Task(mclient.write_response, ResponseMessage.error(
                request.id,
                reason="No process running for %r." % request['project']
            ))
            raise StopIteration

        self.process_query.terminate()
        yield gen.Task(mclient.write_response, ResponseMessage.success(request.id))

        # really kill it if we need to
        yield gen.Task(mclient.wait_for, seconds=1)
        self.process_query.kill()
        self.process_query = None
Beispiel #24
0
    def do_files(self, mclient, request):
        if self._invalid_project(mclient, request):
            raise StopIteration

        files = self.builder.get_files(request["project"], request["branch"])

        # files is None when switching branches fails.
        # TODO: perhaps we should stash & apply instead?
        if files is None:
            yield gen.Task(
                mclient.write_response,
                ResponseMessage.error(request.id, reason="Failed to checkout files", code=ErrorCodes.INTERNAL_ERROR),
            )
        else:
            yield gen.Task(
                mclient.write_response,
                ResponseMessage.success(
                    request.id, files=files, branch=self.builder.get_current_branch(request["project"])
                ),
            )
Beispiel #25
0
 def do_request(self, request):
     # TODO: reject if sender or command is malformed
     print 'REQUEST: namespace =', self.namespace, '; machine =', request['machine']
     target = self.tracker.get_client_in_namespace(self.namespace, request['machine'])
     if target is None:
         print "No machine named:", request['machine']
         msg = ResponseMessage.error(request.id,
                 reason="No machine exists named %r" % request['machine'],
                 code=ErrorCodes.UNKNOWN_MACHINE)
         yield gen.Task(self.stream.write, msg)
         raise StopIteration
     msg = InvocationMessage.create(request['command'])
     if not msg:
         print "bad message:", repr(msg)
         raise StopIteration
     msg.sender = self.machine
     print target.id, '<-', msg.name, '[forwarding]'
     response = yield gen.Task(target.request, msg)
     print '[forwarding]', target.id, '->', response
     response.sender = target.machine
     print self.id, '<-', response, '[forwarding]'
     yield gen.Task(self.stream.write, response)
Beispiel #26
0
    def do_files(self, mclient, request):
        if self._invalid_project(mclient, request):
            raise StopIteration

        files = self.builder.get_files(
            request['project'],
            request['branch']
        )

        # files is None when switching branches fails.
        # TODO: perhaps we should stash & apply instead?
        if files is None:
            yield gen.Task(mclient.write_response, ResponseMessage.error(
                request.id,
                reason="Failed to checkout files",
                code=ErrorCodes.INTERNAL_ERROR,
            ))
        else:
            yield gen.Task(mclient.write_response, ResponseMessage.success(
                request.id,
                files=files,
                branch=self.builder.get_current_branch(request['project']),
            ))