JustasB / BlenderNEURON

Exports 3D structure and activity from NEURON simulator to Blender
http://blenderNEURON.org
MIT License
27 stars 7 forks source link

Automatic installer #20

Closed Helveg closed 3 years ago

Helveg commented 3 years ago

I was wondering if installing addons was possible programmatically, and I for sure thought it wouldn't be as imho it poses a huge security risk, but look:

https://docs.blender.org/api/current/bpy.ops.preferences.html#bpy.ops.preferences.addon_install

We should be able to provide an installer that contains something like:

# wget the latest release possibly overwrite with a specific version or smth
wget https://github.com/blenderneuron/.../latest -O _tmp_bn_installer.zip
# wget the install script or just hardcode it in this script and write it to a tmp_file then run it
wget https://blenderneuron.org/installer/addon_install.py -O _tmp_bn_addon_install.py
# Install the zip
blender --background --python _tmp_bn_installer.py
# Cleanup all the files
# rm ...
# Install blenderneuron also in Python
pip install blenderneuron

Where the py file probably does:

bpy.ops.preferences.addon_install(filepath='_tmp_bn_installer.zip', overwrite=True)
bpy.ops.preferences.addon_enable(module='addon_name')

And for users installing blenderneuron now becomes as simple as:

curl https://blenderneuron.org/install | bash
Helveg commented 3 years ago

In order to be able to literally modify bl_info, we could clone with --depth=1, overwrite the data in blenderneuron/__init__.py depending on what blender --version tells us, zip it and install it.

I am a horrible bash scripter so expect the first version to only work if everything is OK and crash horribly otherwise ;p

JustasB commented 3 years ago

Yes, that should work and simplify the installation a bit.

If the addon_install operator does not work for some reason, I know it's possible to drop the contents of the addon zip file in the blender/2.XX/scripts/addons/ folder and then call addon_enable operator.

Couple of concerns:

  1. Windows OS. I wonder if the installer should be Python-based, which could be executed during pip install blenderneuron or separately as needed. That way users with Windows OS+Blender could install the addon without having Bash. Otherwise, we'd need to write/maintain .sh/.bat files for each platform.
  2. Thoughts on how to handle multiple installations of Blender. E.g. if 2.7 and 2.9 are installed, we should allow users to chose the target Blender version. Or if no choice provided, default to the version that resolves to the blender(.exe) binary. How could we collect/pass the choice to the installer? Does pip allow passing of custom params? Could also use an ENV var e.g. BLENDER_PATH.
  3. Non-terminal users. For users who don't start NEURON from a terminal (think basic NRN installation where they just open it with a shortcut link - I've seen this in classroom settings) and same with Blender (shortcut link), I wonder if it still would be easier for them to take the "download zip + enable addon in Blender UI" route to install the addon. Those users might not have bash or even Python setup and are generally uncomfortable working with terminals.

What do you think?

Helveg commented 3 years ago
  1. I think diving into Python asap is a good idea and that an installer like this always comes with some platform dependence (I'm actually starting work on the bat as a Windows user ;p ). I do not think that we should use pip to execute our Blender installation code. They are moving away from arbitrary code execution, which only old formats like source distributions can do, but I'd like to distribute automated wheels with cibuildwheel. Our python package shouldn't even load the code that the Blender addon needs. By checking bpy we only load the _blender's addon when inside Blender.
  2. I think the first versions of my install scripts etc will just assume blender on the PATH or error out 😂
  3. Yea we should for sure just keep distributing a drag and droppable zip folder for each Blender version that we support. We might even just use those in the installer. The difference between each version's zip will very ridiculously just be which bl_info["blender"] version we put in there haha.
Helveg commented 3 years ago

The repository is rather large, so we'd best distribute a leaner version from the CI pipelines hehe

Helveg commented 3 years ago

I'm thinking that the installer could be simplified right? We just: 1) During a release CI build we create zip for each blender version that we support and modify the bl_info accordingly. 2) Host a python script at https://blenderneuron.org/install, pipe that to python

We host the build artifacts like this on blenderneuron.org:

https://blenderneuron.org/addon/<version>/<blender-version>

Then a user can install us with:

# Linux & Windows PowerShell, (probably also Mac?)
curl https://blenderneuron.org/install | python

Take a look at the rework/installer branch, it works but it doesn't enable the addon (see https://blender.stackexchange.com/questions/208650/how-can-i-permanently-enable-an-addon-in-the-userpref, let's hope the answer isn't "you can't").

The non-terminal oriented folks can still grab the zip files from those URLs and we can make https://blenderneuron.org/latest point to the latest zip for the latest blender and /latest/<blender-version> to our latest version for a specific Blender version!

Helveg commented 3 years ago

Good news! We might be able to finish the installer if we save the user preferences inside of the addon install script using bpy.ops.wm.save_userpref(). I can't test if this solves the issue right now but I'm adding it here for future reference :)

Helveg commented 3 years ago

It works!!! We have an automatic installer. Still VERY fragile but as long as blender is a valid command and blenderneuron.zip is in the CWD we can install using python installer/install.py!

We should discuss next steps in CI so that we can manage the content on blenderneuron.org from the CI pipelines and sexify the install to wget https://blenderneuron.org/install | python

Next steps: some basic error handling