Solved How to uninstall a package without pkg?

I have a chicken&egg problem...

I tried to update Python according to the instructions in /usr/ports/UPDATING, using portmaster(8).
To begin, portmaster(8) uninstalled ports-mgmt/pkg.
Then the installation of the new version of ports-mgmt/pkg failed, because it conflicts with security/base-audit. (If /usr/ports/UPDATING had mentioned this conflict I would have uninstalled security/base-audit first, but unfortunately it didn't.)
So I'm now left with a system that does not have ports-mgmt/pkg installed, and that cannot install ports-mgmt/pkg, because of a conflict with base-audit.

I cannot uninstall base-audit, because I don't have pkg(8).
The backup of the old ports-mgmt/pkg that portmaster(8) made in the /usr/ports/packages/portmaster-backup/ directory is a package that must be installed using pkg(8), so I cannot reinstall the backup either.
The security/base-audit directory was deleted from the ports tree because of the merge with net-mgmt/pkg, but I copied this directory from another system in the hopes that I could run make deinstall. But unfortunately that also depends on pkg(8).

So, how do I go about?

All I can think of now is to generate a list of files from /var/db/pkg/local.sqlite, and then manually delete base-audit's files (and the entries in local.sqlite), but I really hope that there's a better way...

Thanks in advance.
 
Last edited by a moderator:
If you try to run pkg when it's not currently installed (typically after a fresh install), you normally get offered to bootstrap it. Doesn't this work in your case?
 
I haven't tried it but can you extract pkg package and execute pkg command.

I thought about copying pkg from another machine, but they are different versions (even different FreeBSD versions), and I don't want to risk messing up my package database.
If someone could confirm that this is safe, I will most certainly try this.

If you try to run pkg when it's not currently installed (typically after a fresh install), you normally get offered to bootstrap it. Doesn't this work in your case?

Unfortunately not:
Code:
$ pkg
bash: /usr/local/sbin/pkg: No such file or directory
 
I thought about copying pkg from another machine, but they are different versions (even different FreeBSD versions), and I don't want to risk messing up my package database.
If someone could confirm that this is safe, I will most certainly try this.



Unfortunately not:
Code:
$ pkg
bash: /usr/local/sbin/pkg: No such file or directory
Can't you tar x the pkg file in your system
 
This should not have happened, but I do not understand the sequence of events that lead to this issue.
If a port is added to MOVED, then it should be de-installed and replaced by the port built from the new origin.
That should not lead to the pkg command being deinstalled.
I'll try to reproduce the issue by installing from a check-out of the ports tree that precedes the removal of the pkg-audit port and performing the update that has been reported to removed the pkg command.

BTW: the pkg command in /usr/sbin should still have been available to perform a "pkg bootstrap", provided the system is online (as it typically is when updating from ports).
 
That should not lead to the pkg command being deinstalled.
I think this happened because portmaster(8) tried to update ports-mgmt/pkg. It got as far as removing the old version but failed installing the new one due to a conflict with base-audit.

The security/base-audit directory was deleted from the ports tree because of the merge with net-mgmt/pkg, but I copied this directory from another system in the hopes that I could run make deinstall.
That's some next level foot-shooting here.
 
That's some next level foot-shooting here.
Not really.

I'm sure you've done make deinstall reinstall before, without having to make sure that the port version in the ports tree matches the installed version.

Actually, make deinstall does pkg delete -f (see /usr/ports/Mk/bsd.port.mk, around line 3700), which means
1) make deinstall doesn't care about the version in the ports tree, but only about the installed version
2) make deinstall doesn't care about dependencies or other sensitivities

I'm pretty sure that if make deinstall were implemented without using pkg, it would do something like

Code:
sqlite3 /var/db/pkg/local.sqlite "select all filenames for this_package"
rm -f resulting_files
rmdir resulting_directories
sqlite3 /var/db/pkg/local.sqlite "delete all entries related to this_package"

I didn't check beforehand, but I was fully confident that make deinstall wouldn't (couldn't) care about the port version currently in the ports tree (and it turns out I was right :) ).
 
I'm sure you've done make deinstall reinstall before, without having to make sure that the port version in the ports tree matches the installed version.
No, but I did do yum erase yum once on RedHat. Not the smartest thing I did ?

I'm pretty sure that if make deinstall were implemented without using pkg, it would do something like
Ports build packages. What you don't notice (it's all done behind the scenes) is, a port is installed in a 'staging' area and a package is created from that. That package is what actually gets installed if you run make install in a port's directory.
 
No, but I did do yum erase yum once on RedHat. Not the smartest thing I did ?

That's how we learn... :)

Ports build packages. What you don't notice (it's all done behind the scenes) is, a port is installed in a 'staging' area and a package is created from that. That package is what actually gets installed if you run make install in a port's directory.

True.
But a package is nothing more than a tarball containing files (executables, config, docs) packed according to a defined structure, so that pkg knows where to copy those files on the hard disk. And maybe a pre or post install script, to create users or the likes.
There's nothing magic about packages. They are just intermediate vehicles between compilation and installation of the files, to make sure pkg (or yum, or apt) always receive the files to be installed according to the same specs, so they only need to understand a single file format.

FreeBSD packages are actually XZ compressed tar balls, so to see their contents you'd do something like

Code:
tar tzf somepackage-1.2.3.pkg

And pkg just copies these files to disk, executes the scripts, if any, and registers all files and directories, the installation time and all forward and backward dependencies in /var/db/pkg/local.sqlite.
So uninstalling is just retrieving the file list from the sqlite database, deleting all the files, and deleting all entries from the database.
 
Back
Top