1
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
2
# See LICENSE for details.
6
from zope.interface import implements
8
from twisted.application import service, app
9
from twisted.persisted import sob
10
from twisted.python import usage, util, plugin as oldplugin
11
from twisted import plugin as newplugin
14
IServiceMaker = service.IServiceMaker
20
"mktap is obsolete as of Twisted 2.5, and will be officially deprecated "
21
"in Twisted 2.6. Use Twisted Application Plugins with the "
22
"'twistd' command directly, as described in "
23
"'Writing a Twisted Application Plugin for twistd' chapter of the "
24
"Developer Guide.", PendingDeprecationWarning)
41
uid = pwd.getpwnam(uid)[2]
46
gid = grp.getgrnam(gid)[2]
50
def loadPlugins(debug = None, progress = None):
53
plugins = oldplugin._getPlugIns("tap", debug, progress)
55
if hasattr(plug, 'tapname'):
56
shortTapName = plug.tapname
58
shortTapName = plug.module.split('.')[-1]
59
tapLookup[shortTapName] = plug
61
plugins = newplugin.getPlugins(IServiceMaker)
63
tapLookup[plug.tapname] = plug
67
def addToApplication(ser, name, append, procname, type, encrypted, uid, gid):
68
if append and os.path.exists(append):
69
a = service.loadApplication(append, 'pickle', None)
71
a = service.Application(name, uid, gid)
73
service.IProcess(a).processName = procname
74
ser.setServiceParent(service.IServiceCollection(a))
75
sob.IPersistable(a).setStyle(type)
76
passphrase = app.getSavePassphrase(encrypted)
79
sob.IPersistable(a).save(filename=append, passphrase=passphrase)
81
class FirstPassOptions(usage.Options):
82
synopsis = """Usage: mktap [options] <command> [command options] """
88
['uid', 'u', None, "The uid to run as."],
89
['gid', 'g', None, "The gid to run as."],
91
"An existing .tap file to append the plugin to, rather than "
92
"creating a new one."],
93
['type', 't', 'pickle',
94
"The output format to use; this can be 'pickle', 'xml', "
96
['appname', 'n', None, "The process name to use for this application."]
100
['encrypted', 'e', "Encrypt file before writing "
101
"(will make the extension of the resultant "
102
"file begin with 'e')"],
103
['debug', 'd', "Show debug information for plugin loading"],
104
['progress', 'p', "Show progress information for plugin loading"],
105
['help', 'h', "Display this message"],
107
#zsh_altArgDescr = {"foo":"use this description for foo instead"}
108
#zsh_multiUse = ["foo", "bar"]
109
#zsh_mutuallyExclusive = [("foo", "bar"), ("bar", "baz")]
110
zsh_actions = {"append":'_files -g "*.tap"',
111
"type":"(pickle xml source)"}
112
zsh_actionDescr = {"append":"tap file to append to", "uid":"uid to run as",
113
"gid":"gid to run as", "type":"output format"}
115
def init(self, tapLookup):
117
for (name, module) in tapLookup.iteritems():
118
if IServiceMaker.providedBy(module):
120
name, None, lambda m=module: m.options(), module.description))
123
name, None, lambda obj=module: obj.load().Options(),
124
getattr(module, 'description', '')))
127
self.subCommands = sc
129
def parseArgs(self, *rest):
132
def _reportDebug(self, info):
133
print 'Debug: ', info
135
def _reportProgress(self, info):
138
print '\rProgress: ', s,
140
print '\r' + (' ' * 79) + '\r',
142
def postOptions(self):
145
debug = progress = None
147
debug = self._reportDebug
149
progress = self._reportProgress
150
self.pb = util.makeStatBar(60, 1.0)
152
self.tapLookup = loadPlugins(debug, progress)
154
raise usage.UsageError("Couldn't load the plugins file!")
155
self.init(self.tapLookup)
157
self.parseOptions(self.params)
158
if not hasattr(self, 'subOptions') or self['help']:
159
raise usage.UsageError(str(self))
160
if hasattr(self, 'subOptions') and self.subOptions.get('help'):
161
raise usage.UsageError(str(self.subOptions))
162
if not self.tapLookup.has_key(self.subCommand):
163
raise usage.UsageError("Please select one of: "+
164
' '.join(self.tapLookup))
168
options = FirstPassOptions()
170
options.parseOptions(sys.argv[1:])
171
except usage.UsageError, e:
174
except KeyboardInterrupt:
177
plg = options.tapLookup[options.subCommand]
178
if not IServiceMaker.providedBy(plg):
180
ser = plg.makeService(options.subOptions)
181
addToApplication(ser,
182
options.subCommand, options['append'], options['appname'],
183
options['type'], options['encrypted'],
184
*getid(options['uid'], options['gid']))
186
from twisted.python.reflect import namedAny
187
from twisted.plugin import IPlugin
189
class _tapHelper(object):
191
Internal utility class to simplify the definition of \"new-style\"
192
mktap plugins based on existing, \"classic\" mktap plugins.
195
implements(IPlugin, IServiceMaker)
197
def __init__(self, name, module, description, tapname):
200
self.description = description
201
self.tapname = tapname
205
return namedAny(self.module).Options
207
options = property(*options())
211
return namedAny(self.module).makeService
213
makeService = property(*makeService())