Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Headless Mode #8

Open
Soltares opened this issue Sep 18, 2024 · 14 comments
Open

Headless Mode #8

Soltares opened this issue Sep 18, 2024 · 14 comments

Comments

@Soltares
Copy link
Contributor

A few requests have come in asking for the ability to run MeshSense without the user interface relying solely on the web interface. I would like to find a way to accomplish this while still taking advantage of the bundled node runtime and automatic updates provided by Electron.

@nbgibson
Copy link
Contributor

I've been musing about this off and on for a bit now. Having a dedicated mode would be useful, but I may try my hand at bundling the app and guacamole (or similar) into a docker container so it can at least function that way if nothing else. It would be wasteful but it ought to work.

@typicalaimster
Copy link

This would be a nice to have along with ARM support. As I access most of my nodes via TCP. Having a headless mode would be one step closer to containerization of the app, putting it on my RaPi cluster, and accessing it via the web interface.

@nbgibson
Copy link
Contributor

Agreed, that would be ideal. I do love a good desktop app though.

I did try and kludge something together to get the app running on a headless x64 linux instance and quickly ran into dependency hell. I suspect that it absolutely could be achieved via some arcane series of nonsense and packages, but the juice likely isn't worth the squeeze unless you're already well versed in that sort of thing. I'll look into it some more as I have time, but the headless refactor is likely going to be the prerequisite before anything moves there.

@RyanWor
Copy link

RyanWor commented Sep 28, 2024

I'd also love to see a headless mode. I am mostly interested in the web interface. But it's also not a big deal to just install a desktop environment and run it that way, especially if it can run and connect automatically at startup.

@valentintintin
Copy link

valentintintin commented Sep 29, 2024

This is what I use on my server with Docker connected with TCP (can work with Bluetooth).

FROM node

RUN apt-get update

WORKDIR /app

RUN git clone https://github.com/Affirmatech/MeshSense.git .

WORKDIR /app/api
RUN npm install
RUN npm run build

WORKDIR /app/ui
RUN npm install
RUN npm run build

WORKDIR /app/api/dist

RUN apt-get update && apt-get install -y libdbus-1-3 && rm -rf /var/lib/apt/lists/*

EXPOSE 5920

CMD ["node", "index.cjs"]

Make a folder with this Dockerfile inside.
Build: docker build -t meshsense .
Run: docker run --rm -v /directory/to/meshsense/config/data:/root/.local/share/meshsense/ -v /var/run/dbus/system_bus_socket:/var/run/dbus/system_bus_socket:ro -p 5920:5920 meshsense
Go to: http://ip:5920

@nbgibson
Copy link
Contributor

nbgibson commented Sep 30, 2024

That's interesting as attempting to replicate that results in a slew of errors at the npm install step. Among other things it's mad that CMAKE isn't present within the build container. Adding that in just results in the following:

8.454 npm error path /app/api/node_modules/webbluetooth
8.454 npm error command failed
8.454 npm error command sh -c prebuild-install --backend cmake-js --runtime napi || cmake-js rebuild
8.454 npm error Not searching for unused variables given on the command line.
8.454 npm error -- The C compiler identification is GNU 12.2.0
8.454 npm error -- The CXX compiler identification is GNU 12.2.0
8.454 npm error -- Detecting C compiler ABI info
8.454 npm error -- Detecting C compiler ABI info - done
8.454 npm error -- Check for working C compiler: /usr/bin/cc - skipped
8.454 npm error -- Detecting C compile features
8.454 npm error -- Detecting C compile features - done
8.454 npm error -- Detecting CXX compiler ABI info
8.454 npm error -- Detecting CXX compiler ABI info - done
8.454 npm error -- Check for working CXX compiler: /usr/bin/c++ - skipped
8.454 npm error -- Detecting CXX compile features
8.454 npm error -- Detecting CXX compile features - done
8.454 npm error -- Configuring incomplete, errors occurred!
8.454 npm error See also "/app/api/node_modules/webbluetooth/build/CMakeFiles/CMakeOutput.log".
8.454 npm error prebuild-install warn install No prebuilt binaries found (target=6 runtime=napi arch=arm64 libc= platform=linux)
8.454 npm error info TOOL Using Unix Makefiles generator.
8.454 npm error info CMD CLEAN
8.454 npm error info RUN [
8.454 npm error info RUN   'cmake',
8.454 npm error info RUN   '-E',
8.454 npm error info RUN   'remove_directory',
8.454 npm error info RUN   '/app/api/node_modules/webbluetooth/build'
8.454 npm error info RUN ]
8.454 npm error info CMD CONFIGURE
8.454 npm error info RUN [
8.454 npm error info RUN   'cmake',
8.454 npm error info RUN   '/app/api/node_modules/webbluetooth',
8.454 npm error info RUN   '--no-warn-unused-cli',
8.454 npm error info RUN   '-G',
8.454 npm error info RUN   'Unix Makefiles',
8.454 npm error info RUN   '-DCMAKE_JS_VERSION=7.3.0',
8.454 npm error info RUN   '-DCMAKE_BUILD_TYPE=Release',
8.454 npm error info RUN   '-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=/app/api/node_modules/webbluetooth/build/Release',
8.454 npm error info RUN   '-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded$<$<CONFIG:Debug>:Debug>',
8.454 npm error info RUN   '-DCMAKE_JS_INC=/app/api/node_modules/node-api-headers/include;/app/api/node_modules/node-addon-api',
8.454 npm error info RUN   '-DCMAKE_JS_SRC=',
8.454 npm error info RUN   '-DNODE_RUNTIME=node',
8.454 npm error info RUN   '-DNODE_RUNTIMEVERSION=22.9.0',
8.454 npm error info RUN   '-DNODE_ARCH=arm64',
8.454 npm error info RUN   '-DCMAKE_JS_LIB=',
8.454 npm error info RUN   '-DCMAKE_CXX_FLAGS=-DBUILDING_NODE_EXTENSION'
8.454 npm error info RUN ]
8.454 npm error CMake Error at CMakeLists.txt:14 (add_subdirectory):
8.454 npm error   add_subdirectory given source "SimpleBLE/simpleble" which is not an
8.454 npm error   existing directory.

I'll keep poking at it but I would appreciate any input you could lend as I hate webdev and have done my best to avoid node just on principle. That said, if this approach can get going it would be pretty trivial to throw together a compose file to do it all. Plus, we could just have CICD build and push out images for folks to use by way of dockerhub.


Wait no, I figured it out. Something about that process hates ARM based architectures. That works exactly as described on x86 machines. Fun. Well if nothing else we could get things going for that.

@nbgibson
Copy link
Contributor

Playing around with that config, it seems extremely promising. Offhand I think the main changes we'd need from the app proper would be to:

  1. Randomize the client key by default
  2. Accept a passed env var to set the client key to a custom string (so it can be set during provisioning)
  3. Require a submission on the field the key is input on to help detect and mitigate potential attacks.
  • The thinking here is that a quick temp auto ban or similar could be put in place after so many failed attempts vs the current check of whether the string in the field is correct that is checked (presumably) on every keystroke; making scripting attacks a viable attack vector. (Instances shouldn't be exposed to the internet, but you know how end users be).

@Soltares
Copy link
Contributor Author

Awesome discussion! My initial idea for headless was to simply be able to pass a CLI flag like --headless to tell Electron not to launch the GUI so it would run in a CLI-based environment. Ideally in this scenario electron could still manage automatic updates.

Creating a docker container also sounds useful and perhaps the headless flag would still be useful here provided it works properly.

Regarding ARM support, I believe the build issue comes from the webbluetooth and simpleble libraries not having prebuilt binaries. #22

Also great ideas on securing the client key! Setting it via environment variable would be pretty straightforward to implement.

@nbgibson
Copy link
Contributor

--headless would be a good value add as we could then slim down the container images a good bit and reduce some operational overhead. (Even more so if we just build a "binary" and chuck it onto an alpine base image. Presuming that's even possible with node.) That remains a "nice to have" as the code @valentintintin provided does output a working setup as is. In Docker's case we don't need to worry about preserving auto updating as you should be pulling a new image for that sort of thing. Cattle vs Pets and so on.

I'd really like to move the git checkout step to a COPY/ADD command pointed at the repo itself for speed and efficiency of the build process, but it's also a nice to have. I can't for the life of me get it to work that way, but that's a function of exhaustion from kids and my willful ignorance of node.

Either way it'd be pretty trivial to implement some pipelines to build docker images. I'll try and get that going when I get a chance. Similarly we could automate out builds for the Desktop versions as well, but I'd need to know how you're doing that currently for the existing offered clients (again, willfully ignorant re: node) and we'd need some sort of workaround to deal with the webbluetooth and simpleble matters. Presumably that's just a matter of compiling them in an ARM system, but that's just supposing; if so, one more thing for CICD to handle.

Soltares added a commit that referenced this issue Oct 4, 2024
Soltares added a commit that referenced this issue Oct 10, 2024
Soltares added a commit that referenced this issue Oct 10, 2024
@Soltares
Copy link
Contributor Author

Randomize the client key by default
Accept a passed env var to set the client key to a custom string (so it can be set during provisioning)
Require a submission on the field the key is input on to help detect and mitigate potential attacks.

The following three have been implemented in some form. Instead of randomizing the key I leave it blank and don't grant permissions to clients until the user explicitly sets an access key. The environment variable is ACCESS_KEY and will override any previous value. The input form no longer validates on keystroke and will test on submit. The form will disappear for an increasing number of seconds on incorrect key entry.

@Soltares
Copy link
Contributor Author

Soltares commented Oct 10, 2024

The recently published 1.0.15-beta.3 includes the commits above. Launching headless would be akin to:

ACCESS_KEY=myKey ./meshsense-x86_64.AppImage --headless

Edit: Usage changed to #8 (comment)

@Soltares
Copy link
Contributor Author

I am changing the above approach for 1.0.15-beta.4 to use an environment variable HEADLESS=1 instead of the --headless argument. When the application restarts after an update, the environment variables persist while the CLI arguments don't.

HEADLESS=1 ACCESS_KEY=myKey ./meshsense-x86_64.AppImage

Soltares added a commit that referenced this issue Oct 17, 2024
@Soltares
Copy link
Contributor Author

Closing for now as Headless Mode is included in the latest release.

@Soltares
Copy link
Contributor Author

Reopening due to some issues discovered with headless mode.

The --headless flag was used initially to launch MeshSense without a GUI and this worked, however the electron-builder automatic update would relaunch MeshSense without this flag causing it to crash when trying to open a window

Switching to the HEADLESS=1 environment variable allowed this option to persist through MeshSense restarts, however, it was discovered that MeshSense is now trying to open a window despite implementation being largely the same.

My best guess is that there is more at play here with Electron and it's Chromium engine and that we happened to get lucky initially and use a --headless flag that also affected the Electron execution. (See https://developer.chrome.com/docs/chromium/headless)

At the very least we should probably switch back to using --headless so that Electron starts properly, but we will need to consider how this will impact auto-updates and if it's feasible to support automatic updates in headless mode.

@Soltares Soltares reopened this Dec 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants