auser-poolparty 0.2.39 → 0.2.40

Sign up to get free protection for your applications and to get access to all the features.
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(", ")