test(CI): add actions for build emqx packages (#3915)
This commit is contained in:
parent
66ebcfa301
commit
c0f03ca132
|
@ -0,0 +1,12 @@
|
||||||
|
ARG BUILD_FROM=emqx/build-env:erl22.3-ubuntu20.04
|
||||||
|
FROM ${BUILD_FROM}
|
||||||
|
|
||||||
|
ARG EMQX_NAME=emqx
|
||||||
|
|
||||||
|
COPY . /emqx
|
||||||
|
|
||||||
|
WORKDIR /emqx
|
||||||
|
|
||||||
|
RUN make ${EMQX_NAME}-pkg || cat rebar3.crashdump
|
||||||
|
|
||||||
|
RUN /emqx/.ci/build_packages/tests.sh
|
|
@ -0,0 +1,171 @@
|
||||||
|
#!/bin/sh
|
||||||
|
set -x -e -u
|
||||||
|
export EMQX_NAME=${EMQX_NAME:-"emqx"}
|
||||||
|
export PACKAGE_PATH="/emqx/_packages/${EMQX_NAME}"
|
||||||
|
export RELUP_PACKAGE_PATH="/emqx/relup_packages/${EMQX_NAME}"
|
||||||
|
# export EMQX_NODE_NAME="emqx-on-$(uname -m)@127.0.0.1"
|
||||||
|
# export EMQX_NODE_COOKIE=$(date +%s%N)
|
||||||
|
|
||||||
|
emqx_prepare(){
|
||||||
|
mkdir -p ${PACKAGE_PATH}
|
||||||
|
|
||||||
|
if [ ! -d "/paho-mqtt-testing" ]; then
|
||||||
|
git clone -b develop-4.0 https://github.com/emqx/paho.mqtt.testing.git /paho-mqtt-testing
|
||||||
|
fi
|
||||||
|
pip3 install pytest
|
||||||
|
}
|
||||||
|
|
||||||
|
emqx_test(){
|
||||||
|
cd ${PACKAGE_PATH}
|
||||||
|
|
||||||
|
for var in $(ls $PACKAGE_PATH/${EMQX_NAME}-*);do
|
||||||
|
case ${var##*.} in
|
||||||
|
"zip")
|
||||||
|
packagename=`basename ${PACKAGE_PATH}/${EMQX_NAME}-*.zip`
|
||||||
|
unzip -q ${PACKAGE_PATH}/$packagename
|
||||||
|
sed -i "/zone.external.server_keepalive/c zone.external.server_keepalive = 60" ${PACKAGE_PATH}/emqx/etc/emqx.conf
|
||||||
|
sed -i "/mqtt.max_topic_alias/c mqtt.max_topic_alias = 10" ${PACKAGE_PATH}/emqx/etc/emqx.conf
|
||||||
|
|
||||||
|
if [ ! -z $(echo ${EMQX_DEPS_DEFAULT_VSN#v} | grep -oE "[0-9]+\.[0-9]+(\.[0-9]+)?-(alpha|beta|rc)\.[0-9]") ]; then
|
||||||
|
if [ ! -d ${PACKAGE_PATH}/emqx/lib/emqx-${EMQX_DEPS_DEFAULT_VSN#v} ] || [ ! -d ${PACKAGE_PATH}/emqx/releases/${EMQX_DEPS_DEFAULT_VSN#v} ] ;then
|
||||||
|
echo "emqx zip version error"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "running ${packagename} start"
|
||||||
|
${PACKAGE_PATH}/emqx/bin/emqx start || tail ${PACKAGE_PATH}/emqx/log/erlang.log.1
|
||||||
|
IDLE_TIME=0
|
||||||
|
while [ -z "$(${PACKAGE_PATH}/emqx/bin/emqx_ctl status |grep 'is running'|awk '{print $1}')" ]
|
||||||
|
do
|
||||||
|
if [ $IDLE_TIME -gt 10 ]
|
||||||
|
then
|
||||||
|
echo "emqx running error"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
sleep 10
|
||||||
|
IDLE_TIME=$((IDLE_TIME+1))
|
||||||
|
done
|
||||||
|
pytest -v /paho-mqtt-testing/interoperability/test_client/V5/test_connect.py::test_basic
|
||||||
|
${PACKAGE_PATH}/emqx/bin/emqx stop
|
||||||
|
echo "running ${packagename} stop"
|
||||||
|
rm -rf ${PACKAGE_PATH}/emqx
|
||||||
|
;;
|
||||||
|
"deb")
|
||||||
|
packagename=`basename ${PACKAGE_PATH}/${EMQX_NAME}-*.deb`
|
||||||
|
dpkg -i ${PACKAGE_PATH}/$packagename
|
||||||
|
if [ $(dpkg -l |grep emqx |awk '{print $1}') != "ii" ]
|
||||||
|
then
|
||||||
|
echo "package install error"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "running ${packagename} start"
|
||||||
|
running_test
|
||||||
|
echo "running ${packagename} stop"
|
||||||
|
|
||||||
|
dpkg -r ${EMQX_NAME}
|
||||||
|
if [ $(dpkg -l |grep emqx |awk '{print $1}') != "rc" ]
|
||||||
|
then
|
||||||
|
echo "package remove error"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
dpkg -P ${EMQX_NAME}
|
||||||
|
if [ ! -z "$(dpkg -l |grep emqx)" ]
|
||||||
|
then
|
||||||
|
echo "package uninstall error"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
"rpm")
|
||||||
|
packagename=`basename ${PACKAGE_PATH}/${EMQX_NAME}-*.rpm`
|
||||||
|
rpm -ivh ${PACKAGE_PATH}/$packagename
|
||||||
|
if [ -z $(rpm -q emqx | grep -o emqx) ];then
|
||||||
|
echo "package install error"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "running ${packagename} start"
|
||||||
|
running_test
|
||||||
|
echo "running ${packagename} stop"
|
||||||
|
|
||||||
|
rpm -e ${EMQX_NAME}
|
||||||
|
if [ "$(rpm -q emqx)" != "package emqx is not installed" ];then
|
||||||
|
echo "package uninstall error"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
running_test(){
|
||||||
|
if [ ! -z $(echo ${EMQX_DEPS_DEFAULT_VSN#v} | grep -oE "[0-9]+\.[0-9]+(\.[0-9]+)?-(alpha|beta|rc)\.[0-9]") ]; then
|
||||||
|
if [ ! -d /usr/lib/emqx/lib/emqx-${EMQX_DEPS_DEFAULT_VSN#v} ] || [ ! -d /usr/lib/emqx/releases/${EMQX_DEPS_DEFAULT_VSN#v} ];then
|
||||||
|
echo "emqx package version error"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
sed -i "/zone.external.server_keepalive/c zone.external.server_keepalive = 60" /etc/emqx/emqx.conf
|
||||||
|
sed -i "/mqtt.max_topic_alias/c mqtt.max_topic_alias = 10" /etc/emqx/emqx.conf
|
||||||
|
|
||||||
|
emqx start || tail /var/log/emqx/erlang.log.1
|
||||||
|
IDLE_TIME=0
|
||||||
|
while [ -z "$(emqx_ctl status |grep 'is running'|awk '{print $1}')" ]
|
||||||
|
do
|
||||||
|
if [ $IDLE_TIME -gt 10 ]
|
||||||
|
then
|
||||||
|
echo "emqx running error"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
sleep 10
|
||||||
|
IDLE_TIME=$((IDLE_TIME+1))
|
||||||
|
done
|
||||||
|
pytest -v /paho-mqtt-testing/interoperability/test_client/V5/test_connect.py::test_basic
|
||||||
|
emqx stop || kill $(ps -ef |grep emqx | grep beam.smp |awk '{print $2}')
|
||||||
|
|
||||||
|
if [ $(sed -n '/^ID=/p' /etc/os-release | sed -r 's/ID=(.*)/\1/g' | sed 's/"//g') = ubuntu ] \
|
||||||
|
|| [ $(sed -n '/^ID=/p' /etc/os-release | sed -r 's/ID=(.*)/\1/g' | sed 's/"//g') = debian ] \
|
||||||
|
|| [ $(sed -n '/^ID=/p' /etc/os-release | sed -r 's/ID=(.*)/\1/g' | sed 's/"//g') = raspbian ];then
|
||||||
|
service emqx start || tail /var/log/emqx/erlang.log.1
|
||||||
|
IDLE_TIME=0
|
||||||
|
while [ -z "$(emqx_ctl status |grep 'is running'|awk '{print $1}')" ]
|
||||||
|
do
|
||||||
|
if [ $IDLE_TIME -gt 10 ]
|
||||||
|
then
|
||||||
|
echo "emqx service error"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
sleep 10
|
||||||
|
IDLE_TIME=$((IDLE_TIME+1))
|
||||||
|
done
|
||||||
|
service emqx stop
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
relup_test(){
|
||||||
|
if [ -d ${RELUP_PACKAGE_PATH} ];then
|
||||||
|
cd ${RELUP_PACKAGE_PATH }
|
||||||
|
|
||||||
|
for var in $(ls ${EMQX_NAME}-*-$(uname -m).zip);do
|
||||||
|
packagename=`basename ${var}`
|
||||||
|
unzip $packagename
|
||||||
|
./emqx/bin/emqx start
|
||||||
|
./emqx/bin/emqx_ctl status
|
||||||
|
./emqx/bin/emqx versions
|
||||||
|
cp ${PACKAGE_PATH}/${EMQX_NAME}-*-${EMQX_DEPS_DEFAULT_VSN#v}-$(uname -m).zip ./emqx/releases
|
||||||
|
./emqx/bin/emqx install ${EMQX_DEPS_DEFAULT_VSN#v}
|
||||||
|
[ $(./emqx/bin/emqx versions |grep permanent | grep -oE "[0-9].[0-9].[0-9]") = ${EMQX_DEPS_DEFAULT_VSN#v} ] || exit 1
|
||||||
|
./emqx/bin/emqx_ctl status
|
||||||
|
./emqx/bin/emqx stop
|
||||||
|
rm -rf emqx
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
emqx_prepare
|
||||||
|
emqx_test
|
||||||
|
relup_test
|
|
@ -0,0 +1,62 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Author: Stefan Buck
|
||||||
|
# License: MIT
|
||||||
|
# https://gist.github.com/stefanbuck/ce788fee19ab6eb0b4447a85fc99f447
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# This script accepts the following parameters:
|
||||||
|
#
|
||||||
|
# * owner
|
||||||
|
# * repo
|
||||||
|
# * tag
|
||||||
|
# * filename
|
||||||
|
# * github_api_token
|
||||||
|
#
|
||||||
|
# Script to upload a release asset using the GitHub API v3.
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
#
|
||||||
|
# upload-github-release-asset.sh github_api_token=TOKEN owner=stefanbuck repo=playground tag=v0.1.0 filename=./build.zip
|
||||||
|
#
|
||||||
|
|
||||||
|
# Check dependencies.
|
||||||
|
set -e
|
||||||
|
xargs=$(which gxargs || which xargs)
|
||||||
|
|
||||||
|
# Validate settings.
|
||||||
|
[ "$TRACE" ] && set -x
|
||||||
|
|
||||||
|
CONFIG=$@
|
||||||
|
|
||||||
|
for line in $CONFIG; do
|
||||||
|
eval "$line"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Define variables.
|
||||||
|
GH_API="https://api.github.com"
|
||||||
|
GH_REPO="$GH_API/repos/$owner/$repo"
|
||||||
|
GH_TAGS="$GH_REPO/releases/tags/$tag"
|
||||||
|
AUTH="Authorization: token $github_api_token"
|
||||||
|
WGET_ARGS="--content-disposition --auth-no-challenge --no-cookie"
|
||||||
|
CURL_ARGS="-LJO#"
|
||||||
|
|
||||||
|
if [[ "$tag" == 'LATEST' ]]; then
|
||||||
|
GH_TAGS="$GH_REPO/releases/latest"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Validate token.
|
||||||
|
curl -o /dev/null -sH "$AUTH" $GH_REPO || { echo "Error: Invalid repo, token or network issue!"; exit 1; }
|
||||||
|
|
||||||
|
# Read asset tags.
|
||||||
|
response=$(curl -sH "$AUTH" $GH_TAGS)
|
||||||
|
|
||||||
|
# Get ID of the asset based on given filename.
|
||||||
|
eval $(echo "$response" | grep -m 1 "id.:" | grep -w id | tr : = | tr -cd '[[:alnum:]]=')
|
||||||
|
[ "$id" ] || { echo "Error: Failed to get release id for tag: $tag"; echo "$response" | awk 'length($0)<100' >&2; exit 1; }
|
||||||
|
|
||||||
|
# Upload asset
|
||||||
|
# Construct url
|
||||||
|
GH_ASSET="https://uploads.github.com/repos/$owner/$repo/releases/$id/assets?name=$(basename $filename)"
|
||||||
|
|
||||||
|
curl "$GITHUB_OAUTH_BASIC" --data-binary @"$filename" -H "Authorization: token $github_api_token" -H "Content-Type: application/octet-stream" $GH_ASSET
|
|
@ -0,0 +1,47 @@
|
||||||
|
## default globals
|
||||||
|
TARGET ?= emqx/emqx
|
||||||
|
EMQX_NAME = $(subst emqx/,,$(TARGET))
|
||||||
|
|
||||||
|
.PHONY: all
|
||||||
|
all: test
|
||||||
|
|
||||||
|
define wait_emqx
|
||||||
|
@while [ "$$(docker inspect -f '{{ .State.Health.Status}}' $$(docker ps -a -q -f name=paho_test_emqx1))" != "healthy" ] || [ "$$(docker inspect -f '{{ .State.Health.Status}}' $$(docker ps -a -q -f name=paho_test_emqx2))" != "healthy" ]; do \
|
||||||
|
if [ $$(docker ps -a -f name=paho_test_emqx -f status=exited -q | wc -l) -ne 0 ]; then \
|
||||||
|
echo "['$$(date -u +"%Y-%m-%dT%H:%M:%SZ")']:emqx stop"; \
|
||||||
|
exit; \
|
||||||
|
else \
|
||||||
|
echo "['$$(date -u +"%Y-%m-%dT%H:%M:%SZ")']:waiting emqx"; \
|
||||||
|
sleep 5; \
|
||||||
|
fi; \
|
||||||
|
done
|
||||||
|
endef
|
||||||
|
|
||||||
|
.PHONY: create_container
|
||||||
|
create_container: clean
|
||||||
|
@docker-compose -p paho_test up -d
|
||||||
|
|
||||||
|
$(call wait_emqx)
|
||||||
|
|
||||||
|
.PHONY: test
|
||||||
|
test: create_container
|
||||||
|
@docker exec -i $$(docker ps -a -q -f name=paho_test_client) sh -c "apk update && apk add git curl \
|
||||||
|
&& git clone -b $(PAHO_BRANCH) https://github.com/emqx/paho.mqtt.testing.git /paho.mqtt.testing \
|
||||||
|
&& pip install pytest \
|
||||||
|
&& pytest -v /paho.mqtt.testing/interoperability/test_client/ --host node1.emqx.io"
|
||||||
|
|
||||||
|
@docker-compose -p paho_test down
|
||||||
|
|
||||||
|
.PHONY: cluster_test
|
||||||
|
cluster_test: create_container
|
||||||
|
@docker exec -i $$(docker ps -a -q -f name=paho_test_client) sh -c "apk update && apk add git curl \
|
||||||
|
&& git clone -b $(PAHO_BRANCH) https://github.com/emqx/paho.mqtt.testing.git /paho.mqtt.testing \
|
||||||
|
&& pip install pytest \
|
||||||
|
&& pytest -v /paho.mqtt.testing/interoperability/test_client/V5/test_connect.py -k test_basic --host node1.emqx.io \
|
||||||
|
&& pytest -v /paho.mqtt.testing/interoperability/test_cluster --host1 node1.emqx.io --host2 node2.emqx.io"
|
||||||
|
|
||||||
|
@docker-compose -p paho_test down
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
@if [ ! -z "$$(docker ps -a -q -f name=paho_test)" ]; then docker-compose -p paho_test down; fi
|
|
@ -0,0 +1,65 @@
|
||||||
|
version: '3'
|
||||||
|
|
||||||
|
services:
|
||||||
|
emqx1:
|
||||||
|
image: emqx/emqx:build-alpine-amd64
|
||||||
|
environment:
|
||||||
|
- "EMQX_NAME=emqx"
|
||||||
|
- "EMQX_HOST=node1.emqx.io"
|
||||||
|
- "EMQX_CLUSTER__DISCOVERY=static"
|
||||||
|
- "EMQX_CLUSTER__STATIC__SEEDS=emqx@node1.emqx.io, emqx@node2.emqx.io"
|
||||||
|
- "EMQX_ZONE__EXTERNAL__RETRY_INTERVAL=2s"
|
||||||
|
- "EMQX_MQTT__MAX_TOPIC_ALIAS=10"
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
sed -i "s 127.0.0.1 $$(ip route show |grep "link" |awk '{print $$1}') g" /opt/emqx/etc/acl.conf
|
||||||
|
/usr/bin/start.sh
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "/opt/emqx/bin/emqx_ctl", "status"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 25s
|
||||||
|
retries: 5
|
||||||
|
networks:
|
||||||
|
emqx-bridge:
|
||||||
|
aliases:
|
||||||
|
- node1.emqx.io
|
||||||
|
|
||||||
|
emqx2:
|
||||||
|
image: emqx/emqx:build-alpine-amd64
|
||||||
|
environment:
|
||||||
|
- "EMQX_NAME=emqx"
|
||||||
|
- "EMQX_HOST=node2.emqx.io"
|
||||||
|
- "EMQX_CLUSTER__DISCOVERY=static"
|
||||||
|
- "EMQX_CLUSTER__STATIC__SEEDS=emqx@node1.emqx.io, emqx@node2.emqx.io"
|
||||||
|
- "EMQX_ZONE__EXTERNAL__RETRY_INTERVAL=2s"
|
||||||
|
- "EMQX_MQTT__MAX_TOPIC_ALIAS=10"
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
sed -i "s 127.0.0.1 $$(ip route show |grep "link" |awk '{print $$1}') g" /opt/emqx/etc/acl.conf
|
||||||
|
/usr/bin/start.sh
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "/opt/emqx/bin/emqx_ctl", "status"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 25s
|
||||||
|
retries: 5
|
||||||
|
networks:
|
||||||
|
emqx-bridge:
|
||||||
|
aliases:
|
||||||
|
- node2.emqx.io
|
||||||
|
|
||||||
|
client:
|
||||||
|
image: python:3.7.2-alpine3.9
|
||||||
|
depends_on:
|
||||||
|
- emqx1
|
||||||
|
- emqx2
|
||||||
|
tty: true
|
||||||
|
networks:
|
||||||
|
emqx-bridge:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
emqx-bridge:
|
||||||
|
driver: bridge
|
|
@ -0,0 +1,393 @@
|
||||||
|
name: Cross build packages
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- v*
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
windows:
|
||||||
|
runs-on: windows-2019
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
- uses: ilammy/msvc-dev-cmd@v1
|
||||||
|
- uses: gleam-lang/setup-erlang@v1.1.0
|
||||||
|
id: install_erlang
|
||||||
|
with:
|
||||||
|
otp-version: 22.3
|
||||||
|
- name: build
|
||||||
|
run: |
|
||||||
|
# set-executionpolicy remotesigned -s cu
|
||||||
|
# iex (new-object net.webclient).downloadstring('https://get.scoop.sh')
|
||||||
|
# # $env:path + ";" + $env:USERPROFILE + "\scoop\shims" + ';C:\Program Files\erl10.4\bin'
|
||||||
|
# [environment]::SetEnvironmentvariable("Path", ";" + $env:USERPROFILE + "\scoop\shims")
|
||||||
|
# [environment]::SetEnvironmentvariable("Path", ';C:\Program Files\erl10.4\bin')
|
||||||
|
# scoop bucket add extras https://github.com/lukesampson/scoop-extras.git
|
||||||
|
# scoop update
|
||||||
|
# scoop install sudo curl vcredist2013
|
||||||
|
|
||||||
|
$env:PATH = "${{ steps.install_erlang.outputs.erlpath }}\bin;$env:PATH"
|
||||||
|
|
||||||
|
$version = $( "${{ github.ref }}" -replace "^(.*)/(.*)/" )
|
||||||
|
if ($version -match "^v[0-9]+\.[0-9]+(\.[0-9]+)?") {
|
||||||
|
$regex = "[0-9]+\.[0-9]+(-alpha|-beta|-rc)?\.[0-9]"
|
||||||
|
$pkg_name = "emqx-windows-$([regex]::matches($version, $regex).value).zip"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$pkg_name = "emqx-windows-$($version -replace '/').zip"
|
||||||
|
}
|
||||||
|
|
||||||
|
make deps-emqx || cat rebar3.crashdump
|
||||||
|
$rebar3 = $env:USERPROFILE + "\rebar3"
|
||||||
|
(New-Object System.Net.WebClient).DownloadFile('https://s3.amazonaws.com/rebar3/rebar3', $rebar3)
|
||||||
|
cd _build/emqx/lib/jiffy/
|
||||||
|
escript $rebar3 compile
|
||||||
|
cd ../../../../
|
||||||
|
|
||||||
|
make emqx
|
||||||
|
mkdir -p _packages/emqx
|
||||||
|
Compress-Archive -Path _build/emqx/rel/emqx -DestinationPath _build/emqx/rel/$pkg_name
|
||||||
|
mv _build/emqx/rel/$pkg_name _packages/emqx
|
||||||
|
Get-FileHash -Path "_packages/emqx/$pkg_name" | Format-List | grep 'Hash' | awk '{print $3}' > _packages/emqx/$pkg_name.sha256
|
||||||
|
- name: run emqx
|
||||||
|
run: |
|
||||||
|
./_build/emqx/rel/emqx/bin/emqx start
|
||||||
|
./_build/emqx/rel/emqx/bin/emqx stop
|
||||||
|
./_build/emqx/rel/emqx/bin/emqx install
|
||||||
|
./_build/emqx/rel/emqx/bin/emqx uninstall
|
||||||
|
- uses: actions/upload-artifact@v1
|
||||||
|
with:
|
||||||
|
name: emqx
|
||||||
|
path: ./_packages/emqx/.
|
||||||
|
|
||||||
|
mac:
|
||||||
|
runs-on: macos-10.15
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
- name: prepare
|
||||||
|
run: |
|
||||||
|
brew install curl zip unzip gnu-sed kerl unixodbc freetds
|
||||||
|
echo "/usr/local/bin" >> $GITHUB_PATH
|
||||||
|
git config --global credential.helper store
|
||||||
|
- name: build erlang
|
||||||
|
run: |
|
||||||
|
kerl build 22.3.4.13
|
||||||
|
kerl install 22.3.4.13 $HOME/.kerl/22.3.4.13
|
||||||
|
- name: build
|
||||||
|
run: |
|
||||||
|
. $HOME/.kerl/22.3.4.13/activate
|
||||||
|
make emqx-pkg
|
||||||
|
- name: test
|
||||||
|
run: |
|
||||||
|
pkg_name=$(basename _packages/emqx/emqx-macos-*.zip)
|
||||||
|
unzip _packages/emqx/$pkg_name
|
||||||
|
./emqx/bin/emqx start || cat emqx/log/erlang.log.1
|
||||||
|
./emqx/bin/emqx_ctl status
|
||||||
|
./emqx/bin/emqx stop
|
||||||
|
rm -rf emqx
|
||||||
|
openssl dgst -sha256 ./_packages/emqx/$pkg_name | awk '{print $2}' > ./_packages/emqx/$pkg_name.sha256
|
||||||
|
- uses: actions/upload-artifact@v1
|
||||||
|
with:
|
||||||
|
name: emqx
|
||||||
|
path: ./_packages/emqx/.
|
||||||
|
|
||||||
|
linux:
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os:
|
||||||
|
- ubuntu20.04
|
||||||
|
- ubuntu18.04
|
||||||
|
- ubuntu16.04
|
||||||
|
- debian10
|
||||||
|
- debian9
|
||||||
|
- opensuse
|
||||||
|
- centos8
|
||||||
|
- centos7
|
||||||
|
- centos6
|
||||||
|
- raspbian10
|
||||||
|
- raspbian9
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: prepare docker
|
||||||
|
run: |
|
||||||
|
mkdir -p $HOME/.docker
|
||||||
|
echo '{ "experimental": "enabled" }' | tee $HOME/.docker/config.json
|
||||||
|
echo '{ "experimental": true, "storage-driver": "overlay2", "max-concurrent-downloads": 50, "max-concurrent-uploads": 50}' | sudo tee /etc/docker/daemon.json
|
||||||
|
sudo systemctl restart docker
|
||||||
|
docker info
|
||||||
|
docker buildx create --use --name mybuild
|
||||||
|
docker run --rm --privileged tonistiigi/binfmt --install all
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
- name: get deps
|
||||||
|
run: |
|
||||||
|
docker run -i --rm \
|
||||||
|
-e GITHUB_RUN_ID=$GITHUB_RUN_ID \
|
||||||
|
-e GITHUB_REF=$GITHUB_REF \
|
||||||
|
-v $(pwd):/emqx \
|
||||||
|
-w /emqx \
|
||||||
|
emqx/build-env:erl22.3-debian10 \
|
||||||
|
bash -c "make deps-all"
|
||||||
|
- name: downloads emqx zip packages
|
||||||
|
env:
|
||||||
|
SYSTEM: ${{ matrix.os }}
|
||||||
|
run: |
|
||||||
|
set -e -u -x
|
||||||
|
version=$(echo ${{ github.ref }} | sed -r "s ^refs/heads/|^refs/tags/(.*) \1 g")
|
||||||
|
if [ "$(echo $version | grep -oE "^[ev0-9]+\.[0-9]+\.[1-9]?")" = "$version" ]; then
|
||||||
|
tags=$(git tag -l "$(echo $version | grep -oE "^[ev0-9]+\.[0-9]").*" |grep -v "$version")
|
||||||
|
for tag in ${tags[@]};do
|
||||||
|
for arch in x86_64 aarch64; do
|
||||||
|
mkdir -p tmp/relup_packages/emqx
|
||||||
|
cd tmp/relup_packages/emqx
|
||||||
|
if [ ! -z "$(echo $(curl -I -m 10 -o /dev/null -s -w %{http_code} https://packages.emqx.io/emqx-ce/v${tag#[e|v]}/emqx-$SYSTEM-${tag#[e|v]}-$arch.zip) | grep -oE "^[23]+")" ];then
|
||||||
|
wget https://www.emqx.io/downloads/broker/v${tag#[e|v]}/emqx-$SYSTEM-${tag#[e|v]}-$arch.zip
|
||||||
|
wget https://www.emqx.io/downloads/broker/v${tag#[e|v]}/emqx-$SYSTEM-${tag#[e|v]}-$arch.zip.sha256
|
||||||
|
echo "$(cat emqx-$SYSTEM-${tag#[e|v]}-$arch.zip.sha256) emqx-$SYSTEM-${tag#[e|v]}-$arch.zip" | sha256sum -c || exit 1
|
||||||
|
fi
|
||||||
|
cd -
|
||||||
|
|
||||||
|
mkdir -p tmp/relup_packages/emqx-edge
|
||||||
|
cd tmp/relup_packages/emqx-edge
|
||||||
|
if [ ! -z "$(echo $(curl -I -m 10 -o /dev/null -s -w %{http_code} https://packages.emqx.io/emqx-edge/v${tag#[e|v]}/emqx-edge-$SYSTEM-${tag#[e|v]}-$arch.zip) | grep -oE "^[23]+")" ];then
|
||||||
|
wget https://www.emqx.io/downloads/edge/v${tag#[e|v]}/emqx-edge-$SYSTEM-${tag#[e|v]}-$arch.zip
|
||||||
|
wget https://www.emqx.io/downloads/edge/v${tag#[e|v]}/emqx-edge-$SYSTEM-${tag#[e|v]}-$arch.zip.sha256
|
||||||
|
echo "$(cat emqx-edge-$SYSTEM-${tag#[e|v]}-$arch.zip.sha256) emqx-edge-$SYSTEM-${tag#[e|v]}-$arch.zip" | sha256sum -c || exit 1
|
||||||
|
fi
|
||||||
|
cd -
|
||||||
|
done
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
- name: build emqx packages on amd64
|
||||||
|
env:
|
||||||
|
ERL_OTP: erl22.3
|
||||||
|
SYSTEM: ${{ matrix.os }}
|
||||||
|
if: matrix.os != 'raspbian9' && matrix.os != 'raspbian10'
|
||||||
|
run: |
|
||||||
|
set -e -u -x
|
||||||
|
for EMQX in emqx emqx-edge; do
|
||||||
|
docker buildx build --no-cache \
|
||||||
|
--platform=linux/amd64 \
|
||||||
|
-t cross_build_emqx_for_$SYSTEM \
|
||||||
|
-f .ci/build_packages/Dockerfile \
|
||||||
|
--build-arg BUILD_FROM=emqx/build-env:$ERL_OTP-$SYSTEM \
|
||||||
|
--build-arg EMQX_NAME=${EMQX} \
|
||||||
|
--output type=tar,dest=/tmp/cross-build-$EMQX-for-$SYSTEM.tar .
|
||||||
|
|
||||||
|
mkdir -p /tmp/packages/$EMQX
|
||||||
|
tar -xvf /tmp/cross-build-$EMQX-for-$SYSTEM.tar --wildcards emqx/_packages/$EMQX/*
|
||||||
|
mv emqx/_packages/$EMQX/* /tmp/packages/$EMQX/
|
||||||
|
rm -rf /tmp/cross-build-$EMQX-for-$SYSTEM.tar
|
||||||
|
|
||||||
|
docker rm -f $(docker ps -a -q)
|
||||||
|
docker volume prune -f
|
||||||
|
done
|
||||||
|
- name: build emqx packages on arm64
|
||||||
|
if: matrix.os != 'centos6'
|
||||||
|
env:
|
||||||
|
ERL_OTP: erl22.3
|
||||||
|
SYSTEM: ${{ matrix.os }}
|
||||||
|
run: |
|
||||||
|
set -e -u -x
|
||||||
|
for EMQX in emqx emqx-edge; do
|
||||||
|
if [ "$EMQX" == "emqx" ] && [ ! -z $( echo $SYSTEM | grep -o raspbian) ];then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
docker buildx build --no-cache \
|
||||||
|
--platform=linux/arm64 \
|
||||||
|
-t cross_build_emqx_for_$SYSTEM \
|
||||||
|
-f .ci/build_packages/Dockerfile \
|
||||||
|
--build-arg BUILD_FROM=emqx/build-env:$ERL_OTP-$SYSTEM \
|
||||||
|
--build-arg EMQX_NAME=${EMQX} \
|
||||||
|
--output type=tar,dest=/tmp/cross-build-$EMQX-for-$SYSTEM.tar . || df -h
|
||||||
|
|
||||||
|
mkdir -p /tmp/packages/$EMQX
|
||||||
|
tar -xvf /tmp/cross-build-$EMQX-for-$SYSTEM.tar --wildcards emqx/_packages/$EMQX/*
|
||||||
|
mv emqx/_packages/$EMQX/* /tmp/packages/$EMQX/
|
||||||
|
rm -rf /tmp/cross-build-$EMQX-for-$SYSTEM.tar
|
||||||
|
|
||||||
|
docker rm -f $(docker ps -a -q)
|
||||||
|
docker volume prune -f
|
||||||
|
done
|
||||||
|
- name: create sha256
|
||||||
|
run: |
|
||||||
|
if [ -d /tmp/packages/emqx ]; then
|
||||||
|
cd /tmp/packages/emqx
|
||||||
|
for var in $(ls emqx-* ); do
|
||||||
|
bash -c "echo $(sha256sum $var | awk '{print $1}') > $var.sha256"
|
||||||
|
done
|
||||||
|
cd -
|
||||||
|
fi
|
||||||
|
if [ -d /tmp/packages/emqx-edge ]; then
|
||||||
|
cd /tmp/packages/emqx-edge
|
||||||
|
for var in $(ls emqx-edge-* ); do
|
||||||
|
bash -c "echo $(sha256sum $var | awk '{print $1}') > $var.sha256"
|
||||||
|
done
|
||||||
|
cd -
|
||||||
|
fi
|
||||||
|
- uses: actions/upload-artifact@v1
|
||||||
|
if: matrix.os != 'raspbian9' && matrix.os != 'raspbian10'
|
||||||
|
with:
|
||||||
|
name: emqx
|
||||||
|
path: /tmp/packages/emqx/.
|
||||||
|
- uses: actions/upload-artifact@v1
|
||||||
|
with:
|
||||||
|
name: emqx-edge
|
||||||
|
path: /tmp/packages/emqx-edge/.
|
||||||
|
|
||||||
|
docker:
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
arch:
|
||||||
|
- [amd64, x86_64]
|
||||||
|
- [arm64v8, aarch64]
|
||||||
|
- [arm32v7, arm]
|
||||||
|
- [i386, i386]
|
||||||
|
- [s390x, s390x]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
- name: get deps
|
||||||
|
run: |
|
||||||
|
docker run -i --rm \
|
||||||
|
-e GITHUB_RUN_ID=$GITHUB_RUN_ID \
|
||||||
|
-e GITHUB_REF=$GITHUB_REF \
|
||||||
|
-v $(pwd):/emqx \
|
||||||
|
-w /emqx \
|
||||||
|
emqx/build-env:erl22.3-alpine-amd64 \
|
||||||
|
sh -c "make deps-emqx"
|
||||||
|
- name: build emqx docker image
|
||||||
|
env:
|
||||||
|
ARCH: ${{ matrix.arch[0] }}
|
||||||
|
QEMU_ARCH: ${{ matrix.arch[1] }}
|
||||||
|
run: |
|
||||||
|
sudo docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
|
||||||
|
|
||||||
|
sudo TARGET=emqx/emqx ARCH=$ARCH QEMU_ARCH=$QEMU_ARCH make docker
|
||||||
|
cd _packages/emqx && for var in $(ls emqx-docker-* ); do sudo bash -c "echo $(sha256sum $var | awk '{print $1}') > $var.sha256"; done && cd -
|
||||||
|
|
||||||
|
sudo TARGET=emqx/emqx-edge ARCH=$ARCH QEMU_ARCH=$QEMU_ARCH make docker
|
||||||
|
cd _packages/emqx-edge && for var in $(ls emqx-edge-docker-* ); do sudo bash -c "echo $(sha256sum $var | awk '{print $1}') > $var.sha256"; done && cd -
|
||||||
|
- name: docker test
|
||||||
|
if: matrix.arch[0] == 'amd64'
|
||||||
|
run: |
|
||||||
|
sudo TARGET=emqx/emqx PAHO_BRANCH="develop-4.0" make -C .ci/paho_tests cluster_test
|
||||||
|
sudo TARGET=emqx/emqx-edge PAHO_BRANCH="develop-4.0" make -C .ci/paho_tests cluster_test
|
||||||
|
- uses: actions/upload-artifact@v1
|
||||||
|
with:
|
||||||
|
name: emqx
|
||||||
|
path: ./_packages/emqx/.
|
||||||
|
- uses: actions/upload-artifact@v1
|
||||||
|
with:
|
||||||
|
name: emqx-edge
|
||||||
|
path: ./_packages/emqx-edge/.
|
||||||
|
|
||||||
|
upload:
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
|
||||||
|
needs: [windows, mac, linux, docker]
|
||||||
|
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/download-artifact@v2
|
||||||
|
with:
|
||||||
|
name: emqx
|
||||||
|
path: ./_packages/emqx
|
||||||
|
- uses: actions/download-artifact@v2
|
||||||
|
with:
|
||||||
|
name: emqx-edge
|
||||||
|
path: ./_packages/emqx-edge
|
||||||
|
- name: install dos2unix
|
||||||
|
run: sudo apt-get update && sudo apt install -y dos2unix
|
||||||
|
- name: get packages
|
||||||
|
run: |
|
||||||
|
set -e -x -u
|
||||||
|
for EMQX in emqx emqx-edge; do
|
||||||
|
cd _packages/$EMQX
|
||||||
|
for var in $( ls |grep emqx |grep -v sha256); do
|
||||||
|
dos2unix $var.sha256
|
||||||
|
echo "$(cat $var.sha256) $var" | sha256sum -c || exit 1
|
||||||
|
done
|
||||||
|
cd -
|
||||||
|
done
|
||||||
|
- name: upload aws s3
|
||||||
|
if: contains(github.ref, 'refs/tags/')
|
||||||
|
run: |
|
||||||
|
set -e -x -u
|
||||||
|
version=$(echo ${{ github.ref }} | sed -r "s ^refs/heads/|^refs/tags/(.*) \1 g")
|
||||||
|
curl "https://d1vvhvl2y92vvt.cloudfront.net/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
|
||||||
|
unzip awscliv2.zip
|
||||||
|
sudo ./aws/install
|
||||||
|
aws configure set aws_access_key_id ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||||
|
aws configure set aws_secret_access_key ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||||
|
aws configure set default.region us-west-2
|
||||||
|
|
||||||
|
aws s3 cp --recursive _packages/emqx s3://packages.emqx/emqx-ce/$version
|
||||||
|
aws s3 cp --recursive _packages/emqx-edge s3://packages.emqx/emqx-edge/$version
|
||||||
|
aws cloudfront create-invalidation --distribution-id E170YEULGLT8XB --paths "/emqx-ce/$version/*,/emqx-edge/$version/*"
|
||||||
|
|
||||||
|
mkdir packages
|
||||||
|
mv _packages/emqx/* packages
|
||||||
|
mv _packages/emqx-edge/* packages
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
path: emqx
|
||||||
|
- name: update to github and emqx.io
|
||||||
|
if: contains(github.ref, 'refs/tags/')
|
||||||
|
run: |
|
||||||
|
set -e -x -u
|
||||||
|
version=$(echo ${{ github.ref }} | sed -r "s ^refs/heads/|^refs/tags/(.*) \1 g")
|
||||||
|
cd packages
|
||||||
|
for var in $(ls); do
|
||||||
|
../emqx/.ci/build_packages/upload_github_release_asset.sh owner=emqx repo=emqx tag=$version filename=$var github_api_token=$(echo ${{ secrets.AccessToken }})
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
curl -w %{http_code} \
|
||||||
|
--insecure \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "token: ${{ secrets.EMQX_IO_TOKEN }}" \
|
||||||
|
-X POST \
|
||||||
|
-d "{\"repo\":\"emqx/emqx\", \"tag\": \"${version}\" }" \
|
||||||
|
${{ secrets.EMQX_IO_RELEASE_API }}
|
||||||
|
- name: push docker image to docker hub
|
||||||
|
if: contains(github.ref, 'refs/tags/')
|
||||||
|
run: |
|
||||||
|
set -e -x -u
|
||||||
|
version=$(echo ${{ github.ref }} | sed -r "s ^refs/heads/|^refs/tags/(.*) \1 g")
|
||||||
|
sudo make -C emqx docker-prepare
|
||||||
|
cd packages && for var in $(ls |grep docker |grep -v sha256); do unzip $var; sudo docker load < ${var%.*}; rm -f ${var%.*}; done && cd -
|
||||||
|
echo ${{ secrets.DOCKER_HUB_TOKEN }} |sudo docker login -u ${{ secrets.DOCKER_HUB_USER }} --password-stdin
|
||||||
|
sudo TARGET=emqx/emqx make -C emqx docker-push
|
||||||
|
sudo TARGET=emqx/emqx make -C emqx docker-manifest-list
|
||||||
|
sudo TARGET=emqx/emqx-edge make -C emqx docker-push
|
||||||
|
sudo TARGET=emqx/emqx-edge make -C emqx docker-manifest-list
|
||||||
|
- name: update repo.emqx.io
|
||||||
|
if: contains(github.ref, 'refs/tags/')
|
||||||
|
run: |
|
||||||
|
set -e -x -u
|
||||||
|
version=$(echo ${{ github.ref }} | sed -r "s ^refs/heads/|^refs/tags/(.*) \1 g")
|
||||||
|
curl \
|
||||||
|
-H "Authorization: token ${{ secrets.AccessToken }}" \
|
||||||
|
-H "Accept: application/vnd.github.v3+json" \
|
||||||
|
-X POST \
|
||||||
|
-d "{\"ref\":\"v1.0.0\",\"inputs\":{\"version\": \"${version}\", \"emqx_ce\": \"true\"}}" \
|
||||||
|
https://api.github.com/repos/emqx/emqx-ci-helper/actions/workflows/update_repos.yaml/dispatches
|
||||||
|
- uses: geekyeggo/delete-artifact@v1
|
||||||
|
with:
|
||||||
|
name: emqx
|
||||||
|
- uses: geekyeggo/delete-artifact@v1
|
||||||
|
with:
|
||||||
|
name: emqx-edge
|
||||||
|
# - name: update homebrew packages
|
||||||
|
# run: |
|
||||||
|
# version=$(echo ${{ github.ref }} | sed -r "s .*/.*/(.*) \1 g")
|
||||||
|
# if [ ! -z $(echo $version | grep -oE "v[0-9]+\.[0-9]+(\.[0-9]+)?") ] && [ -z $(echo $version | grep -oE "(alpha|beta|rc)\.[0-9]") ]; then
|
||||||
|
# curl -H "Authorization: token ${{ secrets.AccessToken }}" -H "Accept: application/vnd.github.everest-preview+json" -H "Content-Type: application/json" -X POST -d "{\"event_type\":\"update_homebrew\",\"client_payload\":{\"version\": \"$version\"}}" https://api.github.com/repos/emqx/emqx-packages-docker/dispatches
|
||||||
|
# fi
|
|
@ -36,5 +36,6 @@ _checkouts
|
||||||
rebar.config.rendered
|
rebar.config.rendered
|
||||||
/rebar3
|
/rebar3
|
||||||
rebar.lock
|
rebar.lock
|
||||||
|
.stamp
|
||||||
tmp/
|
tmp/
|
||||||
_packages
|
_packages
|
||||||
|
|
8
Makefile
8
Makefile
|
@ -1,6 +1,6 @@
|
||||||
REBAR_VERSION = 3.14.3-emqx-2
|
REBAR_VERSION = 3.14.3-emqx-3
|
||||||
REBAR = ./rebar3
|
REBAR = $(CURDIR)/rebar3
|
||||||
export PKG_VSN ?= $(shell git describe --tags --always)
|
export PKG_VSN ?= $(shell git describe --tags --match '[0-9]*' 2>/dev/null || git describe --always)
|
||||||
# comma separated versions
|
# comma separated versions
|
||||||
export RELUP_BASE_VERSIONS ?=
|
export RELUP_BASE_VERSIONS ?=
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ all: $(REBAR) $(PROFILES)
|
||||||
|
|
||||||
.PHONY: ensure-rebar3
|
.PHONY: ensure-rebar3
|
||||||
ensure-rebar3:
|
ensure-rebar3:
|
||||||
@./ensure-rebar3.sh $(REBAR_VERSION)
|
$(CURDIR)/ensure-rebar3.sh $(REBAR_VERSION)
|
||||||
|
|
||||||
$(REBAR): ensure-rebar3
|
$(REBAR): ensure-rebar3
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
apiVersion: v2
|
||||||
|
name: emqx
|
||||||
|
description: A Helm chart for EMQ X
|
||||||
|
# A chart can be either an 'application' or a 'library' chart.
|
||||||
|
#
|
||||||
|
# Application charts are a collection of templates that can be packaged into versioned archives
|
||||||
|
# to be deployed.
|
||||||
|
#
|
||||||
|
# Library charts provide useful utilities or functions for the chart developer. They're included as
|
||||||
|
# a dependency of application charts to inject those utilities and functions into the rendering
|
||||||
|
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
|
||||||
|
type: application
|
||||||
|
|
||||||
|
# This is the chart version. This version number should be incremented each time you make changes
|
||||||
|
# to the chart and its templates, including the app version.
|
||||||
|
version: v4.1.1
|
||||||
|
|
||||||
|
# This is the version number of the application being deployed. This version number should be
|
||||||
|
# incremented each time you make changes to the application.
|
||||||
|
appVersion: v4.1.1
|
|
@ -0,0 +1,77 @@
|
||||||
|
# Introduction
|
||||||
|
This chart bootstraps an emqx deployment on a Kubernetes cluster using the Helm package manager.
|
||||||
|
|
||||||
|
# Prerequisites
|
||||||
|
+ Kubernetes 1.6+
|
||||||
|
+ Helm
|
||||||
|
|
||||||
|
# Installing the Chart
|
||||||
|
To install the chart with the release name `my-emqx`:
|
||||||
|
|
||||||
|
+ From github
|
||||||
|
```
|
||||||
|
$ git clone https://github.com/emqx/emqx.git
|
||||||
|
$ cd emqx/deploy/charts/emqx
|
||||||
|
$ helm install my-emqx .
|
||||||
|
```
|
||||||
|
|
||||||
|
+ From chart repos
|
||||||
|
```
|
||||||
|
helm repo add emqx https://repos.emqx.io/charts
|
||||||
|
helm install my-emqx emqx/emqx
|
||||||
|
```
|
||||||
|
> If you want to install an unstable version, you need to add `--devel` when you execute the `helm install` command.
|
||||||
|
|
||||||
|
# Uninstalling the Chart
|
||||||
|
To uninstall/delete the `my-emqx` deployment:
|
||||||
|
```
|
||||||
|
$ helm del my-emqx
|
||||||
|
```
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
The following table lists the configurable parameters of the emqx chart and their default values.
|
||||||
|
|
||||||
|
| Parameter | Description | Default Value |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `replicaCount` | It is recommended to have odd number of nodes in a cluster, otherwise the emqx cluster cannot be automatically healed in case of net-split. |3|
|
||||||
|
| `image.repository` | EMQ X Image name |emqx/emqx|
|
||||||
|
| `image.pullPolicy` | The image pull policy |IfNotPresent|
|
||||||
|
| `image.pullSecrets ` | The image pull secrets |`[]` (does not add image pull secrets to deployed pods)|
|
||||||
|
| `persistence.enabled` | Enable EMQX persistence using PVC |false|
|
||||||
|
| `persistence.storageClass` | Storage class of backing PVC |`nil` (uses alpha storage class annotation)|
|
||||||
|
| `persistence.existingClaim` | EMQ X data Persistent Volume existing claim name, evaluated as a template |""|
|
||||||
|
| `persistence.accessMode` | PVC Access Mode for EMQX volume |ReadWriteOnce|
|
||||||
|
| `persistence.size` | PVC Storage Request for EMQX volume |20Mi|
|
||||||
|
| `initContainers` | Containers that run before the creation of EMQX containers. They can contain utilities or setup scripts. |`{}`|
|
||||||
|
| `resources` | CPU/Memory resource requests/limits |{}|
|
||||||
|
| `nodeSelector` | Node labels for pod assignment |`{}`|
|
||||||
|
| `tolerations` | Toleration labels for pod assignment |`[]`|
|
||||||
|
| `affinity` | Map of node/pod affinities |`{}`|
|
||||||
|
| `service.type` | Kubernetes Service type. |ClusterIP|
|
||||||
|
| `service.mqtt` | Port for MQTT. |1883|
|
||||||
|
| `service.mqttssl` | Port for MQTT(SSL). |8883|
|
||||||
|
| `service.mgmt` | Port for mgmt API. |8081|
|
||||||
|
| `service.ws` | Port for WebSocket/HTTP. |8083|
|
||||||
|
| `service.wss` | Port for WSS/HTTPS. |8084|
|
||||||
|
| `service.dashboard` | Port for dashboard. |18083|
|
||||||
|
| `service.nodePorts.mqtt` | Kubernetes node port for MQTT. |nil|
|
||||||
|
| `service.nodePorts.mqttssl` | Kubernetes node port for MQTT(SSL). |nil|
|
||||||
|
| `service.nodePorts.mgmt` | Kubernetes node port for mgmt API. |nil|
|
||||||
|
| `service.nodePorts.ws` | Kubernetes node port for WebSocket/HTTP. |nil|
|
||||||
|
| `service.nodePorts.wss` | Kubernetes node port for WSS/HTTPS. |nil|
|
||||||
|
| `service.nodePorts.dashboard` | Kubernetes node port for dashboard. |nil|
|
||||||
|
| `service.loadBalancerIP` | loadBalancerIP for Service | nil |
|
||||||
|
| `service.loadBalancerSourceRanges` | Address(es) that are allowed when service is LoadBalancer | [] |
|
||||||
|
| `service.annotations` | Service annotations | {}(evaluated as a template)|
|
||||||
|
| `ingress.dashboard.enabled` | Enable ingress for EMQX Dashboard | false |
|
||||||
|
| `ingress.dashboard.path` | Ingress path for EMQX Dashboard | / |
|
||||||
|
| `ingress.dashboard.hosts` | Ingress hosts for EMQX Mgmt API | dashboard.emqx.local |
|
||||||
|
| `ingress.dashboard.tls` | Ingress tls for EMQX Mgmt API | [] |
|
||||||
|
| `ingress.dashboard.annotations` | Ingress annotations for EMQX Mgmt API | {} |
|
||||||
|
| `ingress.mgmt.enabled` | Enable ingress for EMQX Mgmt API | false |
|
||||||
|
| `ingress.mgmt.path` | Ingress path for EMQX Mgmt API | / |
|
||||||
|
| `ingress.mgmt.hosts` | Ingress hosts for EMQX Mgmt API | api.emqx.local |
|
||||||
|
| `ingress.mgmt.tls` | Ingress tls for EMQX Mgmt API | [] |
|
||||||
|
| `ingress.mgmt.annotations` | Ingress annotations for EMQX Mgmt API | {} |
|
||||||
|
| `emqxConfig` | Emqx configuration item, see the [documentation](https://hub.docker.com/r/emqx/emqx) | |
|
||||||
|
| `emqxAclConfig` | Emqx acl configuration item, see the [documentation](https://docs.emqx.io/broker/latest/en/advanced/acl-file.html) | |
|
|
@ -0,0 +1,150 @@
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: StatefulSet
|
||||||
|
metadata:
|
||||||
|
name: {{ include "emqx.fullname" . }}
|
||||||
|
namespace: {{ .Release.Namespace }}
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: {{ include "emqx.name" . }}
|
||||||
|
helm.sh/chart: {{ include "emqx.chart" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||||
|
spec:
|
||||||
|
serviceName: {{ include "emqx.fullname" . }}-headless
|
||||||
|
{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }}
|
||||||
|
volumeClaimTemplates:
|
||||||
|
- metadata:
|
||||||
|
name: emqx-data
|
||||||
|
namespace: {{ .Release.Namespace }}
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: {{ include "emqx.name" . }}
|
||||||
|
helm.sh/chart: {{ include "emqx.chart" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||||
|
annotations:
|
||||||
|
{{- if .Values.persistence.storageClass }}
|
||||||
|
volume.beta.kubernetes.io/storage-class: {{ .Values.persistence.storageClass | quote }}
|
||||||
|
{{- else }}
|
||||||
|
volume.alpha.kubernetes.io/storage-class: default
|
||||||
|
{{- end }}
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- {{ .Values.persistence.accessMode | quote }}
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: {{ .Values.persistence.size | quote }}
|
||||||
|
{{- end }}
|
||||||
|
updateStrategy:
|
||||||
|
type: RollingUpdate
|
||||||
|
replicas: {{ .Values.replicaCount }}
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: {{ include "emqx.name" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: {{ include "emqx.name" . }}
|
||||||
|
version: {{ .Chart.AppVersion }}
|
||||||
|
app.kubernetes.io/name: {{ include "emqx.name" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
spec:
|
||||||
|
volumes:
|
||||||
|
- name: emqx-acl
|
||||||
|
configMap:
|
||||||
|
name: {{ include "emqx.fullname" . }}-acl
|
||||||
|
items:
|
||||||
|
- key: acl.conf
|
||||||
|
path: acl.conf
|
||||||
|
{{- if not .Values.persistence.enabled }}
|
||||||
|
- name: emqx-data
|
||||||
|
emptyDir: {}
|
||||||
|
{{- else if .Values.persistence.existingClaim }}
|
||||||
|
- name: emqx-data
|
||||||
|
persistentVolumeClaim:
|
||||||
|
{{- with .Values.persistence.existingClaim }}
|
||||||
|
claimName: {{ tpl . $ }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.emqxLicneseSecretName }}
|
||||||
|
- name: emqx-license
|
||||||
|
secret:
|
||||||
|
secretName: {{ .Values.emqxLicneseSecretName }}
|
||||||
|
{{- end }}
|
||||||
|
serviceAccountName: {{ include "emqx.fullname" . }}
|
||||||
|
securityContext:
|
||||||
|
fsGroup: 1000
|
||||||
|
{{- if .Values.initContainers }}
|
||||||
|
initContainers:
|
||||||
|
{{ toYaml .Values.initContainers | indent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
containers:
|
||||||
|
- name: emqx
|
||||||
|
image: "{{ .Values.image.repository }}:{{ .Chart.AppVersion }}"
|
||||||
|
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||||
|
{{- if .Values.image.pullSecrets }}
|
||||||
|
imagePullSecrets:
|
||||||
|
{{- range .Values.image.pullSecrets }}
|
||||||
|
- name: {{ . }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
ports:
|
||||||
|
- name: mqtt
|
||||||
|
containerPort: {{ .Values.emqxConfig.EMQX_LISTENER__TCP__EXTERNAL | default 1883 }}
|
||||||
|
- name: mqttssl
|
||||||
|
containerPort: {{ .Values.emqxConfig.EMQX_LISTENER__SSL__EXTERNAL | default 8883 }}
|
||||||
|
- name: mgmt
|
||||||
|
containerPort: {{ .Values.emqxConfig.EMQX_MANAGEMENT__LISTENER__HTTP | default 8081 }}
|
||||||
|
- name: ws
|
||||||
|
containerPort: {{ .Values.emqxConfig.EMQX_LISTENER__WS__EXTERNAL | default 8083 }}
|
||||||
|
- name: wss
|
||||||
|
containerPort: {{ .Values.emqxConfig.EMQX_LISTENER__WSS__EXTERNAL | default 8084 }}
|
||||||
|
- name: dashboard
|
||||||
|
containerPort: {{ .Values.emqxConfig.EMQX_DASHBOARD__LISTENER__HTTP | default 18083 }}
|
||||||
|
- name: ekka
|
||||||
|
containerPort: 4370
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: {{ include "emqx.fullname" . }}-env
|
||||||
|
env:
|
||||||
|
- name: EMQX_NAME
|
||||||
|
value: {{ .Release.Name }}
|
||||||
|
- name: EMQX_CLUSTER__K8S__APP_NAME
|
||||||
|
value: {{ .Release.Name }}
|
||||||
|
- name: EMQX_CLUSTER__DISCOVERY
|
||||||
|
value: k8s
|
||||||
|
- name: EMQX_CLUSTER__K8S__SERVICE_NAME
|
||||||
|
value: {{ include "emqx.fullname" . }}-headless
|
||||||
|
- name: EMQX_CLUSTER__K8S__NAMESPACE
|
||||||
|
value: {{ .Release.Namespace }}
|
||||||
|
resources:
|
||||||
|
{{ toYaml .Values.resources | indent 12 }}
|
||||||
|
volumeMounts:
|
||||||
|
- name: emqx-data
|
||||||
|
mountPath: "/opt/emqx/data/mnesia"
|
||||||
|
- name: emqx-acl
|
||||||
|
mountPath: "/opt/emqx/etc/acl.conf"
|
||||||
|
subPath: "acl.conf"
|
||||||
|
{{ if .Values.emqxLicneseSecretName }}
|
||||||
|
- name: emqx-license
|
||||||
|
mountPath: "/opt/emqx/etc/emqx.lic"
|
||||||
|
subPath: "emqx.lic"
|
||||||
|
readOnly: true
|
||||||
|
{{ end }}
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /status
|
||||||
|
port: {{ .Values.emqxConfig.EMQX_MANAGEMENT__LISTENER__HTTP | default 8081 }}
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 5
|
||||||
|
{{- with .Values.nodeSelector }}
|
||||||
|
nodeSelector:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.affinity }}
|
||||||
|
affinity:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.tolerations }}
|
||||||
|
tolerations:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
|
@ -0,0 +1,32 @@
|
||||||
|
{{/* vim: set filetype=mustache: */}}
|
||||||
|
{{/*
|
||||||
|
Expand the name of the chart.
|
||||||
|
*/}}
|
||||||
|
{{- define "emqx.name" -}}
|
||||||
|
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create a default fully qualified app name.
|
||||||
|
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||||
|
If release name contains chart name it will be used as a full name.
|
||||||
|
*/}}
|
||||||
|
{{- define "emqx.fullname" -}}
|
||||||
|
{{- if .Values.fullnameOverride -}}
|
||||||
|
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- $name := default .Chart.Name .Values.nameOverride -}}
|
||||||
|
{{- if contains $name .Release.Name -}}
|
||||||
|
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create chart name and version as used by the chart label.
|
||||||
|
*/}}
|
||||||
|
{{- define "emqx.chart" -}}
|
||||||
|
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
|
||||||
|
{{- end -}}
|
|
@ -0,0 +1,14 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: {{ include "emqx.fullname" . }}-env
|
||||||
|
namespace: {{ .Release.Namespace }}
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: {{ include "emqx.name" . }}
|
||||||
|
helm.sh/chart: {{ include "emqx.chart" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||||
|
data:
|
||||||
|
{{- range $index, $value := .Values.emqxConfig}}
|
||||||
|
{{$index}}: "{{ $value }}"
|
||||||
|
{{- end}}
|
|
@ -0,0 +1,13 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: {{ include "emqx.fullname" . }}-acl
|
||||||
|
namespace: {{ .Release.Namespace }}
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: {{ include "emqx.name" . }}
|
||||||
|
helm.sh/chart: {{ include "emqx.chart" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||||
|
data:
|
||||||
|
"acl.conf": |
|
||||||
|
{{ .Values.emqxAclConfig }}
|
|
@ -0,0 +1,70 @@
|
||||||
|
{{- if .Values.ingress.dashboard.enabled -}}
|
||||||
|
{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||||
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
|
{{- else -}}
|
||||||
|
apiVersion: extensions/v1beta1
|
||||||
|
{{- end }}
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: {{ printf "%s-%s" (include "emqx.fullname" .) "dashboard" }}
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: {{ include "emqx.name" . }}
|
||||||
|
helm.sh/chart: {{ include "emqx.chart" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||||
|
{{- if .Values.ingress.dashboard.annotations }}
|
||||||
|
annotations:
|
||||||
|
{{- toYaml .Values.ingress.dashboard.annotations | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
{{- range $host := .Values.ingress.dashboard.hosts }}
|
||||||
|
- host: {{ $host }}
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
backend:
|
||||||
|
serviceName: {{ include "emqx.fullname" $ }}
|
||||||
|
servicePort: {{ $.Values.service.dashboard }}
|
||||||
|
{{- end -}}
|
||||||
|
{{- if .Values.ingress.dashboard.tls }}
|
||||||
|
tls:
|
||||||
|
{{- toYaml .Values.ingress.dashboard.tls | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
---
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.ingress.mgmt.enabled -}}
|
||||||
|
{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||||
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
|
{{- else -}}
|
||||||
|
apiVersion: extensions/v1beta1
|
||||||
|
{{- end }}
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: {{ printf "%s-%s" (include "emqx.fullname" .) "mgmt" }}
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: {{ include "emqx.name" . }}
|
||||||
|
helm.sh/chart: {{ include "emqx.chart" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||||
|
{{- if .Values.ingress.mgmt.annotations }}
|
||||||
|
annotations:
|
||||||
|
{{- toYaml .Values.ingress.mgmt.annotations | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
{{- range $host := .Values.ingress.mgmt.hosts }}
|
||||||
|
- host: {{ $host }}
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
backend:
|
||||||
|
serviceName: {{ include "emqx.fullname" $ }}
|
||||||
|
servicePort: {{ $.Values.service.mgmt }}
|
||||||
|
{{- end -}}
|
||||||
|
{{- if .Values.ingress.mgmt.tls }}
|
||||||
|
tls:
|
||||||
|
{{- toYaml .Values.ingress.mgmt.tls | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
---
|
||||||
|
{{- end }}
|
|
@ -0,0 +1,34 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
namespace: {{ .Release.Namespace }}
|
||||||
|
name: {{ include "emqx.fullname" . }}
|
||||||
|
---
|
||||||
|
kind: Role
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||||
|
metadata:
|
||||||
|
namespace: {{ .Release.Namespace }}
|
||||||
|
name: {{ include "emqx.fullname" . }}
|
||||||
|
rules:
|
||||||
|
- apiGroups:
|
||||||
|
- ""
|
||||||
|
resources:
|
||||||
|
- endpoints
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
|
- watch
|
||||||
|
- list
|
||||||
|
---
|
||||||
|
kind: RoleBinding
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||||
|
metadata:
|
||||||
|
namespace: {{ .Release.Namespace }}
|
||||||
|
name: {{ include "emqx.fullname" . }}
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: {{ include "emqx.fullname" . }}
|
||||||
|
namespace: {{ .Release.Namespace }}
|
||||||
|
roleRef:
|
||||||
|
kind: Role
|
||||||
|
name: {{ include "emqx.fullname" . }}
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
|
@ -0,0 +1,130 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: {{ include "emqx.fullname" . }}
|
||||||
|
namespace: {{ .Release.Namespace }}
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: {{ include "emqx.name" . }}
|
||||||
|
helm.sh/chart: {{ include "emqx.chart" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||||
|
{{- if .Values.service.annotations }}
|
||||||
|
annotations:
|
||||||
|
{{ toYaml .Values.service.annotations | indent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
spec:
|
||||||
|
type: {{ .Values.service.type }}
|
||||||
|
{{- if eq .Values.service.type "LoadBalancer" }}
|
||||||
|
{{- if .Values.service.loadBalancerIP }}
|
||||||
|
loadBalancerIP: {{ .Values.service.loadBalancerIP }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.service.loadBalancerSourceRanges }}
|
||||||
|
loadBalancerSourceRanges: {{- toYaml .Values.service.loadBalancerSourceRanges | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
ports:
|
||||||
|
- name: mqtt
|
||||||
|
port: {{ .Values.service.mqtt | default 1883 }}
|
||||||
|
protocol: TCP
|
||||||
|
targetPort: mqtt
|
||||||
|
{{- if and (or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer")) (not (empty .Values.service.nodePorts.mqtt)) }}
|
||||||
|
nodePort: {{ .Values.service.nodePorts.mqtt }}
|
||||||
|
{{- else if eq .Values.service.type "ClusterIP" }}
|
||||||
|
nodePort: null
|
||||||
|
{{- end }}
|
||||||
|
- name: mqttssl
|
||||||
|
port: {{ .Values.service.mqttssl | default 8883 }}
|
||||||
|
protocol: TCP
|
||||||
|
targetPort: mqttssl
|
||||||
|
{{- if and (or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer")) (not (empty .Values.service.nodePorts.mqttssl)) }}
|
||||||
|
nodePort: {{ .Values.service.nodePorts.mqttssl }}
|
||||||
|
{{- else if eq .Values.service.type "ClusterIP" }}
|
||||||
|
nodePort: null
|
||||||
|
{{- end }}
|
||||||
|
- name: mgmt
|
||||||
|
port: {{ .Values.service.mgmt | default 8081 }}
|
||||||
|
protocol: TCP
|
||||||
|
targetPort: mgmt
|
||||||
|
{{- if and (or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer")) (not (empty .Values.service.nodePorts.mgmt)) }}
|
||||||
|
nodePort: {{ .Values.service.nodePorts.mgmt }}
|
||||||
|
{{- else if eq .Values.service.type "ClusterIP" }}
|
||||||
|
nodePort: null
|
||||||
|
{{- end }}
|
||||||
|
- name: ws
|
||||||
|
port: {{ .Values.service.ws | default 8083 }}
|
||||||
|
protocol: TCP
|
||||||
|
targetPort: ws
|
||||||
|
{{- if and (or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer")) (not (empty .Values.service.nodePorts.ws)) }}
|
||||||
|
nodePort: {{ .Values.service.nodePorts.ws }}
|
||||||
|
{{- else if eq .Values.service.type "ClusterIP" }}
|
||||||
|
nodePort: null
|
||||||
|
{{- end }}
|
||||||
|
- name: wss
|
||||||
|
port: {{ .Values.service.wss | default 8084 }}
|
||||||
|
protocol: TCP
|
||||||
|
targetPort: wss
|
||||||
|
{{- if and (or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer")) (not (empty .Values.service.nodePorts.wss)) }}
|
||||||
|
nodePort: {{ .Values.service.nodePorts.wss }}
|
||||||
|
{{- else if eq .Values.service.type "ClusterIP" }}
|
||||||
|
nodePort: null
|
||||||
|
{{- end }}
|
||||||
|
- name: dashboard
|
||||||
|
port: {{ .Values.service.dashboard | default 18083 }}
|
||||||
|
protocol: TCP
|
||||||
|
targetPort: dashboard
|
||||||
|
{{- if and (or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer")) (not (empty .Values.service.nodePorts.dashboard)) }}
|
||||||
|
nodePort: {{ .Values.service.nodePorts.dashboard }}
|
||||||
|
{{- else if eq .Values.service.type "ClusterIP" }}
|
||||||
|
nodePort: null
|
||||||
|
{{- end }}
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/name: {{ include "emqx.name" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: {{ include "emqx.fullname" . }}-headless
|
||||||
|
namespace: {{ .Release.Namespace }}
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: {{ include "emqx.name" . }}
|
||||||
|
helm.sh/chart: {{ include "emqx.chart" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
sessionAffinity: None
|
||||||
|
clusterIP: None
|
||||||
|
ports:
|
||||||
|
- name: mqtt
|
||||||
|
port: {{ .Values.service.mqtt | default 1883 }}
|
||||||
|
protocol: TCP
|
||||||
|
targetPort: mqtt
|
||||||
|
- name: mqttssl
|
||||||
|
port: {{ .Values.service.mqttssl | default 8883 }}
|
||||||
|
protocol: TCP
|
||||||
|
targetPort: mqttssl
|
||||||
|
- name: mgmt
|
||||||
|
port: {{ .Values.service.mgmt | default 8081 }}
|
||||||
|
protocol: TCP
|
||||||
|
targetPort: mgmt
|
||||||
|
- name: ws
|
||||||
|
port: {{ .Values.service.ws | default 8083 }}
|
||||||
|
protocol: TCP
|
||||||
|
targetPort: ws
|
||||||
|
- name: wss
|
||||||
|
port: {{ .Values.service.wss | default 8084 }}
|
||||||
|
protocol: TCP
|
||||||
|
targetPort: wss
|
||||||
|
- name: dashboard
|
||||||
|
port: {{ .Values.service.dashboard | default 18083 }}
|
||||||
|
protocol: TCP
|
||||||
|
targetPort: dashboard
|
||||||
|
- name: ekka
|
||||||
|
port: 4370
|
||||||
|
protocol: TCP
|
||||||
|
targetPort: ekka
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/name: {{ include "emqx.name" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
|
@ -0,0 +1,158 @@
|
||||||
|
## Default values for emqx.
|
||||||
|
## This is a YAML-formatted file.
|
||||||
|
## Declare variables to be passed into your templates.
|
||||||
|
|
||||||
|
## It is recommended to have odd number of nodes in a cluster, otherwise the emqx cluster cannot be automatically healed in case of net-split.
|
||||||
|
replicaCount: 3
|
||||||
|
image:
|
||||||
|
repository: emqx/emqx
|
||||||
|
pullPolicy: IfNotPresent
|
||||||
|
## Optionally specify an array of imagePullSecrets.
|
||||||
|
## Secrets must be manually created in the namespace.
|
||||||
|
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
|
||||||
|
##
|
||||||
|
# pullSecrets:
|
||||||
|
# - myRegistryKeySecretName
|
||||||
|
|
||||||
|
persistence:
|
||||||
|
enabled: false
|
||||||
|
size: 20Mi
|
||||||
|
## If defined, volume.beta.kubernetes.io/storage-class: <storageClass>
|
||||||
|
## Default: volume.alpha.kubernetes.io/storage-class: default
|
||||||
|
# storageClass: "-"
|
||||||
|
accessMode: ReadWriteOnce
|
||||||
|
## Existing PersistentVolumeClaims
|
||||||
|
## The value is evaluated as a template
|
||||||
|
## So, for example, the name can depend on .Release or .Chart
|
||||||
|
# existingClaim: ""
|
||||||
|
|
||||||
|
resources: {}
|
||||||
|
# limits:
|
||||||
|
# cpu: 500m
|
||||||
|
# memory: 512Mi
|
||||||
|
# requests:
|
||||||
|
# cpu: 500m
|
||||||
|
# memory: 512Mi
|
||||||
|
|
||||||
|
# Containers that run before the creation of EMQX containers. They can contain utilities or setup scripts.
|
||||||
|
initContainers: {}
|
||||||
|
# - name: mysql-probe
|
||||||
|
# image: alpine
|
||||||
|
# command: ["sh", "-c", "for i in $(seq 1 300); do nc -zvw1 mysql 3306 && exit 0 || sleep 3; done; exit 1"]
|
||||||
|
|
||||||
|
## EMQX configuration item, see the documentation (https://github.com/emqx/emqx-docker#emq-x-configuration)
|
||||||
|
emqxConfig:
|
||||||
|
EMQX_CLUSTER__K8S__APISERVER: "https://kubernetes.default.svc:443"
|
||||||
|
## The address type is used to extract host from k8s service.
|
||||||
|
## Value: ip | dns | hostname
|
||||||
|
## Note:Hostname is only supported after v4.0-rc.2
|
||||||
|
EMQX_CLUSTER__K8S__ADDRESS_TYPE: "hostname"
|
||||||
|
EMQX_CLUSTER__K8S__SUFFIX: "svc.cluster.local"
|
||||||
|
## if EMQX_CLUSTER__K8S__ADDRESS_TYPE eq dns
|
||||||
|
# EMQX_CLUSTER__K8S__SUFFIX: "pod.cluster.local"
|
||||||
|
|
||||||
|
## --------------------------------------------------------------------
|
||||||
|
## [ACL](https://docs.emqx.io/broker/latest/en/advanced/acl-file.html)
|
||||||
|
|
||||||
|
## -type(who() :: all | binary() |
|
||||||
|
## {ipaddr, esockd_access:cidr()} |
|
||||||
|
## {client, binary()} |
|
||||||
|
## {user, binary()}).
|
||||||
|
|
||||||
|
## -type(access() :: subscribe | publish | pubsub).
|
||||||
|
|
||||||
|
## -type(topic() :: binary()).
|
||||||
|
|
||||||
|
## -type(rule() :: {allow, all} |
|
||||||
|
## {allow, who(), access(), list(topic())} |
|
||||||
|
## {deny, all} |
|
||||||
|
## {deny, who(), access(), list(topic())}).
|
||||||
|
## --------------------------------------------------------------------
|
||||||
|
emqxAclConfig: >
|
||||||
|
{allow, {user, "dashboard"}, subscribe, ["$SYS/#"]}.
|
||||||
|
{allow, {ipaddr, "127.0.0.1"}, pubsub, ["$SYS/#", "#"]}.
|
||||||
|
{deny, all, subscribe, ["$SYS/#", {eq, "#"}]}.
|
||||||
|
{allow, all}.
|
||||||
|
|
||||||
|
## EMQX Enterprise Edition requires manual creation of a Secret containing the licensed content. Write the name of Secret to the value of "emqxLicneseSecretName"
|
||||||
|
## Example:
|
||||||
|
## kubectl create secret generic emqx-license-secret-name --from-file=/path/to/emqx.lic
|
||||||
|
emqxLicneseSecretName:
|
||||||
|
|
||||||
|
service:
|
||||||
|
## Service type
|
||||||
|
##
|
||||||
|
type: ClusterIP
|
||||||
|
## Port for MQTT
|
||||||
|
##
|
||||||
|
mqtt: 1883
|
||||||
|
## Port for MQTT(SSL)
|
||||||
|
##
|
||||||
|
mqttssl: 8883
|
||||||
|
## Port for mgmt API
|
||||||
|
##
|
||||||
|
mgmt: 8081
|
||||||
|
## Port for WebSocket/HTTP
|
||||||
|
##
|
||||||
|
ws: 8083
|
||||||
|
## Port for WSS/HTTPS
|
||||||
|
##
|
||||||
|
wss: 8084
|
||||||
|
## Port for dashboard
|
||||||
|
##
|
||||||
|
dashboard: 18083
|
||||||
|
## Specify the nodePort(s) value for the LoadBalancer and NodePort service types.
|
||||||
|
## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport
|
||||||
|
##
|
||||||
|
nodePorts:
|
||||||
|
mqtt:
|
||||||
|
mqttssl:
|
||||||
|
mgmt:
|
||||||
|
ws:
|
||||||
|
wss:
|
||||||
|
dashboard:
|
||||||
|
## Set the LoadBalancer service type to internal only.
|
||||||
|
## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer
|
||||||
|
##
|
||||||
|
# loadBalancerIP:
|
||||||
|
## Load Balancer sources
|
||||||
|
## ref: https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service
|
||||||
|
## Example:
|
||||||
|
## loadBalancerSourceRanges:
|
||||||
|
## - 10.10.10.0/24
|
||||||
|
##
|
||||||
|
loadBalancerSourceRanges: []
|
||||||
|
## Provide any additional annotations which may be required. Evaluated as a template
|
||||||
|
##
|
||||||
|
annotations: {}
|
||||||
|
|
||||||
|
nodeSelector: {}
|
||||||
|
|
||||||
|
tolerations: []
|
||||||
|
|
||||||
|
affinity: {}
|
||||||
|
|
||||||
|
ingress:
|
||||||
|
## ingress for EMQX Dashboard
|
||||||
|
dashboard:
|
||||||
|
enabled: false
|
||||||
|
annotations: {}
|
||||||
|
# kubernetes.io/ingress.class: nginx
|
||||||
|
# kubernetes.io/tls-acme: "true"
|
||||||
|
path: /
|
||||||
|
hosts:
|
||||||
|
- dashboard.emqx.local
|
||||||
|
tls: []
|
||||||
|
|
||||||
|
## ingress for EMQX Mgmt API
|
||||||
|
mgmt:
|
||||||
|
enabled: false
|
||||||
|
annotations: {}
|
||||||
|
# kubernetes.io/ingress.class: nginx
|
||||||
|
# kubernetes.io/tls-acme: "true"
|
||||||
|
path: /
|
||||||
|
hosts:
|
||||||
|
- api.emqx.local
|
||||||
|
tls: []
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
ARG BUILD_FROM=emqx/build-env:erl22.3-alpine-amd64
|
||||||
|
ARG RUN_FROM=alpine:3.11
|
||||||
|
FROM ${BUILD_FROM} AS builder
|
||||||
|
|
||||||
|
ARG QEMU_ARCH=x86_64
|
||||||
|
COPY tmp/qemu-$QEMU_ARCH-stati* /usr/bin/
|
||||||
|
|
||||||
|
RUN apk add --no-cache \
|
||||||
|
git \
|
||||||
|
curl \
|
||||||
|
gcc \
|
||||||
|
g++ \
|
||||||
|
make \
|
||||||
|
perl \
|
||||||
|
ncurses-dev \
|
||||||
|
openssl-dev \
|
||||||
|
coreutils \
|
||||||
|
bsd-compat-headers \
|
||||||
|
libc-dev \
|
||||||
|
libstdc++ \
|
||||||
|
bash
|
||||||
|
|
||||||
|
COPY . /emqx
|
||||||
|
|
||||||
|
ARG PKG_VSN
|
||||||
|
ARG EMQX_NAME=emqx
|
||||||
|
|
||||||
|
RUN cd /emqx && make $EMQX_NAME
|
||||||
|
|
||||||
|
FROM $RUN_FROM
|
||||||
|
|
||||||
|
# Basic build-time metadata as defined at http://label-schema.org
|
||||||
|
LABEL org.label-schema.docker.dockerfile="Dockerfile" \
|
||||||
|
org.label-schema.license="GNU" \
|
||||||
|
org.label-schema.name="emqx" \
|
||||||
|
org.label-schema.version=${PKG_VSN} \
|
||||||
|
org.label-schema.description="EMQ (Erlang MQTT Broker) is a distributed, massively scalable, highly extensible MQTT messaging broker written in Erlang/OTP." \
|
||||||
|
org.label-schema.url="http://emqx.io" \
|
||||||
|
org.label-schema.vcs-type="Git" \
|
||||||
|
org.label-schema.vcs-url="https://github.com/emqx/emqx-docker" \
|
||||||
|
maintainer="Raymond M Mouthaan <raymondmmouthaan@gmail.com>, Huang Rui <vowstar@gmail.com>, EMQ X Team <support@emqx.io>"
|
||||||
|
|
||||||
|
ARG QEMU_ARCH=x86_64
|
||||||
|
ARG EMQX_NAME=emqx
|
||||||
|
|
||||||
|
COPY deploy/docker/docker-entrypoint.sh deploy/docker/start.sh tmp/qemu-$QEMU_ARCH-stati* /usr/bin/
|
||||||
|
COPY --from=builder /emqx/_build/$EMQX_NAME/rel/emqx /opt/emqx
|
||||||
|
|
||||||
|
RUN ln -s /opt/emqx/bin/* /usr/local/bin/
|
||||||
|
RUN apk add --no-cache curl ncurses-libs openssl sudo libstdc++ bash
|
||||||
|
|
||||||
|
WORKDIR /opt/emqx
|
||||||
|
|
||||||
|
RUN adduser -D -u 1000 emqx \
|
||||||
|
&& echo "emqx ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers
|
||||||
|
|
||||||
|
RUN chgrp -Rf emqx /opt/emqx && chmod -Rf g+w /opt/emqx \
|
||||||
|
&& chown -Rf emqx /opt/emqx
|
||||||
|
|
||||||
|
USER emqx
|
||||||
|
|
||||||
|
VOLUME ["/opt/emqx/log", "/opt/emqx/data", "/opt/emqx/lib", "/opt/emqx/etc"]
|
||||||
|
|
||||||
|
# emqx will occupy these port:
|
||||||
|
# - 1883 port for MQTT
|
||||||
|
# - 8081 for mgmt API
|
||||||
|
# - 8083 for WebSocket/HTTP
|
||||||
|
# - 8084 for WSS/HTTPS
|
||||||
|
# - 8883 port for MQTT(SSL)
|
||||||
|
# - 11883 port for internal MQTT/TCP
|
||||||
|
# - 18083 for dashboard
|
||||||
|
# - 4369 for port mapping (epmd)
|
||||||
|
# - 4370 for port mapping
|
||||||
|
# - 5369 for gen_rpc port mapping
|
||||||
|
# - 6369 for distributed node
|
||||||
|
EXPOSE 1883 8081 8083 8084 8883 11883 18083 4369 4370 5369 6369
|
||||||
|
|
||||||
|
ENTRYPOINT ["/usr/bin/docker-entrypoint.sh"]
|
||||||
|
|
||||||
|
CMD ["/usr/bin/start.sh"]
|
|
@ -0,0 +1,336 @@
|
||||||
|
# Quick reference
|
||||||
|
|
||||||
|
+ **Where to get help**:
|
||||||
|
|
||||||
|
https://emqx.io, https://github.com/emqx/emqx-rel, or https://github.com/emqx/emqx
|
||||||
|
|
||||||
|
+ **Where to file issues:**
|
||||||
|
|
||||||
|
https://github.com/emqx/emqx/issues
|
||||||
|
|
||||||
|
+ **Supported architectures**
|
||||||
|
|
||||||
|
`amd64`, `arm64v8`, `arm32v7`, `i386`, `s390x`
|
||||||
|
|
||||||
|
|
||||||
|
+ **Supported Docker versions**:
|
||||||
|
|
||||||
|
[the latest release](https://github.com/docker/docker-ce/releases/latest)
|
||||||
|
|
||||||
|
# What is EMQ X
|
||||||
|
|
||||||
|
[EMQ X MQTT broker](https://emqx.io/products/broker) is a fully open source, highly scalable, highly available distributed MQTT messaging broker for IoT, M2M and Mobile applications that can handle tens of millions of concurrent clients.
|
||||||
|
|
||||||
|
Starting from 3.0 release, *EMQ X* broker fully supports MQTT V5.0 protocol specifications and backward compatible with MQTT V3.1 and V3.1.1, as well as other communication protocols such as MQTT-SN, CoAP, LwM2M, WebSocket and STOMP. The 3.0 release of the *EMQ X* broker can scaled to 10+ million concurrent MQTT connections on one cluster.
|
||||||
|
|
||||||
|
# How to use this image
|
||||||
|
|
||||||
|
### Run emqx
|
||||||
|
|
||||||
|
Execute some command under this docker image
|
||||||
|
|
||||||
|
``docker run -d --name emqx emqx/emqx:$(tag)``
|
||||||
|
|
||||||
|
For example
|
||||||
|
|
||||||
|
``docker run -d --name emqx -p 18083:18083 -p 1883:1883 emqx/emqx:latest``
|
||||||
|
|
||||||
|
The emqx broker runs as linux user `emqx` in the docker container.
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
|
||||||
|
Use the environment variable to configure the EMQ X docker container.
|
||||||
|
|
||||||
|
The environment variables which with ``EMQX_`` prefix are mapped to configuration fils.
|
||||||
|
|
||||||
|
+ Prefix ``EMQX_`` is removed
|
||||||
|
+ All upper case letters is replaced with lower case letters
|
||||||
|
+ ``__`` is replaced with ``.``
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
EMQX_LISTENER__SSL__EXTERNAL__ACCEPTORS <--> listener.ssl.external.acceptors
|
||||||
|
EMQX_MQTT__MAX_PACKET_SIZE <--> mqtt.max_packet_size
|
||||||
|
```
|
||||||
|
|
||||||
|
Non mapped environment variables:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
EMQX_NAME
|
||||||
|
EMQX_HOST
|
||||||
|
```
|
||||||
|
|
||||||
|
These environment variables will ignore for configuration file.
|
||||||
|
|
||||||
|
#### EMQ X Configuration
|
||||||
|
|
||||||
|
> NOTE: All EMQ X Configuration in [etc/emqx.conf](https://github.com/emqx/emqx/blob/master/etc/emqx.conf) could config by environment. The following list is just an example, not a complete configuration.
|
||||||
|
|
||||||
|
| Options | Default | Mapped | Description |
|
||||||
|
| ---------------------------| ------------------ | ------------------------- | ------------------------------------- |
|
||||||
|
| EMQX_NAME | container name | none | emqx node short name |
|
||||||
|
| EMQX_HOST | container IP | none | emqx node host, IP or FQDN |
|
||||||
|
| EMQX_WAIT_TIME | 5 | none | wait time in sec before timeout |
|
||||||
|
| EMQX_NODE__NAME | EMQX_NAME@EMQX_HOST| node.name | Erlang node name, name@ipaddress/host |
|
||||||
|
| EMQX_NODE__COOKIE | emqx_dist_cookie | node.cookie | cookie for cluster |
|
||||||
|
| EMQX_LOG__CONSOLE | console | log.console | log console output method |
|
||||||
|
| EMQX_ALLOW_ANONYMOUS | true | allow_anonymous | allow mqtt anonymous login |
|
||||||
|
| EMQX_LISTENER__TCP__EXTERNAL| 1883 | listener.tcp.external | MQTT TCP port |
|
||||||
|
| EMQX_LISTENER__SSL__EXTERNAL| 8883 | listener.ssl.external | MQTT TCP TLS/SSL port |
|
||||||
|
| EMQX_LISTENER__WS__EXTERNAL | 8083 | listener.ws.external | HTTP and WebSocket port |
|
||||||
|
| EMQX_LISTENER__WSS__EXTERNAL| 8084 | listener.wss.external | HTTPS and WSS port |
|
||||||
|
| EMQX_LISTENER__API__MGMT | 8080 | listener.api.mgmt | MGMT API port |
|
||||||
|
| EMQX_MQTT__MAX_PACKET_SIZE | 64KB | mqtt.max_packet_size | Max Packet Size Allowed |
|
||||||
|
|
||||||
|
The list is incomplete and may changed with [etc/emqx.conf](https://github.com/emqx/emqx/blob/master/etc/emqx.conf) and plugin configuration files. But the mapping rule is similar.
|
||||||
|
|
||||||
|
If set ``EMQX_NAME`` and ``EMQX_HOST``, and unset ``EMQX_NODE__NAME``, ``EMQX_NODE__NAME=$EMQX_NAME@$EMQX_HOST``.
|
||||||
|
|
||||||
|
For example, set mqtt tcp port to 1883
|
||||||
|
|
||||||
|
``docker run -d --name emqx -e EMQX_LISTENER__TCP__EXTERNAL=1883 -p 18083:18083 -p 1883:1883 emqx/emqx:latest``
|
||||||
|
|
||||||
|
#### EMQ Loaded Modules Configuration
|
||||||
|
|
||||||
|
| Oprtions | Default | Description |
|
||||||
|
| ------------------------ | ------------------ | ------------------------------------- |
|
||||||
|
| EMQX_LOADED_MODULES | see content below | default modules emqx loaded |
|
||||||
|
|
||||||
|
Default environment variable ``EMQX_LOADED_MODULES``, including
|
||||||
|
|
||||||
|
+ ``emqx_mod_acl_internal``
|
||||||
|
+ ``emqx_mod_presence``
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# The default EMQX_LOADED_MODULES env
|
||||||
|
EMQX_LOADED_MODULES="emqx_mod_acl_internal,emqx_mod_acl_internal"
|
||||||
|
```
|
||||||
|
|
||||||
|
For example, set ``EMQX_LOADED_MODULES=emqx_mod_delayed,emqx_mod_rewrite`` to load these two modules.
|
||||||
|
|
||||||
|
You can use comma, space or other separator that you want.
|
||||||
|
|
||||||
|
All the modules defined in env ``EMQX_LOADED_MODULES`` will be loaded.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
EMQX_LOADED_MODULES="emqx_mod_delayed,emqx_mod_rewrite"
|
||||||
|
EMQX_LOADED_MODULES="emqx_mod_delayed emqx_mod_rewrite"
|
||||||
|
EMQX_LOADED_MODULES="emqx_mod_delayed | emqx_mod_rewrite"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### EMQ Loaded Plugins Configuration
|
||||||
|
|
||||||
|
| Oprtions | Default | Description |
|
||||||
|
| ------------------------ | ------------------ | ------------------------------------- |
|
||||||
|
| EMQX_LOADED_PLUGINS | see content below | default plugins emqx loaded |
|
||||||
|
|
||||||
|
Default environment variable ``EMQX_LOADED_PLUGINS``, including
|
||||||
|
|
||||||
|
+ ``emqx_recon``
|
||||||
|
+ ``emqx_retainer``
|
||||||
|
+ ``emqx_management``
|
||||||
|
+ ``emqx_dashboard``
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# The default EMQX_LOADED_PLUGINS env
|
||||||
|
EMQX_LOADED_PLUGINS="emqx_recon,emqx_retainer,emqx_management,emqx_dashboard"
|
||||||
|
```
|
||||||
|
|
||||||
|
For example, set ``EMQX_LOADED_PLUGINS= emqx_auth_redis,emqx_auth_mysql`` to load these two plugins.
|
||||||
|
|
||||||
|
You can use comma, space or other separator that you want.
|
||||||
|
|
||||||
|
All the plugins defined in ``EMQX_LOADED_PLUGINS`` will be loaded.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
EMQX_LOADED_PLUGINS="emqx_auth_redis,emqx_auth_mysql"
|
||||||
|
EMQX_LOADED_PLUGINS="emqx_auth_redis emqx_auth_mysql"
|
||||||
|
EMQX_LOADED_PLUGINS="emqx_auth_redis | emqx_auth_mysql"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### EMQ X Plugins Configuration
|
||||||
|
|
||||||
|
The environment variables which with ``EMQX_`` prefix are mapped to all emqx plugins' configuration file, ``.`` get replaced by ``__``.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
EMQX_AUTH__REDIS__SERVER <--> auth.redis.server
|
||||||
|
EMQX_AUTH__REDIS__PASSWORD <--> auth.redis.password
|
||||||
|
```
|
||||||
|
|
||||||
|
Don't worry about where to find the configuration file of emqx plugins, this docker image will find and config them automatically using some magic.
|
||||||
|
|
||||||
|
All plugin of emqx project could config in this way, following the environment variables mapping rule above.
|
||||||
|
|
||||||
|
Assume you are using redis auth plugin, for example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#EMQX_AUTH__REDIS__SERVER="redis.at.yourserver"
|
||||||
|
#EMQX_AUTH__REDIS__PASSWORD="password_for_redis"
|
||||||
|
|
||||||
|
docker run -d --name emqx -p 18083:18083 -p 1883:1883 -p 4369:4369 \
|
||||||
|
-e EMQX_LISTENER__TCP__EXTERNAL=1883 \
|
||||||
|
-e EMQX_LOADED_PLUGINS="emqx_auth_redis" \
|
||||||
|
-e EMQX_AUTH__REDIS__SERVER="your.redis.server:6379" \
|
||||||
|
-e EMQX_AUTH__REDIS__PASSWORD="password_for_redis" \
|
||||||
|
-e EMQX_AUTH__REDIS__PASSWORD_HASH=plain \
|
||||||
|
emqx/emqx:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
For numbered configuration options where the number is next to a ``.`` such as:
|
||||||
|
|
||||||
|
+ backend.redis.pool1.server
|
||||||
|
+ backend.redis.hook.message.publish.1
|
||||||
|
|
||||||
|
You can configure an arbitrary number of them as long as each has a uniq unber for it's own configuration option:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run -d --name emqx -p 18083:18083 -p 1883:1883 -p 4369:4369 \
|
||||||
|
-e EMQX_BACKEND_REDIS_POOL1__SERVER=127.0.0.1:6379
|
||||||
|
[...]
|
||||||
|
-e EMQX_BACKEND__REDIS__POOL5__SERVER=127.0.0.5:6379
|
||||||
|
-e EMQX_BACKEND__REDIS__HOOK_MESSAGE__PUBLISH__1='{"topic": "persistant/topic1", "action": {"function": "on_message_publish"}, "pool": "pool1"}'
|
||||||
|
-e EMQX_BACKEND__REDIS__HOOK_MESSAGE__PUBLISH__2='{"topic": "persistant/topic2", "action": {"function": "on_message_publish"}, "pool": "pool1"}'
|
||||||
|
-e EMQX_BACKEND__REDIS__HOOK_MESSAGE__PUBLISH__3='{"topic": "persistant/topic3", "action": {"function": "on_message_publish"}, "pool": "pool1"}'
|
||||||
|
[...]
|
||||||
|
-e EMQX_BACKEND__REDIS__HOOK_MESSAGE__PUBLISH__13='{"topic": "persistant/topic13", "action": {"function": "on_message_publish"}, "pool": "pool1"}'
|
||||||
|
emqx/emqx:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Mask Sensitive Configuration
|
||||||
|
|
||||||
|
Use ``MASK_CONFIG_FILTER`` to hide senstive configuration values from leaking to logging system.
|
||||||
|
|
||||||
|
For example, set ``MASK_CONFIG_FILTER="password|token"`` to hide all configuration names containing those keywords.
|
||||||
|
|
||||||
|
By default emqx masks the configuration using following filter `"password|passwd|key|token|secret"`. Setting ``MASK_CONFIG_FILTER`` will be merged with the default filter.
|
||||||
|
|
||||||
|
The configuration should match whole word (after splitting it by '.') with `MASK_CONFIG_FILTER`. You can use commas, spaces or other required separators to separate different words.
|
||||||
|
|
||||||
|
### Cluster
|
||||||
|
|
||||||
|
EMQ X supports a variety of clustering methods, see our [documentation](https://docs.emqx.io/broker/latest/en/advanced/cluster.html#emqx-service-discovery) for details.
|
||||||
|
|
||||||
|
Let's create a static node list cluster from docker-compose.
|
||||||
|
|
||||||
|
+ Create `docker-compose.yaml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
version: '3'
|
||||||
|
|
||||||
|
services:
|
||||||
|
emqx1:
|
||||||
|
image: emqx/emqx:v4.0.0
|
||||||
|
environment:
|
||||||
|
- "EMQX_NAME=emqx"
|
||||||
|
- "EMQX_HOST=node1.emqx.io"
|
||||||
|
- "EMQX_CLUSTER__DISCOVERY=static"
|
||||||
|
- "EMQX_CLUSTER__STATIC__SEEDS=emqx@node1.emqx.io, emqx@node2.emqx.io"
|
||||||
|
networks:
|
||||||
|
emqx-bridge:
|
||||||
|
aliases:
|
||||||
|
- node1.emqx.io
|
||||||
|
|
||||||
|
emqx2:
|
||||||
|
image: emqx/emqx:v4.0.0
|
||||||
|
environment:
|
||||||
|
- "EMQX_NAME=emqx"
|
||||||
|
- "EMQX_HOST=node2.emqx.io"
|
||||||
|
- "EMQX_CLUSTER__DISCOVERY=static"
|
||||||
|
- "EMQX_CLUSTER__STATIC__SEEDS=emqx@node1.emqx.io, emqx@node2.emqx.io"
|
||||||
|
networks:
|
||||||
|
emqx-bridge:
|
||||||
|
aliases:
|
||||||
|
- node2.emqx.io
|
||||||
|
|
||||||
|
networks:
|
||||||
|
emqx-bridge:
|
||||||
|
driver: bridge
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
+ Start the docker-compose cluster
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker-compose -p my_emqx up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
+ View cluster
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ docker exec -it my_emqx_emqx1_1 sh -c "emqx_ctl cluster status"
|
||||||
|
Cluster status: #{running_nodes => ['emqx@node1.emqx.io','emqx@node2.emqx.io'],
|
||||||
|
stopped_nodes => []}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Persistence
|
||||||
|
|
||||||
|
If you want to persist the EMQ X docker container, you need to keep the following directories:
|
||||||
|
|
||||||
|
+ `/opt/emqx/data`
|
||||||
|
+ `/opt/emqx/etc`
|
||||||
|
+ `/opt/emqx/log`
|
||||||
|
|
||||||
|
Since data in these folders are partially stored under the `/opt/emqx/data/mnesia/${node_name}`, the user also needs to reuse the same node name to see the previous state. In detail, one needs to specify the two environment variables: `EMQX_NAME` and `EMQX_HOST`, `EMQX_HOST` set as `127.0.0.1` or network alias would be useful.
|
||||||
|
|
||||||
|
In if you use docker-compose, the configuration would look something like this:
|
||||||
|
|
||||||
|
```YAML
|
||||||
|
volumes:
|
||||||
|
vol-emqx-data:
|
||||||
|
name: foo-emqx-data
|
||||||
|
vol-emqx-etc:
|
||||||
|
name: foo-emqx-etc
|
||||||
|
vol-emqx-log:
|
||||||
|
name: foo-emqx-log
|
||||||
|
|
||||||
|
services:
|
||||||
|
emqx:
|
||||||
|
image: emqx/emqx:v4.0.0
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
EMQX_NAME: foo_emqx
|
||||||
|
EMQX_HOST: 127.0.0.1
|
||||||
|
volumes:
|
||||||
|
- vol-emqx-data:/opt/emqx/data
|
||||||
|
- vol-emqx-etc:/opt/emqx/etc
|
||||||
|
- vol-emqx-log:/opt/emqx/log
|
||||||
|
```
|
||||||
|
|
||||||
|
### Kernel Tuning
|
||||||
|
|
||||||
|
Under linux host machine, the easiest way is [tuning host machine's kernel](https://docs.emqx.io/broker/latest/en/tutorial/turn.html#turning-guide).
|
||||||
|
|
||||||
|
If you want tune linux kernel by docker, you must ensure your docker is latest version (>=1.12).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
|
||||||
|
docker run -d --name emqx -p 18083:18083 -p 1883:1883 -p 4369:4369 \
|
||||||
|
--sysctl fs.file-max=2097152 \
|
||||||
|
--sysctl fs.nr_open=2097152 \
|
||||||
|
--sysctl net.core.somaxconn=32768 \
|
||||||
|
--sysctl net.ipv4.tcp_max_syn_backlog=16384 \
|
||||||
|
--sysctl net.core.netdev_max_backlog=16384 \
|
||||||
|
--sysctl net.ipv4.ip_local_port_range=1000 65535 \
|
||||||
|
--sysctl net.core.rmem_default=262144 \
|
||||||
|
--sysctl net.core.wmem_default=262144 \
|
||||||
|
--sysctl net.core.rmem_max=16777216 \
|
||||||
|
--sysctl net.core.wmem_max=16777216 \
|
||||||
|
--sysctl net.core.optmem_max=16777216 \
|
||||||
|
--sysctl net.ipv4.tcp_rmem=1024 4096 16777216 \
|
||||||
|
--sysctl net.ipv4.tcp_wmem=1024 4096 16777216 \
|
||||||
|
--sysctl net.ipv4.tcp_max_tw_buckets=1048576 \
|
||||||
|
--sysctl net.ipv4.tcp_fin_timeout=15 \
|
||||||
|
emqx/emqx:latest
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
> REMEMBER: DO NOT RUN EMQ X DOCKER PRIVILEGED OR MOUNT SYSTEM PROC IN CONTAINER TO TUNE LINUX KERNEL, IT IS UNSAFE.
|
||||||
|
|
||||||
|
### Thanks
|
||||||
|
|
||||||
|
+ [@je-al](https://github.com/emqx/emqx-docker/issues/2)
|
||||||
|
+ [@RaymondMouthaan](https://github.com/emqx/emqx-docker/pull/91)
|
||||||
|
+ [@zhongjiewu](https://github.com/emqx/emqx/issues/3427)
|
|
@ -0,0 +1,205 @@
|
||||||
|
#!/bin/bash
|
||||||
|
## EMQ docker image start script
|
||||||
|
# Huang Rui <vowstar@gmail.com>
|
||||||
|
# EMQ X Team <support@emqx.io>
|
||||||
|
|
||||||
|
## Shell setting
|
||||||
|
if [[ -n "$DEBUG" ]]; then
|
||||||
|
set -ex
|
||||||
|
else
|
||||||
|
set -e
|
||||||
|
fi
|
||||||
|
|
||||||
|
shopt -s nullglob
|
||||||
|
|
||||||
|
## Local IP address setting
|
||||||
|
|
||||||
|
LOCAL_IP=$(hostname -i | grep -oE '((25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])\.){3}(25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])' | head -n 1)
|
||||||
|
|
||||||
|
## EMQ Base settings and plugins setting
|
||||||
|
# Base settings in /opt/emqx/etc/emqx.conf
|
||||||
|
# Plugin settings in /opt/emqx/etc/plugins
|
||||||
|
|
||||||
|
_EMQX_HOME='/opt/emqx'
|
||||||
|
|
||||||
|
if [[ -z "$EMQX_NAME" ]]; then
|
||||||
|
EMQX_NAME="$(hostname)"
|
||||||
|
export EMQX_NAME
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$EMQX_HOST" ]]; then
|
||||||
|
if [[ "$EMQX_CLUSTER__K8S__ADDRESS_TYPE" == "dns" ]] && [[ -n "$EMQX_CLUSTER__K8S__NAMESPACE" ]]; then
|
||||||
|
EMQX_CLUSTER__K8S__SUFFIX=${EMQX_CLUSTER__K8S__SUFFIX:-"pod.cluster.local"}
|
||||||
|
EMQX_HOST="${LOCAL_IP//./-}.$EMQX_CLUSTER__K8S__NAMESPACE.$EMQX_CLUSTER__K8S__SUFFIX"
|
||||||
|
elif [[ "$EMQX_CLUSTER__K8S__ADDRESS_TYPE" == 'hostname' ]] && [[ -n "$EMQX_CLUSTER__K8S__NAMESPACE" ]]; then
|
||||||
|
EMQX_CLUSTER__K8S__SUFFIX=${EMQX_CLUSTER__K8S__SUFFIX:-'svc.cluster.local'}
|
||||||
|
EMQX_HOST=$(grep -h "^$LOCAL_IP" /etc/hosts | grep -o "$(hostname).*.$EMQX_CLUSTER__K8S__NAMESPACE.$EMQX_CLUSTER__K8S__SUFFIX")
|
||||||
|
else
|
||||||
|
EMQX_HOST="$LOCAL_IP"
|
||||||
|
fi
|
||||||
|
export EMQX_HOST
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$EMQX_WAIT_TIME" ]]; then
|
||||||
|
export EMQX_WAIT_TIME=5
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$EMQX_NODE_NAME" ]]; then
|
||||||
|
export EMQX_NODE_NAME="$EMQX_NAME@$EMQX_HOST"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set hosts to prevent cluster mode failed
|
||||||
|
|
||||||
|
if [[ -z "$EMQX_NODE__PROCESS_LIMIT" ]]; then
|
||||||
|
export EMQX_NODE__PROCESS_LIMIT=2097152
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$EMQX_NODE__MAX_PORTS" ]]; then
|
||||||
|
export EMQX_NODE__MAX_PORTS=1048576
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$EMQX_NODE__MAX_ETS_TABLES" ]]; then
|
||||||
|
export EMQX_NODE__MAX_ETS_TABLES=2097152
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$EMQX__LOG_CONSOLE" ]]; then
|
||||||
|
export EMQX__LOG_CONSOLE='console'
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$EMQX_LISTENER__TCP__EXTERNAL__ACCEPTORS" ]]; then
|
||||||
|
export EMQX_LISTENER__TCP__EXTERNAL__ACCEPTORS=64
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$EMQX_LISTENER__TCP__EXTERNAL__MAX_CLIENTS" ]]; then
|
||||||
|
export EMQX_LISTENER__TCP__EXTERNAL__MAX_CLIENTS=1000000
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$EMQX_LISTENER__SSL__EXTERNAL__ACCEPTORS" ]]; then
|
||||||
|
export EMQX_LISTENER__SSL__EXTERNAL__ACCEPTORS=32
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$EMQX_LISTENER__SSL__EXTERNAL__MAX_CLIENTS" ]]; then
|
||||||
|
export EMQX_LISTENER__SSL__EXTERNAL__MAX_CLIENTS=500000
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$EMQX_LISTENER__WS__EXTERNAL__ACCEPTORS" ]]; then
|
||||||
|
export EMQX_LISTENER__WS__EXTERNAL__ACCEPTORS=16
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$EMQX_LISTENER__WS__EXTERNAL__MAX_CLIENTS" ]]; then
|
||||||
|
export EMQX_LISTENER__WS__EXTERNAL__MAX_CLIENTS=250000
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Fix issue #42 - export env EMQX_DASHBOARD__DEFAULT_USER__PASSWORD to configure
|
||||||
|
# 'dashboard.default_user.password' in etc/plugins/emqx_dashboard.conf
|
||||||
|
if [[ -n "$EMQX_ADMIN_PASSWORD" ]]; then
|
||||||
|
export EMQX_DASHBOARD__DEFAULT_USER__PASSWORD=$EMQX_ADMIN_PASSWORD
|
||||||
|
fi
|
||||||
|
|
||||||
|
# echo value of $VAR hiding secrets if any
|
||||||
|
# SYNOPSIS
|
||||||
|
# echo_value KEY VALUE
|
||||||
|
echo_value() {
|
||||||
|
# get MASK_CONFIG
|
||||||
|
MASK_CONFIG_FILTER="$MASK_CONFIG_FILTER|password|passwd|key|token|secret"
|
||||||
|
FORMAT_MASK_CONFIG_FILTER=$(echo "$MASK_CONFIG_FILTER" | sed -r -e 's/^[^A-Za-z0-9_]+//' -e 's/[^A-Za-z0-9_]+$//' -e 's/[^A-Za-z0-9_]+/|/g')
|
||||||
|
local key=$1
|
||||||
|
local value=$2
|
||||||
|
# check if contains sensitive value
|
||||||
|
if echo "$key" | grep -iqwE "$FORMAT_MASK_CONFIG_FILTER"; then
|
||||||
|
echo "$key=***secret***"
|
||||||
|
else
|
||||||
|
echo "$key=$value"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# fill config on specific file if the key exists
|
||||||
|
# SYNOPSIS
|
||||||
|
# try_fill_config FILE KEY VALUE
|
||||||
|
try_fill_config() {
|
||||||
|
local file=$1
|
||||||
|
local key=$2
|
||||||
|
local value=$3
|
||||||
|
local escaped_key
|
||||||
|
# shellcheck disable=SC2001
|
||||||
|
escaped_key=$(echo "$key" | sed 's/[^a-zA-Z0-9_]/\\&/g')
|
||||||
|
local escaped_value
|
||||||
|
escaped_value=$(echo "$value" | sed 's/[\/&]/\\&/g')
|
||||||
|
if grep -qE "^[#[:space:]]*$escaped_key\s*=" "$file"; then
|
||||||
|
echo_value "$key" "$value"
|
||||||
|
if [[ -z "$value" ]]; then
|
||||||
|
sed -i -r "s/^[#[:space:]]*($escaped_key)\s*=\s*(.*)/# \1 = \2/" "$file"
|
||||||
|
else
|
||||||
|
sed -i -r "s/^[#[:space:]]*($escaped_key)\s*=\s*(.*)/\1 = $escaped_value/" "$file"
|
||||||
|
fi
|
||||||
|
# Check if config has a numbering system, but no existing configuration line in file
|
||||||
|
elif echo "$key" | grep -qE '\.\d+|\d+\.'; then
|
||||||
|
if [[ -n "$value" ]]; then
|
||||||
|
local template
|
||||||
|
template="$(echo "$escaped_key" | sed -r -e 's/\\\.[0-9]+/\\.[0-9]+/g' -e 's/[0-9]+\\\./[0-9]+\\./g')"
|
||||||
|
if grep -qE "^[#[:space:]]*$template\s*=" "$file"; then
|
||||||
|
echo_value "$key" "$value"
|
||||||
|
sed -i '$a'\\ "$file"
|
||||||
|
echo "$key = $value" >> "$file"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Catch all EMQX_ prefix environment variable and match it in configure file
|
||||||
|
CONFIG_FILE="$_EMQX_HOME/etc/emqx.conf"
|
||||||
|
CONFIG_PLUGINS="$_EMQX_HOME/etc/plugins"
|
||||||
|
for VAR in $(compgen -e); do
|
||||||
|
# Config normal keys such like node.name = emqx@127.0.0.1
|
||||||
|
if echo "$VAR" | grep -q '^EMQX_'; then
|
||||||
|
VAR_NAME=$(echo "$VAR" | sed -e 's/^EMQX_//' -e 's/__/./g' | tr '[:upper:]' '[:lower:]' | tr -d '[:cntrl:]')
|
||||||
|
VAR_VALUE=$(echo "${!VAR}" | tr -d '[:cntrl:]')
|
||||||
|
# Config in emqx.conf
|
||||||
|
try_fill_config "$CONFIG_FILE" "$VAR_NAME" "$VAR_VALUE"
|
||||||
|
# Config in plugins/*
|
||||||
|
for CONFIG_PLUGINS_FILE in "$CONFIG_PLUGINS"/*; do
|
||||||
|
try_fill_config "$CONFIG_PLUGINS_FILE" "$VAR_NAME" "$VAR_VALUE"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# fill tuples on specific file
|
||||||
|
# SYNOPSIS
|
||||||
|
# fill_tuples FILE [ELEMENTS ...]
|
||||||
|
fill_tuples() {
|
||||||
|
local file=$1
|
||||||
|
local elements=${*:2}
|
||||||
|
for var in $elements; do
|
||||||
|
if grep -qE "\{\s*$var\s*,\s*(true|false)\s*\}\s*\." "$file"; then
|
||||||
|
sed -i -r "s/\{\s*($var)\s*,\s*(true|false)\s*\}\s*\./{\1, true}./1" "$file"
|
||||||
|
elif grep -q "$var\s*\." "$file"; then
|
||||||
|
# backward compatible.
|
||||||
|
sed -i -r "s/($var)\s*\./{\1, true}./1" "$file"
|
||||||
|
else
|
||||||
|
sed -i '$a'\\ "$file"
|
||||||
|
echo "{$var, true}." >>"$file"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
## EMQX Plugin load settings
|
||||||
|
# Plugins loaded by default
|
||||||
|
LOADED_PLUGINS="$_EMQX_HOME/data/loaded_plugins"
|
||||||
|
if [[ -n "$EMQX_LOADED_PLUGINS" ]]; then
|
||||||
|
EMQX_LOADED_PLUGINS=$(echo "$EMQX_LOADED_PLUGINS" | tr -d '[:cntrl:]' | sed -r -e 's/^[^A-Za-z0-9_]+//g' -e 's/[^A-Za-z0-9_]+$//g' -e 's/[^A-Za-z0-9_]+/ /g')
|
||||||
|
echo "EMQX_LOADED_PLUGINS=$EMQX_LOADED_PLUGINS"
|
||||||
|
# Parse module names and place `{module_name, true}.` tuples in `loaded_plugins`.
|
||||||
|
fill_tuples "$LOADED_PLUGINS" "$EMQX_LOADED_PLUGINS"
|
||||||
|
fi
|
||||||
|
|
||||||
|
## EMQX Modules load settings
|
||||||
|
# Modules loaded by default
|
||||||
|
LOADED_MODULES="$_EMQX_HOME/data/loaded_modules"
|
||||||
|
if [[ -n "$EMQX_LOADED_MODULES" ]]; then
|
||||||
|
EMQX_LOADED_MODULES=$(echo "$EMQX_LOADED_MODULES" | tr -d '[:cntrl:]' | sed -r -e 's/^[^A-Za-z0-9_]+//g' -e 's/[^A-Za-z0-9_]+$//g' -e 's/[^A-Za-z0-9_]+/ /g')
|
||||||
|
echo "EMQX_LOADED_MODULES=$EMQX_LOADED_MODULES"
|
||||||
|
# Parse module names and place `{module_name, true}.` tuples in `loaded_modules`.
|
||||||
|
fill_tuples "$LOADED_MODULES" "$EMQX_LOADED_MODULES"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec "$@"
|
|
@ -0,0 +1,60 @@
|
||||||
|
#!/bin/sh
|
||||||
|
set -e -u
|
||||||
|
|
||||||
|
emqx_exit(){
|
||||||
|
# At least erlang.log.1 exists
|
||||||
|
if [ -f /opt/emqx/log/erlang.log.1 ]; then
|
||||||
|
# tail emqx.log.*
|
||||||
|
erlang_log=$(echo $(ls -t /opt/emqx/log/erlang.log.*) | awk '{print $1}')
|
||||||
|
num=$(sed -n -e '/LOGGING STARTED/=' ${erlang_log} | tail -1)
|
||||||
|
[ ! -z $num ] && [ $num -gt 2 ] && tail -n +$(expr $num - 2) ${erlang_log}
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "['$(date -u +"%Y-%m-%dT%H:%M:%SZ")']:emqx exit abnormally"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
## EMQ Main script
|
||||||
|
|
||||||
|
# When receiving the EXIT signal, execute emqx_exit function
|
||||||
|
trap "emqx_exit" EXIT
|
||||||
|
|
||||||
|
# Start and run emqx, and when emqx crashed, this container will stop
|
||||||
|
/opt/emqx/bin/emqx start
|
||||||
|
|
||||||
|
# Sleep 5 seconds to wait for the loaded plugins catch up.
|
||||||
|
sleep 5
|
||||||
|
|
||||||
|
echo "['$(date -u +"%Y-%m-%dT%H:%M:%SZ")']:emqx start"
|
||||||
|
|
||||||
|
## Fork tailing erlang.log, the fork is not killed after this script exits
|
||||||
|
## The assumption is that this is the docker entrypoint,
|
||||||
|
## hence docker container is terminated after entrypoint exists
|
||||||
|
tail -f /opt/emqx/log/erlang.log.1 &
|
||||||
|
|
||||||
|
# monitor emqx is running, or the docker must stop to let docker PaaS know
|
||||||
|
# warning: never use infinite loops such as `` while true; do sleep 1000; done`` here
|
||||||
|
# you must let user know emqx crashed and stop this container,
|
||||||
|
# and docker dispatching system can known and restart this container.
|
||||||
|
IDLE_TIME=0
|
||||||
|
MGMT_CONF='/opt/emqx/etc/plugins/emqx_management.conf'
|
||||||
|
MGMT_PORT=$(sed -n -r '/^management.listener.http[ \t]=[ \t].*$/p' $MGMT_CONF | sed -r 's/^management.listener.http = (.*)$/\1/g')
|
||||||
|
while [ $IDLE_TIME -lt 5 ]; do
|
||||||
|
IDLE_TIME=$(expr $IDLE_TIME + 1)
|
||||||
|
if curl http://localhost:${MGMT_PORT}/status >/dev/null 2>&1; then
|
||||||
|
IDLE_TIME=0
|
||||||
|
# Print the latest erlang.log
|
||||||
|
now_erlang_log=$(ps -ef |grep "tail -f /opt/emqx/log/erlang.log" |grep -v grep | sed -r "s/.*tail -f (.*)/\1/g")
|
||||||
|
new_erlang_log="$(ls -t /opt/emqx/log/erlang.log.* | head -1)"
|
||||||
|
if [ $now_erlang_log != $new_erlang_log ];then
|
||||||
|
tail -f $new_erlang_log &
|
||||||
|
kill $(ps -ef |grep "tail -f $now_erlang_log" | grep -v grep | awk '{print $1}')
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "['$(date -u +"%Y-%m-%dT%H:%M:%SZ")']:emqx not running, waiting for recovery in $((25-IDLE_TIME*5)) seconds"
|
||||||
|
fi
|
||||||
|
sleep 5
|
||||||
|
done
|
||||||
|
|
||||||
|
# If running to here (the result 5 times not is running, thus in 25s emqx is not running), exit docker image
|
||||||
|
# Then the high level PaaS, e.g. docker swarm mode, will know and alert, rebanlance this service
|
|
@ -0,0 +1,24 @@
|
||||||
|
emqx-packages
|
||||||
|
=============
|
||||||
|
|
||||||
|
EMQ X RPM/Debian Packages
|
||||||
|
|
||||||
|
NOTICE: Requires Erlang/OTP R21+ to build since 3.0 release.
|
||||||
|
|
||||||
|
How to use
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
```
|
||||||
|
cd project-root-directory-path
|
||||||
|
EMQX_DEPS_DEFAULT_VSN=${version} make emqx-pkg
|
||||||
|
```
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
|
||||||
|
Apache License Version 2.0
|
||||||
|
|
||||||
|
Author
|
||||||
|
------
|
||||||
|
|
||||||
|
EMQ X Team.
|
|
@ -0,0 +1,31 @@
|
||||||
|
# Keep this short to avoid bloating beam files with long file path info
|
||||||
|
TOPDIR := /tmp/emqx
|
||||||
|
SRCDIR := $(TOPDIR)/$(PKG_VSN)
|
||||||
|
BUILT := $(SRCDIR)/BUILT
|
||||||
|
|
||||||
|
EMQX_NAME=$(subst -pkg,,$(EMQX_BUILD))
|
||||||
|
|
||||||
|
TAR_PKG := $(EMQX_REL)/_build/$(EMQX_BUILD)/rel/emqx/emqx-$(PKG_VSN).tar.gz
|
||||||
|
SOURCE_PKG := $(EMQX_NAME)_$(PKG_VSN)_$(shell dpkg --print-architecture)
|
||||||
|
TARGET_PKG := $(EMQX_NAME)-$(SYSTEM)-$(PKG_VSN)-$(shell uname -m)
|
||||||
|
|
||||||
|
.PHONY: all
|
||||||
|
all: | $(BUILT)
|
||||||
|
cp -r debian $(SRCDIR)/
|
||||||
|
sed -i "s#<DATETIME>#$(shell date -u '+%a, %d %b %Y %T %z')#g" $(SRCDIR)/debian/changelog
|
||||||
|
sed -i "s#<VERSION>#$(PKG_VSN)#g" $(SRCDIR)/debian/changelog
|
||||||
|
if [ ! -z $(shell echo $(EMQX_NAME) |grep edge) ]; then \
|
||||||
|
sed -i "s/emqx-pkg/emqx-edge-pkg/g" $(SRCDIR)/debian/rules; \
|
||||||
|
sed -i "s debian/emqx debian/emqx-edge g" $(SRCDIR)/debian/rules; \
|
||||||
|
sed -i "s/Package: emqx/Package: emqx-edge/1" $(SRCDIR)/debian/control; \
|
||||||
|
fi
|
||||||
|
cd $(SRCDIR) && dpkg-buildpackage -us -uc
|
||||||
|
mkdir -p $(EMQX_REL)/_packages/$(EMQX_NAME)
|
||||||
|
cp $(SRCDIR)/../$(SOURCE_PKG).deb $(EMQX_REL)/_packages/$(EMQX_NAME)/$(TARGET_PKG).deb
|
||||||
|
|
||||||
|
$(BUILT):
|
||||||
|
mkdir -p $(TOPDIR) $(SRCDIR)
|
||||||
|
tar zxf $(TAR_PKG) -C $(SRCDIR)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(SRCDIR)
|
|
@ -0,0 +1,5 @@
|
||||||
|
emqx (<VERSION>) unstable; urgency=medium
|
||||||
|
|
||||||
|
* See github commit history: https://github.com/emqx/emqx
|
||||||
|
|
||||||
|
-- emqx <contact@emqx.io> <DATETIME>
|
|
@ -0,0 +1 @@
|
||||||
|
9
|
|
@ -0,0 +1,12 @@
|
||||||
|
Source: emqx
|
||||||
|
Section: unknown
|
||||||
|
Priority: optional
|
||||||
|
Maintainer: emqx <contact@emqx.io>
|
||||||
|
Build-Depends: debhelper (>=9)
|
||||||
|
Standards-Version: 3.9.6
|
||||||
|
Homepage: https://www.emqx.io
|
||||||
|
|
||||||
|
Package: emqx
|
||||||
|
Architecture: any
|
||||||
|
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||||
|
Description: EMQX, a distributed, massively scalable, highly extensible MQTT message broker written in Erlang/OTP
|
|
@ -0,0 +1,202 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright {yyyy} {name of copyright owner}
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
|
@ -0,0 +1,150 @@
|
||||||
|
#! /bin/bash
|
||||||
|
### BEGIN INIT INFO
|
||||||
|
# Provides: emqx
|
||||||
|
# Required-Start: $remote_fs $syslog
|
||||||
|
# Required-Stop: $remote_fs $syslog
|
||||||
|
# Default-Start: 2 3 4 5
|
||||||
|
# Default-Stop: 0 1 6
|
||||||
|
# Short-Description: Erlang MQTT Broker
|
||||||
|
# Description: EMQX, a distributed, massively scalable, highly extensible MQTT message broker written in Erlang/OT
|
||||||
|
### END INIT INFO
|
||||||
|
|
||||||
|
NAME=emqx
|
||||||
|
DAEMON=/usr/bin/$NAME
|
||||||
|
SCRIPTNAME=/etc/init.d/$NAME
|
||||||
|
|
||||||
|
# Read configuration variable file if it is present
|
||||||
|
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
|
||||||
|
|
||||||
|
# Load the VERBOSE setting and other rcS variables
|
||||||
|
. /lib/init/vars.sh
|
||||||
|
. /lib/lsb/init-functions
|
||||||
|
|
||||||
|
# `service` strips all environmental VARS so
|
||||||
|
# if no HOME was set in /etc/default/$NAME then set one here
|
||||||
|
# to the data directory for erlexec's sake
|
||||||
|
if [ -z "$HOME" ]; then
|
||||||
|
export HOME=/var/lib/emqx
|
||||||
|
fi
|
||||||
|
|
||||||
|
#
|
||||||
|
# Function that starts the daemon/service
|
||||||
|
#
|
||||||
|
do_start()
|
||||||
|
{
|
||||||
|
# Return
|
||||||
|
# 0 if daemon has been started
|
||||||
|
# 1 if daemon was already running
|
||||||
|
# 2 if daemon could not be started
|
||||||
|
|
||||||
|
# Startup with the appropriate user
|
||||||
|
start-stop-daemon --start \
|
||||||
|
--name emqx \
|
||||||
|
--user emqx \
|
||||||
|
--exec $DAEMON -- start \
|
||||||
|
|| return 2
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Function that stops the daemon/service
|
||||||
|
#
|
||||||
|
do_stop()
|
||||||
|
{
|
||||||
|
# Identify the erts directory
|
||||||
|
ERTS_PATH=`$DAEMON ertspath`
|
||||||
|
|
||||||
|
# Attempt a clean shutdown.
|
||||||
|
$DAEMON stop
|
||||||
|
|
||||||
|
# waiting stop done sleep 5
|
||||||
|
sleep 5
|
||||||
|
|
||||||
|
# Return
|
||||||
|
# 0 if daemon has been stopped
|
||||||
|
# 1 if daemon was already stopped
|
||||||
|
# 2 if daemon could not be stopped
|
||||||
|
# other if a failure occurred
|
||||||
|
# Make sure it's down by using a more direct approach
|
||||||
|
start-stop-daemon --stop \
|
||||||
|
--quiet \
|
||||||
|
--retry=TERM/30/KILL/5 \
|
||||||
|
--user emqx \
|
||||||
|
--exec $ERTS_PATH/run_erl
|
||||||
|
return $?
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Function that graceful reload the daemon/service
|
||||||
|
#
|
||||||
|
do_reload() {
|
||||||
|
# Restart the VM without exiting the process
|
||||||
|
$DAEMON restart && return $? || return 2
|
||||||
|
}
|
||||||
|
|
||||||
|
# Checks the status of a node
|
||||||
|
do_status() {
|
||||||
|
$DAEMON ping && echo $"$NAME is running" && return 0
|
||||||
|
echo $"$NAME is stopped" && return 2
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
log_daemon_msg "Starting $NAME"
|
||||||
|
$DAEMON ping >/dev/null 2>&1 && echo $"$NAME is already running" && exit 0
|
||||||
|
do_start
|
||||||
|
case "$?" in
|
||||||
|
0|1) log_end_msg 0 ;;
|
||||||
|
2) log_end_msg 1
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
log_daemon_msg "Stopping $NAME"
|
||||||
|
do_stop
|
||||||
|
case "$?" in
|
||||||
|
0|1) log_end_msg 0 ;;
|
||||||
|
2) log_end_msg 1
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
ping)
|
||||||
|
# See if the VM is alive
|
||||||
|
$DAEMON ping || exit $?
|
||||||
|
;;
|
||||||
|
reload|force-reload)
|
||||||
|
log_daemon_msg "Reloading $NAME"
|
||||||
|
do_reload
|
||||||
|
ES=$?
|
||||||
|
log_end_msg $ES
|
||||||
|
exit $ES
|
||||||
|
;;
|
||||||
|
restart)
|
||||||
|
log_daemon_msg "Restarting $NAME"
|
||||||
|
do_stop
|
||||||
|
case "$?" in
|
||||||
|
0|1)
|
||||||
|
do_start
|
||||||
|
case "$?" in
|
||||||
|
0) log_end_msg 0 ;;
|
||||||
|
1) log_end_msg 1 && exit 1 ;; # Old process is still running
|
||||||
|
*) log_end_msg 1 && exit 1 ;; # Failed to start
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
# Failed to stop
|
||||||
|
log_end_msg 1 && exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
do_status && exit 0 || exit $?
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: $SCRIPTNAME {start|stop|ping|restart|force-reload|status}" >&2
|
||||||
|
exit 3
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# postinst script for emqx
|
||||||
|
#
|
||||||
|
# see: dh_installdeb(1)
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# install startup script
|
||||||
|
update-rc.d emqx defaults >/dev/null
|
||||||
|
|
||||||
|
# create group
|
||||||
|
if ! getent group emqx >/dev/null; then
|
||||||
|
addgroup --system emqx
|
||||||
|
fi
|
||||||
|
|
||||||
|
# create user
|
||||||
|
if ! getent passwd emqx >/dev/null; then
|
||||||
|
adduser --ingroup emqx \
|
||||||
|
--home /var/lib/emqx \
|
||||||
|
--disabled-password \
|
||||||
|
--system --shell /bin/bash --no-create-home \
|
||||||
|
--gecos "emqx user" emqx
|
||||||
|
fi
|
||||||
|
|
||||||
|
for i in lib run log; do
|
||||||
|
chown -R emqx:emqx /var/$i/emqx
|
||||||
|
done
|
||||||
|
|
||||||
|
chown -R emqx:emqx /usr/lib/emqx
|
||||||
|
chown -R emqx:emqx /etc/emqx
|
||||||
|
|
||||||
|
chmod 0755 /var/run/emqx /etc/emqx
|
||||||
|
chmod 0644 /etc/emqx/*
|
||||||
|
chmod -R +X /etc/emqx
|
||||||
|
chmod -R 0755 /usr/lib/emqx/bin
|
||||||
|
[ -f /usr/bin/emqx ] && rm /usr/bin/emqx
|
||||||
|
[ -f /usr/bin/emqx_ctl ] && rm /usr/bin/emqx_ctl
|
||||||
|
ln -s /usr/lib/emqx/bin/emqx /usr/bin/emqx
|
||||||
|
ln -s /usr/lib/emqx/bin/emqx_ctl /usr/bin/emqx_ctl
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
configure)
|
||||||
|
;;
|
||||||
|
|
||||||
|
abort-upgrade|abort-remove|abort-deconfigure)
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "postinst called with unknown argument \`$1'" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# dh_installdeb will replace this with shell code automatically
|
||||||
|
# generated by other debhelper scripts.
|
||||||
|
|
||||||
|
#DEBHELPER#
|
||||||
|
|
||||||
|
exit 0
|
|
@ -0,0 +1,82 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# postrm script for emqx
|
||||||
|
#
|
||||||
|
# see: dh_installdeb(1)
|
||||||
|
|
||||||
|
|
||||||
|
# summary of how this script can be called:
|
||||||
|
# * <postrm> `remove'
|
||||||
|
# * <postrm> `purge'
|
||||||
|
# * <old-postrm> `upgrade' <new-version>
|
||||||
|
# * <new-postrm> `failed-upgrade' <old-version>
|
||||||
|
# * <new-postrm> `abort-install'
|
||||||
|
# * <new-postrm> `abort-install' <old-version>
|
||||||
|
# * <new-postrm> `abort-upgrade' <old-version>
|
||||||
|
# * <disappearer's-postrm> `disappear' <overwriter>
|
||||||
|
# <overwriter-version>
|
||||||
|
# for details, see http://www.debian.org/doc/debian-policy/ or
|
||||||
|
# the debian-policy package
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
purge)
|
||||||
|
rm -f /etc/default/emqx
|
||||||
|
|
||||||
|
# ensure we remove the rc.d scripts installed by postinst
|
||||||
|
update-rc.d emqx remove >/dev/null
|
||||||
|
|
||||||
|
if [ -d /var/lib/emqx ]; then
|
||||||
|
rm -r /var/lib/emqx
|
||||||
|
fi
|
||||||
|
if [ -d /var/log/emqx ]; then
|
||||||
|
rm -r /var/log/emqx
|
||||||
|
fi
|
||||||
|
if [ -d /var/run/emqx ]; then
|
||||||
|
rm -r /var/run/emqx
|
||||||
|
fi
|
||||||
|
if [ -d /etc/emqx ]; then
|
||||||
|
rm -r /etc/emqx
|
||||||
|
fi
|
||||||
|
if [ -e /etc/init.d/emqx ]; then
|
||||||
|
rm /etc/init.d/emqx
|
||||||
|
fi
|
||||||
|
# Remove User & Group, killing any process owned by them
|
||||||
|
if getent passwd emqx >/dev/null; then
|
||||||
|
pkill -u emqx || true
|
||||||
|
deluser --quiet --system emqx
|
||||||
|
fi
|
||||||
|
if getent group emqx >/dev/null; then
|
||||||
|
delgroup --quiet --system --only-if-empty emqx || true
|
||||||
|
fi
|
||||||
|
if [ -f /usr/bin/emqx ]; then
|
||||||
|
rm /usr/bin/emqx
|
||||||
|
fi
|
||||||
|
if [ -f /usr/bin/emqx_ctl ]; then
|
||||||
|
rm /usr/bin/emqx_ctl
|
||||||
|
fi
|
||||||
|
if [ -d /usr/lib/emqx ]; then
|
||||||
|
rm -r /usr/lib/emqx
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
remove)
|
||||||
|
rm /usr/bin/emqx
|
||||||
|
rm /usr/bin/emqx_ctl
|
||||||
|
;;
|
||||||
|
|
||||||
|
upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "postrm called with unknown argument \`$1\`" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# dh_installdeb will replace this with shell code automatically
|
||||||
|
# generated by other debhelper scripts.
|
||||||
|
|
||||||
|
#DEBHELPER#
|
||||||
|
|
||||||
|
exit 0
|
|
@ -0,0 +1,65 @@
|
||||||
|
#!/usr/bin/make -f
|
||||||
|
# -*- makefile -*-
|
||||||
|
# Sample debian/rules that uses debhelper.
|
||||||
|
# This file was originally written by Joey Hess and Craig Small.
|
||||||
|
# As a special exception, when this file is copied by dh-make into a
|
||||||
|
# dh-make output file, you may use that output file without restriction.
|
||||||
|
# This special exception was added by Craig Small in version 0.37 of dh-make.
|
||||||
|
|
||||||
|
# modified for node_package by dizzyd@basho.com and jared@basho.com
|
||||||
|
|
||||||
|
# Uncomment this to turn on verbose mode.
|
||||||
|
export DH_VERBOSE=1
|
||||||
|
|
||||||
|
|
||||||
|
## Clear variables that may confound our build of sub-projects; also
|
||||||
|
## note that it is necessary to use overlay_vars relative to .. as
|
||||||
|
## the generate command EXECUTES in rel/
|
||||||
|
build:
|
||||||
|
|
||||||
|
clean:
|
||||||
|
dh_clean
|
||||||
|
rm -f build
|
||||||
|
# make clean
|
||||||
|
|
||||||
|
## dh_shlibdeps was added to figure out the dependencies on shared libraries
|
||||||
|
## and will populate the ${shlibs:Depends} callout in the control file
|
||||||
|
install: build
|
||||||
|
dh_testdir
|
||||||
|
dh_testroot
|
||||||
|
dh_prep
|
||||||
|
dh_installdirs
|
||||||
|
mkdir -p debian/emqx/usr/lib/emqx
|
||||||
|
mkdir -p debian/emqx/var/lib/emqx
|
||||||
|
mkdir -p debian/emqx/var/run/emqx
|
||||||
|
mkdir -p debian/emqx/var/log/emqx
|
||||||
|
|
||||||
|
mkdir -p debian/emqx/usr/lib/emqx/bin
|
||||||
|
|
||||||
|
mkdir -p debian/emqx/etc/emqx
|
||||||
|
mkdir -p debian/emqx/etc/init.d
|
||||||
|
|
||||||
|
cp bin/* debian/emqx/usr/lib/emqx/bin
|
||||||
|
|
||||||
|
cp -R lib debian/emqx/usr/lib/emqx
|
||||||
|
cp -R erts* debian/emqx/usr/lib/emqx
|
||||||
|
cp -R releases debian/emqx/usr/lib/emqx
|
||||||
|
cp -R etc/* debian/emqx/etc/emqx
|
||||||
|
cp -R data/* debian/emqx/var/lib/emqx
|
||||||
|
install -m755 debian/init.script debian/emqx/etc/init.d/emqx
|
||||||
|
|
||||||
|
dh_shlibdeps
|
||||||
|
|
||||||
|
# We have nothing to do by default.
|
||||||
|
binary-indep: install build-stamp
|
||||||
|
build-stamp:
|
||||||
|
|
||||||
|
# Build architecture-dependent files here.
|
||||||
|
binary-arch: install
|
||||||
|
dh_strip -a
|
||||||
|
dh_compress -a
|
||||||
|
dh_installdeb
|
||||||
|
dh_gencontrol
|
||||||
|
dh_builddeb
|
||||||
|
|
||||||
|
binary: binary-indep binary-arch
|
|
@ -0,0 +1,62 @@
|
||||||
|
# Keep this short to avoid bloating beam files with long file path info
|
||||||
|
TOPDIR := /tmp/emqx
|
||||||
|
SRCDIR := $(TOPDIR)/$(PKG_VSN)
|
||||||
|
BUILT := $(SRCDIR)/BUILT
|
||||||
|
dash := -
|
||||||
|
none :=
|
||||||
|
space := $(none) $(none)
|
||||||
|
RPM_VSN ?= $(shell echo $(PKG_VSN) | grep -oE "[0-9]+\.[0-9]+(\.[0-9]+)?")
|
||||||
|
RPM_REL ?= $(shell echo $(PKG_VSN) | grep -oE "(alpha|beta|rc)\.[0-9]")
|
||||||
|
|
||||||
|
ARCH:=$(shell uname -m)
|
||||||
|
ifeq ($(ARCH),mips64)
|
||||||
|
ARCH:=mips64el
|
||||||
|
endif
|
||||||
|
|
||||||
|
EMQX_NAME=$(subst -pkg,,$(EMQX_BUILD))
|
||||||
|
|
||||||
|
TAR_PKG := $(EMQX_REL)/_build/$(EMQX_BUILD)/rel/emqx/emqx-$(PKG_VSN).tar.gz
|
||||||
|
TARGET_PKG := $(EMQX_NAME)-$(SYSTEM)-$(PKG_VSN)-$(ARCH)
|
||||||
|
ifeq ($(RPM_REL),)
|
||||||
|
# no tail
|
||||||
|
RPM_REL := 1
|
||||||
|
endif
|
||||||
|
SOURCE_PKG := emqx-$(SYSTEM)-$(RPM_VSN)-$(RPM_REL).$(ARCH)
|
||||||
|
|
||||||
|
SYSTEMD := $(shell if command -v systemctl >/dev/null 2>&1; then echo yes; fi)
|
||||||
|
# Not $(PWD) as it does not work for make -C
|
||||||
|
CURDIR := $(shell pwd)
|
||||||
|
|
||||||
|
SERVICE_SRC := $(if $(SYSTEMD),$(CURDIR)/emqx.service,$(CURDIR)/init.script)
|
||||||
|
SERVICE_DST := $(if $(SYSTEMD),%{_unitdir}/emqx.service,%{_initddir}/emqx)
|
||||||
|
|
||||||
|
POST_ADDITION := $(if $(SYSTEMD),%systemd_post %{_name}.service,echo post)
|
||||||
|
PREUN_ADDITION := $(if $(SYSTEMD),%systemd_preun %{_name}.service,echo preun)
|
||||||
|
|
||||||
|
.PHONY: all
|
||||||
|
all: | $(BUILT)
|
||||||
|
cd $(SRCDIR)
|
||||||
|
rpmbuild -v -bb \
|
||||||
|
--define "_package_name $(EMQX_NAME)" \
|
||||||
|
--define "_name emqx" \
|
||||||
|
--define "_topdir $(TOPDIR)" \
|
||||||
|
--define "_version $(RPM_VSN)" \
|
||||||
|
--define "_reldir $(SRCDIR)" \
|
||||||
|
--define "_release $(RPM_REL)" \
|
||||||
|
--define "_service_src $(SERVICE_SRC)" \
|
||||||
|
--define "_service_dst $(SERVICE_DST)" \
|
||||||
|
--define "_post_addition $(POST_ADDITION)" \
|
||||||
|
--define "_preun_addition $(PREUN_ADDITION)" \
|
||||||
|
--define "_ostype -$(SYSTEM)" \
|
||||||
|
--define "_sharedstatedir /var/lib" \
|
||||||
|
emqx.spec
|
||||||
|
mkdir -p $(EMQX_REL)/_packages/$(EMQX_NAME)
|
||||||
|
cp $(TOPDIR)/RPMS/$(ARCH)/$(SOURCE_PKG).rpm $(EMQX_REL)/_packages/$(EMQX_NAME)/$(TARGET_PKG).rpm
|
||||||
|
|
||||||
|
$(BUILT):
|
||||||
|
mkdir -p $(TOPDIR) $(SRCDIR) $(SRCDIR)/BUILT
|
||||||
|
tar zxf $(TAR_PKG) -C $(SRCDIR)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(SRCDIR)
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
[Unit]
|
||||||
|
Description=emqx daemon
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
User=emqx
|
||||||
|
Group=emqx
|
||||||
|
Type=forking
|
||||||
|
Environment=HOME=/var/lib/emqx
|
||||||
|
ExecStart=/bin/sh /usr/bin/emqx start
|
||||||
|
LimitNOFILE=1048576
|
||||||
|
ExecStop=/bin/sh /usr/bin/emqx stop
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
|
@ -0,0 +1,102 @@
|
||||||
|
%define debug_package %{nil}
|
||||||
|
%define _user %{_name}
|
||||||
|
%define _group %{_name}
|
||||||
|
%define _conf_dir %{_sysconfdir}/%{_name}
|
||||||
|
%define _log_dir %{_var}/log/%{_name}
|
||||||
|
%define _lib_home /usr/lib/%{_name}
|
||||||
|
%define _var_home %{_sharedstatedir}/%{_name}
|
||||||
|
%define _build_name_fmt %{_arch}/%{_name}%{?_ostype}-%{_version}-%{_release}.%{_arch}.rpm
|
||||||
|
%define _build_id_links none
|
||||||
|
|
||||||
|
Name: %{_package_name}
|
||||||
|
Version: %{_version}
|
||||||
|
Release: %{_release}%{?dist}
|
||||||
|
Summary: emqx
|
||||||
|
Group: System Environment/Daemons
|
||||||
|
License: Apache License Version 2.0
|
||||||
|
URL: https://www.emqx.io
|
||||||
|
BuildRoot: %{_tmppath}/%{_name}-%{_version}-root
|
||||||
|
Provides: %{_name}
|
||||||
|
AutoReq: 0
|
||||||
|
|
||||||
|
%description
|
||||||
|
EMQX, a distributed, massively scalable, highly extensible MQTT message broker written in Erlang/OTP.
|
||||||
|
|
||||||
|
%prep
|
||||||
|
|
||||||
|
%build
|
||||||
|
|
||||||
|
%install
|
||||||
|
mkdir -p %{buildroot}%{_lib_home}
|
||||||
|
mkdir -p %{buildroot}%{_log_dir}
|
||||||
|
mkdir -p %{buildroot}%{_unitdir}
|
||||||
|
mkdir -p %{buildroot}%{_conf_dir}
|
||||||
|
mkdir -p %{buildroot}%{_bindir}
|
||||||
|
mkdir -p %{buildroot}%{_var_home}
|
||||||
|
mkdir -p %{buildroot}%{_initddir}
|
||||||
|
|
||||||
|
cp -R %{_reldir}/lib %{buildroot}%{_lib_home}/
|
||||||
|
cp -R %{_reldir}/erts-* %{buildroot}%{_lib_home}/
|
||||||
|
cp -R %{_reldir}/releases %{buildroot}%{_lib_home}/
|
||||||
|
cp -R %{_reldir}/bin %{buildroot}%{_lib_home}/
|
||||||
|
cp -R %{_reldir}/etc/* %{buildroot}%{_conf_dir}/
|
||||||
|
cp -R %{_reldir}/data/* %{buildroot}%{_var_home}/
|
||||||
|
install -m644 %{_service_src} %{buildroot}%{_service_dst}
|
||||||
|
|
||||||
|
%pre
|
||||||
|
if [ $1 = 1 ]; then
|
||||||
|
# Initial installation
|
||||||
|
/usr/bin/getent group %{_group} >/dev/null || /usr/sbin/groupadd -r %{_group}
|
||||||
|
if ! /usr/bin/getent passwd %{_user} >/dev/null ; then
|
||||||
|
/usr/sbin/useradd -r -g %{_group} -m -d %{_sharedstatedir}/%{_name} -c "%{_name}" %{_user}
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
%post
|
||||||
|
if [ $1 = 1 ]; then
|
||||||
|
ln -s %{_lib_home}/bin/emqx %{_bindir}/emqx
|
||||||
|
ln -s %{_lib_home}/bin/emqx_ctl %{_bindir}/emqx_ctl
|
||||||
|
fi
|
||||||
|
%{_post_addition}
|
||||||
|
if [ -e %{_initddir}/%{_name} ] ; then
|
||||||
|
/sbin/chkconfig --add %{_name}
|
||||||
|
else
|
||||||
|
systemctl enable %{_name}.service
|
||||||
|
fi
|
||||||
|
chown -R %{_user}:%{_group} %{_lib_home}
|
||||||
|
|
||||||
|
%preun
|
||||||
|
%{_preun_addition}
|
||||||
|
# Only on uninstall, not upgrades
|
||||||
|
if [ $1 = 0 ]; then
|
||||||
|
if [ -e %{_initddir}/%{_name} ] ; then
|
||||||
|
/sbin/service %{_name} stop > /dev/null 2>&1
|
||||||
|
/sbin/chkconfig --del %{_name}
|
||||||
|
else
|
||||||
|
systemctl disable %{_name}.service
|
||||||
|
fi
|
||||||
|
rm -f %{_bindir}/emqx
|
||||||
|
rm -f %{_bindir}/emqx_ctl
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
%postun
|
||||||
|
if [ $1 = 0 ]; then
|
||||||
|
rm -rf %{_lib_home}
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
%files
|
||||||
|
%defattr(-,root,root)
|
||||||
|
%{_service_dst}
|
||||||
|
%attr(-,%{_user},%{_group}) %{_lib_home}/*
|
||||||
|
%attr(-,%{_user},%{_group}) %dir %{_var_home}
|
||||||
|
%attr(-,%{_user},%{_group}) %config(noreplace) %{_var_home}/*
|
||||||
|
%attr(-,%{_user},%{_group}) %dir %{_log_dir}
|
||||||
|
%attr(-,%{_user},%{_group}) %config(noreplace) %{_conf_dir}/*
|
||||||
|
|
||||||
|
%clean
|
||||||
|
rm -rf %{buildroot}
|
||||||
|
|
||||||
|
%changelog
|
||||||
|
|
|
@ -0,0 +1,146 @@
|
||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# emqx
|
||||||
|
#
|
||||||
|
# chkconfig: 2345 80 30
|
||||||
|
# description: EMQX, a distributed, massively scalable, highly extensible MQTT message broker written in Erlang/OTP
|
||||||
|
# processname: beam
|
||||||
|
#
|
||||||
|
|
||||||
|
# Source function library.
|
||||||
|
. /etc/rc.d/init.d/functions
|
||||||
|
|
||||||
|
RETVAL=0
|
||||||
|
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
||||||
|
DESC="EMQX, a distributed, massively scalable, highly extensible MQTT message broker written in Erlang/OTP"
|
||||||
|
NAME=emqx
|
||||||
|
DAEMON=/usr/bin/$NAME
|
||||||
|
lockfile=/var/lock/subsys/$NAME
|
||||||
|
mkdir -p /var/run/$NAME
|
||||||
|
pidfile=/var/run/$NAME/$NAME.pid
|
||||||
|
|
||||||
|
# Check for script, config and data dirs
|
||||||
|
[ -x /usr/bin/$NAME ] || exit 0
|
||||||
|
[ -d /etc/$NAME ] || exit 0
|
||||||
|
[ -d /var/lib/$NAME ] || exit 0
|
||||||
|
|
||||||
|
# Read configuration variable file if it is present and readable
|
||||||
|
[ -r /etc/sysconfig/$NAME ] && . /etc/sysconfig/$NAME
|
||||||
|
|
||||||
|
# `service` strips all environmental VARS so
|
||||||
|
# if no HOME was set in /etc/sysconfig/$NAME then set one here
|
||||||
|
# to the data directory for erlexec's sake
|
||||||
|
if [ -z "$HOME" ]; then
|
||||||
|
export HOME=
|
||||||
|
fi
|
||||||
|
|
||||||
|
status -p $pidfile -l $(basename $lockfile) $NAME >/dev/null 2>&1
|
||||||
|
running=$?
|
||||||
|
|
||||||
|
find_pid() {
|
||||||
|
ps ax | grep beam.smp | grep -E "\-progname.+$NAME" | awk '{print $1}'
|
||||||
|
}
|
||||||
|
|
||||||
|
check_pid_status() {
|
||||||
|
local pid="$(find_pid)"
|
||||||
|
if [ "$pid" = "" ]; then
|
||||||
|
# prog not running?
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
# running
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
start() {
|
||||||
|
# Start daemons.
|
||||||
|
echo -n $"Starting emqx: "
|
||||||
|
$DAEMON start
|
||||||
|
RETVAL=$?
|
||||||
|
if [ $RETVAL -eq 0 ]; then
|
||||||
|
touch $lockfile
|
||||||
|
find_pid > $pidfile
|
||||||
|
success
|
||||||
|
else
|
||||||
|
failure $"$NAME start"
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
return $RETVAL
|
||||||
|
}
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
# Stop daemon.
|
||||||
|
echo -n $"Shutting down emqx: "
|
||||||
|
$DAEMON stop 2>/dev/null
|
||||||
|
for n in $(seq 1 10); do
|
||||||
|
sleep 1
|
||||||
|
check_pid_status
|
||||||
|
RETVAL=$?
|
||||||
|
if [ $RETVAL -eq 1 ]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [ $RETVAL -eq 1 ]; then
|
||||||
|
rm -f $lockfile $pidfile
|
||||||
|
success
|
||||||
|
echo && return 0
|
||||||
|
else
|
||||||
|
failure $"$NAME stop"
|
||||||
|
echo && return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
hardstop() {
|
||||||
|
echo -n $"Shutting down $NAME: "
|
||||||
|
su - emqx -c "ps -ef | grep beam.smp | grep '\-progname $NAME ' | grep -v grep | awk '{print \$2}' | xargs kill -9"
|
||||||
|
for n in $(seq 1 10); do
|
||||||
|
sleep 1
|
||||||
|
check_pid_status
|
||||||
|
RETVAL=$?
|
||||||
|
if [ $RETVAL -eq 1 ]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [ $RETVAL -eq 1 ]; then
|
||||||
|
rm -f $lockfile $pidfile
|
||||||
|
success
|
||||||
|
echo && return 0
|
||||||
|
else
|
||||||
|
failure $"$NAME hardstop"
|
||||||
|
echo && return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# See how we were called.
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
[ $running -eq 0 ] && exit 0
|
||||||
|
start
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
stop
|
||||||
|
;;
|
||||||
|
restart|force-reload)
|
||||||
|
[ $running -eq 0 ] && stop
|
||||||
|
start
|
||||||
|
;;
|
||||||
|
hardstop)
|
||||||
|
[ $running -eq 0 ] || exit 0
|
||||||
|
hardstop
|
||||||
|
;;
|
||||||
|
condrestart|try-restart)
|
||||||
|
[ $running -eq 0 ] || exit 0
|
||||||
|
restart
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
status -p $pidfile -l $(basename $lockfile) $NAME
|
||||||
|
;;
|
||||||
|
ping)
|
||||||
|
$DAEMON ping || exit $?
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo $"Usage: $0 {start|stop|restart|force-reload|hardstop|condrestart|try-restart|status|ping}"
|
||||||
|
exit 1
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit $?
|
|
@ -7,6 +7,7 @@ QEMU_ARCH ?= x86_64
|
||||||
ARCH ?= amd64
|
ARCH ?= amd64
|
||||||
QEMU_VERSION ?= v5.0.0-2
|
QEMU_VERSION ?= v5.0.0-2
|
||||||
OS ?= alpine
|
OS ?= alpine
|
||||||
|
PKG_VSN ?= $(shell git describe --tags --match '[0-9]*')
|
||||||
|
|
||||||
EMQX_NAME = $(subst emqx/,,$(TARGET))
|
EMQX_NAME = $(subst emqx/,,$(TARGET))
|
||||||
ARCH_LIST = amd64 arm64v8 arm32v7 i386 s390x
|
ARCH_LIST = amd64 arm64v8 arm32v7 i386 s390x
|
||||||
|
@ -40,7 +41,6 @@ docker-build:
|
||||||
@echo "DOCKER BUILD: qemu arch - $(QEMU_ARCH)."
|
@echo "DOCKER BUILD: qemu arch - $(QEMU_ARCH)."
|
||||||
@echo "DOCKER BUILD: docker repo - $(TARGET) "
|
@echo "DOCKER BUILD: docker repo - $(TARGET) "
|
||||||
@echo "DOCKER BUILD: emqx name - $(EMQX_NAME)."
|
@echo "DOCKER BUILD: emqx name - $(EMQX_NAME)."
|
||||||
@echo "DOCKER BUILD: emqx version - $(EMQX_DEPS_DEFAULT_VSN)."
|
|
||||||
|
|
||||||
## Prepare qemu to build images other then x86_64 on travis
|
## Prepare qemu to build images other then x86_64 on travis
|
||||||
@echo "PREPARE: Qemu" \
|
@echo "PREPARE: Qemu" \
|
||||||
|
@ -53,7 +53,7 @@ docker-build:
|
||||||
&& cd -
|
&& cd -
|
||||||
|
|
||||||
@docker build --no-cache \
|
@docker build --no-cache \
|
||||||
--build-arg EMQX_DEPS_DEFAULT_VSN=$(EMQX_DEPS_DEFAULT_VSN) \
|
--build-arg PKG_VSN=$(PKG_VSN) \
|
||||||
--build-arg BUILD_FROM=emqx/build-env:erl22.3-alpine-$(ARCH) \
|
--build-arg BUILD_FROM=emqx/build-env:erl22.3-alpine-$(ARCH) \
|
||||||
--build-arg RUN_FROM=$(ARCH)/alpine:3.11 \
|
--build-arg RUN_FROM=$(ARCH)/alpine:3.11 \
|
||||||
--build-arg EMQX_NAME=$(EMQX_NAME) \
|
--build-arg EMQX_NAME=$(EMQX_NAME) \
|
||||||
|
|
|
@ -266,4 +266,4 @@ str(L) when is_list(L) -> L;
|
||||||
str(B) when is_binary(B) -> unicode:characters_to_list(B, utf8).
|
str(B) when is_binary(B) -> unicode:characters_to_list(B, utf8).
|
||||||
|
|
||||||
erl_opts_i() ->
|
erl_opts_i() ->
|
||||||
[{i, Dir} || Dir <- filelib:wildcard("apps/**/include")].
|
[{i, Dir} || Dir <- filelib:wildcard(filename:join(["apps", "**", "include"]))].
|
||||||
|
|
Loading…
Reference in New Issue