Solved pkg and "options changed"

Hi, I am using FreeBSD 11.1-RELEASE-p9.
I use binary packages, except for mailman (which I needed to install via ports because of some options, see Thread 65502).
Everytime I use pkg upgrade, I get this:

Code:
# pkg upgrade
Updating FreeBSD repository catalogue...
Fetching meta.txz: 100%    944 B   0.9kB/s    00:01
Fetching packagesite.txz: 100%    6 MiB   3.2MB/s    00:02
Processing entries: 100%
FreeBSD repository update completed. 31143 packages processed.
All repositories are up to date.
Checking for upgrades (2 candidates): 100%
Processing candidates (2 candidates): 100%
The following 2 package(s) will be affected (of 0 checked):

Installed packages to be UPGRADED:
        libnghttp2: 1.31.0 -> 1.31.1

Installed packages to be REINSTALLED:
        mailman-2.1.26_4 (options changed)

Number of packages to be upgraded: 1
Number of packages to be reinstalled: 1

108 KiB to be downloaded.

Proceed with this action? [y/N]: n

Of course I don't want to reinstall mailman, as it will be reverted to binary package's options.
What is correct way to handle this situation?
Should I simply ignore this warning, and upgrade only other package (in this case, only libnghttp2 for example)?
Thank you
 
What is correct way to handle this situation?
Build your own package repository, point pkg to it, and install mailman once via pkg install -r yourrepo -f mailman.

EDIT: Here's the long answer.

You can use Synth or Poudriere to create the repository but you don't have to.

Create /usr/local/etc/pkg/repos/local.conf
Code:
local: {
    url: "file:///usr/ports/packages"
    enabled: yes
}

Then
Code:
mkdir /usr/ports/packages
make -C /usr/ports/mail/mailman package
pkg repo /usr/ports/packages
pkg update
pkg install -r local -f mailman
Thanks to CONSERVATIVE_UPGRADE pkg will now strongly prefer the local repository over others when looking at mailman and pkg shouldn't try to upgrade it from the FreeBSD repo anymore.
 
Of course I don't want to reinstall mailman, as it will be reverted to binary package's options.
This is exactly why you should not mix ports with binary packages and what you're experiencing is a failsave mechanic. For good reasons too.

But as with all things there is an easy way out. It's most definitely not the best solution because if you don't know what you're doing you are going to run into problems in the longer run. And with all due respect: there was a reason why you asked here.

So yeah... # pkg upgrade -Fy, now all upgrades get downloaded into /var/cache/pkg without anything being done. All that's left is to install the packages you need using pkg add. A lot less effort than rolling your own repository and when applied correctly this can work without causing issues.

I'd still advice against this though.
 
For dual maintenance of ports & packages, I use a shell script and at the top of it, I inform explicitly the ports which I need to be installed from source because of customized options. This works very well on several installations for a few years already. Here comes the shell script:
Bash:
#!/bin/sh

### the list of the ports that shall be updated from sources
portslist="\
apr \
subversion \
cairo \
poppler \
poppler-utils \
php72 \
mod_php72 \
\
php72-iconv \
php72-mbstring \
php72-pgsql \
php72-filter \
php72-hash \
php72-session"

### fetching FreeBSD system updates
/usr/bin/printf "Fetching FreeBSD system updates...\n"
PAGER=/bin/cat
/usr/sbin/freebsd-update fetch

### fetching updates of the FreeBSD ports tree
/usr/bin/printf "\nFetching updates of the FreeBSD ports tree...\n"
/usr/sbin/portsnap fetch update
/usr/sbin/pkg version -v
/usr/sbin/pkg updating -d `date -v-2w +%Y%m%d`

### ask and in case of y|Y run the updating processes
/usr/bin/printf "\nDo you want to continue (y/n)? "
save_stty_state=$(stty -g); stty raw -echo; answer=$(head -c 1); stty $save_stty_state
if echo "$answer" | grep -iq "^y" ; then
   /usr/bin/printf "\n\n"
   /usr/sbin/pkg update

   portmake=""
   pkgslist=`/usr/local/bin/sqlite3 -list /var/db/pkg/local.sqlite 'select name from packages;' | xargs`
   for port in $portslist ; do
      for pkg in $pkgslist ; do
         if [ "$pkg" == "$port" ] ; then
            continue 2
         fi
      done

      portmake="$portmake $port"
   done

   pkgslist=""
   outdated=`/usr/sbin/pkg version -l\< | /usr/bin/cut -f1 -w`
   for outd in $outdated ; do
      outd=`/usr/sbin/pkg query %n $outd`
      for port in $portslist ; do
         if [ "$port" == "$outd" ] ; then
            portmake="$portmake $port"
            continue 2
         fi
      done

      pkgslist="$pkgslist $outd"       
   done

   pkgupgrd=""
   outdated=`/usr/sbin/pkg version -RU -l\< | /usr/bin/cut -f1 -w`
   for outd in $outdated ; do
      outd=`/usr/sbin/pkg query %n $outd`
      for pkg in $pkgslist ; do
         if [ "$pkg" == "$outd" ] ; then
            pkgupgrd="$pkgupgrd $outd"
            continue 2
         fi
      done
   done

   /usr/bin/printf "\nUpdating binary packages...\n"
   if [ "$pkgupgrd" != "" ] ; then
      /usr/sbin/pkg upgrade -U $pkgupgrd
   else
      echo "All installed packages are up-to-date."
   fi

   /usr/bin/printf "\nUpdating ports...\n"
   if [ "$portmake" != "" ] ; then
      cwd=$PWD
      py="py27-"

      for port in $portmake ; do
         origin="`/usr/local/bin/sqlite3 /var/db/pkg/local.sqlite select\ origin\ from\ packages\ where\ name\=\'$port\'\;`"
         if [ "$origin" != "" ] ; then
            portdir="/usr/ports/$origin"
         else
            portdir="`ls -1d /usr/ports/*/$port`"
         fi
         if [ $? == 0 ] ; then
            cd "$portdir"
            /usr/bin/make deinstall clean
            if [ "${port#$py}" != "$port" ]; then
               /usr/bin/make FLAVOR=py27 install clean
            else
               /usr/bin/make install clean
            fi
         fi
      done

      cd "$cwd"

      rm -rf /usr/ports/distfiles/*
   else
      echo "All installed ports are up-to-date."
   fi

   /usr/bin/printf "\nCleaning up...\n"
   /usr/sbin/pkg clean -ay

   /usr/bin/find /usr/ports/distfiles -type f -mtime +4w -delete
   /usr/bin/find /usr/ports/distfiles -type d -depth +0 -and -empty -delete

else

   /usr/bin/printf "\n\n"

fi

In your case, you would need to set only "mailman" to the variable $portslist.

You want also to switch your packages to be updated from the latest repository.
# mkdir -p /usr/local/etc/pkg/repos
# ee /usr/local/etc/pkg/repos/FreeBSD.conf
Code:
FreeBSD: {
  url: "pkg+http://pkg.FreeBSD.org/${ABI}/latest",
}

The script should simply work on top of your installation, no special setup is needed. Beware that it also checks for base system updates. If you don't need it, you can safely remove that part from it.

The whole story about dual mode maintenance of ports & packages is available on my BLog – FreeBSD Dual Mode updating of the installed ports collection - https://obsigna.com/articles/1519780374.html
 
Last edited:
This is exactly why you should not mix ports with binary packages and what you're experiencing is a failsave mechanic. For good reasons too.

I really would like to use ONLY packages, but it seems impossible in my case.
It is not clear which command should I use to know that some update is available for mailman.
When using ports, I normally use this line in crontab:

Code:
0      3       *       *       *       root    portsnap -I cron update && pkg version -vIL=

When using packages, I normally use:

Code:
0     3       *       *       *       root    pkg version -vqL=

Now what? Should I keep both?
Thank you very much!
 
I really would like to use ONLY packages, but it seems impossible in my case.
Use Synth or Poudriere to set up your own repository. This will give you the best of both worlds, the ability to change options and the ease of use of packages.
 
Back
Top