Transactional package installation to revert changes in case of installation failure
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.
You mean like try/catch?
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 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.
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?
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.
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 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 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.
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).
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 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:
- 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
- I'm in QA, so most of my job is breaking stuff
- 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 have you ever heard of turbo?
@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 sorry to hear that. There is also sandboxie. I've not used it but I hear it works well for similar.
https://chocolatey.org/packages/sandboxie
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 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.
There used to be a tool a long time ago called System State Analyzer that used to do just this.
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.
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?
CI? AppVeyor, TeamCity, and Travis CI.
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.
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.