capricorn 0.2.25 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (139) hide show
  1. data/LICENSE +19 -0
  2. data/README.md +1 -0
  3. data/bin/capricorn-app-scaffolder +27 -0
  4. data/bin/capricorn-gem-spec +33 -0
  5. data/bin/capricornctl +12 -0
  6. data/bin/capricornd +31 -0
  7. data/erlang/lib/bert/doc/overview.edoc +4 -0
  8. data/erlang/lib/bert/ebin/bert.app +9 -0
  9. data/erlang/lib/bert/rebar.config +3 -0
  10. data/erlang/lib/bert/src/bert.erl +69 -0
  11. data/erlang/lib/bertio/doc/overview.edoc +4 -0
  12. data/erlang/lib/bertio/ebin/bertio.app +9 -0
  13. data/erlang/lib/bertio/rebar.config +3 -0
  14. data/erlang/lib/bertio/src/bertio.erl +28 -0
  15. data/erlang/lib/bertrpc/doc/overview.edoc +4 -0
  16. data/erlang/lib/bertrpc/ebin/bertrpc.app +12 -0
  17. data/erlang/lib/bertrpc/include/bertrpc.hrl +1 -0
  18. data/erlang/lib/bertrpc/rebar.config +5 -0
  19. data/erlang/lib/bertrpc/src/bertrpc.erl +471 -0
  20. data/erlang/lib/bertrpc/src/bertrpc_hello_world.erl +148 -0
  21. data/erlang/lib/bertrpc/src/fd_tcp.erl +376 -0
  22. data/erlang/lib/capricorn/doc/overview.edoc +4 -0
  23. data/erlang/lib/capricorn/ebin/capricorn.app +56 -0
  24. data/erlang/lib/capricorn/include/capricorn.hrl +76 -0
  25. data/erlang/lib/capricorn/rebar.config +3 -0
  26. data/erlang/lib/capricorn/src/cap_application.erl +170 -0
  27. data/erlang/lib/capricorn/src/cap_cluster.erl +121 -0
  28. data/erlang/lib/capricorn/src/cap_cluster_gems.erl +422 -0
  29. data/erlang/lib/capricorn/src/cap_config.erl +25 -0
  30. data/erlang/lib/capricorn/src/cap_dets_updater.erl +26 -0
  31. data/erlang/lib/capricorn/src/cap_event_sup.erl +35 -0
  32. data/erlang/lib/capricorn/src/cap_events.erl +24 -0
  33. data/erlang/lib/capricorn/src/cap_external_api.erl +87 -0
  34. data/erlang/lib/capricorn/src/cap_external_apps_api.erl +125 -0
  35. data/erlang/lib/capricorn/src/cap_external_gems_api.erl +85 -0
  36. data/erlang/lib/capricorn/src/cap_external_machines_api.erl +18 -0
  37. data/erlang/lib/capricorn/src/cap_gem_utils.erl +111 -0
  38. data/erlang/lib/capricorn/src/cap_internal_api.erl +69 -0
  39. data/erlang/lib/capricorn/src/cap_internal_apps_api.erl +38 -0
  40. data/erlang/lib/capricorn/src/cap_log.erl +113 -0
  41. data/erlang/lib/capricorn/src/cap_machine.erl +338 -0
  42. data/erlang/lib/capricorn/src/cap_machine_apps.erl +410 -0
  43. data/erlang/lib/capricorn/src/cap_machine_apps_sup.erl +57 -0
  44. data/erlang/lib/capricorn/src/cap_sup.erl +200 -0
  45. data/erlang/lib/capricorn/src/cap_util.erl +278 -0
  46. data/erlang/lib/capricorn/src/capricorn.erl +45 -0
  47. data/erlang/lib/capricorn/src/capricorn_app.erl +36 -0
  48. data/erlang/lib/emq/ebin/emq.app +17 -0
  49. data/erlang/lib/emq/src/emq.erl +261 -0
  50. data/erlang/lib/emq/src/emq_app.erl +11 -0
  51. data/erlang/lib/emq/src/emq_pool.erl +178 -0
  52. data/erlang/lib/emq/src/emq_queue.erl +332 -0
  53. data/erlang/lib/emq/src/emq_status.erl +148 -0
  54. data/erlang/lib/emq/src/emq_sup.erl +132 -0
  55. data/erlang/lib/gcd/ebin/gcd.app +18 -0
  56. data/erlang/lib/gcd/include/gcd.hrl +5 -0
  57. data/erlang/lib/gcd/rebar.config +3 -0
  58. data/erlang/lib/gcd/src/gcd.erl +51 -0
  59. data/erlang/lib/gcd/src/gcd_app.erl +13 -0
  60. data/erlang/lib/gcd/src/gcd_event.erl +39 -0
  61. data/erlang/lib/gcd/src/gcd_server.erl +30 -0
  62. data/erlang/lib/gcd/src/gcd_srv.erl +186 -0
  63. data/erlang/lib/gcd/src/gcd_sup.erl +18 -0
  64. data/erlang/rebar +0 -0
  65. data/erlang/rebar.config +9 -0
  66. data/erlang/rel/overlay/bin/capricornd +146 -0
  67. data/erlang/rel/overlay/erts-vsn/bin/erl +34 -0
  68. data/erlang/rel/overlay/erts-vsn/bin/nodetool +80 -0
  69. data/erlang/rel/overlay/etc/capricorn/app.config +59 -0
  70. data/erlang/rel/overlay/etc/capricorn/cluster-vm.args +21 -0
  71. data/erlang/rel/overlay/etc/capricorn/machine-vm.args +21 -0
  72. data/erlang/rel/reltool.config +43 -0
  73. data/ext/Makefile +2 -0
  74. data/ext/extconf.rb +1 -0
  75. data/lib/capricorn-client.rb +86 -0
  76. data/lib/capricorn-client/cli/applications.rb +256 -0
  77. data/lib/capricorn-client/cli/gems.rb +57 -0
  78. data/lib/capricorn-client/cli/machines.rb +9 -0
  79. data/lib/capricorn-client/helpers.rb +62 -0
  80. data/lib/capricorn.rb +5 -99
  81. data/lib/capricorn/driver.rb +86 -0
  82. data/lib/capricorn/recipes/apache-debian.rb +112 -0
  83. data/lib/capricorn/recipes/centos-plesk.rb +162 -0
  84. data/lib/capricorn/recipes/macports.rb +54 -0
  85. data/lib/capricorn/system_context.rb +49 -0
  86. data/lib/capricorn/version.rb +5 -0
  87. metadata +233 -74
  88. data/app_generators/engine/engine_generator.rb +0 -40
  89. data/app_generators/engine/templates/Gmfile +0 -20
  90. data/app_generators/engine/templates/MIT-LICENSE.txt +0 -20
  91. data/app_generators/engine/templates/README.rdoc +0 -7
  92. data/app_generators/engine/templates/config/initializers/rails_init.rb +0 -1
  93. data/app_generators/engine/templates/config/routes.rb +0 -2
  94. data/app_generators/engine/templates/gitignore +0 -9
  95. data/app_generators/engine/templates/init.rb +0 -1
  96. data/app_generators/engine/templates/lib/engine.rb +0 -4
  97. data/app_generators/engine/templates/rails/init.rb +0 -1
  98. data/app_generators/engine/templates/tasks/engine_tasks.rake +0 -4
  99. data/bin/capricorn +0 -20
  100. data/lib/capricorn/actor.rb +0 -23
  101. data/lib/capricorn/actor/actions.rb +0 -76
  102. data/lib/capricorn/actors/apache_actor.rb +0 -56
  103. data/lib/capricorn/actors/base_actor.rb +0 -335
  104. data/lib/capricorn/actors/host_file_actor.rb +0 -77
  105. data/lib/capricorn/actors/mysql_actor.rb +0 -20
  106. data/lib/capricorn/actors/passenger_actor.rb +0 -28
  107. data/lib/capricorn/actors/plesk_actor.rb +0 -228
  108. data/lib/capricorn/actors/sqlite3_actor.rb +0 -44
  109. data/lib/capricorn/app_runner.rb +0 -108
  110. data/lib/capricorn/apps/dev.rb +0 -15
  111. data/lib/capricorn/apps/engines.rb +0 -33
  112. data/lib/capricorn/apps/jobs.rb +0 -35
  113. data/lib/capricorn/apps/satellite.rb +0 -68
  114. data/lib/capricorn/apps/server.rb +0 -73
  115. data/lib/capricorn/client.rb +0 -48
  116. data/lib/capricorn/client/auth_token.rb +0 -98
  117. data/lib/capricorn/daemon.rb +0 -81
  118. data/lib/capricorn/exception_handler.rb +0 -79
  119. data/lib/capricorn/extentions/rubygems_plugin.rb +0 -27
  120. data/lib/capricorn/extentions/thor_extentions.rb +0 -32
  121. data/lib/capricorn/job_queue.rb +0 -203
  122. data/lib/capricorn/satellite.rb +0 -52
  123. data/lib/capricorn/satellite/actions.rb +0 -55
  124. data/lib/capricorn/satellite/dependency_loader.rb +0 -82
  125. data/lib/capricorn/satellite/persistence.rb +0 -50
  126. data/lib/capricorn/server.rb +0 -144
  127. data/lib/capricorn/server/daemon.rb +0 -83
  128. data/lib/capricorn/server/proxy.rb +0 -25
  129. data/lib/capricorn/server/security.rb +0 -120
  130. data/lib/capricorn/system.rb +0 -218
  131. data/lib/capricorn/system/config.rb +0 -49
  132. data/lib/capricorn/system/helper.rb +0 -21
  133. data/lib/capricorn/system/options.rb +0 -79
  134. data/lib/capricorn/system/process_user.rb +0 -73
  135. data/lib/capricorn/system/satellites.rb +0 -44
  136. data/lib/capricorn/system/shell.rb +0 -80
  137. data/lib/rubygems_plugin.rb +0 -1
  138. data/spec/actor/actions_spec.rb +0 -13
  139. data/spec/spec_helper.rb +0 -1
@@ -0,0 +1,410 @@
1
+ -module(cap_machine_apps).
2
+ -include("capricorn.hrl").
3
+ -behaviour(gen_server).
4
+
5
+
6
+
7
+ -export([start_link/0]).
8
+ -export([create/4, create/5, import/7, import/8, update/3, update/4, fupdate/1, fupdate/2, update_gem/1, update_gem/2, all/0, all/1]).
9
+ -export([init/1, handle_call/3, handle_cast/2,
10
+ handle_info/2, terminate/2, code_change/3]).
11
+
12
+
13
+
14
+ -record(ctx, {recipe :: binary(),apps,scaffolder}).
15
+
16
+
17
+
18
+ %%% Start the server
19
+ start_link() ->
20
+ gen_server:start_link({local, cap_machine_apps}, ?MODULE, [], []).
21
+
22
+
23
+
24
+ -spec create(binary(),[binary(),...],atom(),[binary()]) -> ok.
25
+
26
+ create(Name, Domains, Environment, Gems) ->
27
+ gen_server:cast(cap_machine_apps, {create, Name, Domains, Environment, Gems}).
28
+
29
+
30
+
31
+ -spec create(atom(), binary(),[binary(),...],atom(),[binary()]) -> ok.
32
+
33
+ create(Node, Name, Domains, Environment, Gems) ->
34
+ gen_server:cast({cap_machine_apps, Node}, {create, Name, Domains, Environment, Gems}).
35
+
36
+
37
+
38
+ -spec import(binary(),[binary(),...],atom(),[binary()], binary(), binary(), binary()) -> 'ok'.
39
+
40
+ import(Name, Domains, Environment, Gems, Root, Uid, Gid) ->
41
+ gen_server:cast(cap_machine_apps, {import, Name, Domains, Environment, Gems, Root, Uid, Gid}).
42
+
43
+
44
+
45
+ -spec import(atom(), binary(),[binary(),...],atom(),[binary()], binary(), binary(), binary()) -> 'ok'.
46
+
47
+ import(Node, Name, Domains, Environment, Gems, Root, Uid, Gid) ->
48
+ gen_server:cast({cap_machine_apps, Node}, {import, Name, Domains, Environment, Gems, Root, Uid, Gid}).
49
+
50
+
51
+
52
+ -spec update(binary(), [binary(),...], [binary()]) -> ok.
53
+
54
+ update(Id, Domains, Gems) ->
55
+ gen_server:cast(cap_machine_apps, {update, Id, Domains, Gems}).
56
+
57
+
58
+
59
+ -spec update(atom(), binary(), [binary(),...], [binary()]) -> ok.
60
+
61
+ update(Node, Id, Domains, Gems) ->
62
+ gen_server:cast({cap_machine_apps, Node}, {update, Id, Domains, Gems}).
63
+
64
+
65
+
66
+ -spec fupdate(binary()) -> ok.
67
+
68
+ fupdate(Id) ->
69
+ gen_server:cast(cap_machine_apps, {fupdate, Id}).
70
+
71
+
72
+
73
+ -spec fupdate(atom(), binary()) -> ok.
74
+
75
+ fupdate(Node, Id) ->
76
+ gen_server:cast({cap_machine_apps, Node}, {fupdate, Id}).
77
+
78
+
79
+
80
+ -spec update_gem(binary()) -> ok.
81
+
82
+ update_gem(Name) ->
83
+ gen_server:cast(cap_machine_apps, {update_gem, Name}).
84
+
85
+
86
+
87
+ -spec update_gem(atom(), binary()) -> ok.
88
+
89
+ update_gem(Node, Name) ->
90
+ gen_server:cast({cap_machine_apps, Node}, {update_gem, Name}).
91
+
92
+
93
+
94
+ -spec all() -> [application()].
95
+
96
+ all() ->
97
+ gen_server:call(cap_machine_apps, {all}).
98
+
99
+
100
+
101
+ -spec all(atom()) -> [application()].
102
+
103
+ all(Node) ->
104
+ gen_server:call({cap_machine_apps, Node}, {all}).
105
+
106
+
107
+
108
+ %%% Initialize the server
109
+ init([]) ->
110
+ Root = cap_config:get(machine, database, "var/run/capricorn"),
111
+ Recipe = cap_config:get(machine, recipe, "macports"),
112
+
113
+ TablePath = filename:join([Root, "applications.db"]),
114
+ {ok, Ref} = dets:open_file(cap_machine_apps, [{file, TablePath}, {keypos, 2}]),
115
+ update_apps_table(Ref),
116
+
117
+ State = #ctx{recipe=list_to_binary(Recipe), apps=Ref},
118
+ State1 = start_scaffolder(State),
119
+
120
+ {ok, State1}.
121
+
122
+
123
+
124
+ %%% Handle call messages
125
+ handle_call({all}, _From, #ctx{apps=Apps}=State) ->
126
+ All = dets:foldl(fun(App, Acc) -> [App|Acc] end, [], Apps),
127
+ {reply, All, State};
128
+
129
+ handle_call(_Request, _From, State) ->
130
+ {reply, ok, State}.
131
+
132
+
133
+
134
+ %%% Handle cast messages
135
+ handle_cast({create, Name, [MainDomain|_]=Domains, Environment, Gems}, Ctx) ->
136
+ App = #application{
137
+ id=MainDomain,
138
+ node=node(),
139
+ name=Name,
140
+ domains=Domains,
141
+ environment=Environment,
142
+ required_gems=Gems},
143
+ case valid_app(App) of
144
+ true ->
145
+ R = do_create(App, Ctx),
146
+ ?LOG_ERROR("app: ~p", [R]),
147
+ {noreply, Ctx};
148
+ {false, E} ->
149
+ ?LOG_ERROR("Invalid app: ~p", [E]),
150
+ {noreply, Ctx}
151
+ end;
152
+
153
+ handle_cast({import, Name, [MainDomain|_]=Domains, Environment, Gems, Root, Uid, Gid}, Ctx) ->
154
+ App = #application{
155
+ id=MainDomain,
156
+ node=node(),
157
+ name=Name,
158
+ domains=Domains,
159
+ environment=Environment,
160
+ www_user=Uid,
161
+ www_group=Gid,
162
+ root_path=Root,
163
+ required_gems=Gems},
164
+ case valid_app(App) of
165
+ true ->
166
+ R = do_import(App, Ctx),
167
+ ?LOG_ERROR("app: ~p", [R]),
168
+ {noreply, Ctx};
169
+ {false, E} ->
170
+ ?LOG_ERROR("Invalid app: ~p", [E]),
171
+ {noreply, Ctx}
172
+ end;
173
+
174
+ handle_cast({update, Id, Domains, Gems}, Ctx) ->
175
+ do_update(Id, Domains, Gems, Ctx),
176
+ {noreply, Ctx};
177
+
178
+ handle_cast({fupdate, Id}, Ctx) ->
179
+ do_fupdate(Id, Ctx),
180
+ {noreply, Ctx};
181
+
182
+ handle_cast({update_gem, GemName}, Ctx) ->
183
+ #ctx{ apps=Apps } = Ctx,
184
+
185
+ dets:foldl(fun
186
+ (App, _) ->
187
+ Included = lists:foldl(fun
188
+ (#gem_id{name = Name}, _) when Name == GemName ->
189
+ true;
190
+ (_, Acc) ->
191
+ Acc
192
+ end, false, App#application.installed_gems),
193
+
194
+ case Included of
195
+ true ->
196
+ do_fupdate(App#application.id, Ctx);
197
+ false ->
198
+ ignore
199
+ end
200
+ end, [], Apps),
201
+ {noreply, Ctx};
202
+
203
+ handle_cast(stop, Ctx) ->
204
+ {stop, normal, Ctx};
205
+
206
+ handle_cast(_Msg, State) ->
207
+ {noreply, State}.
208
+
209
+
210
+ %%% Handle generic messages
211
+ handle_info({Port, {exit_status, _Status}}, #ctx{scaffolder=Port}=State) ->
212
+ {noreply, start_scaffolder(State)};
213
+
214
+ handle_info(_Info, State) ->
215
+ {noreply, State}.
216
+
217
+
218
+
219
+ %%% Before stopping the server
220
+ terminate(_Reason, #ctx{apps=Apps}) ->
221
+ dets:close(Apps),
222
+ ok.
223
+
224
+
225
+
226
+ %%% Code Changes
227
+ code_change(_OldVsn, State, _Extra) ->
228
+ {ok, State}.
229
+
230
+
231
+
232
+ start_scaffolder(State) ->
233
+ Cmd = os:find_executable("capricorn-app-scaffolder"),
234
+ Port = bertio:open_port({spawn_executable, Cmd}, [exit_status]),
235
+ State#ctx{scaffolder=Port}.
236
+
237
+
238
+
239
+ -spec do_update(binary(),[binary(),...],[binary(),...],#ctx{}) -> {'error',_}|{'ok',application()}.
240
+
241
+ do_update(Id, Domains, Gems, Ctx) ->
242
+ ?LOG_INFO("updating ~s => ~p", [Id, {Domains, Gems}]),
243
+ try
244
+ {ok, App1} = do_lookup_app(Id, Ctx),
245
+ {ok, App2} = do_update_domains(App1, Domains, Ctx),
246
+ {ok, App3} = do_try_update_gems(App2, Gems,Ctx),
247
+ {ok, App4} = do_save_app(App3, Ctx),
248
+ {ok, App4}
249
+ catch
250
+ error:E ->
251
+ ?LOG_ERROR("error while updating app ~s: ~p", [Id, E]),
252
+ {error, E}
253
+ end.
254
+
255
+
256
+
257
+ -spec do_fupdate(binary(),#ctx{}) -> {'error',_}|{'ok',application()}.
258
+
259
+ do_fupdate(Id, Ctx) ->
260
+ ?LOG_INFO("queued update for ~s", [Id]),
261
+ emq:push(machine_queue, {fupdate, Id}, fun() ->
262
+ ?LOG_INFO("force updating ~s", [Id]),
263
+ try
264
+ {ok, App1} = do_lookup_app(Id, Ctx),
265
+ {ok, App2} = do_update_gems(App1, App1#application.required_gems, Ctx),
266
+ {ok, App3} = do_save_app(App2, Ctx),
267
+ {ok, App3}
268
+ catch
269
+ error:E ->
270
+ ?LOG_ERROR("error while updating app ~s: ~p", [Id, E]),
271
+ {error, E}
272
+ end
273
+ end).
274
+
275
+
276
+
277
+ -spec do_lookup_app(binary(), #ctx{}) -> {ok, application()}.
278
+
279
+ do_lookup_app(Id, #ctx{apps=Apps}) ->
280
+ case dets:lookup(Apps, Id) of
281
+ [] -> throw(not_found);
282
+ [App] -> {ok, App}
283
+ end.
284
+
285
+
286
+
287
+ -spec do_save_app(application(), #ctx{}) -> {ok, application()}.
288
+
289
+ do_save_app(App, #ctx{apps=Apps}) ->
290
+ dets:insert(Apps, App),
291
+ {ok, App}.
292
+
293
+
294
+
295
+ -spec do_update_domains(application(), [binary(),...], #ctx{}) -> {ok, application()}.
296
+
297
+ do_update_domains(App, Domains, #ctx{recipe=Recipe, scaffolder=P}) ->
298
+ if Domains /= App#application.domains ->
299
+ bertio:send(P, {update, Recipe, App}),
300
+ receive
301
+ {P, {bert, true}} -> {ok, App#application{domains=Domains}};
302
+ {P, {bert, E}} -> throw(E)
303
+ end;
304
+ true -> {ok, App}
305
+ end.
306
+
307
+
308
+
309
+ -spec do_try_update_gems(application(), [binary(),...], #ctx{}) -> {ok, application()}.
310
+
311
+ do_try_update_gems(App, Gems, Ctx) ->
312
+ if Gems /= App#application.required_gems ->
313
+ do_update_gems(App, Gems, Ctx);
314
+ true ->
315
+ ?LOG_DEBUG("app gems are already updated", []),
316
+ {ok, App}
317
+ end.
318
+
319
+
320
+
321
+ -spec do_update_gems(application(), [binary(),...], #ctx{}) -> {ok, application()}.
322
+
323
+ do_update_gems(App, Gems, _Ctx) ->
324
+ ?LOG_INFO("updating app gems ~p => ~p", [App#application.required_gems, Gems]),
325
+
326
+ App1 = App#application{required_gems=Gems,installed_gems=[]},
327
+
328
+ case cap_machine:ensure_gems_are_present_for_app(App1) of
329
+ {ok, App2} ->
330
+ ?LOG_INFO("relinking app ~s", [App#application.id]),
331
+ case cap_application:update(App2) of
332
+ ok ->
333
+ ?LOG_DEBUG("relinked app ~s", [App#application.id]),
334
+ {ok, App2};
335
+ Error ->
336
+ ?LOG_DEBUG("error ~p", [Error]),
337
+ Error
338
+ end;
339
+ Error ->
340
+ ?LOG_DEBUG("error ~p", [Error]),
341
+ Error
342
+ end.
343
+
344
+
345
+
346
+ -spec do_create(application(), #ctx{}) -> ok | any().
347
+
348
+ do_create(App, #ctx{recipe=Recipe, apps=Apps, scaffolder=P}) ->
349
+ bertio:send(P, {create, Recipe, App}),
350
+ try bertio:recv(P, 25000) of
351
+ {bert, {true, {User, Group, RootPath}}} ->
352
+ App1 = App#application{www_user=User,www_group=Group,root_path=RootPath},
353
+ dets:insert_new(Apps, App1),
354
+ cap_machine_apps_sup:start(App1),
355
+ ok;
356
+ {bert, R} -> R
357
+ catch
358
+ error:timeout -> {error, timeout}
359
+ end.
360
+
361
+
362
+
363
+ -spec do_import(application(), #ctx{}) -> ok | any().
364
+
365
+ do_import(App, #ctx{apps=Apps}) ->
366
+ dets:insert_new(Apps, App),
367
+ cap_machine_apps_sup:start(App),
368
+ ok.
369
+
370
+
371
+
372
+ -spec valid_app(application()) -> 'true' | {'false',binary()}.
373
+
374
+ valid_app(#application{node=No,name=N,domains=D,required_gems=G}) ->
375
+ if
376
+ (not is_atom(No)) orelse No /= node() ->
377
+ {false, <<"Invalid Node">>};
378
+ (not is_binary(N) orelse size(N) == 0) ->
379
+ {false, <<"Invalid Name">>};
380
+ (not is_list(D) orelse length(D) == 0) ->
381
+ {false, <<"Please pass at least one domain">>};
382
+ (not is_list(G) orelse length(G) == 0) ->
383
+ {false, <<"Please pass at least one gem">>};
384
+ true ->
385
+ true
386
+ end.
387
+
388
+
389
+
390
+ update_apps_table(Table) ->
391
+ cap_dets_updater:update(Table, fun
392
+
393
+ ({application, _Id, _Node, _Name, _Domains, _Environment, _User,
394
+ _Group, _Root, _Installed, _Required, {rvsn, 1}}) ->
395
+ ok;
396
+
397
+ ({application, Id, Node, Name, Domains, Environment, User,
398
+ Group, Root, Installed, Required, {rvsn, 0}}) ->
399
+ GemIds = [lists:nth(2, erlang:tuple_to_list(Gem)) || Gem <- Installed],
400
+ {update, {application, Id, Node, Name, Domains, Environment,
401
+ User, Group, Root, GemIds, Required, {rvsn, 1}}};
402
+
403
+ ({application, Id, Node, Name, Domains, Environment, User,
404
+ Group, Root, Installed, Required}) ->
405
+ {update, {application, Id, Node, Name, Domains, Environment,
406
+ User, Group, Root, Installed, Required, {rvsn, 0}}}
407
+
408
+ end).
409
+
410
+
@@ -0,0 +1,57 @@
1
+ -module(cap_machine_apps_sup).
2
+ -include("capricorn.hrl").
3
+ -behaviour(supervisor).
4
+
5
+ -export([start_link/0, start_app_link/1, init/1]).
6
+ -export([start/1, stop/1, restart/1]).
7
+
8
+ -spec start(application()) -> any().
9
+ start(#application{id=Id}=App) ->
10
+ supervisor:start_child(cap_machine_apps_sup,
11
+ {Id,
12
+ {cap_machine_apps_sup, start_app_link, [App]},
13
+ permanent,
14
+ infinity,
15
+ supervisor,
16
+ [cap_machine_apps_sup]}).
17
+
18
+ -spec stop(application()) -> any().
19
+ stop(#application{id=Id}) ->
20
+ supervisor:terminate_child(cap_machine_apps_sup, Id),
21
+ supervisor:delete_child(cap_machine_apps_sup, Id).
22
+
23
+ -spec restart(application()) -> any().
24
+ restart(#application{id=Id}) ->
25
+ supervisor:restart_child(cap_machine_apps_sup, Id).
26
+
27
+ -spec start_link() -> 'ignore' | {'error',_} | {'ok',pid()}.
28
+ start_link() ->
29
+ Specs = {{one_for_one, 10, 3600},[]},
30
+ case supervisor:start_link({local, cap_machine_apps_sup}, ?MODULE, Specs) of
31
+ {ok, Pid} ->
32
+ start_children(cap_machine_apps:all()),
33
+ {ok, Pid};
34
+ E -> E
35
+ end.
36
+
37
+ -spec start_app_link(application()) -> 'ignore' | {'error',_} | {'ok',pid()}.
38
+ start_app_link(App) ->
39
+ Specs = {{one_for_one, 10, 3600},[
40
+ {cap_application,
41
+ {cap_application, start_link, [App]},
42
+ permanent,
43
+ 1000,
44
+ worker,
45
+ [cap_application]}
46
+ ]},
47
+ supervisor:start_link(?MODULE, Specs).
48
+
49
+ -spec init([term()]) -> {ok, [term()]}.
50
+ init(Specs) ->
51
+ {ok, Specs}.
52
+
53
+ -spec start_children([application()]) -> ok.
54
+ start_children([]) -> ok;
55
+ start_children([App|Rest]) ->
56
+ start(App),
57
+ start_children(Rest).