Compare commits
106 Commits
Author | SHA1 | Date |
---|---|---|
![]() |
23d72b334e | |
![]() |
0f57fb9599 | |
![]() |
5d31c7eb6b | |
![]() |
44446bb762 | |
![]() |
c5241670e0 | |
![]() |
f936aba6b7 | |
![]() |
295b1312be | |
![]() |
c6ea575d35 | |
![]() |
36fd7369e0 | |
![]() |
2b46e16d74 | |
![]() |
7a4edc0104 | |
![]() |
c1b737a9b2 | |
![]() |
2ded7fbe8c | |
![]() |
4eb966549e | |
![]() |
70491aee07 | |
![]() |
bc99d5c1a6 | |
![]() |
fdf439bc7b | |
![]() |
d796f815d7 | |
![]() |
b8de05891e | |
![]() |
74b63f7d68 | |
![]() |
2def7e4ac2 | |
![]() |
ddcf73f465 | |
![]() |
cc5b995cf2 | |
![]() |
ab201625c3 | |
![]() |
1c144d7d67 | |
![]() |
92d5f4b3b2 | |
![]() |
54223e4fe6 | |
![]() |
0531a1925c | |
![]() |
1b56fba471 | |
![]() |
147e2e911f | |
![]() |
1d24e46ece | |
![]() |
d78fbc5a8a | |
![]() |
595598916f | |
![]() |
cde614aad8 | |
![]() |
7364e821b8 | |
![]() |
2b7e93f55f | |
![]() |
b0e579fcd8 | |
![]() |
15205942e0 | |
![]() |
c9a0c37dbb | |
![]() |
d2fc66f436 | |
![]() |
6697b9fa42 | |
![]() |
2f2a093150 | |
![]() |
efca545d3d | |
![]() |
1c22c0d596 | |
![]() |
c0364ad5a2 | |
![]() |
6d9b3ed341 | |
![]() |
494bac419d | |
![]() |
835539364e | |
![]() |
4b8bd8e562 | |
![]() |
fc1e4893a8 | |
![]() |
257bc353a4 | |
![]() |
0d38b75bb2 | |
![]() |
6ef68f8e2c | |
![]() |
fca7fd755d | |
![]() |
760d896d9d | |
![]() |
69126fede6 | |
![]() |
887544c3c1 | |
![]() |
d224687de2 | |
![]() |
e182a5f38c | |
![]() |
1a473bb73b | |
![]() |
3e8b9ff76a | |
![]() |
22858eb845 | |
![]() |
814623edae | |
![]() |
75c9267473 | |
![]() |
ae71bdc0fe | |
![]() |
fd482e2ec0 | |
![]() |
591b704f65 | |
![]() |
dbe45d9d6f | |
![]() |
783a10c5a1 | |
![]() |
6a4b437446 | |
![]() |
d0b54ac365 | |
![]() |
b76334ea01 | |
![]() |
0312f07b11 | |
![]() |
93532615c1 | |
![]() |
2d25e895a8 | |
![]() |
f20d5b5395 | |
![]() |
ddb79f51ae | |
![]() |
7e2c035562 | |
![]() |
df1cbb0bab | |
![]() |
e3437d5b9e | |
![]() |
c14319e5bd | |
![]() |
188f44ad50 | |
![]() |
13e146d1ee | |
![]() |
5e812a1add | |
![]() |
7a7cccb337 | |
![]() |
69673613d6 | |
![]() |
22b2a3902e | |
![]() |
1ef7f4e2a0 | |
![]() |
5dd7f53662 | |
![]() |
19e92d7936 | |
![]() |
3c4430c252 | |
![]() |
2c6e8204b8 | |
![]() |
e4eeb585cb | |
![]() |
25f03ed87a | |
![]() |
d33465052f | |
![]() |
bd3760d5c7 | |
![]() |
4c1e03bbcd | |
![]() |
ef4c30b2fd | |
![]() |
9fc635826c | |
![]() |
e83217fb09 | |
![]() |
6905eb4ac1 | |
![]() |
c940ab9e0a | |
![]() |
e40148a6dd | |
![]() |
ba002bb1b5 | |
![]() |
ed34783dd7 | |
![]() |
8ec83705ad |
|
@ -0,0 +1,5 @@
|
|||
# Used by "mix format"
|
||||
[
|
||||
inputs: ["mix.exs", "config/*.exs"],
|
||||
subdirectories: ["apps/*"]
|
||||
]
|
|
@ -0,0 +1,4 @@
|
|||
# Used by "mix format"
|
||||
[
|
||||
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
|
||||
]
|
|
@ -0,0 +1,42 @@
|
|||
defmodule EMQX.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx,
|
||||
version: "5.0.0",
|
||||
build_path: "../../_build",
|
||||
config_path: "../../config/config.exs",
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.12",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps(),
|
||||
description: "EMQ X"
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[
|
||||
mod: {:emqx_app, []},
|
||||
extra_applications: [:logger, :os_mon, :syntax_tools]
|
||||
]
|
||||
end
|
||||
|
||||
defp deps do
|
||||
[
|
||||
{:gproc, "0.9.0"},
|
||||
{:recon, "2.5.2"},
|
||||
{:cowboy, github: "emqx/cowboy", tag: "2.8.2"},
|
||||
{:esockd, github: "emqx/esockd", tag: "5.8.0"},
|
||||
{:ekka, github: "emqx/ekka", tag: "0.11.1"},
|
||||
{:gen_rpc, github: "emqx/gen_rpc", tag: "2.5.1"},
|
||||
{:cuttlefish, github: "emqx/cuttlefish", tag: "v4.0.1"},
|
||||
{:hocon, github: "emqx/hocon"},
|
||||
{:pbkdf2, github: "emqx/erlang-pbkdf2", tag: "2.0.4"},
|
||||
{:snabbkaffe, github: "kafka4beam/snabbkaffe", tag: "0.14.0"},
|
||||
{:jiffy, github: "emqx/jiffy", tag: "1.0.5"},
|
||||
{:lc, github: "qzhuyan/lc", tag: "0.1.1"}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -22,7 +22,6 @@
|
|||
-include("logger.hrl").
|
||||
-include_lib("lc/include/lc.hrl").
|
||||
|
||||
|
||||
%% gen_event callbacks
|
||||
-export([ init/1
|
||||
, handle_event/2
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
# Used by "mix format"
|
||||
[
|
||||
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
|
||||
]
|
|
@ -0,0 +1,38 @@
|
|||
defmodule EMQXAuthn.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_authn,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
config_path: "../../config/config.exs",
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.12",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps(),
|
||||
description: "EMQ X Authentication"
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[
|
||||
registered: [:emqx_authn_sup, :emqx_authn_registry],
|
||||
mod: {:emqx_authn_app, []},
|
||||
extra_applications: [:logger]
|
||||
]
|
||||
end
|
||||
|
||||
defp deps do
|
||||
[
|
||||
{:emqx, in_umbrella: true, runtime: false},
|
||||
{:emqx_resource, in_umbrella: true},
|
||||
{:emqx_http_lib, github: "emqx/emqx_http_lib", tag: "0.2.1"},
|
||||
{:esasl, github: "emqx/esasl", tag: "0.1.0"},
|
||||
{:epgsql, github: "epgsql/epgsql", tag: "4.4.0"},
|
||||
{:mysql, github: "emqx/mysql-otp", tag: "1.7.1"},
|
||||
{:jose, "1.11.2"}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,4 @@
|
|||
# Used by "mix format"
|
||||
[
|
||||
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
|
||||
]
|
|
@ -0,0 +1,29 @@
|
|||
defmodule EMQXAuthz.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_authz,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
config_path: "../../config/config.exs",
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.12",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[
|
||||
extra_applications: [:logger]
|
||||
]
|
||||
end
|
||||
|
||||
defp deps do
|
||||
[
|
||||
{:emqx_connector, in_umbrella: true}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,32 @@
|
|||
defmodule EMQXAutoSubscribe.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_auto_subscribe,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
config_path: "../../config/config.exs",
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.12",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps(),
|
||||
description: "EMQ X Auto Subscribe"
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[
|
||||
registered: [],
|
||||
mod: {:emqx_auto_subscribe_app, []},
|
||||
extra_applications: [:logger]
|
||||
]
|
||||
end
|
||||
|
||||
defp deps do
|
||||
[
|
||||
{:emqx, in_umbrella: true, runtime: false}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,33 @@
|
|||
defmodule EMQXBridge.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_bridge,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
config_path: "../../config/config.exs",
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.12",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps(),
|
||||
description: "EMQ X Bridge"
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[
|
||||
registered: [],
|
||||
mod: {:emqx_bridge_app, []},
|
||||
extra_applications: [:logger]
|
||||
]
|
||||
end
|
||||
|
||||
defp deps do
|
||||
[
|
||||
{:emqx, in_umbrella: true, runtime: false},
|
||||
{:emqx_connector, in_umbrella: true}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,32 @@
|
|||
defmodule EMQXConf.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_conf,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
config_path: "../../config/config.exs",
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.12",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps(),
|
||||
description: "EMQ X Configuration Management"
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[
|
||||
mod: {:emqx_conf_app, []},
|
||||
extra_applications: [:logger, :os_mon, :syntax_tools]
|
||||
]
|
||||
end
|
||||
|
||||
defp deps do
|
||||
[
|
||||
{:emqx, in_umbrella: true, runtime: false},
|
||||
{:hocon, github: "emqx/hocon"}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,4 @@
|
|||
# Used by "mix format"
|
||||
[
|
||||
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
|
||||
]
|
|
@ -0,0 +1,33 @@
|
|||
defmodule EMQXConnector.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_connector,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
config_path: "../../config/config.exs",
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.12",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[
|
||||
mod: {:emqx_connector_app, []},
|
||||
extra_applications: [:logger]
|
||||
]
|
||||
end
|
||||
|
||||
defp deps do
|
||||
[
|
||||
{:emqx_resource, in_umbrella: true},
|
||||
{:mysql, github: "emqx/mysql-otp", tag: "1.7.1"},
|
||||
{:ecpool, github: "emqx/ecpool", tag: "0.5.1"},
|
||||
{:emqtt, github: "emqx/emqtt", tag: "1.4.3"}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,4 @@
|
|||
# Used by "mix format"
|
||||
[
|
||||
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
|
||||
]
|
|
@ -0,0 +1,33 @@
|
|||
defmodule EMQXDashboard.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_dashboard,
|
||||
version: "4.4.0",
|
||||
build_path: "../../_build",
|
||||
config_path: "../../config/config.exs",
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.12",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps(),
|
||||
description: "EMQ X Web Dashboard"
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[
|
||||
registered: [:emqx_dashboard_sup],
|
||||
mod: {:emqx_dashboard_app, []},
|
||||
extra_applications: [:logger]
|
||||
]
|
||||
end
|
||||
|
||||
defp deps do
|
||||
[
|
||||
{:emqx, in_umbrella: true, runtime: false},
|
||||
{:minirest, github: "emqx/minirest", tag: "1.2.4"}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,59 @@
|
|||
defmodule EMQXExhook.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_exhook,
|
||||
version: "5.0.0",
|
||||
build_path: "../../_build",
|
||||
config_path: "../../config/config.exs",
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.12",
|
||||
compilers: [:protos | Mix.compilers()],
|
||||
aliases: ["compile.protos": &protos/1],
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps(),
|
||||
description: "EMQ X Extension for Hook"
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[
|
||||
registered: [],
|
||||
mod: {:emqx_exhook_app, []},
|
||||
extra_applications: [:logger]
|
||||
]
|
||||
end
|
||||
|
||||
defp deps do
|
||||
[
|
||||
{:emqx, in_umbrella: true, runtime: false},
|
||||
{:grpc, github: "emqx/grpc-erl", tag: "0.6.2"}
|
||||
]
|
||||
end
|
||||
|
||||
defp protos(_args) do
|
||||
app_path = Path.expand("..", __ENV__.file)
|
||||
config = [
|
||||
:use_packages,
|
||||
:maps,
|
||||
:strings_as_binaries,
|
||||
rename: {:msg_name, :snake_case},
|
||||
rename: {:msg_fqname, :base_name},
|
||||
i: '.',
|
||||
report_errors: false,
|
||||
o: app_path |> Path.join("src") |> to_charlist(),
|
||||
module_name_prefix: 'emqx_',
|
||||
module_name_suffix: '_pb'
|
||||
]
|
||||
|
||||
app_path
|
||||
|> Path.join("priv/protos/*.proto")
|
||||
|> Path.wildcard()
|
||||
|> Enum.map(&to_charlist/1)
|
||||
|> Enum.each(&:gpb_compile.file(&1, config))
|
||||
|
||||
:ok
|
||||
end
|
||||
end
|
|
@ -0,0 +1,4 @@
|
|||
# Used by "mix format"
|
||||
[
|
||||
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
|
||||
]
|
|
@ -0,0 +1,62 @@
|
|||
defmodule EMQXGateway.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_gateway,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
config_path: "../../config/config.exs",
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.12",
|
||||
compilers: [:protos | Mix.compilers()],
|
||||
aliases: ["compile.protos": &protos/1],
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps(),
|
||||
description: "The Gateway Management Application"
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[
|
||||
registered: [],
|
||||
mod: {:emqx_gateway_app, []},
|
||||
extra_applications: [:logger]
|
||||
]
|
||||
end
|
||||
|
||||
defp protos(_args) do
|
||||
app_path = Path.expand("..", __ENV__.file)
|
||||
config = [
|
||||
:use_packages,
|
||||
:maps,
|
||||
:strings_as_binaries,
|
||||
rename: {:msg_name, :snake_case},
|
||||
rename: {:msg_fqname, :base_name},
|
||||
i: '.',
|
||||
report_errors: false,
|
||||
o: app_path |> Path.join("src/exproto") |> to_charlist(),
|
||||
module_name_prefix: 'emqx_',
|
||||
module_name_suffix: '_pb'
|
||||
]
|
||||
|
||||
app_path
|
||||
|> Path.join("src/exproto/protos/*.proto")
|
||||
|> Path.wildcard()
|
||||
|> Enum.map(&to_charlist/1)
|
||||
|> Enum.each(&:gpb_compile.file(&1, config))
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
defp deps do
|
||||
[
|
||||
{:gpb, "4.19.1", runtime: false},
|
||||
{:emqx, in_umbrella: true},
|
||||
{:lwm2m_coap, github: "emqx/lwm2m-coap", tag: "v2.0.0"},
|
||||
{:grpc, github: "emqx/grpc-erl", tag: "0.6.2"},
|
||||
{:esockd, github: "emqx/esockd", tag: "5.7.4"}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
-behaviour(minirest_api).
|
||||
|
||||
-include_lib("emqx_gateway/src/coap/include/emqx_coap.hrl").
|
||||
-include("emqx_coap.hrl").
|
||||
|
||||
%% API
|
||||
-export([api_spec/0]).
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
-behaviour(emqx_gateway_channel).
|
||||
|
||||
-include_lib("emqx/include/logger.hrl").
|
||||
-include_lib("emqx_gateway/src/coap/include/emqx_coap.hrl").
|
||||
-include("emqx_coap.hrl").
|
||||
|
||||
%% API
|
||||
-export([ info/1
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
%% API
|
||||
-export([]).
|
||||
|
||||
-include("include/emqx_coap.hrl").
|
||||
-include("apps/emqx/include/types.hrl").
|
||||
-include_lib("emqx/include/types.hrl").
|
||||
-include("emqx_coap.hrl").
|
||||
|
||||
-define(VERSION, 1).
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
-module(emqx_coap_medium).
|
||||
|
||||
-include_lib("emqx_gateway/src/coap/include/emqx_coap.hrl").
|
||||
-include("emqx_coap.hrl").
|
||||
|
||||
%% API
|
||||
-export([ empty/0, reset/1, reset/2
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
-export([ set/3, set_payload/2, get_option/2
|
||||
, get_option/3, set_payload_block/3, set_payload_block/4]).
|
||||
|
||||
-include_lib("emqx_gateway/src/coap/include/emqx_coap.hrl").
|
||||
-include("emqx_coap.hrl").
|
||||
|
||||
request(Type, Method) ->
|
||||
request(Type, Method, <<>>, []).
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
-include_lib("emqx/include/emqx.hrl").
|
||||
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||
-include_lib("emqx/include/logger.hrl").
|
||||
-include_lib("emqx_gateway/src/coap/include/emqx_coap.hrl").
|
||||
-include("emqx_coap.hrl").
|
||||
|
||||
%% API
|
||||
-export([ new/0
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
-export_type([manager/0, event_result/1]).
|
||||
|
||||
-include_lib("emqx/include/logger.hrl").
|
||||
-include_lib("emqx_gateway/src/coap/include/emqx_coap.hrl").
|
||||
-include("emqx_coap.hrl").
|
||||
|
||||
-type direction() :: in | out.
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
-module(emqx_coap_transport).
|
||||
|
||||
-include_lib("emqx/include/logger.hrl").
|
||||
-include_lib("emqx_gateway/src/coap/include/emqx_coap.hrl").
|
||||
-include("emqx_coap.hrl").
|
||||
|
||||
-define(ACK_TIMEOUT, 2000).
|
||||
-define(ACK_RANDOM_FACTOR, 1000).
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
-module(emqx_coap_mqtt_handler).
|
||||
|
||||
-include_lib("emqx_gateway/src/coap/include/emqx_coap.hrl").
|
||||
-include("emqx_coap.hrl").
|
||||
|
||||
-export([handle_request/4]).
|
||||
-import(emqx_coap_message, [response/2, response/3]).
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
-module(emqx_coap_pubsub_handler).
|
||||
|
||||
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||
-include_lib("emqx_gateway/src/coap/include/emqx_coap.hrl").
|
||||
-include("emqx_coap.hrl").
|
||||
|
||||
-export([handle_request/4]).
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
%%--------------------------------------------------------------------
|
||||
|
||||
-module(emqx_exproto_channel).
|
||||
-include("src/exproto/include/emqx_exproto.hrl").
|
||||
-include("emqx_exproto.hrl").
|
||||
-include_lib("emqx/include/emqx.hrl").
|
||||
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||
-include_lib("emqx/include/types.hrl").
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
% -behaviour(emqx_exproto_v_1_connection_adapter_bhvr).
|
||||
|
||||
-include("src/exproto/include/emqx_exproto.hrl").
|
||||
-include("emqx_exproto.hrl").
|
||||
-include_lib("emqx/include/logger.hrl").
|
||||
|
||||
-define(IS_QOS(X), (X =:= 0 orelse X =:= 1 orelse X =:= 2)).
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
-module(emqx_lwm2m_channel).
|
||||
|
||||
-include_lib("emqx/include/logger.hrl").
|
||||
-include_lib("emqx_gateway/src/coap/include/emqx_coap.hrl").
|
||||
-include_lib("emqx_gateway/src/lwm2m/include/emqx_lwm2m.hrl").
|
||||
-include("emqx_coap.hrl").
|
||||
-include("emqx_lwm2m.hrl").
|
||||
|
||||
%% API
|
||||
-export([ info/1
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
-module(emqx_lwm2m_cmd).
|
||||
|
||||
-include_lib("emqx/include/logger.hrl").
|
||||
-include_lib("emqx_gateway/src/coap/include/emqx_coap.hrl").
|
||||
-include_lib("emqx_gateway/src/lwm2m/include/emqx_lwm2m.hrl").
|
||||
-include("emqx_coap.hrl").
|
||||
-include("emqx_lwm2m.hrl").
|
||||
|
||||
-export([ mqtt_to_coap/2
|
||||
, coap_to_mqtt/4
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
, translate_json/1
|
||||
]).
|
||||
|
||||
-include("src/lwm2m/include/emqx_lwm2m.hrl").
|
||||
-include("emqx_lwm2m.hrl").
|
||||
|
||||
tlv_to_json(BaseName, TlvData) ->
|
||||
DecodedTlv = emqx_lwm2m_tlv:parse(TlvData),
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
-include_lib("emqx/include/logger.hrl").
|
||||
-include_lib("emqx/include/emqx.hrl").
|
||||
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||
-include_lib("emqx_gateway/src/coap/include/emqx_coap.hrl").
|
||||
-include_lib("emqx_gateway/src/lwm2m/include/emqx_lwm2m.hrl").
|
||||
-include("emqx_coap.hrl").
|
||||
-include("emqx_lwm2m.hrl").
|
||||
|
||||
%% API
|
||||
-export([ new/0, init/4, update/3, parse_object_list/1
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
-export([binary_to_hex_string/1]).
|
||||
-endif.
|
||||
|
||||
-include("src/lwm2m/include/emqx_lwm2m.hrl").
|
||||
-include("emqx_lwm2m.hrl").
|
||||
|
||||
-define(TLV_TYPE_OBJECT_INSTANCE, 0).
|
||||
-define(TLV_TYPE_RESOURCE_INSTANCE, 1).
|
||||
|
@ -158,4 +158,3 @@ encode_value(Value) ->
|
|||
binary_to_hex_string(Data) ->
|
||||
lists:flatten([io_lib:format("~2.16.0B ",[X]) || <<X:8>> <= Data ]).
|
||||
-endif.
|
||||
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
|
||||
-module(emqx_lwm2m_xml_object).
|
||||
|
||||
-include_lib("emqx_gateway/src/lwm2m/include/emqx_lwm2m.hrl").
|
||||
-include_lib("xmerl/include/xmerl.hrl").
|
||||
-include("emqx_lwm2m.hrl").
|
||||
|
||||
-export([ get_obj_def/2
|
||||
, get_object_id/1
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
|
||||
-module(emqx_lwm2m_xml_object_db).
|
||||
|
||||
-include_lib("emqx_gateway/src/lwm2m/include/emqx_lwm2m.hrl").
|
||||
-include_lib("xmerl/include/xmerl.hrl").
|
||||
-include_lib("emqx/include/logger.hrl").
|
||||
-include("emqx_lwm2m.hrl").
|
||||
|
||||
% This module is for future use. Disabled now.
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
-behaviour(gen_server).
|
||||
|
||||
-include("src/mqttsn/include/emqx_sn.hrl").
|
||||
-include("emqx_sn.hrl").
|
||||
-include_lib("emqx/include/logger.hrl").
|
||||
|
||||
-export([ start_link/2
|
||||
|
@ -105,4 +105,3 @@ send_advertise(#state{gwid = GwId, sock = Sock, port = Port,
|
|||
boradcast_addrs() ->
|
||||
lists:usort([Addr || {ok, IfList} <- [inet:getiflist()], If <- IfList,
|
||||
{ok, [{broadaddr, Addr}]} <- [inet:ifget(If, [broadaddr])]]).
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
-behaviour(emqx_gateway_channel).
|
||||
|
||||
-include("src/mqttsn/include/emqx_sn.hrl").
|
||||
-include("emqx_sn.hrl").
|
||||
-include_lib("emqx/include/emqx.hrl").
|
||||
-include_lib("emqx/include/emqx_mqtt.hrl").
|
||||
-include_lib("emqx/include/logger.hrl").
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
-behaviour(emqx_gateway_frame).
|
||||
|
||||
-include("src/mqttsn/include/emqx_sn.hrl").
|
||||
-include("emqx_sn.hrl").
|
||||
|
||||
-export([ initial_parse_state/1
|
||||
, serialize_opts/0
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
-behaviour(gen_server).
|
||||
|
||||
-include("src/mqttsn/include/emqx_sn.hrl").
|
||||
-include("emqx_sn.hrl").
|
||||
-include_lib("emqx/include/logger.hrl").
|
||||
|
||||
-export([ start_link/2
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
-behaviour(emqx_gateway_channel).
|
||||
|
||||
-include("src/stomp/include/emqx_stomp.hrl").
|
||||
-include("emqx_stomp.hrl").
|
||||
-include_lib("emqx/include/emqx.hrl").
|
||||
-include_lib("emqx/include/logger.hrl").
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
|
||||
-behaviour(emqx_gateway_frame).
|
||||
|
||||
-include("src/stomp/include/emqx_stomp.hrl").
|
||||
-include("emqx_stomp.hrl").
|
||||
|
||||
-export([ initial_parse_state/1
|
||||
, parse/2
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
%% @doc Stomp heartbeat.
|
||||
-module(emqx_stomp_heartbeat).
|
||||
|
||||
-include("src/stomp/include/emqx_stomp.hrl").
|
||||
-include("emqx_stomp.hrl").
|
||||
|
||||
-export([ init/1
|
||||
, check/3
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
defmodule EMQXLimiter.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_limiter,
|
||||
version: "1.0.0",
|
||||
build_path: "../../_build",
|
||||
config_path: "../../config/config.exs",
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.12",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps(),
|
||||
description: "EMQ X Hierachical Limiter"
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[
|
||||
registered: [:emqx_limiter_sup],
|
||||
mod: {:emqx_limiter_app, []},
|
||||
extra_applications: [:logger]
|
||||
]
|
||||
end
|
||||
|
||||
defp deps do
|
||||
[
|
||||
{:emqx, in_umbrella: true, runtime: false}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,30 @@
|
|||
defmodule EMQXMachine.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_machine,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
config_path: "../../config/config.exs",
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.12",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps(),
|
||||
description: "The EMQ X Machine"
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[
|
||||
registered: [],
|
||||
mod: {:emqx_machine_app, []},
|
||||
extra_applications: [:logger]
|
||||
]
|
||||
end
|
||||
|
||||
defp deps do
|
||||
[]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,4 @@
|
|||
# Used by "mix format"
|
||||
[
|
||||
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
|
||||
]
|
|
@ -0,0 +1,35 @@
|
|||
defmodule EMQXManagement.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_management,
|
||||
version: "4.4.0",
|
||||
build_path: "../../_build",
|
||||
config_path: "../../config/config.exs",
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.12",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps(),
|
||||
description: "EMQ X Management API and CLI"
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[
|
||||
registered: [:emqx_management_sup],
|
||||
mod: {:emqx_mgmt_app, []},
|
||||
extra_applications: [:logger, :syntax_tools]
|
||||
]
|
||||
end
|
||||
|
||||
defp deps do
|
||||
[
|
||||
{:emqx_rule_engine, in_umbrella: true},
|
||||
{:ekka, github: "emqx/ekka", tag: "0.11.1", runtime: false},
|
||||
{:emqx_http_lib, github: "emqx/emqx_http_lib", tag: "0.2.1"},
|
||||
{:minirest, github: "emqx/minirest", tag: "1.2.4"}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,4 @@
|
|||
# Used by "mix format"
|
||||
[
|
||||
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
|
||||
]
|
|
@ -0,0 +1,29 @@
|
|||
defmodule EMQXModules.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_modules,
|
||||
version: "4.3.2",
|
||||
build_path: "../../_build",
|
||||
config_path: "../../config/config.exs",
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.12",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[
|
||||
registered: [:emqx_mod_sup],
|
||||
mod: {:emqx_modules_app, []},
|
||||
extra_applications: [:logger]
|
||||
]
|
||||
end
|
||||
|
||||
defp deps do
|
||||
[]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,4 @@
|
|||
# Used by "mix format"
|
||||
[
|
||||
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
|
||||
]
|
|
@ -0,0 +1,28 @@
|
|||
defmodule EMQXPluginLibs.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_plugin_libs,
|
||||
version: "4.3.1",
|
||||
build_path: "../../_build",
|
||||
config_path: "../../config/config.exs",
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.12",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps(),
|
||||
description: "EMQ X Plugin utility libs"
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[
|
||||
extra_applications: [:logger]
|
||||
]
|
||||
end
|
||||
|
||||
defp deps do
|
||||
[]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,4 @@
|
|||
# Used by "mix format"
|
||||
[
|
||||
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
|
||||
]
|
|
@ -0,0 +1,32 @@
|
|||
defmodule EMQXPrometheus.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_prometheus,
|
||||
version: "4.3.0",
|
||||
build_path: "../../_build",
|
||||
config_path: "../../config/config.exs",
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.12",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps(),
|
||||
description: "Prometheus for EMQ X"
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[
|
||||
registered: [:emqx_prometheus_sup],
|
||||
mod: {:emqx_prometheus_app, []},
|
||||
extra_applications: [:logger]
|
||||
]
|
||||
end
|
||||
|
||||
defp deps do
|
||||
[
|
||||
{:prometheus, github: "emqx/prometheus.erl", tag: "v3.1.1"}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,32 @@
|
|||
defmodule EmqxPSK.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_psk,
|
||||
version: "5.0.0",
|
||||
build_path: "../../_build",
|
||||
config_path: "../../config/config.exs",
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.12",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps(),
|
||||
description: "EMQ X PSK"
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[
|
||||
registered: [:emqx_psk_sup],
|
||||
mod: {:emqx_psk_app, []},
|
||||
extra_applications: [:logger]
|
||||
]
|
||||
end
|
||||
|
||||
defp deps do
|
||||
[
|
||||
{:emqx, in_umbrella: true, runtime: false}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
# Used by "mix format"
|
||||
[
|
||||
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"],
|
||||
locals_without_parens: [
|
||||
start_type: 1,
|
||||
overlay: 1,
|
||||
mkdir: 1,
|
||||
copy: 2,
|
||||
template: 2
|
||||
]
|
||||
]
|
|
@ -0,0 +1,26 @@
|
|||
# The directory Mix will write compiled artifacts to.
|
||||
/_build/
|
||||
|
||||
# If you run "mix test --cover", coverage assets end up here.
|
||||
/cover/
|
||||
|
||||
# The directory Mix downloads your dependencies sources to.
|
||||
/deps/
|
||||
|
||||
# Where third-party dependencies like ExDoc output generated docs.
|
||||
/doc/
|
||||
|
||||
# Ignore .fetch files in case you like to edit your project deps locally.
|
||||
/.fetch
|
||||
|
||||
# If the VM crashes, it generates a dump, let's ignore it too.
|
||||
erl_crash.dump
|
||||
|
||||
# Also ignore archive artifacts (built via "mix archive.build").
|
||||
*.ez
|
||||
|
||||
# Ignore package tarball (built via "mix hex.build").
|
||||
emqx_release_helper-*.tar
|
||||
|
||||
# Temporary files, for example, from tests.
|
||||
/tmp/
|
|
@ -0,0 +1,21 @@
|
|||
# EmqxReleaseHelper
|
||||
|
||||
**TODO: Add description**
|
||||
|
||||
## Installation
|
||||
|
||||
If [available in Hex](https://hex.pm/docs/publish), the package can be installed
|
||||
by adding `emqx_release_helper` to your list of dependencies in `mix.exs`:
|
||||
|
||||
```elixir
|
||||
def deps do
|
||||
[
|
||||
{:emqx_release_helper, "~> 0.1.0"}
|
||||
]
|
||||
end
|
||||
```
|
||||
|
||||
Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
|
||||
and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
|
||||
be found at [https://hexdocs.pm/emqx_release_helper](https://hexdocs.pm/emqx_release_helper).
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
defmodule EmqxReleaseHelper do
|
||||
def applications do
|
||||
config = profile_vars()
|
||||
|
||||
EmqxReleaseHelper.Applications.__all__()
|
||||
|> Enum.filter(fn
|
||||
%{enable?: fun} -> fun.(config)
|
||||
_ -> true
|
||||
end)
|
||||
|> Enum.map(fn %{name: name, start_type: start_type} -> {name, start_type} end)
|
||||
end
|
||||
|
||||
def run(release) do
|
||||
config = Map.merge(profile_vars(), release_vars(release))
|
||||
|
||||
release
|
||||
|> EmqxReleaseHelper.Script.run(config)
|
||||
|> EmqxReleaseHelper.Overlay.run(config)
|
||||
|> EmqxReleaseHelper.Applications.run(config)
|
||||
end
|
||||
|
||||
def profile_vars() do
|
||||
"RELEASE_PROFILE"
|
||||
|> System.get_env("emqx")
|
||||
|> String.to_existing_atom()
|
||||
|> case do
|
||||
:emqx ->
|
||||
%{
|
||||
release_type: :cloud,
|
||||
package_type: :bin
|
||||
}
|
||||
end
|
||||
|> Map.merge(%{
|
||||
erts_vsn: :version |> :erlang.system_info() |> to_string(),
|
||||
project_path: EMQXUmbrella.MixProject.project_path(),
|
||||
enable_bcrypt: EMQXUmbrella.MixProject.enable_bcrypt(),
|
||||
enable_plugin_emqx_modules: false,
|
||||
enable_plugin_emqx_retainer: true,
|
||||
apps_paths: Mix.Project.apps_paths(),
|
||||
built_on_arch: get_arch()
|
||||
})
|
||||
|> then(fn %{release_type: release_type} = config ->
|
||||
Map.merge(config, profile_vars(:release_type, release_type))
|
||||
end)
|
||||
|> then(fn %{package_type: package_type} = config ->
|
||||
Map.merge(config, profile_vars(:package_type, package_type))
|
||||
end)
|
||||
end
|
||||
|
||||
defp profile_vars(:release_type, :cloud) do
|
||||
%{
|
||||
emqx_description: "EMQ X Broker",
|
||||
enable_plugin_emqx_rule_engine: true,
|
||||
enable_plugin_emqx_bridge_mqtt: false
|
||||
}
|
||||
end
|
||||
|
||||
defp profile_vars(:release_type, :edge) do
|
||||
%{
|
||||
emqx_description: "EMQ X Edge",
|
||||
enable_plugin_emqx_rule_engine: false,
|
||||
enable_plugin_emqx_bridge_mqtt: true
|
||||
}
|
||||
end
|
||||
|
||||
defp profile_vars(:package_type, :bin) do
|
||||
%{
|
||||
platform_bin_dir: "bin",
|
||||
platform_data_dir: "data",
|
||||
platform_etc_dir: "etc",
|
||||
platform_lib_dir: "lib",
|
||||
platform_log_dir: "log",
|
||||
platform_plugins_dir: "etc/plugins",
|
||||
runner_root_dir: "$(cd $(dirname $(readlink $0 || echo $0))/..; pwd -P)",
|
||||
runner_bin_dir: "$RUNNER_ROOT_DIR/bin",
|
||||
runner_etc_dir: "$RUNNER_ROOT_DIR/etc",
|
||||
runner_lib_dir: "$RUNNER_ROOT_DIR/lib",
|
||||
runner_log_dir: "$RUNNER_ROOT_DIR/log",
|
||||
runner_data_dir: "$RUNNER_ROOT_DIR/data",
|
||||
runner_user: ""
|
||||
}
|
||||
end
|
||||
|
||||
defp profile_vars(:package_type, :pkg) do
|
||||
%{
|
||||
platform_bin_dir: "",
|
||||
platform_data_dir: "/var/lib/emqx",
|
||||
platform_etc_dir: "/etc/emqx",
|
||||
platform_lib_dir: "",
|
||||
platform_log_dir: "/var/log/emqx",
|
||||
platform_plugins_dir: "/var/lib/emqx/plugins",
|
||||
runner_root_dir: "/usr/lib/emqx",
|
||||
runner_bin_dir: "/usr/bin",
|
||||
runner_etc_dir: "/etc/emqx",
|
||||
runner_lib_dir: "$RUNNER_ROOT_DIR/lib",
|
||||
runner_log_dir: "/var/log/emqx",
|
||||
runner_data_dir: "/var/lib/emqx",
|
||||
runner_user: "emqx"
|
||||
}
|
||||
end
|
||||
|
||||
defp release_vars(release) do
|
||||
%{
|
||||
release_version: release.version,
|
||||
release_path: release.path,
|
||||
release_version_path: release.version_path
|
||||
}
|
||||
end
|
||||
|
||||
defp get_arch do
|
||||
major_version = System.otp_release()
|
||||
|
||||
otp_release =
|
||||
[:code.root_dir(), "releases", major_version, "OTP_VERSION"]
|
||||
|> Path.join()
|
||||
|> File.read()
|
||||
|> case do
|
||||
{:ok, version} -> String.trim(version)
|
||||
{:error, _} -> major_version
|
||||
end
|
||||
|
||||
wordsize =
|
||||
try do
|
||||
:erlang.system_info({:wordsize, :external}) * 8
|
||||
rescue
|
||||
_ ->
|
||||
:erlang.system_info(:wordsize) * 8
|
||||
end
|
||||
|
||||
Enum.join([otp_release, :erlang.system_info(:system_architecture), wordsize], "-")
|
||||
end
|
||||
end
|
|
@ -0,0 +1,138 @@
|
|||
defmodule EmqxReleaseHelper.Applications do
|
||||
use EmqxReleaseHelper.DSL.Application
|
||||
|
||||
application :emqx do
|
||||
start_type :load
|
||||
|
||||
overlay %{release_type: release_type} do
|
||||
copy "etc/certs", "etc/certs"
|
||||
|
||||
template "etc/ssl_dist.conf", "etc/ssl_dist.conf"
|
||||
template "etc/emqx_#{release_type}/vm.args", "etc/vm.args"
|
||||
end
|
||||
end
|
||||
|
||||
application :emqx_conf do
|
||||
start_type :load
|
||||
|
||||
overlay do
|
||||
template "etc/emqx.conf.all", "etc/emqx.conf"
|
||||
end
|
||||
end
|
||||
|
||||
application :lc do
|
||||
start_type :load
|
||||
end
|
||||
|
||||
application :esasl do
|
||||
start_type :load
|
||||
end
|
||||
|
||||
application :mria do
|
||||
start_type :load
|
||||
end
|
||||
|
||||
application :mnesia do
|
||||
start_type :load
|
||||
end
|
||||
|
||||
application :ekka do
|
||||
start_type :load
|
||||
end
|
||||
|
||||
application :emqx_plugin_libs do
|
||||
start_type :load
|
||||
end
|
||||
|
||||
application :emqx_gateway do
|
||||
start_type :load
|
||||
|
||||
overlay do
|
||||
copy "src/lwm2m/lwm2m_xml", "etc/lwm2m_xml"
|
||||
end
|
||||
end
|
||||
|
||||
application :emqx_resource do
|
||||
start_type :load
|
||||
end
|
||||
|
||||
application :emqx_connector do
|
||||
start_type :load
|
||||
end
|
||||
|
||||
application :emqx_bridge do
|
||||
start_type :load
|
||||
end
|
||||
|
||||
application :emqx_authn do
|
||||
start_type :load
|
||||
end
|
||||
|
||||
application :emqx_authz do
|
||||
start_type :load
|
||||
|
||||
overlay do
|
||||
template "etc/acl.conf", "etc/acl.conf"
|
||||
end
|
||||
end
|
||||
|
||||
application :emqx_machine do
|
||||
start_type :permanent
|
||||
end
|
||||
|
||||
application :emqx_auto_subscribe do
|
||||
start_type :permanent
|
||||
end
|
||||
|
||||
application :emqx_exhook do
|
||||
start_type :permanent
|
||||
end
|
||||
|
||||
application :emqx_modules do
|
||||
start_type :permanent
|
||||
end
|
||||
|
||||
application :emqx_dashboard do
|
||||
start_type :permanent
|
||||
end
|
||||
|
||||
application :emqx_management do
|
||||
start_type :permanent
|
||||
end
|
||||
|
||||
application :emqx_statsd do
|
||||
start_type :permanent
|
||||
end
|
||||
|
||||
application :emqx_retainer do
|
||||
start_type :permanent
|
||||
end
|
||||
|
||||
application :emqx_rule_engine do
|
||||
start_type :permanent
|
||||
end
|
||||
|
||||
application :emqx_psk do
|
||||
start_type :permanent
|
||||
end
|
||||
|
||||
application :emqx_limiter do
|
||||
start_type :permanent
|
||||
end
|
||||
|
||||
application :emqx_prometheus do
|
||||
start_type :permanent
|
||||
end
|
||||
|
||||
application :bcrypt, %{enable_bcrypt: true, release_type: :cloud} do
|
||||
start_type :permanent
|
||||
end
|
||||
|
||||
application :xmerl, %{release_type: :cloud} do
|
||||
start_type :permanent
|
||||
end
|
||||
|
||||
application :observer, %{release_type: :cloud} do
|
||||
start_type :load
|
||||
end
|
||||
end
|
|
@ -0,0 +1,83 @@
|
|||
defmodule EmqxReleaseHelper.DSL.Application do
|
||||
defmacro __using__(_) do
|
||||
quote do
|
||||
import unquote(__MODULE__)
|
||||
import EmqxReleaseHelper.DSL.Overlay, only: [
|
||||
overlay: 1,
|
||||
overlay: 2,
|
||||
copy: 2,
|
||||
template: 2
|
||||
]
|
||||
Module.register_attribute(__MODULE__, :applications, accumulate: true)
|
||||
@before_compile unquote(__MODULE__)
|
||||
@overlay_source_path :app_source_path
|
||||
end
|
||||
end
|
||||
|
||||
defmacro application(app, condition, do: block) do
|
||||
func =
|
||||
Macro.escape(
|
||||
quote do
|
||||
fn config -> match?(unquote(condition), config) end
|
||||
end
|
||||
)
|
||||
|
||||
quote do
|
||||
@current_application %{name: unquote(app), enable?: unquote(func)}
|
||||
@overlays []
|
||||
unquote(block)
|
||||
overlays = Enum.reverse(@overlays)
|
||||
@applications Map.put(@current_application, :overlays, overlays)
|
||||
@current_application nil
|
||||
@overlays []
|
||||
end
|
||||
end
|
||||
|
||||
defmacro application(app, do: block) do
|
||||
quote do
|
||||
@current_application %{name: unquote(app)}
|
||||
@overlays []
|
||||
unquote(block)
|
||||
overlays = Enum.reverse(@overlays)
|
||||
@applications Map.put(@current_application, :overlays, overlays)
|
||||
@current_application nil
|
||||
@overlays []
|
||||
end
|
||||
end
|
||||
|
||||
defmacro start_type(type) do
|
||||
quote do
|
||||
@current_application Map.put(@current_application, :start_type, unquote(type))
|
||||
end
|
||||
end
|
||||
|
||||
defmacro __before_compile__(%Macro.Env{module: module}) do
|
||||
block =
|
||||
module
|
||||
|> Module.get_attribute(:applications)
|
||||
|> Enum.reverse()
|
||||
|> Enum.map(fn app -> {:%{}, [], Map.to_list(app)} end)
|
||||
|
||||
quote do
|
||||
def __all__, do: unquote(block)
|
||||
|
||||
def run(release, config) do
|
||||
%{project_path: project_path, apps_paths: apps_paths} = config
|
||||
|
||||
__all__()
|
||||
|> Enum.filter(fn %{name: name} -> Map.has_key?(apps_paths, name) end)
|
||||
|> Enum.filter(fn
|
||||
%{enable?: fun} -> fun.(config)
|
||||
_ -> true
|
||||
end)
|
||||
|> Enum.each(fn %{name: name, overlays: overlays} ->
|
||||
app_path = Map.get(apps_paths, name)
|
||||
config = Map.put(config, :app_source_path, Path.join(project_path, app_path))
|
||||
Enum.each(overlays, fn overlay -> overlay.(config) end)
|
||||
end)
|
||||
|
||||
release
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,132 @@
|
|||
defmodule EmqxReleaseHelper.DSL.Overlay do
|
||||
defmacro __using__(_) do
|
||||
quote do
|
||||
import unquote(__MODULE__)
|
||||
@before_compile unquote(__MODULE__)
|
||||
@overlays []
|
||||
@overlay_source_path :project_path
|
||||
end
|
||||
end
|
||||
|
||||
defmacro overlay(do: block) do
|
||||
block =
|
||||
Macro.escape(
|
||||
quote do
|
||||
fn unquote(Macro.var(:config, nil)) ->
|
||||
unquote(block)
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
quote do
|
||||
@overlays [unquote(block) | @overlays]
|
||||
end
|
||||
end
|
||||
|
||||
defmacro overlay(literal_config, do: block) do
|
||||
block =
|
||||
Macro.escape(
|
||||
quote do
|
||||
fn unquote(literal_config) = unquote(Macro.var(:config, nil)) ->
|
||||
unquote(block)
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
quote do
|
||||
@overlays [unquote(block) | @overlays]
|
||||
end
|
||||
end
|
||||
|
||||
defmacro mkdir(path) do
|
||||
path =
|
||||
quote do
|
||||
unquote(Macro.var(:config, nil))
|
||||
|> Map.get(:release_path)
|
||||
|> Path.join(unquote(path))
|
||||
end
|
||||
|
||||
quote do
|
||||
run_mkdir(unquote(path))
|
||||
end
|
||||
end
|
||||
|
||||
defmacro copy(from_path, to_path) do
|
||||
from_path =
|
||||
quote do
|
||||
unquote(Macro.var(:config, nil))
|
||||
|> Map.get(@overlay_source_path)
|
||||
|> Path.join(unquote(from_path))
|
||||
end
|
||||
|
||||
to_path =
|
||||
quote do
|
||||
unquote(Macro.var(:config, nil))
|
||||
|> Map.get(:release_path)
|
||||
|> Path.join(unquote(to_path))
|
||||
end
|
||||
|
||||
quote do
|
||||
unquote(__MODULE__).run_copy(unquote(from_path), unquote(to_path))
|
||||
end
|
||||
end
|
||||
|
||||
defmacro template(from_path, to_path) do
|
||||
from_path =
|
||||
quote do
|
||||
unquote(Macro.var(:config, nil))
|
||||
|> Map.get(@overlay_source_path)
|
||||
|> Path.join(unquote(from_path))
|
||||
end
|
||||
|
||||
to_path =
|
||||
quote do
|
||||
unquote(Macro.var(:config, nil))
|
||||
|> Map.get(:release_path)
|
||||
|> Path.join(unquote(to_path))
|
||||
end
|
||||
|
||||
quote do
|
||||
unquote(__MODULE__).run_template(
|
||||
unquote(from_path),
|
||||
unquote(to_path),
|
||||
unquote(Macro.var(:config, nil))
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def run_mkdir(path) do
|
||||
File.mkdir_p!(path)
|
||||
end
|
||||
|
||||
def run_copy(from_path, to_path) do
|
||||
to_path |> Path.dirname() |> File.mkdir_p!()
|
||||
File.cp_r!(from_path, to_path)
|
||||
end
|
||||
|
||||
def run_template(from_path, to_path, config) do
|
||||
config = Enum.map(config, fn {key, value} -> {to_charlist(key), value} end)
|
||||
to_path |> Path.dirname() |> File.mkdir_p!()
|
||||
|
||||
content =
|
||||
from_path
|
||||
|> File.read!()
|
||||
|> :bbmustache.render(config)
|
||||
|
||||
File.write!(to_path, content)
|
||||
end
|
||||
|
||||
defmacro __before_compile__(%Macro.Env{module: module}) do
|
||||
block =
|
||||
module
|
||||
|> Module.get_attribute(:overlays)
|
||||
|> Enum.reverse()
|
||||
|
||||
quote do
|
||||
def run(release, config) do
|
||||
Enum.each(unquote(block), fn overlay -> overlay.(config) end)
|
||||
release
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,21 @@
|
|||
defmodule EmqxReleaseHelper.Overlay do
|
||||
use EmqxReleaseHelper.DSL.Overlay
|
||||
|
||||
overlay %{release_version: release_version} do
|
||||
mkdir "log"
|
||||
mkdir "etc"
|
||||
mkdir "data"
|
||||
mkdir "data/mnesia"
|
||||
mkdir "data/configs"
|
||||
mkdir "data/patches"
|
||||
mkdir "data/scripts"
|
||||
|
||||
copy "bin/install_upgrade.escript", "bin/install_upgrade.escript"
|
||||
|
||||
copy "bin/node_dump", "bin/node_dump"
|
||||
copy "bin/emqx_ctl", "bin/emqx_ctl"
|
||||
|
||||
template "data/emqx_vars", "releases/emqx_vars"
|
||||
template "data/BUILT_ON", "releases/#{release_version}/BUILT_ON"
|
||||
end
|
||||
end
|
|
@ -0,0 +1,17 @@
|
|||
defmodule EmqxReleaseHelper.Script do
|
||||
def run(release, config) do
|
||||
script_path = Path.join(config.project_path, "scripts")
|
||||
|
||||
{_, 0} =
|
||||
script_path
|
||||
|> Path.join("merge-config.escript")
|
||||
|> System.cmd([])
|
||||
|
||||
{_, 0} =
|
||||
script_path
|
||||
|> Path.join("get-dashboard.sh")
|
||||
|> System.cmd([], env: [{"EMQX_DASHBOARD_VERSION", "v5.0.0-beta.13"}])
|
||||
|
||||
release
|
||||
end
|
||||
end
|
|
@ -0,0 +1,29 @@
|
|||
defmodule EMQXReleaseHelper.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_release_helper,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
config_path: "../../config/config.exs",
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.12",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[
|
||||
extra_applications: [:logger]
|
||||
]
|
||||
end
|
||||
|
||||
defp deps do
|
||||
[
|
||||
{:bbmustache, "1.12.1"}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,8 @@
|
|||
defmodule EmqxReleaseHelperTest do
|
||||
use ExUnit.Case
|
||||
doctest EmqxReleaseHelper
|
||||
|
||||
test "greets the world" do
|
||||
assert EmqxReleaseHelper.hello() == :world
|
||||
end
|
||||
end
|
|
@ -0,0 +1 @@
|
|||
ExUnit.start()
|
|
@ -0,0 +1,4 @@
|
|||
# Used by "mix format"
|
||||
[
|
||||
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
|
||||
]
|
|
@ -0,0 +1,33 @@
|
|||
defmodule EMQXResource.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_resource,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
config_path: "../../config/config.exs",
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.12",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[
|
||||
mod: {:emqx_resource_app, []},
|
||||
extra_applications: [:logger, :syntax_tools]
|
||||
]
|
||||
end
|
||||
|
||||
defp deps do
|
||||
[
|
||||
{:jsx, "3.1.0"},
|
||||
{:gproc, "0.9.0"},
|
||||
{:hocon, github: "emqx/hocon"},
|
||||
{:emqx_conf, in_umbrella: true}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,4 @@
|
|||
# Used by "mix format"
|
||||
[
|
||||
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
|
||||
]
|
|
@ -0,0 +1,32 @@
|
|||
defmodule EMQXRetainer.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_retainer,
|
||||
version: "4.3.1",
|
||||
build_path: "../../_build",
|
||||
config_path: "../../config/config.exs",
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.12",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps(),
|
||||
description: "EMQ X Retainer"
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[
|
||||
registered: [:emqx_retainer_sup],
|
||||
mod: {:emqx_retainer_app, []},
|
||||
extra_applications: [:logger]
|
||||
]
|
||||
end
|
||||
|
||||
defp deps do
|
||||
[
|
||||
{:emqx, in_umbrella: true, runtime: false}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,4 @@
|
|||
# Used by "mix format"
|
||||
[
|
||||
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
|
||||
]
|
|
@ -0,0 +1,34 @@
|
|||
defmodule EMQXRuleEngine.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_rule_engine,
|
||||
version: "4.3.2",
|
||||
build_path: "../../_build",
|
||||
config_path: "../../config/config.exs",
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.12",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps(),
|
||||
description: "EMQ X Rule Engine"
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[
|
||||
registered: [:emqx_rule_engine_sup, :emqx_rule_registry],
|
||||
mod: {:emqx_rule_engine_app, []},
|
||||
extra_applications: [:logger, :syntax_tools]
|
||||
]
|
||||
end
|
||||
|
||||
defp deps do
|
||||
[
|
||||
{:emqx, in_umbrella: true, runtime: false},
|
||||
{:ekka, github: "emqx/ekka", tag: "0.11.1", runtime: false},
|
||||
{:emqx_http_lib, github: "emqx/emqx_http_lib", tag: "0.2.1"}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,4 @@
|
|||
# Used by "mix format"
|
||||
[
|
||||
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
|
||||
]
|
|
@ -0,0 +1,31 @@
|
|||
defmodule EMQXStatsd.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :emqx_statsd,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
config_path: "../../config/config.exs",
|
||||
deps_path: "../../deps",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.12",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps(),
|
||||
description: "EMQ X Statsd"
|
||||
]
|
||||
end
|
||||
|
||||
def application do
|
||||
[
|
||||
mod: {:emqx_statsd_app, []},
|
||||
extra_applications: [:logger]
|
||||
]
|
||||
end
|
||||
|
||||
defp deps do
|
||||
[
|
||||
{:estatsd, github: "emqx/estatsd", tag: "0.1.0"}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -0,0 +1 @@
|
|||
import Config
|
|
@ -58,7 +58,7 @@ do_stop()
|
|||
|
||||
# waiting stop done sleep 5
|
||||
sleep 5
|
||||
|
||||
|
||||
# Return
|
||||
# 0 if daemon has been stopped
|
||||
# 1 if daemon was already stopped
|
||||
|
@ -146,5 +146,3 @@ case "$1" in
|
|||
exit 3
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,75 @@
|
|||
defmodule EMQXUmbrella.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
def project do
|
||||
[
|
||||
apps_path: "apps",
|
||||
version: pkg_vsn(),
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps(),
|
||||
releases: releases()
|
||||
]
|
||||
end
|
||||
|
||||
defp deps do
|
||||
[
|
||||
{:jiffy, github: "emqx/jiffy", tag: "1.0.5", override: true},
|
||||
{:jsx, "~> 3.1", override: true},
|
||||
{:gun, github: "emqx/gun", tag: "1.3.4", override: true},
|
||||
{:hocon, github: "emqx/hocon", tag: "0.20.5", override: true},
|
||||
{:cuttlefish,
|
||||
github: "emqx/cuttlefish",
|
||||
manager: :rebar3,
|
||||
system_env: [{"CUTTLEFISH_ESCRIPT", "true"}],
|
||||
override: true},
|
||||
{:getopt, github: "emqx/getopt", tag: "v1.0.2", override: true},
|
||||
{:cowboy, github: "emqx/cowboy", tag: "2.8.2", override: true},
|
||||
{:cowlib, "~> 2.8", override: true},
|
||||
{:ranch, "~> 2.0", override: true},
|
||||
{:poolboy, github: "emqx/poolboy", tag: "1.5.2", override: true},
|
||||
{:esockd, github: "emqx/esockd", tag: "5.8.0", override: true},
|
||||
{:gproc, "~> 0.9", override: true},
|
||||
{:eetcd, "~> 0.3", override: true},
|
||||
{:grpc, github: "emqx/grpc-erl", tag: "0.6.2", override: true},
|
||||
{:pbkdf2, github: "emqx/erlang-pbkdf2", tag: "2.0.4", override: true},
|
||||
{:typerefl, github: "k32/typerefl", tag: "0.8.4", manager: :rebar3, override: true},
|
||||
{:gen_rpc, github: "emqx/gen_rpc", tag: "2.5.1", override: true},
|
||||
{:gen_coap, github: "emqx/gen_coap", tag: "v0.3.2", override: true},
|
||||
{:snabbkaffe, github: "kafka4beam/snabbkaffe", tag: "0.14.0", override: true},
|
||||
{:emqx_http_lib, github: "emqx/emqx_http_lib", tag: "0.4.0", override: true}
|
||||
| (enable_bcrypt() && [{:bcrypt, github: "emqx/erlang-bcrypt", tag: "0.6.0"}]) || []
|
||||
]
|
||||
end
|
||||
|
||||
defp releases do
|
||||
[
|
||||
emqx: fn ->
|
||||
[
|
||||
applications: EmqxReleaseHelper.applications(),
|
||||
steps: [:assemble, &EmqxReleaseHelper.run/1]
|
||||
]
|
||||
end
|
||||
]
|
||||
end
|
||||
|
||||
def enable_bcrypt do
|
||||
not match?({:win_32, _}, :os.type())
|
||||
end
|
||||
|
||||
def project_path do
|
||||
Path.expand("..", __ENV__.file)
|
||||
end
|
||||
|
||||
def pkg_vsn do
|
||||
project_path()
|
||||
|> Path.join("pkg-vsn.sh")
|
||||
|> System.cmd([])
|
||||
|> elem(0)
|
||||
|> String.trim()
|
||||
|> String.split("-")
|
||||
|> Enum.reverse()
|
||||
|> tl()
|
||||
|> Enum.reverse()
|
||||
|> Enum.join("-")
|
||||
end
|
||||
end
|
|
@ -0,0 +1,44 @@
|
|||
%{
|
||||
"bbmustache": {:hex, :bbmustache, "1.12.1", "857fbdf86bda46d07201b0e7a969820cb763a7c174c485fd0780d7e033efe9f0", [:rebar3], [], "hexpm", "f4320778c31a821a2a664db8894618abb79c1af7bbf7c03c703c8868d9bb09fe"},
|
||||
"bcrypt": {:git, "https://github.com/emqx/erlang-bcrypt.git", "dc2ba66acf2332c111362d01137746eefecc5e90", [tag: "0.6.0"]},
|
||||
"cowboy": {:git, "https://github.com/emqx/cowboy.git", "b89d4689a04149b1a4a3641280aa5c5643f921b2", [tag: "2.8.2"]},
|
||||
"cowboy_swagger": {:git, "https://github.com/inaka/cowboy_swagger", "f4b49a4f289a9ee9ae1ff35772c4e191b5fafbd5", [tag: "2.4.0"]},
|
||||
"cowlib": {:hex, :cowlib, "2.11.0", "0b9ff9c346629256c42ebe1eeb769a83c6cb771a6ee5960bd110ab0b9b872063", [:make, :rebar3], [], "hexpm", "2b3e9da0b21c4565751a6d4901c20d1b4cc25cbb7fd50d91d2ab6dd287bc86a9"},
|
||||
"cuttlefish": {:git, "https://github.com/emqx/cuttlefish.git", "6c346563e89ebbd95dbc1c29017adaf9abf85ca1", []},
|
||||
"ecpool": {:git, "https://github.com/emqx/ecpool.git", "0516d2cebd14654ef8c583c347e4a0b01363b86d", [tag: "0.5.1"]},
|
||||
"eetcd": {:hex, :eetcd, "0.3.4", "27e8b4775230c53a9ef602f62a1603591302b40b2eb195d567edffb35b6cf1a2", [:rebar3], [{:gun, "1.3.3", [hex: :gun, repo: "hexpm", optional: false]}], "hexpm", "b763c0e1a9741d39a62f5a19186a342863eacbc769151c4e81db5790efecefca"},
|
||||
"ekka": {:git, "https://github.com/emqx/ekka.git", "005fd6bb94199dc2ecb4ba03284f253b408e02d9", [tag: "0.11.1"]},
|
||||
"emqtt": {:git, "https://github.com/emqx/emqtt.git", "25892ef48a979a9dfbd74d86133cb28cf11f3cf4", [tag: "1.4.3"]},
|
||||
"emqx_http_lib": {:git, "https://github.com/emqx/emqx_http_lib.git", "9a1aafcbad1bb35392ebabc0cf102c7bce660432", [tag: "0.4.0"]},
|
||||
"epgsql": {:git, "https://github.com/epgsql/epgsql.git", "895c8f9d53f08d09ec6a0301c56d3d6f270929f2", [tag: "4.4.0"]},
|
||||
"esasl": {:git, "https://github.com/emqx/esasl.git", "1d4ab8d3ff7fd52018d3dddfec499933f9bb62b6", [tag: "0.1.0"]},
|
||||
"esockd": {:git, "https://github.com/emqx/esockd.git", "9b959fc11a1c398a589892f335235be6c5b4a454", [tag: "5.8.0"]},
|
||||
"estatsd": {:git, "https://github.com/emqx/estatsd.git", "5184d846b7ecb83509bd4d32695c60428c0198cd", [tag: "0.1.0"]},
|
||||
"gen_coap": {:git, "https://github.com/emqx/gen_coap.git", "9bf5e7f795badf68e2fb4eb226f576308f5b1bb4", [tag: "v0.3.2"]},
|
||||
"gen_rpc": {:git, "https://github.com/emqx/gen_rpc.git", "fb7418dc8cf7e97d153fba073bee0fac07dce753", [tag: "2.5.1"]},
|
||||
"getopt": {:git, "https://github.com/emqx/getopt.git", "215f2083408e1fe562d441aea6062bf5d9e1fb67", [tag: "v1.0.2"]},
|
||||
"gpb": {:hex, :gpb, "4.19.1", "665f59680577038508a11cf6c932fce26a4e35a19d586b912d763f292bc8e33b", [:make, :rebar3], [], "hexpm", "f6f4a7dcabd1723fdd3a3fd7c7efeea8146da02b6f575e75bfc49f15ff4db359"},
|
||||
"gproc": {:hex, :gproc, "0.9.0", "853ccb7805e9ada25d227a157ba966f7b34508f386a3e7e21992b1b484230699", [:rebar3], [], "hexpm", "587e8af698ccd3504cf4ba8d90f893ede2b0f58cabb8a916e2bf9321de3cf10b"},
|
||||
"grpc": {:git, "https://github.com/emqx/grpc-erl.git", "f8ba39eb075fb2a7f370563045d5e5d0914f2703", [tag: "0.6.2"]},
|
||||
"gun": {:git, "https://github.com/emqx/gun.git", "e1b5e14139e2a936ad6561bf960f70f1e80b81e2", [tag: "1.3.4"]},
|
||||
"hocon": {:git, "https://github.com/emqx/hocon.git", "2021a1b82c1f654c98181ba2dbfec5457c5c6eb7", [tag: "0.20.5"]},
|
||||
"jiffy": {:git, "https://github.com/emqx/jiffy.git", "baa1f4e750ae3c5c9e54f9c2e52280b7fc24a8d9", [tag: "1.0.5"]},
|
||||
"jose": {:hex, :jose, "1.11.2", "f4c018ccf4fdce22c71e44d471f15f723cb3efab5d909ab2ba202b5bf35557b3", [:mix, :rebar3], [], "hexpm", "98143fbc48d55f3a18daba82d34fe48959d44538e9697c08f34200fa5f0947d2"},
|
||||
"jsx": {:hex, :jsx, "3.1.0", "d12516baa0bb23a59bb35dccaf02a1bd08243fcbb9efe24f2d9d056ccff71268", [:rebar3], [], "hexpm", "0c5cc8fdc11b53cc25cf65ac6705ad39e54ecc56d1c22e4adb8f5a53fb9427f3"},
|
||||
"lc": {:git, "https://github.com/qzhuyan/lc.git", "6f38a748af0993bb4e440a0f9223d6aa7b90b86b", [tag: "0.1.1"]},
|
||||
"lwm2m_coap": {:git, "https://github.com/emqx/lwm2m-coap.git", "495f3c62fae153040c89f9a0ba5344789ff5acc8", [tag: "v2.0.0"]},
|
||||
"minirest": {:git, "https://github.com/emqx/minirest.git", "60c1a5a1f5df00a662cb34cf4101c7a21ffe08f9", [tag: "1.2.4"]},
|
||||
"mria": {:git, "https://github.com/emqx/mria", "f0efc591339f960b5126ec4e1a0fed85d1578eb5", [tag: "0.1.2"]},
|
||||
"mysql": {:git, "https://github.com/emqx/mysql-otp.git", "bdabac44cc8836a9e23897b7e1b77c7df7e04f70", [tag: "1.7.1"]},
|
||||
"pbkdf2": {:git, "https://github.com/emqx/erlang-pbkdf2.git", "45d9981209ea07a83a58cf85aaf8236457da4342", [tag: "2.0.4"]},
|
||||
"poolboy": {:git, "https://github.com/emqx/poolboy.git", "29be47db8c2be38b18c908e43a80ebb7b9b6116b", [tag: "1.5.2"]},
|
||||
"prometheus": {:git, "https://github.com/emqx/prometheus.erl.git", "a41488df09472448057d264ef520cf2f71d925f8", [tag: "v3.1.1"]},
|
||||
"quicer": {:git, "https://github.com/emqx/quic.git", "348c08a3f5a3b90861906fb436ff0ced453adfa2", [tag: "0.0.8"]},
|
||||
"ranch": {:hex, :ranch, "2.1.0", "2261f9ed9574dcfcc444106b9f6da155e6e540b2f82ba3d42b339b93673b72a3", [:make, :rebar3], [], "hexpm", "244ee3fa2a6175270d8e1fc59024fd9dbc76294a321057de8f803b1479e76916"},
|
||||
"recon": {:hex, :recon, "2.5.2", "cba53fa8db83ad968c9a652e09c3ed7ddcc4da434f27c3eaa9ca47ffb2b1ff03", [:mix, :rebar3], [], "hexpm", "2c7523c8dee91dff41f6b3d63cba2bd49eb6d2fe5bf1eec0df7f87eb5e230e1c"},
|
||||
"replayq": {:git, "https://github.com/emqx/replayq", "9e5ba14d65ff1885ad85b6d33a859c01c322f273", [tag: "0.3.1"]},
|
||||
"snabbkaffe": {:git, "https://github.com/kafka4beam/snabbkaffe.git", "ea1fbffddf8a3b5939bff61cc72ba45c3dceb058", [tag: "0.14.0"]},
|
||||
"ssl_verify_fun": {:git, "https://github.com/deadtrickster/ssl_verify_fun.erl.git", "c5718226b0b9f3d1a38ef6ca3c3b4c75f53dda92", [tag: "1.1.4"]},
|
||||
"trails": {:hex, :trails, "2.3.0", "b09703f056705f4943e14fff077b98c711a6f48fad40f4ff0b350794074ad69c", [:rebar3], [{:cowboy, "2.8.0", [hex: :cowboy, repo: "hexpm", optional: false]}, {:ranch, "2.0.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "40804001eb80417aa9d02400f39b7216956c3f251539a8a6096a69b3fac0ea07"},
|
||||
"typerefl": {:git, "https://github.com/k32/typerefl.git", "a751e0664752b1824206ca34377ac2d2c3ed53bc", [tag: "0.8.4"]},
|
||||
}
|
|
@ -0,0 +1,274 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
SELF=$(readlink "$0" || true)
|
||||
if [ -z "$SELF" ]; then SELF="$0"; fi
|
||||
RELEASE_ROOT="$(CDPATH='' cd "$(dirname "$SELF")/.." && pwd -P)"
|
||||
export RELEASE_ROOT
|
||||
export RELEASE_NAME="${RELEASE_NAME:-"emqx"}"
|
||||
export RELEASE_VSN="${RELEASE_VSN:-"$(cut -d' ' -f2 "$RELEASE_ROOT/releases/start_erl.data")"}"
|
||||
export RELEASE_COMMAND="$1"
|
||||
export RELEASE_MODE="${RELEASE_MODE:-"embedded"}"
|
||||
export RELEASE_PROG="${RELEASE_PROG:-"$(echo "$0" | sed 's/.*\///')"}"
|
||||
|
||||
REL_VSN_DIR="$RELEASE_ROOT/releases/$RELEASE_VSN"
|
||||
. "$REL_VSN_DIR/env.sh"
|
||||
. "$RELEASE_ROOT/releases/emqx_vars"
|
||||
|
||||
export RELEASE_COOKIE="${RELEASE_COOKIE:-"$(cat "$RELEASE_ROOT/releases/COOKIE")"}"
|
||||
export RELEASE_NODE="${RELEASE_NODE:-"$RELEASE_NAME"}"
|
||||
export RELEASE_TMP="${RELEASE_TMP:-"$RELEASE_ROOT/tmp"}"
|
||||
export RELEASE_VM_ARGS="${RELEASE_VM_ARGS:-"$REL_VSN_DIR/vm.args"}"
|
||||
export RELEASE_REMOTE_VM_ARGS="${RELEASE_REMOTE_VM_ARGS:-"$REL_VSN_DIR/remote.vm.args"}"
|
||||
export RELEASE_BOOT_SCRIPT="${RELEASE_BOOT_SCRIPT:-"start"}"
|
||||
export RELEASE_BOOT_SCRIPT_CLEAN="${RELEASE_BOOT_SCRIPT_CLEAN:-"start_clean"}"
|
||||
export RELEASE_SYS_CONFIG="${RELEASE_SYS_CONFIG:-"$REL_VSN_DIR/sys"}"
|
||||
|
||||
# defined in emqx_vars
|
||||
export RUNNER_ROOT_DIR
|
||||
export RUNNER_ETC_DIR
|
||||
export ERTS_VSN
|
||||
|
||||
export SCHEMA_MOD=emqx_conf_schema
|
||||
export CONFIGS_DIR="$RUNNER_DATA_DIR/configs"
|
||||
export MNESIA_DATA_DIR="$RUNNER_DATA_DIR/mnesia"
|
||||
|
||||
set_name () {
|
||||
IS_BOOT_COMMAND='no'
|
||||
case "$1" in
|
||||
start|start_iex|daemon|daemon_iex)
|
||||
IS_BOOT_COMMAND='yes'
|
||||
;;
|
||||
esac
|
||||
|
||||
## Possible ways to configure emqx node name:
|
||||
## 1. configure node.name in emqx.conf
|
||||
## 2. override with environment variable EMQX_NODE_NAME
|
||||
## Node name is either short-name (without '@'), e.g. 'emqx'
|
||||
## or long name (with '@') e.g. 'emqx@example.net' or 'emqx@127.0.0.1'
|
||||
NAME="${EMQX_NODE_NAME:-}"
|
||||
if [ -z "$NAME" ]; then
|
||||
if [ "$IS_BOOT_COMMAND" = 'yes' ]; then
|
||||
# for boot commands, inspect emqx.conf for node name
|
||||
NAME="$(call_hocon -s $SCHEMA_MOD -c $RUNNER_ETC_DIR/emqx.conf get node.name | tr -d \")"
|
||||
else
|
||||
# for non-boot commands, inspect vm.<time>.args for node name
|
||||
# shellcheck disable=SC2012,SC2086
|
||||
LATEST_VM_ARGS="$(ls -t $CONFIGS_DIR/vm.*.args | head -1)"
|
||||
NAME="$(grep -E '^-s?name' "$LATEST_VM_ARGS" | awk '{print $2}')"
|
||||
fi
|
||||
fi
|
||||
|
||||
[ -z "$NAME" ] && NAME='emqx'
|
||||
|
||||
case "$NAME" in
|
||||
*@*)
|
||||
NAME_TYPE='-name'
|
||||
;;
|
||||
*)
|
||||
NAME_TYPE='-sname'
|
||||
esac
|
||||
SHORT_NAME="$(echo "$NAME" | awk -F'@' '{print $1}')"
|
||||
export ESCRIPT_NAME="$SHORT_NAME"
|
||||
|
||||
export NAME_TYPE
|
||||
export NAME
|
||||
}
|
||||
|
||||
SED_REPLACE="sed -i "
|
||||
case $(sed --help 2>&1) in
|
||||
*GNU*) SED_REPLACE="sed -i ";;
|
||||
*BusyBox*) SED_REPLACE="sed -i ";;
|
||||
*) SED_REPLACE="sed -i '' ";;
|
||||
esac
|
||||
|
||||
rand () {
|
||||
dd count=1 bs=2 if=/dev/urandom 2> /dev/null | od -x | awk 'NR==1{print $2}'
|
||||
}
|
||||
|
||||
generate_config () {
|
||||
local name_type="$NAME_TYPE"
|
||||
local node_name="$NAME"
|
||||
|
||||
## Delete the *.siz files first or it cann't start after
|
||||
## changing the config 'log.rotation.size'
|
||||
rm -rf "${RUNNER_LOG_DIR}"/*.siz
|
||||
|
||||
EMQX_LICENSE_CONF_OPTION=""
|
||||
if [ "${EMQX_LICENSE_CONF:-}" != "" ]; then
|
||||
EMQX_LICENSE_CONF_OPTION="-c ${EMQX_LICENSE_CONF}"
|
||||
fi
|
||||
|
||||
## timestamp for each generation
|
||||
local NOW_TIME
|
||||
NOW_TIME="$(call_hocon now_time)"
|
||||
|
||||
## ths command populates two files: app.<time>.config and vm.<time>.args
|
||||
## disable SC2086 to allow EMQX_LICENSE_CONF_OPTION to split
|
||||
# shellcheck disable=SC2086
|
||||
call_hocon -v -t $NOW_TIME -s $SCHEMA_MOD -c $RUNNER_ETC_DIR/emqx.conf $EMQX_LICENSE_CONF_OPTION -d $RUNNER_DATA_DIR/configs generate
|
||||
|
||||
## filenames are per-hocon convention
|
||||
RELEASE_SYS_CONFIG="$CONFIGS_DIR/app.$NOW_TIME.config"
|
||||
RELEASE_VM_ARGS="$CONFIGS_DIR/vm.$NOW_TIME.args"
|
||||
|
||||
## Merge hocon generated *.args into the vm.args
|
||||
TMP_ARG_FILE="$CONFIGS_DIR/vm.args.tmp"
|
||||
cp "$RUNNER_ETC_DIR/vm.args" "$TMP_ARG_FILE"
|
||||
echo "" >> "$TMP_ARG_FILE"
|
||||
echo "-pa ${REL_VSN_DIR}/consolidated" >> "$TMP_ARG_FILE"
|
||||
## read lines from generated vm.<time>.args file
|
||||
## drop comment lines, and empty lines using sed
|
||||
## pipe the lines to a while loop
|
||||
sed '/^#/d' "$RELEASE_VM_ARGS" | sed '/^$/d' | while IFS='' read -r ARG_LINE || [ -n "$ARG_LINE" ]; do
|
||||
## in the loop, split the 'key[:space:]value' pair
|
||||
ARG_KEY=$(echo "$ARG_LINE" | awk '{$NF="";print}')
|
||||
ARG_VALUE=$(echo "$ARG_LINE" | awk '{print $NF}')
|
||||
## use the key to look up in vm.args file for the value
|
||||
TMP_ARG_VALUE=$(grep "^$ARG_KEY" "$TMP_ARG_FILE" || true | awk '{print $NF}')
|
||||
## compare generated (to override) value to original (to be overriden) value
|
||||
if [ "$ARG_VALUE" != "$TMP_ARG_VALUE" ] ; then
|
||||
## if they are different
|
||||
if [ -n "$TMP_ARG_VALUE" ]; then
|
||||
## if the old value is present, replace it with generated value
|
||||
sh -c "$SED_REPLACE 's|^$ARG_KEY.*$|$ARG_LINE|' $TMP_ARG_FILE"
|
||||
else
|
||||
## otherwise append generated value to the end
|
||||
echo "$ARG_LINE" >> "$TMP_ARG_FILE"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
echo "$name_type $node_name" >> "$TMP_ARG_FILE"
|
||||
## rename the generated vm.<time>.args file
|
||||
mv -f "$TMP_ARG_FILE" "$RELEASE_VM_ARGS"
|
||||
|
||||
# # # shellcheck disable=SC2086
|
||||
# if ! relx_nodetool chkconfig $CONFIG_ARGS; then
|
||||
# die "failed_to_check_config $CONFIG_ARGS"
|
||||
# fi
|
||||
}
|
||||
|
||||
rpc () {
|
||||
# TODO: remote vm args
|
||||
exec "$REL_VSN_DIR/elixir" \
|
||||
--hidden --cookie "$RELEASE_COOKIE" \
|
||||
--boot "$REL_VSN_DIR/$RELEASE_BOOT_SCRIPT_CLEAN" \
|
||||
--boot-var RELEASE_LIB "$RELEASE_ROOT/lib" \
|
||||
--vm-args "$RELEASE_REMOTE_VM_ARGS" \
|
||||
--rpc-eval "$RELEASE_NODE" "$1"
|
||||
}
|
||||
|
||||
start () {
|
||||
generate_config
|
||||
REL_EXEC="$1"
|
||||
shift
|
||||
exec "$REL_VSN_DIR/$REL_EXEC" \
|
||||
--cookie "$RELEASE_COOKIE" \
|
||||
--erl "-mode $RELEASE_MODE -mnesia dir \"${MNESIA_DATA_DIR}\"" \
|
||||
--erl-config "$RELEASE_SYS_CONFIG" \
|
||||
--boot "$REL_VSN_DIR/$RELEASE_BOOT_SCRIPT" \
|
||||
--boot-var RELEASE_LIB "$RELEASE_ROOT/lib" \
|
||||
--vm-args "$RELEASE_VM_ARGS" "$@"
|
||||
}
|
||||
|
||||
call_hocon() {
|
||||
nodetool hocon "$@"
|
||||
}
|
||||
|
||||
nodetool () {
|
||||
command="$1"; shift
|
||||
"$RUNNER_ROOT_DIR/erts-$ERTS_VSN/bin/erl" \
|
||||
+B -noshell \
|
||||
-boot "$REL_VSN_DIR/$RELEASE_BOOT_SCRIPT_CLEAN" \
|
||||
-boot_var RELEASE_LIB "$RELEASE_ROOT/lib" \
|
||||
-run escript start \
|
||||
-extra "$RUNNER_ROOT_DIR/bin/nodetool" \
|
||||
"$command" "$@"
|
||||
}
|
||||
|
||||
set_name "$1"
|
||||
|
||||
case $1 in
|
||||
start)
|
||||
start "elixir" --no-halt
|
||||
;;
|
||||
|
||||
start_iex)
|
||||
start "iex" --werl
|
||||
;;
|
||||
|
||||
daemon)
|
||||
start "elixir" --no-halt --pipe-to "${RELEASE_TMP}/pipe" "${RELEASE_TMP}/log"
|
||||
;;
|
||||
|
||||
daemon_iex)
|
||||
start "iex" --pipe-to "${RELEASE_TMP}/pipe" "${RELEASE_TMP}/log"
|
||||
;;
|
||||
|
||||
eval)
|
||||
if [ -z "$2" ]; then
|
||||
echo "ERROR: EVAL expects an expression as argument" >&2
|
||||
exit 1
|
||||
fi
|
||||
exec "$REL_VSN_DIR/elixir" \
|
||||
--cookie "$RELEASE_COOKIE" \
|
||||
--erl-config "$RELEASE_SYS_CONFIG" \
|
||||
--boot "$REL_VSN_DIR/$RELEASE_BOOT_SCRIPT_CLEAN" \
|
||||
--boot-var RELEASE_LIB "$RELEASE_ROOT/lib" \
|
||||
--vm-args "$RELEASE_VM_ARGS" --eval "$2"
|
||||
;;
|
||||
|
||||
remote)
|
||||
generate_config
|
||||
exec "$REL_VSN_DIR/iex" \
|
||||
--werl --hidden --cookie "$RELEASE_COOKIE" \
|
||||
--boot "$REL_VSN_DIR/$RELEASE_BOOT_SCRIPT_CLEAN" \
|
||||
--boot-var RELEASE_LIB "$RELEASE_ROOT/lib" \
|
||||
--vm-args "$RELEASE_REMOTE_VM_ARGS" \
|
||||
--remsh "$RELEASE_NODE"
|
||||
;;
|
||||
|
||||
rpc)
|
||||
if [ -z "$2" ]; then
|
||||
echo "ERROR: RPC expects an expression as argument" >&2
|
||||
exit 1
|
||||
fi
|
||||
rpc "$2"
|
||||
;;
|
||||
|
||||
restart|stop)
|
||||
rpc "System.$1()"
|
||||
;;
|
||||
|
||||
pid)
|
||||
rpc "IO.puts System.pid()"
|
||||
;;
|
||||
|
||||
version)
|
||||
echo "$RELEASE_NAME $RELEASE_VSN"
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Usage: $(basename "$0") COMMAND [ARGS]
|
||||
|
||||
The known commands are:
|
||||
|
||||
start Starts the system
|
||||
start_iex Starts the system with IEx attached
|
||||
daemon Starts the system as a daemon
|
||||
daemon_iex Starts the system as a daemon with IEx attached
|
||||
eval \"EXPR\" Executes the given expression on a new, non-booted system
|
||||
rpc \"EXPR\" Executes the given expression remotely on the running system
|
||||
remote Connects to the running system via a remote shell
|
||||
restart Restarts the running system via a remote command
|
||||
stop Stops the running system via a remote command
|
||||
pid Prints the operating system PID of the running system via a remote command
|
||||
version Prints the release name and version to be booted
|
||||
" >&2
|
||||
|
||||
if [ -n "$1" ]; then
|
||||
echo "ERROR: Unknown command $1" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
esac
|
|
@ -0,0 +1,309 @@
|
|||
#!/usr/bin/env escript
|
||||
%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
|
||||
%% ex: ft=erlang ts=4 sw=4 et
|
||||
%% -------------------------------------------------------------------
|
||||
%%
|
||||
%% nodetool: Helper Script for interacting with live nodes
|
||||
%%
|
||||
%% -------------------------------------------------------------------
|
||||
-mode(compile).
|
||||
|
||||
main(Args) ->
|
||||
case os:type() of
|
||||
{win32, nt} -> ok;
|
||||
_nix ->
|
||||
case init:get_argument(start_epmd) of
|
||||
{ok, [["true"]]} ->
|
||||
ok = start_epmd();
|
||||
_ ->
|
||||
ok
|
||||
end
|
||||
end,
|
||||
case Args of
|
||||
["hocon" | Rest] ->
|
||||
%% forward the call to hocon_cli
|
||||
hocon_cli:main(Rest);
|
||||
_ ->
|
||||
do(Args)
|
||||
end.
|
||||
|
||||
do(Args) ->
|
||||
ok = do_with_halt(Args, "mnesia_dir", fun create_mnesia_dir/2),
|
||||
ok = do_with_halt(Args, "chkconfig", fun("-config", X) -> chkconfig(X) end),
|
||||
ok = do_with_halt(Args, "chkconfig", fun chkconfig/1),
|
||||
Args1 = do_with_ret(Args, "-name",
|
||||
fun(TargetName) ->
|
||||
ThisNode = this_node_name(longnames, TargetName),
|
||||
{ok, _} = net_kernel:start([ThisNode, longnames]),
|
||||
put(target_node, nodename(TargetName))
|
||||
end),
|
||||
Args2 = do_with_ret(Args1, "-sname",
|
||||
fun(TargetName) ->
|
||||
ThisNode = this_node_name(shortnames, TargetName),
|
||||
{ok, _} = net_kernel:start([ThisNode, shortnames]),
|
||||
put(target_node, nodename(TargetName))
|
||||
end),
|
||||
RestArgs = do_with_ret(Args2, "-setcookie",
|
||||
fun(Cookie) ->
|
||||
erlang:set_cookie(node(), list_to_atom(Cookie))
|
||||
end),
|
||||
|
||||
[application:start(App) || App <- [crypto, public_key, ssl]],
|
||||
TargetNode = get(target_node),
|
||||
|
||||
%% See if the node is currently running -- if it's not, we'll bail
|
||||
case {net_kernel:hidden_connect_node(TargetNode), net_adm:ping(TargetNode)} of
|
||||
{true, pong} ->
|
||||
ok;
|
||||
{false, pong} ->
|
||||
io:format(standard_error, "Failed to connect to node ~p\n", [TargetNode]),
|
||||
halt(1);
|
||||
{_, pang} ->
|
||||
io:format(standard_error, "Node ~p not responding to pings.\n", [TargetNode]),
|
||||
halt(1)
|
||||
end,
|
||||
|
||||
case RestArgs of
|
||||
["getpid"] ->
|
||||
io:format("~p\n", [list_to_integer(rpc:call(TargetNode, os, getpid, []))]);
|
||||
["ping"] ->
|
||||
%% If we got this far, the node already responsed to a ping, so just dump
|
||||
%% a "pong"
|
||||
io:format("pong\n");
|
||||
["stop"] ->
|
||||
case rpc:call(TargetNode, emqx_machine, graceful_shutdown, [], 60000) of
|
||||
ok ->
|
||||
ok;
|
||||
{badrpc, nodedown} ->
|
||||
%% nodetool commands are always executed after a ping
|
||||
%% which if the code gets here, it's because the target node
|
||||
%% has shutdown before RPC returns.
|
||||
ok
|
||||
end;
|
||||
["rpc", Module, Function | RpcArgs] ->
|
||||
case rpc:call(TargetNode, list_to_atom(Module), list_to_atom(Function),
|
||||
[RpcArgs], 60000) of
|
||||
ok ->
|
||||
ok;
|
||||
{error, cmd_not_found} ->
|
||||
halt(1);
|
||||
{error, Reason} ->
|
||||
io:format("RPC to ~s error: ~p\n", [TargetNode, Reason]),
|
||||
halt(1);
|
||||
{badrpc, Reason} ->
|
||||
io:format("RPC to ~s failed: ~p\n", [TargetNode, Reason]),
|
||||
halt(1);
|
||||
_ ->
|
||||
halt(1)
|
||||
end;
|
||||
["rpc_infinity", Module, Function | RpcArgs] ->
|
||||
case rpc:call(TargetNode, list_to_atom(Module), list_to_atom(Function), [RpcArgs], infinity) of
|
||||
ok ->
|
||||
ok;
|
||||
{badrpc, Reason} ->
|
||||
io:format("RPC to ~p failed: ~p\n", [TargetNode, Reason]),
|
||||
halt(1);
|
||||
_ ->
|
||||
halt(1)
|
||||
end;
|
||||
["rpcterms", Module, Function | ArgsAsString] ->
|
||||
case rpc:call(TargetNode, list_to_atom(Module), list_to_atom(Function),
|
||||
consult(lists:flatten(ArgsAsString)), 60000) of
|
||||
{badrpc, Reason} ->
|
||||
io:format("RPC to ~p failed: ~p\n", [TargetNode, Reason]),
|
||||
halt(1);
|
||||
Other ->
|
||||
io:format("~p\n", [Other])
|
||||
end;
|
||||
["eval" | ListOfArgs] ->
|
||||
Parsed = parse_eval_args(ListOfArgs),
|
||||
% and evaluate it on the remote node
|
||||
case rpc:call(TargetNode, erl_eval, exprs, [Parsed, [] ]) of
|
||||
{value, Value, _} ->
|
||||
io:format ("~p~n",[Value]);
|
||||
{badrpc, Reason} ->
|
||||
io:format("RPC to ~p failed: ~p~n", [TargetNode, Reason]),
|
||||
halt(1)
|
||||
end;
|
||||
Other ->
|
||||
io:format("Other: ~p~n", [Other]),
|
||||
io:format("Usage: nodetool chkconfig|getpid|ping|stop|rpc|rpc_infinity|rpcterms|eval|cold_eval [Terms] [RPC]\n")
|
||||
end,
|
||||
net_kernel:stop().
|
||||
|
||||
parse_eval_args(Args) ->
|
||||
% shells may process args into more than one, and end up stripping
|
||||
% spaces, so this converts all of that to a single string to parse
|
||||
String = binary_to_list(
|
||||
list_to_binary(
|
||||
join(Args," ")
|
||||
)
|
||||
),
|
||||
|
||||
% then just as a convenience to users, if they forgot a trailing
|
||||
% '.' add it for them.
|
||||
Normalized =
|
||||
case lists:reverse(String) of
|
||||
[$. | _] -> String;
|
||||
R -> lists:reverse([$. | R])
|
||||
end,
|
||||
|
||||
% then scan and parse the string
|
||||
{ok, Scanned, _} = erl_scan:string(Normalized),
|
||||
{ok, Parsed } = erl_parse:parse_exprs(Scanned),
|
||||
Parsed.
|
||||
|
||||
do_with_ret(Args, Name, Handler) ->
|
||||
{arity, Arity} = erlang:fun_info(Handler, arity),
|
||||
case take_args(Args, Name, Arity) of
|
||||
false ->
|
||||
Args;
|
||||
{Args1, Rest} ->
|
||||
_ = erlang:apply(Handler, Args1),
|
||||
Rest
|
||||
end.
|
||||
|
||||
do_with_halt(Args, Name, Handler) ->
|
||||
{arity, Arity} = erlang:fun_info(Handler, arity),
|
||||
case take_args(Args, Name, Arity) of
|
||||
false ->
|
||||
ok;
|
||||
{Args1, _Rest} ->
|
||||
erlang:apply(Handler, Args1), %% should halt
|
||||
io:format(standard_error, "~s handler did not halt", [Name]),
|
||||
halt(?LINE)
|
||||
end.
|
||||
|
||||
%% Return option args list if found, otherwise 'false'.
|
||||
take_args(Args, OptName, 0) ->
|
||||
lists:member(OptName, Args) andalso [];
|
||||
take_args(Args, OptName, OptArity) ->
|
||||
take_args(Args, OptName, OptArity, _Scanned = []).
|
||||
|
||||
take_args([], _, _, _) -> false; %% no such option
|
||||
take_args([Name | Rest], Name, Arity, Scanned) ->
|
||||
length(Rest) >= Arity orelse error({not_enough_args_for, Name}),
|
||||
{Result, Tail} = lists:split(Arity, Rest),
|
||||
{Result, lists:reverse(Scanned) ++ Tail};
|
||||
take_args([Other | Rest], Name, Arity, Scanned) ->
|
||||
take_args(Rest, Name, Arity, [Other | Scanned]).
|
||||
|
||||
start_epmd() ->
|
||||
[] = os:cmd("\"" ++ epmd_path() ++ "\" -daemon"),
|
||||
ok.
|
||||
|
||||
epmd_path() ->
|
||||
ErtsBinDir = filename:dirname(escript:script_name()),
|
||||
Name = "epmd",
|
||||
case os:find_executable(Name, ErtsBinDir) of
|
||||
false ->
|
||||
case os:find_executable(Name) of
|
||||
false ->
|
||||
io:format("Could not find epmd.~n"),
|
||||
halt(1);
|
||||
GlobalEpmd ->
|
||||
GlobalEpmd
|
||||
end;
|
||||
Epmd ->
|
||||
Epmd
|
||||
end.
|
||||
|
||||
nodename(Name) ->
|
||||
case re:split(Name, "@", [{return, list}, unicode]) of
|
||||
[_Node, _Host] ->
|
||||
list_to_atom(Name);
|
||||
[Node] ->
|
||||
[_, Host] = re:split(atom_to_list(node()), "@", [{return, list}, unicode]),
|
||||
list_to_atom(lists:concat([Node, "@", Host]))
|
||||
end.
|
||||
|
||||
this_node_name(longnames, Name) ->
|
||||
[Node, Host] = re:split(Name, "@", [{return, list}, unicode]),
|
||||
list_to_atom(lists:concat(["remsh_maint_", Node, os:getpid(), "@", Host]));
|
||||
this_node_name(shortnames, Name) ->
|
||||
list_to_atom(lists:concat(["remsh_maint_", Name, os:getpid()])).
|
||||
|
||||
%% For windows???
|
||||
create_mnesia_dir(DataDir, NodeName) ->
|
||||
MnesiaDir = filename:join(DataDir, NodeName),
|
||||
file:make_dir(MnesiaDir),
|
||||
io:format("~s", [MnesiaDir]),
|
||||
halt(0).
|
||||
|
||||
chkconfig(File) ->
|
||||
case file:consult(File) of
|
||||
{ok, Terms} ->
|
||||
case validate(Terms) of
|
||||
ok ->
|
||||
halt(0);
|
||||
{error, Problems} ->
|
||||
lists:foreach(fun print_issue/1, Problems),
|
||||
%% halt(1) if any problems were errors
|
||||
halt(case [x || {error, _} <- Problems] of
|
||||
[] -> 0;
|
||||
_ -> 1
|
||||
end)
|
||||
end;
|
||||
{error, {Line, Mod, Term}} ->
|
||||
io:format(standard_error, ["Error on line ", file:format_error({Line, Mod, Term}), "\n"], []),
|
||||
halt(1);
|
||||
{error, Error} ->
|
||||
io:format(standard_error, ["Error reading config file: ", File, " ", file:format_error(Error), "\n"], []),
|
||||
halt(1)
|
||||
end.
|
||||
|
||||
%%
|
||||
%% Given a string or binary, parse it into a list of terms, ala file:consult/0
|
||||
%%
|
||||
consult(Str) when is_list(Str) ->
|
||||
consult([], Str, []);
|
||||
consult(Bin) when is_binary(Bin)->
|
||||
consult([], binary_to_list(Bin), []).
|
||||
|
||||
consult(Cont, Str, Acc) ->
|
||||
case erl_scan:tokens(Cont, Str, 0) of
|
||||
{done, Result, Remaining} ->
|
||||
case Result of
|
||||
{ok, Tokens, _} ->
|
||||
{ok, Term} = erl_parse:parse_term(Tokens),
|
||||
consult([], Remaining, [Term | Acc]);
|
||||
{eof, _Other} ->
|
||||
lists:reverse(Acc);
|
||||
{error, Info, _} ->
|
||||
{error, Info}
|
||||
end;
|
||||
{more, Cont1} ->
|
||||
consult(Cont1, eof, Acc)
|
||||
end.
|
||||
|
||||
%%
|
||||
%% Validation functions for checking the app.config
|
||||
%%
|
||||
validate([Terms]) ->
|
||||
Results = [ValidateFun(Terms) || ValidateFun <- get_validation_funs()],
|
||||
Failures = [Res || Res <- Results, Res /= true],
|
||||
case Failures of
|
||||
[] ->
|
||||
ok;
|
||||
_ ->
|
||||
{error, Failures}
|
||||
end.
|
||||
|
||||
%% Some initial and basic checks for the app.config file
|
||||
get_validation_funs() ->
|
||||
[ ].
|
||||
|
||||
print_issue({warning, Warning}) ->
|
||||
io:format(standard_error, "Warning in app.config: ~s~n", [Warning]);
|
||||
print_issue({error, Error}) ->
|
||||
io:format(standard_error, "Error in app.config: ~s~n", [Error]).
|
||||
|
||||
%% string:join/2 copy; string:join/2 is getting obsoleted
|
||||
%% and replaced by lists:join/2, but lists:join/2 is too new
|
||||
%% for version support (only appeared in 19.0) so it cannot be
|
||||
%% used. Instead we just adopt join/2 locally and hope it works
|
||||
%% for most unicode use cases anyway.
|
||||
join([], Sep) when is_list(Sep) ->
|
||||
[];
|
||||
join([H|T], Sep) ->
|
||||
H ++ lists:append([Sep ++ X || X <- T]).
|
Loading…
Reference in New Issue