示例#1
0
    def groupMessage(self, command, signatureKey):
        """Given a command string and signature create a signed payload"""
        digest = DIGEST_INIT()
        keyID = signatureKey.id

        magicStr = packify(self.value)
        timestamp = int(time.time())
        payload = str(magicStr) + str(timestamp) + str(command)

        digest.update(payload)
        signature = signatureKey.encrypt(digest.hexdigest())

        if '.' in signatureKey.id:
            keyID = signatureKey.id.split('.', 1)[0]

        args = command.split()
        action = args.pop(0)
        argstr = ""

        if args:
            argstr = " ".join(args)

        #group payload
        msgDict = {
            'action': action,
            'argstr': argstr,
            'magic': magicStr,
            'time': timestamp,
            'key': keyID,
            'signature': signature,
        }

        proto = Serialize()
        return urllib.quote(proto.execute(self.MIME, msgDict))
示例#2
0
    def startInstance(self, label):
        """Starts an Application Instances based on our models rules

           @param label: (string) - app instance label

           @return defer.Deferred - be prepared for Failures()
        """
        start = dictwrapper(copy.deepcopy(self.STARTUP_INFO))

        #configure our protocol
        if 'debug' not in self.startProtoKwargs:
            self.startProtoKwargs['debug'] = False
        if 'timeout' not in self.startProtoKwargs:
            self.startProtoKwargs['timeout'] = self.DEFAULT_TIMEOUT
        if 'logger' not in self.startProtoKwargs:
            self.startProtoKwargs['logger'] = self.log

        #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        #
        # !! READ THIS COMMENT BLOCK !!
        #
        # the callback result from your protocol should return a dictionary
        # with a KEY 'pid' included and 'pid' should be an integer otherwise
        # the injected callback immediately following 'command' will fail to
        # update your instance state.  You have been warned.
        #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        result = None
        try:
            thisInst = self.getInstance(label)
            TIME = str(time.time())
            anchor = DIGEST_INIT()
            anchor.update(self.name)
            anchor.update(label)
            anchor.update(TIME)  #add some randomness
            anchor = str(anchor.hexdigest())
            #inject some env variables that we may want to retrieve later
            ENV = {
                'DRONED_IDENTIFIER': anchor,
                'DRONED_STARTTIME': TIME,
                'DRONED_LABEL': label,
                'DRONED_APPLICATION': self.name,
                'DRONED_LOGDIR': config.LOG_DIR,
            }
            if thisInst.version:
                ENV['DRONED_VERSION'] = thisInst.version
            #add these vars to the start env of the contained application
            start.START_ENV.update(ENV)
            d = command(start.START_CMD, start.START_ARGS, start.START_ENV,
                        start.START_PATH, start.START_USEPTY,
                        start.START_CHILDFD, self.startProtocol,
                        *self.startProtoArgs, **self.startProtoKwargs)
            wfd = defer.waitForDeferred(d)
            yield wfd
            result = wfd.getResult()  #we probably might not know the pid yet
            #if allowed by config search for the instance after some delay
            pid = result.get('pid', 0)  #just in case the protocol knows it
            if isinstance(self.SEARCH_DELAY, (int, float)) and not pid:
                d = defer.Deferred()
                self.reactor.callLater(self.SEARCH_DELAY, d.callback, None)
                wfd = defer.waitForDeferred(d)
                yield wfd
                wfd.getResult()  #don't care about this result
                d = self.findProcesses()
                wfd = defer.waitForDeferred(d)
                yield wfd
                data = wfd.getResult()
                if data:
                    data = data.pop(0)[1]  #we are just going to take the first
                    result.update(data)  #we should have the pid captured
            #this is the proper way to notify the AppInstance that we are running
            thisInst.pid = int(result.get('pid', 0))
        except:
            result = Failure()
        yield result