Skip to content

Commit

Permalink
Standalone single-docker image version of UDMIS (faucetsdn#931)
Browse files Browse the repository at this point in the history
  • Loading branch information
grafnu authored Jul 17, 2024
1 parent 2897084 commit 36d4604
Show file tree
Hide file tree
Showing 19 changed files with 207 additions and 112 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ jobs:
- name: base setup
run: bin/run_tests install_dependencies
- name: local setup
run: bin/start_local $TARGET_PROJECT
run: bin/start_local sites/udmi_site_model $TARGET_PROJECT
- name: registrar clean
run: bin/test_regclean $TARGET_PROJECT
- name: sequence tests clean
Expand Down Expand Up @@ -218,7 +218,7 @@ jobs:
- name: base setup
run: bin/run_tests install_dependencies
- name: local setup
run: bin/start_local $TARGET_PROJECT
run: bin/start_local sites/udmi_site_model $TARGET_PROJECT
- name: registrar clean
run: bin/test_regclean solo $TARGET_PROJECT
- name: telemetry validator
Expand Down Expand Up @@ -262,7 +262,7 @@ jobs:
bin/clone_model
bin/registrar sites/udmi_site_model
- name: local setup
run: bin/start_local //mqtt/localhost
run: bin/start_local sites/udmi_site_model //mqtt/localhost
- name: bin/test_etcd
run: bin/test_etcd
- name: bin/test_mosquitto
Expand Down Expand Up @@ -313,7 +313,7 @@ jobs:
- name: base setup
run: bin/run_tests install_dependencies
- name: local setup
run: bin/start_local $TARGET_PROJECT
run: bin/start_local sites/udmi_site_model $TARGET_PROJECT
- name: regclean
run: bin/test_regclean $TARGET_PROJECT
- name: bin/test_proxy
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ credentials.json
/udmis/var/
/udmis/profile/
/udmis/.idea/libraries/
/udmis/udmi_bin/
/udmis/udmi_etc/
/selfie/build/
/pubber/build/
/pubber/out/
Expand Down
4 changes: 4 additions & 0 deletions bin/container
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ EOF
fi

if [[ -n $build ]]; then
echo Cleaning old images...
images=$(docker images | fgrep $REPOSITORY | awk '{print $1":"$2}') || true
[[ -n $images ]] && docker rmi $images

echo Building Dockerfile.$target
docker build -f Dockerfile.$target -t $target .
docker tag $target $udmi_ref
Expand Down
38 changes: 38 additions & 0 deletions bin/docker_udmis
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/bin/bash -e

UDMI_ROOT=$(dirname $0)/..
source $UDMI_ROOT/etc/shell_common.sh

[[ $# == 1 ]] || usage site_model

site_model=$(realpath $1)
shift

cd $UDMI_ROOT

docker rm udmis || true

[[ -f $site_model/cloud_iot_config.json ]] || fail missing $site_model/cloud_iot_config.json

IMAGE_TAG=ghcr.io/faucetsdn/udmi:latest
docker inspect -f '{{.Id}}' --type=image udmis:latest && IMAGE_TAG=udmis:latest

cmd="docker run -d --name udmis -p 8883:8883 \
-v $site_model:/root/site \
-v $PWD/var/etcd:/root/default.etcd \
-v $PWD/var/mosquitto:/etc/mosquitto \
$IMAGE_TAG udmi/bin/start_local block site/ //mqtt/localhost"

echo exec: $cmd
$cmd

echo Waiting 30s for container startup...
sleep 30

echo :::::::::::::: docker logs udmis
docker logs udmis

echo :::::::::::::: docker ps
docker ps

echo ::::::::::::::
2 changes: 1 addition & 1 deletion bin/mosquctl_log
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash -ex
#!/bin/bash -e

UDMI_ROOT=$(dirname $0)/..
cd $UDMI_ROOT
Expand Down
2 changes: 1 addition & 1 deletion bin/setup_chromedriver
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash -ex
#!/bin/bash -e

echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" | sudo tee -a /etc/apt/sources.list.d/google.list

Expand Down
22 changes: 15 additions & 7 deletions bin/start_etcd
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
#!/bin/bash -e

IMAGE=quay.io/coreos/etcd:v3.5.13
BINDIR=/tmp/etcd

docker kill etcd || true
echo pwd: $(pwd)

docker run -v /usr/share/ca-certificates/:/etc/ssl/certs \
-p 2379:2379 --rm --name etcd ${IMAGE} etcd --version
udmis/bin/etcdctl version || ../bin/etcdctl version

docker run -d -v /usr/share/ca-certificates/:/etc/ssl/certs \
-p 2379:2379 --rm --name etcd ${IMAGE} etcd \
-listen-client-urls=http://0.0.0.0:2379 \
-advertise-client-urls=http://127.0.0.1:2379
$BINDIR/etcd -version

$BINDIR/etcd -listen-client-urls=http://0.0.0.0:2379 \
-advertise-client-urls=http://127.0.0.1:2379 \
> etcd.log 2>&1 &
ETCD_PID=$!

echo Waiting 10s for etcd to start...
sleep 10
[[ -d /proc/$ETCD_PID ]] || (cat etcd.log && fail starting etcd)

echo Completed etcd startup.
30 changes: 22 additions & 8 deletions bin/start_local
Original file line number Diff line number Diff line change
@@ -1,35 +1,47 @@
#!/bin/bash -e

UDMI_ROOT=$(dirname $0)/..
cd $UDMI_ROOT

source $UDMI_ROOT/etc/shell_common.sh

[[ $# == 1 ]] || fail Usage: $0 project_spec
block=
if [[ ${1:-} == block ]]; then
block=$1
shift
fi

[[ $# == 2 ]] || usage [block] site_model project_spec

project_spec=$1
site_model=$(realpath $1)
project_spec=$2
shift

echo "export TARGET_PROJECT=${project_spec:-}"
echo "export UDMI_REGISTRY_SUFFIX=${UDMI_REGISTRY_SUFFIX:-}"
echo "export UDMI_ALT_REGISTRY=${UDMI_ALT_REGISTRY:-}"

# Check for missing etc/ dir for docker execution.
if [[ -d var/ && ! -d etc/ ]]; then
ln -s var etc
fi

cd $UDMI_ROOT

if [[ ! $project_spec =~ ^//mqtt/ ]]; then
echo Not a local setup, doing nothing!
exit 0
fi

site_model=sites/udmi_site_model
site_config=sites/udmi_site_model/cloud_iot_config.json
site_config=$site_model/cloud_iot_config.json
registry_id=$(jq -r .registry_id $site_config)${UDMI_REGISTRY_SUFFIX:-}

bin/start_etcd

source $UDMI_ROOT/etc/mosquitto_ctrl.sh
mkdir -p $CERT_DIR

bin/setup_ca $site_model
bin/start_mosquitto

source $UDMI_ROOT/etc/mosquitto_ctrl.sh

$MOSQUITTO_CTRL deleteClient $SERV_USER
$MOSQUITTO_CTRL createClient $SERV_USER -p $SERV_PASS # No client_id to allow multiple backend connections.
$MOSQUITTO_CTRL addClientRole $SERV_USER service
Expand All @@ -46,3 +58,5 @@ sudo chmod a+r /var/log/mosquitto/mosquitto.log
bin/start_udmis

echo Done with local server setup.

[[ -z $block ]] || (echo Blocking until termination. && tail -f /dev/null)
31 changes: 25 additions & 6 deletions bin/start_mosquitto
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,59 @@ source $UDMI_ROOT/etc/shell_common.sh

source $UDMI_ROOT/etc/mosquitto_ctrl.sh

# This is not already set-up when running inside of docker...
if [[ ! -f $ETC_DIR/mosquitto.conf ]]; then
echo Installing base mosquitto.conf
cp ../var/mosquitto.conf $ETC_DIR/
fi

GROUP=mosquitto
UDMI_FILE=$ETC_DIR/conf.d/udmi.conf
PASS_FILE=$ETC_DIR/mosquitto.passwd
DYN_FILE=$ETC_DIR/dynamic_security.json

mkdir -p /var/log/mosquitto/

if [[ ! -f $UDMI_FILE ]]; then
echo Creating new $UDMI_FILE from template...
mkdir -p $(dirname $UDMI_FILE)
sudo cp etc/mosquitto_udmi.conf $UDMI_FILE
PLUGIN_FILE=$(whereis -b mosquitto_dynamic_security.so | awk '{print $2}')
PLUGIN_FILE=/usr/lib/mosquitto_dynamic_security.so
[[ -f $PLUGIN_FILE ]] || PLUGIN_FILE=$(whereis -b mosquitto_dynamic_security.so | awk '{print $2}')
ls -l "$PLUGIN_FILE"
echo Configuring dynamic security plugin $PLUGIN_FILE
sudo sed -i "s%plugin dynsec%plugin $PLUGIN_FILE%" $UDMI_FILE
sudo sed -i "s%plugin_opt_config_file dynsec%plugin_opt_config_file $DYN_FILE%" $UDMI_FILE
[[ $(whoami) == root ]] && echo user root >> $UDMI_FILE
fi

if [[ ! -f $DYN_FILE ]]; then
echo Creating new $DYN_FILE
echo Configuring MQTT user: $AUTH_USER
sudo mosquitto_ctrl dynsec init $DYN_FILE $AUTH_USER $AUTH_PASS
sudo chgrp $GROUP $DYN_FILE
[[ $(whoami) != root ]] && sudo chgrp $GROUP $DYN_FILE
sudo chmod 0660 $DYN_FILE
fi

if [[ ! -f $PASS_FILE ]]; then
echo Creating $PASS_FILE
sudo touch $PASS_FILE
sudo chmod 0640 $PASS_FILE
sudo chgrp $GROUP $PASS_FILE
[[ $(whoami) != root ]] && sudo chgrp $GROUP $PASS_FILE
sudo mosquitto_passwd -b ${PASS_FILE} ${AUTH_USER} ${AUTH_PASS}
fi

sudo systemctl restart mosquitto
if [[ -n $(which systemctl) ]]; then
sudo systemctl restart mosquitto
else
# Raw mode for running (e.g.) in a docker container
mosquitto -c $ETC_DIR/mosquitto.conf > mosquitto.log 2>&1 &
MOSQUITTO_PID=$!
echo Waiting 10s for background mosquitto to start...
sleep 10
[[ -d /proc/$MOSQUITTO_PID ]] || (cat mosquitto.log && fail starting mosquitto)
echo Completed mosquitto startup.
fi

$MOSQUITTO_CTRL createRole device
$MOSQUITTO_CTRL addRoleACL device subscribePattern '/r/+/d/+/#' allow
Expand All @@ -51,5 +72,3 @@ if [[ $clients =~ ${AUTH_USER} ]]; then
else
fail Improper client: $clients
fi

echo use: systemctl status mosquitto
12 changes: 9 additions & 3 deletions bin/start_udmis
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,32 @@ if [[ ${1:-} == stop ]]; then
exit 0
fi

bin/container udmis prep --no-check
bin/container udmis prep --no-check || true

mkdir -p out
LOGFILE=out/udmis.log
date > $LOGFILE

export ETCD_CLUSTER=localhost
export SSL_SECRETS_DIR=/etc/mosquitto/certs

sudo PATH=$PATH -E udmis/bin/run udmis/etc/local_pod.json > $LOGFILE 2>&1 &
UDMIS_DIR=udmis
[[ -d $UDMIS_DIR ]] || UDMIS_DIR=..

sudo PATH=$PATH -E $UDMIS_DIR/bin/run $UDMIS_DIR/etc/local_pod.json > $LOGFILE 2>&1 &

PID=$!

WAITING=30
for i in `seq 1 $WAITING`; do
if [[ -f $POD_READY ]]; then
if [[ -f $POD_READY || ! -d /proc/$PID ]]; then
break
fi
echo Waiting for udmis startup $((WAITING - i))...
sleep 1
done

echo ::::::::: tail $LOGFILE
tail -n 30 $LOGFILE

[[ -f $POD_READY ]] || fail pod_ready.txt not found.
Expand Down
16 changes: 12 additions & 4 deletions common/src/main/java/com/google/udmi/util/CertManager.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.google.udmi.util;

import static com.google.common.base.Preconditions.checkState;
import static com.google.udmi.util.GeneralUtils.sha256;
import static java.lang.String.format;

Expand Down Expand Up @@ -34,6 +35,7 @@
public class CertManager {

public static final String TLS_1_2_PROTOCOL = "TLSv1.2";
public static final String CA_CERT_FILE = "ca.crt";
private static final String BOUNCY_CASTLE_PROVIDER = "BC";
private static final String X509_FACTORY = "X.509";
private static final String X509_ALGORITHM = "X509";
Expand All @@ -42,7 +44,6 @@ public class CertManager {
private static final String CA_CERT_ALIAS = "ca-certificate";
private static final String CLIENT_CERT_ALIAS = "certificate";
private static final String PRIVATE_KEY_ALIAS = "private-key";
public static final String CA_CERT_FILE = "ca.crt";
private final File caCrtFile;
private final File keyFile;
private final File crtFile;
Expand All @@ -62,8 +63,7 @@ public CertManager(File caCrtFile, File clientDir, Transport transport,
isSsl = Transport.SSL.equals(transport);

if (isSsl) {
File rsaCrtFile = new File(clientDir, "rsa_private.crt");
String prefix = rsaCrtFile.exists() ? "rsa" : "ec";
String prefix = keyPrefix(clientDir);
crtFile = new File(clientDir, prefix + "_private.crt");
keyFile = new File(clientDir, prefix + "_private.pem");
this.password = passString.toCharArray();
Expand All @@ -78,6 +78,14 @@ public CertManager(File caCrtFile, File clientDir, Transport transport,
}
}

private String keyPrefix(File clientDir) {
File rsaCrtFile = new File(clientDir, "rsa_private.crt");
File ecCrtFile = new File(clientDir, "ec_private.crt");
checkState(rsaCrtFile.exists() || ecCrtFile.exists(),
"no .crt found for device in " + clientDir.getAbsolutePath());
return rsaCrtFile.exists() ? "rsa" : "ec";
}

/**
* Get a certificate-backed socket factory.
*/
Expand Down Expand Up @@ -120,7 +128,7 @@ public SSLSocketFactory getCertSocketFactory() throws Exception {
clientKeyStore.load(null, null);
clientKeyStore.setCertificateEntry(CLIENT_CERT_ALIAS, clientCert);
clientKeyStore.setKeyEntry(PRIVATE_KEY_ALIAS, privateKey, password,
new java.security.cert.Certificate[] {clientCert});
new java.security.cert.Certificate[]{clientCert});
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(
KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(clientKeyStore, password);
Expand Down
13 changes: 13 additions & 0 deletions contrib/mango/mango_docker
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/sh
set -o errexit -o nounset

MANGO_VERSION=5.1.4
mkdir -p mango/data && cd mango
curl -sSL https://store.mango-os.com/downloads/m2m2-udmi-${MANGO_VERSION}.zip -o udmi.zip
unzip udmi.zip -d udmi && rm udmi.zip

docker run --rm \
-p 8443:8443 \
-v data:/opt/mango-data \
-v udmi:/opt/mango/web/modules/udmi \
ghcr.io/radixiot/mango:${MANGO_VERSION}
Loading

0 comments on commit 36d4604

Please sign in to comment.