[tahoe-dev] [tahoe-lafs] #1159: make it possible to change appname, Python package-directory name, perhaps other names
tahoe-lafs
trac at tahoe-lafs.org
Wed Oct 27 22:35:53 UTC 2010
#1159: make it possible to change appname, Python package-directory name, perhaps
other names
----------------------------+-----------------------------------------------
Reporter: davidsarah | Owner: somebody
Type: defect | Status: new
Priority: major | Milestone: eventually
Component: code | Version: 1.8β
Resolution: | Keywords: test-needed backward-compatibility forward-compatibility
Launchpad Bug: |
----------------------------+-----------------------------------------------
Comment (by warner):
Re .tac files:
It's probably time for them to die. When I wrote the very first
get-a-client-running framework (30-Nov-2006, wow), I copied the scheme I'd
used in buildbot, since it was an easy way to get a daemon process
running.
The original idea of .tac files (and .tap and .tax files, their black-
sheep
siblings) was to decouple the implementation of a service from the
deployment. From a developer's point of view, it's pretty easy to create a
service in the Twisted world: you make a subclass of
{{{twisted.application.service.Service}}}, override
{{{startService}}}/{{{stopService}}} to control startup/shutdown, and
connect
other services in a tree shape with {{{setServiceParent}}}.
To actually start this, the cheap "{{{__main__}}}" way is to use
{{{service.startService(); reactor.run()}}}, and the cheap way to
configure
it is to pass arguments into your service's constructor. But ops folks
(or,
you know, *users*) who want to run your service don't want to write python
code. And they might want to configure the service without writing python
code.
The "official" way to do this, at least as of 2006, was a Twisted tool
named
'{{{mktap}}}'. This uses plugins (which you write just after you write
your
Service subclass) to transform command-line arguments (a
twisted.python.usage.Usage instance) into a fully-configured Service
instance, and then serializes (with {{{pickle}}}) the Service out into a
.tap
file. Then, later, you use '{{{twistd foo.tap}}}' to thaw out the Service
and
start it running (properly daemonized and setuided and all). {{{twistd}}}
would also serialize the Service object when you quit the process, so you
could achieve persistence by running '{{{twistd foo-shutdown.tap}}}' on
subsequent runs.
Eventually {{{twistd}}} learned how to use the {{{mktap}}} plugins
directly,
so I think you can run {{{twistd web --path .}}} to do the same thing as
{{{mktap web --path . ; twistd web.tap}}} but without the leftover .tap
file.
But, pickle files are a drag, and the auto-persistence -shutdown.tap
feature
turned out to be a bad idea. Once you stop using pickle, then having a
non-human-readable configuration/deployment file is a drag. So .tac (which
is
a python program that provides a distinguished 'application' symbol, and
is
evaluated by {{{twistd}}}) becomes reasonable.
Anyways, the benefit of writing out a .tac file is that you could use the
generic {{{twistd}}} to launch the service (assuming that everything is on
your PYTHONPATH), which gives you a bunch of maybe-useful options for
free:
{{{--syslog, --profile, --rundir, --chroot, --uid, --reactor}}}. There are
also some tools which make it easy to launch twistd-style jobs from
{{{/etc/init.d/}}} initscripts, or from mac {{{LaunchAgent}}} plists.
But, now that twistd is invokable as a library, it's easier to get those
free
arguments without needing to duplicate them all in the '{{{tahoe start}}}'
option parser. If we commit to having {{{bin/tahoe}}} be the only way to
launch tahoe, then it can set up {{{sys.path}}} before importing
{{{twisted.scripts.twistd}}}.
So maybe what's left is to define a data file (perhaps named
{{{client.tac}}}, for backwards compatibility), from which {{{tahoe
start}}}
can determine that it ought to instantiate an
{{{allmydata.client.Client}}}
instead of an {{{allmydata.introducer.IntroducerNode}}}. And then change
{{{tahoe start}}} to do whatever {{{pkg_resources.require}}} might really
really be necessary before scanning the data file and doing the
conditional
import.
Or maybe {{{tahoe start}}} could look for "tahoe.cfg" to decide if the
target
directory is really a tahoe nodedir, look either for a key in it or the
presence of {{{client.tac}}}/{{{introducer.tac}}} to decide what top-level
Service to instantiate, but then otherwise ignore the .tac file. And new
versions of {{{tahoe create-node}}} could write the {{{nodetype=}}} key
into
tahoe.cfg and *not* write the .tac file.
--
Ticket URL: <http://tahoe-lafs.org/trac/tahoe-lafs/ticket/1159#comment:11>
tahoe-lafs <http://tahoe-lafs.org>
secure decentralized storage
More information about the tahoe-dev
mailing list