The Minimal InfluxDB Client in Go

While you can get a proper InfluxDB client library for Go, sometime there’s no substitution for rolling one yourself - especially since InfluxDB’s Line Protocol is really easy.

It’s just a matter of constructing a correct URL and setting up just two headers. Something like this:

func sendInfluxData(line string, baseUrl string, org string, bucket string, token string) {
    var url string
    if len(org) > 0 {
        url = fmt.Sprintf("%s/api/v2/write?org=%s&bucket=%s",
			  baseUrl, org, bucket)
    } else {
        url = fmt.Sprintf("%s/api/v2/write?bucket=%s",
			  baseUrl, bucket)
    }

    request, _ := http.NewRequest("POST", url, strings.NewReader(line))
    request.Header.Set("Content-Type", "text/plain")
    if len(token) > 0 {
        request.Header.Set("Authorization", "Token " + token)
    }

    response, _ := http.DefaultClient.Do(request)
}

And yes, code doesn’t do error checking nor it has any comments. Deal with it. ;)

Dazed and Confused, but Trying to Continue

Illustration

From time to time, I would see the following slightly poetic statement on my console.

Uhhuh. NMI received for unknown reason 31 on CPU 3.
Do you have a strange power saving mode enabled?
Dazed and confused, but trying to continue

The first Internet search brought me sadness and dismay - my hardware was failing. It took going a bit deeper to find that AMD servers have that issue quite often even in the absence of real hardware failure.

Solution? Disable darn C-States. It’s a server after all.


PS: And no, even if you want to keep C-States, reason 31 is nothing to worry about - it’s been happening on my system for 2 years before this and I had no issues with it. It’s just annoyance and nothing more.

Recording Both Microphone and Speaker Under Ubuntu 21.04

When one records audio under Linux, issue that quite a few applications have is recording both microphone input and headphone output. And that’s true for SimpleScreenRecorder, otherwise really good recording application.

However, Linux always has a way around those restrictions and those can be actually found on SimpleScreenRecorder pages if you look deep enough.

pactl load-module module-null-sink \
  sink_name=duplex_out sink_properties=device.description="\"Duplex\ Output\""
pactl load-module module-null-sink \
  sink_name=app_out sink_properties=device.description="\"Application\ Output\""
pactl load-module module-loopback source=app_out.monitor
pactl load-module module-loopback source=app_out.monitor sink=duplex_out
pactl load-module module-loopback sink=duplex_out
pactl set-default-sink app_out

Trick is to essentially create two new output devices (i.e. sinks). One of them (app_out) will just be a target toward which applications should direct their output. Magic happens with the second output (duplex_out) which combines application output and what comes from microphone.

Now when you record audio, you can just point application to Duplex Output and record both sides.


PS: To make these changes permanent, they can be entered into /etc/pulse/default.pa. Of course, quoting rules are bit different so adjust accordingly if you have a space in your description.

…
# Recording setup
load-module module-null-sink sink_name=duplex_out sink_properties=device.description="Duplex\ Output"
load-module module-null-sink sink_name=app_out sink_properties=device.description="Application\ Output"
load-module module-loopback source=app_out.monitor
load-module module-loopback source=app_out.monitor sink=duplex_out
load-module module-loopback sink=duplex_out
set-default-sink app_out

On Air

Illustration

Working from home requires a bit of synchronization between occupants. Especially if one member of family spends a lot of time on calls. Quite early into the work-at-home adventure, my wife found a solution. She bought a lighted “On Air” sign.

Idea was good. Whenever I am in conference call, I just light up the sign and everybody knows to keep quiet as our words are not private anymore. In reality most of the time I would either leave sign on longer than needed or forger to turn it off when I’m done speaking.

And pretty much all issues could be traced to the position of the sign. While it was visible to everybody else in the room, it wasn’t directly visible to me. And to make it more annoying, turning it off and on required me to get off the chair. Excellent for physical activity but annoying to do if I need to turn it on/off multiple times in a call.

So I decided to automatize this a bit.

I first repurposed one of the Wyze Plug devices I had around and went about looking for API. Unfortunately, Wyze doesn’t offer public API at this time but other people already reverse-engineered it. But alas, all those ports were outdated. Until I found a gem in comments. With those changes it was easy enough to make my own mini application.

While this would be enough for turning on/off the light, I was after something a bit more fine-grained. In quite a few conference calls I might not speak a lot. For them I just usually hit Mute Mic button on my Lenovo P70 and unmute only when I need to actually speak. So it seemed like a good compromise to only light up the sign when I am unmuted. If I’m muted, other family members can have their conversations without impacting my call.

And the following script was the last piece of the puzzle:

#!/bin/bash

LAST_MIC_STATUS=
while (true); do
  CURR_MIC_STATUS=`/usr/bin/amixer get Capture | grep -q '\[off\]' && echo 0 || echo 1`

  if [[ "$LAST_MIC_STATUS" != "$CURR_MIC_STATUS" ]]; then
    LAST_MIC_STATUS=$CURR_MIC_STATUS
    if [[ "$CURR_MIC_STATUS" -ne 0 ]]; then NEW_STATE=true; else NEW_STATE=false; fi

    WYZE_EMAIL="^^unknown@example.com^^" \
    WYZE_PASSWORD="^^changeme^^" \
    WyzePlugControl ^^2CAA8E6616D2^^ $NEW_STATE
  fi

  sleep 1
done

It will essentially just check for the status of my mute button and adjust Wyze Plug accordingly. At least until Wyze changes API again.

DevStack on VirtualBox Ubuntu 20.04

Illustration

The first step for DevStack inside of VirtualBox is creating the virtual machine. There are two obvious changes that you need to make and those are increasing processor count and assigned memory as high as you can afford it. The other two are a bit more “sneaky”.

We really have to enable Nested VT-x/AMD-V under System, Processor and if we want to access our system we should really set network forwarding rules for port 80 (HTTP for Dashboard) and port 22 (SSH, optional but really helpful). I usually set them to be 56080 and 56022 respectively under my localhost but the actual numbers can be of your choosing. And yes, there are other ways to setup networking but NAT with forwarding is mine.

With the virtual machine set, the next step toward DevStack is installing OS. While official guidelines prefer Ubuntu 18.04, I like to go with a slightly newer Ubuntu 20.04 Server. Whole installation is essentially one big click-next event with the only non-default part being installation of OpenSSH.

Once OS is installed, I also like to add my user to password-less sudoers and do any needed updates:

echo "$USER ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/$USER

sudo apt update
sudo apt dist-upgrade --yes

And now finally we can follow the DevStack instructions with customized host IP (otherwise you’ll get “Could not determine host ip address” error) and admin password.

sudo useradd -s /bin/bash -d /opt/stack -m stack
echo "stack ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/stack
sudo su - stack

git clone https://github.com/openstack-dev/devstack.git -b $STACK_BRANCH devstack/
STACK_BRANCH=stable/^^wallaby^^

cd devstack
cp samples/local.conf .
sed -i 's/#HOST_IP=w.x.y.z/HOST_IP=^^10.0.2.15^^/' local.conf
sed -i 's/ADMIN_PASSWORD=nomoresecret/ADMIN_PASSWORD=^^devstack^^/' local.conf
echo "#Enable heat services" >> local.conf
echo "enable_service h-eng h-api h-api-cfn h-api-cw" >> local.conf
echo "#Enable heat plugin" >> local.conf
echo "enable_plugin heat https://git.openstack.org/openstack/heat $STACK_BRANCH" >> local.conf

./stack.sh

Once done, GUI is available at http://localhost:56080/dashboard/.