CSSimon, a CS game of Simon

Again I use this forum as a kind of sticky note of things I consider interesting but not necessarily useful. Again this is some kind of digest of the CodePen email bulletin – suscribe if you like to code, the code, or simply the electronic art.

Here to the left we have a picture of what you get if you implement this codepen. A fully functional Simon game. For those of you who didn’t live it, Simon is a memory game. It’s very easy to play and a lot of fun – at least for me. A sequence of sounds and colours are given by the device – in this case by the CSS implementation – that you are asked to repeat. The sequence becomes after each repetition longer and faster, until you have no way to win. Because you can be sharp, and fast, but on sequences, you will never defeat the machine. As far as I know. Since each colour has a light in it, I remember we playing the physical device in turns in the dark, with the hope of beating it up. Long time ago, in a galaxy far, far away. Have a nice weekend you all!

GPU programming tests on CentOS 7

As a benchmarking fan, I was looking for a minimal code to run able to give us the difference between CPU and GPU calculations. I found it on this linuxhint article. At the bottom, you have two links for further reading: GPU programming with C++ and GPU programming with python. I’ve tried both on my CentOS 7.9 and a Quadro K5200. First step is to install the default CUDA:

yum install cuda

In my case, the above command installed cuda-11.7. I previoulsy had the drivers for the GPU installed. Unfortunately that seems not to be enough. You need the nvidia compiler, nvcc. Very easy to install if you don’t have it:

yum install nvcc

The compiler lands on /usr/local/cuda/bin/nvcc. You may want to modify your PATH variable to point to that folder also. I didn’t. Time to copy the sample code given above. I save everything in my project folder and type make as suggested.

gputest ## > make
/usr/local/cuda/bin/nvcc
-std=c++11 gpu-example.cpp -o gpu-example
gpu-example.cpp: In function
'void vector_add_gpu(int*, int*, int*, int)':
gpu-example.cpp:24:13: error: 'threadIdx'
was not declared in this scope
int i = threadIdx.x;
^
gpu-example.cpp: In function 'int main()':
gpu-example.cpp:64:22: error: expected primary-expression
before '<' token
vector_add_gpu <<<1, ITER>>>
(gpu_a, gpu_b, gpu_c, ITER);
^
gpu-example.cpp:64:32: error: expected primary-expression
before '>' token
vector_add_gpu <<<1, ITER>>>
(gpu_a, gpu_b, gpu_c, ITER);
^
make: *** [all] Error 1

In case it’s not clear, the code copied as-is didn’t work. I check the nvcc compiler is there (it is!) so it’s something else. I guess from this nvidia forum post the problem may be in the convention I’m using. I rename my file and adjust the Makefile accordingly

mv gpu-example.cpp gpu-example.cu

After that, make works and I get a binary that I can run. This is my output.

gputest ## > make
/usr/local/cuda/bin/nvcc -std=c++11 gpu-example.cu -o gpu-example
gputest ## > ls
gpu-example* gpu-example.cu Makefile
gputest ## > ./gpu-example
vector_add_cpu: 432218 nanoseconds.
vector_add_gpu: 19573 nanoseconds.

Later runs give me different numbers but in the same order: the GPU calculation is 20 times faster than the CPU one. Further analysis is needed 🧐

Night live

I’m not anymore a teenager. So I don’t go out as frequently as before, when I was craving for new experiences. In my early years at the university, we were looking forward to meet just to comment on the hair of the new anchorman, or to gossip about the new girlfriend of B. I have very good memories of dark long nights, and those wanders from bar A to club Z, and the other way around. The moonlight against a streetlamp, counting pocket money to save for the last drink, a coffee in the morning. People living the moment, with dumb phones, and we spoke a lot, about every little spot. Now when I feel low I want to come back to those memories. Reset my mind by running out of words. The thing is, the magic still works. Yesterday I met a friend from my childhood, and we had a big time. The clubs were not the same. The city was not the same. We definitely were not the same. But I almost didn’t look at my phone, if only to connect, somehow, with the rest of the world. A picture here, another there. Just for the records. Just in case. Maybe even ashamed of it. A dream that is not a dream, but it worked. And I have strength again to assume that, after all, we may be getting old, but inside, we are still those two wandering boys.

The systemd-analyze and daemon management on Linux

I feel like I need to write down this.I was fighting with a rebel docker process in a multi-purposed server so I was forced to review the services. First thing I did is to check the starting time of each service. You can find a detailed post in the geekdiary. This is done like this

systemd-analyze blame

I’m not going to copy my output, but I’ll say I didn’t find any clear culprit. Here you have the official systemd-analyze man page. Let’s say I really suspect of the docker daemon. Where’s the service file? We can cat the service like this (partial output):

root@bad ~ ## > systemctl cat docker
# /usr/lib/systemd/system/docker.service
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target docker.socket firewalld.service containerd.service
Wants=network-online.target
Requires=docker.socket containerd.service

[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
...

As you see, it gives you the location of the file as well as the content. Now I can change the timeout, or the restart options, or whatever I want. I go anyway for reinstalling the service completely (docker) and reviewing my docker monitoring code, so that it doesn’t make so many calls to the daemon, and after that my service lagging problem is gone. BTW my docker error is described here. Long story short, there was nothing wrong with the service but with my code. So review your code and test it as much as you can! 😉

HOWTO: install xwiki on debian 11

Previously I gave you serveral options to install a wiki as a docker. This time we are going to do it for real on a Debian 11 (bullseye) system. I want to log this because I tried already several times, and I tend to screw it up at one point. Just in case you want to start with the online sources, here you have the howto from linuxhotsupport, here one howto from rosehosting, and here the official xwiki documentation. Let’s go. First we update and so on:

root # apt-get update
Hit:1 http://deb.debian.org/debian bullseye InRelease
Get:2 http://deb.debian.org/debian bullseye-updates InRelease [44.1 kB]
Get:3 http://deb.debian.org/debian bullseye-backports InRelease [49.0 kB]
Get:4 http://security.debian.org/debian-security bullseye-security InRelease [48.4 kB]
Get:5 http://deb.debian.org/debian bullseye-backports/main Sources.diff/Index [63.3 kB]
Get:6 http://deb.debian.org/debian bullseye-backports/main Sources T-XXX.pdiff [637 B]
Get:6 http://deb.debian.org/debian bullseye-backports/main Sources T-XXX.pdiff [637 B]
Get:7 http://security.debian.org/debian-security bullseye-security/main Sources [152 kB]
Get:8 http://security.debian.org/debian-security bullseye-security/main amd64 Packages [183 kB]
Get:9 http://security.debian.org/debian-security bullseye-security/main Translation-en [115 kB]
Fetched 655 kB in 1s (696 kB/s)
Reading package lists... Done
root # apt-get upgrade
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Calculating upgrade... Done
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

Now we do the apt configuration.

root # wget https://maven.xwiki.org/xwiki-keyring.gpg 
-P /usr/share/keyrings/

--DATE-- https://maven.xwiki.org/xwiki-keyring.gpg
Resolving maven.xwiki.org (maven.xwiki.org)...
Connecting to maven.xwiki.org (maven.xwiki.org)|92.222.135.198|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1188 (1.2K)
Saving to: /usr/share/keyrings/xwiki-keyring.gpg
xwiki-keyring.gpg 100%[=====================>] 1.16K --.-KB/s in 0s
DATE (16.3 MB/s) - /usr/share/keyrings/xwiki-keyring.gpg
saved [1188/1188]
root # wget "https://maven.xwiki.org/stable/xwiki-stable.list"
-P /etc/apt/sources.list.d/

--DATE-- https://maven.xwiki.org/stable/xwiki-stable.list
Resolving maven.xwiki.org (maven.xwiki.org)...
Connecting to maven.xwiki.org (maven.xwiki.org)|92.222.135.198|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 85
Saving to: /etc/apt/sources.list.d/xwiki-stable.list.1
xwiki-stable.list.1 100%[=============>] 85 --.-KB/s in 0s
DATe (48.3 MB/s) - /etc/apt/sources.list.d/xwiki-stable.list.1
saved [85/85]
root # apt update -y
Hit:1 http://deb.debian.org/debian bullseye InRelease
Hit:2 http://deb.debian.org/debian bullseye-updates InRelease
Hit:3 http://deb.debian.org/debian bullseye-backports InRelease
Hit:4 http://security.debian.org/debian-security bullseye-security InRelease
Ign:5 http://maven.xwiki.org stable/ InRelease
Get:6 http://maven.xwiki.org stable/ Release [1,310 B]
Get:7 http://maven.xwiki.org stable/ Release.gpg [488 B]
Get:8 http://maven.xwiki.org stable/ Packages [410 kB]
Fetched 412 kB in 1s (340 kB/s)
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
All packages are up to date.
N: Ignoring file 'xwiki-stable.list.1' in directory '/etc/apt/sources.list.d/' as it has an invalid filename extension

After that we can see the xwiki packages as in the documentation. Let’s install the one with tomcat9 and mariadb. It’s very simple:

 

root # apt-get install xwiki-tomcat9-mariadb

...some more stuff here ...

Setting up tomcat9-common (9.0.43-2~deb11u3) ...
Setting up tomcat9 (9.0.43-2~deb11u3) ...
Creating group tomcat with gid 998.
Creating user tomcat (Apache Tomcat) with uid 998 and gid 998.
Creating config file /etc/tomcat9/tomcat-users.xml with new version
Creating config file /etc/tomcat9/web.xml with new version
Creating config file /etc/tomcat9/server.xml with new version
Creating config file /etc/tomcat9/logging.properties with new version
Creating config file /etc/tomcat9/context.xml with new version
Creating config file /etc/tomcat9/catalina.properties with new version
Creating config file /etc/tomcat9/jaspic-providers.xml with new version
Creating config file /etc/logrotate.d/tomcat9 with new version
Creating config file /etc/default/tomcat9 with new version
Created symlink /etc/systemd/system/multi-user.target.wants/tomcat9.service ? /lib/systemd/system/tomcat9.service.
Setting up xwiki-tomcat9-common (14.7) ...
Setting up xwiki-tomcat9-mariadb (14.7) ...
Processing triggers for libc-bin (2.31-13+deb11u4) ...
Processing triggers for rsyslog (8.2102.0-2+deb11u1) ...
Processing triggers for man-db (2.9.4-2) ...
Processing triggers for ca-certificates (20210119) ...
Updating certificates in /etc/ssl/certs...
0 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...

done.
done.

At one point before the done message this pops up:

Image source : here.

We have left the default option and provided a password. Now we go to the so called distribution wizard. You reach it on http://machine-name:8080/xwiki. Not obvious at all. Something like this (taken from the official documentation) should pop up.

WARNING: if you screw it up here it’s not easy at all to re-run the distribution wizard. Unistalling and installing the whole thing again didn’t work also, I somehow end up always screwing up the tomcat9 configuration without any hope… you definitely don’t want to mess up with the tomcat configuration 😩😩. Happy wiking, anyway.

The best joke in the world

There’s a Monty Python Flying Circus sketch about a killing joke. In the sketch, someone invents a joke so funny that people die laughing about it. Then of course they use it as a weapon.. but just watch the episode. This was very shocking for me when I was learning to speak other languages. Because humor is the most complex subject of a foreign language. A joke may involve accents to acknowledge, or local population, or famous characters from the region. It may use historical figures, or landmarks, you need to know to understand the basics, to avoid the painful explanation from the speaker. There’s fortunately a type of humor that doesn’t use any of that, and it runs on common grounds, like food, or features, or concepts. The Monty Pythons, although very English, were at the same time fond of this last humor mode. They were running on the preciousness of the absurdity. I always admired that freedom. Let me try my five cents of it here. There are two Germans in a bar. One says “Otto, Otto, do the olives have little legs?” and the other answers: “No, Hans, I’m afraid not.” The first one puts a sad face and comments: “Then I’m afraid I ate a cockroach.” Yeah I know. Sorry about it 😂.

Write and write and write

I was writing yesterday that in order to keep my mind sharp I wanted to release a couple of pages per day. The problem is about what to write. Once I got one of these dice games (story cubes) where you roll a dice to choose a subject, a person, and an object, just to tell a story around them. I played no more than five times with my kids, because, even having a string to connect them, it’s not easy to speak about something unless you have the right vocabulary, the right mood, and a good plot. And who’s brave enough to say he or she has a good plot? Every amateur when starting thinks he or she has the best ideas. That was also my case, until someone studying classics (Greek, Sumerian, and similar) told me after I first published a couple of tales in paper that the available number of plots was already calculated in ancient Rome, it is fixed, and its number is 52. OK, maybe it was not 52, but something like that. Who cares. I got the message. Originality may be overrated. We can do the math with the very story cubes that I’m mentioning above. 6 characters, by 6 objects, by 6 places. Barely two hundred. That if we don’t discard the bad rolls, so to say. Is everything already written also? Maybe, but is it written the best way possible, in any existing language? Definitely not. Like they say, you never appreciate Shakespeare until you read it in the original Klingon. And let that sentence be my piece of wisdom for the day 😉. Think about it.

Me & my dragons

Now that I do have time to write, I don’t know where to begin. I feel overwhelmed by everything, and the only reason I write here is because I know it’s going to help me release my dragons. I need my mind clear of them, then maybe I can focus. I wonder if I need some kind of mental gym, nothing like those stupid apps to give you a mark depending on how fast you solve your sudoku. More like write two pages in this language or the other, even if you feel like you have nothing to say. Or, memorise this list of chemical components before tomorrow. Or, calculate the energy levels of this atomic interaction. Easy tasks. I’ve tried like everyone else, that is, doom scrolling or gaming, but it doesn’t seem to work. My mind is not clearer. There’s this whirlpool in the middle of my mental landscape, guarded by winged creatures. The dragons fly away from time to time, but when I look, another one has taken its place. And I can’t go beyond that vortex. And I know that what I need is right there, after it. But I don’t want to jump in it, I’m simply, not ready for it.

An Ansible Semaphore docker : run ansible with a GUI

Image taken from the website.

I’ve been posting about ansible for a while. You should know what you can do with it already. By defining tasks and an inventory, you can decide what to install, how and where. These recipees can be files on a folder or they could be nicely organized on a website. The Ansible Semaphore is a website that is letting you do it, at least, the physical install lets. I’ve tried the docker install, that is going to let you play with it but it comes with the corresponding isolation issues. Here you have the github page. Step by step, what I did on a CentOS client with dockers. First I create a folder for the project (semaphore) and docker-compose.yml as in the documentation. Then it’s very simple. Inside the folder, type

docker-compose up

That’s it. Go to https://localhost:3000 and enjoy your semaphore. Unfortunately it’s empty and we don’t have any ssh key, user, etc. But that’s not the important thing, right? The important thing is that all the functionalities are there. And that it’s modern, and mobile-phone friendly 😉. Anyway. Here’s the guide about how to install semaphore for real. And if you don’t like the GUI, you can also try the AWX GUI. A separate article may come 😏.

HOWTO: install docker on debian 11

I’m a CentOS user, but it’s good to be open-minded. The debian systems are not managed in the same way than CentOS, so it’s not a stupid question if the installation instructions work out of the box. I will follow the official documentation for debian. I have root access to the machine, so no sudo needed. Let’s see:

> apt-get remove docker docker-engine docker.io containerd runc
> apt-get install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release
> mkdir -p /etc/apt/keyrings
> curl -fsSL https://download.docker.com/linux/debian/gpg \
| gpg --dearmor -o /etc/apt/keyrings/docker.gpg
> echo \
  "deb [arch=$(dpkg --print-architecture) \
signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/debian $(lsb_release -cs) stable" \
| tee /etc/apt/sources.list.d/docker.list > /dev/null
> apt-get update
> apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin

After the above lines “docker run hello-world” works. This exercise was indeed mildly boring 😩. Or could it be I’m running on the wrong distro? 🧐