-
Notifications
You must be signed in to change notification settings - Fork 55
Description
A little background for any reader who might not be familiar with Unix-likes besides Linux:
Modern FreeBSD and DragonFly BSD use a package manager called pkg which has been available as an alternative from FreeBSD 8.4 onward and as the only supported pm since FreeBSD 10.0. It replaced what was known as the pkg*_ tools. The latter (or rather a re-implementation thereof) is still used on OpenBSD. On modern Solaris / illumos the "Image Packaging System" is used and the package manager for that is also called pkg.
Depending on how far Comtrya wants to take portability, it makes sense to consider this when choosing a provider name. Since Solaris and BSD use different manpage sections, a common differentiator is to use these when referring to either BSD's pkg(8) or Solaris' pkg(1). I'd probably call the provider "bsdpkg" or something; it's just helpful to be aware of the potential name clash upfront.
To allow for more rapid development, pkg(8) is not part of FreeBSD's base system. The system ships with a script, though, which transparently does the actual bootstrap and acts as a wrapper afterwards. FreeBSD's default shell is not bash but the C-shell variant called tcsh. This requires setting environment variables with env $SOMETHING=$VALUE $COMMAND-TO-RUN instead of $SOMETHING=$VALUE $COMMAND as you'd do with a bourne shell.
One thing to take into account regarding pkg(8) is that you are supposed to read the summary of actions to be taken before acknowledging it. The reason is that pkg deals with conflicts by proposing package removal of already installed packages. This is perfectly expected if e.g. installing Salt 300x on a system that still has Salt 2019 installed: As both install files to the same location, they are in conflict.
However in certain situations (due to interesting dependency issues) you can install a new package and end up having e.g. Libre Office or Firefox deleted. This definitely does not happen very often with the official FreeBSD repo, but somewhat more frequently for people rolling their own packages (which is a common thing to do). Since an automation tool cannot decide if pkg's proposal is the right thing for the system, this is a potential problem (I've had Salt screw up systems like this a couple of times over the years). Might make sense to choose safety by default here and allow for a special variable like "tolerate_remove" or something which defaults to "no".
To give the reader an impression of what that looks like, here's the output for trying to install the old version of Salt on a system that has a current version installed:
Checking integrity... done (1 conflicting)
- py37-salt-2019-2019.2.8 conflicts with py37-salt-3002.5 on /usr/local/etc/salt/master.sample
Checking integrity... done (0 conflicting)
Conflicts with the existing packages have been found.
One more solver iteration is needed to resolve them.
The following 4 package(s) will be affected (of 0 checked):
Installed packages to be REMOVED:
py37-salt: 3002.5
New packages to be INSTALLED:
gmp: 6.2.1
py37-pycrypto: 2.6.1_3
py37-salt-2019: 2019.2.8
Number of packages to be removed: 1
Number of packages to be installed: 3
The operation will free 1 MiB.
Proceed with this action? [y/N]:
Here's some thoughts on an actual pkg provider:
Bootstrapping function:
- Check whether /usr/local/sbin/pkg exists
- Yes: Already bootstrapped, nothing to do
- No: Execute "env ASSUME_ALWAYS_YES=1 /usr/sbin/pkg bootstrap" to bootstrap without having to press "y"
Updating repository catalogue function (probably not even needed - pkg does this automatically if the catalogue is too old):
- Execute "pkg update"
Installing a package:
- If tolerating package removes on install: Execute "pkg install -y $PACKAGENAME"
- If not tolerating removes: Execute dry run "pkg install -n $PACKAGENAME"
- Parse output for "REMOVED", fail if encountered
- Execute "pkg install -y $PACKAGENAME"
Removing a package:
- Execute "pkg delete -y $PACKAGENAME"