<div dir="ltr"><div class="gmail_quote"><div dir="ltr">On Fri, Nov 27, 2015 at 6:04 AM Ulf Wiger <<a href="mailto:ulf.wiger@gmail.com" target="_blank">ulf.wiger@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><br><div><blockquote type="cite"><div>On 26 Nov 2015, at 02:37, Benoit Chesneau <<a href="mailto:bchesneau@gmail.com" target="_blank">bchesneau@gmail.com</a>> wrote:</div><br><div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Are there other ways to do it? What would be the right pattern to do it? To be honest I am balancing between 2 and 3. 4 would be fine but would mean rewriting something similar to the release_handler.</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Generally speaking how people feels about augmenting dynamically a release with new applications/modules ?</div><br></div></blockquote></div><br></div><div style="word-wrap:break-word"><div>I’ve been using setup [1] to manage plugins, where each plugin is an application which you e.g. can copy into a designated plugin directory.</div><div><br></div><div>The code could look like this:</div><div><br></div><div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">load_plugins() -></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">    AllPlugins = find_plugins(),</div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">    load_apps(AllPlugins),</div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">    register_plugins(AllPlugins),</div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">    start_apps(AllPlugins),</div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">    {ok, [A || {A,_} <- AllPlugins]}.</div></div><div><br></div><div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">find_plugins() -></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">    LibDirs = setup:lib_dirs("ERL_SETUP_LIBS"),</div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">    AppNames = app_names(LibDirs),</div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">    [{A,setup:pick_vsn(A, setup:find_app(A, LibDirs), latest)} ||</div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">        A <- AppNames].</div></div><div><br></div><div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">load_apps(AllPlugins) -></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">    lists:foreach(</div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">      fun({A,{V,D}}) -></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">              true = setup:patch_app(A, V, [D]),</div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">              ReloadRes = setup:reload_app(A, V, [D]),</div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">              ?debug("reload_app(~p, ~p, ~p) -> ~p~n", [A,V,[D], ReloadRes])</div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">      end, AllPlugins).</div></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo"><br></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">register_plugins(AllPlugins) -></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">    … % provide system-specific code</div><div><br></div><div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">start_apps(AllPlugins) -></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">    lists:foreach(</div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">      fun({A, _}) -></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">              maybe_start(A)</div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">      end, AllPlugins).</div></div><div><br></div><div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">maybe_start(App) -></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">    case application:get_key(App, mod) of</div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">        {ok, {_, _}} -></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">            %% Can be started</div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">            application:start(App);</div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">        _ -></div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">            ok</div><div style="margin:0px;font-size:9px;line-height:normal;font-family:Menlo">    end.</div></div><div><br></div><div>Setup can also help during upgrade, since when you call setup:reload_app/1, setup can automatically generate upgrade scripts to transition from a previous version of the app to the newest.</div><div><br></div><div>Another possibly useful feature is that setup can generate new boot scripts from what’s currently running, with setup:keep_release(SystemVsn). Not that it was really intented for this scenario, but rather as an easy way to get started.</div><div><br></div><div>BR,</div><div>Ulf W</div></div></blockquote><div><br></div><div><br></div></div><div dir="ltr"><div class="gmail_quote"><div>Thanks!</div><div><br></div><div>I did to some experiment this week-end using `setup` and so far I am very pleased by what I see. The thing I am currently working on is the "uninstall" action. So far I don't see any code for it in setup (which sounds logical).  I do the easy for now :</div><div><br></div><div>uninstall(myplugin) -></div><div>    application:stop(myplugin),</div><div>    application:stop(myplugin),</div><div>    remove_path(myplugin).</div><div><br></div><div>The remove_path function is inspired from the one in setup but not exposed. </div><div><br></div><div>Although that's the easy way. I probably need to manage possible dependencies. My idea for it is parsing each .app and maintain the relations between each apps. WHich would allows me to stop them as well if they have no more relations. </div><div><br></div><div>Anyway, I will work more on that topic over the week and come back with some code asap :) Thanks again for your code!<br></div><div><br></div><div>- benoit</div><div><br></div><div><br></div><div> </div></div></div></div>