auser-poolparty 0.2.39 → 0.2.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. data/Manifest.txt +117 -0
  2. data/bin/cloud-configure +3 -3
  3. data/bin/cloud-expand +10 -6
  4. data/bin/cloud-handle-load +32 -0
  5. data/bin/cloud-maintain +3 -9
  6. data/bin/cloud-provision +1 -1
  7. data/bin/cloud-start +2 -1
  8. data/bin/server-show-stats +1 -0
  9. data/lib/erlang/cloudpanel/EMakefile +1 -0
  10. data/lib/erlang/cloudpanel/Makefile +3 -0
  11. data/lib/erlang/cloudpanel/cloudpanel.rb +15 -0
  12. data/lib/erlang/cloudpanel/doc/cloudpanel_web.html +1 -1
  13. data/lib/erlang/cloudpanel/doc/string.html +222 -0
  14. data/lib/erlang/cloudpanel/priv/www/index.html +2 -1
  15. data/lib/erlang/cloudpanel/priv/www/javascripts/site.js +2 -0
  16. data/lib/erlang/cloudpanel/priv/www/pages/index.html +1 -0
  17. data/lib/erlang/cloudpanel/priv/www/pages/tail.html +1 -0
  18. data/lib/erlang/cloudpanel/priv/www/partials/error.html +3 -0
  19. data/lib/erlang/cloudpanel/priv/www/partials/footer.html +6 -0
  20. data/lib/erlang/cloudpanel/priv/www/partials/header.html +13 -0
  21. data/lib/erlang/cloudpanel/priv/www/partials/menu.html +13 -0
  22. data/lib/erlang/cloudpanel/src/cloudpanel.hrl +1 -0
  23. data/lib/erlang/cloudpanel/src/cloudpanel_web.erl +18 -24
  24. data/lib/erlang/cloudpanel/src/string.erl +387 -0
  25. data/lib/erlang/cloudpanel/src/tail_log.erl +66 -0
  26. data/lib/erlang/cloudpanel/src/tailor.erl +31 -0
  27. data/lib/erlang/cloudpanel/src/utils.erl +9 -0
  28. data/lib/erlang/cloudpanel/src/views.erl +44 -0
  29. data/lib/erlang/cloudpanel/yaws.conf +20 -0
  30. data/lib/erlang/messenger/useful_snippets +1 -1
  31. data/lib/poolparty/aska/aska.rb +29 -4
  32. data/lib/poolparty/base_packages/poolparty.rb +14 -6
  33. data/lib/poolparty/config/postlaunchmessage.txt +5 -0
  34. data/lib/poolparty/exceptions/LoadRulesException.rb +7 -0
  35. data/lib/poolparty/helpers/provisioner_base.rb +24 -8
  36. data/lib/poolparty/helpers/provisioners/master.rb +8 -2
  37. data/lib/poolparty/helpers/provisioners/slave.rb +4 -3
  38. data/lib/poolparty/modules/method_missing_sugar.rb +1 -1
  39. data/lib/poolparty/monitors/base_monitor.rb +1 -1
  40. data/lib/poolparty/net/remoter.rb +8 -5
  41. data/lib/poolparty/plugins/git.rb +1 -1
  42. data/lib/poolparty/pool/base.rb +6 -3
  43. data/lib/poolparty/pool/cloud.rb +4 -2
  44. data/lib/poolparty/pool/loggable.rb +2 -5
  45. data/lib/poolparty/templates/yaws.conf +19 -0
  46. data/lib/poolparty/version.rb +1 -1
  47. data/lib/poolparty.rb +2 -2
  48. data/poolparty.gemspec +121 -2
  49. data/spec/poolparty/aska/aska_spec.rb +33 -0
  50. data/spec/poolparty/core/hash_spec.rb +3 -3
  51. data/spec/poolparty/net/remote_spec.rb +4 -3
  52. data/spec/poolparty/net/remoter_spec.rb +1 -0
  53. data/spec/poolparty/pool/base_spec.rb +11 -2
  54. data/spec/poolparty/pool/cloud_spec.rb +2 -2
  55. data/website/index.html +1 -1
  56. metadata +121 -2
@@ -0,0 +1,13 @@
1
+ <div id='nav'>
2
+ <h3>Actions</h3>
3
+ <div id='navmenu'>
4
+ <ul>
5
+ <li>
6
+ <a href='/tail'>Tail the syslog</a>
7
+ </li>
8
+ <li>
9
+ <a href='#soon'>More stuff</a>
10
+ </li>
11
+ </ul>
12
+ </div>
13
+ </div>
@@ -1 +1,2 @@
1
1
 
2
+ -define (TIMEOUT, 1000).
@@ -6,14 +6,14 @@
6
6
  -module (cloudpanel_web).
7
7
  -author('Ari Lerner <ari.lerner@citrusbyte.com>').
8
8
 
9
+ -import(random).
9
10
  -export([start/1, stop/0, loop/2]).
10
-
11
- -define(TIMEOUT, 20000).
11
+ -include ("cloudpanel.hrl").
12
12
 
13
13
  %% External API
14
14
 
15
15
  start(Options) ->
16
- {DocRoot, Options1} = get_option(docroot, Options),
16
+ {DocRoot, Options1} = utils:get_option(docroot, Options),
17
17
  Loop = fun (Req) ->
18
18
  ?MODULE:loop(Req, DocRoot)
19
19
  end,
@@ -22,24 +22,18 @@ start(Options) ->
22
22
  stop() ->
23
23
  mochiweb_http:stop(?MODULE).
24
24
 
25
- loop(Req, DocRoot) ->
26
- "/" ++ Path = Req:get(path),
27
- case Req:get(method) of
28
- Method when Method =:= 'GET'; Method =:= 'HEAD' ->
29
- case Path of
30
- _ ->
31
- Req:serve_file(Path, DocRoot)
32
- end;
33
- 'POST' ->
34
- case Path of
35
- _ ->
36
- Req:not_found()
37
- end;
38
- _ ->
39
- Req:respond({501, [], []})
40
- end.
41
-
42
- %% Internal API
43
-
44
- get_option(Option, Options) ->
45
- {proplists:get_value(Option, Options), proplists:delete(Option, Options)}.
25
+ loop(Req, _DocRoot) ->
26
+ Path = Req:get(path),
27
+ case {Path, Req:get(method)} of
28
+ {"/tail", 'GET'} ->
29
+ Body = tailor:go(Req:parse_qs()),
30
+ Req:ok({"text/html", [], Body});
31
+ {"/", 'GET'} ->
32
+ Body = views:wrap_page("index"),
33
+ Req:ok({"text/html", [], Body});
34
+ {_, 'GET'} ->
35
+ Body = views:wrap_page(Path),
36
+ Req:ok({"text/html", [], Body});
37
+ _ ->
38
+ Req:respond({501, [], []})
39
+ end.
@@ -0,0 +1,387 @@
1
+ %% ``The contents of this file are subject to the Erlang Public License,
2
+ %% Version 1.1, (the "License"); you may not use this file except in
3
+ %% compliance with the License. You should have received a copy of the
4
+ %% Erlang Public License along with this software. If not, it can be
5
+ %% retrieved via the world wide web at http://www.erlang.org/.
6
+ %%
7
+ %% Software distributed under the License is distributed on an "AS IS"
8
+ %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
9
+ %% the License for the specific language governing rights and limitations
10
+ %% under the License.
11
+ %%
12
+ %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
13
+ %% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
14
+ %% AB. All Rights Reserved.''
15
+ %%
16
+ %% $Id$
17
+ %%
18
+ -module(string).
19
+
20
+ -export([len/1,equal/2,concat/2,chr/2,rchr/2,str/2,rstr/2,
21
+ span/2,cspan/2,substr/2,substr/3,tokens/2,chars/2,chars/3]).
22
+ -export([copies/2,words/1,words/2,strip/1,strip/2,strip/3,
23
+ sub_word/2,sub_word/3,left/2,left/3,right/2,right/3,
24
+ sub_string/2,sub_string/3,centre/2,centre/3, join/2]).
25
+ -export([to_upper/1, to_lower/1]).
26
+
27
+ -import(lists,[reverse/1,member/2]).
28
+
29
+ %%---------------------------------------------------------------------------
30
+
31
+ -type(direction() :: 'left' | 'right' | 'both').
32
+
33
+ %%---------------------------------------------------------------------------
34
+
35
+ %% Robert's bit
36
+
37
+ %% len(String)
38
+ %% Return the length of a string.
39
+
40
+ -spec(len/1 :: (string()) -> non_neg_integer()).
41
+
42
+ len(S) -> length(S).
43
+
44
+ %% equal(String1, String2)
45
+ %% Test if 2 strings are equal.
46
+
47
+ -spec(equal/2 :: (string(), string()) -> bool()).
48
+
49
+ equal(S, S) -> true;
50
+ equal(_, _) -> false.
51
+
52
+ %% concat(String1, String2)
53
+ %% Concatenate 2 strings.
54
+
55
+ -spec(concat/2 :: (string(), string()) -> string()).
56
+
57
+ concat(S1, S2) -> S1 ++ S2.
58
+
59
+ %% chr(String, Char)
60
+ %% rchr(String, Char)
61
+ %% Return the first/last index of the character in a string.
62
+
63
+ -spec(chr/2 :: (string(), char()) -> non_neg_integer()).
64
+
65
+ chr(S, C) when is_integer(C) -> chr(S, C, 1).
66
+
67
+ chr([C|_Cs], C, I) -> I;
68
+ chr([_|Cs], C, I) -> chr(Cs, C, I+1);
69
+ chr([], _C, _I) -> 0.
70
+
71
+ -spec(rchr/2 :: (string(), char()) -> non_neg_integer()).
72
+
73
+ rchr(S, C) when is_integer(C) -> rchr(S, C, 1, 0).
74
+
75
+ rchr([C|Cs], C, I, _L) -> %Found one, now find next!
76
+ rchr(Cs, C, I+1, I);
77
+ rchr([_|Cs], C, I, L) ->
78
+ rchr(Cs, C, I+1, L);
79
+ rchr([], _C, _I, L) -> L.
80
+
81
+ %% str(String, SubString)
82
+ %% rstr(String, SubString)
83
+ %% index(String, SubString)
84
+ %% Return the first/last index of the sub-string in a string.
85
+ %% index/2 is kept for backwards compatibility.
86
+
87
+ -spec(str/2 :: (string(), string()) -> non_neg_integer()).
88
+
89
+ str(S, Sub) when is_list(Sub) -> str(S, Sub, 1).
90
+
91
+ str([C|S], [C|Sub], I) ->
92
+ case prefix(Sub, S) of
93
+ true -> I;
94
+ false -> str(S, [C|Sub], I+1)
95
+ end;
96
+ str([_|S], Sub, I) -> str(S, Sub, I+1);
97
+ str([], _Sub, _I) -> 0.
98
+
99
+ -spec(rstr/2 :: (string(), string()) -> non_neg_integer()).
100
+
101
+ rstr(S, Sub) when is_list(Sub) -> rstr(S, Sub, 1, 0).
102
+
103
+ rstr([C|S], [C|Sub], I, L) ->
104
+ case prefix(Sub, S) of
105
+ true -> rstr(S, [C|Sub], I+1, I);
106
+ false -> rstr(S, [C|Sub], I+1, L)
107
+ end;
108
+ rstr([_|S], Sub, I, L) -> rstr(S, Sub, I+1, L);
109
+ rstr([], _Sub, _I, L) -> L.
110
+
111
+ prefix([C|Pre], [C|String]) -> prefix(Pre, String);
112
+ prefix([], String) when is_list(String) -> true;
113
+ prefix(Pre, String) when is_list(Pre), is_list(String) -> false.
114
+
115
+ %% span(String, Chars) -> Length.
116
+ %% cspan(String, Chars) -> Length.
117
+
118
+ -spec(span/2 :: (string(), string()) -> non_neg_integer()).
119
+
120
+ span(S, Cs) when is_list(Cs) -> span(S, Cs, 0).
121
+
122
+ span([C|S], Cs, I) ->
123
+ case member(C, Cs) of
124
+ true -> span(S, Cs, I+1);
125
+ false -> I
126
+ end;
127
+ span([], _Cs, I) -> I.
128
+
129
+ -spec(cspan/2 :: (string(), string()) -> non_neg_integer()).
130
+
131
+ cspan(S, Cs) when is_list(Cs) -> cspan(S, Cs, 0).
132
+
133
+ cspan([C|S], Cs, I) ->
134
+ case member(C, Cs) of
135
+ true -> I;
136
+ false -> cspan(S, Cs, I+1)
137
+ end;
138
+ cspan([], _Cs, I) -> I.
139
+
140
+ %% substr(String, Start)
141
+ %% substr(String, Start, Length)
142
+ %% Extract a sub-string from String.
143
+
144
+ -spec(substr/2 :: (string(), pos_integer()) -> string()).
145
+
146
+ substr(String, 1) when is_list(String) ->
147
+ String;
148
+ substr(String, S) when is_integer(S), S > 1 ->
149
+ substr2(String, S).
150
+
151
+ -spec(substr/3 :: (string(), pos_integer(), non_neg_integer()) -> string()).
152
+
153
+ substr(String, S, L) when is_integer(S), S >= 1, is_integer(L), L >= 0 ->
154
+ substr1(substr2(String, S), L).
155
+
156
+ substr1([C|String], L) when L > 0 -> [C|substr1(String, L-1)];
157
+ substr1(String, _L) when is_list(String) -> []. %Be nice!
158
+
159
+ substr2(String, 1) when is_list(String) -> String;
160
+ substr2([_|String], S) -> substr2(String, S-1).
161
+
162
+ %% tokens(String, Seperators).
163
+ %% Return a list of tokens seperated by characters in Seperators.
164
+
165
+ -spec(tokens/2 :: (string(), string()) -> [[char(),...]]).
166
+
167
+ tokens(S, Seps) ->
168
+ tokens1(S, Seps, []).
169
+
170
+ tokens1([C|S], Seps, Toks) ->
171
+ case member(C, Seps) of
172
+ true -> tokens1(S, Seps, Toks);
173
+ false -> tokens2(S, Seps, Toks, [C])
174
+ end;
175
+ tokens1([], _Seps, Toks) ->
176
+ reverse(Toks).
177
+
178
+ tokens2([C|S], Seps, Toks, Cs) ->
179
+ case member(C, Seps) of
180
+ true -> tokens1(S, Seps, [reverse(Cs)|Toks]);
181
+ false -> tokens2(S, Seps, Toks, [C|Cs])
182
+ end;
183
+ tokens2([], _Seps, Toks, Cs) ->
184
+ reverse([reverse(Cs)|Toks]).
185
+
186
+ -spec(chars/2 :: (char(), non_neg_integer()) -> string()).
187
+
188
+ chars(C, N) -> chars(C, N, []).
189
+
190
+ -spec(chars/3 :: (char(), non_neg_integer(), string()) -> string()).
191
+
192
+ chars(C, N, Tail) when N > 0 ->
193
+ chars(C, N-1, [C|Tail]);
194
+ chars(C, 0, Tail) when is_integer(C) ->
195
+ Tail.
196
+
197
+ %% Torbjörn's bit.
198
+
199
+ %%% COPIES %%%
200
+
201
+ copies(CharList, Num) when is_list(CharList), Num >= 0 ->
202
+ copies(CharList, Num, []).
203
+
204
+ copies(_CharList, 0, R) ->
205
+ R;
206
+ copies(CharList, Num, R) ->
207
+ copies(CharList, Num-1, CharList++R).
208
+
209
+ %%% WORDS %%%
210
+
211
+ -spec(words/1 :: (string()) -> pos_integer()).
212
+
213
+ words(String) -> words(String, $\s).
214
+
215
+ -spec(words/2 :: (string(), char()) -> pos_integer()).
216
+
217
+ words(String, Char) when is_integer(Char) ->
218
+ w_count(strip(String, both, Char), Char, 0).
219
+
220
+ w_count([], _, Num) -> Num+1;
221
+ w_count([H|T], H, Num) -> w_count(strip(T, left, H), H, Num+1);
222
+ w_count([_H|T], Char, Num) -> w_count(T, Char, Num).
223
+
224
+ %%% SUB_WORDS %%%
225
+
226
+ -spec(sub_word/2 :: (string(), integer()) -> string()).
227
+
228
+ sub_word(String, Index) -> sub_word(String, Index, $\s).
229
+
230
+ -spec(sub_word/3 :: (string(), integer(), char()) -> string()).
231
+
232
+ sub_word(String, Index, Char) when is_integer(Index), is_integer(Char) ->
233
+ case words(String, Char) of
234
+ Num when Num < Index ->
235
+ [];
236
+ _Num ->
237
+ s_word(strip(String, left, Char), Index, Char, 1, [])
238
+ end.
239
+
240
+ s_word([], _, _, _,Res) -> reverse(Res);
241
+ s_word([Char|_],Index,Char,Index,Res) -> reverse(Res);
242
+ s_word([H|T],Index,Char,Index,Res) -> s_word(T,Index,Char,Index,[H|Res]);
243
+ s_word([Char|T],Stop,Char,Index,Res) when Index < Stop ->
244
+ s_word(strip(T,left,Char),Stop,Char,Index+1,Res);
245
+ s_word([_|T],Stop,Char,Index,Res) when Index < Stop ->
246
+ s_word(T,Stop,Char,Index,Res).
247
+
248
+ %%% STRIP %%%
249
+
250
+ -spec(strip/1 :: (string()) -> string()).
251
+
252
+ strip(String) -> strip(String, both).
253
+
254
+ -spec(strip/2 :: (string(), direction()) -> string()).
255
+
256
+ strip(String, left) -> strip_left(String, $\s);
257
+ strip(String, right) -> strip_right(String, $\s);
258
+ strip(String, both) ->
259
+ strip_right(strip_left(String, $\s), $\s).
260
+
261
+ -spec(strip/3 :: (string(), direction(), char()) -> string()).
262
+
263
+ strip(String, right, Char) -> strip_right(String, Char);
264
+ strip(String, left, Char) -> strip_left(String, Char);
265
+ strip(String, both, Char) ->
266
+ strip_right(strip_left(String, Char), Char).
267
+
268
+ strip_left([Sc|S], Sc) ->
269
+ strip_left(S, Sc);
270
+ strip_left([_|_]=S, Sc) when is_integer(Sc) -> S;
271
+ strip_left([], Sc) when is_integer(Sc) -> [].
272
+
273
+ strip_right([Sc|S], Sc) ->
274
+ case strip_right(S, Sc) of
275
+ [] -> [];
276
+ T -> [Sc|T]
277
+ end;
278
+ strip_right([C|S], Sc) ->
279
+ [C|strip_right(S, Sc)];
280
+ strip_right([], Sc) when is_integer(Sc) ->
281
+ [].
282
+
283
+ %%% LEFT %%%
284
+
285
+ -spec(left/2 :: (string(), non_neg_integer()) -> string()).
286
+
287
+ left(String, Len) when is_integer(Len) -> left(String, Len, $\s).
288
+
289
+ -spec(left/3 :: (string(), non_neg_integer(), char()) -> string()).
290
+
291
+ left(String, Len, Char) when is_integer(Char) ->
292
+ Slen = length(String),
293
+ if
294
+ Slen > Len -> substr(String, 1, Len);
295
+ Slen < Len -> l_pad(String, Len-Slen, Char);
296
+ Slen =:= Len -> String
297
+ end.
298
+
299
+ l_pad(String, Num, Char) -> String ++ chars(Char, Num).
300
+
301
+ %%% RIGHT %%%
302
+
303
+ -spec(right/2 :: (string(), non_neg_integer()) -> string()).
304
+
305
+ right(String, Len) when is_integer(Len) -> right(String, Len, $\s).
306
+
307
+ -spec(right/3 :: (string(), non_neg_integer(), char()) -> string()).
308
+
309
+ right(String, Len, Char) when is_integer(Char) ->
310
+ Slen = length(String),
311
+ if
312
+ Slen > Len -> substr(String, Slen-Len+1);
313
+ Slen < Len -> r_pad(String, Len-Slen, Char);
314
+ Slen =:= Len -> String
315
+ end.
316
+
317
+ r_pad(String, Num, Char) -> chars(Char, Num, String).
318
+
319
+ %%% CENTRE %%%
320
+
321
+ -spec(centre/2 :: (string(), non_neg_integer()) -> string()).
322
+
323
+ centre(String, Len) when is_integer(Len) -> centre(String, Len, $\s).
324
+
325
+ -spec(centre/3 :: (string(), non_neg_integer(), char()) -> string()).
326
+
327
+ centre(String, 0, Char) when is_list(String), is_integer(Char) ->
328
+ []; % Strange cases to centre string
329
+ centre(String, Len, Char) when is_integer(Char) ->
330
+ Slen = length(String),
331
+ if
332
+ Slen > Len -> substr(String, (Slen-Len) div 2 + 1, Len);
333
+ Slen < Len ->
334
+ N = (Len-Slen) div 2,
335
+ r_pad(l_pad(String, Len-(Slen+N), Char), N, Char);
336
+ Slen =:= Len -> String
337
+ end.
338
+
339
+ %%% SUB_STRING %%%
340
+
341
+ sub_string(String, Start) -> substr(String, Start).
342
+
343
+ sub_string(String, Start, Stop) -> substr(String, Start, Stop - Start + 1).
344
+
345
+ %% ISO/IEC 8859-1 (latin1) letters are converted, others are ignored
346
+ %%
347
+
348
+ to_lower_char(C) when is_integer(C), C >= $A, C =< $Z ->
349
+ C + 32;
350
+ to_lower_char(C) when is_integer(C), C >= 16#C1, C =< 16#D6 ->
351
+ C + 32;
352
+ to_lower_char(C) when is_integer(C), C >= 16#D8, C =< 16#DE ->
353
+ C + 32;
354
+ to_lower_char(C) ->
355
+ C.
356
+
357
+ to_upper_char(C) when is_integer(C), C >= $a, C =< $z ->
358
+ C - 32;
359
+ to_upper_char(C) when is_integer(C), C >= 16#E1, C =< 16#F6 ->
360
+ C - 32;
361
+ to_upper_char(C) when is_integer(C), C >= 16#F8, C =< 16#FE ->
362
+ C - 32;
363
+ to_upper_char(C) ->
364
+ C.
365
+
366
+ -spec(to_lower/1 :: (string()) -> string()
367
+ ; (char()) -> char()).
368
+
369
+ to_lower(S) when is_list(S) ->
370
+ [to_lower_char(C) || C <- S];
371
+ to_lower(C) when is_integer(C) ->
372
+ to_lower_char(C).
373
+
374
+ -spec(to_upper/1 :: (string()) -> string()
375
+ ; (char()) -> char()).
376
+
377
+ to_upper(S) when is_list(S) ->
378
+ [to_upper_char(C) || C <- S];
379
+ to_upper(C) when is_integer(C) ->
380
+ to_upper_char(C).
381
+
382
+ -spec(join/2 :: ([string()], string()) -> string()).
383
+
384
+ join([], Sep) when is_list(Sep) ->
385
+ [];
386
+ join([H|T], Sep) ->
387
+ H ++ lists:append([Sep ++ X || X <- T]).
@@ -0,0 +1,66 @@
1
+ -module (tail_log).
2
+ -compile(export_all).
3
+ -include ("cloudpanel.hrl").
4
+
5
+ start(File) ->
6
+ start(File, fun display/1, "/var/log").
7
+
8
+ start(File, Callback) ->
9
+ Dir = "/var/log",
10
+ start(File, Callback, Dir).
11
+
12
+ start(File, Callback, Dir) ->
13
+ spawn_link(?MODULE, init, [File, Callback, Dir]).
14
+
15
+ stop(Pid) ->
16
+ Pid ! stop.
17
+
18
+ init(File, Callback, Dir) ->
19
+ Cmd = "/usr/bin/tail -f "++ Dir ++ "/" ++ File,
20
+ Port = open_port({spawn, Cmd}, [ {cd, Dir}, stderr_to_stdout, {line, 256}, exit_status, binary]),
21
+ tail_loop(Port, Callback).
22
+
23
+ snap(Pid) ->
24
+ Pid ! {snap, self() },
25
+ receive
26
+ {Port, Callback} ->
27
+ display(element(2, {Port, Callback}));
28
+ Any ->
29
+ io:format("Received: ~p~n", [Any]),
30
+ Any
31
+ after ?TIMEOUT ->
32
+ "Timeout error"
33
+ end.
34
+
35
+ tail_loop(Port, Callback) ->
36
+ receive
37
+ {Port, {data, {eol, Bin}}} ->
38
+ Callback(Bin),
39
+ tail_loop(Port, Callback);
40
+ {Port, {data, Bin}} ->
41
+ Callback(Bin),
42
+ tail_loop(Port, Callback);
43
+ {snap, Who} ->
44
+ Who ! {Port, Callback},
45
+ tail_loop(Port, Callback);
46
+ stop ->
47
+ port_close(Port),
48
+ {ok, stop};
49
+ {From, post, Mess} ->
50
+ io:format("Received post message: ~p ~p~n", [From, Mess]),
51
+ From ! {From, post, Mess};
52
+ {From, subscribe} ->
53
+ io:format("Received subscribe message from ~p~n", [From]),
54
+ From ! {From, subscribe};
55
+ {_, {exit_status, Num}} ->
56
+ io:format("Received error messate: ~p~n", [Num]),
57
+ port_close(Port),
58
+ {ok, stop};
59
+ Any ->
60
+ io:format("Received unknown Message: ~p~n", [Any]),
61
+ tail_loop(Port, Callback)
62
+ end.
63
+
64
+ display(Bin) ->
65
+ Content = iolist_to_binary(Bin),
66
+ utils:subst("[INFO] ~s~n", [Content]).
@@ -0,0 +1,31 @@
1
+ -module (tailor).
2
+ -compile(export_all).
3
+ -import (mochijson2).
4
+ -include ("cloudpanel.hrl").
5
+
6
+ go(Qs) ->
7
+ Body = case Qs of
8
+ "log" ->
9
+ latest_log(Qs);
10
+ _ ->
11
+ index(Qs)
12
+ end,
13
+ io:format("Body from go: ~p~n", [Body]),
14
+ Body.
15
+
16
+ index(Qs) ->
17
+ File = proplists:get_value("log", Qs),
18
+ % Tell the system that we are watching the logs
19
+ self() ! {self(), subscribe},
20
+ % Wait for messages
21
+ Dir = "/var/log",
22
+ % Callback = fun(X) -> displayLogLine(X, Log) end,
23
+ Cmd = "/usr/bin/tail -n 10 "++ Dir ++ "/" ++ File,
24
+ Body = os:cmd(Cmd),
25
+ string:join(string:tokens(Body, "\n"), "\n").
26
+
27
+ latest_log(Qs) ->
28
+ ok.
29
+
30
+ start_logger(File) ->
31
+ ok.
@@ -0,0 +1,9 @@
1
+ -module (utils).
2
+ -compile(export_all).
3
+
4
+
5
+ subst(Template, Values) when is_list(Values) ->
6
+ list_to_binary(lists:flatten(io_lib:fwrite(Template, Values))).
7
+
8
+ get_option(Option, Options) ->
9
+ {proplists:get_value(Option, Options), proplists:delete(Option, Options)}.
@@ -0,0 +1,44 @@
1
+ -module (views).
2
+ -compile(export_all).
3
+
4
+ wrap_page(Name) ->
5
+ AssetMatch = "(.*)([css|js])+",
6
+ case regexp:first_match(Name, AssetMatch) of
7
+ {match,_,_} ->
8
+ erlang:binary_to_list(read_asset(Name));
9
+ nomatch ->
10
+ wrap(read_page(Name));
11
+ {_, _} ->
12
+ io:format("Error: ~p~n", [Name]),
13
+ "error"
14
+ end.
15
+
16
+ json(Content) ->
17
+ mochijson2:encode(Content).
18
+
19
+ wrap(Content) ->
20
+ Header = read_partial("header"),
21
+ Menu = read_partial("menu"),
22
+ Footer = read_partial("footer"),
23
+ Out = erlang:list_to_binary([Header, Menu, protect(Content), Footer]),
24
+ erlang:binary_to_list(Out).
25
+
26
+ read_page(Name) ->
27
+ {_, Cont} = file:read_file("priv/www/pages/"++Name++".html"),
28
+ protect(Cont).
29
+ read_partial(Name) ->
30
+ {_, Cont} = file:read_file("priv/www/partials/"++Name++".html"),
31
+ protect(Cont).
32
+ read_asset(Name) ->
33
+ {_, Cont} = file:read_file("priv/www/"++Name),
34
+ protect(Cont).
35
+
36
+ protect(Content) ->
37
+ case Content of
38
+ enoent ->
39
+ read_partial("error");
40
+ [] ->
41
+ read_partial("error");
42
+ _ ->
43
+ Content
44
+ end.
@@ -0,0 +1,20 @@
1
+ # Configuration file for Yaws HTTP daemon
2
+
3
+ # This config defines virtual server localhost. It is
4
+ # enabled by default. If you want to disable it, remove
5
+ # symlink from /etc/yaws/conf.d/.
6
+
7
+ # Instead you may edit this file and after that reload
8
+ # yaws configureation using invoke-rc.d yaws reload
9
+
10
+ # (If you want to use privileged port, run yaws as root,
11
+ # setting YAWS_USER in /etc/default/yaws, or use port
12
+ # redirection, e.g. via iptables.)
13
+
14
+ <server localhost>
15
+ port = 8000
16
+ listen = 0.0.0.0
17
+ docroot = /Users/auser/Sites/work/citrusbyte/internal/gems/pool-party/poolparty/lib/erlang/cloudpanel/www
18
+ appmods = <"tail", tailer>
19
+ # dir_listings = true
20
+ </server>
@@ -9,6 +9,6 @@
9
9
  % erl -pa /var/lib/gems/1.8/gems/poolparty-0.2.37/lib/erlang/messenger/ebin -kernel inet_dist_listen_min 7000 inet_dist_listen_max 7050 -sname client -setcookie poolparty -run pm_client start
10
10
 
11
11
  % Get the load
12
- % erl -pa /var/lib/gems/1.8/gems/poolparty-0.2.38/lib/erlang/messenger/ebin -kernel inet_dist_listen_min 7000 inet_dist_listen_max 7050 -sname client -setcookie poolparty -run pm_client start -run pm_client get_load cpu -run erlang init stop
12
+ % erl -pa /var/lib/gems/1.8/gems/poolparty-0.2.40/lib/erlang/messenger/ebin -kernel inet_dist_listen_min 7000 inet_dist_listen_max 7050 -sname client -setcookie poolparty -run pm_client start -run pm_client get_load cpu -run erlang init stop
13
13
 
14
14
  % cd /var/poolparty && gem uninstall poolparty && wget http://github.com/auser/poolparty/tree/master%2Fpkg%2Fpoolparty-latest.gem?raw=true -O poolparty-latest.gem 2>&1 && gem install --no-ri --no-rdoc poolparty-latest.gem
@@ -8,10 +8,12 @@ module Aska
8
8
  returning look_up_rules(name) do |rs|
9
9
  arr.each do |line|
10
10
  next unless line
11
- k = line[/(.+)[=\\\<\>](.*)/, 1].gsub(/\s+/, '')
12
- v = line[/(.+)[=\\<>](.*)/, 2].gsub(/\s+/, '')
13
- m = line[/[=\\<>]/, 0].gsub(/\s+/, '')
14
-
11
+ rule = Rule.new(line)
12
+ raise LoadRulesException.new(line) unless rule.valid?
13
+ k = rule.key
14
+ v = rule.var
15
+ m = rule.comparison
16
+
15
17
  create_instance_variable(k, create_vars)
16
18
  rs << {k => [m, v]}
17
19
  rs << {k => [">", "0"]} unless rs.reject {|a| a.to_s == "#{k}>0" }
@@ -118,6 +120,29 @@ module Aska
118
120
  receiver.send :include, InstanceMethods
119
121
  end
120
122
 
123
+ class Rule < String
124
+ attr_accessor :value
125
+
126
+ def initialize(v)
127
+ @value = v
128
+ end
129
+ def valid?
130
+ value =~ /(.+)[=\\\<\>](.*)/
131
+ end
132
+ def key
133
+ value[/(.+)[=\\\<\>](.*)/, 1].gsub(/\s+/, '')
134
+ end
135
+ def comparison
136
+ value[/[=\\<>]/, 0].gsub(/\s+/, '')
137
+ end
138
+ def var
139
+ value[/(.+)[=\\<>](.*)/, 2].gsub(/\s+/, '')
140
+ end
141
+ def value
142
+ @value ||= ""
143
+ end
144
+ end
145
+
121
146
  class Rules < Array
122
147
  def to_s
123
148
  self.map {|r| v=r.keys.first;"'#{v} #{r[v][0]} #{r[v][1]}'"}.join(", ")