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
|
||||
/rebar3
|
||||
rebar.lock
|
||||
.stamp
|
||||
tmp/
|
||||
_packages
|
||||
|
|
8
Makefile
8
Makefile
|
@ -1,6 +1,6 @@
|
|||
REBAR_VERSION = 3.14.3-emqx-2
|
||||
REBAR = ./rebar3
|
||||
export PKG_VSN ?= $(shell git describe --tags --always)
|
||||
REBAR_VERSION = 3.14.3-emqx-3
|
||||
REBAR = $(CURDIR)/rebar3
|
||||
export PKG_VSN ?= $(shell git describe --tags --match '[0-9]*' 2>/dev/null || git describe --always)
|
||||
# comma separated versions
|
||||
export RELUP_BASE_VERSIONS ?=
|
||||
|
||||
|
@ -18,7 +18,7 @@ all: $(REBAR) $(PROFILES)
|
|||
|
||||
.PHONY: ensure-rebar3
|
||||
ensure-rebar3:
|
||||
@./ensure-rebar3.sh $(REBAR_VERSION)
|
||||
$(CURDIR)/ensure-rebar3.sh $(REBAR_VERSION)
|
||||
|
||||
$(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
|
||||
QEMU_VERSION ?= v5.0.0-2
|
||||
OS ?= alpine
|
||||
PKG_VSN ?= $(shell git describe --tags --match '[0-9]*')
|
||||
|
||||
EMQX_NAME = $(subst emqx/,,$(TARGET))
|
||||
ARCH_LIST = amd64 arm64v8 arm32v7 i386 s390x
|
||||
|
@ -40,7 +41,6 @@ docker-build:
|
|||
@echo "DOCKER BUILD: qemu arch - $(QEMU_ARCH)."
|
||||
@echo "DOCKER BUILD: docker repo - $(TARGET) "
|
||||
@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
|
||||
@echo "PREPARE: Qemu" \
|
||||
|
@ -53,7 +53,7 @@ docker-build:
|
|||
&& cd -
|
||||
|
||||
@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 RUN_FROM=$(ARCH)/alpine:3.11 \
|
||||
--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).
|
||||
|
||||
erl_opts_i() ->
|
||||
[{i, Dir} || Dir <- filelib:wildcard("apps/**/include")].
|
||||
[{i, Dir} || Dir <- filelib:wildcard(filename:join(["apps", "**", "include"]))].
|
||||
|
|
Loading…
Reference in New Issue