Rev 63: Add pyftpdlib support, not all bzr tests passing. in file:///net/bigmamac/Volumes/home/vila/.bazaar/plugins/local_test_server/
Vincent Ladeuil
v.ladeuil+lp at free.fr
Thu Feb 26 15:09:38 GMT 2009
At file:///net/bigmamac/Volumes/home/vila/.bazaar/plugins/local_test_server/
------------------------------------------------------------
revno: 63
revision-id: v.ladeuil+lp at free.fr-20090226150932-nfi7723hshm9f2x2
parent: v.ladeuil+lp at free.fr-20090225122349-pmbzis0scoqtf7bo
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: local_test_server
timestamp: Thu 2009-02-26 16:09:32 +0100
message:
Add pyftpdlib support, not all bzr tests passing.
* tests/test_utils.py:
(full_scenarios): Add scenario for pyftpdlib.
* test_server.py:
(PyftpdlibFeature): New class.
(Muddleftpd.tearDown): Oops, forgot to delete the symlink.
(Pyftpdlib): Test server serving '/' for anonymous ftp.
* server.py:
(Server._start_by_spawning): Factored out from Vsftpd._start.
(Vsftpd._start): Simplified.
(Pyftpdlib): Spawn a pyftpdlib FTP server.
* configs/pyftpdlib.conf:
Rough configuration options.
* config.py:
(Pyftpdlib): New class.
* bin/pyftpdlib:
Wrapper to start a pyftpdlib FTP server.
-------------- next part --------------
=== added directory 'bin'
=== added file 'bin/pyftpdlib'
--- a/bin/pyftpdlib 1970-01-01 00:00:00 +0000
+++ b/bin/pyftpdlib 2009-02-26 15:09:32 +0000
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+
+import sys
+from pyftpdlib import ftpserver
+
+class AnonymousWithWriteAccessAuthorizer(ftpserver.DummyAuthorizer):
+
+ def _check_permissions(self, username, perm):
+ # Like base implementation but don't warn about write permissions
+ # assigned to anonynous, since that exactly our purpose.
+ for p in perm:
+ if p not in self.read_perms + self.write_perms:
+ raise ftpserver.AuthorizerError('No such permission "%s"' %p)
+
+
+def start_server(conf):
+ authorizer = AnonymousWithWriteAccessAuthorizer()
+ authorizer.add_user('anonymous', None, '/', perm='elradfmw')
+ ftpserver.FTPHandler.authorizer = authorizer
+ address = (conf['host'], conf['port'])
+ ftpd = ftpserver.FTPServer(address, ftpserver.FTPHandler)
+ log_file = open(conf['log_file'], 'w')
+ def do_log(msg):
+ log_file.write(msg + '\n')
+ log_file.flush()
+
+ ftpserver.log = ftpserver.logline = ftpserver.logerror = do_log
+ try:
+ ftpd.serve_forever()
+ finally:
+ log_file_close()
+
+def main():
+ conf_path = sys.argv[1]
+ conf = {}
+ conf_file = open(conf_path)
+ try:
+ for l in conf_file:
+ l = l.rstrip('\n')
+ # Strip comments
+ comment_start = l.find('#')
+ if comment_start >= 0: l = l[:comment_start]
+ # Ignore empty line
+ if not l: continue
+ key, value = l.split(None, 1)
+ conf[key] = value
+ finally:
+ conf_file.close()
+ conf['port'] = int(conf['port'])
+ start_server(conf)
+
+
+main()
=== modified file 'config.py'
--- a/config.py 2009-02-25 12:23:49 +0000
+++ b/config.py 2009-02-26 15:09:32 +0000
@@ -191,5 +191,6 @@
_required_dirs = Config._required_dirs + ('var/lock',)
-
-
+class Pyftpdlib(Config):
+
+ name = 'pyftpdlib'
=== added file 'configs/pyftpdlib.conf'
--- a/configs/pyftpdlib.conf 1970-01-01 00:00:00 +0000
+++ b/configs/pyftpdlib.conf 2009-02-26 15:09:32 +0000
@@ -0,0 +1,17 @@
+# pyftpdlib configuration
+
+# each line is key<space(s)>value
+
+server_name %(server_name)s
+base_dir %(base_dir)s
+host %(host)s
+port %(port)s
+pid_file %(pid_file)s
+log_file %(log_file)s
+
+user %(user)s
+
+etc_dir %(etc_dir)s
+var_run_dir %(var_run_dir)s
+var_log_dir %(var_log_dir)s
+data_dir %(data_dir)s
=== modified file 'server.py'
--- a/server.py 2009-02-24 21:15:01 +0000
+++ b/server.py 2009-02-26 15:09:32 +0000
@@ -18,6 +18,8 @@
The classes described here provide an interface with the real servers.
"""
+import sys
+
try:
import kerberos
has_kerberos = True
@@ -156,9 +158,9 @@
def start(self):
if self.is_running():
raise LTSAlreadyRunningError(self)
+ self.config.ensure_required_dirs_exist()
# Create the config to be used by the real server
infile = open(self.config.config_path)
- self.config.ensure_required_dirs_exist()
outfile = open(self.output_config_path, 'wt')
try:
self.config.expand(infile, outfile)
@@ -388,6 +390,27 @@
self, extra='%s returned non-zero exit status %d'
% (apparent_cmd_name, retcode))
+ def _start_by_spawning(self, cmd_args, apparent_cmd_name=None,
+ create_pid_file=True):
+ """Start the server by spawning a command without waiting.
+
+ A failure to execute the command is fatal.
+ The pid file is created on request.
+ """
+ if apparent_cmd_name is None:
+ apparent_cmd_name = cmd_args[0]
+ proc = subprocess.Popen(cmd_args)
+ if proc.returncode is not None:
+ raise LTSCantStartError(
+ self, 'return code: %s, while spawing %s'
+ % (proc.returncode, apparent_cmd_name))
+ if create_pid_file:
+ f = open(self.get_config_value('pid_file'), 'w')
+ try:
+ f.write('%s' % proc.pid)
+ finally:
+ f.close()
+
class Apache2(Server):
@@ -628,15 +651,8 @@
# goes wrong during server launch... There is nothing in the log to get
# confirmation that the start went right, the log file itself is not
# created before the first connection :-/
- proc = subprocess.Popen([self._server_command_name,
+ self._start_by_spawning([self._server_command_name,
self.output_config_path])
- if proc.returncode is not None:
- raise LTSCantStartError(self, 'return code: %s' % proc.returncode)
- f = open(self.get_config_value('pid_file'), 'w')
- try:
- f.write('%s' % proc.pid)
- finally:
- f.close()
def _stop(self):
if not self._wait_for_server_process_death():
@@ -741,6 +757,36 @@
raise LTSCantStopError(self)
+class Pyftpdlib(Server):
+
+ def __init__(self, port, conf=None):
+ if conf is None:
+ conf = config.Pyftpdlib()
+ super(Pyftpdlib, self).__init__(port, conf)
+ self.output_config_path = self.config.abspath('etc/pyftpdlib.conf')
+ # Be sure to use the currently running python
+ self._server_command_name = sys.executable
+
+ def is_installed(self):
+ try:
+ import pyftpdlib.ftpserver
+ return True
+ except ImportError:
+ return False
+
+ def _start(self):
+ self._start_by_spawning([self._server_command_name,
+ config.get_lts_path('bin/pyftpdlib'),
+ self.output_config_path],
+ apparent_cmd_name='pyftpdlib')
+
+ def _stop(self):
+ if not self._wait_for_server_process_death():
+ raise LTSCantStopError(self)
+ # We need to delete the pid file ourselves
+ osutils.delete_any(self.get_config_value('pid_file'))
+
+
# For self tests we use a range of unassigned port numbers as described
# in http://www.iana.org/assignments/port-numbers
# We use the 29168-30000 range
@@ -787,6 +833,7 @@
_servers['proftpd'] = Proftpd(25018)
_servers['apache2-https'] = Apache2HTTPS(25019)
_servers['muddleftpd'] = Muddleftpd(25020)
+_servers['pyftpdlib'] = Pyftpdlib(25021)
def get_server(name):
=== modified file 'test_server.py'
--- a/test_server.py 2009-02-23 17:00:14 +0000
+++ b/test_server.py 2009-02-26 15:09:32 +0000
@@ -120,6 +120,11 @@
_server_name = 'muddleftpd'
+class PyftpdlibFeature(LocalTestServerFeature):
+
+ _server_name = 'pyftpdlib'
+
+
class LocalTestServer(transport.Server):
# Must be set by daughter classes
@@ -345,6 +350,12 @@
super(Muddleftpd, self).setUp(backing_transport_server)
self._build_symlink_under_data_dir()
+ def tearDown(self):
+ """See bzrlib.transport.Server.tearDown."""
+ super(Muddleftpd, self).tearDown()
+ data_dir = self._server.get_config_value('data_dir')
+ osutils.delete_any(osutils.pathjoin(data_dir, self._symlink_name))
+
def _build_base_url(self):
user = 'anonymous'
return '%s://%s@%s:%s/' % (self._url_protocol, user,
@@ -355,6 +366,20 @@
return self._base_url + self._symlink_name
+class Pyftpdlib(LocalFTPTestServer):
+
+ _server_name = 'pyftpdlib'
+
+ def _build_base_url(self):
+ user = 'anonymous'
+ return '%s://%s@%s:%s' % (self._url_protocol, user,
+ self.host, self.port)
+
+ def get_url(self):
+ """See bzrlib.transport.Server.get_url."""
+ return self._base_url + self._test_working_dir
+
+
# We have registered a transport for the purpose of adding new servers in the
# test permutations. Registering a transport makes our module appears in the
# list which is queried for a get_test_permutations function.
@@ -422,4 +447,7 @@
if MuddleftpdFeature().available():
permutations.append((FtpTransport, Muddleftpd))
+ if PyftpdlibFeature().available():
+ permutations.append((FtpTransport, Pyftpdlib))
+
return permutations
=== modified file 'tests/test_utils.py'
--- a/tests/test_utils.py 2009-02-23 13:12:18 +0000
+++ b/tests/test_utils.py 2009-02-26 15:09:32 +0000
@@ -174,6 +174,13 @@
_server_feature_class=test_server.MuddleftpdFeature,
_test_server_class=test_server.Muddleftpd,
)),
+ ('pyftpdlib', dict(
+ _server_name='pyftpdlib',
+ _config_class=config.Pyftpdlib,
+ _server_class=server.Pyftpdlib,
+ _server_feature_class=test_server.PyftpdlibFeature,
+ _test_server_class=test_server.Pyftpdlib,
+ )),
]
return scenarios
More information about the bazaar-commits
mailing list