TLDR
Applications in snaps running script to call other electron snapped application do not mix well.
Final solution, was use old tools like incrond to captures the changes in the diagrams to auto generate the files.
Story
💡
My first thought was to create a GitHub Action to generate these files, but actions-drawio is based in code it is archived, because drawio-desktop already supports command line interface to export to image formats.
Some time ago, skimming git documentation I saw references for hooks and this time, was a good time to try it out. Each time I commit a new diagram, it will auto generate a new image.
It could not to be to difficult to do a simple script to do this task… and… oh god! how wrong I was.
Hurdle ① - Snap Confinement and drawio-desktop
Snap Confinement is good for the security of our computers, but, it expects users have their files in the default locations, and, almost all my files are not.
So I try to use the trick to remount my working directory inside /mnt
to allow snap removable-media interface to use it, but no luck.
$ sudo snap connections drawio | grep removable-media
$
Solution
Modify the snap to add the removable-media
interface
$ snap download drawio
$ unsquashfs -dest drawio_138 drawio_138.snap
Edit drawio_138/meta/snap.yaml
and add removable-media
into plugs
Resulting in something like:
apps:
drawio:
command: command.sh
plugs:
(...)
- opengl
- removable-media
environment:
Then, use the modified snap with snap try
$ sudo snap try drawio_138
Snap, installed
$ snap list
Name Version Rev Tracking Publisher Notes
core20 20211129 1270 latest/stable canonical✓ base
drawio 16.0.2 x1 - - try
Last task, mount
the directory in the new location, adapted from Home directories outside of ‘/home’
# mount --bind /work/WIP/ /mnt/WIP/
Hurdle ② - Git Hooks
I’m new to git, so, choose the right hook to do the task, was not easy… some voices in internet, say to use pre-commit
, but adding files at this stage is not linear.
My chosen solution was to do a post-commit
, in which will generate the file and then add and commit the file. Something like:
/snap/bin/drawio --export
git add
git commit -m "AutoCommit - Update DrawIO Images"
I made the script work when I manually ran git commit
on terminal… but when the hook ran inside VSCodium… it didn’t work…
Hurdle ③ - Electron… Snaps…
From inside an Electron App (VSCodium) try to run another Electron App (drawio-desktop), was an hell, so I quit to make it work.
Just a quick note, if you see something like this in your system logs
kernel: traps: drawio[767435] trap int3 ip:55fac191b086 sp:7ffe0bb228d0 error:0 in drawio[55fac0bcb000+6a10000]
Consider it as a core dump.
Hurdle ④ - No Git Hooks
Without git hooks, I need to find a solution to detect file changes, and inotify kernel feature is a great solution, but lack a good user land tools.
inotifywait paired with while, as many solutions out there, was not an option…
Just found to possible paths:
incron
👍 Already use it on other project and it simple to use
👎🏼 mask special symbol do not work: dotdirs, loopable and recursive,
👎🏼 Security problems
👎🏼 Project stalled
systemd.path
- 👍 I would like to use
StartLimitIntervalSec
andStartLimitBurst
, because, drawio-desktop after each change saves the file. - 👎🏼 How to tell which PathChanged?
Do not have an option to have the name of the modified file, kills the possibility to use systemd.path
, I do not know how many files and directories I will have in the end, and manage all manually, will kill the agility.
So in the end, I just have the option of incron
😒
Hurdle ⑤ - Electron is not meant to run on headless
Electron apps are made to be used in a graphical environment, not to be used in a script.
But fortunately, someone use CICD process to test their electron app already have that problem solved.
Meanwhile, feature request in electron is not done, we have an option to create a Xvfb
Solution
Install and configure incron
This is the easiest part
$ sudo apt install incron
Then, add your username to /etc/incron.allow
Deploy user configurations
Edit incrontab
$ incrontab -e
and add your configuration
/work/WIP/Clouds/*.drawio IN_CLOSE_WRITE /home/johndoe/bin/incron-drawio.sh $@
Then create your script /home/johndoe/bin/incron-drawio.sh
My Script
#!/bin/bash
set -Eeuo pipefail
# because drawio runs as a snap, it can not access the real location of the file
# to be changed as needed
realFile=$( readlink -f "$1" | sed "s#/work#/mnt#" )
lastChange=$(stat --format="%Y" "${realFile%.*}".png)
now=$(date +"%s")
delta=$(( now - lastChange ))
# drawio saves file each time it move an item... ignore changes below 30 seconds
[ $delta -lt 30 ] && exit
echo "incron generating image from $1" | logger
# drawio is an electron app, and expect to have a display server
# so, use a framebuffer without GPU
export DISPLAY=':99.0'
Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
Xvfb_PID=$!
drawio='/snap/bin/drawio --export --width 1024 --border 10'
$drawio --output "${realFile%.*}".png "$realFile" | logger
kill $Xvfb_PID
🍬
Some other resources how help me in this journey