Web Chart and Graph tools: Zing and CanvasJS

annual-sales-dashboardCoding is scary. So the more code I can steal, the less scared I feel. Unfortunately we need web plots, the more beautiful, the better. I wrote already quite some posts about data management, so you know all of this is about handling data. Sometimes from a database, sometimes from command line results. If you have a database, I heard that Zing seems to be the weapon of choice. Here you have a working example of loading MySQL data to create charts. Unfortunately Zing is, as you will read later, not my choice.

Since we speak about MySql, it may be interesting for debugging purposes to graph data from mysql database in python. On the previous link, you have a step-by-step tutorial that includes from the initial health checks over mysql to embedding the python plotly result on a web as an iframe. The results look very professional, but if you ask me, it’s a killer for my already structured data. What is structured data? For me, something like username:value, date:value or parameter:value, on a list, recorded or available as standard output. Something I can grep. It can be CSV, it can be separated by a space.

For that kind of data, my choice is CanvasJs, from where I took the above picture. It uses javascript to plot my values, and it has a lot of easy examples (cut-and-copy) of angular and bar charts, react charts with zooming and similar, and very practical dynamic charts. Play with it, since it’s for free. What I did with it is I created a chart from CSV with CanvasJS to test my data, then render multiple charts in a web page. That page can be html, or php code to read your csv. The choice is yours 🙂



Slurm 18.08 with QOS mariadb problems on CentOS 7

I already told you how to install Slurm on CentOS 7 so I’m not going to repeat it for a  modern slurm package. I’m going to comment on the new issues I had using the procedure. Problem one: making rpms.

rpmbuild -ta slurm-15.08.9.tar.bz2

This I solved by using a variation of this solution. I just did it as root.

yum install 'perl(ExtUtils::Embed)' 'rubygem(minitest)'

You could also configure, make and make install the source code. Once done, I run a script to copy my slurm rpms or my slurm source code to the local machine, clean up the previous installation (deleting the packages and the munge and slurm users and folders) and install everything (munge + slurm).

Problem two: the slurm database configuration. I’m going to start from a working installation of 18.08. That means you can submit jobs, they run and so on. First time I did a modification on it I screwed up the queuing system: all jobs got stucked with status CG. The solution to stucked CG jobs is scancel followed by.

scontrol update NodeName=$node State=down Reason=hung_proc
scontrol update NodeName=$node State=resume

Of course it is normal to commit mistakes if you play around. On Sloppy Linux Notes they have a very short guide about how to install a mariadb with slurm. Please try out the above method before go on reading, this one is a sad story 😦

So I had it already installed on my database client, but I was not using it. Instead of removing all the little bits and pieces, I tried to reset the mariadb root password. Note that you may want to recover the mysqld password instead. In any case, this is the error:

root@node ~ ## > mysql -u root -p
Enter password: 
ERROR 1045 (28000): Access denied for user 'root'@'localhost' 
(using password: YES)

Even with the right password. Depending on your install, skip grant tables may work, in my case, I get this

MariaDB [(none)]> ALTER USER 'root'@'localhost' 
ERROR 1064 (42000): You have an error in your SQL syntax; 
check the manual that corresponds to your MariaDB server version 
for the right syntax to use near 'USER 'root'@'localhost' 

I check the documentation as suggested, but I still don’t manage. Even some potsts about the problem on a mac. I tried generating a password hash…but without luck. This works:

MariaDB [(none)]> SET PASSWORD FOR 'root'@'localhost' 
= PASSWORD('NewPass'); 
Query OK, 0 rows affected (0.00 sec)

But I can’t login as root after flushing the privileges and removing the skip-grant-tables from my.cnf. On the DigitalOcean they advice to alter user also, but instead of modifying the my.cnf, they suggest to start the database skipping the grant tables

mysqld_safe --skip-grant-tables --skip-networking &

My mariadb version is 5.5

root@node > rpm -qa | grep mariadb 


MariaDB[(none)]> SET PASSWORD FOR 'root'@'localhost' 
= PASSWORD('NewPass');

Now I can log in as root with my new password. What’s next? Yes, we need to setup the mariadb slurm user and the slurm tables.

MariaDB [(none)]> CREATE USER 'slurm'@'node' 
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> create database slurm_acct_db;
Query OK, 1 row affected (0.00 sec)
`slurm_acct_db`.* TO 'slurm'@'node' with grant option;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> grant all on slurm_acct_db.* TO 'slurm'@'node'
-> identified by 'SLURMPW' with grant option;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)

Here you have how to add a user to mariadb with all privileges in case you need more info. And the documentation on GRANT. And all in a nutshell with a script. If you have problems with the database (for example it is corrupted)

root@node> more /var/log/mariadb/mariadb.log
XXX [ERROR] Native table 'performance_schema'.'rwlock_instances' 
has the wrong structure

you may want to DROP it or rebuild all the databases.

root@node ~ ## > mysql_upgrade -uroot -p --force
Enter password: 
MySQL upgrade detected
Phase 1/4: Fixing views from mysql
Phase 2/4: Fixing table and database names
Phase 3/4: Checking and upgrading tables
Processing databases

After such an action, it may be interesting to get a list of mariadb users and rights.  Or show your grants:

MariaDB [(none)]> show grants

But let’s don’t look back and go ahead. If after all this troubles you didn’t give up and you have a mariadb running, it’s time to configure the slurmdbd daemon. Our slurmdbd.conf should look like this:


We can start the daemon now…and here comes the section for slurmdbd errors.

Error:  ConditionPathExists=/etc/slurm/slurmdbd.conf was not met
Solution: Check the file exist, has that name and it is accessible by ‘node’.

Error:  This host (‘node’) is not a valid controller
Solution: Check your slurm.conf, where it is defined the controller in ‘ControlMachine’

Error:  mysql_real_connect failed: 2003 Can’t connect to MySQL server on ‘node’
Solution: Check StorageHost=XXX on your slurmdbd.conf. and AccountingStorageHost=XXX on slurm.conf Change it for an IP instead of name.

Error:  mysql_real_connect failed: 1045 Access denied for user ‘slurm’@’node’ (using password: YES)
Solution: Check that you can log in as ‘slurm’ with SLURMPW on myslq. If not, you need to create a user that is able to do that.

Error:  Couldn’t load specified plugin name for accounting_storage/mysql: Plugin init() callback failed
Solution: Check that your mariadb is up and running. Check that you have the accounting_storage.so. You may need to recompile everything…

Error:  It looks like the storage has gone away trying to reconnect
Solution: Check that the cluster is seen by the accounting system. If not, you need to add it using an account manager command

root@node ## > sacctmgr add cluster MYCLUSTER

We need to set QOS also. To do so, maybe we need to use the consumable resource allocation plugin select/cons_res, that is to say, tell slurm to manage the CPUs, RAM, and GPUs.  Add to your slurm.conf something like this:


There are a lot of examples of the slurm documentation on cons_res. Be aware that there is cons_res bug on hardened systems if you compile slurm hardening. Let’s define some QOS as in the documentation.

sacctmgr add qos zebra

And see how they look like:

sacctmgr show qos format=name,priority
Name       Priority 
---------- ---------- 
normal     0 
zebra      0 
elephant   0

Now everything should be fine. We check:

root@node ## > slurmctld -Dvvv

If you need it, here you have the QOS at the biocluster. And the official documentation on slurm accounting. And I’m pretty tired of fixing things, distributing files, and look at logs. I hope you didn’t need it at all. At the end, just to finish this collection of troubles, the slurm problems page from SCSC. Happy slurming…

Install Python 3 on OSX for data science

While I edit as a book The Water Wedding I keep working, of course. This is also my log. I’m following this instructions to build up a proper environment on my mac to test some data science tools. First, I open a terminal and I check my python version.

mymac:~ user$ which python
mymac:~ user$ python --version
Python 2.7.10
mymac:~ user$ python3
-bash: python3: command not found
mymac:~ user$  xcode-select --install

This opens up the Apple store and starts installing xcode. It takes some time. But it was expected. The next one is brew. This is my output:

mymac:~user$ /usr/bin/ruby -e 
"$(curl -fsSL https://raw.githubusercontent.com/
==> This script will install:
==> The following existing directories will be made group writable:
==> The following existing directories will have their owner 
set to user:
==> The following existing directories 
will have their group set to admin:
==> The following new directories will be created:
Press RETURN to continue or any other key to abort
==> Installation successful!
==> Homebrew has enabled anonymous aggregate formulae 
and cask analytics.
Read the analytics documentation (and how to opt-out) here:
==> Homebrew is run entirely by unpaid volunteers. 
  Please consider donating:
==> Next steps:
- Run `brew help` to get started
- Further documentation: 

So far so good. Let’s test it.

mymac:~ user$ brew doctor
Error: You have not agreed to the Xcode license. 
Please resolve this by running:
  sudo xcodebuild -license accept
mymac:~ user$  xcodebuild -license accept
Agreeing to the Xcode/iOS license requires admin privileges, 
please run “sudo xcodebuild -license” and then retry this command.
mymac:~ user$ sudo xcodebuild -license accept

Another test.

mymac:~ user$ brew doctor
Your system is ready to brew.

We brew python3 now. Output also written as a reference. Colours are mine.

mymac:~ user$ brew install python3
==> Installing dependencies for python: 
gdbm, openssl, readline, sqlite and xz
==> Installing python dependency: gdbm
==> Downloading https://XXXbottle.1
################################################## 100.0%
==> Pouring gdbm-1.18.1.mojave.bottle.1.tar.gz
🍺  /usr/local/Cellar/gdbm/1.18.1: 20 files, 586.8KB
==> Installing python dependency: openssl
==> Downloading https://homebrewXXX.mojave.bottl
################################################## 100.0%
==> Pouring openssl-1.0.2q.mojave.bottle.tar.gz
==> Caveats
A CA file has been bootstrapped using certificates from 
the SystemRoots keychain. To add additional certificates 
(e.g. the certificates added in the System keychain), 
place .pem files in
and run
openssl is keg-only, which means it was not symlinked 
into /usr/local, because Apple has deprecated use of 
OpenSSL in favor of its own TLS and crypto libraries.
If you need to have openssl first in your PATH run:
  echo 'export PATH="/usr/local/opt/openssl/bin:$PATH"' 
>> ~/.bash_profile
For compilers to find openssl you may need to set:
  export LDFLAGS="-L/usr/local/opt/openssl/lib"
  export CPPFLAGS="-I/usr/local/opt/openssl/include"
==> Summary
🍺  /usr/local/Cellar/openssl/1.0.2q: 1,794 files, 12.1MB
==> Installing python dependency: readline
...some stuff here...
==> Summary
🍺  /usr/local/Cellar/readline/8.0.0: 48 files, 1.5MB
==> Installing python dependency: sqlite
...some stuff here...
==> Summary
🍺  /usr/local/Cellar/sqlite/3.27.1: 11 files, 3.7MB
==> Installing python dependency: xz
...some stuff here...
==> Pouring xz-5.2.4.mojave.bottle.tar.gz
🍺  /usr/local/Cellar/xz/5.2.4: 92 files, 1MB
==> Installing python
...some stuff here...
==> Caveats
Python has been installed as
Unversioned symlinks `python`, `python-config`, `pip` etc. 
pointing to `python3`, `python3-config`, `pip3` etc., 
respectively, have been installed into
If you need Homebrew's Python 2.7 run
  brew install python@2
You can install Python packages with
  pip3 install <package>
They will install into the site-package directory
See: https://docs.brew.sh/Homebrew-and-Python
==> Summary
🍺  /usr/local/Cellar/python/3.7.2_2: 3,861 files, 59.7MB
mymac:~ user$ python3 --version
Python 3.7.2

The same that goes on for openssl (the keychain problem and the export PATH problem) appears for readline, sqlite, and xz. I have edited the output so it’s not enormous. Now we install conda with pip3.

mymac:~ user$ pip3 install conda

Installing collected packages: pycosat, certifi, 
idna, urllib3, chardet, requests, ruamel.yaml, conda

Successfully installed certifi-2018.11.29 chardet-3.0.4 
conda-4.3.16 idna-2.8 pycosat-0.6.3 requests-2.21.0 
ruamel.yaml-0.15.88 urllib3-1.24.1

And finally, the data science packages. This way:

pip3 install numpy pandas scikit-learn matplotlib seaborn jupyter

It takes some time but we are ready to continue with the tutorial of the Python DataScience Handbook. We’ll see where we hit another stone…

mysqld recover root password on CentOS 7

The disaster scenario is that you have been installing third party software and its scripts somehow screwed up your mysql (users, tables, whatever). Or it could be that you get a server with mysqld already installed but you don’t know the root password. (Can such a thing happen? Of course in research everything is possible!) This solution from stack overflow worked for me.

1. Stop mysql:
systemctl stop mysqld

2. Set the mySQL environment option 
systemctl set-environment MYSQLD_OPTS="--skip-grant-tables"

3. Start mysql usig the environment option
systemctl start mysqld

4. Login as root
mysql -u root

5. Update the root user password

mysql> UPDATE mysql.user SET authentication_string =
PASSWORD('MyNewPass') WHERE User = 'root' AND Host = 'localhost';
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'MyNewPass';

6. Stop mysql
systemctl stop mysqld

7. Unset the mySQL environment option
systemctl unset-environment MYSQLD_OPTS

8. Start mysql normally:
systemctl start mysqld

9. Login using your new password:
mysql -u root -p

It could be the system still complains about the password. You can try to change the password policies as written here on another StackOverflow post. Now I need to fix phpMyAdmin, but maybe that story I will tell another day 😛

phpMyAdmin migrate database

I’m making dockers for all my web applications. And most of my web applications are hooked up with databases. And where you have a database, you have phpMyAdmin. Anyway. I have this computer A with a very extensive database that I want to have now on a docker. The docker I will call B. What we do to have the database of A in B is to dump it first.

root@A ~ ## > mysqldump -u root -p --all-databases > alldb.sql

I assume we can ssh into the docker B, and scp or transfer files to it from another location. So now we simply load the database in the docker.

[root@B ~]# mysql -u root -p < alldb.sql

That’s it. My calendars, my web, all is in B as in A. But B is a docker 🙂

A leginon docker on CentOS 7 Part II: centos7AutoInstallation.py

selinuxinstallOn the previous post, we prepared a basic LAMP docker to hold a leginon installation.  I assume now you downloaded the installer for CentOS 7 and copied it to the docker via ssh or shared folder. We can simply run it. At the beginning it looks like this:

[root@dleginon]# python centos7AutoInstallation.py 
Current OS Information: CentOS Linux release 7.3.1611 (Core)
"root" access checked success...
Installing job submission server
Installing processing server
Installing database server
Installing web server

I choose “no” on would you like to install EMAN, Xmipp, and all the processing software. We don’t want to process in the docker. Note that the auto installer seems to try to install the database server and configure it, but we already did it. Unfortunately even being careful with the options, the installer fails with multiple errors. Additional work is needed. I created a wrap over the original installer, then customize the installer so that it doesn’t throw us errors. This is my wrap:

echo " Changing phpMyAdmin to password-protected, cookie-based "
\cp config.inc.php.phpMyAdmin.docker /etc/phpMyAdmin/config.inc.php
echo " Please setup NOW the MYSQL root password"
mysqladmin -u root password
echo " Please test login on the phpMyAdmin web interface"
echo " Setting up my.cnf limits" 
\cp my.cnf.docker /etc/my.cnf 
echo " Installing missing packages. This may take some time "
yum -y install nedit gedit net-tools torque-client torque-mom \
ImageMagick MySQL-python compat-gcc-34-g77 fftw3-devel \
gcc-c++ gcc-gfortran gcc-objc gnuplot grace gsl-devel \
libtiff-devel netpbm-progs numpy openmpi-devel opencv-python \
python-devel python-imaging python-matplotlib python-tools \
python-pip scipy wxPython xorg-x11-server-Xvfb libjpeg-devel \
### to have openmpi temporary and permanently available
echo "export PATH=\$PATH:/usr/lib64/openmpi/bin" \
>> /root/.bash_profile
export PATH=$PATH:/usr/lib64/openmpi/bin
echo " ..packages installed"
### database configuration
php -f leginon-db-config.php
echo " Intial configuration done. "
echo " Starting the autoinstaller..."
python centos7AutoInstallationCustom.py
echo " Autoinstaller done. "
cp config.php.myamiweb.docker /var/www/html/myamiweb/config.php
chmod 777 /var/www/html/myamiweb
chmod 777 /var/www/html/myamiweb/config.php

As you see, we copy two template files, my.cnf.docker and config.php.myamiweb.docker. The first one is simply the one we edited on the first part of this post. The second one is not so important, since it will be overwritten after the first run of the Web Tools Setup Wizard, pictured above. Basically, just change the host name and login type.

We need to have a look to the php file also. It’s just doing what you’re asked to do for the Database Server Installation. Let’s say your docker is called “dleginon“. My php file is like this:

 $connection = mysql_connect( "", "root", "docker" ) 
 or die( "Sorry - unable to connect to MySQL" );
 echo( " Congratulations - you are connected to MySQL \n" );
 echo( " Creating initial databases and users \n" );

mysql_query("CREATE DATABASE leginondb");
mysql_query("CREATE DATABASE projectdb");

mysql_query("CREATE USER 'usr_object'@'localhost' \
mysql_query("GRANT ALL PRIVILEGES ON leginondb.* TO \
mysql_query("GRANT ALL PRIVILEGES ON projectdb.* TO \

mysql_query("GRANT ALL ON leginondb.* TO \
mysql_query("GRANT ALL ON projectdb.* TO \
DELETE ON ON `ap%`.* TO 'user_object'@'localhost'");
mysql_query("GRANT ALL PRIVILEGES ON *.* TO \
mysql_query("CREATE USER 'usr_object'@'%' \
mysql_query("GRANT ALL PRIVILEGES ON leginondb.* TO \
mysql_query("GRANT ALL PRIVILEGES ON projectdb.* TO \

mysql_query("GRANT ALL ON leginondb.* TO 'user_object'@'%'");
mysql_query("GRANT ALL ON projectdb.* TO 'user_object'@'%'");
DELETE ON ON `ap%`.* TO 'user_object'@'%'");
mysql_query("GRANT ALL PRIVILEGES ON *.* TO 'usr_object'@'%'");

 echo( " ...done \n" );


The user “usr_object” is having the password “DOCKERLEGINON“, while the root docker is having the password “docker“. Be aware that inconsistency on root and  usr_object users on the database will lead to errors. Now what is centos7AutoInstallationCustom? I will not post it here (it’s too long) but basically it’s the auto installer you downloaded minus the system calls and minus the last lines that are opening the browser. I will not post it here, just modify it yourself.

Now we need to run the Web Tools Setup Wizard.  If your docker is called dleginon, open your browser pointing to http://dleginon/myamiweb/setup/ and use Database User: usr_object, Database password: DOCKERLEGINON. It is recommended to restart the docker first, in case you didn’t do it. Once you’re done, you should be able to log in as Administrator onto the myamiweb.

Are we ready to go? Not yet. If you ssh into the container to run start-leginon.py, you will get the next error:

(1045, "Access denied for user 'root'@'localhost' 
(using password: NO)")

This is due to an unconfigured /etc/myami/sinedon.cfg. Edit the file, and change the username and password so that start-leginon can access the database. If you run it afterwards, you will get this error:

RuntimeError: Must create at least one project 
before starting Leginon

To get rid of this one, go to myamiweb, and create a test project. Then run start-leginon.py again. Now it should work, and if not, let me know 🙂

A docker macvlan on CentOS 7

I want to dockerize my services (not only leginon) so I need to find out an effective way to integrate them onto our intranet. That is proven to be a little bit complex, since I have partial control of our intranet. Here I explain how to create a secure docker network, where each docker can see the other, but they can’t see outside world.

First we need to stop the docker service, and edit the daemon.json docker configuration file on /etc/docker. In my case, it is empty. We fill it with a bip and fixed cidr. Then we need to successfully restart the docker daemon. Here you have a complete example of a docker bridge file definition.

  "bip": "",
  "fixed-cidr": "",
  "fixed-cidr-v6": "2001:db8::/64",
  "mtu": 1500,
  "default-gateway": "",
  "default-gateway-v6": "2001:db8:abcd::89",
  "dns": ["",""]

I used  only the parameters needed. If your bip or fixed-cidr are wrong, the docker daemon will not start. Now I create my docker network mynet with a command I took from the docker overlay documentation.

docker network create -d macvlan \
--subnet=MY.SUBNET.IS.0/24 \
--ip-range=MY.SUBNET.IS.1/24 \
--gateway MY.SUBNET.IS.1 \
-o parent=vlan-TEST mynet

The output should be the typical string of letters and numbers. If your parameters are wrong, you can get this meaningless errors instead:

Error response from daemon: 
Pool overlaps with other one on this address space


no matching subnet for gateway MY.SUBNET.IS.1

Just try until it works. We create two dummy containers (I will let you choose the names, mines are leginon1 and leginon2) and we check their isolated IPs:

docker network inspect mynet | grep -i ipv4

Note that the alias that is giving us the IP of the docker will not work because they are isolated. Also I didn’t find something similar for network inspect, so grep it is. If you want to see all the info from the JSON file, just remove the grep part. Let’s log in each one and ping the other from the other like this:

shell1 > docker exec -i -t leginon1 /bin/bash
shell2 > docker exec -i -t leginon2 /bin/bash

There you have it! Isolated containers communicating with each other.
I quote from here: Linux Macvlan interface types are not able to ping or communicate with the default namespace IP address. For example, if you create a container and try to ping the Docker host’s eth0 it will not work. That traffic is explicitly filtered by the kernel to offer additional provider isolation and security. That means also that an alias that can give us the IP of the docker will not to work.

So don’t do this if you want to have dockers available from other machines different from the one running the docker daemon. But if you did, maybe now you want to remove the traces. It’s very simple.

  1. Stop the daemon  # > systemctl stop docker
  2. Remove the network information, by editing the daemon.json file to an empty state (just the two brackets)
  3. Delete the docker and the bridge using ip link del as explained here.
  4. Start the daemon

And now, back to the drawing board 😦