Skip to content
Showing user profile of selected author: -

Read a JSON text into a variable in Ansible without parsing it

For one project I need to insert the content of a local file into another file on the remote system, and the first file happens to be JSON. The JSON file is in compact format (jq --compact-output) and is supposed to stay this way. When Ansible reads the content of the file, it determines that the content is JSON, and parses the content into the variable - and along the way is uncompressing the format. Not what I want.

 

Continue reading "Read a JSON text into a variable in Ansible without parsing it"

Does an openHAB Item exist?

In a more complex openHAB2 Rule I'm writing, I need to find out if a certain Item exist. If I try to access it when it does not exist, the Rule will fail. Not good.

I could pass in a parameter to the framework which builds the Rule, but that is cumbersome and requires changes on several places.

Let's see if I can have the Rule figure this out.

 

Continue reading "Does an openHAB Item exist?"

Hanging script at the end of Python multiprocessing

While writing and stress-testing a Python script which uses the multiprocessing library, I ran into the problem that occasionally the script hangs at the end. Literally runs past the last line of code and then hangs.

In this script I'm using Queues and Events, so I made sure that I properly close the queues in the forked/spawned (tried both) processes and also clean out all queues in the parent. Nevertheless occasionally - like seldom, but it happens - the script hangs. Checked the process list, checked remaining threads, checked the queues, all fine. Still ...

When I hit Ctrl+C, I get the following stack trace:

^CError in atexit._run_exitfuncs:
Traceback (most recent call last):
  File "/usr/lib/python3.9/multiprocessing/util.py", line 300, in _run_finalizers
    finalizer()
  File "/usr/lib/python3.9/multiprocessing/util.py", line 224, in __call__
    res = self._callback(*self._args, **self._kwargs)
  File "/usr/lib/python3.9/multiprocessing/queues.py", line 201, in _finalize_join
    thread.join()
  File "/usr/lib/python3.9/threading.py", line 1053, in join
    self._wait_for_tstate_lock()
  File "/usr/lib/python3.9/threading.py", line 1073, in _wait_for_tstate_lock
    if lock.acquire(block, timeout):
KeyboardInterrupt

(Can't change the Python 3.9, as I don't control the target system where this is supposed to run)

There's nothing left to join, the only two remaining threads are MainThread and QueueFeederThread.

 

After some more debugging I had the simple idea not only to empty the queue before finishing the script, but setting the queue variable to None:

worker_queue = None

This helps. The script is no longer hanging at the end. At a later point I will see if the problem is fixed in newer versions.

Not so equal texts in PostgreSQL - and how to compare texts in a more elaborate way

Christophe Pettus posted an interesting challenge here. Two strings which on the surface look equal, but if you ask PostgreSQL to compare them, they are not equal.

Now let me start with a note: Twitter totally screws this challenge up.

How so? Although the two strings are different in the original, when posting this to Twitter the strings are made equal. Where is the fun in that?

I asked Christophe for the original query:

INSERT INTO t VALUES (E'Zo\u0065\u0301', E'Zo\u00e9');

And you end up with the following texts in the table:

SELECT * FROM t;
  a  |  b  
-----+-----
 Zoé | Zoé
(1 row)

If you translate the UTF-8 strings into hex, you get "0x5a 0x6f 0x65 0xcc 0x81" and "0x5a 0x6f 0xc3 0xa9". Clearly they are different.

However if you convert the two strings from the Tweet, you get "0x5a 0x6f 0xc3 0xa9" and "0x5a 0x6f 0xc3 0xa9". Same string. Poor Twitter.

Checking the hex values was actually one of my first ideas when I spotted this challenge. But nevertheless based on my experience from my "Data Types in PostgreSQL" and "Advanced Data Types in PostgreSQL" talks, I figured it should be possible to "solve" this puzzle even if the strings are in fact equal.

Buckle up! We are about to dive deep into how extendible PostgreSQL really is!

 

Continue reading "Not so equal texts in PostgreSQL - and how to compare texts in a more elaborate way"

Golf 8 - ein Jahr

Wir haben den Golf 8 jetzt etwas über ein Jahr, Zeit eine weitere Bilanz zu ziehen.
Oder wie der Werkstattmeister so schön sagte: “Das Fahrzeug ist häufiger bei uns als bei Ihnen”.

Die Aussage aus dem letzten Blog Post bleibt im wesentlichen: von der Hardware her ist der Golf 8 ein solides Auto. Die Software braucht jedoch noch 3, 4 Jahre. Die meisten Probleme die wir im letzten Jahr hatten, waren irgendwie mit der Software verbunden. Das Fahrzeug stand insgesamt 5 oder 6 Mal in der Werkstatt, was für einen Neuwagen viel zu viel ist.
 

 

Continue reading "Golf 8 - ein Jahr"

WMF Küchenminis Smoothie-to-go 0,6l

Irgendwann September 2020 wollten wir unseren in die Tage gekommenen Smoothiemaker ersetzen. Nach etwas Recherche wurde es dann der "WMF Küchenminis Smoothie-to-go 0,6l". Es sollte nicht der einzige bleiben.

Das Gerät ist eigentlich gut verarbeitet, aber recht laut im Gebrauch. Stört aber nicht so sehr, weil man es meistens tagsüber verwendet. Solider Rahmen aus Edelstahl, lässt sich leicht reinigen. Ein paar Kleinigkeiten sind mit der Zeit jedoch aufgefallen:

  • Der Verschluss des Behälters mit dem eigentlichen Schneidwerk schließt recht genau mit der Fassung des Gehäuses ab. Nechdem sich einmal nach dem Mixen der Behälter vom Schneidkopf gelöst hat und der Kopf selber nicht aus der Fassung ausrasten wollte, standen wir dann mit einem etwas klebrigen Problem dar. Letzten Endes haben wir den Behälter umgedreht und abgeschraubt und danach mit einer Zange den Schneidkopf herausgedreht. Der glatte Abschluss zwischen Schneidkopf und Rahmen des Motors sieht zwar hübsch aus, ist aber nicht in jedem Fall hilfreich.
  • Das Gehäuse hat Öffnungen zum Motor hin. Mir ist nicht ganz klar wozu diese gut sind, aber wenn etwas Flüssigkeit aus dem Behälter (siehe oben) da hineinläuft, tut man sich schwer diese Öffnungen wieder sauber zu bekommen. Öffnungen nach unten zum Boden hin sollten reichen.

Im Juni 2021 ergab sich ein größeres Problem: der Einschaltknopf schaltete das Gerät nicht mehr in jedem Fall ein, sondern blockierte ab und zu. Im Boden des schwarzen Kopfes der den Schneidkopf aufnimmt ist eine mechanische Verriegelung angebracht die durch den Schneidkopf betätigt wird. Das stellt sicher dass der Motor nur angeschaltet werden kann wenn ein Behälter eingesetzt ist. Diese Verriegelung ist irgendwie mechanisch mit dem Einschaltknopf innerhalb des Gehäuses verbunden. Wenn man (mit gezogenem Stecker) die Verriegelung eindrückt stellt man fest wie die Verriegelung am Schalter aufgehoben wird. So weit, so gut. Jedoch funktionierte dieser Mechanismus nach rund 9 Monaten nicht mehr zuverlässig, sondern blockierte immer häufiger.

Garantiefall aufgemacht, das Gerät wurde getauscht. Das neue Gerät funktionierte anfangs einwandfrei - bis zum Dezember. Danach trat das gleiche Problem auf, jedoch diesmal sofort. Während beim ersten Gerät immer mal wieder der Einschaltknopf noch betätigt werden konnte, blockierte das zweite Gerät von einem Tag auf den anderen und ließ sich nicht mehr einschalten. Nach rund 8 Monaten genau das gleiche Problem?

Diesmal habe ich das Gerät einfach zurück gegeben. Jetzt muss ich noch einen anderen Smoothiemaker finden, nicht von WMF.

Icinga Director and disk checks for fuse mountpoints

When I rolled out my new Icinga2 installation, and added disk checks for all laptops, I ran into a small problem: there is a fuse mountpoint for logged in users which only the user can read. Apparently it has something to do with Flatpack.

cat /proc/mounts | grep doc
/dev/fuse /run/user/1000/doc fuse rw,nosuid,nodev,relatime,user_id=1000,group_id=1000 0 0

By default, the Icinga2 ITL has a number of file system types excluded for the "check_disk" check, even some special fuse types, but plain "fuse" is not among them. Kind of makes sense, a fuse mountpoint can be anything, and you don't want to exclude all of them by default.

This results in the following error message when the check is rolled out on our laptops:

Plugin Output
DISK CRITICAL - /run/user/1000/doc is not accessible: Permission denied

Fortunately the fix is rather easy:

 

 

Continue reading "Icinga Director and disk checks for fuse mountpoints"