1
# -*- test-case-name: twisted.scripts.test.test_mktap -*-
2
# Copyright (c) 2001-2008 Twisted Matrix Laboratories.
3
# See LICENSE for details.
5
import warnings, sys, os
8
from twisted.application import service, app
9
from twisted.persisted import sob
10
from twisted.python import usage, util
11
from twisted import plugin
12
from twisted.python.util import uidFromString, gidFromString
15
IServiceMaker = service.IServiceMaker
16
_tapHelper = service.ServiceMaker
19
"mktap and related support modules are deprecated as of Twisted 8.0. "
20
"Use Twisted Application Plugins with the 'twistd' command directly, "
21
"as described in 'Writing a Twisted Application Plugin for twistd' "
22
"chapter of the Developer Guide.", DeprecationWarning, stacklevel=2)
28
Convert one or both of a string representation of a UID and GID into
29
integer form. On platforms where L{pwd} and L{grp} is available, user and
30
group names can be converted.
32
@type uid: C{str} or C{NoneType}
33
@param uid: A string giving the base-ten representation of a UID or the
34
name of a user which can be converted to a UID via L{pwd.getpwnam},
35
or None if no UID value is to be obtained.
37
@type gid: C{str} or C{NoneType}
38
@param uid: A string giving the base-ten representation of a GID or the
39
name of a group which can be converted to a GID via
40
L{grp.getgrnam}, or None if no UID value is to be obtained.
42
@return: A two-tuple giving integer UID and GID information for
43
whichever (or both) parameter is provided with a non-C{None} value.
45
@raise ValueError: If a user or group name is supplied and L{pwd} or L{grp}
49
uid = uidFromString(uid)
51
gid = gidFromString(gid)
56
def loadPlugins(debug = None, progress = None):
59
plugins = plugin.getPlugins(IServiceMaker)
61
tapLookup[plug.tapname] = plug
65
def addToApplication(ser, name, append, procname, type, encrypted, uid, gid):
66
if append and os.path.exists(append):
67
a = service.loadApplication(append, 'pickle', None)
69
a = service.Application(name, uid, gid)
71
service.IProcess(a).processName = procname
72
ser.setServiceParent(service.IServiceCollection(a))
73
sob.IPersistable(a).setStyle(type)
74
passphrase = app.getSavePassphrase(encrypted)
77
sob.IPersistable(a).save(filename=append, passphrase=passphrase)
79
class FirstPassOptions(usage.Options):
80
synopsis = """Usage: mktap [options] <command> [command options] """
86
['uid', 'u', None, "The uid to run as.", uidFromString],
87
['gid', 'g', None, "The gid to run as.", gidFromString],
89
"An existing .tap file to append the plugin to, rather than "
90
"creating a new one."],
91
['type', 't', 'pickle',
92
"The output format to use; this can be 'pickle', 'xml', "
94
['appname', 'n', None, "The process name to use for this application."]
98
['encrypted', 'e', "Encrypt file before writing "
99
"(will make the extension of the resultant "
100
"file begin with 'e')"],
101
['debug', 'd', "Show debug information for plugin loading"],
102
['progress', 'p', "Show progress information for plugin loading"],
103
['help', 'h', "Display this message"],
105
#zsh_altArgDescr = {"foo":"use this description for foo instead"}
106
#zsh_multiUse = ["foo", "bar"]
107
#zsh_mutuallyExclusive = [("foo", "bar"), ("bar", "baz")]
108
zsh_actions = {"append":'_files -g "*.tap"',
109
"type":"(pickle xml source)"}
110
zsh_actionDescr = {"append":"tap file to append to", "uid":"uid to run as",
111
"gid":"gid to run as", "type":"output format"}
113
def init(self, tapLookup):
115
for (name, module) in tapLookup.iteritems():
116
if IServiceMaker.providedBy(module):
118
name, None, lambda m=module: m.options(), module.description))
121
name, None, lambda obj=module: obj.load().Options(),
122
getattr(module, 'description', '')))
125
self.subCommands = sc
127
def parseArgs(self, *rest):
130
def _reportDebug(self, info):
131
print 'Debug: ', info
133
def _reportProgress(self, info):
136
print '\rProgress: ', s,
138
print '\r' + (' ' * 79) + '\r',
140
def postOptions(self):
143
debug = progress = None
145
debug = self._reportDebug
147
progress = self._reportProgress
148
self.pb = util.makeStatBar(60, 1.0)
150
self.tapLookup = loadPlugins(debug, progress)
152
raise usage.UsageError("Couldn't load the plugins file!")
153
self.init(self.tapLookup)
155
self.parseOptions(self.params)
156
if not hasattr(self, 'subOptions') or self['help']:
157
raise usage.UsageError(str(self))
158
if hasattr(self, 'subOptions') and self.subOptions.get('help'):
159
raise usage.UsageError(str(self.subOptions))
160
if not self.tapLookup.has_key(self.subCommand):
161
raise usage.UsageError("Please select one of: "+
162
' '.join(self.tapLookup))
166
options = FirstPassOptions()
168
options.parseOptions(sys.argv[1:])
169
except usage.UsageError, e:
172
except KeyboardInterrupt:
175
plg = options.tapLookup[options.subCommand]
176
if not IServiceMaker.providedBy(plg):
178
ser = plg.makeService(options.subOptions)
179
addToApplication(ser,
180
options.subCommand, options['append'], options['appname'],
181
options['type'], options['encrypted'],
182
options['uid'], options['gid'])