How to extend foreman with a plugin method callable from a provisioning ERB template

Hi,

I have written a foreman plugin which extends Host::Managed with an
instance method.
I would like this function to be publicly available so I could call it from
a template and use the return value, but unfortunately the template
compilation fails due to:

There was an error rendering the Preseed finish template: undefined method `expose_osd_part_late' for #<Host::Managed:0x7f12ce62b1b8>

Q. #1: What is to correct way to extend Host::Managed with a publicly available instance method, callable from templates/snippets?

Q. #2: What is the correct way to extend foreman with a global helper function which can be called from a template?

Thanks much,

Benjamin

Hi Benjamin,

> Hi,
>
> I have written a foreman plugin which extends Host::Managed with an
> instance method.
> I would like this function to be publicly available so I could call it
> from a template and use the return value, but unfortunately the template
> compilation fails due to:
>
> There was an error rendering the Preseed finish template: undefined method `expose_osd_part_late' for #<Host::Managed:0x7f12ce62b1b8>
>
>
> Q. #1: What is to correct way to extend Host::Managed with a publicly available instance method, callable from templates/snippets?

For foreman_bootdisk, I use a concern, e.g.

https://github.com/theforeman/foreman_bootdisk/blob/master/app/models/concerns/bootdisk/host_ext.rb

https://github.com/theforeman/foreman_bootdisk/blob/master/lib/bootdisk/engine.rb#L43

From what you've said, it sounds like your method should work too, if
the instance method is correctly defined. Perhaps try launching the
Rails console ("bundle exec rails c" in a git checkout) and see if you
can call the method there.

The only thing that might interfere is safemode, which you can disable
under settings. I don't know if there's an easy way to extend that,
I've not investigated.

> Q. #2: What is the correct way to extend foreman with a global helper function which can be called from a template?

I don't know of any examples of this. I think you'd first need to
create a module which uses "alias_method_chain" and wraps the
render_safe method in Foreman::Renderer (lib/foreman/renderer.rb), in
order to add your method into the allowed_helpers list. You'd then
include your module into Host::Managed and UnattendedHelper (which both
include Foreman::Renderer) to get the added behaviour.

··· On 12/03/14 13:22, Somhegyi Benjamin wrote:


Dominic Cleal
Red Hat Engineering

Hi Dominic,

  1. március 12., szerda 16:16:50 UTC+1 időpontban Dominic Cleal a
    következőt írta:
    >
    >
    > From what you've said, it sounds like your method should work too, if
    > the instance method is correctly defined. Perhaps try launching the
    > Rails console ("bundle exec rails c" in a git checkout) and see if you
    > can call the method there.
    >
    > The only thing that might interfere is safemode, which you can disable
    > under settings. I don't know if there's an easy way to extend that,
    > I've not investigated.
    >
    >
    Thanks for the pointers! I have found the problem, I included the wrong
    module into Host::Managed… Pretty lame mistake.

> Q. #2: What is the correct way to extend foreman with a global helper
> function which can be called from a template?
>
> I don't know of any examples of this. I think you'd first need to
> create a module which uses "alias_method_chain" and wraps the
> render_safe method in Foreman::Renderer (lib/foreman/renderer.rb), in
> order to add your method into the allowed_helpers list. You'd then
> include your module into Host::Managed and UnattendedHelper (which both
> include Foreman::Renderer) to get the added behaviour.
>
>
I tried this and it works perfectly well. However I will not use it since
it requires patching original foreman files which are overwritten at each
package update.

Many thanks for the help,
Ben