[Twisted-Python] help using deferred

Luigi Conte luigiandcosolutions at gmail.com
Mon May 11 13:49:19 EDT 2009

2009/5/11 Jean-Paul Calderone <exarkun at divmod.com>

> On Mon, 11 May 2009 16:55:40 +0200, Luigi Conte <
> luigiandcosolutions at gmail.com> wrote:
> >I'm sure you're saying only good things but I'm so inexpert in twisted
> that
> >I can't understand very well what to do.
> >I'll try to explain all that I want to do and how I did it wrongly:
> >first I have to call the connect method from the api and it returns a
> >deferred so I do:
> >in conn_to_ctrl i have:
> >d = api.connect(...)
> >return d
> >
> >now I do some operations with config files to call many times the start
> >method from the api (I have to start many virtual machines) and the
> >api.start returns a deferred so what have I to do now?
> >I do so:
> >in examinecfg i have:
> ># tha same d that i used to add api.connect!
> >self.d.addCallback(api.start, (method_args))
> >return d
> >
> >Then I have to call the disconnect method from the api. But i tried to
> print
> >out something to fallow the executing but I only see printing the first
> >method that call the connection. after that the process ends.
> >
> >In the main I have:
> >defer = conn_to_ctrl()
> >or have I to add to defer also the examinecfg?
> >
> >thank you very much
> I'm not sure what you're doing wrong.  It's hard to understand mixed up
> snippets and fragments of code.  Please:
>  - don't top post
>  - share complete, runnable examples (preferably minimal, too)
>  - share the failure you're seeing - possibly including a traceback, or a
>    description of the behavior that the program exhibits when you run it,
>    and an explanation of how this differs from what you want
> Jean-Paul
> _______________________________________________
> Twisted-Python mailing list
> Twisted-Python at twistedmatrix.com
> http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python

Ok I'll try to explain what the api provides to me and what I want to do
with it:
mothods provided by api that I want to use:
1) connection

    def connect(self, ctrl_host, ctrl_port, user, passwd):
        """Connect to an Usher control server.
        @param ctrl_host: fqdn where Usher controller is running
        @type ctrl_host: string
        @param ctrl_port: port number Usher controller is listening on
        @type ctrl_port: int
        @param user: username of user connecting to Usher controller
        @type user: string
        @param passwd: password of user connecting to Usher controller
        @type passwd: string
        return: Deferred which returns and L{UsherResult}
        rtype: twisted.internet.defer.Deferred
        # serialize access to connect
        if not self.connect_lock.acquire(False):
            raise UsherEx, "Connection Pending"
        if self.factory:
        # reset vms
        self.vms = {}
        # reset passwd to None until we're connected
        self.passwd = None
        self.factory = APIFactory()
        self.factory.api = self
        # connect to server
        reactor.connectSSL(ctrl_host, ctrl_port, self.factory,
        d = self.factory.login(credentials.UsernamePassword(user, passwd),
        d.addErrback(self._handle_err, misc.whoami())
        d.addCallback(self._connected_to_ctrl, ctrl_host, ctrl_port, user,
        return d

2) start single vm

    def start(self, cluster=None, prefix='', vmlist=None, count=None,
first=None, last=None, dregex=None,  dlist=None, dryrun=False, eid=None,
        """Start a VM or set of VMs
        @param cluster: Name of cluster to which VMs should belong
        @type cluster: string
        @param prefix: prefix to prepend to VM names
        @type prefix: string
        @param vmlist: list of strings of VMs to start
        @type vmlist: list of strings
        @param count: Number of consecutive VMs to start
        @type count: int
        @param first: Lowest number of VM to start
        @type first: int
        @param last: Highest number of VM to start
        @type last: int
        @param dregex: regular expression to match against destination LNM
        @type dregex: list of strings
        @param dlist: list of strings to match against destination LNM names
        @type dlist: list of strings
        @param dryrun: Show what would have happened if the command had been
run without the dryrun command (at the instant that the dryrun command was
run of course)
        @type dryrun: bool
        @param eid: mechanism for admin user to be able to specify an
alternate username for forming suffix for regex
        @type eid: string
        @param kw: Extra arguments passed to controller for use by plugins
or LNM.  Any keywords starting with 'vm_' are added to VM's uargs
parameter.  Note, the controller actually checks for two kw arguments: ram
and ip_addrs.  Though these are, strictly speaking, VM parameters, they're
considered important enough that the controller checks for them.
        @type kw: dict

        @return: Deferred which returns an L{UsherResult}
        @rtype: twisted.internet.defer.Deferred
        @raise UsherNotConnected: Raised when not connected to Usher
        @raise UsherPBDeadRefEx: Raised when capability for Usher Controller
goes stale.  Must reconnect when this happens
        @raise UsherInvalidInputEx: Raised when an invalid input or
combination of parameters is received.

        # make sure we're connected
        if not self.aref:
            raise UsherNotConnectedEx
        # combine these to reduce params
        if ((first and first < 0) or (last and last < 0) or (count and count
            raise UsherInvalidInputEx("first, last, and count must be
        vmrange = (first,last,count)
        # arg check
        self._arg_check(vmlist, vmrange)
        # get final destination list
        dlist = self._namecomplete(dlist, suffix=self.suffix)
        dregex = self._regex_append(dregex, dlist)
        dlist = self._regex_filter(dregex, self.lnms.keys())
        # complete names (if necessary) in the vmlist
        vmlist = self._namecomplete(vmlist, cluster, eid)
        # check that the vms specified don't already exist
self._check_vmlist(vmlist, isin=True)
        vmlist = self._get_vm_names_to_start(vmlist, cluster, prefix,
vmrange, eid)
        # controller handles eid from kw, so add it
        if eid:
            kw['eid'] = eid
        if dryrun:
            d = UsherResult('dryrun', msg = 'started:' + linesep +
            return d
            if vmlist:
                d = self.aref.callRemote("start", vmlist, dlist, **kw)
                d.addErrback(self._handle_err, misc.whoami())
                raise UsherInvalidInputEx( "No VMs started.  No unique VMs
specified in command")
            return d
        except pb.DeadReferenceError, ex: raise UsherPBDeadRefEx

in my script I have to use connect method and then I have to do some
operations first of calling the start method
1) start connection

    def startConnection(self):
        d = my_api.connect(self.ctrl_ip, self.ctrl_port, self.user,
        print "Connection added"
        return d
2) operation before starting a virtual machine:
def newVMCfg(self, new_vms_cfg):
       #some operations
       #if condition valid I try to start the virtual machine
                        # is this the correct way to pass args to the start
                        d = self.d.addCallback(self.startVM,(new_vm,
                        print "started vm %s"%new_vm
        return d

in the main process I call them as:
d = startConnection()
d.addCallback(newVMCfg, arg)

Is it correct? Because the process stops at the first method called: I see
only "connection added".
Thank you for your help!!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://twistedmatrix.com/pipermail/twisted-python/attachments/20090511/cdc0700d/attachment.htm 

More information about the Twisted-Python mailing list