Alien-SVN
view release on metacpan or search on metacpan
src/subversion/tools/dist/collect_sigs.py view on Meta::CPAN
#!/usr/bin/env python
#
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
#
# A script intended to be useful in helping to collect signatures for a
# release. This is a pretty rough, and patches are welcome to improve it.
#
# Some thoughts about future improvement:
# * Display of per-file and per-release statistics
# * Make use of the python-gpg package (http://code.google.com/p/python-gnupg/)
# * Post to IRC when a new signature is collected
# - Since we don't want to have a long running bot, perhaps we could
# also patch wayita to accept and then echo a privmsg?
# * Mail dev@ when somebody submits a successful signature, and include a
# comments field which could be included in the mail.
# * Use a subversion repository instead of sqlite backend
# - no need to re-invent storage and retrieval
# - perhaps we could re-use existing CIA/mailer hooks?
#
import sys, os
import sqlite3
def make_config():
'Output a blank config file'
if os.path.exists('config.py'):
print "'config.py' already exists!'"
sys.exit(1)
conf = open('config.py', 'w')
conf.write("version = ''\n")
conf.write("sigdir = ''\n")
conf.write("filesdir = ''\n")
conf.close()
print "'config.py' generated"
def make_db():
'Initialize a blank database'
db = sqlite3.connect('sigs.db')
db.execute('''
CREATE TABLE signatures (
keyid TEXT, filename TEXT, signature BLOB,
UNIQUE(keyid,filename)
);
''');
# This function is web-facing
def generate_asc_files(target_dir='.'):
fds = {}
def _open(filename):
if not fds.has_key(filename):
fd = open(os.path.join(target_dir, filename + '.asc'), 'w')
fds[filename] = fd
return fds[filename]
db = sqlite3.connect(os.path.join(target_dir, 'sigs.db'))
curs = db.cursor()
like_filename = 'subversion-%s.%%' % config.version
curs.execute('''SELECT filename, signature FROM signatures
WHERE filename LIKE ?''', (like_filename, ) )
for filename, signature in curs:
fd = _open(filename)
fd.write(signature)
for fd in fds.values():
fd.flush()
fd.close()
src/subversion/tools/dist/collect_sigs.py view on Meta::CPAN
<p>This page is used to collect <a href="%s/list">signatures</a> for the
proposed release of Apache Subversion $version.</p>
$content
</body>
</html>
''' % os.getenv('SCRIPT_NAME')
signature_area = '''
<hr/>
<form method="post" action="%s">
<p>Paste one or more signatures in the area below:<br/>
<textarea name="signatures" rows="20" cols="80"></textarea>
</p>
<input type="submit" value="Submit" />
<p>Any text not between the <tt>BEGIN PGP SIGNATURE</tt>
and <tt>END PGP SIGNATURE</tt> lines will be ignored.</p>
</form>
<hr/>
''' % os.getenv('SCRIPT_NAME')
def split(sigs):
lines = []
for line in sigs.split('\n'):
if lines or '--BEGIN' in line:
lines.append(line)
if '--END' in line:
yield "\n".join(lines) + "\n"
lines = []
def list_signatures():
db = sqlite3.connect(os.path.join(config.sigdir, 'sigs.db'))
template = '''
<hr/>
<p>The following signature files are available:</p>
<p>%s</p>
'''
lines = ""
curs = db.cursor()
like_filename = 'subversion-%s.%%' % config.version
curs.execute('''SELECT filename, COUNT(*) FROM signatures
WHERE filename LIKE ?
GROUP BY filename ORDER BY filename''',
(like_filename, ) )
for filename, count in curs:
lines += '<a href="%s/%s.asc">%s.asc</a>: %d signature%s<br/>\n' \
% (os.getenv('SCRIPT_NAME'), filename, filename,
count, ['s', ''][count == 1])
return (template % lines) + signature_area
def save_valid_sig(db, filename, keyid, signature):
db.execute('INSERT OR REPLACE INTO signatures VALUES (?,?,?);',
(keyid, filename, buffer(signature)))
db.commit()
generate_asc_files(config.sigdir)
def verify_sig_for_file(signature, filename):
args = ['gpg', '--logger-fd', '1', '--no-tty',
'--status-fd', '2', '--verify', '-',
os.path.join(config.filesdir, filename)]
gpg = subprocess.Popen(args,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
gpg.stdin.write(signature)
gpg.stdin.close()
rc = gpg.wait()
output = gpg.stdout.read()
status = gpg.stderr.read()
if rc:
return (False, status + output)
lines = status.split('\n')
for line in lines:
match = r.search(line)
if match:
keyid = match.group(1)
user = match.group(2)
return (True, (filename, keyid, user))
def verify_sig(signature):
all_failures = ""
for filename in files():
(verified, result) = verify_sig_for_file(signature, filename)
if verified:
return (verified, result)
else:
all_failures += "%s:\n[[[\n%s]]]\n\n" % (filename, result)
return (False, all_failures)
def process_sigs(signatures):
success = '''
<p style="color: green;">All %d signatures verified!</p>
'''
failure = '''
<p style="color: red;">%d of %d signatures failed to verify; details below.</p>
'''
c_verified = '''
<p style="color: green;">The signature is verified!</p>
<p>Filename: <code>%s</code></p>
<p>Key ID: <code>%s</code></p>
<p>User: <code>%s</code></p>
<p>This signature has been saved, and will be included as part of the
release signatures.</p>
'''
c_unverified = '''
<p style="color: red;">The signature was not able to be verified!</p>
<p>Signature: <pre>%s</pre></p>
<p>Reason:</p><pre>%s</pre>
<p>Please talk to the release manager if this is in error.</p>
'''
outcomes = []
N_sigs = 0
N_verified = 0
retval = ''
# Verify
db = sqlite3.connect(os.path.join(config.sigdir, 'sigs.db'))
for signature in split(signatures):
N_sigs += 1
(verified, result) = verify_sig(signature)
outcomes.append((verified, result))
if verified:
(filename, keyid, user) = result
save_valid_sig(db, filename, keyid, signature)
( run in 0.599 second using v1.01-cache-2.11-cpan-df04353d9ac )