Merge pull request #2 from zxq9/dev
Where is fancy bred, in the heart or in the head?
This commit is contained in:
commit
9c79ab2889
@ -19,7 +19,7 @@
|
|||||||
-license("GPL-3.0").
|
-license("GPL-3.0").
|
||||||
|
|
||||||
|
|
||||||
-export([run/0, run/1]).
|
-export([do/0, do/1]).
|
||||||
-export([subscribe/1, unsubscribe/0]).
|
-export([subscribe/1, unsubscribe/0]).
|
||||||
-export([start/2, stop/1, stop/0]).
|
-export([start/2, stop/1, stop/0]).
|
||||||
-export([usage_exit/1]).
|
-export([usage_exit/1]).
|
||||||
@ -69,105 +69,131 @@
|
|||||||
|
|
||||||
%%% Command Dispatch
|
%%% Command Dispatch
|
||||||
|
|
||||||
-spec run() -> no_return().
|
-spec do() -> no_return().
|
||||||
|
|
||||||
run() ->
|
do() ->
|
||||||
run([]).
|
do([]).
|
||||||
|
|
||||||
|
|
||||||
-spec run(Args) -> no_return()
|
-spec do(Args) -> no_return()
|
||||||
when Args :: [string()].
|
when Args :: [string()].
|
||||||
%% Dispatch work functions based on the nature of the input arguments.
|
%% Dispatch work functions based on the nature of the input arguments.
|
||||||
|
|
||||||
run(["help"]) ->
|
do(["help"]) ->
|
||||||
usage_exit(0);
|
usage_exit(0);
|
||||||
run(["run", PackageString | Args]) ->
|
do(["run", PackageString | Args]) ->
|
||||||
ok = start(),
|
ok = start(),
|
||||||
run(PackageString, Args);
|
run(PackageString, Args);
|
||||||
run(["runlocal" | ArgV]) ->
|
do(["runlocal" | ArgV]) ->
|
||||||
ok = start(),
|
ok = start(),
|
||||||
run_local(ArgV);
|
run_local(ArgV);
|
||||||
run(["init", "app", PackageString]) ->
|
do(["init", "app", PackageString]) ->
|
||||||
ok = compatibility_check([unix]),
|
ok = compatibility_check([unix]),
|
||||||
zx_local:initialize(app, PackageString);
|
ok = zx_local:initialize(app, PackageString),
|
||||||
run(["init", "lib", PackageString]) ->
|
halt(0);
|
||||||
|
do(["init", "lib", PackageString]) ->
|
||||||
ok = compatibility_check([unix]),
|
ok = compatibility_check([unix]),
|
||||||
zx_local:initialize(lib, PackageString);
|
ok = zx_local:initialize(lib, PackageString),
|
||||||
run(["install", PackageFile]) ->
|
halt(0);
|
||||||
zx_local:assimilate(PackageFile);
|
do(["install", PackageFile]) ->
|
||||||
run(["set", "dep", PackageString]) ->
|
ok = zx_local:assimilate(PackageFile),
|
||||||
zx_local:set_dep(PackageString);
|
halt(0);
|
||||||
run(["set", "version", VersionString]) ->
|
do(["set", "dep", PackageString]) ->
|
||||||
|
ok = zx_local:set_dep(PackageString),
|
||||||
|
halt(0);
|
||||||
|
do(["set", "version", VersionString]) ->
|
||||||
ok = compatibility_check([unix]),
|
ok = compatibility_check([unix]),
|
||||||
zx_local:set_version(VersionString);
|
ok = zx_local:set_version(VersionString),
|
||||||
run(["verup", Level]) ->
|
halt(0);
|
||||||
|
do(["verup", Level]) ->
|
||||||
ok = compatibility_check([unix]),
|
ok = compatibility_check([unix]),
|
||||||
zx_local:verup(Level);
|
ok = zx_local:verup(Level),
|
||||||
run(["list", "realms"]) ->
|
halt(0);
|
||||||
zx_loca:list_realms();
|
do(["list", "realms"]) ->
|
||||||
run(["list", "packages", Realm]) ->
|
ok = zx_local:list_realms(),
|
||||||
|
halt(0);
|
||||||
|
do(["list", "packages", Realm]) ->
|
||||||
ok = start(),
|
ok = start(),
|
||||||
zx_local:list_packages(Realm);
|
ok = zx_local:list_packages(Realm),
|
||||||
run(["list", "versions", PackageName]) ->
|
halt(0);
|
||||||
|
do(["list", "versions", PackageName]) ->
|
||||||
ok = start(),
|
ok = start(),
|
||||||
zx_local:list_versions(PackageName);
|
ok = zx_local:list_versions(PackageName),
|
||||||
run(["add", "realm", RealmFile]) ->
|
halt(0);
|
||||||
zx_local:add_realm(RealmFile);
|
do(["add", "realm", RealmFile]) ->
|
||||||
run(["drop", "dep", PackageString]) ->
|
ok = zx_local:add_realm(RealmFile),
|
||||||
|
halt(0);
|
||||||
|
do(["drop", "dep", PackageString]) ->
|
||||||
PackageID = zx_lib:package_id(PackageString),
|
PackageID = zx_lib:package_id(PackageString),
|
||||||
zx_local:drop_dep(PackageID);
|
ok = zx_local:drop_dep(PackageID),
|
||||||
run(["drop", "key", Realm, KeyName]) ->
|
halt(0);
|
||||||
zx_key:drop({Realm, KeyName});
|
do(["package"]) ->
|
||||||
run(["drop", "realm", Realm]) ->
|
|
||||||
zx_local:drop_realm(Realm);
|
|
||||||
run(["package"]) ->
|
|
||||||
{ok, TargetDir} = file:get_cwd(),
|
{ok, TargetDir} = file:get_cwd(),
|
||||||
zx_local:package(TargetDir);
|
zx_local:package(TargetDir);
|
||||||
run(["package", TargetDir]) ->
|
do(["package", TargetDir]) ->
|
||||||
case filelib:is_dir(TargetDir) of
|
case filelib:is_dir(TargetDir) of
|
||||||
true ->
|
true ->
|
||||||
zx_local:package(TargetDir);
|
ok = zx_local:package(TargetDir),
|
||||||
|
halt(0);
|
||||||
false ->
|
false ->
|
||||||
ok = log(error, "Target directory ~tp does not exist!", [TargetDir]),
|
ok = log(error, "Target directory ~tp does not exist!", [TargetDir]),
|
||||||
halt(22)
|
halt(22)
|
||||||
end;
|
end;
|
||||||
run(["dialyze"]) ->
|
do(["dialyze"]) ->
|
||||||
zx_local:dialyze();
|
ok = zx_local:dialyze(),
|
||||||
run(["create", "user", Realm, Name]) ->
|
halt(0);
|
||||||
zx_local:create_user(Realm, Name);
|
do(["create", "user", Realm, Name]) ->
|
||||||
run(["create", "keypair"]) ->
|
ok = zx_local:create_user(Realm, Name),
|
||||||
zx_key:grow_a_pair();
|
halt(0);
|
||||||
run(["create", "plt"]) ->
|
do(["create", "keypair"]) ->
|
||||||
zx_local:create_plt();
|
ok = zx_local:grow_a_pair(),
|
||||||
run(["create", "realm"]) ->
|
halt(0);
|
||||||
zx_local:create_realm();
|
do(["drop", "key", Realm, KeyName]) ->
|
||||||
run(["create", "realmfile", Realm]) ->
|
ok = zx_local:drop_key({Realm, KeyName}),
|
||||||
zx_local:create_realmfile(Realm);
|
halt(0);
|
||||||
run(["list", "pending", PackageName]) ->
|
do(["create", "plt"]) ->
|
||||||
|
ok = zx_local:create_plt(),
|
||||||
|
halt(0);
|
||||||
|
do(["create", "realm"]) ->
|
||||||
|
ok = zx_local:create_realm(),
|
||||||
|
halt(0);
|
||||||
|
do(["create", "realmfile", Realm]) ->
|
||||||
|
ok = zx_local:create_realmfile(Realm, "."),
|
||||||
|
halt(0);
|
||||||
|
do(["takeover", Realm]) ->
|
||||||
|
ok = zx_local:takeover(Realm),
|
||||||
|
halt(0);
|
||||||
|
do(["abdicate", Realm]) ->
|
||||||
|
ok = zx_local:abdicate(Realm),
|
||||||
|
halt(0);
|
||||||
|
do(["drop", "realm", Realm]) ->
|
||||||
|
ok = zx_local:drop_realm(Realm),
|
||||||
|
halt(0);
|
||||||
|
do(["list", "pending", PackageName]) ->
|
||||||
zx_auth:list_pending(PackageName);
|
zx_auth:list_pending(PackageName);
|
||||||
run(["list", "resigns", Realm]) ->
|
do(["list", "resigns", Realm]) ->
|
||||||
zx_auth:list_resigns(Realm);
|
zx_auth:list_resigns(Realm);
|
||||||
run(["submit", PackageFile]) ->
|
do(["submit", PackageFile]) ->
|
||||||
zx_auth:submit(PackageFile);
|
zx_auth:submit(PackageFile);
|
||||||
run(["review", PackageString]) ->
|
do(["review", PackageString]) ->
|
||||||
zx_auth:review(PackageString);
|
zx_auth:review(PackageString);
|
||||||
run(["approve", PackageString]) ->
|
do(["approve", PackageString]) ->
|
||||||
PackageID = zx_lib:package_id(PackageString),
|
PackageID = zx_lib:package_id(PackageString),
|
||||||
zx_auth:approve(PackageID);
|
zx_auth:approve(PackageID);
|
||||||
run(["reject", PackageString]) ->
|
do(["reject", PackageString]) ->
|
||||||
PackageID = zx_lib:package_id(PackageString),
|
PackageID = zx_lib:package_id(PackageString),
|
||||||
zx_auth:reject(PackageID);
|
zx_auth:reject(PackageID);
|
||||||
run(["accept", PackageString]) ->
|
do(["accept", PackageString]) ->
|
||||||
zx_auth:accept(PackageString);
|
zx_auth:accept(PackageString);
|
||||||
run(["add", "packager", Package, UserName]) ->
|
do(["add", "packager", Package, UserName]) ->
|
||||||
zx_auth:add_packager(Package, UserName);
|
zx_auth:add_packager(Package, UserName);
|
||||||
run(["add", "maintainer", Package, UserName]) ->
|
do(["add", "maintainer", Package, UserName]) ->
|
||||||
zx_auth:add_maintainer(Package, UserName);
|
zx_auth:add_maintainer(Package, UserName);
|
||||||
run(["add", "sysop", Package, UserName]) ->
|
do(["add", "sysop", Package, UserName]) ->
|
||||||
zx_auth:add_sysop(Package, UserName);
|
zx_auth:add_sysop(Package, UserName);
|
||||||
run(["add", "package", PackageName]) ->
|
do(["add", "package", PackageName]) ->
|
||||||
zx_auth:add_package(PackageName);
|
zx_auth:add_package(PackageName);
|
||||||
run(_) ->
|
do(_) ->
|
||||||
usage_exit(22).
|
usage_exit(22).
|
||||||
|
|
||||||
|
|
||||||
@ -300,7 +326,6 @@ unsubscribe() ->
|
|||||||
|
|
||||||
run(Identifier, RunArgs) ->
|
run(Identifier, RunArgs) ->
|
||||||
ok = file:set_cwd(zx_lib:zomp_dir()),
|
ok = file:set_cwd(zx_lib:zomp_dir()),
|
||||||
ok = start(),
|
|
||||||
FuzzyID =
|
FuzzyID =
|
||||||
case zx_lib:package_id(Identifier) of
|
case zx_lib:package_id(Identifier) of
|
||||||
{ok, Fuzzy} ->
|
{ok, Fuzzy} ->
|
||||||
@ -312,12 +337,9 @@ run(Identifier, RunArgs) ->
|
|||||||
ok = build(PackageID),
|
ok = build(PackageID),
|
||||||
Dir = zx_lib:package_dir(PackageID),
|
Dir = zx_lib:package_dir(PackageID),
|
||||||
{ok, Meta} = zx_lib:read_project_meta(Dir),
|
{ok, Meta} = zx_lib:read_project_meta(Dir),
|
||||||
execute(PackageID, Meta, Dir, RunArgs).
|
prepare(PackageID, Meta, Dir, RunArgs).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
%%% Execution of local project
|
|
||||||
|
|
||||||
-spec run_local(RunArgs) -> no_return()
|
-spec run_local(RunArgs) -> no_return()
|
||||||
when RunArgs :: [term()].
|
when RunArgs :: [term()].
|
||||||
%% @private
|
%% @private
|
||||||
@ -335,11 +357,10 @@ run_local(RunArgs) ->
|
|||||||
ok = zx_lib:build(),
|
ok = zx_lib:build(),
|
||||||
{ok, Dir} = file:get_cwd(),
|
{ok, Dir} = file:get_cwd(),
|
||||||
ok = file:set_cwd(zx_lib:zomp_dir()),
|
ok = file:set_cwd(zx_lib:zomp_dir()),
|
||||||
ok = start(),
|
prepare(PackageID, Meta, Dir, RunArgs).
|
||||||
execute(PackageID, Meta, Dir, RunArgs).
|
|
||||||
|
|
||||||
|
|
||||||
-spec execute(PackageID, Meta, Dir, RunArgs) -> no_return()
|
-spec prepare(PackageID, Meta, Dir, RunArgs) -> no_return()
|
||||||
when PackageID :: package_id(),
|
when PackageID :: package_id(),
|
||||||
Meta :: package_meta(),
|
Meta :: package_meta(),
|
||||||
Dir :: file:filename(),
|
Dir :: file:filename(),
|
||||||
@ -347,21 +368,43 @@ run_local(RunArgs) ->
|
|||||||
%% @private
|
%% @private
|
||||||
%% Execution prep common to all packages.
|
%% Execution prep common to all packages.
|
||||||
|
|
||||||
execute(PackageID, Meta, Dir, RunArgs) ->
|
prepare(PackageID, Meta, Dir, RunArgs) ->
|
||||||
PackageString = zx_lib:package_string(PackageID),
|
{ok, PackageString} = zx_lib:package_string(PackageID),
|
||||||
ok = log(info, "Preparing ~ts...", [PackageString]),
|
ok = log(info, "Preparing ~ts...", [PackageString]),
|
||||||
Type = maps:get(type, Meta),
|
Type = maps:get(type, Meta),
|
||||||
Deps = maps:get(deps, Meta),
|
Deps = maps:get(deps, Meta),
|
||||||
case zx_daemon:fetch(Deps) of
|
NotInstalled = fun(P) -> not filelib:is_dir(zx_lib:ppath(lib, P)) end,
|
||||||
{{ok, _}, {error, []}} ->
|
Needed = lists:filter(NotInstalled, Deps),
|
||||||
ok = lists:foreach(fun install/1, Deps),
|
Pending = lists:map(fun zx_daemon:fetch/1, Needed),
|
||||||
ok = lists:foreach(fun build/1, Deps),
|
case await_fetches(Pending) of
|
||||||
execute(Type, PackageID, Dir, Meta, RunArgs);
|
ok ->
|
||||||
{{ok, _}, {error, Errors}} ->
|
ok = lists:foreach(fun install/1, Needed),
|
||||||
|
ok = lists:foreach(fun build/1, Needed),
|
||||||
|
execute(Type, PackageID, Meta, Dir, RunArgs);
|
||||||
|
{error, Errors} ->
|
||||||
error_exit("Failed package fetches: ~tp", [Errors], ?LINE)
|
error_exit("Failed package fetches: ~tp", [Errors], ?LINE)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
await_fetches([]) -> ok;
|
||||||
|
await_fetches(Pending) -> await_fetches(Pending, []).
|
||||||
|
|
||||||
|
|
||||||
|
await_fetches([], []) ->
|
||||||
|
ok;
|
||||||
|
await_fetches([], Errors) ->
|
||||||
|
{error, Errors};
|
||||||
|
await_fetches(Pending, Errors) ->
|
||||||
|
{NewPending, NewErrors} =
|
||||||
|
receive
|
||||||
|
{z_reply, ID, ok} ->
|
||||||
|
{lists:delete(ID, Pending), Errors};
|
||||||
|
{z_reply, ID, {error, Package, Reason}} ->
|
||||||
|
{lists:delete(ID, Pending), [{Package, Reason} | Errors]}
|
||||||
|
end,
|
||||||
|
await_fetches(NewPending, NewErrors).
|
||||||
|
|
||||||
|
|
||||||
-spec execute(Type, PackageID, Meta, Dir, RunArgs) -> no_return()
|
-spec execute(Type, PackageID, Meta, Dir, RunArgs) -> no_return()
|
||||||
when Type :: app | lib,
|
when Type :: app | lib,
|
||||||
PackageID :: package_id(),
|
PackageID :: package_id(),
|
||||||
@ -373,12 +416,13 @@ execute(PackageID, Meta, Dir, RunArgs) ->
|
|||||||
%% the exec_wait/1 loop to wait for any queries from the application.
|
%% the exec_wait/1 loop to wait for any queries from the application.
|
||||||
|
|
||||||
execute(app, PackageID, Meta, Dir, RunArgs) ->
|
execute(app, PackageID, Meta, Dir, RunArgs) ->
|
||||||
PackageString = zx_lib:package_string(PackageID),
|
{ok, PackageString} = zx_lib:package_string(PackageID),
|
||||||
ok = log(info, "Starting ~ts.", [PackageString]),
|
ok = log(info, "Starting ~ts.", [PackageString]),
|
||||||
Name = element(2, PackageID),
|
Name = element(2, PackageID),
|
||||||
AppMod = list_to_atom(Name),
|
AppTag = list_to_atom(Name),
|
||||||
ok = zx_daemon:pass_meta(Meta, Dir),
|
{AppMod, _} = maps:get(appmod, Meta),
|
||||||
ok = ensure_all_started(AppMod),
|
ok = zx_daemon:pass_meta(Meta, Dir, RunArgs),
|
||||||
|
ok = ensure_all_started(AppTag),
|
||||||
ok = pass_argv(AppMod, RunArgs),
|
ok = pass_argv(AppMod, RunArgs),
|
||||||
log(info, "Launcher complete.");
|
log(info, "Launcher complete.");
|
||||||
execute(lib, PackageID, _, _, _) ->
|
execute(lib, PackageID, _, _, _) ->
|
||||||
|
|||||||
@ -127,14 +127,14 @@ timeout(#d{timeout = Timeout}) ->
|
|||||||
Timeout.
|
Timeout.
|
||||||
|
|
||||||
|
|
||||||
-spec timeout(Data, Value) -> NewData
|
-spec timeout(Value, Data) -> NewData
|
||||||
when Data :: data(),
|
when Value :: pos_integer(),
|
||||||
Value :: pos_integer(),
|
Data :: data(),
|
||||||
NewData :: data().
|
NewData :: data().
|
||||||
%% @doc
|
%% @doc
|
||||||
%% Set the timeout attribute to a new value.
|
%% Set the timeout attribute to a new value.
|
||||||
|
|
||||||
timeout(Data, Value)
|
timeout(Value, Data)
|
||||||
when is_integer(Value) and Value > 0 ->
|
when is_integer(Value) and Value > 0 ->
|
||||||
Data#d{timeout = Value}.
|
Data#d{timeout = Value}.
|
||||||
|
|
||||||
@ -147,14 +147,14 @@ retries(#d{retries = {_, Retries}}) ->
|
|||||||
Retries.
|
Retries.
|
||||||
|
|
||||||
|
|
||||||
-spec retries(Data, Value) -> NewData
|
-spec retries(Value, Data) -> NewData
|
||||||
when Data :: data(),
|
when Value :: non_neg_integer(),
|
||||||
Value :: non_neg_integer(),
|
Data :: data(),
|
||||||
NewData :: data().
|
NewData :: data().
|
||||||
%% @doc
|
%% @doc
|
||||||
%% Set the retries attribute to a new value.
|
%% Set the retries attribute to a new value.
|
||||||
|
|
||||||
retries(Data = #d{retries = {Remaining, _}}, Value)
|
retries(Value, Data = #d{retries = {Remaining, _}})
|
||||||
when is_integer(Value) and Value >= 0 ->
|
when is_integer(Value) and Value >= 0 ->
|
||||||
Data#d{retries = {Remaining, Value}}.
|
Data#d{retries = {Remaining, Value}}.
|
||||||
|
|
||||||
@ -192,14 +192,14 @@ maxconn(#d{maxconn = MaxConn}) ->
|
|||||||
MaxConn.
|
MaxConn.
|
||||||
|
|
||||||
|
|
||||||
-spec maxconn(Data, Value) -> NewData
|
-spec maxconn(Value, Data) -> NewData
|
||||||
when Data :: data(),
|
when Value :: pos_integer(),
|
||||||
Value :: pos_integer(),
|
Data :: data(),
|
||||||
NewData :: data().
|
NewData :: data().
|
||||||
%% @doc
|
%% @doc
|
||||||
%% Set the value of maxconn.
|
%% Set the value of maxconn.
|
||||||
|
|
||||||
maxconn(Data, Value)
|
maxconn(Value, Data)
|
||||||
when is_integer(Value) and Value > 0 ->
|
when is_integer(Value) and Value > 0 ->
|
||||||
Data#d{maxconn = Value}.
|
Data#d{maxconn = Value}.
|
||||||
|
|
||||||
@ -212,24 +212,24 @@ managed(#d{managed = Managed}) ->
|
|||||||
sets:to_list(Managed).
|
sets:to_list(Managed).
|
||||||
|
|
||||||
|
|
||||||
-spec managed(Data, List) -> NewData
|
-spec managed(List, Data) -> NewData
|
||||||
when Data :: data(),
|
when List :: [zx:realm()],
|
||||||
List :: [zx:realm()],
|
Data :: data(),
|
||||||
NewData :: data().
|
NewData :: data().
|
||||||
%% @doc
|
%% @doc
|
||||||
%% Reset the set of managed realms entirely.
|
%% Reset the set of managed realms entirely.
|
||||||
%% The realms must be configured on the current realm at a minimum.
|
%% The realms must be configured on the current realm at a minimum.
|
||||||
|
|
||||||
managed(Data, List) ->
|
managed(List, Data) ->
|
||||||
Desired = sets:from_list(List),
|
Desired = sets:from_list(List),
|
||||||
Configured = sets:from_list(zx_lib:list_realms()),
|
Configured = sets:from_list(zx_lib:list_realms()),
|
||||||
NewManaged = sets:intersection(Desired, Configured),
|
NewManaged = sets:intersection(Desired, Configured),
|
||||||
Data#d{managed = NewManaged}.
|
Data#d{managed = NewManaged}.
|
||||||
|
|
||||||
|
|
||||||
-spec add_managed(Data, Realm) -> Result
|
-spec add_managed(Realm, Data) -> Result
|
||||||
when Data :: data(),
|
when Realm :: zx:realm(),
|
||||||
Realm :: zx:realm(),
|
Data :: data(),
|
||||||
Result :: {ok, NewData}
|
Result :: {ok, NewData}
|
||||||
| {error, unconfigured},
|
| {error, unconfigured},
|
||||||
NewData :: data().
|
NewData :: data().
|
||||||
@ -238,8 +238,8 @@ managed(Data, List) ->
|
|||||||
%% the current node. This node will then behave as the prime node for the realm (whether
|
%% the current node. This node will then behave as the prime node for the realm (whether
|
||||||
%% it is or not).
|
%% it is or not).
|
||||||
|
|
||||||
add_managed(Data = #d{managed = Managed}, Realm) ->
|
add_managed(Realm, Data = #d{managed = Managed}) ->
|
||||||
case lists:member(Realm, zx_lib:list_realms()) of
|
case zx_lib:realm_exists(Realm) of
|
||||||
true ->
|
true ->
|
||||||
NewData = Data#d{managed = sets:add_element(Realm, Managed)},
|
NewData = Data#d{managed = sets:add_element(Realm, Managed)},
|
||||||
ok = log(info, "Now managing realm: ~tp", [Realm]),
|
ok = log(info, "Now managing realm: ~tp", [Realm]),
|
||||||
@ -250,16 +250,16 @@ add_managed(Data = #d{managed = Managed}, Realm) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
-spec rem_managed(Data, Realm) -> Result
|
-spec rem_managed(Realm, Data) -> Result
|
||||||
when Data :: data(),
|
when Realm :: zx:realm(),
|
||||||
Realm :: zx:realm(),
|
Data :: data(),
|
||||||
Result :: {ok, NewData}
|
Result :: {ok, NewData}
|
||||||
| {error, unmanaged},
|
| {error, unmanaged},
|
||||||
NewData :: data().
|
NewData :: data().
|
||||||
%% @doc
|
%% @doc
|
||||||
%% Stop managing a realm.
|
%% Stop managing a realm.
|
||||||
|
|
||||||
rem_managed(Data = #d{managed = Managed}, Realm) ->
|
rem_managed(Realm, Data = #d{managed = Managed}) ->
|
||||||
case sets:is_element(Realm, Managed) of
|
case sets:is_element(Realm, Managed) of
|
||||||
true ->
|
true ->
|
||||||
NewData = Data#d{managed = sets:del_element(Realm, Managed)},
|
NewData = Data#d{managed = sets:del_element(Realm, Managed)},
|
||||||
@ -279,20 +279,20 @@ mirrors(#d{mirrors = Mirrors}) ->
|
|||||||
Mirrors.
|
Mirrors.
|
||||||
|
|
||||||
|
|
||||||
-spec mirrors(Data, Hosts) -> NewData
|
-spec mirrors(Hosts, Data) -> NewData
|
||||||
when Data :: data(),
|
when Hosts :: [zx:host()],
|
||||||
Hosts :: [zx:host()],
|
Data :: data(),
|
||||||
NewData :: data().
|
NewData :: data().
|
||||||
%% @private
|
%% @private
|
||||||
%% Reset the mirror configuration.
|
%% Reset the mirror configuration.
|
||||||
|
|
||||||
mirrors(Data, Hosts) ->
|
mirrors(Hosts, Data) ->
|
||||||
Data#d{mirrors = Hosts}.
|
Data#d{mirrors = Hosts}.
|
||||||
|
|
||||||
|
|
||||||
-spec add_mirror(Data, Host) -> NewData
|
-spec add_mirror(Host, Data) -> NewData
|
||||||
when Data :: data(),
|
when Host :: zx:host(),
|
||||||
Host :: zx:host(),
|
Data :: data(),
|
||||||
NewData :: data().
|
NewData :: data().
|
||||||
%% @doc
|
%% @doc
|
||||||
%% Add a mirror to the permanent configuration.
|
%% Add a mirror to the permanent configuration.
|
||||||
@ -304,14 +304,14 @@ add_mirror(Data = #d{mirrors = Mirrors}, Host) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
-spec rem_mirror(Data, Host) -> NewData
|
-spec rem_mirror(Host, Data) -> NewData
|
||||||
when Data :: data(),
|
when Host :: zx:host(),
|
||||||
Host :: zx:host(),
|
Data :: data(),
|
||||||
NewData :: data().
|
NewData :: data().
|
||||||
%% @private
|
%% @private
|
||||||
%% Remove a host from the list of permanent mirrors.
|
%% Remove a host from the list of permanent mirrors.
|
||||||
|
|
||||||
rem_mirror(Data = #d{mirrors = Mirrors}, Host) ->
|
rem_mirror(Host, Data = #d{mirrors = Mirrors}) ->
|
||||||
Data#d{mirrors = lists:delete(Host, Mirrors)}.
|
Data#d{mirrors = lists:delete(Host, Mirrors)}.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -147,7 +147,7 @@
|
|||||||
-export([pass_meta/3,
|
-export([pass_meta/3,
|
||||||
subscribe/1, unsubscribe/1,
|
subscribe/1, unsubscribe/1,
|
||||||
list/0, list/1, list/2, list/3, latest/1,
|
list/0, list/1, list/2, list/3, latest/1,
|
||||||
fetch_zsp/1, fetch_key/1,
|
fetch/1, verify_key/1,
|
||||||
pending/1, packagers/1, maintainers/1, sysops/1]).
|
pending/1, packagers/1, maintainers/1, sysops/1]).
|
||||||
-export([report/1, result/2, notify/2]).
|
-export([report/1, result/2, notify/2]).
|
||||||
-export([start_link/0, stop/0]).
|
-export([start_link/0, stop/0]).
|
||||||
@ -326,6 +326,9 @@
|
|||||||
%% references.
|
%% references.
|
||||||
|
|
||||||
pass_meta(Meta, Dir, ArgV) ->
|
pass_meta(Meta, Dir, ArgV) ->
|
||||||
|
ok = log(info, "Meta: ~tp", [Meta]),
|
||||||
|
ok = log(info, "Dir : ~tp", [Dir]),
|
||||||
|
ok = log(info, "ArgV: ~tp", [ArgV]),
|
||||||
gen_server:cast(?MODULE, {pass_meta, Meta, Dir, ArgV}).
|
gen_server:cast(?MODULE, {pass_meta, Meta, Dir, ArgV}).
|
||||||
|
|
||||||
|
|
||||||
@ -446,7 +449,7 @@ latest({Realm, Name, Version}) ->
|
|||||||
request({latest, Realm, Name, Version}).
|
request({latest, Realm, Name, Version}).
|
||||||
|
|
||||||
|
|
||||||
-spec fetch_zsp(PackageID) -> {ok, RequestID}
|
-spec fetch(PackageID) -> {ok, RequestID}
|
||||||
when PackageID :: zx:package_id(),
|
when PackageID :: zx:package_id(),
|
||||||
RequestID :: integer().
|
RequestID :: integer().
|
||||||
%% @doc
|
%% @doc
|
||||||
@ -458,27 +461,28 @@ latest({Realm, Name, Version}) ->
|
|||||||
%% Response messages are of the type `result()' where the third element is of the
|
%% Response messages are of the type `result()' where the third element is of the
|
||||||
%% type `fetch_result()'.
|
%% type `fetch_result()'.
|
||||||
|
|
||||||
fetch_zsp(PackageID = {Realm, Name, Version}) ->
|
fetch({Realm, Name, Version}) ->
|
||||||
true = zx_lib:valid_lower0_9(Realm),
|
true = zx_lib:valid_lower0_9(Realm),
|
||||||
true = zx_lib:valid_lower0_9(Name),
|
true = zx_lib:valid_lower0_9(Name),
|
||||||
true = zx_lib:valid_version(Version),
|
true = zx_lib:valid_version(Version),
|
||||||
request({fetch, zsp, PackageID}).
|
request({fetch, Realm, Name, Version}).
|
||||||
|
|
||||||
|
|
||||||
-spec fetch_key(KeyID) -> {ok, RequestID}
|
-spec verify_key(KeyID) -> {ok, RequestID}
|
||||||
when KeyID :: zx:key_id(),
|
when KeyID :: zx:key_id(),
|
||||||
RequestID :: id().
|
RequestID :: id().
|
||||||
%% @doc
|
%% @doc
|
||||||
%% Request a public key be fetched from its relevant realm.
|
%% Request a public key be fetched from its upstream, and pursue the key validation
|
||||||
|
%% chain until a key in possession is found or the chain is proven to be broken.
|
||||||
%% Crashes the caller if either component of the KeyID is illegal.
|
%% Crashes the caller if either component of the KeyID is illegal.
|
||||||
%%
|
%%
|
||||||
%% Response messages are of the type `result()' where the third element is of the
|
%% Response messages are of the type `result()' where the third element is of the
|
||||||
%% type `key_result()'.
|
%% type `key_result()'.
|
||||||
|
|
||||||
fetch_key(KeyID = {Realm, KeyName}) ->
|
verify_key({Realm, KeyName}) ->
|
||||||
true = zx_lib:valid_lower0_9(Realm),
|
true = zx_lib:valid_lower0_9(Realm),
|
||||||
true = zx_lib:valid_lower0_9(KeyName),
|
true = zx_lib:valid_lower0_9(KeyName),
|
||||||
request({fetch, key, KeyID}).
|
request({verify_key, Realm, KeyName}).
|
||||||
|
|
||||||
|
|
||||||
-spec pending(Package) -> {ok, RequestID}
|
-spec pending(Package) -> {ok, RequestID}
|
||||||
|
|||||||
@ -13,7 +13,7 @@
|
|||||||
-license("GPL-3.0").
|
-license("GPL-3.0").
|
||||||
|
|
||||||
-export([ensure_keypair/1, have_public_key/1, have_private_key/1,
|
-export([ensure_keypair/1, have_public_key/1, have_private_key/1,
|
||||||
prompt_keygen/0, grow_a_pair/0, generate_rsa/1,
|
prompt_keygen/0, generate_rsa/1,
|
||||||
load/2, verify/3]).
|
load/2, verify/3]).
|
||||||
|
|
||||||
-include("zx_logger.hrl").
|
-include("zx_logger.hrl").
|
||||||
@ -102,25 +102,10 @@ prompt_keygen() ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
-spec grow_a_pair() -> no_return().
|
|
||||||
%% @private
|
|
||||||
%% Execute the key generation procedure for 16k RSA keys once and then terminate.
|
|
||||||
|
|
||||||
grow_a_pair() ->
|
|
||||||
ok = file:set_cwd(zx_lib:zomp_dir()),
|
|
||||||
KeyID = prompt_keygen(),
|
|
||||||
case generate_rsa(KeyID) of
|
|
||||||
{ok, _, _} -> halt(0);
|
|
||||||
Error -> error_exit("grow_a_pair/0 error: ~tp", [Error], ?LINE)
|
|
||||||
end.
|
|
||||||
|
|
||||||
|
|
||||||
-spec generate_rsa(KeyID) -> Result
|
-spec generate_rsa(KeyID) -> Result
|
||||||
when KeyID :: zx:key_id(),
|
when KeyID :: zx:key_id(),
|
||||||
Result :: {ok, KeyFile, PubFile}
|
Result :: ok
|
||||||
| {error, keygen_fail},
|
| {error, keygen_fail}.
|
||||||
KeyFile :: file:filename(),
|
|
||||||
PubFile :: file:filename().
|
|
||||||
%% @private
|
%% @private
|
||||||
%% Generate an RSA keypair and write them in der format to the current directory, using
|
%% Generate an RSA keypair and write them in der format to the current directory, using
|
||||||
%% filenames derived from Prefix.
|
%% filenames derived from Prefix.
|
||||||
@ -144,10 +129,7 @@ generate_rsa({Realm, KeyName}) ->
|
|||||||
case check_key(KeyFile, PubFile) of
|
case check_key(KeyFile, PubFile) of
|
||||||
true ->
|
true ->
|
||||||
ok = file:delete(PemFile),
|
ok = file:delete(PemFile),
|
||||||
ok = log(info, "~ts and ~ts agree", [KeyFile, PubFile]),
|
log(info, "~ts and ~ts agree", [KeyFile, PubFile]);
|
||||||
ok = log(info, "Wrote private key to: ~ts.", [KeyFile]),
|
|
||||||
ok = log(info, "Wrote public key to: ~ts.", [PubFile]),
|
|
||||||
{ok, KeyFile, PubFile};
|
|
||||||
false ->
|
false ->
|
||||||
ok = lists:foreach(fun file:delete/1, [PemFile, KeyFile, PubFile]),
|
ok = lists:foreach(fun file:delete/1, [PemFile, KeyFile, PubFile]),
|
||||||
ok = log(error, "Something has gone wrong."),
|
ok = log(error, "Something has gone wrong."),
|
||||||
|
|||||||
@ -15,8 +15,8 @@
|
|||||||
-license("GPL-3.0").
|
-license("GPL-3.0").
|
||||||
|
|
||||||
-export([zomp_dir/0, find_zomp_dir/0,
|
-export([zomp_dir/0, find_zomp_dir/0,
|
||||||
path/1, path/2, path/3,
|
path/1, path/2, path/3, path/4, ppath/2,
|
||||||
force_dir/1,
|
force_dir/1, mktemp_dir/1,
|
||||||
list_realms/0,
|
list_realms/0,
|
||||||
hosts_cache_file/1, get_prime/1, realm_meta/1,
|
hosts_cache_file/1, get_prime/1, realm_meta/1,
|
||||||
read_project_meta/0, read_project_meta/1, read_package_meta/1,
|
read_project_meta/0, read_project_meta/1, read_package_meta/1,
|
||||||
@ -71,13 +71,13 @@ find_zomp_dir() ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
-spec path(Type) -> Result
|
-spec path(Type) -> Path
|
||||||
when Type :: etc
|
when Type :: etc
|
||||||
| var
|
| var
|
||||||
| tmp
|
| tmp
|
||||||
| log
|
| log
|
||||||
| lib,
|
| lib,
|
||||||
Result :: file:filename().
|
Path :: file:filename().
|
||||||
%% @private
|
%% @private
|
||||||
%% Return the top-level path of the given type in the Zomp/ZX system.
|
%% Return the top-level path of the given type in the Zomp/ZX system.
|
||||||
|
|
||||||
@ -85,17 +85,19 @@ path(etc) -> filename:join(zomp_dir(), "etc");
|
|||||||
path(var) -> filename:join(zomp_dir(), "var");
|
path(var) -> filename:join(zomp_dir(), "var");
|
||||||
path(tmp) -> filename:join(zomp_dir(), "tmp");
|
path(tmp) -> filename:join(zomp_dir(), "tmp");
|
||||||
path(log) -> filename:join(zomp_dir(), "log");
|
path(log) -> filename:join(zomp_dir(), "log");
|
||||||
|
path(key) -> filename:join(zomp_dir(), "key");
|
||||||
|
path(zsp) -> filename:join(zomp_dir(), "zsp");
|
||||||
path(lib) -> filename:join(zomp_dir(), "lib").
|
path(lib) -> filename:join(zomp_dir(), "lib").
|
||||||
|
|
||||||
|
|
||||||
-spec path(Type, Realm) -> Result
|
-spec path(Type, Realm) -> Path
|
||||||
when Type :: etc
|
when Type :: etc
|
||||||
| var
|
| var
|
||||||
| tmp
|
| tmp
|
||||||
| log
|
| log
|
||||||
| lib,
|
| lib,
|
||||||
Realm :: zx:realm(),
|
Realm :: zx:realm(),
|
||||||
Result :: file:filename().
|
Path :: file:filename().
|
||||||
%% @private
|
%% @private
|
||||||
%% Return the realm-level path of the given type in the Zomp/ZX system.
|
%% Return the realm-level path of the given type in the Zomp/ZX system.
|
||||||
|
|
||||||
@ -103,7 +105,7 @@ path(Type, Realm) ->
|
|||||||
filename:join(path(Type), Realm).
|
filename:join(path(Type), Realm).
|
||||||
|
|
||||||
|
|
||||||
-spec path(Type, Realm, Name) -> Result
|
-spec path(Type, Realm, Name) -> Path
|
||||||
when Type :: etc
|
when Type :: etc
|
||||||
| var
|
| var
|
||||||
| tmp
|
| tmp
|
||||||
@ -111,7 +113,7 @@ path(Type, Realm) ->
|
|||||||
| lib,
|
| lib,
|
||||||
Realm :: zx:realm(),
|
Realm :: zx:realm(),
|
||||||
Name :: zx:name(),
|
Name :: zx:name(),
|
||||||
Result :: file:filename().
|
Path :: file:filename().
|
||||||
%% @private
|
%% @private
|
||||||
%% Return the package-level path of the given type in the Zomp/ZX system.
|
%% Return the package-level path of the given type in the Zomp/ZX system.
|
||||||
|
|
||||||
@ -119,6 +121,40 @@ path(Type, Realm, Name) ->
|
|||||||
filename:join([path(Type), Realm, Name]).
|
filename:join([path(Type), Realm, Name]).
|
||||||
|
|
||||||
|
|
||||||
|
-spec path(Type, Realm, Name, Version) -> Path
|
||||||
|
when Type :: etc
|
||||||
|
| var
|
||||||
|
| tmp
|
||||||
|
| log
|
||||||
|
| lib,
|
||||||
|
Realm :: zx:realm(),
|
||||||
|
Name :: zx:name(),
|
||||||
|
Version :: zx:version(),
|
||||||
|
Path :: file:filename().
|
||||||
|
%% @private
|
||||||
|
%% Return the version-specific level path of the given type in the Zomp/ZX system.
|
||||||
|
|
||||||
|
path(Type, Realm, Name, Version) ->
|
||||||
|
{ok, VersionString} = version_to_string(Version),
|
||||||
|
filename:join([path(Type), Realm, Name, VersionString]).
|
||||||
|
|
||||||
|
|
||||||
|
-spec ppath(Type, PackageID) -> Path
|
||||||
|
when Type :: etc
|
||||||
|
| var
|
||||||
|
| tmp
|
||||||
|
| log
|
||||||
|
| lib,
|
||||||
|
PackageID :: zx:package_id(),
|
||||||
|
Path :: file:filename().
|
||||||
|
%% @private
|
||||||
|
%% An alias for path/4, but more convenient when needing a path from a closed
|
||||||
|
%% package_id().
|
||||||
|
|
||||||
|
ppath(Type, {Realm, Name, Version}) ->
|
||||||
|
path(Type, Realm, Name, Version).
|
||||||
|
|
||||||
|
|
||||||
-spec force_dir(Path) -> Result
|
-spec force_dir(Path) -> Result
|
||||||
when Path :: file:filename(),
|
when Path :: file:filename(),
|
||||||
Result :: ok
|
Result :: ok
|
||||||
@ -134,6 +170,20 @@ force_dir(Path) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
-spec mktemp_dir(Package) -> Result
|
||||||
|
when Package :: zx:package(),
|
||||||
|
Result :: {ok, TempDir :: file:filename()}
|
||||||
|
| {error, Reason :: file:posix()}.
|
||||||
|
|
||||||
|
mktemp_dir({Realm, Name}) ->
|
||||||
|
Rand = integer_to_list(binary:decode_unsigned(crypto:strong_rand_bytes(8)), 36),
|
||||||
|
TempDir = filename:join(path(etc, Realm, Name), Rand),
|
||||||
|
case force_dir(TempDir) of
|
||||||
|
ok -> {ok, TempDir};
|
||||||
|
Error -> Error
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
-spec hosts_cache_file(zx:realm()) -> file:filename().
|
-spec hosts_cache_file(zx:realm()) -> file:filename().
|
||||||
%% @private
|
%% @private
|
||||||
%% Given a Realm name, construct a realm's .hosts filename and return it.
|
%% Given a Realm name, construct a realm's .hosts filename and return it.
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
2
zx_dev
2
zx_dev
@ -12,4 +12,4 @@ export ZX_DIR="$ZOMP_DIR/lib/otpr/zx/$VERSION"
|
|||||||
pushd "$ZX_DIR" > /dev/null
|
pushd "$ZX_DIR" > /dev/null
|
||||||
./make_zx
|
./make_zx
|
||||||
popd > /dev/null
|
popd > /dev/null
|
||||||
erl -pa "$ZX_DIR/ebin" -run zx run $@
|
erl -noshell -pa "$ZX_DIR/ebin" -run zx do $@
|
||||||
|
|||||||
15
zxh_dev
Executable file
15
zxh_dev
Executable file
@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
pushd $(dirname $BASH_SOURCE) > /dev/null
|
||||||
|
ZX_DEV_ROOT=$PWD
|
||||||
|
popd > /dev/null
|
||||||
|
export ZOMP_DIR="$ZX_DEV_ROOT/tester"
|
||||||
|
rm -rf "$ZOMP_DIR"
|
||||||
|
cp -r "$ZX_DEV_ROOT/zomp" "$ZOMP_DIR"
|
||||||
|
VERSION=$(cat "$ZOMP_DIR/etc/version.txt")
|
||||||
|
export ZX_DIR="$ZOMP_DIR/lib/otpr/zx/$VERSION"
|
||||||
|
|
||||||
|
pushd "$ZX_DIR" > /dev/null
|
||||||
|
./make_zx
|
||||||
|
popd > /dev/null
|
||||||
|
erl -pa "$ZX_DIR/ebin" -run zx do $@
|
||||||
Loading…
x
Reference in New Issue
Block a user