Preserving Unpacked Software During a Package Uninstall

I love it when I can wriggle out of the unintended side effects created by an automated system designed to simplify my life.

Here's a side effect created by the very good Image Packaging System (IPS) in our beloved Oracle Solaris 11. If you use the IPS to uninstall all packaged content from a directory, it also removes the directory. Not good if you also kinda sorta loaded unpackaged content into that directory.

For instance, let's say you worked with a third-party IPS package that installed its software into /usr/local. After a pause to polish the chrome on your custom Softail Deluxe, you install a second application into /usr/local from a tar file. What happens to that second application when you use IPS to remove the third-party IPS package from the /usr/local directory? Yup. IPS dumps the directory on the asphalt and high-sides the unpackaged content all the way to /var/pkg/lost+found.

Thank goodness somebody watches out for those of us who don't follow directions. Alta Elstad, from the Solaris Documentation Team at Oracle, is one of them. Here's how she suggests you avoid this problem.

How to Preserve the Directory

To prevent the packaged directory from being removed along with its content, package the directory separately. Create an IPS package that delivers only the one directory or directory structure that you want. Then that directory structure will remain in place until you uninstall that specific package. Uninstalling a different package that delivers content to that directory will not remove the directory.

Here's a detailed example.

  1. Create the directory structure you want to deliver. This example shows /usr/local. You could easily expand this to include /usr/local/bin and other subdirectories if necessary.
    $ mkdir -p usrlocal/usr/local
  2. Create the initial package manifest.
    $ pkgsend generate usrlocal | pkgfmt > usrlocal.p5m.1
    $ cat usrlocal.p5m.1
    dir path=usr owner=root group=bin mode=0755
    dir path=usr/local owner=root group=bin mode=0755
  3. Create a pkgmogrify input file to add metadata and to exclude delivering /usr since that directory is already delivered by Oracle Solaris. You might also want to add transforms to change directory ownership or permissions.
    $ cat usrlocal.mog
    set name=pkg.fmri value=pkg://site/usrlocal@1.0
    set name=pkg.summary value="Create the /usr/local directory."
    set name=pkg.description value="This package installs the /usr/local \
    directory so that /usr/local remains available for unpackaged files."
    set name=variant.arch value=$(ARCH)
    <transform dir path=usr$->drop>
    
  4. Apply the changes to the initial manifest.
    $ pkgmogrify -DARCH=`uname -p` usrlocal.p5m.1 usrlocal.mog | 
      pkgfmt > usrlocal.p5m.2
    $ cat usrlocal.p5m.2
    set name=pkg.fmri value=pkg://site/usrlocal@1.0
    set name=pkg.summary value="Create the /usr/local directory."
    set name=pkg.description value="This package installs the /usr/local \
    directory so that /usr/local remains available for unpackaged files."
    set name=variant.arch value=$(ARCH)
    <transform dir path=usr$->drop> 
    
  5. Check your work.
    $ pkglint usrlocal.p5m.2
    Lint engine setup...
    Starting lint run...
    $
    
  6. Publish the package to your repository.
    $ pkgsend -s yourlocalrepo publish -d usrlocal usrlocal.p5m.2
    pkg://site/usrlocal@1.0,5.11:20140303T180555Z
    PUBLISHED
    
    
    
  7. Make sure you can see the new package that you want to install.
    $ pkg refresh site
    $ pkg list -a usrlocal
    NAME (PUBLISHER)      VERSION      IFO
    usrlocal (site)       1.0          --- 
    
  8. Install the package.
    $ pkg install -v usrlocal
               Packages to install:         1
         Estimated space available:  20.66 GB
    Estimated space to be consumed: 454.42 MB
           Create boot environment:        No
    Create backup boot environment:        No
              Rebuild boot archive:        No
    
    Changed packages:
    site
      usrlocal
        None -> 1.0,5.11:20140303T180555Z
    PHASE                                          ITEMS
    Installing new actions                           5/5
    Updating package state database                 Done
    Updating package cache                           0/0
    Updating image state                            Done
    Creating fast lookup database                   Done
    Reading search index                            Done
    Updating search index                            1/1
    
  9. Make sure the package is installed.
    $ pkg list usrlocal
    NAME (PUBLISHER)      VERSION      IFO
    usrlocal (site)       1.0          i-- 
    $ pkg info usrlocal
              Name: usrlocal
           Summary: Create the /usr/local directory.
       Description: This package installs the /usr/local directory so that
                    /usr/local remains available for unpackaged files.
             State: Installed
         Publisher: site
           Version: 1.0
     Build Release: 5.11
            Branch: None
    Packaging Date: March  3, 2014 06:05:55 PM
              Size: 0.00 B
              FMRI: pkg://site/usrlocal@1.0,5.11:20140303T180555Z
    $ ls -ld /usr/local
    drwxr-xr-x   2 root     bin            2 Mar  3 10:17 /usr/local/
    

For More Information

About the Photograph

Photograph of Vancouver's laughing statues courtesy of BMK via Wikipedia Commons Creative Commons License 2.0

- Rick

Follow me on:
Blog | Facebook | Twitter | YouTube | The Great Peruvian Novel

Comments:

Hi,

Interesting workaround, even if it is not very obvious to circumvent this that way.

Anyway, what can be done in this other situation where /usr/local is not a simple directory, but a (ZFS) file system? It can't be delivered by the IPS package (as a file system is not an action of IPS), but an IPS package which put some content in it will try to move this path under /var/pkg/lost+found too if it is removed (and is the last IPS package to reference this path)?

Thank you.

--
Best regards,
Julien Gabel.

Posted by guest on March 06, 2014 at 05:51 AM MST #

You are correct that the directory cannot be delivered by an IPS package as a ZFS file system, and if you create the directory outside of an IPS package and then install packaged content into it, the directory will be removed when the last packaged content is uninstalled.

We have an enhancement request to use IPS packages to install ZFS file systems and are considering options.

Posted by Alta on March 06, 2014 at 11:24 AM MST #

Hi Alta,

> We have an enhancement request to use IPS packages to install ZFS file systems and are considering options.

Good to hear that: I got this "problem" since 2012Q1 :-( I even talked about that with a Solaris instructor in the past, which was very surprised by this behavior, i.e. IPS trying to alter something it didn't provide...

--
Best regards,
Julien Gabel.

Posted by guest on March 07, 2014 at 03:54 AM MST #

When you say IPS is altering something it did not provide, I assume you mean the directory: /usr/local in this example. But IPS did provide the directory, and when the package that delivered it is uninstalled, the directory is uninstalled and any unpackaged content salvaged. Perhaps you mean that if a directory still contains content after the last packaged content is removed, you would rather see the directory remain, instead of salvaging the content somewhere else? This solution presents other issues. However, alternative solutions are being discussed.

Posted by Alta on March 07, 2014 at 09:01 AM MST #

I am so sorry - you meant the case where you created the directory prior to installing a package that also delivers the directory. Yes, alternative solutions to that issue are being discussed.

Posted by Alta on March 07, 2014 at 09:15 AM MST #

I am so sorry - you meant the case where you created the directory prior to installing an IPS package that also delivers the directory. Alternative solutions to that issue are being discussed.

Posted by Alta on March 07, 2014 at 09:22 AM MST #

Hi Alta,

> I am so sorry - you meant the case where you created the directory prior to installing an IPS package that also delivers the directory.

Yes: I mean the case where a ZFS file system is present, and an IPS package delivers content in it. But I think the problem is the same.

When we want to install a new application on a server, we want it to be contained inside a dedicated file system, such as /usr/local/<appname> for example. So, since IPS is not currently able to create this file system on its own, a script creates the ZFS file system name /usr/local/<appname> before installing the IPS package which will deliver the content for the application (mostly files and directories) under /usr/local/<appname>/*.

But, if the IPS package for the application <appname> is now removed and it is the last package referencing something under /usr/local, it will try to move /usr/local (and probably /usr/local/<appname> IIRC) under /var/pkg/lost+found, although /usr/local and /usr/local/<appname> are two ZFS file systems managed outside of IPS.

> Alternative solutions to that issue are being discussed.

Good news. Thank you for your work!

--
Best regards,
Julien Gabel.

Posted by Julien Gabel on March 07, 2014 at 10:10 AM MST #

The workaround you describe is a real pain and just damn crazy. The real solution to this problem is to provide the features, a smart packaging system should really have! I wouldn't say that the apt-* stuff on Linux is smart, however, it doesn't destroy valueable data/information per default on uninstall. To do that, one has to use explicitly 'apt-get purge ...'. Why doesn't IPS provide a similar feature? E.g. why does IPS not provide an "file|dir|link" action attribute like 'keep', which let it know, that on uninstall the thingy shouldn't be destroyed/moved anywhere? That would be much saner and what most people would expect. In a 2nd stage IPS might implement a new command, e.g. "pkg show-artifacts [FMRI]..." which shows all "keep" related data from the artifacts-db and another cmd like "pkg purge[-artifacts] [FMRI]..." which allows one to move the stuff into the nirvana, i.e. no totally brain damaged move to /var/pkg/lost+found/, which is not only brain damaged because it does such unexpected things, but also, because it neither preserves the directory structure nor permissions/ownership. So restoring the data will give the casual customer a really hard time!
BTW: A really smart PS would allow one to package the artifacts [before destroying them], so that one is able to clean up the system, but has all the data, to [re-]install a SW [on a different machine] without any hassle. But I know, I'm already asking for too much ;-)

Posted by jelmd on April 11, 2014 at 10:34 AM MDT #

I've appreciated the previous comments.
I think that the integration with ZFS is important.
I do prefer the "workaround" as a way of making intentions explicit.
Otherwise one will probably end up in a mess along the time.
As an enterprise OS Solaris couldn't afford that.

Regards.

Posted by Carlos Azevedo on May 12, 2014 at 05:10 AM MDT #

Post a Comment:
  • HTML Syntax: NOT allowed
About

Contributors:
Rick Ramsey
Kemer Thomson
and members of the OTN community

Search

Archives
« March 2015
SunMonTueWedThuFriSat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
    
       
Today
Blogs We Like