Ticket #3292: 3292-tap2rpm-fix.patch

File 3292-tap2rpm-fix.patch, 15.8 KB (added by TimAllen, 5 years ago)

Make tap2rpm work with modern Twisted, attempt 7 (now with news file!)

  • doc/core/howto/basics.xhtml

    diff --git a/doc/core/howto/basics.xhtml b/doc/core/howto/basics.xhtml
    index 30b7048..df27fba 100644
    a b pid (usually you would do <code class="shell">kill `cat twistd.pid`</code>). 
    6060 
    6161<p>As always, the gory details are in the manual page.</p> 
    6262 
    63 <h2>tap2deb</h2> 
     63<h2>OS Integration</h2> 
    6464 
    6565<p> 
    66 For Twisted-based server application developers who want to deploy on 
    67 Debian, Twisted supplies the <code class="shell">tap2deb</code> program. This program 
    68 wraps a Twisted Application file (of any of the supported formats -- Python, 
    69 source, xml or pickle) 
    70 in a Debian package, including correct installation and removal scripts 
    71 and <code>init.d</code> scripts. This frees the installer from manually 
    72 stopping or starting the service, and will make sure it goes properly up 
    73 on startup and down on shutdown and that it obeys the init levels. 
     66If you have an Application that runs with <code class="shell">twistd</code>, 
     67you can easily deploy it on RedHat Linux or Debian GNU/Linux based systems 
     68using the <code class="shell">tap2deb</code> or <code 
     69class="shell">tap2rpm</code> tools. These take a Twisted Application file (of 
     70any of the supported formats — Python source, XML or pickle), and build a 
     71Debian or RPM package (respectively) that installs the Application as a system 
     72service. The package includes the Application file, a default 
     73<code>/etc/init.d/</code> script that starts and stops the process with twistd, 
     74and post-installation scripts that configure the Application to be run in the 
     75appropriate init levels. 
    7476</p> 
    7577 
     78<!-- Is "note" really the right class to be using here? --> 
     79<div class="note"> 
     80<code class="shell">tap2rpm</code> and <code class="shell">tap2deb</code> do 
     81not package your entire application and dependent code, just the Twisted 
     82Application file. You will need to find some other way to package your Python 
     83code, such as <code class="API">distutils</code>' <code>bdist_rpm</code> 
     84command. 
     85</div> 
     86 
    7687<p> 
    77 For the more savvy Debian users, the 
    78 <code class="shell">tap2deb</code> also generates the source package, allowing her 
    79 to modify and polish things which automated software cannot detect 
    80 (such as dependencies or relationships to virtual packages). In addition, 
    81 the Twisted team itself intends to produce Debian packages for some common 
    82 services, such as web servers and an inetd replacement. Those packages 
    83 will enjoy the best of all worlds -- both the consistency which comes 
    84 from being based on the <code class="shell">tap2deb</code> and the delicate manual 
    85 tweaking of a Debian maintainer, insuring perfect integration with 
    86 Debian. 
     88For more savvy users, these tools also generate the source package, allowing 
     89you to modify and polish things which automated software cannot detect (such as 
     90dependencies or relationships to virtual packages). 
    8791</p> 
    8892 
    89 <h2>tap2rpm</h2> 
    90  
    91 <p><code class="shell">tap2rpm</code> is similar to <code class="shell">tap2deb</code>, except that 
    92 it generates RPMs for Redhat and other related platforms.</p> 
    93  
    9493</body></html> 
  • doc/core/howto/tutorial/configuration.xhtml

    diff --git a/doc/core/howto/tutorial/configuration.xhtml b/doc/core/howto/tutorial/configuration.xhtml
    index 70fbf0e..c4e31f7 100644
    a b integration:</p> 
    6464<h3>Red Hat / Mandrake</h3> 
    6565 
    6666<pre class="shell"> 
    67 % tap2rpm --type=python finger.tac #[maybe other options needed] 
    68 % sudo rpm -i .build/*.rpm 
     67% tap2rpm --type=python finger.tac 
     68% sudo rpm -i *.rpm 
    6969</pre> 
    7070 
    71 <p>Will properly register the tap/tac, init.d scripts, etc. for the given file.</p> 
     71<p>These packages will properly install and register init.d scripts, etc. for 
     72the given file.</p> 
    7273 
    7374<p>If it doesn't work on your favorite OS: patches accepted!</p> 
    7475</body> 
  • doc/core/man/tap2rpm.1

    diff --git a/doc/core/man/tap2rpm.1 b/doc/core/man/tap2rpm.1
    index a406c45..cb279b2 100644
    a b tap2rpm \- create RPM packages which wrap .tap files 
    77.SH DESCRIPTION 
    88Create a set of RPM/SRPM packages in the current directory 
    99.TP 
    10 \fB\-u\fR, \fB\--unsigned\fR  
    11 do not sign the RPM package 
    12 .TP 
    1310\fB\-t\fR, \fB\--tapfile\fR \fI<tapfile>\fR 
    1411Build the application around the given .tap (default twistd.tap) 
    1512.TP 
    this being an automatic package created from tap2rpm. 
    4037.TP 
    4138\fB\-m\fR, \fB\--maintainer\fR \fI<maintainer>\fR 
    4239The maintainer, as "Name Lastname <email address>". This will 
    43 go in the meta-files, as well as be used as the id to sign the package. 
     40go in the meta-files. 
    4441.TP 
    4542\fB\--version\fR 
    4643Output version information and exit. 
    Output version information and exit. 
    4845tap2rpm was written by Sean Reifschneider based on tap2deb by Moshe Zadka. 
    4946This man page is heavily based on the tap2deb man page by Moshe Zadka. 
    5047.SH "REPORTING BUGS" 
    51 To report a bug, visit \fIhttp://twistedmatrix.com/bugs/\fR 
     48To report a bug, visit 
     49\fIhttp://twistedmatrix.com/trac/wiki/TwistedDevelopment#FilingTickets\fR for more 
     50information. 
    5251.SH COPYRIGHT 
    53 Copyright \(co 2000-2008 Twisted Matrix Laboratories. 
     52Copyright \(co 2000-2009 Twisted Matrix Laboratories. 
    5453.br 
    5554This is free software; see the source for copying conditions.  There is NO 
    5655warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
  • twisted/scripts/tap2rpm.py

    diff --git a/twisted/scripts/tap2rpm.py b/twisted/scripts/tap2rpm.py
    index 8a179ee..a3888a7 100755
    a b  
    1 #  based off the tap2deb.py file 
    2 #  tap2rpm.py built by Sean Reifschneider, <jafo@tummy.com> 
     1# -*- test-case-name: twisted.scripts.test.test_tap2rpm -*- 
    32 
    4 #  TODO: need to implement log-file rotation 
     3# Copyright (c) 2003-2009 Twisted Matrix Laboratories. 
     4# See LICENSE for details. 
    55 
    66import sys, os, shutil, time, glob 
    77 
    Summary: %(description)s 
    8888Name:       %(rpm_file)s 
    8989Version:    %(version)s 
    9090Release:    1 
    91 Copyright:  Unknown 
     91License:    Unknown 
    9292Group:      Networking/Daemons 
    9393Source:     %(tarfile_basename)s 
    9494BuildRoot:  /var/tmp/%%{name}-%%{version}-root 
    def makeBuildDir(baseDir): 
    207207 
    208208 
    209209########## 
    210 def run(): 
     210def run(options=None): 
    211211    #  parse options 
    212212    try: 
    213213        config = MyOptions() 
    214         config.parseOptions() 
     214        config.parseOptions(options) 
    215215    except usage.error, ue: 
    216216         sys.exit("%s: %s" % (sys.argv[0], ue)) 
    217217 
    def run(): 
    271271     
    272272    #  remove the build directory 
    273273    shutil.rmtree(tmp_dir) 
     274 
     275    return [ 
     276            os.path.basename(rpm_path), 
     277            os.path.basename(srpm_path), 
     278        ] 
  • new file twisted/scripts/test/test_tap2rpm.py

    diff --git a/twisted/scripts/test/test_tap2rpm.py b/twisted/scripts/test/test_tap2rpm.py
    new file mode 100644
    index 0000000..3544533
    - +  
     1# Copyright (c) 2009 Twisted Matrix Laboratories. 
     2# See LICENSE for details. 
     3 
     4""" 
     5Tests for L{twisted.scripts.tap2rpm}. 
     6""" 
     7from os.path import exists 
     8from twisted.trial.unittest import TestCase, SkipTest 
     9from twisted.python import log 
     10from twisted.internet import utils 
     11from twisted.scripts import tap2rpm 
     12 
     13# When we query the RPM metadata, we get back a string we'll have to parse, so 
     14# we'll use suitably rare delimiter characters to split on. Luckily, ASCII 
     15# defines some for us! 
     16RECORD_SEPARATOR = "\x1E" 
     17UNIT_SEPARATOR   = "\x1F" 
     18 
     19 
     20 
     21def _makeRPMs(tapfile=None, maintainer=None, protocol=None, description=None, 
     22        longDescription=None, setVersion=None, rpmfile=None, type_=None): 
     23    """ 
     24    Helper function to invoke tap2rpm with the given parameters. 
     25    """ 
     26    args = [] 
     27 
     28    if not tapfile: 
     29        tapfile = "dummy-tap-file" 
     30        handle = open(tapfile, "w") 
     31        handle.write("# Dummy TAP file\n") 
     32        handle.close() 
     33 
     34    args.extend(["--tapfile", tapfile]) 
     35 
     36    if maintainer: 
     37        args.extend(["--maintainer", maintainer]) 
     38    if protocol: 
     39        args.extend(["--protocol", protocol]) 
     40    if description: 
     41        args.extend(["--description", description]) 
     42    if longDescription: 
     43        args.extend(["--long_description", longDescription]) 
     44    if setVersion: 
     45        args.extend(["--set-version", setVersion]) 
     46    if rpmfile: 
     47        args.extend(["--rpmfile", rpmfile]) 
     48    if type_: 
     49        args.extend(["--type", type_]) 
     50 
     51    return tap2rpm.run(args) 
     52 
     53 
     54 
     55def _queryRPMTags(rpmfile, taglist): 
     56    """ 
     57    Helper function to read the given header tags from the given RPM file. 
     58 
     59    Returns a Deferred that fires with dictionary mapping a tag name to a list 
     60    of the associated values in the RPM header. If a tag has only a single 
     61    value in the header (like NAME or VERSION), it will be returned as a 1-item 
     62    list. 
     63 
     64    Run "rpm --querytags" to see what tags can be queried. 
     65    """ 
     66 
     67    # Build a query format string that will return appropriately delimited 
     68    # results. Every field is treated as an array field, so single-value tags 
     69    # like VERSION will be returned as 1-item lists. 
     70    queryFormat = RECORD_SEPARATOR.join([ 
     71            "[%%{%s}%s]" % (tag, UNIT_SEPARATOR) for tag in taglist 
     72           ]) 
     73 
     74    def parseTagValues(output): 
     75        res = {} 
     76 
     77        for tag, values in zip(taglist, output.split(RECORD_SEPARATOR)): 
     78            values = values.strip(UNIT_SEPARATOR).split(UNIT_SEPARATOR) 
     79            res[tag] = values 
     80 
     81        return res 
     82 
     83    d = utils.getProcessOutput("rpm", 
     84            ("-q", "--queryformat", queryFormat, "-p", rpmfile)) 
     85    d.addCallback(parseTagValues) 
     86    return d 
     87 
     88 
     89 
     90class TestTap2RPM(TestCase): 
     91 
     92 
     93    def setUp(self): 
     94        return self._checkForRpmbuild() 
     95 
     96 
     97    def _checkForRpmbuild(self): 
     98        """ 
     99        tap2rpm requires rpmbuild; skip tests if rpmbuild is not present. 
     100        """ 
     101        skipMsg = "rpmbuild must be present to test tap2rpm" 
     102        def skipTestIfNotFound(result): 
     103            out, err, code = result 
     104            # If there was a problem running rpmbuild, or it looks like we've 
     105            # accidentally found some unrelated script with the same name, skip 
     106            # these tests. 
     107            if code != 0 or not out.startswith("RPM version"): 
     108                raise SkipTest(skipMsg) 
     109 
     110        def skipTestIfError(failure): 
     111            # According to the spawnProcess docs, OSError is raised if new 
     112            # proceses can't be created for some reason. According to #4184, 
     113            # OSError is raised if Windows can't find the program to be run. 
     114            failure.trap(OSError) 
     115            raise SkipTest(skipMsg) 
     116 
     117        d = utils.getProcessOutputAndValue("rpmbuild", ("--version",)) 
     118        d.addCallbacks(skipTestIfNotFound, skipTestIfError) 
     119        return d 
     120 
     121 
     122    def _makeTapFile(self, basename="dummy"): 
     123        """ 
     124        Makes a temporary .tap file and returns the absolute path. 
     125        """ 
     126        path = basename + ".tap" 
     127        handle = open(path, "w") 
     128        handle.write("# Dummy .tap file") 
     129        handle.close() 
     130        return path 
     131 
     132 
     133    def _verifyRPMTags(self, rpmfile, **tags): 
     134        """ 
     135        Checks the given file has the given tags set to the given values. 
     136        """ 
     137 
     138        d = _queryRPMTags(rpmfile, tags.keys()) 
     139        d.addCallback(self.failUnlessEqual, tags) 
     140        return d 
     141 
     142 
     143    def test_basicOperation(self): 
     144        """ 
     145        Calling tap2rpm should produce an RPM and SRPM with default metadata. 
     146        """ 
     147        basename = "frenchtoast" 
     148 
     149        # Create RPMs based on a TAP file with this name. 
     150        rpm, srpm = _makeRPMs(tapfile = self._makeTapFile(basename)) 
     151 
     152        # Verify the resulting RPMs have the correct tags. 
     153        d = self._verifyRPMTags(rpm, 
     154                NAME=["twisted-%s" % (basename,)], 
     155                VERSION=["1.0"], 
     156                RELEASE=["1"], 
     157                SUMMARY=["A TCP server for %s" % (basename,)], 
     158                DESCRIPTION=["Automatically created by tap2rpm"], 
     159            ) 
     160        d.addCallback(lambda _: self._verifyRPMTags(srpm, 
     161                NAME=["twisted-%s" % (basename,)], 
     162                VERSION=["1.0"], 
     163                RELEASE=["1"], 
     164                SUMMARY=["A TCP server for %s" % (basename,)], 
     165                DESCRIPTION=["Automatically created by tap2rpm"], 
     166            )) 
     167 
     168        return d 
     169 
     170 
     171    def test_protocolOverride(self): 
     172        """ 
     173        Setting 'protocol' should change the name of the resulting package. 
     174        """ 
     175        basename = "acorn" 
     176        protocol = "banana" 
     177 
     178        # Create RPMs based on a TAP file with this name. 
     179        rpm, srpm = _makeRPMs(tapfile = self._makeTapFile(basename), 
     180                protocol=protocol) 
     181 
     182        # Verify the resulting RPMs have the correct tags. 
     183        d = self._verifyRPMTags(rpm, 
     184                NAME=["twisted-%s" % (protocol,)], 
     185                SUMMARY=["A TCP server for %s" % (protocol,)], 
     186            ) 
     187        d.addCallback(lambda _: self._verifyRPMTags(srpm, 
     188                NAME=["twisted-%s" % (protocol,)], 
     189                SUMMARY=["A TCP server for %s" % (protocol,)], 
     190            )) 
     191 
     192        return d 
     193 
     194 
     195    def test_rpmfileOverride(self): 
     196        """ 
     197        Setting 'rpmfile' should change the name of the resulting package. 
     198        """ 
     199        basename = "cherry" 
     200        rpmfile = "donut" 
     201 
     202        # Create RPMs based on a TAP file with this name. 
     203        rpm, srpm = _makeRPMs(tapfile = self._makeTapFile(basename), 
     204                rpmfile=rpmfile) 
     205 
     206        # Verify the resulting RPMs have the correct tags. 
     207        d = self._verifyRPMTags(rpm, 
     208                NAME=[rpmfile], 
     209                SUMMARY=["A TCP server for %s" % (basename,)], 
     210            ) 
     211        d.addCallback(lambda _: self._verifyRPMTags(srpm, 
     212                NAME=[rpmfile], 
     213                SUMMARY=["A TCP server for %s" % (basename,)], 
     214            )) 
     215 
     216        return d 
     217 
     218 
     219    def test_descriptionOverride(self): 
     220        """ 
     221        Setting 'description' should change the SUMMARY tag. 
     222        """ 
     223        description="eggplant" 
     224 
     225        # Create RPMs based on a TAP file with this name. 
     226        rpm, srpm = _makeRPMs(tapfile = self._makeTapFile(), 
     227                description=description) 
     228 
     229        # Verify the resulting RPMs have the correct tags. 
     230        d = self._verifyRPMTags(rpm, 
     231                SUMMARY=[description], 
     232            ) 
     233        d.addCallback(lambda _: self._verifyRPMTags(srpm, 
     234                SUMMARY=[description], 
     235            )) 
     236 
     237        return d 
     238 
     239 
     240    def test_longDescriptionOverride(self): 
     241        """ 
     242        Setting 'longDescription' should change the DESCRIPTION tag. 
     243        """ 
     244        longDescription="fig" 
     245 
     246        # Create RPMs based on a TAP file with this name. 
     247        rpm, srpm = _makeRPMs(tapfile = self._makeTapFile(), 
     248                longDescription=longDescription) 
     249 
     250        # Verify the resulting RPMs have the correct tags. 
     251        d = self._verifyRPMTags(rpm, 
     252                DESCRIPTION=[longDescription], 
     253            ) 
     254        d.addCallback(lambda _: self._verifyRPMTags(srpm, 
     255                DESCRIPTION=[longDescription], 
     256            )) 
     257 
     258        return d 
     259 
     260 
     261    def test_setVersionOverride(self): 
     262        """ 
     263        Setting 'setVersion' should change the RPM's version info. 
     264        """ 
     265        version="123.456" 
     266 
     267        # Create RPMs based on a TAP file with this name. 
     268        rpm, srpm = _makeRPMs(tapfile = self._makeTapFile(), 
     269                setVersion=version) 
     270 
     271        # Verify the resulting RPMs have the correct tags. 
     272        d = self._verifyRPMTags(rpm, 
     273                VERSION=["123.456"], 
     274                RELEASE=["1"], 
     275            ) 
     276        d.addCallback(lambda _: self._verifyRPMTags(srpm, 
     277                VERSION=["123.456"], 
     278                RELEASE=["1"], 
     279            )) 
     280 
     281        return d 
  • new file twisted/topfiles/3292.bugfix

    diff --git a/twisted/topfiles/3292.bugfix b/twisted/topfiles/3292.bugfix
    new file mode 100644
    index 0000000..b10fccc
    - +  
     1The tap2rpm script now works with modern versions of RPM.