From 2e9df29149d100074ac18be53627868d591386d7 Mon Sep 17 00:00:00 2001 From: Craig Everett Date: Mon, 23 Apr 2018 07:58:56 +0900 Subject: [PATCH] bleh --- TODO | 42 +++-- Zomp Protocol Specification.odt | Bin 0 -> 19362 bytes zomp/lib/otpr-zx/0.1.0/src/zx.erl | 1 + zomp/lib/otpr-zx/0.1.0/src/zx_conn.erl | 218 +++++++++++++++++------ zomp/lib/otpr-zx/0.1.0/src/zx_daemon.erl | 25 ++- 5 files changed, 206 insertions(+), 80 deletions(-) create mode 100644 Zomp Protocol Specification.odt diff --git a/TODO b/TODO index fed003f..8041787 100644 --- a/TODO +++ b/TODO @@ -1,24 +1,36 @@ - - zomp nodes must report the realms they provide to upstream nodes to which they connect. - On redirect a list of hosts of the form [{zx:host(), [zx:realm()]}] must be provided to the downstream client. - This is the only way that downstream clients can determine which redirect hosts are useful to it. +- Make the create project command fail if the realm is invalid or the project bame already exists. - - Change zx_daemon request references to counters. - Count everything. - This will be the only way to sort of track stats other than log analysis. - Log analysis sucks. +- Add a module name conflict checker to ZX - - Double-indexing must happen everywhere for anything to be discoverable without traversing the entire state of zx_daemon whenever a client or conn crashes. +- Check whether the "repo name doesn't have to be the same as package, package doesn't have to be the same as main interface module" statement is true. - - zx_daemon request() types have been changes to flat, wide tuples as in the main zx module. - This change is not yet refected in the using code. +- Make the "create user" bundle command check whether a user already exists at that realm. - - Write a logging process. - Pick a log rotation scheme. - Eventually make it so that it can shed log loads in the event they get out of hand. +- Define the user bundle file contents: .zuf +- Make it possible for a site administrator to declare specific versions for programs executed by clients. + Site adminisration via an organizational mirror should not be ricket science. + +- zomp nodes must report the realms they provide to upstream nodes to which they connect. + On redirect a list of hosts of the form [{zx:host(), [zx:realm()]}] must be provided to the downstream client. + This is the only way that downstream clients can determine which redirect hosts are useful to it. + +- Write a logging process. + Pick a log rotation scheme. + Eventually make it so that it can shed log loads in the event they get out of hand. + +- Create zx_daemon primes. + See below + +- Create persistent Windows alias for "zx" using the doskey command and adding it to the localuser's registry. + The installation escript will need to be updated to update the windows registry for HKEY_CURRENT_USER\Software\Microsoft\Command Processor + AutoRun will need to be set for %USERPROFILE%\zomp_alias.cmd + zomp_alias.cmd will need to do something like: + `doskey zx="werl.exe -pa %zx_dir%/ebin -run zx start $*"` + https://stackoverflow.com/questions/20530996/aliases-in-windows-command-prompt + Whatever happens, local users must be able to do `zx $@` and get the expected results. + Somewhat more tricky is how to make the creation of shortcuts less taxing on the lay user... ? - - Create zx_daemon primes. - See below New Feature: ZX Universal lock Cross-instance communication diff --git a/Zomp Protocol Specification.odt b/Zomp Protocol Specification.odt new file mode 100644 index 0000000000000000000000000000000000000000..2e6118067696b487c41162dd059f9bc92990f2f8 GIT binary patch literal 19362 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 vHfnk{aY3!>U_OBb4{{L%D%TO9*cC@9AK=XjY " zx add package PackageName~n" " zx add packager PackageName~n" " zx add maintainer PackageName~n" + " zx add sysop UserID~n" " zx review PackageID~n" " zx approve PackageID~n" " zx reject PackageID~n" diff --git a/zomp/lib/otpr-zx/0.1.0/src/zx_conn.erl b/zomp/lib/otpr-zx/0.1.0/src/zx_conn.erl index ec6644f..119c27e 100644 --- a/zomp/lib/otpr-zx/0.1.0/src/zx_conn.erl +++ b/zomp/lib/otpr-zx/0.1.0/src/zx_conn.erl @@ -1,4 +1,4 @@ -%%% @doc +%% @doc %%% ZX Connector %%% %%% This module represents a connection to a Zomp server. @@ -11,12 +11,59 @@ -copyright("Craig Everett "). -license("GPL-3.0"). +-export([subscribe/2, unsubscribe/2, fetch/3, query/3]). -export([start/1, stop/1]). --export([start_link/1]). +-export([start_link/1, init/2]). --include("zx_logger.erl"). +-include("zx_logger.hrl"). +%%% Types + +-type incoming() :: ping + | {sub, Channel :: term(), Message :: term()} + | term(). + + +%%% Interface + +-spec subscribe(Conn, Package) -> ok + when Conn :: pid(), + Package :: zx:package(). + +subscribe(Conn, Realm) -> + Conn ! {subscribe, Realm}, + ok. + + +-spec unsubscribe(Conn, Package) -> ok + when Conn :: pid(), + Package :: zx:package(). + +unsubscribe(Conn, Package) -> + Conn ! {unsubscribe, Package}, + ok. + + +-spec fetch(Conn, ID, Object) -> ok + when Conn :: pid(), + ID :: zx_daemon:id(), + Object :: zx_daemon:object(). + +fetch(Conn, ID, Object) -> + Conn ! {fetch, ID, Object}, + ok. + + +-spec query(Conn, ID, Action) -> ok + when Conn :: pid(), + ID :: zx_daemon:id(), + Action :: zx_daemon:action(). + +query(Conn, ID, Action) -> + Conn ! {query, ID, Action}, + ok. + %%% Startup @@ -42,25 +89,7 @@ stop(Conn) -> ok. --spec subscribe(Conn, Package) -> ok - when Conn :: pid(), - Package :: zx:package(). - -subscribe(Conn, Realm) -> - Conn ! {subscribe, Realm}, - ok. - - --spec unsubscribe(Conn, Package) -> ok - when Conn :: pid(), - Package :: zx:package(). - -unsubscribe(Conn, Package) -> - Conn ! {unsubscribe, Package}, - ok. - - --spec start_link(Target) -> +-spec start_link(Target) -> Result when Target :: zx:host(), Result :: {ok, pid()} | {error, Reason}, @@ -94,13 +123,13 @@ init(Parent, Target) -> Target :: zx:host(). connect(Parent, Debug, {Host, Port}) -> - Options = [{packet, 4}, {mode, binary}, {active, true}], + Options = [{packet, 4}, {mode, binary}, {nodelay, true}, {active, true}], case gen_tcp:connect(Host, Port, Options, 5000) of {ok, Socket} -> confirm_service(Parent, Debug, Socket); {error, Error} -> - ok = log(warning, "Connection problem with ~tp: ~tp", [Node, Error]), - ok = zx_daemon:report(disconnected) + ok = log(warning, "Connection problem with ~tp: ~tp", [Host, Error]), + ok = zx_daemon:report(failed), terminate() end. @@ -170,12 +199,23 @@ query_realms(Parent, Debug, Socket) -> loop(Parent, Debug, Socket) -> receive {tcp, Socket, Bin} -> - ok = handle(Bin, Socket), + ok = handle_message(Socket, Bin), ok = inet:setopts(Socket, [{active, once}]), loop(Parent, Debug, Socket); {subscribe, Package} -> + ok = zx_net:send(Socket, {subscribe, Package}), + loop(Parent, Debug, Socket); {unsubscribe, Package} -> - + ok = zx_net:send(Socket, {unsubscribe, Package}), + loop(Parent, Debug, Socket); + {fetch, ID, Object} -> + {ok, Outcome} = handle_fetch(Socket, Object), + ok = zx_daemon:result(ID, Outcome), + loop(Parent, Debug, Socket); + {query, ID, Action} -> + {ok, Outcome} = handle_query(Socket, Action), + ok = zx_daemon:result(ID, Outcome), + loop(Parent, Debug, Socket); stop -> ok = zx_net:disconnect(Socket), terminate(); @@ -185,41 +225,106 @@ loop(Parent, Debug, Socket) -> end. --spec handle(Bin, Socket) -> ok | no_return() - when Bin :: binary(), - Socket :: gen_tcp:socket(). + +%%% Idle Incoming Upstream Messages + +-spec handle_message(Socket, Bin) -> ok | no_return() + when Socket :: gen_tcp:socket(), + Bin :: binary(). %% @private %% Single point to convert a binary message to a safe internal message. Actual handling %% of the converted message occurs in dispatch/2. -handle(Bin, Socket) -> +handle_message(Socket, Bin) -> Message = binary_to_term(Bin, [safe]), ok = log(info, "Received network message: ~tp", [Message]), - dispatch(Message, Socket). + case binary_to_term(Bin, [safe]) of + ping -> + zx_net:send(Socket, pong); + {sub, Channel, Message} -> + log("Sub: ~tp - ~tp", [Channel, Message]); + {update, Message} -> + log("Update: ~tp", [Message]); + {redirect, Nodes} -> + log("Redirected to ~tp", [Nodes]); + Invalid -> + {ok, {Addr, Port}} = zomp:peername(Socket), + Host = inet:ntoa(Addr), + ok = log(warning, "Invalid message from ~tp:~p: ", [Invalid]), + ok = zx_net:disconnect(Socket), + terminate() + end. --spec dispatch(Message, Socket) -> ok | no_return() - when Message :: incoming(), - Socket :: gen_tcp:socket(). -%% @private -%% Dispatch a procedure based on the received message. -%% Tranfers and other procedures that involve a sequence of messages occur in discrete -%% states defined in other functions -- this only dispatches based on a valid initial -%% message received in the default waiting-loop state. -dispatch(ping, Socket) -> - zx_net:send(Socket, pong); -dispatch(Invalid, Socket) -> - {ok, {Addr, Port}} = zomp:peername(Socket), - Host = inet:ntoa(Addr), - ok = log(warning, "Invalid message from ~tp:~p: ", [Invalid]), - ok = zx_net:disconnect(Socket), - terminate(). +%%% Incoming Request Actions + +-spec handle_request(Socket, Action) -> Result + when Socket :: gen_tcp:socket(), + Action :: term(), + Result :: {ok, Outcome :: term()}. + +handle_request(Socket, Action) -> + ok = zx_net:send(Socket, Action), + case element(1, Action) of + list -> + do_list(Action, Socket); + latest -> + do_latest(Action, Socket); + fetch -> + do_fetch(Action, Socket); + key -> + do_key(Action, Socket); + pending -> + do_pending(Action, Socket); + packagers -> + do_packagers(Action, Socket); + maintainers -> + do_maintainers(Action, Socket); + sysops -> + do_sysops(Action, Socket) + end, + handle_response(Socket, Response). + + + +handle_response(Socket, Command) -> + receive + {tcp, Socket, Bin} -> + Outcome = binary_to_term(Bin, [safe]), + interpret_response(Socket, Outcome, Command); + {tcp_closed, Socket} -> + handle_unexpected_close() + after 5000 -> + handle_timeout(Socket) + end. + + +interpret_response(Socket, ping, Command) -> + ok = zx_net:send(Socket, pong), + handle_response(Socket, Command); +interpret_response(Socket, {sub, Channel, Message}, Command) -> + ok = zx_daemon:notify(Channel, Message), + handle_response(Socket, Command); +interpret_response(Socket, {update, Message}, Command) -> +interpret_response(Socket, Response, list) -> +interpret_response(Socket, Response, latest) -> +interpret_response(Socket, Response, fetch) -> +interpret_response(Socket, Response, key) -> +interpret_response(Socket, Response, pending) -> +interpret_response(Socket, Response, packagers) -> +interpret_response(Socket, Response, maintainers) -> +interpret_response(Socket, Response, sysops) -> + + + + case element(1, Action) of + end, -spec fetch(Socket, PackageID) -> Result when Socket :: gen_tcp:socket(), - PackageID :: package_id(), + PackageID :: zx:package_id(), Result :: ok. %% @private %% Download a package to the local cache. @@ -227,13 +332,14 @@ dispatch(Invalid, Socket) -> fetch(Socket, PackageID) -> {ok, LatestID} = request_zrp(Socket, PackageID), ok = receive_zrp(Socket, LatestID), - log(info, "Fetched ~ts", [package_string(LatestID)]). + Latest = zx_lib:package_string(LatestID), + log(info, "Fetched ~ts", [Latest]). -spec request_zrp(Socket, PackageID) -> Result when Socket :: gen_tcp:socket(), - PackageID :: package_id(), - Result :: {ok, Latest :: package_id()} + PackageID :: zx:package_id(), + Result :: {ok, Latest :: zx:package_id()} | {error, Reason :: timeout | term()}. request_zrp(Socket, PackageID) -> @@ -244,7 +350,7 @@ request_zrp(Socket, PackageID) -> {sending, LatestID} -> {ok, LatestID}; Error = {error, Reason} -> - PackageString = package_string(PackageID), + PackageString = zx_lib:package_string(PackageID), Message = "Error receiving package ~ts: ~tp", ok = log(info, Message, [PackageString, Reason]), Error @@ -258,7 +364,7 @@ request_zrp(Socket, PackageID) -> -spec receive_zrp(Socket, PackageID) -> Result when Socket :: gen_tcp:socket(), - PackageID :: package_id(), + PackageID :: zx:package_id(), Result :: ok | {error, timeout}. receive_zrp(Socket, PackageID) -> @@ -286,11 +392,11 @@ handle_unexpected_close() -> terminate(). --spec handle_timeout(gen_tcp:socket()) -> no_return() +-spec handle_timeout(gen_tcp:socket()) -> no_return(). handle_timeout(Socket) -> ok = zx_daemon:report(timeout), - ok = disconnect(Socket), + ok = zx_net:disconnect(Socket), terminate(). diff --git a/zomp/lib/otpr-zx/0.1.0/src/zx_daemon.erl b/zomp/lib/otpr-zx/0.1.0/src/zx_daemon.erl index b078f0b..cc78934 100644 --- a/zomp/lib/otpr-zx/0.1.0/src/zx_daemon.erl +++ b/zomp/lib/otpr-zx/0.1.0/src/zx_daemon.erl @@ -218,7 +218,9 @@ %% Conn Communication -type conn_report() :: {connected, Realms :: [{zx:realm(), zx:serial()}]} | {redirect, Hosts :: [zx:host()]} - | disconnected. + | failed + | disconnected + | timeout. %% Subscriber / Requestor Communication % Incoming Request messages @@ -229,8 +231,9 @@ | {list, zx:realm(), zx:name(), zx:version()} | {latest, zx:realm(), zx:name(), zx:version()} | {fetch, zx:realm(), zx:name(), zx:version()} - | {key, zx:realm(), zx:key_name()} + | {fetchkey, zx:realm(), zx:key_name()} | {pending, zx:realm(), zx:name()} + | {resigns, zx:realm()} | {packagers, zx:realm(), zx:name()} | {maintainers, zx:realm(), zx:name()} | {sysops, zx:realm()}. @@ -447,14 +450,14 @@ latest({Realm, Name, Version}) -> %% Response messages are of the type `result()' where the third element is of the %% type `fetch_result()'. -fetch({Realm, Name, Version}) -> +fetch_zsp(PackageID = {Realm, Name, Version}) -> true = zx_lib:valid_lower0_9(Realm), true = zx_lib:valid_lower0_9(Name), true = zx_lib:valid_version(Version), - request({fetch, Realm, Name, Version}). + request({fetch, zsp, PackageID}). --spec key(KeyID) -> {ok, RequestID} +-spec fetch_key(KeyID) -> {ok, RequestID} when KeyID :: zx:key_id(), RequestID :: id(). %% @doc @@ -464,10 +467,10 @@ fetch({Realm, Name, Version}) -> %% Response messages are of the type `result()' where the third element is of the %% type `key_result()'. -key({Realm, KeyName}) -> +fetch_key(KeyID = {Realm, KeyName}) -> true = zx_lib:valid_lower0_9(Realm), true = zx_lib:valid_lower0_9(KeyName), - request({key, Realm, KeyName}). + request({fetch, key, KeyID}). -spec pending(Package) -> {ok, RequestID} @@ -561,7 +564,7 @@ report(Message) -> gen_server:cast(?MODULE, {report, self(), Message}). --spec result(reference(), result()) -> ok. +-spec result(id(), result()) -> ok. %% @private %% Return a tagged result back to the daemon to be forwarded to the original requestor. @@ -839,6 +842,10 @@ do_report(Conn, failed, State = #s{mx = MX}) -> NewMX = mx_del_monitor(Conn, attempt, MX), failed(Conn, State#s{mx = NewMX}); do_report(Conn, disconnected, State = #s{mx = MX}) -> + NewMX = mx_del_monitor(Conn, conn, MX), + disconnected(Conn, State#s{mx = NewMX}); +do_report(Conn, timeout, State = #s{mx = MX}) -> + ok = log(warning, "Connection ~tp timed out.", [Conn]), NewMX = mx_del_monitor(Conn, conn, MX), disconnected(Conn, State#s{mx = NewMX}). @@ -1109,7 +1116,7 @@ dispatch_request(Action, ID, CX) -> Realm = element(2, Action), case cx_pre_send(Realm, ID, CX) of {ok, Conn, NewCX} -> - ok = zx_conn:make_request(Conn, ID, Action), + ok = zx_conn:request(Conn, ID, Action), {dispatched, NewCX}; unassigned -> wait;