Thursday, October 11, 2018

Solution for: "macOS, Dovecot and setgroups() failed: Too many extra groups"

I upgraded my home server to macOS 10.14 after the upgrade on my laptop went very smooth. Also here the upgrade went smooth, but in the evening I discovered that I did not get any new email.

I started investigating. First I saw that Dovecot did not correctly start because an very old pid file said it has pid 104 and indeed there was a process wit pid 104, so dovecot though that is itself and stopped.

After removing the pid file and restarting Dovecot, it started again and correctly listened on port 993 (imaps). But the imap client still could not login.

Dovecot.log showed a lot of messages

Oct 11 08:10:27 imap(hwr)<12659>: Fatal: setgroups(501) failed: Too many extra groups

Reading the manpage for setgroups() revealed that this call fails when more than NGROUP_MAX (=16) groups are passed. And indeed the user has more than 16 groups:

$ id -G hwr
20 6 12 61 80 98 500 701 702 30 33 100 204 250 395 103 104

Looking at them shows a lot of groups that macOS creates and assigns internally and which one can't (easily) delete

$ id hwr
...
701(com.apple.sharepoint.group.1),702(com.apple.sharepoint.group.2),30(_keytabusers),33(_appstore),100(_lpoperator),204(_developer),250(_analyticsusers),395(com.apple.access_ftp),103(com.apple.access_screensharing-disabled),104(com.apple.access_ssh-disabled)

I wrote to the dovecot mailing list and after an email exchange it turned out that there is a config option already present that can help here to reduce the number of groups passed to setgroups().

So the solution for me is to last_valid_gid = 100 in /usr/local/etc/dovecot/conf.d/10-mail.conf and restart Dovecot.

And now it is again humming along nicely :)

Wednesday, October 03, 2018

MikroTik: access control helpers

I have a MikroTik router and am overall pretty happy with it. Especially the Caps-Man feature for central administration of Wifi access points is great.

One thing I am a bit fighting with is restricting my kids from accessing the internet at certain times of the day. The firewall offers quite some features, but I can't get it to cut existing connections when the rule is triggered by time (and this is also true for the dynamic rules of the kid control feature). But then perhaps I just don't understand routeros well enough.

What I have done is to set up access-lists for caps-man. When they are enabled, WiFi access is no longer possible. They kick in well at the right time, so all is good.

But: sometimes my kids get legitimate exceptions and when I then forget to re-enable the rule, they won't tell me :)

What I have done is created the following script, which is nightly triggered from the scheduler:

:local maccaps
:foreach i in=[/caps-man access-list find ] do={
  :set maccaps ( [/caps-man access-list get value-name=comment number=$i])
  :if ($maccaps~ "^RESET .*\$") do={
       /caps-man access-list enable numbers=$i
    }
}

This looks for access list entries with a comment, where the comment starts with "RESET ". If found the script just re-enables that access list rule.

Permissions needed are read, write and policy.

Please let me know if there are better options.

Thursday, March 29, 2018

Small helper for Mac OS/X to open Jira items

In our Kiali project we develop at GitHub, but have the issue tracker on a Jira instance.

Developers put the jira ticket number into commit comments and pull-request headers. To see the Jira item I had so far to go to the Safari url bar and type in the issue link. Sometimes there was a different item already in the history, so I only had to change the key. But all in all that was tedious.

Luckily OS/X has tools like Automator, that allow to create your own services.

I launched Automator and selected to create a service. For details about this see this article.

I then put a "Execute AppleScript" action into the Automator workflow

automator workflow

Saving this whole workflow under "Open in JBoss Jira" then makes the service immediately available

So I can now select a Jira-key and do right-click to get the service

My service in the service context menu

Obviously the service is very much tailored to my need, so I'll put the AppleScript here so you can copy & modify it to your needs.

on run {input, parameters}
	set target to "https://issues.jboss.org/browse/" & (input as string)
	tell application "Safari"
		activate
		tell window 1
			set current tab to (make new tab with properties {URL:target})
		end tell
	end tell
end run

[ UPDATE ]
My colleague Max Andersen pointed out an even better way of doing this by having some helpers turn those keys into links that can directly be clicked.

Wednesday, January 03, 2018

Homegrown XY plotter with Arduino

[ This is work in progress and only for myself. If you are looking for ready-made kit, then have e.g. a look at the MaXYposi from German Make Magazine ]

Back in school we had a HP plotter well hidden in some closet in the science department. I was able to play with it for a while and always had the desire to have one on my own (but why, where dot-matrix printers are so much versatile and useful).

Bildschirmfoto 2018 01 03 um 12 11 22
Photo from Plotter in action. Video here.

Fast forward many many years. Stepper motors are easily available, I am back into doing stuff with electronics and micro controllers and recently saw someone creating some displays with engraved acrylic. This triggered me to finally get started with the plotter (and later engraver etc).

To get going I got some parts and as I am an old-school 5V guy, I totally like the original Arduino UNO. In the list, I put in links for reference. I am not affiliated with those companies

  • FabScan shield - physically hosts the Stepper motor drivers
  • SilentStepSticks - motor drivers, as the Arduino itself can't handle the voltage and current that a stepper motor needs. I am using the ones with a Trinamic TMC2130 chip, but in standalone mode for now. Those are replacements for the Pololu 4988, but allow for much quieter operation.
  • StepStick protectors - diodes that prevent the turning motor to fry your motor drivers (you want them, believe me)
  • Stepper motors - I took NEMA 17 ones with 12V (Watterott, Sparkfun)
  • Linear guard rails
  • Wooden base plate
  • Wood, screws, ..
  • GT2 belt, GT2 timing pulley

As you can see in the next picture I started out much too big - I can't really have the plotter sit on my desk comfortably, but anyway :) I did it for learning purposes (and as I have to re-do some things, I'll also use smaller beams).

Hardware side

IMG 20180101 185406
View of the plotter base plate with X-axis and Y-axis rails

The belt is mounted on both sides of the rail and then slung around the motor with some helper wheels:


Detail of the belt routing on the motor

On the Arduino side there is a stack of things. On the bottom, the Arduino, then the FabScan shield, then on motor slots 1+2 a StepStick protector and then on top of them the SilentStepSticks. Note that the SCK and SDI pins are not connected

IMG 20180103 110111
Setup on Arduino (see here for a larger image)

Btw be careful with the wires to the motor to correctly attach them. When in doubt have a look at the data sheet or a ohm-meter to figure out which wires belong together.

Software side

I know that there is software like Grbl, that can interpret so called G-codes for tool movement and other things and I could have just flashed that to the Arduino, but I am too curious for that and wanted to better understand things myself.

Basics

To drive a stepper motor with the StepStick driver (or compatibles) one basically needs to send a high and then a low signal to the respective pin. Or in Arduino-terms

digitalWrite(stepPin, HIGH);
delayMicroseconds(30);
digitalWrite(stepPin, LOW);

Where stepPin is the pin number for the stepper - 3 for motor 1 and 6 for motor 2.

Before the stepper does any work, it needs to be enabled.

digitalWrite(enPin, LOW);

Actually the StepStick knows three states for the pin here

  • LOW: motor is enabled
  • HIGH: motor is disabled
  • pin not connected: motor is enabled but goes into some energy saving after a while

When a motor is enabled, its coils are powered and it keeps its position. It is almost impossible to manually turn its axis. This is good for precision purposes, but also means that both motors and driver chips are "flooded" with power and will thus warm up.

And not last but not least, we need a way to determine the direction

digitalWrite(dirPin, direction);

The following table lists the functions and the pins

FunctionMotor1Motor2
enable25
direction47
step36

Before we can use the pins, we need to set them to OUTPUT mode, best in the setup() section of the code

pinMode(enPin1, OUTPUT);
pinMode(stepPin1, OUTPUT);
pinMode(dirPin1, OUTPUT);
digitalWrite(enPin1, LOW);

With that knowledge we can easily get the stepper to move around:

    totalRounds = ...
    for (int rounds =0 ; rounds < 2*totalRounds; rounds++) {
       if (dir==0){ // set direction
         digitalWrite(dirPin2, LOW);
       } else {
         digitalWrite(dirPin2, HIGH);
       }
       delay(1); // give motors some breathing time
       dir = 1-dir; // reverse direction
       for (int i=0; i < 6400; i++) {
         int t = abs(3200-i) / 200;
         digitalWrite(stepPin2, HIGH);
         delayMicroseconds(70 + t);
         digitalWrite(stepPin2, LOW);
         delayMicroseconds(70 + t);
       }
    }

This will make the slider move left and right. When you execute that code, you can also see that this only deals with one stepper, but for a XY-plotter we have two axis to cater for.

Command interpreter

I started to implement a simple command interpreter that allows to use path specifications like

"X30|Y30|X-30 Y-30|X-20|Y-20|X20|Y20|X-40|Y-25|X40 Y25
to describe relative movements in millimetres (internally 1mm equals 80 steps).

The plotter software implements a continuous mode which allows to feed large paths (in chunks) from a connected PC to the plotter. This how the Hilbert-Curve in this tweet has been plotted.

Better pen holder

In the first image above the pen was only tied to the y-Axis with some metal string. This was not precise and did also not allow to have the software raise and lower the hand (this explains the big black dots).

I have meanwhile created a better, more precise pen holder that is using a servo to raise and lower the pen. The original form of this new holder can be seen in the Hilbert-Curve video.

Servo to raise/lower the pen
Close view of the servo arm in the upper position raising the pen.

The Pen gets a little clamp attached (the one shown is a size 8 one to attach cables to walls). The servo arm can then raise the pen. When the arm goes down, gravity will also lower the pen.

Driving the servo

Driving the servo is relatively straightforward. One has to only provide the position and the servo does all the work.

#include <Servo.h>

// Servo pin
#define servoData PIN_A1

// Positions
#define PEN_UP 10
#define PEN_DOWN 50

Servo penServo;

void setup() {
  // Attach to servo and raise pen
  penServo.attach(servoData);
  penServo.write(PEN_UP);
}

I am using the servo headers on the Motor 4 place of the FabScan shield, so the pin to use is Analog pin number one.

Lowering the pen is then as easy as

  penServo.write(PEN_DOWN);

Next

One of the next steps is to add some end-detectors (but I may skip them and use the StallGuard mode of the TMC2130). Those detectors can then also be used to implement a home command

And then perhaps in the future I add a real z-Axis than can hold an engraver to do wood milling or PCB drilling or engraving of acrylic or .... :-) (A laser comes to mind as well).

More ...

That's it for now. The software is available at https://github.com/pilhuhn/xy-plotter and comes without any warranty.

My original announcement tweet

Friday, September 29, 2017

Find the hidden exception with the IntelliJ debugger

I was hacking some code and running tests and got:

  testA(org.acme.ATest)  Time elapsed: 0.114 sec  <<< ERROR!
   java.lang.RuntimeException: Could not inject members
   Caused by: java.lang.NullPointerException

No stack trace, no line number, nothing :-(

Attaching a debugger and making it stop on NPE also did not help, as this was slowing execution down to no avail.

Luckily IntelliJ IDEA has a nice feature to just log the exception when it happens. Just go to the breakpoint view in the Debugger and tick the respective checkbox

Bildschirmfoto 2017 09 29 um 16 16 46

You should also unmark the suspend checkbox as you don't want your porgram being interrupted all the time in places you don't want to know about (I had some hundreds of lines of NPEs within the JRE itself).

When you then attach the debugger to your process, you will see all NPEs along with the place they were thrown. And if the place is within your code, you can navigate to it via the log entry with one click.

I am sure other IDEs have a similar functionality.

Wednesday, June 14, 2017

Was tun ohne Wald?

Mein Beitrag zum Comic-Collab von Schlogger zum Thema Wald.

Comic collab wald

 

Thema für den 15. Juli: „Schmerzen“

Mit dabei im Juni 2017: (wird noch aktualisiert)

– Schlogger
Skizzenblog
pilhuhn
Rainer Unsinn
Strichweise Diesig
Demystifikation
OnlineComics
Pepperworth
Dramatized Depiction
Schisslaweng