Skip to content

Commit

Permalink
Support setting build options via environment
Browse files Browse the repository at this point in the history
Allow for overriding the build.config settings using environment
variables (of the same name, but upper-case).
  • Loading branch information
weiss committed Jul 25, 2023
1 parent fa483dc commit cc25bb0
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 13 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
/doc/*.html
/index.html
/.make-binary.*/
/.build.config
#
# ExDoc:
#
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ project adheres to [Semantic Versioning][SemVer].

## [Unreleased]
### Added
- Allow for overriding the `build.config` settings using environment variables
(of the same name, but upper-case).
- Docker: Container images can now be pulled from Dockerhub as well. The name
is `docker.io/eturnal/eturnal:latest`. When pulling with `Docker`, `docker.io`
may be omitted.
Expand Down
5 changes: 3 additions & 2 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ and `openssl-devel`.
This generates the archive file `_build/prod/rel/eturnal/eturnal-1.10.1.tar.gz`.
The default installation prefix is set to `/opt/eturnal`, and it's assumed the
server will be executed by a user named `eturnal`. To change these defaults,
edit the [build.config][7] file, re-run `./rebar3 as prod tar`, and adapt the
following installation instructions accordingly.
edit the [build.config][7] file or override the settings using environment
variables (of the same name, but upper-case), re-run `./rebar3 as prod tar`, and
adapt the following installation instructions accordingly.

## Quick Test

Expand Down
4 changes: 3 additions & 1 deletion PACKAGING.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ The `eturnal_prefix` option in the [build.config][7] file must be set to that
location before building eturnal. The user for running eturnal can be adjusted
in that file as well. Apart from that, you might want to set the `code_loading`
option to `"dynamic"`, as that avoids hard-coding of Erlang dependency versions
at build time.
at build time. If patching that file is not desirable, the settings may be
overridden using environment variables (of the same name, but upper-case)
instead.

The `bin` directory contains, among other things, the [eturnalctl][8] script,
which can be moved (or symlinked) elsewhere (e.g., into `/usr/sbin`). If it's
Expand Down
3 changes: 3 additions & 0 deletions build.config
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
%%% eturnal build configuration.
%%%
%%% Note that these settings may be overridden using environment variables of
%%% the same name, but upper-case.

{eturnal_user, "eturnal"}. % The user running eturnal.
{eturnal_prefix, "/opt/eturnal"}. % The installation directory.
Expand Down
83 changes: 73 additions & 10 deletions rebar.config.script
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
% For each profile with a 'relx' configuration specified in the rebar.config
% file, generate three additional profiles. E.g., for the 'prod' profile:
%
% - The 'prod_minimal' excludes non-essential dependencies.
% - The 'prod_cross' profile includes ERTS and system libraries from the
% "lib/erlang" directory (for cross compilation).
% - The 'prod_cross_minimal' does both.
%%% eturnal STUN/TURN server.
%%%
%%% Copyright (c) 2020-2023 Holger Weiss <holger@zedat.fu-berlin.de>.
%%% Copyright (c) 2020-2023 ProcessOne, SARL.
%%% All rights reserved.
%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
%%%
%%% http://www.apache.org/licenses/LICENSE-2.0
%%%
%%% Unless required by applicable law or agreed to in writing, software
%%% distributed under the License is distributed on an "AS IS" BASIS,
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.

Find =
fun(K, L) ->
Expand All @@ -26,9 +36,61 @@ AddSuffix =
list_to_atom(atom_to_list(N) ++ [$_ | atom_to_list(S)])
end,

%% If any of the build.conf settings are overridden via environment variables,
%% create a .build.config file and point Relx to that one.

{ok, OldSettings} = file:consult("build.config"),

NewSettings =
lists:map(
fun({K, V}) ->
EnvKey = string:uppercase(atom_to_list(K)),
case os:getenv(EnvKey) of
EnvVal when is_list(EnvVal) ->
{K, EnvVal};
false ->
{K, V}
end
end, OldSettings),

OldOverlayVars = "build.config",
NewOverlayVars = ".build.config",

OverlayVars =
case {lists:sort(OldSettings), lists:sort(NewSettings)} of
{Settings, Settings} ->
_ = file:delete(NewOverlayVars),
OldOverlayVars;
{_, _} ->
NewData = [io_lib:format("~p.~n", [S]) || S <- NewSettings],
ok = file:write_file(NewOverlayVars, NewData),
NewOverlayVars
end,

{profiles, Profiles} = Find(profiles, CONFIG),

Profiles1 =
lists:map(
fun({ProfName, ProfOpts} = Profile) ->
case Find(relx, ProfOpts) of
{relx, RelxOpts} ->
RelxOpts1 = Store(overlay_vars, OverlayVars, RelxOpts),
ProfOpts1 = Store(relx, RelxOpts1, ProfOpts),
{ProfName, ProfOpts1};
false ->
Profile
end
end, Profiles),

%% For each profile with a 'relx' configuration specified in the rebar.config
%% file, generate three additional profiles. E.g., for the 'prod' profile:
%%
%% - The 'prod_minimal' excludes non-essential dependencies.
%% - The 'prod_cross' profile includes ERTS and system libraries from the
%% "lib/erlang" directory (for cross compilation).
%% - The 'prod_cross_minimal' does both.

Profiles2 =
lists:flatmap(
fun({ProfName, ProfOpts} = Profile) ->
case Find(relx, ProfOpts) of
Expand Down Expand Up @@ -58,11 +120,12 @@ Profiles1 =
false ->
[Profile]
end
end, Profiles),
end, Profiles1),

Config1 = Store(profiles, Profiles1, CONFIG),
Config1 = Store(profiles, Profiles2, CONFIG),

% Remove the rebar.lock file and set SKIP_DEPS=true to skip dependency handling.
%% Remove the rebar.lock file and set SKIP_DEPS=true to skip dependency
%% handling.

case os:getenv("SKIP_DEPS") of
"true" ->
Expand Down

0 comments on commit cc25bb0

Please sign in to comment.