initial import of webmachine-based api

This commit is contained in:
Bart Van Der Meerssche 2010-02-25 17:45:11 +00:00
parent 6a9d4d3f62
commit 6d907016dd
392 changed files with 25592 additions and 0 deletions

6
web/api/flukso/Emakefile Normal file
View File

@ -0,0 +1,6 @@
% -*- mode: erlang -*-
{["src/*"],
[{i, "include"},
{outdir, "ebin"},
debug_info]
}.

23
web/api/flukso/Makefile Normal file
View File

@ -0,0 +1,23 @@
ERL ?= erl
EBIN_DIRS := $(wildcard deps/*/ebin)
APP := flukso
all: erl ebin/$(APP).app erlrrd
erl:
@$(ERL) -pa $(EBIN_DIRS) -noinput +B \
-eval 'case make:all() of up_to_date -> halt(0); error -> halt(1) end.'
docs:
@erl -noshell -run edoc_run application '$(APP)' '"."' '[]'
clean:
@echo "removing:"
@rm -fv ebin/*.beam ebin/*.app
ebin/$(APP).app: src/$(APP).app
@cp -v src/$(APP).app $@
erlrrd:
@(cd deps/erlrrd;$(MAKE))

View File

@ -0,0 +1 @@
fess <fess-erlrrd@fess.org>

View File

@ -0,0 +1,10 @@
Version 0.3.0
* enable a timeout env_var for setting the port timeout
* change app spec to use a port time out of 30s.
Version 0.2.2
* catch port exit and exit the gen_server
VERSION 0.2.1
* rebuild with latest framewerk to get erlrc hooks
* specify dependency on rrdtool

View File

@ -0,0 +1,11 @@
all:
(cd src;$(MAKE) all)
edoc:
(cd src;$(MAKE) edoc)
test:
(cd src;$(MAKE) test)
clean:
(cd src;$(MAKE) clean)

View File

@ -0,0 +1 @@
# put whatever (auto)make commands here, they will be included from Makefile.am

View File

View File

@ -0,0 +1,9 @@
This module provides a gen_server controlling a Port to "rrdtool -"
rrdtool is a very nice graphing system as well as logger for time series data.
for more info on rrdtool check out:
http://oss.oetiker.ch/rrdtool/
for more info on this, the erlrrd module see the doc directory.

View File

@ -0,0 +1,5 @@
if you're trying to build this package from the source repository
ie: not from a dist tarball you'll need to understand the "Framewerk
build system", and the usual autoconf, automake, make voodoo. Framewerk
is just more voodoo on top of that to make things "easier".

View File

@ -0,0 +1,17 @@
#! /bin/sh
if test -d fw/bin
then
PATH="`pwd`/fw/bin:$PATH"
export PATH
fi
fwb=`which fw-bootstrap`
if test -z "$fwb"
then
echo "bootstrap: fatal: fw-bootstrap not installed or not in PATH" 1>&2
exit 1
fi
"$fwb" --fw_version "0.1.2" --name erlrrd --template erlang --revision svn --svn_project_path https://erlrrd.googlecode.com/svn/trunk/erlrrd "$@"

View File

@ -0,0 +1,5 @@
dnl -- include additional autoconf commands here
dnl -- do not include AC_OUTPUT, this is called for you
AC_CONFIG_FILES([doc/overview.edoc])

View File

@ -0,0 +1 @@
# put whatever (auto)make commands here, they will be included from Makefile.am

View File

@ -0,0 +1,9 @@
@author @FW_PACKAGE_MAINTAINER@
@copyright 2007
@version @VERSION@
@title erlrrd - erlang bindings for rrdtool
@doc erlrrd is a gen_server controlling an erlang Port running the command "rrdtool -"
it provides functions for each of the
[http://oss.oetiker.ch/rrdtool/index.en.html rrdtool]
commands with
a bit of error checking to make sure the communication doesn't hang.

View File

@ -0,0 +1,12 @@
{application, erlrrd,
[{description, "erlang rrdtool port"},
{vsn, "1.0"},
{modules, [
erlrrd,
erlrrd_app,
erlrrd_sup
]},
{registered, [erlrrd, erlrrd_sup]},
{mod, {erlrrd_app, []}},
{env, []},
{applications, [kernel, stdlib]}]}.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1 @@
# put whatever (auto)make commands here, they will be included from Makefile.am

View File

@ -0,0 +1,30 @@
# The FW_PACKAGE_MAINTAINER field is populated with the
# environment variable FW_PACKAGE_DEFAULT_MAINTAINER if non-empty
FW_PACKAGE_NAME="erlrrd"
FW_PACKAGE_VERSION="0.3.0"
FW_PACKAGE_MAINTAINER="fess <fess-erlrrd@fess.org>"
FW_PACKAGE_SHORT_DESCRIPTION="rrdtool binding for erlang. [ via an erlang Port. ]"
FW_PACKAGE_DESCRIPTION="`cat README`"
FW_PACKAGE_ARCHITECTURE_DEPENDENT="0"
FW_SUBVERSION_TAG_ROOT="https://erlrrd.googlecode.com/svn/tags/"
# Dependency information. The native syntax corresponds to Debian,
# http://www.debian.org/doc/debian-policy/ch-relationships.html
# Section 7.1 "Syntax of Relationship Fields"
#
# For other packaging systems, the syntax is translated for you.
FW_PACKAGE_DEPENDS="rrdtool"
FW_PACKAGE_CONFLICTS=""
FW_PACKAGE_PROVIDES=""
FW_PACKAGE_REPLACES=""
FW_PACKAGE_BUILD_DEPENDS="eunit"
FW_PACKAGE_BUILD_CONFLICTS=""
FW_ERL_APP_ENVIRONMENT="[
{rrdtoolcmd, \"rrdtool -\"},
{timeout, 30000 }
]"

View File

@ -0,0 +1,9 @@
#! /bin/sh
#---------------------------------------------------------------------
# post-install
#
# Executed after the package is installed.
#---------------------------------------------------------------------
exit 0

View File

@ -0,0 +1,9 @@
#! /bin/sh
#---------------------------------------------------------------------
# post-remove
#
# Executed after the package is removed.
#---------------------------------------------------------------------
exit 0

View File

@ -0,0 +1,9 @@
#! /bin/sh
#---------------------------------------------------------------------
# pre-install
#
# Executed before the package is installed.
#---------------------------------------------------------------------
exit 0

View File

@ -0,0 +1,9 @@
#! /bin/sh
#---------------------------------------------------------------------
# pre-remove
#
# Executed before the package is removed.
#---------------------------------------------------------------------
exit 0

View File

@ -0,0 +1,10 @@
#! /bin/sh
#---------------------------------------------------------------------
# start
#
# Executed when the package (service) is started up.
# Not supported by all package formats.
#---------------------------------------------------------------------
exit 0

View File

@ -0,0 +1,10 @@
#! /bin/sh
#---------------------------------------------------------------------
# start
#
# Executed when the package (service) is shut down.
# Not supported by all package formats.
#---------------------------------------------------------------------
exit 0

View File

@ -0,0 +1,20 @@
include ../support/include.mk
APPLICATION=erlrrd
DOC_OPTS={dir,\"../doc\"}
all: $(EBIN_FILES)
debug:
$(MAKE) DEBUG=-DDEBUG
clean:
rm -rf $(EBIN_FILES)
edoc:
$(ERL) -noshell -pa ../ebin \
-eval "edoc:application($(APPLICATION), \".\", [$(DOC_OPTS)])" \
-s init stop
test: all
$(ERL) -noshell -pa ../ebin -s $(APPLICATION) test -s init stop

View File

@ -0,0 +1,16 @@
# put whatever (auto)make commands here, they will be included from Makefile.am
DIALYZERFLAGS = -Wno_improper_lists
dist_erlappsrc_DATA = \
$(wildcard *.erl)
dist_erlappinclude_DATA = \
$(wildcard *.hrl)
erlappebin_SCRIPTS = \
@FW_PACKAGE_NAME@.app \
$(patsubst %.erl, %.beam, $(dist_erlappsrc_DATA))
check_DATA = \
.dialyzer_ok

View File

@ -0,0 +1,12 @@
{application, erlrrd,
[{description, "erlang rrdtool port"},
{vsn, "1.0"},
{modules, [
erlrrd,
erlrrd_app,
erlrrd_sup
]},
{registered, [erlrrd, erlrrd_sup]},
{mod, {erlrrd_app, []}},
{env, []},
{applications, [kernel, stdlib]}]}.

View File

@ -0,0 +1,865 @@
-module(erlrrd).
-include_lib ("eunit/include/eunit.hrl").
-export([create/1, update/1, updatev/1, dump/1, restore/1, last/1,
first/1, info/1, fetch/1, tune/1, resize/1, xport/1,
graph/1, lastupdate/1, ls/0, cd/1, mkdir/1, pwd/0
]).
-export([start_link/1, start_link/0]).
-export([start/0]).
-export([stop/0]).
-export([combine/1, c/1]).
-behaviour(gen_server).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
-record( state2, { port, timeout } ).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Public
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% @equiv erlrrd_app:start()
start() -> erlrrd_app:start().
%% @equiv erlrrd_app:stop()
stop() -> erlrrd_app:stop().
%% @spec start_link(RRDToolCmd) -> Result
%% RRDToolCmd = string()
%% Result = {ok,Pid} | ignore | {error,Error}
%% Pid = pid()
%% Error = {already_started,Pid} | shutdown | term()
%% @doc calls gen_server:start_link
%% RRDToolCmd is the command passed to open_port()
%% usually "rrdtool -"
start_link(RRDToolCmd) when is_list(RRDToolCmd) ->
application:set_env(erlrrd, rrdtoolcmd, RRDToolCmd ),
start_link().
%% @equiv start_link("rrdtool -")
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
%% @spec combine(List) -> List
%% List = [ term() ]
%% @doc "joins" and quotes the given arg list.
%% takes a list of arguments, and returns a deeplist with
%% each argument surrounded by double quotes
%% then separated by spaces. Note
%% it does not try to escape any double quotes
%% in the arguments.
%%
%% combine(["these", "are", "my args"]). ->
%%
%% [["\"","these","\""]," ",["\"","are","\""]," ",["\"","my args","\""]]
%%
%% it is intended as a convinence function to the
%% rrdtool commands which all take a single iodata() argument
%% which represents the string to be passed as the arguments
%% to the corresponding rrdtool command.
%%
%% erlrrd:xport(erlrrd:c(["DEF:foo=/path with/space/foo.rrd:foo:AVERAGE", "XPORT:foo"])).
combine(Args) ->
join([ [ "\"", X, "\"" ] || X <- Args ], " ").
%% @spec c(List) -> List
%% List = [ term() ]
% @equiv combine(Args)
c(Args) -> combine(Args).
% rrdtool commands
%% @spec create(erlang:iodata()) -> { ok, Response } |
%% { error, Reason }
%% Reason = iolist()
%% Response = iolist()
%% @doc Set up a new Round Robin Database (RRD). Check
%% [http://oss.oetiker.ch/rrdtool/doc/rrdcreate.en.html rrdcreate].
create (Args) when is_list(Args) -> do(create, Args).
%% @spec update(erlang:iodata()) -> { ok, Response } |
%% { error, Reason }
%% Reason = iolist()
%% Response = iolist()
%% @doc Store new data values into an RRD. Check
%% [http://oss.oetiker.ch/rrdtool/doc/rrdupdate.en.html rrdupdate].
update (Args) when is_list(Args) -> do(update, Args).
%% @spec updatev(erlang:iodata()) -> { ok, Response } |
%% { error, Reason }
%% Reason = iolist()
%% Response = iolist()
%% @doc Operationally equivalent to update except for output. Check
%% [http://oss.oetiker.ch/rrdtool/doc/rrdupdate.en.html rrdupdate].
updatev (Args) when is_list(Args) -> do(updatev, Args).
%% @spec dump(erlang:iodata()) -> { ok, Response } |
%% { error, Reason }
%% Reason = iolist()
%% Response = iolist()
%% @doc Dump the contents of an RRD in plain ASCII. In connection with
%% restore you can use this to move an RRD from one computer
%% architecture to another. Check
%% [http://oss.oetiker.ch/rrdtool/doc/rrddump.en.html rrddump].
dump (Args) when is_list(Args) -> do(dump, Args).
%% @spec restore(erlang:iodata()) -> { ok, Response } |
%% { error, Reason }
%% Reason = iolist()
%% Response = iolist()
%% @doc Restore an RRD in XML format to a binary RRD. Check
%% [http://oss.oetiker.ch/rrdtool/doc/rrdrestore.en.html rrdrestore]
restore (Args) when is_list(Args) -> do(restore, Args).
%% @spec last(erlang:iodata()) -> { ok, Response } |
%% { error, Reason }
%% Reason = iolist()
%% Response = integer()
%% @doc Return the date of the last data sample in an RRD. Check
%% [http://oss.oetiker.ch/rrdtool/doc/rrdlast.en.html rrdlast]
last (Args) when is_list(Args) ->
case do(last, Args) of
{ error, Reason } -> { error, Reason };
{ ok, [[Response]] } -> { ok, erlang:list_to_integer(Response) }
end.
%% @spec lastupdate(erlang:iodata()) -> { ok, Response } |
%% { error, Reason }
%% Reason = iolist()
%% Response = iolist()
%% @doc Return the most recent update to an RRD. Check
%% [http://oss.oetiker.ch/rrdtool/doc/rrdlastupdate.en.html rrdlastupdate]
lastupdate (Args) when is_list(Args) -> do(lastupdate, Args).
%% @spec first(erlang:iodata()) -> { ok, Response } |
%% { error, Reason }
%% Reason = iolist()
%% Response = integer()
%% @doc Return the date of the first data sample in an RRA within an
%% RRD. Check
%% [http://oss.oetiker.ch/rrdtool/doc/rrdfirst.en.html rrdfirst]
first (Args) when is_list(Args) ->
case do(first, Args) of
{ error, Reason } -> { error, Reason };
{ ok, [[Response]] } -> { ok, erlang:list_to_integer(Response) }
end.
%% @spec info(erlang:iodata()) -> { ok, Response } |
%% { error, Reason }
%% Reason = iolist()
%% Response = iolist()
%% @doc Get information about an RRD. Check
%% [http://oss.oetiker.ch/rrdtool/doc/rrdinfo.en.html rrdinfo].
info (Args) when is_list(Args) -> do(info, Args).
%% @spec fetch(erlang:iodata()) -> { ok, Response } |
%% { error, Reason }
%% Reason = iolist()
%% Response = iolist()
%% @doc Get data for a certain time period from a RRD. The graph func-
%% tion uses fetch to retrieve its data from an RRD. Check
%% [http://oss.oetiker.ch/rrdtool/doc/rrdfetch.en.html rrdfetch].
fetch (Args) when is_list(Args) -> do(fetch, Args).
%% @spec tune(erlang:iodata()) -> { ok, Response } |
%% { error, Reason }
%% Reason = iolist()
%% Response = iolist()
%% @doc Alter setup of an RRD. Check
%% [http://oss.oetiker.ch/rrdtool/doc/rrdtune.en.html rrdtune].
tune (Args) when is_list(Args) -> do(tune, Args).
%% @spec resize(erlang:iodata()) -> { ok, Response } |
%% { error, Reason }
%% Reason = iolist()
%% Response = iolist()
%% @doc Change the size of individual RRAs. This is dangerous! Check
%% rrdresize.
resize (Args) when is_list(Args) -> do(resize, Args).
%% @spec xport(erlang:iodata()) -> { ok, Response } |
%% { error, Reason }
%% Reason = iolist()
%% Response = iolist()
%% @doc Export data retrieved from one or several RRDs. Check
%% [http://oss.oetiker.ch/rrdtool/doc/rrdxport.en.html rrdxport]
%%
%% erlrrd:xport("'DEF:foo=/path with/space/foo.rrd:foo:AVERAGE' XPORT:foo").
%%
%% erlrrd:xport(erlrrd:c(["DEF:foo=/path with/space/foo.rrd:foo:AVERAGE", "XPORT:foo"])).
xport (Args) when is_list(Args) -> do(xport, Args).
%% @spec graph(erlang:iodata()) -> { ok, Response } |
%% { error, Reason }
%% Reason = iolist()
%% Response = iolist()
%% @doc Create a graph from data stored in one or several RRDs. Apart
%% from generating graphs, data can also be extracted to stdout.
%% Check
%% [http://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html rrdgraph].
graph (Args) when is_list(Args) ->
% TODO: scan for this pattern w/out flattening the io_list?
% TODO: support graphing to stdout!!! :)
Flat = erlang:binary_to_list(erlang:iolist_to_binary(Args)),
case regexp:match(Flat, "(^| )-( |$)") of
{ match, _, _ } ->
% graph to stdout will break this Ports parsing of reponses..
{ error, "Graphing to stdout not supported." };
nomatch ->
do(graph, Args)
end.
%%%%% rrd "remote" commands %%%%
%% @spec cd(erlang:iodata()) -> ok |
%% { error, Reason }
%% Reason = iolist()
%% @doc ask the rrdtool unix process to change directories
%%
%% erlrrd:cd("/usr/share/rrd/data").
%%
%% erlrrd:cd(erlrrd:combine(["/Users/foo/Library/Application Support/myapp/rrd"]).
cd (Arg) when is_list(Arg) ->
case do(cd, Arg) of
{ error, Reason } -> { error, Reason };
{ ok, _ } -> ok
end.
%% @spec mkdir(erlang:iodata()) -> { ok, Response } |
%% { error, Reason }
%% Reason = iolist()
%% Response = iolist()
%% @doc ask the rrdtool unix process to create a directory
mkdir (Arg) when is_list(Arg) -> do(mkdir, Arg).
%% @spec ls() -> { ok, Response } | { error, Reason }
%% Reason = iolist()
%% Response = iolist()
%% @doc lists all *.rrd files in rrdtool unix process'
%% current working directory
ls () -> do(ls, [] ).
%% @spec pwd() -> { ok, Response } | { error, Reason }
%% Reason = iolist()
%% Response = string()
%% @doc return the rrdtool unix process'
%% current working directory.
pwd () ->
case do(pwd, []) of
{ error, Reason } -> { error, Reason };
{ ok, [[Response]] } -> { ok, Response }
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Gen server interface poo
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% @hidden
init([]) ->
RRDToolCmd = case application:get_env(erlrrd, rrdtoolcmd) of
{ ok, Cmd } -> Cmd;
undefined -> "rrdtool -"
end,
Timeout = case application:get_env(erlrrd, timeout) of
{ ok, T } -> T;
undefined -> 3000
end,
process_flag(trap_exit, true),
Port = erlang:open_port(
{spawn, RRDToolCmd},
[ {line, 10000}, eof, exit_status, stream ]
),
{ok, #state2{port = Port, timeout = Timeout}}.
%% handle_call
%% @hidden
handle_call(
{do, Action, Args },
_From,
#state2{port = Port, timeout = Timeout } = State
) ->
Line = [ erlang:atom_to_list(Action), " ", Args , "\n"],
port_command(Port, Line),
case collect_response(Port, Timeout) of
{response, Response} ->
{reply, { ok, Response }, State};
{ error, timeout } ->
{stop, port_timeout, State};
{ error, Error } ->
{reply, { error, Error }, State}
end.
%% handle_cast
%% @hidden
handle_cast(_Msg, State) ->
% io:format(user, "Got unexpected cast msg: ~p~n", [Msg]),
%% TODO error/event loging in erlang style.
{noreply, State}.
%% handle_info
%% @hidden
handle_info({ Port , {exit_status, Status}}, State)
when
Port =:= State#state2.port
->
{ stop, { port_exit, Status }, State};
handle_info(_Msg, State) ->
% io:format(user, "Got unexpected info msg: ~p~n", [Msg]),
%% TODO error/event loging in erlang style.
{noreply, State}.
%% terminate
%% @hidden
terminate(_Reason, _State) -> ok.
%% code_change
%% @hidden
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Private poo
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
do(Command, Args) ->
case has_newline(Args) of
true -> { error, "No newlines" };
false -> gen_server:call (?MODULE, { do, Command, Args } )
end.
join([Head | [] ], _Sep) ->
[Head];
join([Head | Tail], Sep) ->
[ Head, Sep | join(Tail, Sep) ].
has_newline([]) -> false;
has_newline(<<>>) -> false;
has_newline([ H | T])
when is_list(H); is_binary(H) ->
case has_newline(H) of
true -> true;
false -> has_newline(T)
end;
has_newline([ H | T]) when is_integer(H) ->
if
H =:= $\n -> true;
true -> has_newline(T)
end;
has_newline(<<H:8,T/binary>>) ->
if
H =:= $\n -> true;
true -> has_newline(T)
end.
collect_response(Port, Timeout ) ->
collect_response(Port, [], [], Timeout ).
collect_response( Port, RespAcc, LineAcc, Timeout) ->
receive
{Port, {data, {eol, "OK u:" ++ _T }}} ->
{response, lists:reverse(RespAcc)};
{Port, {data, {eol, "ERROR: " ++ Error }}} ->
{error, [ Error, lists:reverse(RespAcc)]};
{Port, {data, {eol, Result}}} ->
Line = lists:reverse([Result | LineAcc]),
collect_response(Port, [Line | RespAcc], [], Timeout);
{Port, {data, {noeol, Result}}} ->
collect_response(Port, RespAcc, [Result | LineAcc], Timeout)
%% Prevent the gen_server from hanging indefinitely in case the
%% spawned process is taking too long processing the request.
after Timeout ->
{ error, timeout }
end.
-ifdef(EUNIT).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Test Helpers
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
test_start_stop_(StartFun, StopFun, Tag) ->
{ spawn,
{ inorder,
[
check_stopped_(Tag),
{ Tag, setup,
StartFun,
StopFun,
check_started_(Tag)
},
check_stopped_(Tag)
]
}
}.
check_started_(Tag) ->
wrap_tag_(Tag,
[
?_test(ls()),
?_test(pwd()),
?_test(ok),
?_test(ok)
]
).
check_stopped_(Tag) ->
wrap_tag_(Tag,
[
?_assertExit( { noproc, _ }, pwd()),
?_assertExit( { noproc, _ }, ls())
]
).
check_last_(RRDFile,Now) ->
fun () ->
{ ok, When } = erlrrd:last(RRDFile),
When = Now
end.
start_helper_() ->
application:unset_env(erlrrd, rrdtoolcmd),
application:unset_env(erlrrd, timeout),
{ok, Pid} = start_link(),
Pid.
stop_helper_(Pid) -> stop_helper_(Pid, 3000).
stop_helper_(Pid, Timeout) ->
true = exit(Pid, normal),
receive
{'EXIT', Pid, Reason} -> Reason
after Timeout ->
throw({ timeout, { Pid, "Pid not responding to EXIT?"} })
end.
% check if the dir we're in end's in /tests
check_cwd_helper_() ->
{ ok, L } = file:get_cwd(),
"stset/" ++ _ = lists:reverse(L).
p_func(X,Steps) ->
Pi = math:pi(),
5 * (
math:sin( 3*Pi/2 + X/(Steps / (8*Pi) ) )
+ 1
).
time_since_epoch() ->
calendar:datetime_to_gregorian_seconds( erlang:universaltime())
- ( 719528 * 86400 ).
wrap_tag_(T,L) when is_list(L) ->
[ { T, X } || X <- L ].
cast(Blah) ->
gen_server:cast(?MODULE, Blah ).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Tests
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% test starting and stopping %%%%
-define(spew(Args), io:format(user, "~p~n", [{Args}])).
-define(assertExists(File),
{ ok, _ } = file:read_file_info(File)).
-define(assertEnoent(File),
{ error, enoent } = file:read_file_info(File)).
start_link_test_() ->
test_start_stop_(
fun start_helper_/0,
fun stop_helper_/1,
"start_link test"
).
start_stop_test_() ->
test_start_stop_(
fun() -> ok = start() end,
fun(_) -> ok = stop() end,
"start/0 stop/0"
).
start_sup_test_() ->
test_start_stop_(
fun() ->
{ok,Pid} = erlrrd_sup:start_link(),
Pid
end,
fun stop_helper_/1,
"sup:start_link/0 exit/2"
).
start_sup2_test_() ->
test_start_stop_(
fun() ->
check_cwd_helper_(),
{ok,Pid} = erlrrd_sup:start_link("./dummyrrdtool"),
Pid
end,
fun stop_helper_/1,
"sup:start_link/1 exit/2"
).
start_app_test_() ->
test_start_stop_(
fun() -> ok = erlrrd_app:start() end,
fun(_) -> ok = erlrrd_app:stop() end,
"app:start/0 app:stop/0"
).
%%%% test interfaces %%%%
datain_dataout_test_() ->
Prefix = "foo",
RRDFile = Prefix ++ ".rrd",
PNGFile = Prefix ++ ".png",
RRDDump = Prefix ++ ".rrd.xml",
RRDRestoredFile = Prefix ++ ".2.rrd",
Now = time_since_epoch(),
Then = Now - 86400,
StepSize = 60,
Steps = round((Now - Then) / StepSize),
{ setup,
fun() ->
check_cwd_helper_(),
file:delete(RRDFile),
file:delete(RRDDump),
file:delete(RRDRestoredFile),
?assertEnoent(RRDFile),
{ ok, Pid } = start_link(),
Pid
end,
fun(Pid) ->
stop_helper_(Pid),
file:delete(RRDFile),
file:delete(RRDDump),
file:delete(RRDRestoredFile),
ok
end,
{ inorder,
[
% create an rrd
fun() ->
{ok, _ } = erlrrd:create([
io_lib:fwrite("~s --start ~B", [RRDFile, Then]),
io_lib:fwrite(" --step ~B DS:thedata:GAUGE:~B:U:U",
[ StepSize, StepSize ]),
io_lib:fwrite(" RRA:AVERAGE:0.5:1:~B",[Steps])
])
end,
% write sin wave to rrd
fun() ->
lists:foreach(
fun(X) ->
P = p_func(X,Steps),
%io:format(user, "~s ~B:~f~n", [ RRDFile, Then + X * StepSize, P ]),
{ok, _ } = erlrrd:update(
io_lib:format("~s ~B:~f", [ RRDFile, Then + X * StepSize, P ])
)
end,
lists:seq(1, Steps)
)
end,
% check the update times
check_last_(RRDFile, Now),
fun() ->
{ ok, When } = erlrrd:first(RRDFile),
RoundThen = (erlang:trunc(Then/StepSize) + 1) * StepSize,
When = RoundThen
end,
?_test(?assertMatch({error, _}, erlrrd:last("/somenothing/file"))),
?_test(?assertMatch({error, _}, erlrrd:first("/somenothing/file"))),
% make a graph!! :)
fun() ->
{ ok, _ } = erlrrd:graph([
"-l 0 -r", " ",
"-w 700 -h 200 -a PNG ", PNGFile,
" DEF:thedata=", RRDFile, ":thedata:AVERAGE AREA:thedata#CC9945",
io_lib:format(" --start ~B --end ~B", [ Then, Now ])
])
% ok, now how can we check the graph??? hmm.
end,
% run fetch
fun() ->
{ ok, _Data } = erlrrd:fetch([
RRDFile, " AVERAGE ",
io_lib:format(" --start ~B --end ~B", [ Then, Now ])
]),
%?spew(Data),
%TODO check data
ok
end,
% dump the rrd
fun() ->
?assertEnoent(RRDDump),
{ ok, _ } = erlrrd:dump( RRDFile ++ " " ++ RRDDump ),
?assertExists(RRDDump)
end,
% restore the rrd
fun() ->
?assertExists(RRDDump),
?assertEnoent(RRDRestoredFile),
{ ok, _ } = erlrrd:restore( RRDDump ++ " " ++ RRDRestoredFile ),
?assertExists(RRDRestoredFile)
end,
check_last_(RRDRestoredFile, Now),
% xport
{ "xport",
fun() ->
?assertExists(RRDRestoredFile),
{ok, Response} = xport([
"DEF:c=", RRDRestoredFile, ":thedata:AVERAGE",
" XPORT:c",
io_lib:format(" --start ~B --end ~B", [ Then, Now ])
]),
%% TODO check response
Response
end
},
%lastupdate
fun() ->
{ ok, [ _, _, [Last]] } = lastupdate(RRDRestoredFile),
?assertMatch(
{match, _, _ },
regexp:match(Last,
% TODO make the regex match beginning of line? why no work?
io_lib:format("~B", [ Now ])
)
),
ok
end,
% info
fun() ->
{ ok, Info } = info(RRDFile),
[ ["filename = " ++ _L] | _T ] = Info
end,
fun() -> commas_are_cool end
]
}
}.
remote_cmds_test_() ->
Dir = "makadir",
{ setup,
fun() ->
check_cwd_helper_(),
?assertEnoent(Dir),
start_helper_()
end,
fun(P) ->
file:del_dir(Dir),
stop_helper_(P)
end,
{ inorder,
[
% pwd
{ "pwd1", fun() ->
{ ok, Cwd } = erlrrd:pwd(),
"stset/" ++ _ = lists:reverse(Cwd)
end},
{ "mkdir", fun() -> erlrrd:mkdir(Dir) end },
{ "cd ", fun() -> ok = erlrrd:cd(Dir) end},
% pwd
{ "pwd2",
fun() ->
{ ok, Cwd } = erlrrd:pwd(),
{ match, _, _ } =
regexp:match(Cwd, "/tests/" ++ Dir ++ "$")
end
},
{ "ls",
fun() ->
% relys on '.' and '..' always returning first?
% is that a bad idea?
{ ok, List } = ls(),
io:format(user," ~p~n", [List]),
?assert( lists:any(fun(X) -> X =:= ["d .."] end, List))
end },
fun() -> commas_are_cool end
]
}
}.
c_test_() ->
[
?_test(
[
["\"", "these", "\""], " ",
["\"", "are", "\""], " ",
["\"", "my", "\""], " ",
["\"", "args", "\""]
] = c(["these", "are", "my", "args"])),
?_test([[ "\"", "a", "\""]] = c(["a"]))
].
pass_newlines_test_() ->
M = "No newlines",
{ setup,
fun start_helper_/0,
fun stop_helper_/1,
[
?_assertMatch( { error, M }, cd("..\n")),
?_assertMatch( { error, M }, info("fart.rrd\n")),
?_assertMatch( { error, M },
create(["foo.rrd bar baz", [[[[<<"blahdedah\n">>]]]], "haha"])
),
fun() -> ok end
]
}.
graph_to_stdout_saftey_test_() ->
M = { error, "Graphing to stdout not supported." },
[
?_assertMatch( M, graph(" -")),
?_assertMatch( M, graph("-")),
?_assertMatch( M, graph(" - ")),
?_assertMatch( M, graph([" ", "-"," "])),
?_assertMatch( M, graph([" ", [[["-"]]]," "])),
?_assertMatch( M, graph([" ", [[["-"]]]])),
?_assertMatch( M, graph([[[["-"]]]," "])),
?_assertMatch( M, graph([" ", [[[<<"-">>]]]," "])),
?_assertMatch( M, graph([" ", [[[<<"-">>]]]])),
?_assertMatch( M, graph([[[[<<"-">>]]]," "])),
fun() -> ok end
].
%%%% tests for corner cases %%%%
cause_long_response_test_() ->
{ setup,
fun() ->
check_cwd_helper_(),
{ ok, Pid } = start_link("./dummyrrdtool -"),
Pid
end,
fun stop_helper_/1,
?_test(do(longresponse, []))
}.
cause_timeout_test_() ->
{ setup,
fun() ->
check_cwd_helper_(),
ok = application:set_env(erlrrd, timeout, 1),
{ ok, Pid } = erlrrd_sup:start_link("./dummyrrdtool -"),
Pid
end,
fun stop_helper_/1,
?_assertExit({port_timeout, _}, do(timeout, []))
}.
%%%% tests of privates %%%%
join_test() ->
[ "a", " ", "b", " ", "c"] = join(["a", "b", "c"], " ").
join_test_() ->
[
?_test([ "a", " ", "b", " ", "c"] = join(["a", "b", "c"], " ")),
?_assertNot([ "a", "b", " ", "c"] =:= join(["a", "b", "c"], " "))
].
has_newline_test_() ->
[
?_test( true = has_newline("\n")),
?_test( true = has_newline(["\n"])),
?_test( true = has_newline(
["these", ["are", [ "my args" ] | <<"newline\n">> ], "so", "there"])),
?_test( false = has_newline(
["these", ["are", [ "my args" ] | <<"newline">> ], "so", "there"])),
?_test( true = has_newline(
["these\n", ["are", [ "my args" ] | <<"newline">> ], "so", "there"])),
?_test( true = has_newline(
["these", ["are",
[ "my args" | [[[[[[[[ "blah\n"]]]]]]]] ] | <<"newline">> ],
"so", "there"])),
?_test( false = has_newline("")),
?_test( false = has_newline([])),
?_test( false = has_newline(<<>>))
].
%%%%% tests to get coverage %%%%%
should_be_done_better_test_() ->
{ setup,
fun start_helper_/0,
fun stop_helper_/1,
[
?_assertMatch( {error, _ }, tune("blah") ),
?_assertMatch( {error, _ }, resize("blah") ),
?_assertMatch( {error, _ }, updatev("blah") ),
?_test(ok)
]
}.
handle_cast_test_() ->
{ setup,
fun start_helper_/0,
fun stop_helper_/1,
?_test(cast(blah))
}.
handle_info_test_() ->
{ setup,
fun start_helper_/0,
fun stop_helper_/1,
?_test(?MODULE ! yo)
}.
stop_helper_test_() ->
{ setup,
% start fun
fun() ->
F = fun(F) ->
receive
Any -> io:format(user,"~p Hey, got: ~p~n", [ self(), Any ])
end,
F(F)
end,
spawn(
fun() ->
process_flag(trap_exit, true),
F(F)
end
)
end,
% stop fun,
fun(P) -> exit(P, kill) end,
% test gen
fun(P) ->
?_assertThrow({timeout,_}, stop_helper_(P, 1))
end
}.
port_exit_test_() ->
?_assert(
begin
io:format(user, "~n==== test: expect erlrrd exit~n", []),
{ok,Pid} = start_link("./dummyrrdtool"),
{ok, _} = do(die, []),
receive
{ 'EXIT', Pid, {port_exit, 1} } -> true
after 4000 ->
exit(Pid,kill),
false
end
end
).
code_change_test() ->
{ ok, state } = code_change( oldvsn, state, extra ).
-endif.

View File

@ -0,0 +1,18 @@
-module(erlrrd_app).
-export([start/0, stop/0]).
-behavior(application).
-export([start/2, stop/1]).
start() ->
application:start(erlrrd).
start(_Type, _Args) ->
erlrrd_sup:start_link().
stop() ->
application:stop(erlrrd).
stop(_State) ->
ok.

View File

@ -0,0 +1,42 @@
-module(erlrrd_sup).
-export([start_link/1, start_link/0]).
-behavior(supervisor).
-export([init/1]).
%% @spec start_link(RRDToolCmd) -> Result
%% RRDToolCmd = string()
%% Result = {ok,Pid} | ignore | {error,Error}
%% Pid = pid()
%% Error = {already_started,Pid} | shutdown | term()
start_link(RRDToolCmd) ->
application:set_env(erlrrd_sup, rrdtoolcmd, RRDToolCmd),
supervisor:start_link(erlrrd_sup, []).
%% @spec start_link() -> Result
%% Result = {ok,Pid} | ignore | {error,Error}
%% Pid = pid()
%% Error = {already_started,Pid} | shutdown | term()
start_link() ->
supervisor:start_link(erlrrd_sup, []).
init(_) ->
{
ok,
{
{one_for_one, 5, 10 },
[
{
erlrrd,
{ erlrrd, start_link, [] },
permanent,
3000,
worker,
[ erlrrd ]
}
]
}
}.

View File

@ -0,0 +1,39 @@
## -*- makefile -*-
######################################################################
## Erlang
ERL := erl
ERLC := $(ERL)c
INCLUDE_DIRS := ../include $(wildcard ../deps/*/include)
EBIN_DIRS := $(wildcard ../deps/*/ebin)
ERLC_FLAGS := -W $(INCLUDE_DIRS:../%=-I ../%) $(EBIN_DIRS:%=-pa %)
ifndef no_debug_info
ERLC_FLAGS += +debug_info
endif
ifdef debug
ERLC_FLAGS += -Ddebug
endif
EBIN_DIR := ../ebin
EMULATOR := beam
ERL_SOURCES := $(wildcard *.erl)
ERL_HEADERS := $(wildcard *.hrl) $(wildcard ../include/*.hrl)
ERL_OBJECTS := $(ERL_SOURCES:%.erl=$(EBIN_DIR)/%.$(EMULATOR))
ERL_OBJECTS_LOCAL := $(ERL_SOURCES:%.erl=./%.$(EMULATOR))
APP_FILES := $(wildcard *.app)
EBIN_FILES = $(ERL_OBJECTS) $(APP_FILES:%.app=../ebin/%.app)
MODULES = $(ERL_SOURCES:%.erl=%)
../ebin/%.app: %.app
cp $< $@
$(EBIN_DIR)/%.$(EMULATOR): %.erl
$(ERLC) $(ERLC_FLAGS) -o $(EBIN_DIR) $<
./%.$(EMULATOR): %.erl
$(ERLC) $(ERLC_FLAGS) -o . $<

View File

@ -0,0 +1,4 @@
TESTS = \
module-erlrrd

View File

@ -0,0 +1,26 @@
#!/bin/sh
while read cmd rest
do
case $cmd in
pwd)
echo "ERROR: pwd disabled for testing"
;;
timeout)
sleep 1
echo "ERROR: timed out"
;;
die)
echo "OK u:0.01 s:0.02 r:0.03"
exit 1
;;
longresponse)
perl -le 'print "a234567890123456789012345678901234567890" x (255)'
echo "OK u:0.01 s:0.02 r:0.03"
;;
*)
echo $cmd $rest
echo "OK u:0.01 s:0.02 r:0.03"
;;
esac
done

View File

@ -0,0 +1 @@
../../webmachine

View File

@ -0,0 +1 @@
{["sensor", sensor], flukso_resource, []}.

View File

@ -0,0 +1,8 @@
<html>
<head>
<title>It Worked</title>
</head>
<body>
MochiWeb running.
</body>
</html>

View File

@ -0,0 +1,14 @@
{application, flukso,
[{description, "flukso"},
{vsn, "0.1"},
{modules, [
flukso,
flukso_app,
flukso_sup,
flukso_deps,
flukso_resource
]},
{registered, []},
{mod, {flukso_app, []}},
{env, []},
{applications, [kernel, stdlib, crypto]}]}.

View File

@ -0,0 +1,44 @@
%% @author author <author@example.com>
%% @copyright YYYY author.
%% @doc TEMPLATE.
-module(flukso).
-author('author <author@example.com>').
-export([start/0, start_link/0, stop/0]).
ensure_started(App) ->
case application:start(App) of
ok ->
ok;
{error, {already_started, App}} ->
ok
end.
%% @spec start_link() -> {ok,Pid::pid()}
%% @doc Starts the app for inclusion in a supervisor tree
start_link() ->
flukso_deps:ensure(),
ensure_started(erlrrd),
ensure_started(crypto),
ensure_started(webmachine),
flukso_sup:start_link().
%% @spec start() -> ok
%% @doc Start the flukso server.
start() ->
flukso_deps:ensure(),
ensure_started(erlrrd),
ensure_started(crypto),
ensure_started(webmachine),
application:start(flukso).
%% @spec stop() -> ok
%% @doc Stop the flukso server.
stop() ->
Res = application:stop(flukso),
application:stop(erlrrd),
application:stop(webmachine),
application:stop(crypto),
Res.

View File

@ -0,0 +1 @@

View File

@ -0,0 +1,22 @@
%% @author author <author@example.com>
%% @copyright YYYY author.
%% @doc Callbacks for the flukso application.
-module(flukso_app).
-author('author <author@example.com>').
-behaviour(application).
-export([start/2,stop/1]).
%% @spec start(_Type, _StartArgs) -> ServerRet
%% @doc application start callback for flukso.
start(_Type, _StartArgs) ->
flukso_deps:ensure(),
flukso_sup:start_link().
%% @spec stop(_State) -> ServerRet
%% @doc application stop callback for flukso.
stop(_State) ->
ok.

View File

@ -0,0 +1,84 @@
%% @author author <author@example.com>
%% @copyright YYYY author.
%% @doc Ensure that the relatively-installed dependencies are on the code
%% loading path, and locate resources relative
%% to this application's path.
-module(flukso_deps).
-author('author <author@example.com>').
-export([ensure/0, ensure/1]).
-export([get_base_dir/0, get_base_dir/1]).
-export([local_path/1, local_path/2]).
-export([deps_on_path/0, new_siblings/1]).
%% @spec deps_on_path() -> [ProjNameAndVers]
%% @doc List of project dependencies on the path.
deps_on_path() ->
F = fun (X, Acc) ->
ProjDir = filename:dirname(X),
case {filename:basename(X),
filename:basename(filename:dirname(ProjDir))} of
{"ebin", "deps"} ->
[filename:basename(ProjDir) | Acc];
_ ->
Acc
end
end,
ordsets:from_list(lists:foldl(F, [], code:get_path())).
%% @spec new_siblings(Module) -> [Dir]
%% @doc Find new siblings paths relative to Module that aren't already on the
%% code path.
new_siblings(Module) ->
Existing = deps_on_path(),
SiblingEbin = filelib:wildcard(local_path(["deps", "*", "ebin"], Module)),
Siblings = [filename:dirname(X) || X <- SiblingEbin,
ordsets:is_element(
filename:basename(filename:dirname(X)),
Existing) =:= false],
lists:filter(fun filelib:is_dir/1,
lists:append([[filename:join([X, "ebin"]),
filename:join([X, "include"])] ||
X <- Siblings])).
%% @spec ensure(Module) -> ok
%% @doc Ensure that all ebin and include paths for dependencies
%% of the application for Module are on the code path.
ensure(Module) ->
code:add_paths(new_siblings(Module)),
code:clash(),
ok.
%% @spec ensure() -> ok
%% @doc Ensure that the ebin and include paths for dependencies of
%% this application are on the code path. Equivalent to
%% ensure(?Module).
ensure() ->
ensure(?MODULE).
%% @spec get_base_dir(Module) -> string()
%% @doc Return the application directory for Module. It assumes Module is in
%% a standard OTP layout application in the ebin or src directory.
get_base_dir(Module) ->
{file, Here} = code:is_loaded(Module),
filename:dirname(filename:dirname(Here)).
%% @spec get_base_dir() -> string()
%% @doc Return the application directory for this application. Equivalent to
%% get_base_dir(?MODULE).
get_base_dir() ->
get_base_dir(?MODULE).
%% @spec local_path([string()], Module) -> string()
%% @doc Return an application-relative directory from Module's application.
local_path(Components, Module) ->
filename:join([get_base_dir(Module) | Components]).
%% @spec local_path(Components) -> string()
%% @doc Return an application-relative directory for this application.
%% Equivalent to local_path(Components, ?MODULE).
local_path(Components) ->
local_path(Components, ?MODULE).

View File

@ -0,0 +1,78 @@
%% @author icarus75 <bart.vandermeerssche@flukso.net>
%% @copyright 2009-2010 flukso.net
%% @doc Flukso webmachine_resource.
-module(flukso_resource).
-export([init/1, allowed_methods/2, malformed_request/2, content_types_provided/2, to_json/2]).
-include_lib("webmachine/include/webmachine.hrl").
init([]) ->
{ok, undefined}.
allowed_methods(ReqData, State) ->
{['GET'], ReqData, State}.
malformed_request(ReqData, State) ->
{RrdSensor, ValidSensor} = rrd_sensor(wrq:path_info(sensor, ReqData)),
{RrdTime, ValidInterval} = rrd_time(wrq:get_qs_value("interval", ReqData)),
{RrdFactor, ValidUnit} = rrd_factor(wrq:get_qs_value("unit", ReqData)),
{case {ValidSensor, ValidInterval, ValidUnit} of
{true, true, true} -> false;
_ -> true
end,
ReqData, {RrdSensor , RrdTime, RrdFactor}}.
content_types_provided(ReqData, State) ->
{[{"application/json", to_json}], ReqData, State}.
to_json(ReqData, State) ->
{RrdSensor , RrdTime, RrdFactor} = State,
case wrq:path_info(interval, ReqData) of
"night" -> Path = "var/data/night/";
_Interval -> Path = "var/data/base/"
end,
case erlrrd:fetch(erlrrd:c([[Path, [RrdSensor|".rrd"]], "AVERAGE", ["-s",RrdTime]])) of
{ok, Response} ->
Filtered = [re:split(X, "[:][ ]", [{return,list}]) || [X] <- Response, string:str(X, ":") == 11],
Datapoints = [[list_to_integer(X), round(list_to_float(Y) * RrdFactor)] || [X, Y] <- Filtered, string:len(Y) /= 3],
Nans = [[list_to_integer(X), list_to_binary(Y)] || [X, Y] <- Filtered, string:len(Y) == 3],
Final = lists:merge(Datapoints, Nans),
{mochijson2:encode(Final), ReqData, State};
{error, Reason} ->
{{halt, 404}, ReqData, State}
end.
rrd_sensor(Sensor) ->
case re:run(Sensor, "[0-9a-f]+", []) of
{match, [{0,32}]} -> {Sensor, true};
_ -> {false, false}
end.
rrd_time(Interval) ->
Intervals = [{"hour", "end-1h"},
{"day", "end-1d"},
{"month", "end-30d"},
{"year", "end-1y"},
{"night", "end-30d"}],
case lists:keyfind(Interval, 1, Intervals) of
false -> {false, false};
{_Interval, RrdTime} -> {RrdTime, true}
end.
rrd_factor(Unit) ->
Units = [{"watt", 3600},
{"kwhperyear", 31536},
{"eurperyear", 5676},
{"audperyear", 5991}],
case lists:keyfind(Unit, 1, Units) of
false -> {false, false};
{_Unit, RrdFactor} -> {RrdFactor, true}
end.

View File

@ -0,0 +1,57 @@
%% @author author <author@example.com>
%% @copyright YYYY author.
%% @doc Supervisor for the flukso application.
-module(flukso_sup).
-author('author <author@example.com>').
-behaviour(supervisor).
%% External exports
-export([start_link/0, upgrade/0]).
%% supervisor callbacks
-export([init/1]).
%% @spec start_link() -> ServerRet
%% @doc API for starting the supervisor.
start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
%% @spec upgrade() -> ok
%% @doc Add processes if necessary.
upgrade() ->
{ok, {_, Specs}} = init([]),
Old = sets:from_list(
[Name || {Name, _, _, _} <- supervisor:which_children(?MODULE)]),
New = sets:from_list([Name || {Name, _, _, _, _, _} <- Specs]),
Kill = sets:subtract(Old, New),
sets:fold(fun (Id, ok) ->
supervisor:terminate_child(?MODULE, Id),
supervisor:delete_child(?MODULE, Id),
ok
end, ok, Kill),
[supervisor:start_child(?MODULE, Spec) || Spec <- Specs],
ok.
%% @spec init([]) -> SupervisorTree
%% @doc supervisor callback.
init([]) ->
Ip = case os:getenv("WEBMACHINE_IP") of false -> "127.0.0.1"; Any -> Any end,
{ok, Dispatch} = file:consult(filename:join(
[filename:dirname(code:which(?MODULE)),
"..", "priv", "dispatch.conf"])),
WebConfig = [
{ip, Ip},
{port, 9999},
{log_dir, "var/log"},
{dispatch, Dispatch}],
Web = {webmachine_mochiweb,
{webmachine_mochiweb, start, [WebConfig]},
permanent, 5000, worker, dynamic},
Processes = [Web],
{ok, {{one_for_one, 10, 10}, Processes}}.

3
web/api/flukso/start-dev.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/sh
cd `dirname $0`
exec erl -smp auto +K true -sname flukso -setcookie mycookie -pa $PWD/ebin $PWD/deps/*/ebin $PWD/deps/*/deps/*/ebin -boot start_sasl -s reloader -s flukso

3
web/api/flukso/start.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/sh
cd `dirname $0`
exec erl -detached -smp auto +K true -sname flukso -setcookie mycookie -pa $PWD/ebin $PWD/deps/*/ebin $PWD/deps/*/deps/*/ebin -boot start_sasl -s reloader -s flukso

1
web/api/flukso/var/data Symbolic link
View File

@ -0,0 +1 @@
../../../public/sites/all/modules/logger/data

Binary file not shown.

View File

@ -0,0 +1 @@
default

View File

@ -0,0 +1,2 @@
b3575cbf3376171f0f040609a7a49cdb9979b480 85
b3575cbf3376171f0f040609a7a49cdb9979b480 default

Binary file not shown.

View File

@ -0,0 +1,2 @@
[paths]
default = http://bitbucket.org/justin/webmachine/

View File

@ -0,0 +1,2 @@
revlogv1
store

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More