Solaris dependency issues: No version matching ‘require’ dependency can be installed and pkgmogrify


Errors with installing a Solaris p5p package

Say you’re packaging a package for Solaris yourself and you need to install it on a slightly older machine than where it was built.

When running a sudo pkg install -g myinstall.p5p myinstall , you run into the following errors:

  Reason:  No version matching 'require' dependency shell/bash@5.1.16-11.4.45.0.1.119.0 can be installed
    ----------------------------------------
    Reject:  pkg://solaris/shell/bash@5.1.16-11.4.45.0.1.119.0
    Reason:  No version matching 'require' dependency library/ncurses@6.3-11.4.45.0.0.117.0 can be installed
      ----------------------------------------
      Reject:  pkg://solaris/library/ncurses@6.3-11.4.45.0.1.119.0
      Reason:  No version matching 'require' dependency shell/bash@5.1.16-11.4.45.0.0.117.0 can be installed
        ----------------------------------------
        Reject:  pkg://solaris/shell/bash@5.1.16-11.4.48.0.1.126.0
        Reason:  No version matching 'require' dependency system/library@11.4-11.4.48.0.0.124.0 can be installed

pkgdepend resolve

Per the documentation above, this command will “Transform dependencies on files into dependencies on the packages that deliver those files. Dependencies are first resolved against the manifests given on the command line and then against the packages installed on the system.”

This will result in package version specifications that are relative to the system being built. For example:

depend fmri=pkg:/shell/bash@5.1.16-11.4.45.0.1.119.0 type=require
depend fmri=pkg:/shell/ksh93@93.21.1.20120801-11.4.45.0.1.119.0 type=require
depend fmri=pkg:/system/core-os@11.4-11.4.45.0.1.119.3 type=require
depend fmri=pkg:/system/library/gcc/gcc-c-runtime@11.2.0-11.4.45.0.1.119.0 type=require
depend fmri=pkg:/system/library/libc@11.4-11.4.45.0.1.119.3 type=require
depend fmri=pkg:/system/library/math@11.4-11.4.0.1.0.17.0 type=require
depend fmri=pkg:/system/library/security/crypto@11.4-11.4.45.0.1.119.3 type=require
depend fmri=pkg:/system/library@11.4-11.4.45.0.1.119.3 type=require
depend fmri=pkg:/system/linker@11.4-11.4.45.0.1.119.3 type=require

Because of this, if your Solaris build system has a newer version (even patch level) than your target install system, you may have version dependencies that aren’t resolvable on the target install system (like those that caused our error).

So how do we resolve this problem? This forum post states

The recommended solution to this problem is to build your packages on the oldest release you’re supporting, so that the dependencies will be at that release or later in line with Solaris binary compatibility,  Modifying them as you’re doing may work for your case, but it entirely depends on the nature of the dependencies.  You can also use the pkgmogrify tool to use a basic manifest template and process it into the final form if needed.

https://forums.oracle.com/ords/apexds/post/while-packaging-is-there-a-way-to-circumvent-that-pkgdepend-6809

So, if you control the entire set of systems being targeted or can require minimum requirements down to the patch level, the first solution is fine. However, if you are a third party source for Solaris users, you probably don’t have as much control. That’s where pkgmogrify can help.

pkgmogrify

pkgmogrify collects all its input files and then applies any directives found to the inputs. There are more directive available, but the one we’re interested in here is transform with the edit operation.

First, lets go back to the depend directive in the package manifest to understand how we’re going to change it:

depend fmri=pkg:/shell/bash@5.1.16-11.4.45.0.1.119.0 type=require
  • depend is the action we’re trying to match
  • fmri and type (following by = and a value) are attributes

Now, we’re going to jump to the transform directive to fix it:

<transform depend fmri=pkg:/shell/bash -> edit fmri '@.+' ''>
  • transform is the transform directive. There is also an include directive, but we won’t be using that here.
  • depend is going to be be matched as the action type
  • fmri=pkg:/shell/bash is going to be matched as an attribute=<value-regexp> key pair. So the value after the = is matched as a regex. Fortunately, no regex special characters here, so it just reduced to a substring match
  • -> is the separator between the matching criteria on the left and then operation to be performed on the right.
  • edit signals that we want to change according to a regex match and substitution. add, default, delete, drop, emit, exit, print, and set are also available. Set the linked man page above for more on those.
  • the fmri after edit is the name of the attribute that we’re modifying. Yes, it does seem like this is redundant because the attribute name on the match side seems to be an exact match.
  • '@.+' is the match regex. For the value pkg:/shell/bash@5.1.16-11.4.45.0.1.119.0 that will match on @5.1.16-11.4.45.0.1.119.0 as a greedy match.
  • '' (this is two single quotes, not a double quote as it may appear in examples elsewhere) specifies the replacement value, which in this case is an empty string.

Based on the above directive, we’re truncating the @ and everything after it in the fmri value. Note that type=require is a completely different key/value attribute pair and is unaffected.

Our output from pkgmogrify manifest.res transform-doc will look like the following (oversimplified to relevant inputs and outputs):

# manifest.res
depend fmri=pkg:/shell/bash@5.1.16-11.4.45.0.1.119.0 type=require

# transform-doc
<transform depend fmri=pkg:/shell/bash -> edit fmri '@.+' ''>

# output
depend fmri=pkg:/shell/bash type=require

The new depend directive will match whatever version of bash is available.

Reducing the pkgmogrify transforms

If you’re trying to be backwards-compatible, you’re probably dealing with more than one version conflict. In the case of something like our original set of dependencies mentioned earlier, you would need a transform that addressed each:

<transform depend fmri=pkg:/shell/bash -> edit fmri '@.+' ''>
<transform depend fmri=pkg:/shell/ksh93 -> edit fmri '@.+' ''>
<transform depend fmri=pkg:/system/core-os -> edit fmri '@.+' ''>
<transform depend fmri=pkg:/system/library/libc -> edit fmri '@.+' ''>
<transform depend fmri=pkg:/system/library/math -> edit fmri '@.+' ''>
<transform depend fmri=pkg:/system/library/security/crypto -> edit fmri '@.+' ''>
<transform depend fmri=pkg:/system/library -> edit fmri '@.+' ''>
<transform depend fmri=pkg:/system/linker -> edit fmri '@.+' ''>

But the match criteria are regular expressions, so you can do the following instead (or however short you want the match string to be):

<transform depend fmri=pkg:/shell -> edit fmri '@.+' ''>
<transform depend fmri=pkg:/system -> edit fmri '@.+' ''>

Keep in mind that this could be a blunt instrument that could impact more dependencies than you intended if you make the match criteria too generic.

Some other commands

Install a package from file

sudo pkg install -g some-package-file-or-uri.p5p package-name

The -g option directs pkg install to use a file path or uri to install the package. package-name still has to match the package file given.

Information on the package

pkg info [-g some-package-file-or-uri.p5p] package-name

$ pkg info bash
             Name: shell/bash
          Summary: GNU Bourne-Again shell (bash)
         Category: System/Shells
            State: Installed
        Publisher: solaris
          Version: 5.1.8
           Branch: 11.4.36.0.1.101.0
   Packaging Date: July 16, 2021 at  2:42:47 AM
Last Install Time: November 11, 2023 at 12:42:14 AM
             Size: 6.86 MB
             FMRI: pkg://solaris/shell/bash@5.1.8-11.4.36.0.1.101.0:20210716T024247Z
      Project URL: https://www.gnu.org/software/bash
       Source URL: https://ftp.gnu.org/gnu/bash/bash-5.1.tar.gz

List all the files in the package

pkg contents [-g some-package-location.p5p] package-name

$ pkg contents bash
PATH
etc/bash/bash_completion.example
etc/bash/bashrc.example
etc/bash/inputrc.example
etc/skel/.bashrc
usr/bin/bash
usr/bin/bashbug
usr/bin/rbash
usr/gnu/bin/sh
usr/share/bash/alias
usr/share/bash/arith
usr/share/bash/arith_for
usr/share/bash/bg
usr/share/bash/bind
usr/share/bash/break
usr/share/bash/builtin
usr/share/bash/caller
usr/share/bash/case

Uninstall

sudo uninstall package_name


Leave a Reply