Option Changed Reinstall

Ever noticed this in the middle of your update?

 

[...]
Installed packages to be REINSTALLED:
        unixODBC-2.3.2_1 (options changed)
        tidy-lib-090315.c_2 (options changed)
        t1lib-5.1.2_4,1 (options changed)
        spamassassin-3.4.0_17 (options changed)
        rrdtool-1.4.8_6 (direct dependency changed)
        pango-1.36.8 (options changed)
        p5-DateTime-HiRes-0.01_1 (direct dependency changed)
        oniguruma4-4.7.1_1 (options changed)
        m4-1.4.17_1,1 (options changed)
        liblqr-1-0.4.1_8 (options changed)
        gdbm-1.11_2 (options changed)
        freetype2-2.5.5 (options changed)
        freetds-0.91.103_2,1 (options changed)
        cairo-1.12.18_1,2 (options changed)
        aspell-0.60.6.1_5 (options changed)
        apache22-2.2.29_2 (options changed)
        apache-ant-1.9.4 (direct dependency changed)
[...]

 

How to find out what's causing it

Looking at the locally set options is done like this:

xxxx-89:/usr/local/etc/pkg/repos# pkg query '%Ok %Ov %Od %OD' spamassassin-3.4.0_17
AS_ROOT on on (null)
DCC off off (null)
DKIM off off (null)
GNUPG on on (null)
MYSQL off off (null)
PGSQL off off (null)
PYZOR off off (null)
RAZOR off off (null)
RELAY_COUNTRY off off (null)
SPF_QUERY off off (null)
SSL on on (null)
UPDATE_AND_COMPILE on on (null)

 

Looking at the remote options is done like this:

xxxx-89:/usr/local/etc/pkg/repos# pkg rquery '%Ok %Ov %Od %OD' spamassassin         
AS_ROOT on on (null)
DCC off off (null)
DKIM off off (null)
GNUPG on on (null)
GNUPG2 off off (null)
GNUPG_NONE off off (null)
MYSQL off off (null)
PGSQL off off (null)
PYZOR off off (null)
RAZOR off off (null)
RELAY_COUNTRY off off (null)
SPF_QUERY off off (null)
SSL on on (null)
UPDATE_AND_COMPILE on on (null)

So, in this case, the option GNUPG2 had been added and set to "off" which was the default there.

This means nothing really changed and that pkg is just not being really careful with the input. At least now it doesn't differentiate different cases of option differences.

Using this local/remote comparism, you can compare if a package difference will break any of your local configuration.

You can manually do it as above, or using the script further down.

Comments

 

please think carefully if you automatically run pkg!

What I can suggest is to first run pkg <action> -n and then screen-scrape the output.

You need not allow removal or reinstall changes from automation.

CFEngine, whenever it will happen, will actually hook into the pkg shell, but I doubt they can *fix* that.

If you work with custom / frozen repositories it's not as bad, but if you're on the smaller side, running just a few servers: please be really careful about this whole thing.

 

Debugging Script

Unfortunately I don't have time to make a good script for you (since I already spent that time finding out that this is in fact no worrysome option change)

What I can offer is working example using diff...

 

optsdiff.sh
#!/bin/sh
attnonly=n
if [ $# = 1 ] && [ $1 = "-a" ]; then
   attnonly=y
fi
cd /tmp
pkgs=`pkg upgrade -n | grep "options changed" | cut -f1 -d\-`
for pkgname in $pkgs ; do
    err=n
    pkg  query '%Ok %Ov %Od %OD' $pkgname > ${pkgname}.LQ
    pkg rquery '%Ok %Ov %Od %OD' $pkgname > ${pkgname}.RQ
    echo "---- option diff for $pkgname ----"
    DIFF=`diff ${pkgname}.LQ ${pkgname}.RQ | egrep "^<|^>"`
    BAD=`echo "$DIFF" | egrep ">.* off o"`
    if [ $? = 0 ]; then
       echo "ATTENTION for $pkgname"
       err=y
    fi
    if [ $attnonly = "y" ] && [ $err = "y" ] ; then
        echo "$BAD"
    fi
    if [ $attnonly = "n" ]; then
        echo "$DIFF"
    fi
done

 

 

The output looks like this:

---- option diff for rinetd ----
> DOCS on on (null)
---- option diff for portmaster ----
ATTENTION for portmaster
< BASH on on (null)
< ZSH on on (null)
> BASH off off (null)
> ZSH off off (null)
---- option diff for php53 ----
ATTENTION for php53
< APACHE on on (null)
> APACHE off off (null)
< IPV6 off off (null)
> IPV6 on on (null)
< MAILHEAD on on (null)
> MAILHEAD off off (null)
---- option diff for ncftp ----
> DOCS on on (null)
> LIBS on on (null)
---- option diff for makeself ----
> DOCS on on (null)
---- option diff for m4 ----
< EXAMPLES off off (null)
> EXAMPLES on on (null)
---- option diff for libexecinfo ----
> DOCS on on (null)

Here it indicates i.e. that the php-5.3 port probably now as a broken apache module.

Keyword to look at is "ATTENTION".

(Later ones had mod_php but not php-5.3. So, if i used pkg upgrade here without checking I might end up with a dead server)

 

if you call it with -a it'll reduce the output and show only ports where an option changed??? to off. Not sure if this is really the perfect solution.

It's past midnight, right now I think -a isn't yet correctly implemented...

You might also wanna add some code to not even have it mention DOCS / EXAMPLES? :)

 

Script for autodetection, new version

Filters DOCS and no output of package name if -a was given.

#!/bin/sh
attnonly=n
if [ $# = 1 ] && [ $1 = "-a" ]; then
   attnonly=y
fi
cd /tmp
pkgs=`pkg upgrade -n | grep "options changed" | cut -f1 -d\-`
for pkgname in $pkgs ; do
    err=n
    pkg  query '%Ok %Ov %Od %OD' $pkgname > ${pkgname}.LQ
    pkg rquery '%Ok %Ov %Od %OD' $pkgname > ${pkgname}.RQ
    #echo "---- option diff for $pkgname ----"
    DIFF=`diff ${pkgname}.LQ ${pkgname}.RQ | egrep "^<|^>"`
    BAD=`echo "$DIFF" | grep -v -e DOCS -e EXAMPLES | egrep ">.* off o"`
    if [ $? = 0 ]; then
       echo "---- option diff for $pkgname ----"
       echo "ATTENTION for $pkgname"
       err=y
    fi
    if [ $attnonly = "y" ] && [ $err = "y" ] ; then
        echo "---- option diff for $pkgname ----"
        echo "$BAD"
    fi
    if [ $attnonly = "n" ]; then
        echo "---- option diff for $pkgname ----"
        echo "$DIFF"
    fi
done

 

We might also want to skip off off (null) or off (null) off deltas, but I don't have enough experience for that.