From feb1ad5b38a6c1e4eec99cd19838b240d626a8eb Mon Sep 17 00:00:00 2001 From: Peter Lemenkov Date: Mon, 6 Jul 2020 23:52:57 +0200 Subject: whitespace Signed-off-by: Peter Lemenkov --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 5d7c937..6ea2bac 100644 --- a/README.md +++ b/README.md @@ -10,10 +10,10 @@ Installation ============ On Fedora/CentOS - + ```bash rpm -i erlang-sd_notify-{version}-1.el7.centos.x86_64.rpm -``` +``` On Debian/Ubuntu @@ -32,7 +32,7 @@ sudo zypper --gpg-auto-import-keys refresh sudo zypper install erlang-sd_notify ``` - + Build from source using Docker === @@ -59,7 +59,7 @@ Example Download Binaries === -[Github Repository](https://github.com/systemd/erlang-sd_notify/releases) +[Github Repository](https://github.com/systemd/erlang-sd_notify/releases) Usage ===== @@ -68,7 +68,7 @@ Quick example: ```bash [root@a499ee66251a]# erl - ... + ... 1> sd_notify:sd_notify(0,"READY=1"). 0 ``` -- cgit v1.2.1 From ef115fcc70b8ea1d2bfe3f76c478d71a0961ec86 Mon Sep 17 00:00:00 2001 From: Peter Lemenkov Date: Mon, 6 Jul 2020 23:48:00 +0200 Subject: Switch to native Unix sockets Closes systemd/erlang-sd_notify#1. Signed-off-by: Peter Lemenkov --- c_src/sd_notify.c | 75 ------------------------------ docker/centos_20/Dockerfile | 2 - docker/centos_21/Dockerfile | 2 - docker/centos_22/Dockerfile | 2 - docker/ubuntu_20/Dockerfile | 4 +- docker/ubuntu_21/Dockerfile | 4 +- packaging/centos/erlang-sd_notify.spec | 9 +--- packaging/deb/Makefile | 1 - packaging/deb/debian/control | 4 +- packaging/deb/debian/erlang-sd-notify.dirs | 1 - rebar.config | 2 - src/sd_notify.app.src | 2 +- src/sd_notify.erl | 34 ++++++-------- test/sd_notify_test.erl | 2 +- 14 files changed, 21 insertions(+), 123 deletions(-) delete mode 100644 c_src/sd_notify.c diff --git a/c_src/sd_notify.c b/c_src/sd_notify.c deleted file mode 100644 index 5c21be4..0000000 --- a/c_src/sd_notify.c +++ /dev/null @@ -1,75 +0,0 @@ -/* -This is the MIT license. - -Copyright (c) 2014 Peter Lemenkov - -Permission is hereby granted, free of charge, to any person obtaining a copy of this -software and associated documentation files (the "Software"), to deal in the Software -without restriction, including without limitation the rights to use, copy, modify, -merge, publish, distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be included in all copies -or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF -CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE -OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#include "erl_nif.h" -#include - -static int upgrade(ErlNifEnv* env, void** priv, void** old_priv, ERL_NIF_TERM load_info) -{ - return 0; -} - -static ERL_NIF_TERM sd_pid_notify_with_fds_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{ - ERL_NIF_TERM head, tail; - unsigned int length = 0; - - pid_t pid = 0; - enif_get_int(env, argv[0], &pid); - - int unset_environment = 0; - enif_get_int(env, argv[1], &unset_environment); - - enif_get_list_length(env, argv[2], &length); - char* state = (char*)enif_alloc(++length); - enif_get_string(env, argv[2], state, length, ERL_NIF_LATIN1); - - enif_get_list_length(env, argv[3], &length); - int* fds = (int*)enif_alloc(length * sizeof(int)); - ERL_NIF_TERM list = argv[3]; - int i = 0; - while(enif_get_list_cell(env, list, &head, &tail)) { - enif_get_int(env, head, &fds[i]); - i++; - list = tail; - } - int result = sd_pid_notify_with_fds(pid, unset_environment, state, fds, length); - - enif_free(fds); - enif_free(state); - - return enif_make_int(env, result); -} - -static ErlNifFunc nif_funcs[] = -{ - {"sd_pid_notify_with_fds", 4, sd_pid_notify_with_fds_nif}, - -}; - -// Initialize this NIF library. -// -// Args: (MODULE, ErlNifFunc funcs[], load, reload, upgrade, unload) -// Docs: http://erlang.org/doc/man/erl_nif.html#ERL_NIF_INIT - -ERL_NIF_INIT(sd_notify, nif_funcs, NULL, NULL, &upgrade, NULL); diff --git a/docker/centos_20/Dockerfile b/docker/centos_20/Dockerfile index e9b2294..04513fc 100644 --- a/docker/centos_20/Dockerfile +++ b/docker/centos_20/Dockerfile @@ -3,8 +3,6 @@ FROM centos RUN yum -y update RUN yum install -y \ - gcc \ - systemd-devel \ make \ git \ wget \ diff --git a/docker/centos_21/Dockerfile b/docker/centos_21/Dockerfile index 6511c0d..27aac68 100644 --- a/docker/centos_21/Dockerfile +++ b/docker/centos_21/Dockerfile @@ -3,8 +3,6 @@ FROM centos RUN yum -y update RUN yum install -y \ - gcc \ - systemd-devel \ make \ git \ wget \ diff --git a/docker/centos_22/Dockerfile b/docker/centos_22/Dockerfile index 2e9ef67..eb93684 100644 --- a/docker/centos_22/Dockerfile +++ b/docker/centos_22/Dockerfile @@ -3,8 +3,6 @@ FROM centos RUN yum -y update RUN yum install -y \ - gcc \ - systemd-devel \ make \ git \ wget \ diff --git a/docker/ubuntu_20/Dockerfile b/docker/ubuntu_20/Dockerfile index 6adcdf3..766c3f9 100644 --- a/docker/ubuntu_20/Dockerfile +++ b/docker/ubuntu_20/Dockerfile @@ -3,15 +3,13 @@ FROM ubuntu:16.04 RUN apt-get -y update RUN apt-get install -y \ - gcc \ make \ git \ wget \ build-essential \ devscripts \ fakeroot \ - debhelper \ - libsystemd-dev + debhelper RUN wget https://packages.erlang-solutions.com/erlang-solutions_1.0_all.deb diff --git a/docker/ubuntu_21/Dockerfile b/docker/ubuntu_21/Dockerfile index eecdb52..666cb73 100644 --- a/docker/ubuntu_21/Dockerfile +++ b/docker/ubuntu_21/Dockerfile @@ -3,15 +3,13 @@ FROM ubuntu:16.04 RUN apt-get -y update RUN apt-get install -y \ - gcc \ make \ git \ wget \ build-essential \ devscripts \ fakeroot \ - debhelper \ - libsystemd-dev + debhelper RUN wget https://packages.erlang-solutions.com/erlang-solutions_1.0_all.deb diff --git a/packaging/centos/erlang-sd_notify.spec b/packaging/centos/erlang-sd_notify.spec index ea2cd26..6a3509c 100644 --- a/packaging/centos/erlang-sd_notify.spec +++ b/packaging/centos/erlang-sd_notify.spec @@ -14,14 +14,12 @@ VCS: scm:git:https://github.com/%{upstream}/%{realname}.git Source0: https://github.com/%{upstream}/%{realname}/archive/%{version}/erlang-%{realname}-%{version}.tar.gz Source1: erlang-sd_notify-rebar.config BuildRequires: erlang-rebar -BuildRequires: systemd-devel -%{?__erlang_nif_version:Requires: %{__erlang_nif_version}} %description %{summary}. -%prep +%prep %setup -c . %build @@ -29,20 +27,17 @@ rebar compile %install -mkdir -p $RPM_BUILD_ROOT%{_libdir}/erlang/lib/%{realname}-%{version}/{ebin,priv} +mkdir -p $RPM_BUILD_ROOT%{_libdir}/erlang/lib/%{realname}-%{version}/ebin install -m 644 -p ebin/%{realname}.app $RPM_BUILD_ROOT%{_libdir}/erlang/lib/%{realname}-%{version}/ebin install -m 644 -p ebin/%{realname}.beam $RPM_BUILD_ROOT%{_libdir}/erlang/lib/%{realname}-%{version}/ebin -install -m 755 -p priv/%{realname}_drv.so $RPM_BUILD_ROOT%{_libdir}/erlang/lib/%{realname}-%{version}/priv %files %doc LICENSE %dir %{_libdir}/erlang/lib/%{realname}-%{version}/ %dir %{_libdir}/erlang/lib/%{realname}-%{version}/ebin/ -%dir %{_libdir}/erlang/lib/%{realname}-%{version}/priv/ %{_libdir}/erlang/lib/%{realname}-%{version}/ebin/%{realname}.app %{_libdir}/erlang/lib/%{realname}-%{version}/ebin/%{realname}.beam -%{_libdir}/erlang/lib/%{realname}-%{version}/priv/%{realname}_drv.so %changelog diff --git a/packaging/deb/Makefile b/packaging/deb/Makefile index dd8bf0a..5272597 100644 --- a/packaging/deb/Makefile +++ b/packaging/deb/Makefile @@ -30,4 +30,3 @@ deb-install: pwd install -o root -g root -t $(TARGET_DIR)/ebin ../../ebin/*.app install -o root -g root -t $(TARGET_DIR)/ebin ../../ebin/*.beam - install -o root -g root -t $(TARGET_DIR)/priv ../../priv/*.so diff --git a/packaging/deb/debian/control b/packaging/deb/debian/control index ff30267..d9fea23 100644 --- a/packaging/deb/debian/control +++ b/packaging/deb/debian/control @@ -5,12 +5,10 @@ Priority: optional Standards-Version: 3.9.2 Build-Depends: debhelper (>= 9), erlang-dev (>=17.3-dfsg-4), - libsystemd-dev (>=215), rebar, Package: erlang-sd-notify Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, - erlang-base (>=17.3) | erlang-base-hipe (>=17.3), - libsystemd0 (>=215), + erlang-base (>=17.3) | erlang-base-hipe (>=17.3) Description: Systemd notification support for Erlang. diff --git a/packaging/deb/debian/erlang-sd-notify.dirs b/packaging/deb/debian/erlang-sd-notify.dirs index 1b9362c..0f90a75 100644 --- a/packaging/deb/debian/erlang-sd-notify.dirs +++ b/packaging/deb/debian/erlang-sd-notify.dirs @@ -1,2 +1 @@ usr/lib/erlang/lib/sd_notify-%VERSION%/ebin -usr/lib/erlang/lib/sd_notify-%VERSION%/priv diff --git a/rebar.config b/rebar.config index 4f871b1..422726d 100644 --- a/rebar.config +++ b/rebar.config @@ -1,3 +1 @@ -{port_env, [{"LDFLAGS", "$LDFLAGS -lsystemd"}]}. - {erl_opts, [debug_info, warnings_as_errors]}. diff --git a/src/sd_notify.app.src b/src/sd_notify.app.src index da3ae2f..f936bd2 100644 --- a/src/sd_notify.app.src +++ b/src/sd_notify.app.src @@ -1,6 +1,6 @@ {application, sd_notify, [ - {description, "Erlang sd_notify NIF"}, + {description, "Erlang sd_notify API"}, {vsn, "git"}, {registered, []}, {applications, [ diff --git a/src/sd_notify.erl b/src/sd_notify.erl index c5201da..9d0b2e2 100644 --- a/src/sd_notify.erl +++ b/src/sd_notify.erl @@ -29,24 +29,6 @@ -export([sd_notify/2, sd_notifyf/3, sd_pid_notify/3, sd_pid_notifyf/4, sd_pid_notify_with_fds/4]). --on_load(init/0). - --define(nif_stub, nif_stub_error(?LINE)). - -nif_stub_error(Line) -> - erlang:nif_error({nif_not_loaded,module,?MODULE,line,Line}). - -init() -> - PrivDir = case code:priv_dir(?MODULE) of - {error, bad_name} -> - EbinDir = filename:dirname(code:which(?MODULE)), - AppPath = filename:dirname(EbinDir), - filename:join(AppPath, "priv"); - Path -> - Path - end, - erlang:load_nif(filename:join(PrivDir, ?MODULE) ++ "_drv", 0). - sd_notify(UnsetEnv, Data) -> sd_pid_notify_with_fds(0, UnsetEnv, Data, []). @@ -59,5 +41,17 @@ sd_notifyf(UnsetEnv, Format, Data) -> sd_pid_notifyf(Pid, UnsetEnv, Format, Data) -> sd_pid_notify_with_fds(Pid, UnsetEnv, lists:flatten(io_lib:format(Format, Data)), []). -sd_pid_notify_with_fds(_, _, _, _) -> - ?nif_stub. +sd_pid_notify_with_fds(_Pid, _UnsetEnv, Call, _Fds) -> + error_logger:info_msg("systemd: ~p", [Call]), + case os:getenv("NOTIFY_SOCKET") of + false -> {error, not_configured}; + Path -> + case gen_udp:open(0, [local]) of + {error, SocketError} -> + {error, SocketError}; + {ok, Socket} -> + Result = gen_udp:send(Socket, {local,Path}, 0, Call), + gen_udp:close(Socket), + Result + end + end. diff --git a/test/sd_notify_test.erl b/test/sd_notify_test.erl index 4ae437a..0281c85 100644 --- a/test/sd_notify_test.erl +++ b/test/sd_notify_test.erl @@ -20,7 +20,7 @@ sd_notify_test_local("19") -> "Try sending message", fun() -> TestMessage = integer_to_list(erlang:phash2(make_ref())), - 1 = sd_notify:sd_pid_notify_with_fds(0, 0, TestMessage, []), + ok = sd_notify:sd_pid_notify_with_fds(0, 0, TestMessage, []), {ok, {_Address, _Port, Packet}} = gen_udp:recv(FakeNotifyUnixSock, length(TestMessage), 1000), ?assertEqual(TestMessage, Packet) end -- cgit v1.2.1 From 9eb84a464326c8d52bdb6cb251a95e63800f6559 Mon Sep 17 00:00:00 2001 From: Peter Lemenkov Date: Mon, 6 Jul 2020 21:06:07 +0200 Subject: Don't check Erlang/OTP versions anymore Signed-off-by: Peter Lemenkov --- test/sd_notify_test.erl | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/test/sd_notify_test.erl b/test/sd_notify_test.erl index 0281c85..86766bc 100644 --- a/test/sd_notify_test.erl +++ b/test/sd_notify_test.erl @@ -4,9 +4,6 @@ sd_notify_test_() -> - sd_notify_test_local(erlang:system_info(otp_release)). - -sd_notify_test_local("19") -> {ok, CWD} = file:get_cwd(), FakeNotifyUnixSockName = CWD ++ "/fake-sock-" ++ integer_to_list(erlang:phash2(make_ref())), {ok, FakeNotifyUnixSock} = gen_udp:open(0, [{ifaddr, {local, FakeNotifyUnixSockName}}, {active, false}, list]), @@ -28,6 +25,4 @@ sd_notify_test_local("19") -> ] - }; -sd_notify_test_local(_) -> - []. + }. -- cgit v1.2.1 From 5f622370d3f5986fa721df016271c064474bd51c Mon Sep 17 00:00:00 2001 From: Peter Lemenkov Date: Tue, 7 Jul 2020 00:03:24 +0200 Subject: Unset NOTIFY_SOCKET env if requested Signed-off-by: Peter Lemenkov --- src/sd_notify.erl | 5 ++++- test/sd_notify_test.erl | 28 ++++++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/sd_notify.erl b/src/sd_notify.erl index 9d0b2e2..72f1324 100644 --- a/src/sd_notify.erl +++ b/src/sd_notify.erl @@ -41,7 +41,7 @@ sd_notifyf(UnsetEnv, Format, Data) -> sd_pid_notifyf(Pid, UnsetEnv, Format, Data) -> sd_pid_notify_with_fds(Pid, UnsetEnv, lists:flatten(io_lib:format(Format, Data)), []). -sd_pid_notify_with_fds(_Pid, _UnsetEnv, Call, _Fds) -> +sd_pid_notify_with_fds(_Pid, UnsetEnv, Call, _Fds) -> error_logger:info_msg("systemd: ~p", [Call]), case os:getenv("NOTIFY_SOCKET") of false -> {error, not_configured}; @@ -52,6 +52,9 @@ sd_pid_notify_with_fds(_Pid, _UnsetEnv, Call, _Fds) -> {ok, Socket} -> Result = gen_udp:send(Socket, {local,Path}, 0, Call), gen_udp:close(Socket), + + UnsetEnv == true andalso os:unsetenv("NOTIFY_SOCKET"), + Result end end. diff --git a/test/sd_notify_test.erl b/test/sd_notify_test.erl index 86766bc..21a9f9d 100644 --- a/test/sd_notify_test.erl +++ b/test/sd_notify_test.erl @@ -2,8 +2,7 @@ -include_lib("eunit/include/eunit.hrl"). - -sd_notify_test_() -> +sd_notify_basic_test_() -> {ok, CWD} = file:get_cwd(), FakeNotifyUnixSockName = CWD ++ "/fake-sock-" ++ integer_to_list(erlang:phash2(make_ref())), {ok, FakeNotifyUnixSock} = gen_udp:open(0, [{ifaddr, {local, FakeNotifyUnixSockName}}, {active, false}, list]), @@ -26,3 +25,28 @@ sd_notify_test_() -> ] }. + +sd_notify_unsetenv_test_() -> + {ok, CWD} = file:get_cwd(), + FakeNotifyUnixSockName = CWD ++ "/fake-sock-" ++ integer_to_list(erlang:phash2(make_ref())), + {ok, FakeNotifyUnixSock} = gen_udp:open(0, [{ifaddr, {local, FakeNotifyUnixSockName}}, {active, false}, list]), + os:putenv("NOTIFY_SOCKET", FakeNotifyUnixSockName), + + {setup, + fun() -> ok end, + fun(_) -> ok = gen_udp:close(FakeNotifyUnixSock), ok = file:delete(FakeNotifyUnixSockName) end, + [ + { + "Try sending message", + fun() -> + TestMessage = integer_to_list(erlang:phash2(make_ref())), + ok = sd_notify:sd_pid_notify_with_fds(0, true, TestMessage, []), + {ok, {_Address, _Port, _Packet}} = gen_udp:recv(FakeNotifyUnixSock, length(TestMessage), 1000), + Ret = os:getenv("NOTIFY_SOCKET"), + ?assertEqual(Ret, false) + end + } + + ] + + }. -- cgit v1.2.1 From 0528181ea4ea54e4db21b6ddccf78d7287e57e85 Mon Sep 17 00:00:00 2001 From: Peter Lemenkov Date: Tue, 7 Jul 2020 13:43:32 +0200 Subject: Add API proposed by Max Lapshin Signed-off-by: Peter Lemenkov --- src/sd_notify.erl | 38 ++++++++++++++++++++++++++++++++++++++ test/sd_notify_test.erl | 24 ++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/src/sd_notify.erl b/src/sd_notify.erl index 72f1324..c0bb824 100644 --- a/src/sd_notify.erl +++ b/src/sd_notify.erl @@ -29,6 +29,44 @@ -export([sd_notify/2, sd_notifyf/3, sd_pid_notify/3, sd_pid_notifyf/4, sd_pid_notify_with_fds/4]). +-export([ready/0, reloading/0, stopping/0, watchdog/0]). +-export([start_link/0]). +-export([init/1, handle_info/2, terminate/2]). + +% API helpers + +ready() -> sd_pid_notify_with_fds(0, false, <<"READY=1">>, []). +reloading() -> sd_pid_notify_with_fds(0, false, <<"RELOADING=1">>, []). +stopping() -> sd_pid_notify_with_fds(0, false, <<"STOPPING=1">>, []). +watchdog() -> sd_pid_notify_with_fds(0, false, <<"WATCHDOG=1">>, []). + +% gen_server API and callbacks + +start_link() -> + gen_server:start_link({local,?MODULE}, ?MODULE, [], []). + +init([]) -> + WatchdogMs = case os:getenv( "WATCHDOG_USEC" ) of + false -> none; + Value -> + Part = erlang:round(0.8 * erlang:list_to_integer(Value)), + erlang:convert_time_unit(Part, microsecond, millisecond) + end, + erlang:send_after(WatchdogMs, self(), watchdog), + error_logger:info_msg("watchdog: ~p ms", [WatchdogMs]), + {ok, WatchdogMs}. + +handle_info(watchdog, none) -> + {noreply, none}; +handle_info(watchdog, WatchdogMs) -> + watchdog(), + erlang:send_after(WatchdogMs, self(), watchdog), + {noreply, WatchdogMs}. + +terminate(_,_) -> ok. + +% Systemd API + sd_notify(UnsetEnv, Data) -> sd_pid_notify_with_fds(0, UnsetEnv, Data, []). diff --git a/test/sd_notify_test.erl b/test/sd_notify_test.erl index 21a9f9d..59df682 100644 --- a/test/sd_notify_test.erl +++ b/test/sd_notify_test.erl @@ -50,3 +50,27 @@ sd_notify_unsetenv_test_() -> ] }. + +sd_notify_watchdog_test_() -> + {ok, CWD} = file:get_cwd(), + FakeNotifyUnixSockName = CWD ++ "/fake-sock-" ++ integer_to_list(erlang:phash2(make_ref())), + {ok, FakeNotifyUnixSock} = gen_udp:open(0, [{ifaddr, {local, FakeNotifyUnixSockName}}, {active, false}, list]), + os:putenv("NOTIFY_SOCKET", FakeNotifyUnixSockName), + + {setup, + fun() -> ok end, + fun(_) -> ok = gen_udp:close(FakeNotifyUnixSock), ok = file:delete(FakeNotifyUnixSockName) end, + [ + { + "Try sending message", + fun() -> + os:putenv("WATCHDOG_USEC", "500000"), + sd_notify:start_link(), + {ok, {_Address, _Port, Packet}} = gen_udp:recv(FakeNotifyUnixSock, length("WATCHDOG=1"), 1000), + ?assertEqual("WATCHDOG=1", Packet) + end + } + + ] + + }. -- cgit v1.2.1