Hey all, The following is the second design spec for the project. I have addressed all of the issues that were brought up. If I missed anything or if you feel I haven't fully answered what you need to know let me know and I will fix it asap
> DECLARATIVE DIVERSIONS > ====================== > Introduction > ------------ > A diversion is when it is possible to have dpkg not overwrite a file when > it > reinstalls the package it belongs to, and to have it put the file from the > package somewhere else instead. > Declarative diversions involves a new control file with a declarative > syntax which dpkg will parse and process directly as part of the package > unpack > and removal phases, eliminating the problems resulting from non-atomic > handling of diversions. > > Topics > ------ > There are a number of topics involved in implementing this kind of project > * What syntax do we use for the new control file? > * What dpkg does with the control file > * How do we handle diversions to a non-existant directory? > * How do we order unpacking a new package which adds a diversion? > * How do we order unpacking a new package that removes a diversion? > * How do we order removing a package which had a diversion? > * How do we handle errors? > * What happens to dpkg-divert? > > Details - Control File Syntax > ----------------------------- > It will conform to RFC2822 style with the following format: > * Divert-From: > * Divert-To: > * Blank lines and lines beginning with '#' will be comments > > 'Divert-To' will be optional and if it is ommitted then files being > diverted > will have their filename changed to 'file.distrib' > The above style has it's advantages, one of the main ones being that there > is > no need to escape whitespace within filenames. It also allows for more > commands > to be added at a later date. > > Details - Control File Handling > ------------------------------- > Within control.tar.gz the file should be named 'diversions' > This file is then copied to /var/lib/info/$package.diversions > We need to store the control file for the currently-installed package so > that > we can detect declarative diversions that have been removed from the > control > file between versions (On-disk version and the to-be-unpacked version). > If there is no previous version of a control file then all current > diversions > within the package are left in place and any new ones declared within the > control file are added. > If there is a previous version of the control file then the diversions > listed within the file are compared with the diversions currently in place. > If a diversion exists that is no longer listed in the control file then it > is > removed. If there is a diversion listed in the control file that doesn't > currently exist then it is added. > > Details - Handling Diversions to non-existant directories > --------------------------------------------------------- > Diverting files to directories that don't exist can cause a number of > problems. > If the package does not 'own' the directory it may be left orphaned on > removal of the package > The package is responsible for ensuring the availability of the target > directory in the unpack phase. > If a declarative diversion attempts to divert a file to a folder that > neither > exists already on the filesystem at unpack time, nor is shipped within > the package, dpkg will return an error at unpack time. > > Details - Ordering Requirements > ------------------------------- > =>Unpacking a new package that adds a diversion > *1. Check if package has a previous diversion control file > *2. Copy control file to tmp directory > *3. Calculate diversions to be added > *4. Unpack folders > *5. Add diversions > *6. Unpack files > *7. Copy control file to /var/lib/dpkg/info/$package.diversion > > *Performing diversions this way avoids trouble with creating folders > and > accidentally overwriting the wrong version of files. > *Another major problem would be extracting a new version of the file and > > overwriting the old one. > *This might cause the wrong version of the file to be diverted and the > package to break. > > =>Unpacking a new package that removes a diversion > *1. Check if package has a previous diversion control file > *2. Copy control file to tmp directory > *3. Calculate diversions to be removed > *4. Check if dropped diversion results in a file conflict and abort the > unpack if it does. > *5. Unpack folders > *6. Unpack files > *7. Remove old files no longer needed in the package > *8. Remove diversions > *9. Copy control file to /var/lib/dpkg/info/$package.diversion > *If a package has no previous diversion control file then no diversions > will be removed and existing diversions can only be removed using > dpkg-divert. > *If removing a diversion results in a file conflict then dpkg will > return > an error at unpack time before anything is unpacked and the unpack > is aborted. > > =>Removing a package which had a diversion > *1. Remove files > *2. Remove diversions > *3. Remove folders > *4. Remove control file at /var/lib/dpkg/info/$package.diversion > *This ensures that all files, diversions and folders are removed > correctly > > Details - Error handling > ------------------------ > Errors in diversions will have to handled with a great deal of care due to > the fact that if they are not the package could be broken. > This means that a great deal of checks must be done to ensure that all the > files > can be diverted properly before any actual diverting takes place. If they > can't > the package installation/update must be stopped and rolled back to avoid > the > package being installed incorrectly or broken. > > Details - 'dpkg-divert' > ----------------------- > When we impliment the new diversion method we should keep the current > dpkg-divert. This allows maintainers to catch up with the new method > without > breaking their packages. It also allows maintainers to perform some > operations > that aren't support by the new method. > All current functionality of dpkg-divert will be left intact for use by > sysadmins and for maintainers to catch up with the new system. The two > systems will work together without directly conflicting with each other. > > Example Usage #1 > ---------------- > The file to be diverted is '/usr/share/foo' > It needs to be moved to '/usr/share/bar' > The syntax of the control file would be: > #Start File > Divert-From: /usr/share/foo > Divert-To: /usr/share/bar > #End File > > Example Usage #2 > ---------------- > In this example the maintainer doesn't want to move the file to any > specific > folder > The syntax of the control file would be: > #Start File > Divert-From: /usr/share/foo > #End File > This would divert the file to '/usr/share/foo.distrib' > > Footnotes > --------- > RFC2822 Guide: > * http://www.faqs.org/rfcs/rfc2822.html > First Email Thread on Declarative Diversions (First Message in Thread): > * http://lists.debian.org/debian-dpkg/2011/05/msg00102.html > > Email thread on first design draft (First message in Thread): > * http://lists.debian.org/debian-dpkg/2011/06/msg00019.html > > Declarative Diversions Wiki: > * http://wiki.debian.org/SummerOfCode2011/DeclarativeDiversions > > My Blog for this Project: > * http://blog.sam-dunne.com -- Sam Dunne

