Slackware This Forum is for the discussion of Slackware Linux.
|
Notices |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
|
|
|
11-21-2013, 05:23 AM
|
#1
|
Senior Member
Registered: Jan 2011
Location: Oslo, Norway
Distribution: Slackware
Posts: 2,557
|
Post-removal clean-up/purge support in Slackware
From time to time I have seen Slackware users mention that they would have liked Slackware packages to include some kind of post-removal support. An uninstall equivalent to what doinst.sh currently does. Even Stuart Winter ( drmozes) once commented on the potential usefulness of such a feature:
Quote:
Originally Posted by drmozes
When I was working as a system administrator and running Slackware in a data centre and building my own custom packages, I really wanted post-remove scripts that would be run by removepkg. This way I could tidy up residue from the package's installation, or adjust config files once a package was removed.
|
Though to be fair the statement immediately following suggests he has since decided that is not that big of an issue:
Quote:
Originally Posted by drmozes
However, I found ways to work around that, and I no longer do that job so I haven't thought about that since then.
|
How do other people feel about this and/or handle these situations? I am just curious really. I'm not currently suggesting that this functionality is added to the official pkgtools, since I figure that if we have made it this far without such a feature it cannot be that critical to most users.
That said, for the sake of playing around and to help me decide how useful I may (or may not) find such a feature, I tweaked my own removepkg very slightly to allow optional running of a post-remove/cleanup function when specifically called with the option '-purge'. My method was not to another script (e.g. install/douninst.sh) but rather to allow the packager to add a function called cleanup to any doinst.sh where they want to have this functionality. If the packager does not want the cleanup function run on post install they can simply not call it anywhere in the dosint.sh itself! However its presence means that when a user runs removepkg with my newly added '-purge' switch, it can extract this function and run it after the package has been removed.
Things might be clearer with an example:
Code:
config() {
NEW="$1"
OLD="`dirname $NEW`/`basename $NEW .new`"
if [ ! -r $OLD ]; then
mv $NEW $OLD
elif [ "`cat $OLD | md5sum`" = "`cat $NEW | md5sum`" ]; then
rm $NEW
fi
}
config etc/someapp.new
cleanup() {
rm -f etc/someapp
}
As you can see above, cleanup is present and can be used to remove the config file but it is never actually called in the rest of doinst.sh so it does not run on post install. It will however be run on post uninstall if the user issues 'removepkg -purge someapp'.
This might seem an odd way of doing things but if you think of that file (doinst.sh) as simply a collection of stuff that must be done outside of normal extraction or deletion (rather than getting hung up on its name), it makes some sense. It is worth noting that removepkg already uses information found in doinst.sh to locate the symlinks it should remove, so in my mind this is just a continuation of that theme.
Additionally, adding this information to doinst.sh rather than another file means that if I want (and it makes sense) I could call the the cleanup function in doinst.sh itself. Consider for example a doinst.sh for Grahpical app that looks like the following:
Code:
cleanup() {
if [ -x /usr/bin/update-desktop-database ]; then
/usr/bin/update-desktop-database -q usr/share/applications >/dev/null 2>&1
fi
if [ -x /usr/bin/update-mime-database ]; then
/usr/bin/update-mime-database usr/share/mime >/dev/null 2>&1
fi
if [ -e usr/share/icons/hicolor/icon-theme.cache ]; then
if [ -x /usr/bin/gtk-update-icon-cache ]; then
/usr/bin/gtk-update-icon-cache usr/share/icons/hicolor >/dev/null 2>&1
fi
fi
}
cleanup
Here installpkg would update various databases and caches after install of that application. If I wanted I could also ensure these were updated after removal by running 'removepkg -purge someapp'. So by having the cleanup code in doinst.sh rather than another script, I can avoid duplication.
Anyway here is my quick hack to removepkg that adds support for calling a cleanup function from doinst.sh when run with '-purge' (be warned I did not spend a lot of time on this and have done almost zero testing so if it ruins your system I shall accept no responsibility):
Code:
--- removepkg.orig
+++ removepkg
@@ -391,6 +391,18 @@
mv $ADM_DIR/scripts/$PKGNAME $ADM_DIR/removed_scripts
fi
fi
+ if [ "$PURGE" = "true" ]; then
+ if [ -r $ADM_DIR/removed_scripts/$PKGNAME ]; then
+ sed -n '/^cleanup() {$/,/^}$/p' $ADM_DIR/removed_scripts/$PKGNAME > $TMP/cleanup$$
+ if grep -q . $TMP/cleanup$$; then
+ . $TMP/cleanup$$
+ cleanup
+ else
+ echo "No cleanup function found in the doinst.sh for $PKGNAME"
+ fi
+ rm -f $TMP/cleanup$$
+ fi
+ fi
else
echo "No such package: $ADM_DIR/packages/$PKGNAME. Can't remove."
fi
@@ -398,7 +410,7 @@
}
if [ "$#" = "0" ]; then
- echo "Usage: $(basename $0) [-copy] [-keep] [-preserve] [-warn] packagename ..."; exit 1
+ echo "Usage: $(basename $0) [-copy] [-keep] [-preserve] [-warn] [-purge] packagename ..."; exit 1
fi
while : ; do
@@ -407,7 +419,8 @@
-keep | --keep) KEEP=true; shift;;
-preserve | --preserve) PRESERVE=true; shift;;
-warn | --warn) WARN=true; shift;;
- -* | --*) echo "Usage: $(basename $0) [-copy] [-keep] [-preserve] [-warn] packagename ..."; exit 1;;
+ -purge | --purge) PURGE=true; shift;;
+ -* | --*) echo "Usage: $(basename $0) [-copy] [-keep] [-preserve] [-warn] [-purge] packagename ..."; exit 1;;
*) break
esac
done
|
|
|
11-21-2013, 07:46 AM
|
#2
|
LQ Veteran
Registered: May 2008
Posts: 7,051
|
Feels somewhat fragile. That sed is going to be vulnerable to a number of whitespace issues, and also consider:
Code:
cleanup() {
{
do this
do that
}
do the other
}
... using a { } block like that is pointless, but it is valid code.
Sourcing 3rd party code into a script is inherently unreliable. I think I'd rather see a separate doremove.sh executed as a child process, though obviously that's going to mean another file that needs to be stored away when the package is installed.
|
|
1 members found this post helpful.
|
11-21-2013, 07:56 AM
|
#3
|
LQ Guru
Registered: Jul 2011
Location: California
Distribution: Slackware64-15.0 Multilib
Posts: 6,564
|
I normally keep a written journal of what all files such as configuration and initialization scripts I create for distributions I use to keep track of these so when, and if, I remove packages, I know what files can be deleted or archived for future usage in reference.
That's a standard practice of many administrators I've learned from.
While a dorem.sh or doremove.sh script would be good, the question would be where do we keep this script? In packages or on the system as part of pkgtools and if installed locally, will these scripts be removed when the package is removed?
|
|
1 members found this post helpful.
|
11-21-2013, 08:10 AM
|
#4
|
Senior Member
Registered: Jan 2011
Location: Oslo, Norway
Distribution: Slackware
Posts: 2,557
Original Poster
|
Quote:
Originally Posted by GazL
Feels somewhat fragile. That sed is going to be vulnerable to a number of whitespace issues, and also consider:
|
I knocked up that patch in a couple of minutes to demo. Anyway, that is not really the point.
- The packager should ensure that they format the dosint.sh so that it works correctly and test it just as they do now
- The regex could easily be improved further, e.g. '/^[ \t]*cleanup[ \t]*()[ \t]*{\{,1\}[ \t]*$/,/^[ \t]*}[ \t]*$/p'
Additionally I am not suggesting this makes its way upstream. It is a potential method for people who package additional apps locally to be able to add post remove support to those packages.
Last edited by ruario; 11-21-2013 at 02:40 PM.
Reason: improved regex added
|
|
|
11-21-2013, 08:15 AM
|
#5
|
Senior Member
Registered: Jan 2011
Location: Oslo, Norway
Distribution: Slackware
Posts: 2,557
Original Poster
|
Quote:
Originally Posted by ReaperX7
I normally keep a written journal of what all files such as configuration and initialization scripts I create for distributions I use to keep track of these so when, and if, I remove packages, I know what files can be deleted or archived for future usage in reference.
|
Valid points, though some automation is nice.
Quote:
Originally Posted by ReaperX7
While a dorem.sh or doremove.sh script would be good, the question would be where do we keep this script? In packages or on the system as part of pkgtools and if installed locally, will these scripts be removed when the package is removed?
|
If a separate script was included it could be run after the package is removed if it was first copied to /var/log/removed_scripts/ after uninstall of the package (this currently happens with doinst.sh).
Last edited by ruario; 11-21-2013 at 03:22 PM.
Reason: added comment about automation
|
|
|
11-21-2013, 02:46 PM
|
#6
|
Senior Member
Registered: Jan 2011
Location: Oslo, Norway
Distribution: Slackware
Posts: 2,557
Original Poster
|
To continue to amuse myself (I'll be honest that is primarily why I am doing this I suppose! ) I updated my example patch. In addition to making the regex more tolerant of whitespace I also changed the switch and searched for function name to "-syncstate" and "syncstate" respectively. I figure this name more accurately reflects what the feature does given my dosint.sh examples above.
EDIT 1: I did not attempt to deal with Gazl's example mid-function {} block from above, since I figure that: 1. Nobody is going to do this given that it is (in his own words) pointless; 2. Anyone making packages should test them (just as they do now) and hence they would see if they somehow hit such an issue (and I would also be very surprised if they could not work around it).
I feel I could probably work around it but I shall take a KISS/ YAGNI approach, rather than overcomplicating my proposed solution for a corner case that will likely not appear in real life.
EDIT 2
Quote:
Originally Posted by GazL
Sourcing 3rd party code into a script is inherently unreliable.
|
Now I strip out the function and then execute it as a child process.
Last edited by ruario; 11-21-2013 at 03:23 PM.
|
|
|
11-21-2013, 03:09 PM
|
#7
|
Slackware Contributor
Registered: Apr 2008
Distribution: Slackware
Posts: 1,599
|
Well, I can tell you how I worked around those issues and it wasn't by patching pktgools: I'd created a package distribution and management framework and set of tools to manage a large number of servers.
In the case of custom-built packages, some of the doinst.sh scripts would clean up from a previous version's installation whilst the new package was being installed.
For official Slackware packages that left residue behind, my tools would clean up - similar to what you can do with cfengine, puppet and others.
I spoke with Pat about this a long time ago and his argument is that (paraphrasing - this was *years ago*) adding a post-uninstall script would open up a world of well intentioned people breaking others' systems. If your packages never see the public, that's fine - but if you're providing them publicly then you might be under the assumption that file 'x' and directory 'y' should be deleted upon package removal; except that you have * no idea * what the user might have put in there - leading to the potential of data loss. Obviously you could be smart about it and perform a number of checks and balances before deleting anything (which I seem to recall that RPMs do, to a degree); but that would be reliant upon the creator of the package doing so and covering all bases.
That's why there's no post removal clean up support in Slackware.
Last edited by drmozes; 11-21-2013 at 03:11 PM.
|
|
6 members found this post helpful.
|
11-21-2013, 04:07 PM
|
#8
|
Senior Member
Registered: Jan 2011
Location: Oslo, Norway
Distribution: Slackware
Posts: 2,557
Original Poster
|
Thanks Stuart, I really appreciate you taking the time to post here and provide some background. The arguments certainly make a lot of sense, though I do wonder if it would be less of an issue now than it was in the past, given that these days most Slackers (at least here on LQ) only seem to accept binary packages from a small handful of well trusted individual packagers or SBo (and in the case of SBo submissions are reviewed).
Nonetheless I won't be expecting official support for post removal scripts any time soon. For my own part if I do find I want/need this functionality for packages I create locally I can employ a quick work around (such as patching my own copy of removepkg) or consider a more elaborate solution along the lines of what you have outlined.
P.S. With your explanation, I feel I can consider this [SOLVED] so thanks again!
EDIT: I do feel my example solution incorporating an optional switch somewhat lessens the likelihood of breakage (given that it is not run by default), nonetheless I fully admit it does not actually prevent problems.
Last edited by ruario; 11-21-2013 at 04:23 PM.
|
|
|
11-21-2013, 04:42 PM
|
#9
|
LQ Guru
Registered: Jul 2011
Location: California
Distribution: Slackware64-15.0 Multilib
Posts: 6,564
|
Automation is nice and it eases processes and workloads, but Stuart is correct. Having a removal script for post-uninstall would make things complicated as removing a directory would be problematic especially if it contained non-packaged files.
Windows got around this somehow with it's many packaging self-extracting executables and uninstallers using a variety of means, such as detecting orphaned files and asking the end-user on notice if they wanted to remove the directory, but then again, most Windows packages are placed in it's own folder in the C:\Program Files or C:\Program Files(x86) directory. I'm not certain, but I think PC-BSD uses something like this with their .PBI packaging system which does this self-contained folder method of installing packages. You might want to ask around on PC-BSD's forums about this.
|
|
|
11-21-2013, 05:27 PM
|
#10
|
Slackware Contributor
Registered: Apr 2008
Distribution: Slackware
Posts: 1,599
|
Quote:
Originally Posted by ReaperX7
Automation is nice and it eases processes and workloads, but Stuart is correct. Having a removal script for post-uninstall would make things complicated as removing a directory would be problematic especially if it contained non-packaged files.
Windows got around this somehow with it's many packaging self-extracting executables and uninstallers using a variety of means, such as detecting orphaned files and asking the end-user on notice if they wanted to remove the directory, but then again, most Windows packages are placed in it's own folder in the C:\Program Files or C:\Program Files(x86) directory. I'm not certain, but I think PC-BSD uses something like this with their .PBI packaging system which does this self-contained folder method of installing packages. You might want to ask around on PC-BSD's forums about this.
|
There was a case in Debian a few years ago where the maintainer of one of the packages decided to make his package clear up a directory created by the package; but a user had subsequently placed user-generated content in this directory. The user wasn't happy when he lost all his data ;-)
|
|
|
11-21-2013, 09:16 PM
|
#11
|
LQ Guru
Registered: Jul 2011
Location: California
Distribution: Slackware64-15.0 Multilib
Posts: 6,564
|
Losing data is never fun.
|
|
|
11-22-2013, 08:10 AM
|
#12
|
Member
Registered: Sep 2011
Posts: 925
|
Quote:
Originally Posted by ReaperX7
Windows got around this somehow with it's many packaging self-extracting executables and uninstallers using a variety of means, such as detecting orphaned files and asking the end-user on notice if they wanted to remove the directory, but then again, most Windows packages are placed in it's own folder in the C:\Program Files or C:\Program Files(x86) directory.
|
Windows has the Side-by-Side-Assemblies for shared libraries (so you can have installed multiple versions of the same shared object and each application picks, what it likes most). Configuration data is stored in the registry and is usually left behind after uninstalling. That is why dozens of superfluous "registry cleaners" exist.
|
|
|
11-22-2013, 09:56 AM
|
#13
|
LQ Veteran
Registered: May 2008
Posts: 7,051
|
Quote:
Originally Posted by drmozes
The user wasn't happy when he lost all his data ;-)
|
No sympathy. He should have had a backup! Preferably two backups.
I think the fear that such a features would be over used, or inappropriately used is justified. Sometimes I get the feeling some of the doinst.sh scripts are already doing too much: "update-desktop-database" and suchlike. If you're installing a large batch of packages you really don't want each and every package repeatedly running the same updates over and over again. While it doesn't hurt anything to do that, it's inefficient and slows everything down. Better to do these sort of things once, if required, at the end of a batch of package installs/removals.
|
|
|
11-22-2013, 10:14 AM
|
#14
|
Senior Member
Registered: Jan 2011
Location: Oslo, Norway
Distribution: Slackware
Posts: 2,557
Original Poster
|
True but for the most part you only install a batch of packages infrequently, e.g. during first install or on distro upgrade. Most of the time you are only adding a particular application that interests you at that moment in time, so it only adds a little overhead. Additionally if you don't call "update-desktop-database" the user may not find their new application in the DEs interface, until the next time they login or restart, which most people would interpret as a bug.
|
|
|
11-22-2013, 11:31 AM
|
#15
|
Amigo developer
Registered: Dec 2003
Location: Germany
Distribution: Slackware
Posts: 4,928
|
I think a system of triggers could be safer, faster and configurable. On mass installation/upgrades, triggering could be delayed until a transaction has finished. A configuration setting could turn off some or all triggers, and actions performed by triggers could be written to do safe things, like not removing non-empty dirs, or other limited actions.
|
|
1 members found this post helpful.
|
All times are GMT -5. The time now is 06:30 PM.
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|