Solution to MobaXterm X11 proxy: Authorisation not recognised

While using remote SSH client MobaXTerm to open up X-11 forwarded GUI app with root privileges, an error message pops up:

MobaXterm X11 proxy: Authorisation not recognised


The GUI app actual crashed with this error and not showing up on client desktop. Here's the solution:

From your MobaXTerm SSH client console after login:

$
$ sudo xauth add $(xauth -f /home/[USER]/.Xauthority list|tail -1)
$


According to mobatek's blog,

We receive a lot of emails asking how to keep X11-forwarding working after changing user to root inside a SSH session in MobaXterm. This is by default not allowed on Unix/Linux systems, because the X11 display connection belongs to the user you used to log with when connecting to your remote SSH server. X11-forwarding mechanism does not allow anyone to use the open display.
However, in some cases you may need to start a graphical application like nedit or firefox in a sudo or su context. In order to achieve this, you could manually retrieve X credentials in the su/sudo context by looking up the “xauth list” for the original username and then adding them using “xauth add” to the current context.
You can also use a single (magic) command in order to achieve this!
The single line of command helps solving problems whenever you need to have a working X11 display through SSH after becoming root.

Update:

The aforementioned method would not survive another SSH login as MIT-MAGIC-COOKIE always changes during user login. The cookie previously copied to ROOT account will become obsolete.

To permanently resolve this, we need root privilege to ADD the following statement to the end of the file /etc/sudoers:

#
Defaults env_keep += "XAUTHORITY"
#

This is enough to allow sudo opening Xorg program. Also, env_keep actually points to environment variable "XAUTHORITY" which is the location of .Xauthority. So you may add the following EXPORT statement to ~/.bashrc or set it globally in the file /etc/environment (CentOS 7)

#
EXPORT XAUTHORITY=/home/[YOUR_USERNAME]/.Xauthority
#

This method ensure that remote sudo opening works even after next SSH login or SSH server reboot.




CentOS: Remote SSH libGL error: failed to load swrast driver

While I was trying to load up some GUI apps from remote SSH server with X11 forwarding and the error pops up:

libGL error: failed to load driver: swrast

To debug it, try the following command:

$ LIBGL_DEBUG=verbose glxinfo | grep renderer


Clearly, this is an openGL issue over SSH remote client. After searching many posts around on the forums, there is one promising solution found here.

Simply export an variable in SSH terminal solves the issue:

$ export LIBGL_ALWAYS_INDIRECT=1



Python: Custom global fonts for Matplotlib without installation

To use custom TTF font on our own, there are similar posts up on the forums. However, none of them works for my case except this one.

Here's the highlight:


  • Dynamically add custom font to current Python script outside of default system font folder, especially on Linux
  • No big changes to the rest of Python source about adding fontsproperties *kwargs to each text/label statement


Here's example:

        # Set global font style
        mpl = matplotlib
        fm = matplotlib.font_manager
        basedir = os.path.join(os.path.dirname(__file__), 'static', 'fonts')
        fpath = os.path.join(basedir,'times.ttf')
        prop = fm.FontProperties(fname=fpath)

        font_files = fm.findSystemFonts(fontpaths=basedir)
        font_list = fm.createFontList(font_files)
        fm.fontManager.ttflist.extend(font_list)

        logging.debug('Register font family: %s' % (prop.get_name()))
        mpl.rcParams['font.family'] = prop.get_name()
        mpl.rcParams.update({'font.size': '10'})
        
        plt.switch_backend('agg')

This code snippet assigns the basedir with current Python script's location as reference and sub-folder structure like:

[current_folder]/static/fonts/

The best of this is to create custom font list and extend it to current font manager's TTF List. It means it will apply the custom font to existing font family within current Python script as a whole. No more hassle to things to any other statements and it works like the default font.

This example uses Times New Roman TTF font. You can use whatever TTF font you like.





Compiling custom version of PHP on CentOS 7 with non-root privilegs

I was trying to test a PHP webapp up on commodity server. Some PHP extensions are not in place while Apache's config files are out of touch due to non-root user privilege.

After a couple of google searches, the closest thing would be how to custom compile PHP engine on web hosting server which fits the scenario of non-root user installation.

First, check out the git source from here:
https://github.com/php/php-src

So far I have been on PHP v7.2.11 and the outcome is satisfied after source compiling.

Second, choose and create a destination directory for new PHP implementation which can be something like:
/home/user/local

Third, steps to compile:

$
$ cd {PHP source directory}
$ make clean
$ ./configure \
  --prefix=/home/user/local \
  --enable-calendar \
  --enable-pcntl \
  --enable-shmop \
  --enable-sockets \
  --enable-mbstring \
  --enable-bcmath \
  --with-gd \
  --with-curl \
  --with-openssl \
  --with-xmlrpc \
  --enable-soap \
  --enable-zip \
  --enable-opcache \
  --with-gd \
  --with-jpeg-dir \
  --with-png-dir \
  --with-mysqli \
  --enable-pcntl \
  --with-pdo-mysql \
  --with-pdo-sqlite \
  --with-pgsql \
  --with-freetype-dir \
  --enable-intl \
  --with-xsl \
  --with-zlib \
  --enable-simplexml \
  --with-sqlite3 \
  --enable-xmlreader \
  --enable-xmlwriter \
  --with-gettext \
  --with-gdbm
$ make
$ make install


Once done, the files will be placed in the directory specified by the flag --prefix.

Please note that a specific PHP target directory is set according to destination directory, i.e., /home/user/local for installation which prevents overwriting default/previous PHP implementation even under non-root privileges.

For fcgid implementation, the following files should be created within the parent directory of targeted PHP app where index.php noramlly stays:

This .htaccess target the wiki webapp whereas first 3 lines may be omitted.

############################ File ".htaccess" (permission:755) ###########################################
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule (api|load)\.php - [L]

Options +Indexes +FollowSymLinks +ExecCGI
AddHandler php-fastcgi72 .php
Action php-fastcgi72 {php_webapp_directory}/php7.fcgi

# DISABLE CACHING

 Header set Cache-Control "no-cache, no-store, must-revalidate"
 Header set Pragma "no-cache"
 Header set Expires 0

############################ End of File ".htaccess"  ###########################################


File "php7.fcgi" must be assigned an execute permission to Apache user/group.
############################ File "php7.fcgi" (permission:775)###########################################
#!/bin/bash

export PHP_INI_SCAN_DIR="/home/user/local/lib/php.d"
export PHP_FCGI_CHILDREN=4
export PHP_FCGI_MAX_REQUESTS=10000
exec /home/user/local/bin/php-cgi -c /home/user/local/lib
############################ End of File "php7.fcgi" ###########################################

I was having trouble to enable opcache for PHP in FCGI mode. However, enabling opcache may not be a good idea for PHP script running in CGI mode (please read here: https://ma.ttias.be/how-to-clear-php-opcache/). Anyway, it's up to your own desire to try improving PHP's performance.






Integrating Dash and Flask with DispatcherMiddleware

The perfect situation is that the existing Flask app in Python is playing nicely while new project using Plotly Dash would like to join in. It's absolutely possible to make use of Dash's built-in Flask infrastructure to run its own server. Nonetheless, my situation is that an existing Flask app is here-to-stay and I don't want to give it a big change.

So the question is: what if we want to run both apps in parallel?

Package werkzeug.wsgi provides DispatcherMiddleware class to let multiple apps running concurrently under a parent app. All things work at Flask's middleware level and it basically shares the same port to the children apps.

Here's the code snippet:
# Assuming Flask object "app" is created for the original app
#

import dash
from werkzeug.wsgi import DispatcherMiddleware
from werkzeug.serving import run_simple
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output

app = Flask(__name__)
# Assuming source code for original Flask "app" is already in place
# ...

dash_app = dash.Dash(__name__)
dash_app.config.supress_callback_exceptions = True
dash_app.css.config.serve_locally = True
dash_app.scripts.config.serve_locally = True
dash_app.config.update({
    'routes_pathname_prefix':'/app2/',
    'requests_pathname_prefix': '/app2/'
})
dash_app.layout = html.Div([html.H1('Hello world')])

# Wrapping original "app" with DispatcherMiddleware
app.wsgi_app = DispatcherMiddleware(app.wsgi_app, {'/app2': dash_app.server})

# Entry point
if __name__ == '__main__':
    run_simple('0.0.0.0', 80, app, use_debugger=True, use_reloader=True, threaded=True)


To link up both apps, we need to make sure "app.wsgi_app" and "dash_app.server" are called correctly within DispatcherMiddleware.

Also, run_simple() method plays an important role here to ease the pain of complicated configurations and avoid unnecessary error messages. You might not want to use app.run() again after all.

The beauty is that the original Flask app remains the same while app2 or even app3 can load in for testing, of course, under the same hostname and port number.

Let's imagine the URLs can be accessed like these:

# Original Flask app
http://localhost

# app2 using Dash
http://localhost/app2/

# app3 and so on...
http://localhost/app3/


Custom build Tensorflow to support Intel CPU specific instruction set on CentOS 6

Custom build Tensorflow is getting popular as developers have started to push their hardware limit to extreme over the standard build which has no acceleration feature enabled on commodity machines (generally without a decent GPU with compute capability over 3.0).

Different machines have different hardware specifications but most likely the commodity servers have a high chance to equip with powerful multi-core Intel CPU which can go down to the pathway of compiled build against Intel MKL library, e.g. a boost to the deep learning performance via CPU.

CentOS 6.9 comes with older version of GCC compiler which is not helpful in compiling recent version of Tensorflow. So, first thing to do is installing newer version of GCC compiler:

$ yum install 
"http://ftp.scientificlinux.org/linux/scientific/6x/external_products/softwarecollections/yum-conf-softwarecollections-2.0-1.el6.noarch.rpm"
$ yum install devtoolset-6

Here's how Tensorflow CPU version is compiled on CentOS 6.9 platform:

Assuming we are working in CONDA environment:

$ conda activate $CONDA_ENVIRNMENT_NAME
$ scl enable devtoolset-6 bash
$ cd tensorflow
$ bazel build --linkopt=-lrt --config=mkl --copt="-DEIGEN_USE_VML" -c opt //tensorflow/tools/pip_package:build_pip_package
$ bazel-bin/tensorflow/tools/pip_package/build_pip_package ../tensorflow_pkg
$ pip install --upgrade --user ../tensorflow_pkg/<wheel_name.whl>


Funny thing is that Intel has similar instruction which actually recommend installing Tensorflow via CONDA command:

$ conda install tensorflow-mkl

They claimed that warning message like:
Warning: “The TensorFlow library was not compiled to use **** instructions, but these are available on your machine and could speed up CPU computations.”
is actually not harmful at all. As we are installing things along with MKL-DNN library. This warning can be ignored since Intel MKL-DNN library with which the TensorFlow is compiled utilizes the latest Instruction sets available in your processor to perform compute-intensive operations.

It's up to you to trying either easy or hard way to set things up. The performance may not vary too much after all.


Deep Learning: It's about information bottleneck

A theory comes out to demystify Deep Learning. This seems to explain how Deep Learning works behind the scene. The graph shows the progress of how a deep neural network evolves during various stages.

Ref: https://www.quantamagazine.org/new-theory-cracks-open-the-black-box-of-deep-learning-20170921/

apt install through corporate proxy

Assuming proxy service like CNTLM is up and running on Ubuntu machine, one can use apt-get to install package with specifying http proxy inf...