Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
3944d7d
Add error handling when app cannot access volume paths
toderian Jan 8, 2025
17fdcad
Add messaging service for handling critical messages
toderian Jan 8, 2025
152399f
GH Actions: Add ubuntu 24.04 to build workflow
toderian Jan 8, 2025
d50439d
Encode credentials in base64
toderian Jan 8, 2025
70fe32c
Set up password in .env file during project build
toderian Jan 8, 2025
81849d2
Load env file on runtime
toderian Jan 8, 2025
f01b310
Load env file before any imports
toderian Jan 8, 2025
36faae8
Revert "Load env file before any imports"
toderian Jan 9, 2025
7be7192
Revert "Load env file on runtime"
toderian Jan 9, 2025
378d932
Revert "Set up password in .env file during project build"
toderian Jan 9, 2025
8fa24e0
Replace password placeholder with actual password before app build
toderian Jan 9, 2025
783026d
Increment version
toderian Jan 9, 2025
d2c91b3
Update workflow to do platform-specific password replacement
toderian Jan 9, 2025
62ad83d
Implement separate steps for windows and linux password replacement
toderian Jan 9, 2025
84bf46c
Fix workflow
toderian Jan 9, 2025
9bad8a3
Remove credentials from docker template
toderian Jan 9, 2025
f6023a6
Use env variables to set up credentials
toderian Jan 9, 2025
617aa9f
Obfuscate password in logs
toderian Jan 9, 2025
d68bc83
Add extra logging when env is not ok
toderian Jan 9, 2025
3e1c8e2
Update env variables names
toderian Jan 10, 2025
d722b6d
cherry-pick fix: refactor local address info
aidamian Jan 10, 2025
babe0eb
Trigger GH Actions
toderian Jan 10, 2025
7cd1bfb
Add GH action to build the launcher when a PR to main is open
toderian Jan 12, 2025
a0e2824
Update workflow
toderian Jan 12, 2025
18f3529
Save all builds in one zip
toderian Jan 12, 2025
1eb190b
BL remove build trigger
toderian Jan 12, 2025
e17e8ba
Remove PR trigger from build workflow
toderian Jan 12, 2025
2d2f9c8
Save all builds
toderian Jan 12, 2025
956ba16
Add PR number and commit SHA to artifact name
toderian Jan 12, 2025
ff8e08d
Add PR number and commit SHA to artifact name
toderian Jan 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ name: Multi-step multi-platform build
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]

jobs:
check-version:
Expand Down Expand Up @@ -56,7 +54,15 @@ jobs:
name: EdgeNodeLauncher-WIN32
platformDependencies: ""

- os: ubuntu-latest
- os: ubuntu-24.04
build: |
chmod +x build_scripts/unix_build.sh
./build_scripts/unix_build.sh
zip: zip -r EdgeNodeLauncher-LINUX_Ubuntu-24.04.zip dist/*
name: EdgeNodeLauncher-LINUX_Ubuntu-24.04
platformDependencies: sudo apt-get update && sudo apt install -y '^libxcb.*-dev' libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev libxkbcommon-dev libxkbcommon-x11-dev --fix-missing

- os: ubuntu-22.04
build: |
chmod +x build_scripts/unix_build.sh
./build_scripts/unix_build.sh
Expand Down Expand Up @@ -102,6 +108,20 @@ jobs:
run: |
pip install -r requirements.txt
pip3 install --upgrade PyInstaller pyinstaller-hooks-contrib
# Replace the `****************` to MQTT_K in utils/const.py
- name: Replace placeholder in const.py (Windows)
if: runner.os == 'Windows'
env:
MQTT_K: ${{ secrets.MQTT_K }}
run: |
$filePath = "utils/const.py"
(Get-Content $filePath) -replace '\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*', "${{ env.MQTT_K }}" | Set-Content $filePath
- name: Replace placeholder in const.py (Linux)
if: runner.os == 'Linux'
env:
MQTT_K: ${{ secrets.MQTT_K }}
run: |
sed -i "s/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/${MQTT_K}/g" utils/const.py
- name: Build app
run: ${{ matrix.build }}
- name: Zip App
Expand Down
141 changes: 141 additions & 0 deletions .github/workflows/pr-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
name: Multi-step multi-platform build on PR to main branch and saves the artifacts

on:
pull_request:
branches: ["main"]

jobs:
check-version:
runs-on: ubuntu-latest
outputs:
should-run: ${{ steps.check-version.outputs.should-run }}

steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0 # Fetches all history for all branches and tags

- name: Get latest release version
id: latest-version
run: |
LATEST_TAG=$(git describe --tags `git rev-list --tags --max-count=1`)
echo "Latest tag is $LATEST_TAG"
echo "LATEST_TAG=$LATEST_TAG" >> $GITHUB_ENV

- name: Check version in ver.py
id: check-version
run: |
CURRENT_VERSION=$(cat ver.py | grep -o "'.*'")
echo "Current version is $CURRENT_VERSION"

if [ "$CURRENT_VERSION" == "$LATEST_TAG" ]; then
echo "Version $CURRENT_VERSION has not been incremented vs already released $LATEST_TAG. Build will be cancelled."
echo "::set-output name=should-run::false"
exit 1
else
echo "Current version $CURRENT_VERSION differs from latest tag $LATEST_TAG. Build will continue."
echo "::set-output name=should-run::true"
fi

build:
needs: check-version
if: needs.check-version.outputs.should-run == 'true'

strategy:
matrix:
include:
- os: windows-latest
build: ./build_scripts/win32_build.bat
name: EdgeNodeLauncher-WIN32
platformDependencies: ""

- os: ubuntu-24.04
build: |
chmod +x build_scripts/unix_build.sh
./build_scripts/unix_build.sh
name: EdgeNodeLauncher-LINUX_Ubuntu-24.04
platformDependencies: sudo apt-get update && sudo apt install -y '^libxcb.*-dev' libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev libxkbcommon-dev libxkbcommon-x11-dev --fix-missing

- os: ubuntu-22.04
build: |
chmod +x build_scripts/unix_build.sh
./build_scripts/unix_build.sh
name: EdgeNodeLauncher-LINUX_Ubuntu-22.04
platformDependencies: sudo apt-get update && sudo apt install -y '^libxcb.*-dev' libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev libxkbcommon-dev libxkbcommon-x11-dev --fix-missing

- os: ubuntu-20.04
build: |
chmod +x build_scripts/unix_build.sh
./build_scripts/unix_build.sh
name: EdgeNodeLauncher-LINUX_Ubuntu-20.04
platformDependencies: sudo apt-get update && sudo apt-get install -y '^libxcb.*-dev' libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev libxkbcommon-dev libxkbcommon-x11-dev --fix-missing

name: Build installers ${{ matrix.os }}
runs-on: ${{ matrix.os }}
permissions: write-all

steps:
- uses: actions/checkout@v3
- name: Set up Python 3.10.11
uses: actions/setup-python@v2
with:
python-version: "3.10.11"
- run: ${{ matrix.platformDependencies }}
- name: Setup env
run: |
pip install -r requirements.txt
pip3 install --upgrade PyInstaller pyinstaller-hooks-contrib

- name: Replace placeholder in const.py (Windows)
if: runner.os == 'Windows'
env:
MQTT_K: ${{ secrets.MQTT_K }}
run: |
$filePath = "utils/const.py"
(Get-Content $filePath) -replace '\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*', "${{ env.MQTT_K }}" | Set-Content $filePath

- name: Replace placeholder in const.py (Linux)
if: runner.os == 'Linux'
env:
MQTT_K: ${{ secrets.MQTT_K }}
run: |
sed -i "s/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/${MQTT_K}/g" utils/const.py

- name: Build app
run: ${{ matrix.build }}

- name: Save build artifacts
uses: actions/upload-artifact@v3
with:
name: ${{ matrix.name }}-build-${{ github.event.pull_request.number }}-${{ github.sha }}
path: dist/*

collect-artifacts:
needs: build
runs-on: ubuntu-latest
permissions: write-all

steps:
- name: Download build artifacts
uses: actions/download-artifact@v3
with:
name: EdgeNodeLauncher-WIN32-build-${{ github.event.pull_request.number }}-${{ github.sha }}
path: ./all-builds/EdgeNodeLauncher-WIN32

- name: Download build artifacts
uses: actions/download-artifact@v3
with:
name: EdgeNodeLauncher-LINUX_Ubuntu-24.04-build-${{ github.event.pull_request.number }}-${{ github.sha }}
path: ./all-builds/EdgeNodeLauncher-LINUX_Ubuntu-24.04

- name: Download build artifacts
uses: actions/download-artifact@v3
with:
name: EdgeNodeLauncher-LINUX_Ubuntu-22.04-build-${{ github.event.pull_request.number }}-${{ github.sha }}
path: ./all-builds/EdgeNodeLauncher-LINUX_Ubuntu-22.04

- name: Download build artifacts
uses: actions/download-artifact@v3
with:
name: EdgeNodeLauncher-LINUX_Ubuntu-20.04-build-${{ github.event.pull_request.number }}-${{ github.sha }}
path: ./all-builds/EdgeNodeLauncher-LINUX_Ubuntu-20.04
33 changes: 21 additions & 12 deletions app_forms/frm_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
from PyQt5.QtGui import QFont, QPixmap, QIcon
import pyqtgraph as pg


import services.messaging_service as messaging_service
from utils.const import *
from utils.docker import _DockerUtilsMixin
from utils.updater import _UpdaterMixin
Expand Down Expand Up @@ -533,7 +533,8 @@ def check_data(self, data):
data_size = len(data['timestamps'])
if data_size > 0 and data_size > MAX_HISTORY_QUEUE:
for key in data:
data[key] = data[key][-MAX_HISTORY_QUEUE:]
if isinstance(data[key], list):
data[key] = data[key][-MAX_HISTORY_QUEUE:]
start_time = data['timestamps'][0]
end_time = data['timestamps'][-1]
self.add_log('Data loaded & cleaned: {} timestamps from {} to {}'.format(
Expand Down Expand Up @@ -647,22 +648,30 @@ def refresh_local_address(self):
address_path = os.path.join(self.volume_path, LOCAL_ADDRESS_FILE)
try:
with open(address_path, 'r') as file:
address_info = [x for x in file.read().split(' ') if len(x) > 0]
if len(address_info) == 0:
raise FileNotFoundError
if address_info[0] != self.node_addr:
self.node_addr = address_info[0]
self.node_name = address_info[1] if len(address_info) > 1 else ''
str_display = address_info[0][:8] + '...' + address_info[0][-8:]
data = json.load(file)
node_addr = data['address']
node_alias= data.get('alias', '')
node_eth_addr = data.get('eth_address', '')
node_signature = data.get('signature', '')
self.node_eth_addr = node_eth_addr
self.node_signature = node_signature
if node_addr != self.node_addr:
self.node_addr = node_addr
self.node_name = node_alias
str_display = node_addr[:8] + '...' + node_addr[-8:]
self.addressDisplay.setText('Addr: ' + str_display)
self.nameDisplay.setText('Name: ' + address_info[1] if len(address_info) > 1 else '')
self.add_log(f'Local address updated: {self.node_addr} : {self.node_name}')

self.nameDisplay.setText('Name: ' + node_alias)
self.add_log(f'Local address updated: {self.node_addr} : {self.node_name}, ETH: {self.node_eth_addr}')
# endif new address
# endwith open
except FileNotFoundError:
self.addressDisplay.setText('Address file not found.')
self.nameDisplay.setText('')
except PermissionError as e:
messaging_service.show_critical_message(self, "Permission Denied",
f"Unable to read the file at {address_path}. Please change the file permissions.")
except Exception as e:
self.add_log(f'Error loading address: {e}', debug=True)
return

def maybe_refresh_uptime(self):
Expand Down
12 changes: 12 additions & 0 deletions services/messaging_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from PyQt5.QtWidgets import QMessageBox

def show_critical_message(parent, title, message):
"""
Display a critical message box.

Parameters:
parent (QWidget): The parent widget.
title (str): The title of the message box.
message (str): The message to display.
"""
QMessageBox.critical(parent, title, message)
11 changes: 4 additions & 7 deletions utils/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
LINUX_VOLUME_PATH = '/var/lib/docker/volumes/naeural_vol/_data'
LOCAL_HISTORY_FILE = '_data/local_history.json'
E2_PEM_FILE = '_data/e2.pem'
LOCAL_ADDRESS_FILE = '_data/local_address.txt'
LOCAL_ADDRESS_FILE = '_data/local_address.json'
CONFIG_STARTUP_FILE = 'config_startup.json'
CONFIG_APP_FILE = '_data/box_configuration/config_app.txt'
ADDRS_FILE = 'authorized_addrs'
Expand Down Expand Up @@ -46,9 +46,9 @@

AUTO_UPDATE_CHECK_INTERVAL = 60

DEFAULT_MQTT_HOST = 'r9092118.ala.eu-central-1.emqxsl.com'
DEFAULT_MQTT_USER = 'corenaeural'
DEFAULT_MQTT_PASSWORD = ''
DEFAULT_MQTT_HOST = 'cjkwOTIxMTguYWxhLmV1LWNlbnRyYWwtMS5lbXF4c2wuY29t'
DEFAULT_MQTT_USER = 'Y29yZW5hZXVyYWw='
DEFAULT_MQTT_PASSWORD = '****************'


ENV_TEMPLATE = '''
Expand All @@ -69,10 +69,7 @@


# MQTT
EE_MQTT_HOST={}
EE_MQTT_PORT=8883
EE_MQTT_USER={}
EE_MQTT={}
EE_MQTT_SUBTOPIC=address
EE_MQTT_CERT=

Expand Down
37 changes: 13 additions & 24 deletions utils/docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import platform
import subprocess
import platform
import base64

from pathlib import Path
from collections import OrderedDict
Expand Down Expand Up @@ -154,9 +155,9 @@ def __init__(self):
self.docker_container_name = DOCKER_CONTAINER_NAME
self.docker_tag = DOCKER_TAG
self.node_id = self.get_node_id()
self.mqtt_host = DEFAULT_MQTT_HOST
self.mqtt_user = DEFAULT_MQTT_USER
self.mqtt_password = DEFAULT_MQTT_PASSWORD
self.mqtt_host = base64.b64decode(DEFAULT_MQTT_HOST).decode("utf-8")
self.mqtt_user = base64.b64decode(DEFAULT_MQTT_USER).decode("utf-8")
self.mqtt_password = base64.b64decode(DEFAULT_MQTT_PASSWORD).decode("utf-8")
self._dev_mode = False

self.run_with_sudo = False
Expand Down Expand Up @@ -226,6 +227,9 @@ def __setup_docker_run(self):
self.__CMD += [
'--rm', # remove the container when it exits
'--env-file', '.env', #f'"{str(self.env_file)}"', # pass the .env file to the container
'-e', f'EE_MQTT_HOST={self.mqtt_host}', # pass the MQTT host to the container
'-e', f'EE_MQTT_USER={self.mqtt_user}', # pass the MQTT user to the container
'-e', f'EE_MQTT={self.mqtt_password}', # pass the MQTT password to the container
'-v', f'{DOCKER_VOLUME}:/edge_node/_local_cache', # mount the volume
'--name', self.docker_container_name, '-d',
]
Expand All @@ -242,9 +246,12 @@ def __setup_docker_run(self):
self.__CMD_CLEAN.insert(0, 'sudo')
self.__CMD_STOP.insert(0, 'sudo')
self.__CMD_INSPECT.insert(0, 'sudo')


run_cmd = " ".join(self.get_cmd())
obfuscated_cmd = run_cmd.replace(self.mqtt_password, '*' * len(self.mqtt_password))

self.add_log('Docker run command setup complete:')
self.add_log(' - Run: {}'.format(" ".join(self.get_cmd())))
self.add_log(' - Run: {}'.format(obfuscated_cmd))
self.add_log(' - Clean: {}'.format(" ".join(self.__CMD_CLEAN)))
self.add_log(' - Stop: {}'.format(" ".join(self.__CMD_STOP)))
self.add_log(' - Inspect: {}'.format(" ".join(self.__CMD_INSPECT)))
Expand All @@ -256,10 +263,8 @@ def get_cmd(self):
result = self.__CMD + ['-p', '80:80', self.docker_image]
else:
result = self.__CMD + [self.docker_image]
self.add_log("Docker command: '{}'".format(" ".join(result)), debug=True)
return result


def get_clean_cmd(self):
return self.__CMD_CLEAN

Expand Down Expand Up @@ -308,23 +313,6 @@ def __check_env_keys(self):
except FileNotFoundError:
QMessageBox.warning(self, 'Error', '.env file not found.')
return False

# Check if the EE_MQTT key is present and set
if 'EE_MQTT' not in env_vars or not env_vars['EE_MQTT']:
# Prompt the user for the MQTT password
password, ok = QInputDialog.getText(self, 'MQTT Broker password Required', 'Enter MQTT broker password:')
if ok and password:
# Update the env_vars dictionary with the new password
env_vars['EE_MQTT'] = password
# Resave the .env file with the updated key
with open(self.env_file, 'w') as file:
for key, value in env_vars.items():
file.write(f'{key}={value}\n')
QMessageBox.information(self, 'Success', 'MQTT password set successfully.')
return True
else:
QMessageBox.warning(self, 'Error', 'MQTT password is required to continue.')
return False
return True


Expand Down Expand Up @@ -403,6 +391,7 @@ def is_container_running(self):
def launch_container(self):
is_env_ok = self.__check_env_keys()
if not is_env_ok:
self.add_log('Environment is not ok. Could not start the container.')
return
self.add_log('Updating image...')
self.__maybe_docker_pull()
Expand Down
2 changes: 1 addition & 1 deletion ver.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__VER__ = '0.8.6'
__VER__ = '0.8.7'
Loading