Work from home vs Work with home

[ Το αντιγράφω από ανάρτηση που έκανα στο Facebook ]

Υπάρχει πολύς κόσμος που επειδή δεν έχει την εμπειρία του WFH, νομίζει πως αυτό που ζούμε τώρα, στις επείγουσες καταστάσεις του προηγούμενου διμήνου είναι η τηλεεργασία. Δεν είναι.

WFH, σημαίνει πως είμαι στο σπίτι (ή σε κάποιο γραφείο όχι πολύ μακριά) και δεν χρειάζεται να είμαι στην έδρα του εργοδότη μου (που για να πάω και να γυρίσω μπορεί να χρειάζομαι 2 και βάλε ώρες κάθε μέρα).

Σημαίνει επίσης πως εγώ είμαι στο σπίτι και έχω ένα χώρο που για όσο δουλεύω είναι ο χώρος εργασίας μου και δεν είναι το υπνοδωμάτιο που μπορεί να είναι προσβάσιμο στον καθένα. Δεν είναι.

Σημαίνει επίσης, πως εγώ είμαι στο σπίτι. Τα παιδιά (αν υπάρχουν) είναι στο σχολείο και το ίδιο και το έταιρο ήμισυ, είναι στον εργασιακό του χώρο (εκτός κι αν επίσης τηλεεργάζεται).

Σημαίνει επίσης πως υπάρχει γραμμή σύνδεσης στο δίκτυο αρκετή για να σηκώσει τη δουλειά, υπάρχει εναλλακτική με data από την κινητή αν χρειάζεται (είναι ξεκαθαρισμένο ποιος τα πληρώνει αυτά εξαρχής) και πως υπάρχει υπολογιστής για να κάνω εγώ και μόνο εγώ την δουλειά μου σε αυτόν.

Τώρα όταν έχεις ανθρώπους που βρεθήκανε ξαφνικά να πρέπει να δουλέψουν από το σπίτι έχοντας ένα μόνο υπολογιστή (για δύο εργαζόμενους στην καλή περίπτωση) που υπήρχε για recreational activities και χωρίς το απαραίτητο software και επιπλέον και παιδιά να πρέπει να κάνουν εργασίες, skype για φροντιστήριο, να παίξουν κάτι και να παρακολουθήσουν streaming με την πιο φτηνή σύνδεση που αντέχει το πορτοφόλι τους, την ώρα που εσύ θα πρέπει να εργάζεσαι, αυτό δεν το λένε “δουλειά από το σπίτι”, αλλά “δουλειά με το σπίτι”.

Τα γράφω αυτά γιατί το τυχαίο νοικοκυριό δύσκολα θα έχει την υπολογιστική επάρκεια που έχει το δικό μου (όπως κι εγώ δεν έχω τόσους κάβουρες ή κόφτες όσους έχουν ένας ηλεκτρολόγος και ένας υδραυλικός).

Two tricks that make life when dual booting between Windows 10 and Ubuntu easier

So you have your laptop with Windows 10 and you also need to run Ubuntu for some reason. Even if Ubuntu is the main OS, you may want to keep Windows around for the occasional system upgrade (Dell Update comes to mind for example) and software that runs exclusively one one of the two platforms (UCINET is such a program for me).

You are then faced with two problems:

  • Default boot operating system
  • The clock gets descynchronized when rebooting between the two operating systems.

StackExchange comes to the rescue. For the first problem you have to modify grub. I have chosen to make so that upon reboot, it will boot the previous operating system it did, unless I choose otherwise via the menu. I use the saved method from this answer.

For the second issue, there are a number of answers that usually involve tweaking systemd or the windows registry, but the easiest thing you can do is to ensure that the windows time service is started automatically with a delay.

 

newsletters that I value

Let’s break this blog’s hiatus with an uninteresting post.

I am still a heavy email user. I am subscribed to more mailing lists and newsletters than most can handle, and even I, after almost 30 years of email usage, am feeling INBOX fatigue. I unsubscribe and delete unread mail without remorse. However there are a handful of newsletters that I think I am going to keep around for as long as they are around. These are:

  • Fermat’s Library. I won’t claim that I understand either every paper, or commentary on paper of the week. But I get interesting, yet never pursued, ideas sometimes.
  • The morning paper. More CS centric and also I won’t claim to always grasp the subject (or even like it). But still, good things to consider here.
  • Quanta magazine. Science concepts delivered in a way they can be understood.
  • The porcupine newsletter. Because if I had time, I’d want to post a newsletter and follow its style.

So what are yours?

 

Temporarily disabling an ansible task in a playbook

I have a playbook that provisions a vagrant box. Among other things is installs docker:

- name: install docker
  apt:
    name: "docker.io"
    state: latest

For reasons, I wanted this temporarily disabled in repeated runs of the playbook. Enter the when: statement:

- name: install docker
  apt:
    name: "docker.io"
    state: latest
  # Do this for example when you choose docker to be 
  # installed from a vagrant provisioner but do not 
  # want to remove the task from the playbook.
  when: 0 > 1

You can of course switch from the condition of 0 > 1 to a variable that takes the values true or false and even drive this from the command line by setting the value of the variable.

Stop the Dell Inspiron 7373 fan from making noise all the time.

This seems to be a problem with some Dells. It also seems to not be remedied with the usual tricks, like BIOS updates, tweaking the BIOS, running Dell Update or SupportAssist. I know because I’ve tried them all suggestions. It made participating to teleconferences (with any tool) extremely difficult.

The last thing I tried was to alter the Maximum Processor State:

Annotation 2020-04-07 102748

And it seems to be working.

Don’t disable IPv6, block the traffic instead

It is a somewhat common practice to disable IPv6 when you have to deal with no such traffic. However, doing so may have some unintended consequences, like when running rpcbind for NFS sharing:

Feb 20 11:27:12 server systemd[1]: rpcbind.socket failed to listen on sockets: Address family not supported by protocol

So, don’t disable IPv6 traffic. Aim to blocking it instead. Or if you must have it disabled, read here.

PS: This is not a post advocating not adopting IPv6. This is simply a workaround if the situation arises. You need to operate in an IPv6 world.

base64 and SASLprep: failed prohibited character check

I was trying something out on a minikube cluster the other day, and my python application could not connect to a mongo database that was deployed with helm. I had authentication enabled, the secret deployed in minikube and was greeted by the following error message:

SASLprep: failed prohibited character check

WTF? The password was definitely ascii printable characters. Could there be prohibited characters among the alphabet? I browsed through RFCs 4013 and 3454 but there was nothing I could immediately pinpoint there. However, this tweet by jpmens was circling my mind, and:

$ echo qwerty1234 | base64
cXdlcnR5MTIzNAo=

$ printf qwerty1234 | base64
cXdlcnR5MTIzNA==

$ echo -n qwerty1234 | base64
cXdlcnR5MTIzNA==

Yes, the kubernetes secret had a \n attached to it. Because two things are hard in CS:
– naming things
– cache invalidation
– off by one errors

aws ssm describe-instance-information for quick ansible dynamic inventory

The aws ssm agent is very useful when working both with EC2 instances and with machinery outside AWS. Once you add an outside instance by installing and configuring the SSM agent, be it on-premises or a VM at another provider, you can tag it for further granularity with aws ssm add-tags-to-resource --resource-type ManagedInstance --resource-id mi-WXYZWXYZ --tags Key=onpremise,Value=true --region eu-west-1 where mi-WXYZWXYZ is the instance ID you see at the SSM’s managed instances list (alternatively you can get this list with aws ssm describe-instance-information along with lots of other information).

It may the case that sometimes you want to apply with ansible a certain change to those machines that live outside AWS. Yes you can run ansible workbooks via the SSM directly, but this requires ansible installed on said machines. If you need the simplest of dynamic inventories, to $ ansible -u user -i ./lala all -m ping here is the crudest version of ./lala, one that happily ignores the --list argument:

#!/bin/bash
printf "%s%s%s" \
'{ "all": { "hosts": [' \
$(aws ssm describe-instance-information --region eu-west-1 --filter Key=tag:onpremise,Values=true --query "InstanceInformationList[].IPAddress" --output text | tr '[:blank:]' ',') \
'] } }'

You can go all the way scripting something like this for a proper solution though.

Why printf instead of echo above? Because jpmens suggested so.

Running monit inside Kubernetes

Sometimes you may want to run monit inside a Kubernetes cluster just to validate what you’re getting from your standard monitoring solution with a second monitor that does not require that much configuration or tinkering. In such cases the Dockerfile bellow might come handy:

FROM ubuntu:bionic
RUN apt-get update
RUN apt-get install monit bind9-host netcat fping -y
RUN ln -f -s /dev/fd/1 /var/log/monit.log
COPY monitrc /etc/monit
RUN chmod 0600 /etc/monit/monitrc
EXPOSE 2812
ENTRYPOINT [ "/usr/bin/monit" ]
CMD [ "-I", "-c", "/etc/monit/monitrc" ]

I connected to it via kubectl -n monit-test port-forward --address=0.0.0.0 pod/monit-XXXX-YYYY 2812:2812. Most people do not need --address=0.0.0.0, but I run kubectl inside a VM for some degree of compartmentalization. Stringent, I know…

Why would you need something like this you ask? Well imagine the case where you have multiple pods running, no restarts, everything fine, but randomly you get connection timeouts to the clusterIP address:port pair. If you have no way of reproducing this, don’t you want an alert the exact moment it happens? That was the case for me.

And also the fun of using a tool in an unforeseen way.

Rancher’s cattle-cluster-agent and error 404

It may be the case that when you deploy a new Rancher2 Kubernetes cluster, all pods are working fine, with the exception of cattle-cluster-agent (whose scope is to connect to the Kubernetes API of Rancher Launched Kubernetes clusters) that enters a CrashLoopBackoff state (red state in your UI under the System project).

One common error you will see from View Logs of the agent’s pod is 404 due to a HTTP ping failing:

ERROR: https://rancher-ui.example.com/ping is not accessible (The requested URL returned error: 404)

It is a DNS problem

The issue here is that if you watch the network traffic on your Rancher2 UI server, you will never see pings coming from the pod, yet the pod is sending traffic somewhere. Where?

Observe the contents of your pod’s /etc/resolv.conf:

nameserver 10.43.0.10
search default.svc.cluster.local svc.cluster.local cluster.local example.com
options ndots:5

Now if you happen to have a wildcard DNS A record in example.com the HTTP ping in question becomes http://rancher-ui.example.com.example.com/ping which happens to resolve to the A record of the wildcard (most likely not the A RR of the host where the Rancher UI runs). Hence if this machine runs a web server, you are at the mercy of what that web server responds.

One quick hack is to edit your Rancher2 cluster’s YAML and instruct the kubelet to start with a different resolv.conf that does not contain a search path with your domain with the wildcard record in it. The kubelet appends the search path line to the default and in this particular case you do not want that. So you tell your Rancher2 cluster the following:

  kubelet:
    extra_args:
      resolv-conf: /host/etc/resolv.rancher

resolv.rancher contains only nameserver entries in my case. The path is /host/etc/resolv.rancher because you have to remember that in Rancher2 clusters, the kubelet itself runs from within a container and access the host’s file system under /host.

Now I am pretty certain this can be dealt with, with some coredns configuration too, but did not have the time to pursue it.