piuparts README
===============

                Lars Wirzenius <liw@iki.fi>


Introduction
------------

                This is a tool for testing that .deb packages can be
                installed, upgraded, and removed without problems. The
                name, a variant of something suggested by Tollef Fog
                Heen, is short for "package installation, upgrading, and
                removal testing suite".
                
                See the manual page for more information about using
                the program.
                
                You need at least Python 2.3 and debootstrap. The
                version of debootstrap in the Debian 3.1 release
                (codename sarge) is too old.
                
                piuparts is licensed under the GNU General Public
                License, version 2.
                

Distrubuted testing
-------------------

                As part of the quality assurance effort of Debian, I run
                piuparts on the Debian package archive. This requires a
                lot of processing power, and so the work is distributed
                over several hosts.

                There is one central machine, the master, and any number
                of slave machines. Each slave machine connects to the
                master, via ssh, and runs the piuparts-master program to
                report results of packages it has tested already, and to
                get more work.
                
                To set this up for yourself, the following steps should
                suffice:
                
                 1. Pick a machine to run the master. It cannot be a chroot,
                    but sarge should be good enough.
                 2. Install piuparts on it.
                 3. Create an account for the master.
                 4. Configure /etc/piuparts/piuparts-master.conf 
                    appropriately.
                 
                 5. Pick one or more slaves to run the slave. You can use
                    the machine running the master also as a slave. You need
                    sid (or possibly etch), but it can be in a chroot.
                 6. Install piuparts on it.
                 7. Configure /etc/piuparts/piuparts-slave.conf
                    appropriately.
                 8. Create an account for the slave. This must be different
                    from the master account.
                 9. Create an ssh keypair for the slave. No passphrase.
                10. Add the slave's public key to the master's 
                    .ssh/authorized_keys
                11. Configure sudo on the slave machine to allow the slave
                    account become root without password (otherwise you'll
                    be typing in a password all the time).

                12. Run /usr/share/piuparts/piuparts-slave.py on the slave
                    accounts. Packages that are installed want to use
                    /dev/tty, so you can't do this from cron. Also, you'll
                    want to keep an eye on what is happening, to catch
                    runaway processes and stuff.

                13. The logs go into the master account, into
                    subdirectories.

                Please note that running piuparts this way is somewhat
                risky, to say the least. There are security implications
                that you want to consider. It's best to do it on
                machines that you don't mind wiping clean at a moment's
                notice, and preferably so that they don't have direct
                network access.


Distributed piuparts testing protocol
--------------------------------------
                
                The slave machine and the piuparts-master program
                communicate using a simplistic line based protocol. Ssh
                takes care of authentication, so there is nothing in the
                protocol for that. The protocol is transaction based:
                the slave gives a command, the master program responds.
                Commands and responses can be simple (a single line) or
                long (a status line plus additional data lines). Simple
                commands and responses are of the following format:
                
                    keyword arg1 arg2 arg3 ... argN
                    
                The keyword is a command or status code ("ok"), and it
                and the arguments are separated by spaces. An argument
                may not contain a space.
                
                A long command or response is deduced from the context:
                certain commands always include additional data, and
                certain commands always get a long response, if
                successful (error responses are always simple). The
                first line of a long command or response is the same as
                for a simple one, the additional lines are prefixed with
                a space, and followed by a line containing only a
                period.
                
                A sample session (">>" indicates what the slave sends,
                "<<" what the master responds with):
                
                    << hello
                    >> pass liwc 1.2.3-4
                    >>  The piuparts
                    >>  log file comes
                    >>  here
                    >> .
                    << ok
                    >> reserve
                    << ok vorbisgain 2.3-4
                
                Here the slave first reports a successful test of
                package liwc, version 1.2.3-4, and sends the piuparts
                log file for it. Then it reserves a new package to test
                and the master gives it vorbisgain, version 2.3-4.
                
                The communication always starts with the master saying
                "hello". The slave shall not speak until the master has
                spoken.
                
                Commands and responses in this protocol:
                
                    Command: reserve
                    Success: ok <packagename> <packageversion>
                    Failure: error
                    
                        Slave asks master to reserve a package (a
                        particular version of it) for the slave to test.
                        The slave may reserve any number of packages to
                        test. If the transaction fails, there are no
                        more packages to test, and the slave should
                        disconnect, wait some time and try again.
                    
                    Command: unreserve <packagename> <packageversion>
                    Success: ok
                    
                        Slave informs master it cannot test the desired
                        version of a package (perhaps it went away from
                        the mirror?).
                
                    Command: pass <packagename> <packageversion>
                              log file contents
                             .
                    Success: ok
                    
                        Slave reports that it has tested a particular
                        version of a package and that the package passed
                        all tests. Master records this and stores the
                        log file somewhere suitable.
                        
                    Command: fail <packagename> <packageversion>
                              log file contents
                             .
                    Success: ok
                    
                        Same as "pass", but package failed one or more tests.
                        
                    Command: untestable <packagename> <packageversion>
                              log file contents
                             .
                    Success: ok
                    
                        Slave reports that a particular package is
                        untestable, possibly because it insists on
                        interacting with the user.
                        
                In all cases, if the master cannot respond with "ok"
                (e.g., because of a disk error storing a log file), it
                aborts and the connection fails. The slave may only
                assume the command has succeeded if the master responds
                with "ok".
                
                The master may likewise abort, without an error message,
                if the slave sends garbage, or sends too much data.
