wip
This commit is contained in:
parent
58aafaf692
commit
8476f3a89a
306
zx
306
zx
@ -87,10 +87,60 @@ start(["set", "dep", PackageString]) ->
|
||||
set_dep(PackageID);
|
||||
start(["set", "version", VersionString]) ->
|
||||
set_version(VersionString);
|
||||
start(["list", "realms"]) ->
|
||||
list_realms();
|
||||
start(["list", "packages", Realm]) ->
|
||||
case valid_lower0_9(Realm) of
|
||||
true ->
|
||||
list_packages(Realm);
|
||||
false ->
|
||||
ok = log(error, "Bad realm name."),
|
||||
halt(1)
|
||||
end;
|
||||
start(["list", "versions", Package]) ->
|
||||
case string:lexemes(Package, "-") of
|
||||
[Realm, Name] ->
|
||||
list_versions({Realm, Name});
|
||||
_ ->
|
||||
ok = log(error, "Bad package name."),
|
||||
halt(1)
|
||||
end;
|
||||
start(["list", "pending", Package]) ->
|
||||
case string:lexemes(Package, "-") of
|
||||
[Realm, Name] ->
|
||||
list_pending({Realm, Name});
|
||||
_ ->
|
||||
ok = log(error, "Bad package name."),
|
||||
halt(1)
|
||||
end;
|
||||
start(["list", "resigns", Realm]) ->
|
||||
case valid_lower0_9(Realm) of
|
||||
true ->
|
||||
list_resigns(Realm);
|
||||
false ->
|
||||
ok = log(error, "Bad realm name."),
|
||||
halt(1)
|
||||
end;
|
||||
start(["add", "realm", RealmFile]) ->
|
||||
add_realm(RealmFile);
|
||||
start(["add", "package", PackageName]) ->
|
||||
add_package(PackageName);
|
||||
start(["add", "packager", Package, UserName]) ->
|
||||
add_packager(Package, UserName);
|
||||
start(["add", "maintainer", Package, UserName]) ->
|
||||
add_maintainer(Package, UserName);
|
||||
start(["review", PackageString]) ->
|
||||
PackageID = package_id(PackageString),
|
||||
review(PackageID);
|
||||
start(["approve", PackageString]) ->
|
||||
PackageID = package_id(PackageString),
|
||||
approve(PackageID);
|
||||
start(["reject", PackageString]) ->
|
||||
PackageID = package_id(PackageString),
|
||||
reject(PackageID);
|
||||
start(["resign", PackageString]) ->
|
||||
PackageID = package_id(PackageString),
|
||||
resign(PackageID);
|
||||
start(["drop", "dep", PackageString]) ->
|
||||
PackageID = package_id(PackageString),
|
||||
drop_dep(PackageID);
|
||||
@ -548,6 +598,104 @@ update_version(Realm, Name, OldVersion, NewVersion, OldMeta) ->
|
||||
|
||||
|
||||
|
||||
%%% List Functions
|
||||
|
||||
-spec list_realms() -> no_return().
|
||||
%% @private
|
||||
%% List all currently configured realms. The definition of a "configured realm" is a
|
||||
%% realm for which a .realm file exists in ~/.zomp/. The realms will be printed to
|
||||
%% stdout and the program will exit.
|
||||
|
||||
list_realms() ->
|
||||
Pattern = filename:join(zomp_dir(), "*.realm"),
|
||||
RealmFiles = filelib:wildcard(Pattern),
|
||||
Realms = [filename:basename(RF, ".realm") || RF <- RealmFiles],
|
||||
ok = lists:foreach(fun(R) -> io:format("~ts~n", [R]) end, Realms),
|
||||
halt(0).
|
||||
|
||||
|
||||
-spec list_packages(realm()) -> no_return().
|
||||
%% @private
|
||||
%% Contact the indicated realm and query it for a list of registered packages and print
|
||||
%% them to stdout.
|
||||
|
||||
list_packages(Realm) ->
|
||||
Socket = connect_user(Realm),
|
||||
ok = send(Socket, {list, Realm}),
|
||||
case recv_or_die(Socket) of
|
||||
{ok, []} ->
|
||||
ok = log(info, "Realm ~tp has no packages available.", [Realm]),
|
||||
halt(0);
|
||||
{ok, Packages} ->
|
||||
Print = fun({R, N}) -> io:format("~ts-~ts~n", [R, N]) end,
|
||||
ok = lists:foreach(Print, Packages),
|
||||
halt(0);
|
||||
end.
|
||||
|
||||
|
||||
-spec list_versions(package()) -> no_return().
|
||||
|
||||
list_versions(Package = {Realm, Name}) ->
|
||||
ok = valid_package(Package),
|
||||
Socket = connect_user(Realm),
|
||||
ok = send(Socket, {list, Realm, Name}),
|
||||
case recv_or_die(Socket) of
|
||||
{ok, []} ->
|
||||
Message = "Package ~ts-~ts has no versions available.",
|
||||
ok = log(info, Message, [Realm, Name]),
|
||||
halt(0);
|
||||
{ok, Versions} ->
|
||||
Print =
|
||||
fun(Version) ->
|
||||
PackageString = package_string({Realm, Name, Version}),
|
||||
io:format("~ts~n", [PackageString])
|
||||
end,
|
||||
ok = lists:foreach(Print, Versions),
|
||||
halt(0)
|
||||
end.
|
||||
|
||||
|
||||
-spec list_pending(package()) -> no_return().
|
||||
|
||||
list_pending(Package = {Realm, Name}) ->
|
||||
ok = valid_package(Package),
|
||||
Socket = connect_user(Realm),
|
||||
ok = send(Socket, {pending, Package}),
|
||||
case recv_or_die(Socket) of
|
||||
{ok, []} ->
|
||||
Message = "Package ~ts-~ts has no versions pending.",
|
||||
ok = log(info, Message, [Realm, Name]),
|
||||
halt(0);
|
||||
{ok, Versions} ->
|
||||
Print =
|
||||
fun(Version) ->
|
||||
PackageString = package_string({Realm, Name, Version}),
|
||||
io:format("~ts~n", [PackageString])
|
||||
end,
|
||||
ok = lists:foreach(Print, Versions),
|
||||
halt(0)
|
||||
end.
|
||||
|
||||
|
||||
-spec valid_package(package()) -> ok | no_return().
|
||||
|
||||
valid_package({Realm, Name}) ->
|
||||
case {valid_lower0_9(Realm), valid_lower0_9(Name)} of
|
||||
{true, true} ->
|
||||
ok;
|
||||
{false, true} ->
|
||||
ok = log(error, "Invalid realm name: ~tp", [Realm]),
|
||||
halt(1);
|
||||
{true, false} ->
|
||||
ok = log(error, "Invalid package name: ~tp", [Name]),
|
||||
halt(1);
|
||||
{false, false} ->
|
||||
ok = log(error, "Invalid realm ~tp and package ~tp", [Realm, Name]),
|
||||
halt(1)
|
||||
end.
|
||||
|
||||
|
||||
|
||||
%%% Add realm
|
||||
|
||||
-spec add_realm(Path) -> no_return()
|
||||
@ -621,35 +769,95 @@ add_package(PackageName) ->
|
||||
%% This sysop-only command can add a package to a realm operated by the caller.
|
||||
|
||||
add_package(Realm, Name) ->
|
||||
Socket =
|
||||
case connect_auth(Realm) of
|
||||
{ok, S} ->
|
||||
S;
|
||||
Error ->
|
||||
M1 = "Connection failed to realm prime with ~160tp.",
|
||||
ok = log(warning, M1, [Error]),
|
||||
halt(1)
|
||||
end,
|
||||
Socket = connect_auth_or_die(Realm),
|
||||
ok = send(Socket, {add_package, {Realm, Name}}),
|
||||
receive
|
||||
{tcp, Socket, Bin} ->
|
||||
case binary_to_term(Bin, [safe]) of
|
||||
ok ->
|
||||
ok = recv_or_die(Socket),
|
||||
ok = log(info, "\"~ts-~ts\" added successfully.", [Realm, Name]),
|
||||
halt(0).
|
||||
|
||||
|
||||
list_resigns(Realm) ->
|
||||
Socket = connect_auth_or_die(Realm),
|
||||
ok = send(Socket, {list_resigns, Realm}),
|
||||
case recv_or_die(Socket) of
|
||||
{ok, []} ->
|
||||
Message = "No packages pending signature in ~tp.",
|
||||
ok = log(info, Message, [Realm]),
|
||||
halt(0);
|
||||
{error, Reason} ->
|
||||
M2 = "Operation failed. Server sends reason: ~160tp",
|
||||
ok = log(error, M2, [Reason]),
|
||||
halt(1)
|
||||
end;
|
||||
{tcp_closed, Socket} ->
|
||||
halt_on_unexpected_close()
|
||||
after 5000 ->
|
||||
ok = log(warning, "Operation timed After submission to server."),
|
||||
halt(1)
|
||||
{ok, PackageIDs} ->
|
||||
Print =
|
||||
fun(PackageID) ->
|
||||
PackageString = package_string(PackageID),
|
||||
io:format("~ts~n", [PackageString])
|
||||
end,
|
||||
ok = lists:foreach(Print, PackageIDs),
|
||||
halt(0)
|
||||
end.
|
||||
|
||||
|
||||
add_packager(Package, UserName) ->
|
||||
ok = log(info, "Would add ~ts to packagers for ~160tp now.", [UserName, Package]),
|
||||
halt(0).
|
||||
|
||||
|
||||
add_maintainer(Package, UserName) ->
|
||||
ok = log(info, "Would add ~ts to maintainer for ~160tp now.", [UserName, Package]),
|
||||
halt(0).
|
||||
|
||||
|
||||
review(PackageID) ->
|
||||
PackageString = package_string(PackageID),
|
||||
ZrpPath = PackageString ++ ".zrp",
|
||||
ok = log(info, "Saving to ~ts, unpacking to ./~ts/", [ZrpPath, PackageString]),
|
||||
ok =
|
||||
case {filelib:is_file(ZrpPath), filelib:is_file(PackageString)} of
|
||||
{false, false} ->
|
||||
ok;
|
||||
{true, false} ->
|
||||
ok = log(error, "~ts already exists. Aborting.", [ZrpPath]),
|
||||
halt(1);
|
||||
{false, true} ->
|
||||
ok = log(error, "~ts already exists. Aborting.", [PackageString]),
|
||||
halt(1);
|
||||
{true true} ->
|
||||
Message = "~ts and ~ts already exist. Aborting.",
|
||||
ok = log(error, Message, [ZrpPath, PackageString]),
|
||||
halt(1);
|
||||
end,
|
||||
Socket = connect_auth_or_die(),
|
||||
ok = send(Socket, {review, PackageID}),
|
||||
ok = receive_or_die(Socket),
|
||||
{ok, ZrpBin} = recieve_or_die(Socket),
|
||||
ok = file:write_file(ZrpPath, ZrpBin),
|
||||
ok = disconnect(Socket),
|
||||
{"zomp.meta", MetaBin} = erl_tar:extract(ZrpBin, [memory, {files, "zomp.meta"}]),
|
||||
Meta = binary_to_term(MetaBin, [safe]),
|
||||
|
||||
|
||||
|
||||
approve(PackageID = {Realm, _, _}) ->
|
||||
Socket = connect_auth_or_die(Realm),
|
||||
ok = send(Socket, {approve, PackageID}),
|
||||
ok = recv_or_die(Socket),
|
||||
ok = log(info, "ok"),
|
||||
halt(0).
|
||||
|
||||
|
||||
reject(PackageID = {Realm, _, _}) ->
|
||||
Socket = connect_auth_or_die(Realm),
|
||||
ok = send(Socket, {reject, PackageID}),
|
||||
ok = recv_or_die(Socket),
|
||||
ok = log(info, "ok"),
|
||||
halt(0).
|
||||
|
||||
|
||||
resign(PackageID) ->
|
||||
M = "Pull the indicated package",
|
||||
ok = log(info, M, [PackageID]),
|
||||
halt(0).
|
||||
|
||||
|
||||
|
||||
%%% Drop dependency
|
||||
|
||||
-spec drop_dep(package_id()) -> no_return().
|
||||
@ -1057,6 +1265,43 @@ send(Socket, Message) ->
|
||||
gen_tcp:send(Socket, Bin).
|
||||
|
||||
|
||||
-spec recv_or_die(Socket) -> Result | no_return()
|
||||
when Socket :: gen_tcp:socket(),
|
||||
Result :: ok | {ok, term()}.
|
||||
|
||||
recv_or_die(Socket) ->
|
||||
receive
|
||||
{tcp, Socket, Bin} ->
|
||||
case binary_to_term(Bin, [safe]) of
|
||||
ok ->
|
||||
ok;
|
||||
{ok, Response} ->
|
||||
{ok, Response};
|
||||
{error, bad_realm} ->
|
||||
ok = log(warning, "No such realm at the connected node.").
|
||||
halt(1);
|
||||
{error, bad_package} ->
|
||||
ok = log(warning, "No such package.").
|
||||
halt(1)
|
||||
{error, bad_version} ->
|
||||
ok = log(warning, "No such version."),
|
||||
halt(1);
|
||||
{error, not_in_queue} ->
|
||||
ok = log(warning, "Version is not queued."),
|
||||
halt(1);
|
||||
{error, bad_message} ->
|
||||
ok = log(error, "Oh noes! zx sent an illegal message!"),
|
||||
halt(1)
|
||||
end;
|
||||
{tcp_closed, Socket} ->
|
||||
ok = log(warning, "Lost connection to node unexpectedly."),
|
||||
halt(1)
|
||||
after 5000 ->
|
||||
ok = log(warning, "Node timed out."),
|
||||
halt(1)
|
||||
end.
|
||||
|
||||
|
||||
-spec halt_on_unexpected_close() -> no_return().
|
||||
|
||||
halt_on_unexpected_close() ->
|
||||
@ -1169,7 +1414,7 @@ confirm_serial(Realm, Socket, Hosts) ->
|
||||
Socket;
|
||||
{ok, Current} when Current > Serial ->
|
||||
ok = log(info, "Node's serial newer than ours. Storing."),
|
||||
NewSerials = lists:keystore(Realm, 1, Current, {Realm, Serials}),
|
||||
NewSerials = lists:keystore(Realm, 1, Serials, {Realm, Current}),
|
||||
{ok, Host} = inet:peername(Socket),
|
||||
ok = write_terms(hosts_cache_file(Realm), [Host | Hosts]),
|
||||
ok = write_terms(SerialFile, NewSerials),
|
||||
@ -1193,6 +1438,19 @@ confirm_serial(Realm, Socket, Hosts) ->
|
||||
end.
|
||||
|
||||
|
||||
-spec connect_auth_or_die(realm()) -> gen_tcp:socket() | no_return().
|
||||
|
||||
connect_auth_or_die(Realm) ->
|
||||
case connect_auth(Realm) of
|
||||
{ok, Socket} ->
|
||||
Socket;
|
||||
Error ->
|
||||
M1 = "Connection failed to realm prime with ~160tp.",
|
||||
ok = log(warning, M1, [Error]),
|
||||
halt(1)
|
||||
end.
|
||||
|
||||
|
||||
-spec connect_auth(Realm) -> Result
|
||||
when Realm :: realm(),
|
||||
Result :: {ok, gen_tcp:socket()}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user