imagej / imagej2

Open scientific N-dimensional image processing :microscope: :sparkler:
https://imagej.net/
BSD 2-Clause "Simplified" License
1.13k stars 328 forks source link

Update, improve and automate the Chocolatey packages #152

Open ctrueden opened 7 years ago

ctrueden commented 7 years ago

The Chocolatey packages for ImageJ provide only ImageJ 1.x, and have not been updated in awhile. Would be great to update them to use ImageJ2, and then automate their deployment using a Jenkins job.

teknowledgist commented 7 years ago

I'm starting to wonder if an automatic Chocolatey package for Fiji is going to be like a Jenga game with me as a vision-impaired player. :sunglasses:

For now, I think we should focus on building a Chocolatey package for Fiji including the Java-8 site. In other words: a package that matches what you get currently when you download Fiji. However, we can make it work in a non-hardcoded way, such that when the Java-8 stuff gets untangled later, you can then start offering vanilla ImageJ2 super easily. Does that seem reasonable?

After all the back and forth in the "Create a Windows Installer" thread, I think you are correct. If the Java-8 site is removed/un-enabled from the default Fiji download, then there should be nothing to worry about.

My thinking at this point is to "install" Fiji to a protected (but not %Program Files%) location and establish a scheduled task to headlessly run the updater as the SYSTEM (i.e. root). That will make Fiji a machine-level install (protected from unpriviledged users), but keep it updated. In fact, if your fix for the Java-8 site mess will push out with a normal ImageJ/Fiji update, there would be no need for admins to update Fiji via a new Chocolatey package.

If/when a vanilla ImageJ2 is available, I can make a similar package for that. At that point, we can decide if Fiji should be an independent package or should be dependent on the ImageJ2 package. The former would allow both vanilla and full Fiji to simultaneously be installed as if they were unrelated.

As for being an automatic Chocolatey package... I'm still learning a lot of that, but only know how to build/push the package from a Windows machine with Chocolatey installed. I don't know anything about Jenkins (or Java). From a very quick look, I think Jenkins could be used to update the Chocolatey install script and nuspec, but I don't know how it would build the package.

At this point, it is much (much) easier for me to build a automated Chocolatey package that queries a webpage for the version number and download URL, updates the files if needed and builds the package. (That is why I was asking about scraping the current version.) Currently, I don't have any of my other "automatic" packages fully automatic. I still initiate the update check and upload any changed packages to the public repository. Since ImageJ2/Fiji updates itself, I don't think there is an urgent need for a Chocolatey package to be immediately updated. If the download URL or the checksum change, only new installs would fail. While upgrades via Chocolatey would fail, that would not leave anyone hanging as the existing ImageJ2/Fiji install would remain untouched.

teknowledgist commented 7 years ago

I'm hitting a bit of an obstacle setting up a schedule task to update Fiji.

Admittedly, return codes of 1 are a common challenge with scheduled tasks, but I have some experience with this and have tried all the options available. In the end, the fact that the ImageJ launcher starts but java does not is making me think there is a problem in the launcher.

Is there any way to bug-track or log the process, or start the update process without the launcher? Can the ImageJ-updater-x.x.jar be started directly by javaw.exe?

Thanks.

teknowledgist commented 7 years ago

Just for reference, if I do imagej-win64.exe --update update --console --dry-run from a cmd window running as SYSTEM I get:

C:\ProgramData\Fiji.app>javaw -Dpatch.ij1=false -Dpython.cachedir.skip=true -Dpl
ugins.dir=C:\\PROGRA~3\\Fiji.app -Xmx3072m -Xincgc -XX:PermSize=128m -Djava.clas
s.path=C:\\PROGRA~3\\Fiji.app/jars/imagej-launcher-4.0.5.jar -Dimagej.dir=C:\\PR
OGRA~3\\Fiji.app -Dij.dir=C:\\PROGRA~3\\Fiji.app -Dfiji.dir=C:\\PROGRA~3\\Fiji.a
pp -Dfiji.defaultLibPath=bin/server/jvm.dll -Dfiji.executable=C:\\ProgramData\\F
iji.app\\ImageJ-win64.exe -Dij.executable=C:\\ProgramData\\Fiji.app\\ImageJ-win6
4.exe -Djava.library.path=C:\\PROGRA~3\\Fiji.app/lib/win64;C:\\PROGRA~3\\Fiji.ap
p/mm/win64 -Dscijava.context.strict=false -Dscijava.log.level=info net.imagej.la
uncher.ClassLauncher -classpath . -ijjarpath jars -ijjarpath plugins net.imagej.
updater.CommandLine update

Whereas imagej-win64.exe --update update runs and updates well.

I have no understanding of what is necessary and what is not to perform an update via a direct java call.

imagejan commented 7 years ago

if I do imagej-win64.exe --update update --console --dry-run from a cmd window running as SYSTEM I get

Did you try to run the javaw command that --dry-run is returning? And does that run and update well when run from a cmd window, but not as a scheduled task?

teknowledgist commented 7 years ago

Did you try to run the javaw command that --dry-run is returning?

I had not, but I should have. Sorry. It does work.

I discovered that when run from the task scheduler, the SYSTEM account does not have Java in the path (although it does if I open a cmd window as SYSTEM in my session). I need to play around with the best method of finding (rather than assuming) the path to javaw.exe.

Question: I will need the path to javaw.exe either way, but considering possible future changes in ImageJ2/Fiji, is it better to use the launcher for updates, or the direct javaw call with the crazy-long string of switches?

(Also, are all those switches really necessary for an update?)

imagejan commented 7 years ago

(Also, are all those switches really necessary for an update?)

I think not. You can probably omit the memory-related switches -Xmx3072m -Xincgc -XX:PermSize=128m, the log level -Dscijava.log.level=info and likely some more, depending on the required classpath for the updater... (all just guesses).

considering possible future changes in ImageJ2/Fiji, is it better to use the launcher for updates, or the direct javaw call with the crazy-long string of switches?

I think only @ctrueden can answer this.

teknowledgist commented 7 years ago

Let's say a user installs Fiji via Chocolatey. Later, if Fiji updates itself, Chocolatey won't know about the newer version. This can get messy if an admin user still later decides to use Chocolatey to upgrade Fiji. The "default" method will overwrite the existing Fiji install even if the versions are the same. (Theoretically, the updated Fiji could be newer than the public, Chocolatey package and a Chocolatey upgrade would overwrite with older.)

I would like to have Chocolatey check what version is installed and only update it's recorded version if there is no need to re-install. I should be able to have Chocolatey tell Fiji to update itself to prevent blindly overwriting customizations too. (This issue would be eliminated if customizations and/or plug-ins could be user-based and independent of the install.)

So, is there any way to identify -- via command line switch and/or file info -- the version of Fiji that is installed without opening the GUI?

teknowledgist commented 7 years ago

Is there a way to stop ImageJ/Fiji from opening the

[WARNING] Your ImageJ installation cannot be updated because it is in a protected location (e.g., "C:\Program Files").
Please move your installation to a directory with write permission

message when an unprivileged user starts it up? I would guess that is equivalent to asking if the update check on start can be turned off.

imagejan commented 7 years ago

Users can choose to never be reminded for updates, and the setting is checked here:

https://github.com/imagej/imagej-updater/blob/660eb43ade5e3fa67699170e52eb498abadd5bb8/src/main/java/net/imagej/updater/UpToDate.java#L137-L145

And there's also an option UPDATES_MANAGED_DIFFERENTLY:

https://github.com/imagej/imagej-updater/blob/660eb43ade5e3fa67699170e52eb498abadd5bb8/src/main/java/net/imagej/updater/UpToDate.java#L63-L67

but I think it is never actually used, because there are only two places where it appears:

https://github.com/imagej/imagej-updater/search?utf8=%E2%9C%93&q=UPDATES_MANAGED_DIFFERENTLY

So I guess you could either set the java Prefs latestNag to Long.MAX_VALUE, or the updater could be adapted to actually make use of the above-mentioned flag.

teknowledgist commented 7 years ago

Unfortunately, I'm not smart enough to translate the code you pointed out into a practical method to configure anything that prevents the update check. :confused:

ctrueden commented 7 years ago

The question of how to completely disable updates comes up occasionally. It's been awhile since the last time I investigated, but IIRC, @imagejan is correct that setting latestNag to Long.MAX_VALUE is the easiest way to go.

I found this old mailing list thread which might help some. Unfortunately the old trac.imagej.net site is currently broken—I need to fix it. Also, since I wrote that mail, the package prefix changed. So the one-liner is now:

net.imagej.util.Prefs.put(net.imagej.updater.UpToDate.class, "latestNag", Long.MAX_VALUE); 

Regarding executing that script to set the latestNag value: I fear the situation is not much improved since I sent that mail more than three years ago... there is still no way to really turn off updates globally. I think we will need to change the Java code. And unfortunately, I do not have the bandwidth to work on it any time soon.

@teknowledgist If you like, you could try your hand at editing the ImageJ Updater code. With Maven and Eclipse, hacking on these Java components is not as hard as you might think. You can find directions here. The component of interest is imagej/imagej-updater. Happy to answer questions or help overcome obstacles. But if you are too busy, I understand, being in the same boat.