choco icon indicating copy to clipboard operation
choco copied to clipboard

Transactional package installation to revert changes in case of installation failure

Open talcloudshare opened this issue 10 years ago • 21 comments

When chocolateyInstall.ps1 fails, Chocolatey doesn't revert the actions already taken during the failed installation process (it's not transactional).

In my case, I registered a windows service in the chocolateyInstall.ps1 script and afterwards the script failed, that left the service and it's files installed on the computer. As the package is not marked as installed, I cannot call choco uninstall ("package_name is not installed. Cannot uninstall a non-existent package.").

It would be helpful if there would be a mechanism for reverting failed installations (implement transactions), or if it would be possible to automatically run an uninstall script (chocolateyUninstall.ps1) after a failed installation.

talcloudshare avatar May 17 '15 13:05 talcloudshare

You mean like try/catch?

ferventcoder avatar May 19 '15 15:05 ferventcoder

Yes, I can see it being done by running the entire installation code in a Try scope, and calling the restore previous state code (which is likely to be the uninstallation code) in the Catch scope.

talcloudshare avatar May 19 '15 16:05 talcloudshare

"The best thing about Chocolatey is that it lets you do darn near anything in the PowerShell script. The worst thing about Chocolatey is that it lets you do darn near anything with PowerShell."

I meant you could do it on a package by package basis now in a try/catch in the PowerShell script file. It appears you are creating the packages, so you have the power to influence what happens if the PowerShell file fails for any reason.

In the long term future I can see this being something for Chocolatey to try to handle as well.

The problem in some cases is that you are using the PowerShell to do your own actions, it seems that it is also in your purview to handle the reverting of those actions should they fail. It would be much easier than trying to have Chocolatey determine what you did and try to revert it.

In the future perhaps there could be the use of the DTC to try to handle any changes to the system and revert them. For now, I would use the PowerShell try/catch mechanism to clean up anything that fails during the Posh script.

ferventcoder avatar May 19 '15 16:05 ferventcoder

Yes, I can see it being done by running the entire installation code in a Try scope, and calling the restore previous state code (which is likely to be the uninstallation code) in the Catch scope.

The problem here is that if the install code can't be trusted to work properly and be idempotent, then why would the uninstall code be trusted to work correctly?

ferventcoder avatar May 19 '15 16:05 ferventcoder

Chocolatey already takes quite a bit of transactional action in the area it can for a package. It is expected the the install scripts are sound and can take action to revert if they are not in anything they do to the system outside of what Chocolatey provides as functions.

It's not perfect and it will get better, but please understand that there is quite a bit of power that the package has to influence transactional behavior on its own.

ferventcoder avatar May 19 '15 16:05 ferventcoder

I find myself avoiding installing packages that interact with the registry via Chocolatey now because I have no idea what the package will do, and how I'm supposed to undo it. This is a hard problem, especially without OS support, but it would be great if you could consider changing the packaging model here so that it is a bit more structured than "run this powershell script and pray".

Some kind of manifest that describes the changes a package makes would go a long way, and you can use continuous integration in a VM to construct such a manifest for existing packages. The idea would roughly be to take VSS snapshots of the disk before and after installation and diff them, and use facter or something to extract structured information from the diff.

masaeedu avatar May 11 '17 18:05 masaeedu

@masaeedu I'm going to assume you rely mostly on packages built by the community instead of internal packages. I'm also going to make the assumption you are probably using the community package repository. Have you noticed that for nearly two years we've been running tests of actual package installs? You know that little green ball / red ball up by the package title on the package page? It's a link. It's clickable. It will provide all of the information you are talking about.

https://chocolatey.org/faq#what-is-the-verifier

ferventcoder avatar May 15 '17 22:05 ferventcoder

@ferventcoder Great! It would be really cool if this could be surfaced during the installation process.

Also, looking at the logs for the package that keeps borking my system, it doesn't really look like any of what I mentioned earlier is being captured. In "FilesSnapshot.xml" I only see four installed files, all of which are in the chocolatey/libs folder, and in "1.RegistrySnapshot.xml" there seems to be one registry key from the HKLM/blahblah/windows/Uninstall part of the registry. Those are easy to clean. What I care about tracking down is all the other files, services, drivers, environment variables, file associations, etc. packages introduce to my system.

The reason this is important is because if anything breaks during installation or uninstallation in a way that an uninstall script did not anticipate, I am usually permanently screwed and unable to use that chocolatey package until I hunt some indeterminate number of bits and bobs on my system and remove them. If I had a comprehensive manifest of what things a package did to some characteristic system, I'd stand a much greater chance of repairing my system when things go awry.

masaeedu avatar May 15 '17 23:05 masaeedu

The reason this is important is because if anything breaks during installation or uninstallation in a way that an uninstall script did not anticipate, I am usually permanently screwed and unable to use that chocolatey package until I hunt some indeterminate number of bits and bobs on my system and remove them. If I had a comprehensive manifest of what things a package did to some characteristic system, I'd stand a much greater chance of repairing my system when things go awry.

@masaeedu Does this happen often? I've been using Chocolatey and installers for years and can count on one hand the number of times I've had any issues like what you are describing (and zero times in the last six years - aka as long as choco has been around).

ferventcoder avatar May 15 '17 23:05 ferventcoder

We've looked at some tools that provide a snapshot of all changes to registry and the file system and have also thought about capturing more of the files that have changed on the system instead of just in the package folder (like it currently captures).

ferventcoder avatar May 15 '17 23:05 ferventcoder

@ferventcoder Yes, it happens so frequently I now have a mental list of which things I need to use bare MSIs or scoop.sh for. I guess the difference between my usage and yours might be that:

  1. I run all my Windows systems off a single frankenstein-ed together VHD, so I tend to have all kinds of crap installed into a single image
  2. I'm in QA, so most of my job is breaking stuff
  3. I mostly use community packages that someone threw together to suit their needs

We've looked at some tools that provide a snapshot of all changes to registry and the file system and have also thought about capturing more of the files that have changed on the system instead of just in the package folder (like it currently captures).

This would be a huge bonus, for me at least.

masaeedu avatar May 15 '17 23:05 masaeedu

@masaeedu have you ever heard of turbo?

ferventcoder avatar May 15 '17 23:05 ferventcoder

@ferventcoder Yeah, I actually tried it for a while. It seems like a great concept but it was pretty locked down and I basically got stonewalled on support during the trial period.

masaeedu avatar May 15 '17 23:05 masaeedu

@masaeedu sorry to hear that. There is also sandboxie. I've not used it but I hear it works well for similar.

ferventcoder avatar May 15 '17 23:05 ferventcoder

https://chocolatey.org/packages/sandboxie

ferventcoder avatar May 15 '17 23:05 ferventcoder

I know that one of these tools would allow us to run tests, then shut down the container and determine everything that changed. However it's not as universal as using vagrant for testing.

ferventcoder avatar May 15 '17 23:05 ferventcoder

@ferventcoder I also have Sandboxie, it works really well. However, there's the licensing model to contend with once again.

How about just starting with VSS to image your disk? You could implement this incrementally; starting with just diffing filesystems on a "before" and "after" snapshot of the disk. You can always go on to extract more structured information from e.g. the registry files.

masaeedu avatar May 15 '17 23:05 masaeedu

There used to be a tool a long time ago called System State Analyzer that used to do just this.

masaeedu avatar May 15 '17 23:05 masaeedu

Good notes! It all depends on performance of the implementation - it does need to have an acceptable performance impact. If a diff takes an hour to do, that is definitely out. TBH, if it has more than a 2 minute performance impact overall, (take original, take ending, diff, etc), then it is likely not going to be acceptable.

ferventcoder avatar May 16 '17 22:05 ferventcoder

I'm pretty sure the changed blocks between any two disk images are available cheaply, the question is whether these can easily be associated back to the filesystem. I believe libvirt provides some tools for diff-ing disks but I need to see whether this can be applied to VSS snapshots or whatever virtualization technology you're using for your CI. Btw, what are you using for CI?

masaeedu avatar May 16 '17 22:05 masaeedu

CI? AppVeyor, TeamCity, and Travis CI.

ferventcoder avatar May 29 '17 21:05 ferventcoder

Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward? This issue will be closed in 14 days if it continues to be inactive.

github-actions[bot] avatar Feb 23 '24 04:02 github-actions[bot]

Dear contributor,

As this issue seems to have been inactive for quite some time now, it has been automatically closed. If you feel this is a valid issue, please feel free to re-open the issue if / when a pull request has been added. Thank you for your contribution.

github-actions[bot] avatar Mar 08 '24 04:03 github-actions[bot]