versioning: include an "appname" in the application version string in the versioning protocol, and make that appname be controlled by setup.py

It is currently hardcoded in setup.py to be 'allmydata-tahoe'.  Ticket #556 is to make it configurable by a runtime command-line argument to setup.py: "--appname=foo", but I suddenly wondered if we really wanted that and at the same time realized that we don't need that for tahoe-1.3.0 release, so this patch just hardcodes it in setup.py.
setup.py inspects a file named 'src/allmydata/_appname.py' and assert that it contains the string "__appname__ = 'allmydata-tahoe'", and creates it if it isn't already present.  src/allmydata/__init__.py import _appname and reads __appname__ from it.  The rest of the Python code imports allmydata and inspects "allmydata.__appname__", although actually every use it uses "allmydata.__full_version__" instead, where "allmydata.__full_version__" is created in src/allmydata/__init__.py to be:

__full_version__ = __appname + '-' + str(__version__).

All the code that emits an "application version string" when describing what version of a protocol it supports (introducer server, storage server, upload helper), or when describing itself in general (introducer client), usese allmydata.__full_version__.

This fixes ticket #556 at least well enough for tahoe-1.3.0 release.
This commit is contained in:
Zooko O'Whielacronx 2009-02-11 17:18:16 -07:00
parent 5a21cecd67
commit 7eb260a9cf
9 changed files with 41 additions and 16 deletions

View File

@ -302,7 +302,20 @@ class MySdist(sdist.sdist):
# _auto_deps.install_requires list, which is used in the call to setup() below. # _auto_deps.install_requires list, which is used in the call to setup() below.
from _auto_deps import install_requires from _auto_deps import install_requires
setup(name='allmydata-tahoe', APPNAME='allmydata-tahoe'
APPNAMEFILE = os.path.join('src', 'allmydata', '_appname.py')
APPNAMEFILESTR = "__appname__ = '%s'" % (APPNAME,)
try:
curappnamefilestr = open(APPNAMEFILE, 'rU').read()
except EnvironmentError:
# No file, or unreadable or something, okay then let's try to write one.
open(APPNAMEFILE, "w").write(APPNAMEFILESTR)
else:
if curappnamefilestr.strip() != APPNAMEFILESTR:
print "Error -- this setup.py file is configured with the 'application name' to be '%s', but there is already a file in place in '%s' which contains the contents '%s'. If the file is wrong, please remove it and setup.py will regenerate it and write '%s' into it." % (APPNAME, APPNAMEFILE, curappnamefilestr, APPNAMEFILESTR)
sys.exit(-1)
setup(name=APPNAME,
description='secure, decentralized, fault-tolerant filesystem', description='secure, decentralized, fault-tolerant filesystem',
long_description=LONG_DESCRIPTION, long_description=LONG_DESCRIPTION,
author='the allmydata.org Tahoe project', author='the allmydata.org Tahoe project',

View File

@ -15,6 +15,18 @@ except ImportError:
# not happen very often. # not happen very often.
pass pass
__appname__ = "unknown"
try:
from _appname import __appname__
except ImportError:
# We're running in a tree that hasn't run "./setup.py". This shouldn't happen.
pass
# __full_version__ is the one that you ought to use when identifying yourself in the
# "application" part of the Tahoe versioning scheme:
# http://allmydata.org/trac/tahoe/wiki/Versioning
__full_version__ = __appname__ + '-' + str(__version__)
hush_pyflakes = __version__ hush_pyflakes = __version__
del hush_pyflakes del hush_pyflakes

View File

@ -115,7 +115,7 @@ class Client(node.Node, pollmixin.PollMixin):
self.introducer_furl = self.get_config("client", "introducer.furl") self.introducer_furl = self.get_config("client", "introducer.furl")
ic = IntroducerClient(self.tub, self.introducer_furl, ic = IntroducerClient(self.tub, self.introducer_furl,
self.nickname, self.nickname,
str(allmydata.__version__), str(allmydata.__full_version__),
str(self.OLDEST_SUPPORTED_VERSION)) str(self.OLDEST_SUPPORTED_VERSION))
self.introducer_client = ic self.introducer_client = ic
# hold off on starting the IntroducerClient until our tub has been # hold off on starting the IntroducerClient until our tub has been

View File

@ -5,7 +5,7 @@ from twisted.application import service
from twisted.internet import defer from twisted.internet import defer
from foolscap import Referenceable, DeadReferenceError from foolscap import Referenceable, DeadReferenceError
from foolscap.eventual import eventually from foolscap.eventual import eventually
import allmydata import allmydata # for __full_version__
from allmydata import interfaces, storage, uri from allmydata import interfaces, storage, uri
from allmydata.immutable import upload from allmydata.immutable import upload
from allmydata.immutable.layout import ReadBucketProxy from allmydata.immutable.layout import ReadBucketProxy
@ -132,7 +132,7 @@ class CHKUploadHelper(Referenceable, upload.CHKUploader):
implements(interfaces.RICHKUploadHelper) implements(interfaces.RICHKUploadHelper)
VERSION = { "http://allmydata.org/tahoe/protocols/helper/chk-upload/v1" : VERSION = { "http://allmydata.org/tahoe/protocols/helper/chk-upload/v1" :
{ }, { },
"application-version": str(allmydata.__version__), "application-version": str(allmydata.__full_version__),
} }
def __init__(self, storage_index, helper, def __init__(self, storage_index, helper,
@ -492,7 +492,7 @@ class Helper(Referenceable, service.MultiService):
name = "helper" name = "helper"
VERSION = { "http://allmydata.org/tahoe/protocols/helper/v1" : VERSION = { "http://allmydata.org/tahoe/protocols/helper/v1" :
{ }, { },
"application-version": str(allmydata.__version__), "application-version": str(allmydata.__full_version__),
} }
chk_upload_helper_class = CHKUploadHelper chk_upload_helper_class = CHKUploadHelper
MAX_UPLOAD_STATUSES = 10 MAX_UPLOAD_STATUSES = 10

View File

@ -49,7 +49,7 @@ class IntroducerService(service.MultiService, Referenceable):
name = "introducer" name = "introducer"
VERSION = { "http://allmydata.org/tahoe/protocols/introducer/v1": VERSION = { "http://allmydata.org/tahoe/protocols/introducer/v1":
{ }, { },
"application-version": str(allmydata.__version__), "application-version": str(allmydata.__full_version__),
} }
def __init__(self, basedir="."): def __init__(self, basedir="."):

View File

@ -1,7 +1,7 @@
from cStringIO import StringIO from cStringIO import StringIO
import urlparse, httplib import urlparse, httplib
import allmydata # for __version__ import allmydata # for __full_version__
# copied from twisted/web/client.py # copied from twisted/web/client.py
def parse_url(url, defaultPort=None): def parse_url(url, defaultPort=None):
@ -44,7 +44,7 @@ def do_http(method, url, body=""):
raise ValueError("unknown scheme '%s', need http or https" % scheme) raise ValueError("unknown scheme '%s', need http or https" % scheme)
c.putrequest(method, path) c.putrequest(method, path)
c.putheader("Hostname", host) c.putheader("Hostname", host)
c.putheader("User-Agent", "tahoe_cli/%s" % allmydata.__version__) c.putheader("User-Agent", "tahoe_cli/%s" % allmydata.__full_version__)
c.putheader("Connection", "close") c.putheader("Connection", "close")
old = body.tell() old = body.tell()

View File

@ -8,7 +8,7 @@ from allmydata.interfaces import RIStorageServer, RIBucketWriter, \
RIBucketReader, BadWriteEnablerError, IStatsProducer RIBucketReader, BadWriteEnablerError, IStatsProducer
from allmydata.util import base32, fileutil, idlib, log, time_format from allmydata.util import base32, fileutil, idlib, log, time_format
from allmydata.util.assertutil import precondition from allmydata.util.assertutil import precondition
import allmydata # for __version__ import allmydata # for __full_version__
class DataTooLargeError(Exception): class DataTooLargeError(Exception):
pass pass
@ -968,7 +968,7 @@ class StorageServer(service.MultiService, Referenceable):
"tolerates-immutable-read-overrun": True, "tolerates-immutable-read-overrun": True,
"delete-mutable-shares-with-zero-length-writev": True, "delete-mutable-shares-with-zero-length-writev": True,
}, },
"application-version": str(allmydata.__version__), "application-version": str(allmydata.__full_version__),
} }
return version return version

View File

@ -174,12 +174,12 @@ class Basic(unittest.TestCase):
ss = c.getServiceNamed("storage") ss = c.getServiceNamed("storage")
verdict = ss.remote_get_version() verdict = ss.remote_get_version()
self.failUnlessEqual(verdict["application-version"], self.failUnlessEqual(verdict["application-version"],
str(allmydata.__version__)) str(allmydata.__full_version__))
self.failIfEqual(str(allmydata.__version__), "unknown") self.failIfEqual(str(allmydata.__version__), "unknown")
self.failUnless("." in str(allmydata.__version__), self.failUnless("." in str(allmydata.__full_version__),
"non-numeric version in '%s'" % allmydata.__version__) "non-numeric version in '%s'" % allmydata.__version__)
all_versions = allmydata.get_package_versions_string() all_versions = allmydata.get_package_versions_string()
self.failUnless("allmydata" in all_versions) self.failUnless("allmydata-tahoe" in all_versions)
log.msg("tahoe versions: %s" % all_versions) log.msg("tahoe versions: %s" % all_versions)
# also test stats # also test stats
stats = c.get_stats() stats = c.get_stats()

View File

@ -7,7 +7,7 @@ from twisted.python import log
from twisted.internet import defer from twisted.internet import defer
from foolscap import eventual from foolscap import eventual
import allmydata import allmydata # for __full_version__
from allmydata import uri, monitor from allmydata import uri, monitor
from allmydata.immutable import upload from allmydata.immutable import upload
from allmydata.interfaces import IFileURI, FileTooLargeError, NotEnoughSharesError from allmydata.interfaces import IFileURI, FileTooLargeError, NotEnoughSharesError
@ -84,12 +84,12 @@ class FakeStorageServer:
self.queries = 0 self.queries = 0
self.version = { "http://allmydata.org/tahoe/protocols/storage/v1" : self.version = { "http://allmydata.org/tahoe/protocols/storage/v1" :
{ "maximum-immutable-share-size": 2**32 }, { "maximum-immutable-share-size": 2**32 },
"application-version": str(allmydata.__version__), "application-version": str(allmydata.__full_version__),
} }
if mode == "small": if mode == "small":
self.version = { "http://allmydata.org/tahoe/protocols/storage/v1" : self.version = { "http://allmydata.org/tahoe/protocols/storage/v1" :
{ "maximum-immutable-share-size": 10 }, { "maximum-immutable-share-size": 10 },
"application-version": str(allmydata.__version__), "application-version": str(allmydata.__full_version__),
} }