Wednesday Mar 05, 2014

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

About

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

Search

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