Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Idempotent configuration commands & config management #4597

Open
dpwrussell opened this issue Apr 21, 2016 · 7 comments
Open

Idempotent configuration commands & config management #4597

dpwrussell opened this issue Apr 21, 2016 · 7 comments

Comments

@dpwrussell
Copy link
Member

During our recent ansible configuration of OMERO I had to do some less than desirable things to make it work because some of the configuration can not be done idempotently.

Examples:

When configuring omero.web.ui.top_links it is not possible to use append because this will result in (after multiple runs) repeated entries, so instead it is necessary to use set which necessitates specifying all of the defaults (which could easily change with a new OMERO version).

omero.web.ui.top_links: '[["Data", "webindex", {"title": "Browse Data via Projects, Tags etc"}],["History", "history", {"title": "History"}],["Help", "http://help.openmicroscopy.org/", {"title": "Open OMERO user guide in a new tab", "target": "new"}],["Figure", "figure_index"],["Tag Search", "tagsearch"]]'

I think the best solution to this could be a new command exists for things which are lists.

For the omero.web.ui.top_links example:

omero config exists omero.web.ui.top_links '["Figure", "figure_index"]'
omero config exists omero.web.ui.top_links '["Tag Search", "tagsearch"]'

This one could probably be configured by manipulating XML instead, but as that is not the recommended way to do these changes then I think this makes more sense. Here is another example which could not be done that way though.

Plugin scripts are installed with upload and then replaced with replace. This is fine when doing things manually, but when using config management, it has no way of knowing what to do. If you run upload every time this results in the original script not being replaced. On the flip side, even if the script is already installed, it can't be replaced without some nasty bash foo to get the ID.

- name: check if figure script has been installed (database)
  shell: "{{ omero_base }}/OMERO.server/current/bin/omero -u root -w {{ omero_root_password }} -s localhost script list | grep 'Figure_To_Pdf' | gawk -F '|' '{ print $1 }'"
  sudo: yes
  sudo_user: "{{ omero_user }}"
  register: figure_script_id

# Install the figure script (only the first time)
- name: load plugin scripts (first time)
  shell: "{{ omero_base }}/OMERO.server/current/bin/omero -u root -w {{ omero_root_password }} -s localhost script upload omero/figure_scripts/Figure_To_Pdf.py --official"
  sudo: yes
  sudo_user: "{{ omero_user }}"
  args:
    chdir: "{{ omero_base }}/OMERO.web/current/lib/python/omeroweb/figure/scripts/"
  when: figure_script_id.stdout == ""

# Always reinstall the figure script (unless this was the first time)
- name: load plugin scripts (subsequent times)
  shell: "{{ omero_base }}/OMERO.server/current/bin/omero -u root -w {{ omero_root_password }} -s localhost script replace {{ figure_script_id.stdout }} omero/figure_scripts/Figure_To_Pdf.py"
  sudo: yes
  sudo_user: "{{ omero_user }}"
  args:
    chdir: "{{ omero_base }}/OMERO.web/current/lib/python/omeroweb/figure/scripts/"
  when: figure_script_id.stdout != ""

I'm not certain what the best way to fix that one is. Perhaps a command that is not based on ID like replace_or_install_script_at_location or something.

It would be really nice to be able to have any idempotent commands return values be such that config management could determine if something has changed or not.

Finally, if Ansible is what we are all using, then perhaps an action plugin or module could be developed (perhaps making use of underlying idempotent commands with nice return types) so that one could do something like:

- name: Add OMERO.figure to web top links
  omero_config:
    key: 'omero.web.config.ui.top_links'
    value: '["Figure", "figure_index"]'
    state: present
@dpwrussell dpwrussell changed the title Idempotent configuration commands Idempotent configuration commands & config management Apr 21, 2016
@manics
Copy link
Member

manics commented Apr 21, 2016

I've done some work in our Ansible repo on OMERO.server: ome/infrastructure#61
using our omego helper utility: https://github.com/ome/omego

There's a lot of conditionals in there to ensure idempotency, but it has crossed my mind that an OMERO Ansible module/library would be useful, e.g. importing omego instead of running it as a command line app.

@joshmoore
Copy link
Member

joshmoore commented Apr 26, 2016

I think the best solution to this could be a new command exists for things which are lists.

For the omero.web.ui.top_links example:

omero config exists omero.web.ui.top_links '["Figure", "figure_index"]'
omero config exists omero.web.ui.top_links '["Tag Search", "tagsearch"]'

...

Noted. Thanks.

Plugin scripts are installed with upload and then replaced with replace. This is fine when doing things manually, but when using config management, it has no way of knowing what to do. If you run upload every time this results in the original script not being replaced. On the flip side, even if the script is already installed, it can't be replaced without some nasty bash foo to get the ID.

Have you tried just putting it into its location?

mv my_script.py $OMERO_DIST/lib/scripts/my_script.py

Using the regular ansible move logic, this should be idempotent. Add a handler "if moved, then run bin/omero scripts list".

Finally, if Ansible is what we are all using, then perhaps an action plugin or module could be developed (perhaps making use of underlying idempotent commands with nice return types) so that one could do something like:

...

In general, definitely a good idea. If anyone has suggestions on concrete actions, we'd love to see them.

Cheers,
~Josh

@dpwrussell
Copy link
Member Author

dpwrussell commented Apr 26, 2016

@joshmoore

Have you tried just putting it into its location?

I did try variations on this, but in the end I decided not to do that because in the end you have to fall back on the bash foo. This happens when:

  • The script has been installed.
  • The server is then rebuilt from scratch
  • The file is now missing, but the script is installed in the database, so you need to then determine if it should be moved into place, or if it needs to be installed.

This is working for now until an idempotent configuration becomes available.

@joshmoore
Copy link
Member

This happens when:

  • The script has been installed.
  • The server is then rebuilt from scratch
  • The file is now missing, but the script is installed in the database, so you need to then determine if it should be moved into place, or if it needs to be installed.

I still think it'd be safe if using cp to just always put it into place. The server will know if it's been changed or not.

The only other alternative I can provide before a full solution is use of git. lib/scripts contains a .git directory. Assuming there are suitable ansible modules for git, you should be able to come up with a merge workflow that will provide you what you want.

Long-term, I'd like to see a registry in the server where you register locations using exists (above) and the server automatically copies them on startup.

@dpwrussell
Copy link
Member Author

The cp would be ok if you assume you're never building a server from scratch (I.e. has never had the script installed) as in this case it has to run the install with --official etc.

I think the way it's working in our ansible configuration at the moment is fine, it was just a good example of something that was hard to deal with idempotently.

@joshmoore
Copy link
Member

The cp would be ok if you assume you're never building a server from scratch (I.e. has never had the script installed) as in this case it has to run the install with --official etc.

I disagree. You can still simply cp the file into place. That counts as an "official installation".

I think the way it's working in our ansible configuration at the moment is fine, it was just a good example of something that was hard to deal with idempotently.

Can certainly understand that if something is working you don't want to change it!

@dpwrussell
Copy link
Member Author

@joshmoore Ok, I think I understand what you are saying now after some experiments.

I thought that the omero script upload step was necessary to register the script with the database, but I see now that OMERO is monitoring this directory and assigning IDs to anything it finds which is new or has changed since the last time since it was assigned an ID.

I might do this as it's a lot simpler. Thanks.

manics added a commit to manics/openmicroscopy that referenced this issue Aug 19, 2016
This will only add a value if it's not already in the list
See ome#4597
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants