Packages and file collisions

Blog post by Sil2100 on Thu, 2007-05-10 18:29

Finally back with a proper development environment.

Seizing the opportunity of having some free time, I finished implementing the user interface and prepared everything for package file parsing. Since I have yet to analyze the .pkg format throughout, I'd rather have everything prepared for this to come. From what I see from the materials sent by Ryan, the format itself doesn't seem to be as complicated, but there are still quite some unknowns. I will have to do some tests on a BeOS platform to see how a few other things work. For instance - unknown various bytes between the package description and the package author and name. Probably unessential though...
I will look into this more as soon as possible.

In the comments of my previous blog entry, the topic of package file collision handling was moved. Even though this is not a very important issue, it's certainly worth some thought. For now, we decided that this will be either left as it is or probably handled in a backup preservation flavor. After adding some attribute goodness (as proposed by Ryan), the result might be quite practical. Let me explain the idea on a simple example.

Let us suppose that the user has CoolApp1 installed on his computer. Now he wants to install package CoolApp2, which has some colliding files with the ones coming from CoolApp1. What will the installer do with such files in this situation? The original ones from CoolApp1 would be renamed as backups and left in the same directory they were in the beginning - with an attribute added to indicate from which package they come from exactly. Then the new ones, from CoolApp2, would be copied in their place.
Now, let's suppose the user uninstalls CoolApp2. The uninstaller would first remove the files belonging to the actual package - in this case, the actual files, not backups. In the next step the previous version of the file, saved as backup till now, would be renamed back to the original name and put in its place as if nothing happened.
If, however, the user would first want to uninstall CoolApp1, the uninstaller would - as previously - remove only the files belonging to the package. In this case, this would mean the backups. Easy.

What are the benefits of such approach? There would be no collisions, having all previous versions properly preserved. Of course, the implementation details are still unknown, as well as the possibility of how the user could have control over this process. PackageInspector, for instance, could then be able to manipulate which version (from which of the installed packages) of a file would be currently in use. Certainly a thing worth discussing.

Comments

Re: Packages and file collisions

1. Wouldn't CoolApp1 expect to find it's add-ons, libraries, data and what-not, by their filenames (or relative path names) and thus find the ones from CoolApp2 instead? This assumes that CoolApp1 is fine with using the files of CoolApp2. If not, how does CoolApp1 know that its files have been renamed? A new API for an application to find its (package-originated-)files, one might propose, but the whole (to me) idea of the PackageInstaller is to allow the old, closed source applications to be installed in Haiku, and these applications can't easily be patched to cope with a changed environment.

Collisions have thankfully not been too common in BeOS, if one uses primarily native applications, but it could get worse if a lot of libraries and script frameworks get ported and developers choose to install these in shared locations instead of within the application folder. How do we cope with this? I think this is beyond the PackageInstaller which should remain a mere installer/uninstaller. (Keep it simple and let's try something else for libraries? I don't know. I'd like to see a package filesystem of some kind. Packages as virtual filesystem overlays?)

2. What if the 1'st set of files ("CoolApp1") were not installed by the package installer, are not part of any known package, and were just unzipped (as per usual in BeOS) or built in place? What package attributes are added the colliding (and renamed) files tagged with? These files may even belong to multiple applications, or to none.

3. In the time between installing CoolApp1, CoolApp2 and uninstalling CoolApp2, (putting the colliding files of CoolApp1 back in place), the user (or some application) may have started using some of the files of CoolApp2, like an image, a sound or something, and suddenly this resource gets pulled and a different file (from CoolApp1) by the same name, gets put in its place, perhaps without any warning.

Just thinking out loud. :]

I think the concept of using attributes to tag collections of files is great, and it's been long coming. I will be very happy to see it implemented, even though I personally hope we won't be needing the PackageInstaller any more in Haiku than we did in BeOS. I prefer zipfiles (BeOS) or disk images (MacOSX) and drag&drop of self-contained application folders as the primary way to install and manage applications. I don't mean any disrespect to your work on the installer. I'm sorry if this is too negative. I'm one of those who will miss a pre-flight collision alert, who inspect packages before-hand and distrust installers in general. :P

Re: Packages and file collisions

jonas.kirilla wrote:

1. Wouldn't CoolApp1 expect to find it's add-ons, libraries, data and what-not, by their filenames (or relative path names) and thus find the ones from CoolApp2 instead? This assumes that CoolApp1 is fine with using the files of CoolApp2. If not, how does CoolApp1 know that its files have been renamed? A new API for an application to find its (package-originated-)files, one might propose, but the whole (to me) idea of the PackageInstaller is to allow the old, closed source applications to be installed in Haiku, and these applications can't easily be patched to cope with a changed environment.

Yes, but this is a problem that cannot be solved much by any logical means right now. The idea is to leave the 'right' working (for a given package) files in place, so that they would not vanish completely. As I mentioned in my blog post, there also might be a tool to manipulate which file (from which package) would currently be the one used by all packages (with the normal filename).

jonas.kirilla wrote:

2. What if the 1'st set of files ("CoolApp1") were not installed by the package installer, are not part of any known package, and were just unzipped (as per usual in BeOS) or built in place? What package attributes are added the colliding (and renamed) files tagged with? These files may even belong to multiple applications, or to none.

In this case no attribute would be added to such 'backed up' (renamed) file, since it does not come from any package. When uninstalling, it would simply be renamed back to what it was before.

jonas.kirilla wrote:

3. In the time between installing CoolApp1, CoolApp2 and uninstalling CoolApp2, (putting the colliding files of CoolApp1 back in place), the user (or some application) may have started using some of the files of CoolApp2, like an image, a sound or something, and suddenly this resource gets pulled and a different file (from CoolApp1) by the same name, gets put in its place, perhaps without any warning.

This is also something that probably cannot be solved. I think that one thing we might consider to make this better is informing/prompting the user when something like this happens, letting him decide what action to take. This would make uninstalling a bit complicated for normal users though...

jonas.kirilla wrote:

Just thinking out loud. :]

I made this post exactly for the purpose of hearing opinions about this idea and discussing its probable details. All thoughts like these are most welcome! ^^

Re: Packages and file collisions

Hi Łukasz,

Łukasz wrote:
jonas.kirilla wrote:

1. Wouldn't CoolApp1 expect to find it's add-ons, libraries, data and what-not, by their filenames (or relative path names) and thus find the ones from CoolApp2 instead? This assumes that CoolApp1 is fine with using the files of CoolApp2. If not, how does CoolApp1 know that its files have been renamed? A new API for an application to find its (package-originated-)files, one might propose, but the whole (to me) idea of the PackageInstaller is to allow the old, closed source applications to be installed in Haiku, and these applications can't easily be patched to cope with a changed environment.

Yes, but this is a problem that cannot be solved much by any logical means right now. The idea is to leave the 'right' working (for a given package) files in place, so that they would not vanish completely. As I mentioned in my blog post, there also might be a tool to manipulate which file (from which package) would currently be the one used by all packages (with the normal filename).

Why don't you just move the files to some backup location instead of renaming them? That way, you're less likely to break the app in case of upgrades (e.g., driver upgrade, add-on upgrade, etc.).

Re: Packages and file collisions

Quote:

Why don't you just move the files to some backup location instead of renaming them? That way, you're less likely to break the app in case of upgrades (e.g., driver upgrade, add-on upgrade, etc.).

Again, is it necessary to move OR rename them? Why not let versions co-exist and choose what is the default version of the library?

Chris

Re: Packages and file collisions

Clebin wrote:

Again, is it necessary to move OR rename them? Why not let versions co-exist and choose what is the default version of the library?

As far as I can see (and understand, since I did not have yet the pleasure of using a mac), the Mac OS X method you proposed might make some things quite complicated. Since BeOS did not have such a feature in any way, installing 'versions' right from the bat to a different directory and then leaving a simlink in the actual directory might be quite a hassle. I mean, since these are BeOS 'legacy' packages, I don't think we should change the way application files were installed as much as you propose.
Another thing is the naming of those directories. It wouldn't be so simple as just a version number, because we want to find a way not only for 'newer versions' of a package, but also the situations when the same file from a different package would want to overwrite the existing one. Since files do not have any version number or whatever from the start, the names of the directories would have to be package names. In my opinion - that would add some unnecessary, complicated directories in the tree.

Waldemar Kornewald wrote:

Why don't you just move the files to some backup location instead of renaming them? That way, you're less likely to break the app in case of upgrades (e.g., driver upgrade, add-on upgrade, etc.).

This would be one good solution for not unnecessary loitering the directory tree. But with this, it would be best to make an application for 'package file version management'.

Re: Packages and file collisions

Łukasz wrote:
Waldemar Kornewald wrote:

Why don't you just move the files to some backup location instead of renaming them? That way, you're less likely to break the app in case of upgrades (e.g., driver upgrade, add-on upgrade, etc.).

This would be one good solution for not unnecessary loitering the directory tree. But with this, it would be best to make an application for 'package file version management'.

Why should we need such an application? You could either get the files from the backup folder or by uninstalling some package. It's not really a common operation and any other package manager would uninstall the files (the whole colliding package). Also, the PackageInspector could be used to extract older file versions.

Re: Packages and file collisions

Clebin wrote:
Quote:

Why don't you just move the files to some backup location instead of renaming them? That way, you're less likely to break the app in case of upgrades (e.g., driver upgrade, add-on upgrade, etc.).

Again, is it necessary to move OR rename them? Why not let versions co-exist and choose what is the default version of the library?

How can you automatically choose the best version if it's an add-on or data file? Adding an overlay FS just for this task is also too complicated for R1. We'll work on improved installation for R2 and there it hopefully won't be necessary to have these "hacks". :)

Re: Packages and file collisions

Thanks both for your answers. Yes, I agree if we're just talking about legacy packages and R1 - I should've realised this from the project abstract.

My biggest dislike of Windows and Linux is the way they manage applications and shared files so it's an issue that's close to my heart.

Sorry to take up your time, and good luck.

Chris

Re: Packages and file collisions

Maybe each app with colliding files should have a directory with symlinks to the proper files.
So when linking the libraries the OS should search them in this order:
1. The application directory
2. The directory with the colliding library symlinks (/boot/home/config/etc/CoolApp2.conflicts)
3. /boot/home/config/lib
4. /beos/system/lib

a similar approach can be used for other files (not just libraries)

Re: Packages and file collisions

I like the way Mac OS X deals with frameworks, where each version is installed in a folder named with the version number and a symlink points to the latest.

Frameworks
--Some.framework
---- 1.0
---- 1.1
---- Current -> 1.1

Your system sounds similar, but do you have to make them 'backups' rather than concurrently installed versions? A user could choose to intsall version 2.0alpha for some new feature but not want to use it for every app. When you're dealing with the Java framework or something like that, it's nice to have the flexibility to choose what is current and over-ride it for particuar apps.

Chris