Hi, Inspired by Marga's excellent document claryfying the maintainer scripts at http://women.debian.org/wiki/English/MaintainerScripts, and also enthused about Emacs org-mode's ability to create a simple plain ascii input file and leveragte things like graphviz and ditaa, I have some up with a slightly different take on clarification of the maintainer script call sequence.
Please have a look-see at: http://people.debian.org/~srivasta/MaintainerScripts.html I'm attaching the source below. I think I am going to continue to enhance it, but I ran out of steam tonight. I am proposing adding this to the policy package, once it gets polished a bit more, and checked for correctness. manoj
#+STARTUP: hidestars showall #+TITLE: Maintainer scripts #+AUTHOR: Manoj Srivastava #+EMAIL: sriva...@debian.org #+DATE: <2009-10-16 Fri> #+LANGUAGE: en #+OPTIONS: H:0 num:nil toc:nil \n:nil @:t ::t |:t ^:t -:t f:t *:t TeX:t LaTeX:t skip:nil d:nil tags:not-in-toc #+INFOJS_OPT: view:info toc:1 path:org-info.js tdepth:2 ftoc:t #+LINK_UP: http://www.golden-gryphon.com/blog/manoj/ #+LINK_HOME: http://www.golden-gryphon.com/ * Introduction This document is meant to clarify the interaction between maintainer scripts and the state changes for a package when a user interacts with the packaging system. This was inspired by Margarita Manterola's [[http://women.debian.org/wiki/English/MaintainerScripts][excellent treatise]] on the subject, but has a slightly different slant: this document is more concerned about user actions, and the resulting state transitions of a package's state on a Debian installation, rather than a maintainer script centric treatment of the process. * Common Use Cases To start with, we consider the most common use cases related to a user's interaction with the packaging system: - *Install*: Starting with a package which is not installed on the system, the user asks the packaging system to install a package. If all goes well, the end result is that the package is installed on the system. - *Remove*: Starting with a package that is currently installed on the system, the user asks the packaging system to remove it. If all goes well, only configuration files shall remain on the system at the end. - *Purge*: Starting with the state when only configuration files remain on the system, the user asks the package system to remove even the configuration files. If all goes well, the package will be fully un-installed. - Starting with a package installed on the system, the user asks the system to fully uninstall the package. This is not an independent use case, it is just the /Remove/ followed by a /Purge/, and we do not consider it separately below. - *Reinstall*: Starting with just the configuration files remaining on the system, the user asks the packaging system to install the package again (potentially newer version of the package). - *Upgrade*: Starting with a version of the package installed on the system, the user asks the packaging system to install a newer version of the package. (A variation is the case where the old and the new version of the package are the same, but it follows the same process). This is not as complex a scenario as one might be afraid of; there are only three states a package may be in when the user initiates the action (/Not Installed/, /Configuration files only/, and /Installed/). These states are also successful terminal state, and there are only three failure terminal states (/Half Installed/, /Failed config/, and /Unpacked/). In the treatment below, we do not discuss details of failure modes, we just detail what happens when a maintainer script encounters an error. Also, we do not go into early sanity checks, for example, complications like the absence of a dependency when trying to (re)install a package, or the presence of a conflicting package. We also do not deal with the cases where the package we are trying to remove has other installed packages that depend on it; in all these cases the result is to abort the operation early, and let the user handle further action. ** Install a previously unknown package This is the case where a package is not currently installed on the system, and the user asks the packaging system to install version /V1/. *** State diagram #+begin_ditaa InstallState.png -r -o -s 0.8 +--------------------------------------------------------+ | +------+ | | | | | | | v | | /---*------*----+ /------------------+ | | | Not Installed | | Half Installed | | | | cGRE *------------>* cRED | | | | | +------------------/ | | +---*------*----/ | | | | | | | +--------------------------+ | | | | | | v v | | /---*-----------+ /-------*----------+ | | | Installed | | Failed Config | | | | cGRE | | cRED | | | +---------------/ +------------------/ | | cCCC | +--------------------------------------------------------+ #+end_ditaa *** Activity diagram The green ellipses are the start states a package may be in, the Blue labels represent user actions. The maintainer scripts are represented by decision boxes, since usually how the process flows depends on whether the maintainer scripts succeeds or fails. Terminal states are /octagons/. The colors /green/ and /red/ denote success and failure, respectively. #+begin_dot InstallActivity.png -Tpng digraph MaintainerScripts { bgcolor=gray3; center="true"; charset="iso-8859-1"; compound=true; concentrate=true; pack=true; outputorder="nodesfirst"; /* Starting states */ "Not-Installed" [shape=ellipse,fontsize=12,fontname="Times-Bold",style=filled,fillcolor="#99FF99" ]; /* Maybe Stating or Terminal states */ "Installed-V1" [shape=ellipse,fontsize=12,fontname="Times-Bold",style=filled,fillcolor="#99FF99" ]; /* install V1*/ "V1->\npreinst install" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V1->\npostrm abort-install" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V1->\npostinst configure" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; /* Failure terminal states */ "Half-Installed-V1" [shape=octagon,fontsize=12,fontname="Times-Bold",style=filled,fillcolor="#FFCCFF" ]; "Failed-Config-V1" [shape=octagon,fontsize=12,fontname="Times-Bold",style=filled,fillcolor="#FFCCFF" ]; subgraph installation { "Not-Installed" -> "V1->\npreinst install" [fontsize=12,fontname="Times-Bold",label="Install",color="cyan",fontcolor=lightskyblue]; "V1->\npreinst install" -> "V1->\npostrm abort-install" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V1->\npreinst install" -> "V1->\npostinst configure" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; "V1->\npostrm abort-install" -> "Half-Installed-V1" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V1->\npostrm abort-install" -> "Not-Installed" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; "V1->\npostinst configure" -> "Installed-V1" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; "V1->\npostinst configure" -> "Failed-Config-V1" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; } labelloc="t"; label="\n"; fontsize="32"; } #+end_dot ** Remove and Purge an installed package This is the reverse operation from above: starting with an installed package, remove the package, and then purge the configuration files. *** State diagram #+begin_ditaa RemoveState.png -r -o -s 0.8 +--------------------------------------------------------+ | /------------------+ | | | | | | +------------------------>* Installed | | | | | cRED | | | | +------------------/ | | /---*-----------+ /------------------+ | | | Installed | | Half Installed | | | | cGRE |------------>* cRED | | | +---*------*----/ +------------------/ | | | | /------------------+ | | | | | | | | | +----------------->* Failed Config | | | v | cRED | | | /---*-----------+ +------------------/ | | | Config Files | /------------------+ | | +-->* cGRE | | | | | | | *------------>* Not Installed | | | +---* | | cGRE | | | +---------------/ +------------------/ | | cCCC | +--------------------------------------------------------+ #+end_ditaa *** Activity Diagram #+begin_dot RemoveActivity.png -Tpng digraph MaintainerScripts { bgcolor=gray3; center="true"; charset="iso-8859-1"; compound=true; concentrate=true; pack=true; outputorder="nodesfirst"; /* Starting states */ "Installed-V1" [shape=ellipse,fontsize=12,fontname="Times-Bold",style=filled,fillcolor="#99FF99" ]; /* Removal and Purge */ "V1->\nprerm remove" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V1->\npostinst abort-remove" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V1->\npostrm remove" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V1->\npostrm purge" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; /* Maybe Terminal states */ "Not-Installed" [shape=ellipse,fontsize=12,fontname="Times-Bold",style=filled,fillcolor="#99FF99" ]; "Config-Files-V1" [shape=ellipse,fontsize=12,fontname="Times-Bold",style=filled,fillcolor="#99FF00" ]; /* Failure terminal states */ "Half-Installed-V1" [shape=octagon,fontsize=12,fontname="Times-Bold",style=filled,fillcolor="#FFCCFF" ]; "Failed-Config-V1" [shape=octagon,fontsize=12,fontname="Times-Bold",style=filled,fillcolor="#FFCCFF" ]; subgraph removal { "Installed-V1" -> "V1->\nprerm remove" [fontsize=12,fontname="Times-Bold",label="Remove",color="cyan",fontcolor=lightskyblue]; "V1->\nprerm remove" -> "V1->\npostinst abort-remove" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V1->\nprerm remove" -> "V1->\npostrm remove" [fontsize=9,fontname="Times-Roman",label="OK (del files)",color="chartreuse",fontcolor="#009900",decorate="true"]; "V1->\npostinst abort-remove" -> "Failed-Config-V1" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V1->\npostinst abort-remove" -> "Installed-V1" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; "V1->\npostrm remove" -> "Half-Installed-V1" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V1->\npostrm remove" -> "Config-Files-V1" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; "Config-Files-V1" -> "V1->\npostrm purge" [fontsize=12,fontname="Times-Bold",label="Purge",color="cyan",fontcolor=lightskyblue]; "V1->\npostrm purge" -> "Config-Files-V1" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V1->\npostrm purge" -> "Not-Installed" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; } labelloc="t"; label="\n"; fontsize="32"; } #+end_dot ** Reinstall a package This is the case where configuration files from a previous installation still exist on the system, and the user asks the packaging system to install a (potentially different) version of the package. *** State Diagram #+begin_ditaa ReinstallState.png -r -o -s 0.8 +--------------------------------------------------------+ | +------+ | | | | | | | v | | /---*------*----+ /------------------+ | | | Config Files | | Half Installed | | | | cGRE *------------>* cRED | | | | | +------------------/ | | +---*------*----/ | | | | | | | +--------------------------+ | | | | | | v v | | /---*-----------+ /-------*----------+ | | | Installed | | Failed Config | | | | cGRE | | cRED | | | +---------------/ +------------------/ | | cCCC | +--------------------------------------------------------+ #+end_ditaa *** Activity Diagram #+begin_dot ReinstallActivity.png -Tpng digraph MaintainerScripts { bgcolor=gray3; center="true"; charset="iso-8859-1"; compound=true; concentrate=true; pack=true; outputorder="nodesfirst"; /* Starting states */ "Config-Files-V1" [shape=ellipse,fontsize=12,fontname="Times-Bold",style=filled,fillcolor="#99FF00" ]; /* reinstall V2 (config files from V1 present) */ "V2->\npreinst install V1" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V2->\npostrm abort-install V1" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V2->\npostinst configure V1" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; /* Successful terminal states */ "Installed-V2" [shape=octagon,fontsize=12,fontname="Times-Bold",style=filled,fillcolor="#99FF99" ]; /* Failure terminal states */ "Half-Installed-V2" [shape=octagon,fontsize=12,fontname="Times-Bold",style=filled,fillcolor="#FFCCFF" ]; "Failed-Config-V2" [shape=octagon,fontsize=12,fontname="Times-Bold",style=filled,fillcolor="#FFCCFF" ]; subgraph reinstall { "Config-Files-V1" -> "V2->\npreinst install V1" [fontsize=12,fontname="Times-Bold",label="Install V2",color="cyan",fontcolor=lightskyblue]; "V2->\npreinst install V1" -> "V2->\npostrm abort-install V1" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V2->\npreinst install V1" -> "V2->\npostinst configure V1" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; "V2->\npostrm abort-install V1" -> "Half-Installed-V2" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V2->\npostrm abort-install V1" -> "Config-Files-V1" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; "V2->\npostinst configure V1" -> "Failed-Config-V2" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V2->\npostinst configure V1" -> "Installed-V2" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; } labelloc="t"; label="\n"; fontsize="32"; } #+end_dot ** Upgrade a package to a new version This is, perhaps unsurprisingly, the most complex operation of the ones we have so far considered. *** State Diagram #+begin_ditaa UpgradeState.png -r -o -s 0.8 +--------------------------------------------------------+ | /-------------------+ | | +--+ | Unpacked V1 | | | | | +------------------>* cRED | | | | v | +-------------------/ | | /---*--*--*-----+ /-------------------+ | | | Installed V1 | | Half Installed V1 | | | | cGRE *------------>* cRED | | | | | +-------------------/ | | +---*------*-*--/ /-------------------+ | | | | | | Failed Config V1 | | | | | +--------------->* cRED | | | | | +-------------------/ | | v +------------+ | | /---*-----------+ | /------------------+ | | | Installed V2 | | | Failed Config V2 | | | | cGRE | +---->* cRED | | | +---------------/ +------------------/ | | cCCC | +--------------------------------------------------------+ #+end_ditaa *** Activity Diagram #+begin_dot UpgradeActivity.png -Tpng digraph MaintainerScripts { bgcolor=gray3; center="true"; charset="iso-8859-1"; compound=true; concentrate=true; pack=true; outputorder="nodesfirst"; /* Starting states */ "Installed-V1" [shape=ellipse,fontsize=12,fontname="Times-Bold",style=filled,fillcolor="#99FF99" ]; /* Upgrade from V1 to V2 */ "V1->\nprerm upgrade V2" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V2->\nprerm failed-upgrade V1" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V1->\npostinst abort-upgrade V2->\na" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V2->\npreinst upgrade V1" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V2->\npostrm abort-upgrade V1->\na" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V1->\npostinst abort-upgrade V2->\nb" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V1->\npostrm upgrade V2" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V2->\npostrm failed-upgrade V2" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V1->\npreinst abort-upgrade V2" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V2->\npostrm abort-upgrade V1->\nb" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V2->\npostinst configure V1" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "Installed-V2" [shape=octagon,fontsize=12,fontname="Times-Bold",style=filled,fillcolor="#99FF99" ]; /* Failure terminal states */ "Half-Installed-V1" [shape=octagon,fontsize=12,fontname="Times-Bold",style=filled,fillcolor="#FFCCFF" ]; "Failed-Config-V1" [shape=octagon,fontsize=12,fontname="Times-Bold",style=filled,fillcolor="#FFCCFF" ]; "Failed-Config-V2" [shape=octagon,fontsize=12,fontname="Times-Bold",style=filled,fillcolor="#FFCCFF" ]; "Unpacked-V1" [shape=octagon,fontsize=12,fontname="Times-Bold",style=filled,fillcolor="#FFCCFF" ]; subgraph upgrading { "Installed-V1" -> "V1->\nprerm upgrade V2" [fontsize=12,fontname="Times-Bold",label="Install V2",color="cyan",fontcolor=lightskyblue]; "V1->\nprerm upgrade V2" -> "V2->\nprerm failed-upgrade V1" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V1->\nprerm upgrade V2" -> "V2->\npreinst upgrade V1" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; "V2->\nprerm failed-upgrade V1" -> "V1->\npostinst abort-upgrade V2->\na" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V2->\nprerm failed-upgrade V1" -> "V2->\npreinst upgrade V1" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; "V1->\npostinst abort-upgrade V2->\na" -> "Failed-Config-V1" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V1->\npostinst abort-upgrade V2->\na" -> "Installed-V1" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; "V2->\npreinst upgrade V1" -> "V2->\npostrm abort-upgrade V1->\na" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V2->\npreinst upgrade V1" -> "V1->\npostrm upgrade V2" [fontsize=9,fontname="Times-Roman",label="OK (unpack)",color="chartreuse",fontcolor="#009900",decorate="true"]; "V2->\npostrm abort-upgrade V1->\na" -> "Half-Installed-V1" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V2->\npostrm abort-upgrade V1->\na" -> "V1->\npostinst abort-upgrade V2->\nb" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; "V1->\npostinst abort-upgrade V2->\nb" -> "Unpacked-V1" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V1->\npostinst abort-upgrade V2->\nb" -> "Installed-V1" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; "V1->\npostrm upgrade V2" -> "V2->\npostrm failed-upgrade V2" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V1->\npostrm upgrade V2" -> "V2->\npostinst configure V1" [fontsize=9,fontname="Times-Roman",label="OK (del old)",color="chartreuse",fontcolor="#009900",decorate="true"]; "V2->\npostrm failed-upgrade V2" -> "V1->\npreinst abort-upgrade V2" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V2->\npostrm failed-upgrade V2" -> "V2->\npostinst configure V1" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; "V1->\npreinst abort-upgrade V2" -> "Half-Installed-V1" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V1->\npreinst abort-upgrade V2" -> "V2->\npostrm abort-upgrade V1->\nb" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; "V2->\npostrm abort-upgrade V1->\nb" -> "Half-Installed-V1" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V2->\npostrm abort-upgrade V1->\nb" -> "V1->\npostinst abort-upgrade V2->\nb" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; "V2->\npostinst configure V1" -> "Failed-Config-V2" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V2->\npostinst configure V1" -> "Installed-V2" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; } labelloc="t"; label="\n"; fontsize="32"; } #+end_dot * Conclusion In conclusion, here is the full activity diagram encompassing the above use cases. While this is certainly complex, it is still fairly easy to see how the use cases flow from the initial states (the green ellipses), through the decision points (the blue diamonds of the maintainer script execution), to the octagonal terminal states. #+begin_dot Activity.png -Tpng digraph MaintainerScripts { bgcolor=gray3; center="true"; charset="iso-8859-1"; compound=true; concentrate=true; pack=true; outputorder="nodesfirst"; /* Starting states */ "Not-Installed" [shape=ellipse,fontsize=12,fontname="Times-Bold",style=filled,fillcolor="#99FF99" ]; /* Maybe Stating or Terminal states */ "Config-Files-V1" [shape=ellipse,fontsize=12,fontname="Times-Bold",style=filled,fillcolor="#99FF00" ]; "Installed-V1" [shape=ellipse,fontsize=12,fontname="Times-Bold",style=filled,fillcolor="#99FF99" ]; /* install V1*/ "V1->\npreinst install" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V1->\npostrm abort-install" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V1->\npostinst configure" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; /* Removal and Purge */ "V1->\nprerm remove" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V1->\npostinst abort-remove" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V1->\npostrm remove" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V1->\npostrm purge" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; /* reinstall V2 (config files from V1 present) */ "V2->\npreinst install V1" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V2->\npostrm abort-install V1" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V2->\npostinst configure V1" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; /* Upgrade from V1 to V2 */ "V1->\nprerm upgrade V2" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V2->\nprerm failed-upgrade V1" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V1->\npostinst abort-upgrade V2->\na" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V2->\npreinst upgrade V1" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V2->\npostrm abort-upgrade V1->\na" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V1->\npostinst abort-upgrade V2->\nb" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V1->\npostrm upgrade V2" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V2->\npostrm failed-upgrade V2" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V1->\npreinst abort-upgrade V2" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; "V2->\npostrm abort-upgrade V1->\nb" [shape=diamond,style=filled,fillcolor="#CCFFFF",fontsize=9,fontname="Times-Roman"]; /* Successful terminal states */ "Installed-V2" [shape=octagon,fontsize=12,fontname="Times-Bold",style=filled,fillcolor="#99FF99" ]; /* Failure terminal states */ "Half-Installed-V1" [shape=octagon,fontsize=12,fontname="Times-Bold",style=filled,fillcolor="#FFCCFF" ]; "Half-Installed-V2" [shape=octagon,fontsize=12,fontname="Times-Bold",style=filled,fillcolor="#FFCCFF" ]; "Failed-Config-V1" [shape=octagon,fontsize=12,fontname="Times-Bold",style=filled,fillcolor="#FFCCFF" ]; "Failed-Config-V2" [shape=octagon,fontsize=12,fontname="Times-Bold",style=filled,fillcolor="#FFCCFF" ]; "Unpacked-V1" [shape=octagon,fontsize=12,fontname="Times-Bold",style=filled,fillcolor="#FFCCFF" ]; subgraph installation { "Not-Installed" -> "V1->\npreinst install" [fontsize=12,fontname="Times-Bold",label="Install",color="cyan",fontcolor=lightskyblue]; "V1->\npreinst install" -> "V1->\npostrm abort-install" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V1->\npreinst install" -> "V1->\npostinst configure" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; "V1->\npostrm abort-install" -> "Half-Installed-V1" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V1->\npostrm abort-install" -> "Not-Installed" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; "V1->\npostinst configure" -> "Installed-V1" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; "V1->\npostinst configure" -> "Failed-Config-V1" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; } subgraph removal { "Installed-V1" -> "V1->\nprerm remove" [fontsize=12,fontname="Times-Bold",label="Remove",color="cyan",fontcolor=lightskyblue]; "V1->\nprerm remove" -> "V1->\npostinst abort-remove" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V1->\nprerm remove" -> "V1->\npostrm remove" [fontsize=9,fontname="Times-Roman",label="OK (del files)",color="chartreuse",fontcolor="#009900",decorate="true"]; "V1->\npostinst abort-remove" -> "Failed-Config-V1" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V1->\npostinst abort-remove" -> "Installed-V1" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; "V1->\npostrm remove" -> "Half-Installed-V1" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V1->\npostrm remove" -> "Config-Files-V1" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; "Config-Files-V1" -> "V1->\npostrm purge" [fontsize=12,fontname="Times-Bold",label="Purge",color="cyan",fontcolor=lightskyblue]; "V1->\npostrm purge" -> "Config-Files-V1" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V1->\npostrm purge" -> "Not-Installed" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; } subgraph reinstall { "Config-Files-V1" -> "V2->\npreinst install V1" [fontsize=12,fontname="Times-Bold",label="Install V2",color="cyan",fontcolor=lightskyblue]; "V2->\npreinst install V1" -> "V2->\npostrm abort-install V1" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V2->\npreinst install V1" -> "V2->\npostinst configure V1" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; "V2->\npostrm abort-install V1" -> "Half-Installed-V2" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V2->\npostrm abort-install V1" -> "Config-Files-V1" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; "V2->\npostinst configure V1" -> "Failed-Config-V2" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V2->\npostinst configure V1" -> "Installed-V2" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; } subgraph upgrading { "Installed-V1" -> "V1->\nprerm upgrade V2" [fontsize=12,fontname="Times-Bold",label="Install V2",color="cyan",fontcolor=lightskyblue]; "V1->\nprerm upgrade V2" -> "V2->\nprerm failed-upgrade V1" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V1->\nprerm upgrade V2" -> "V2->\npreinst upgrade V1" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; "V2->\nprerm failed-upgrade V1" -> "V1->\npostinst abort-upgrade V2->\na" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V2->\nprerm failed-upgrade V1" -> "V2->\npreinst upgrade V1" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; "V1->\npostinst abort-upgrade V2->\na" -> "Failed-Config-V1" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V1->\npostinst abort-upgrade V2->\na" -> "Installed-V1" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; "V2->\npreinst upgrade V1" -> "V2->\npostrm abort-upgrade V1->\na" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V2->\npreinst upgrade V1" -> "V1->\npostrm upgrade V2" [fontsize=9,fontname="Times-Roman",label="OK (unpack)",color="chartreuse",fontcolor="#009900",decorate="true"]; "V2->\npostrm abort-upgrade V1->\na" -> "Half-Installed-V1" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V2->\npostrm abort-upgrade V1->\na" -> "V1->\npostinst abort-upgrade V2->\nb" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; "V1->\npostinst abort-upgrade V2->\nb" -> "Unpacked-V1" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V1->\npostinst abort-upgrade V2->\nb" -> "Installed-V1" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; "V1->\npostrm upgrade V2" -> "V2->\npostrm failed-upgrade V2" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V1->\npostrm upgrade V2" -> "V2->\npostinst configure V1" [fontsize=9,fontname="Times-Roman",label="OK (del old)",color="chartreuse",fontcolor="#009900",decorate="true"]; "V2->\npostrm failed-upgrade V2" -> "V1->\npreinst abort-upgrade V2" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V2->\npostrm failed-upgrade V2" -> "V2->\npostinst configure V1" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; "V1->\npreinst abort-upgrade V2" -> "Half-Installed-V1" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V1->\npreinst abort-upgrade V2" -> "V2->\npostrm abort-upgrade V1->\nb" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; "V2->\npostrm abort-upgrade V1->\nb" -> "Half-Installed-V1" [fontsize=9,fontname="Times-Roman",label="Failed",color="firebrick",fontcolor="#FF6633",decorate="true"]; "V2->\npostrm abort-upgrade V1->\nb" -> "V1->\npostinst abort-upgrade V2->\nb" [fontsize=9,fontname="Times-Roman",label="OK",color="chartreuse",fontcolor="#009900",decorate="true"]; } labelloc="t"; label="\n"; fontsize="32"; } #+end_dot # Local variables: # mode: org # fill-column: 72 # End:
-- "One man's mate is another man's passion." Jeff Daiell's description of adultery Manoj Srivastava <sriva...@debian.org> <http://www.debian.org/~srivasta/> 1024D/BF24424C print 4966 F272 D093 B493 410B 924B 21BA DABB BF24 424C