Pegasus Workflow Management System + VMware Fusion

If you want to start your experience with Pegasus Workflow Management System I strongly advice to use ready to go Virtual Machine available for download. You can get it here.


After downloading it, open VMware Fusion and choose: File -> Import… and choose PegasusTutorialVM-4.7.4.ova (you can find it wherever you have stored it – probably inside Downloads). After choosing the file, you will see something like this

Press Continue. VMware Fusion will complain!

Don’t worry, it will import machine properly, eventually. Simply press Retry. After a while, you will be notified that import was finished.

Fusion may complain about upgrading machine to reflect most recent changes in your release. Feel free to upgrade your machine. Press: Upgrade.

After a while, you will be shown a clock on nice blue background. Just drag it and scroll up. Now, you are ready to log in into machine. Chose user tutorial and type in pegasus as password.

On the left side of screen you will find Terminal application. Double click it. Now, it is the time to start your first task. Go ahead and create your first task.

Do not give up. Fight till the end.

I was supposed to say

This is the end
Beautiful friend
This is the end
My only friend, the end
— The Doors, The End

after seeing this beautiful picture during startup.

As you may guess, it was gone. Everything was gone. Apart from data: “- Thank you! My dear Backup System, thank you. I owe you! Again!”

Anyway. I was 100% sure it was broken GPU. At least that’s what all the Internet was saying. However, I wanted to check my system once again. Just to be sure. All I had to do was pressing


while starting up. I have performed full test (it lasted for more than few hours) and then … it worked. My system started as usual. Of course I had to recover from data loss, but that’s just a minor issue ;)

Java, Python and IO inheritance

If you remember old way of reading/writing streams between JVM and external process, you probably remember how tedious it was in the past (all these Gobblers, Threads, etc.). Today, it’s way more simple. All you have to do, is inheriting JVM’s IO.

Let’s say you want to run simple Python code that reads something from input stream.

value = raw_input("Type the number? ")
print "Your number is: " + value

all you have to do is to call it from ProcessBuilder and inherit the IO.

public class PythonProcess {
  public static void main(String [] arg) throws Exception {
    ProcessBuilder pb =
      new ProcessBuilder("python", "").inheritIO();
    Process p = pb.start();

After this is done you can simply run the code

> javac
> java -cp . PythonProcess
Type the number? 44
Your number is: 44

macOS High Sierra – make sure your system is safe
updated for ClamAV release 0.100.0

If you want to make sure that your macOS High Sierra is clean (when it comes to malicious software) you can use free tool (free as in beer and free as in speech – at the same time) called ClamAV.

You can get it various ways. You can download it’s commercial version from AppStore – as paid release, you can install it using brew, download binary from some place where you have no idea what’s really inside, You can instal macOS Server (ClamAV comes bundled with it), etc.

However, you can also build it by yourself. Directly from sources. It’s a pain in a neck, I know, but you can be sure of what you are actually running. And, you will learn that zlib’s library author is a really brainy person. Go ahead, look for yourself in Wikipedia.

Anyway. Let’s start. Estimated time to complete (depending on your system configuration) – 1h-2h.

I suggest to create some place, where you can put all sources and binaries. I suggest following approach

mkdir -p $HOME/opt/src
mkdir -p $HOME/opt/usr/local

In each step, we will download source codes of given tool into


and then, use

./configure --prefix=$HOME/opt/usr/local/$TOOL_NAME

to install them inside $HOME/opt.

1. You need PCRE – Perl Compatible Regular Expressions

cd $HOME/opt/src
curl -O
tar zxf pcre2-10.30.tar.gz
cd pcre2-10.30
./configure --prefix=$HOME//opt/usr/local/pcre2
make install

# You can also run `make check` before installing PCRE, but you may need to apply path
# source:
# To apply it, simply put patch content inside file RunGrepTest.fix
# --- 8< --- CUT HERE --- 8< --- CUT HERE --- 8< --- CUT HERE --- 8< --- 
--- RunGrepTest	2017-07-18 18:47:56.000000000 +0200
+++ RunGrepTest.fix	2018-01-07 20:00:40.000000000 +0100
@@ -681,7 +681,7 @@
 # works.

 printf "%c--------------------------- Test N7 ------------------------------\r\n" - >>testtrygrep
-if [ `uname` != "SunOS" ] ; then
+if [ `uname` != "Darwin" ] ; then
   printf "abc\0def" >testNinputgrep
   $valgrind $vjs $pcre2grep -na --newline=nul "^(abc|def)" testNinputgrep | sed 's/\x00/ZERO/' >>testtrygrep
   echo "" >>testtrygrep
# --- 8< --- CUT HERE --- 8< --- CUT HERE --- 8< --- CUT HERE --- 8< ---
# and run patch tool
patch -b RunGrepTest RunGrepTest.fix

2. You need LibreSSL
(special thanks go to: I was always using OpenSSL, but recently I had more and more issues with it while compiling stuff from sources.

cd $HOME/opt/src
curl -O
tar zxf libressl-2.6.4.tar.gz
cd libressl-2.6.4
export CXXFLAGS="-O3"
export CFLAGS="-O3"
./configure --prefix=$HOME/opt/usr/local/libressl
make check
make install

3. You need zlib

cd $HOME/opt/src
curl -O
tar zxf zlib-1.2.11.tar.xz
cd zlib-1.2.11
./configure --prefix=$HOME/opt/usr/local/zlib
make install

4. Build the stuff

cd $HOME/opt/src
git clone git://
cd clamav-devel
git checkout tags/clamav-0.100.0 -b rel/0.100
# you can also get stable version from here:
export CFLAGS="-O3 -march=nocona"
export CXXFLAGS="-O3 -march=nocona"
export CPPFLAGS="-I$HOME/opt/usr/local/pcre2/include \
  -I$HOME/opt/usr/local/libressl/include \
./configure --prefix=$HOME/opt/usr/local/clamav --build=x86_64-apple-darwin`uname -r` \
  --with-pcre=$HOME/opt/usr/local/pcre2 \
  --with-openssl=$HOME/opt/usr/local/libressl \
  --with-zlib=$HOME/opt/usr/local/zlib \
  --disable-zlib-vcheck \
make install

5. Make sure to keep your database up to date


6. Now, you can scan your drive for viruses

cd $HOME
$HOME/opt/usr/local/clamav/bin/clamscan --log=$HOME/scan.log -ir $HOME

# if you want to scan your whole drive you need to run the thing as root
# I also suggest to exclude /Volumes, unless you want to scan your TimeMachine
# and all discs attached
# -i - report only infected files
# -r - recursive
# --log=$FILE - store output inside $FILE
# --exclude=$DIR - don't scan directory $DIR
cd $HOME
sudo $HOME/opt/usr/local/clamav/bin/clamscan --log=`pwd`/scan.log --exclude=/Volumes --exclude=/tmp -ir /

To compile ClamAV on macOS High Sierra I have used my old scripts, but many thanks go to:

Simple automation for random commenter name

$input_1 = array(

$input_2 = array(

$name = $input_1[rand(0, count($input_1) - 1)] . ' ' . $input_2[rand(0, count($input_2) - 1)];
  value="<?php echo htmlspecialchars($name)?>"/>

GDPR and blog comments

I have no idea whether GDPR affects personal blogs or not.

However, I decided to clean all the e-mails attached to comments, anyway. In fact, I haven’t asked people for name, e-mail, anything, for quite some time (more than a year already, I guess).

Today, however, I have decided to make a final step. I don’t store anything.

You will be given random name (whenever you want to comment something), I don’t want to know your IP address, and I have no interest in knowing your e-mail. Just express yourself in comment field ;)

If you are looking for GDPR ready SQL query for Word Press, here it is


I’d love to comment an article on your blog

but you don’t let me do it. Dear, anonymous blogger, you make me run away just after reading your ideas.

Yes, you hide yourself behind Disqus, Twitter, Facebook login. You force me to provide my name, my e-mail, my everything. It makes me say “-I don’t care. Reading was nice, but I have no time for all that login stuff”. And I quit. I haven’t given you any feedback, even though I wanted to say “-Thanks man! It was a really nice read! Keep up good work.”

So, maybe you can just get rid of all that “log in to comment” stuff? Just turn moderation on, add some spam filter, that’s it.

Unpacking RPM

rpm2cpio file.rpm | cpio -idmv

It looks like all the people in IT industry write books …

and this reminds me of a quote

The irresistible proliferation of graphomania among politicians, taxi drivers, childbearers, lovers, murderers, thieves, prostitutes, officials, doctors, and patients shows me that everyone without exception bears a potential writer within him, so that the entire human species has good reason to go down into the streets and shout: “We are all writers!” (…) One morning (and it will be soon), when everyone wakes up as a writer, the age of universal deafness and incomprehension will have arrived.

– Milan Kundera, The Book of Laughter and Forgetting, 1978

Are we there yet?

Story of a simple task

There was this on-line challange where you were supposed to calculate the cargo that could fit into your cargo space. Task, itself, was not complicated, however my ideas about solving it, were jumping from technology to technology. From purely functional, via object based to ancient, structural based, approach.

At first, I though – “Why not use Scala or something? All this new functional fuss. It will be super cool”. I have created all possible lists of cargo with toSet and subsets, ordered lists by cargo size and price. Then, I have thrown away cargo that doesn’t fit, and taken head. At this point, I could have easily refer to List of tuples that define the best match. Nice!

def foldTuples(l: List[List[(Int,Int)]]): List[(Int,Int,Int)] = {
  def _foldTuples(res: List[(Int,Int,Int)], rem: List[List[(Int,Int)]], idx: Int):
  List[(Int,Int,Int)] = rem match {
    case Nil => res
    case (h:List[(Int, Int)])::tail => _foldTuples(
        (0,0,idx)){(acc,iter) => (acc._1 + iter._1, acc._2 + iter._2, idx)}, 
  _foldTuples(List.empty[(Int,Int, Int)], l, 0)

var a = List((2,26),(6,30),(4,28),(4,36),(3,30)).
a(foldTuples(a).filter(_._1 <= 12).sortWith(_._2 > _._2).head._3)

But hey! Maybe OO based approach would be better here? I could have created Ship with a Cargo bay. Cargo bay could hold different kinds of Cargo represented by yet another class. This way, process of calculating cargo size would be hidden. It could be delegated to Cargo bay itself. In case like this, all I need to do to get my stuff packed is to ask the Ship: “-Hey, Falcon, here is the cargo. Will it fit in?”

import java.util.ArrayList;

public class Ship {

  public Ship(int cargoSize) {
    bay = new CargoBay(cargoSize);

  public void fillCargoBay(ArrayList<Cargo> cargo) {

  public void printCargo() {

  public static void main(String[] arg) {
    ArrayList<Cargo> boxes = new ArrayList<>();
    boxes.add(new Cargo(2, 26));
    boxes.add(new Cargo(6, 30));
    boxes.add(new Cargo(4, 28));
    boxes.add(new Cargo(4, 36));
    boxes.add(new Cargo(3, 30));

    Ship millenniumFalcon = new Ship(12);

  private CargoBay bay;

class CargoBay {
  public CargoBay(int maxCapacity) {
    this.maxCapacity = maxCapacity;

  public void fill(ArrayList<Cargo> cargo) {
    ArrayList<ArrayList> allSubSets = generateAllSubSets(cargo);

    Cargo currentMax = calculateCapacityOfCargo(this.cargo);

    for(ArrayList list : allSubSets) {
      Cargo nextCargo = calculateCapacityOfCargo(list);
      if(nextCargo.size <= maxCapacity && nextCargo.price > currentMax.price) {
        this.cargo = list;
        currentMax = nextCargo;

  public void printCargo() {
    for(Cargo c : this.cargo) {
      System.out.println("size: " + c.size + " price: " + c.price);

  private Cargo calculateCapacityOfCargo(ArrayList<Cargo> cargo) {
    Cargo result = new Cargo(0, 0);
    for (Cargo c : cargo) {
      result.size += c.size;
      result.price += c.price;
    return result;

  private ArrayList<ArrayList> generateAllSubSets(ArrayList<Cargo> cargo) {

    ArrayList<ArrayList> cargoLists = new ArrayList<>();

    int n = cargo.size();

    for (int i = 0; i < (1 << n); i++) {
      ArrayList<Cargo> newCargo = new ArrayList<>();
      for (int j = 0; j < n; j++) {
        if ((i & (1 << j)) > 0) {
    return cargoLists;

  private ArrayList<Cargo> cargo = new ArrayList<Cargo>();
  private int maxCapacity = 0;

class Cargo {
  public Cargo(int size, int price) {
    this.price = price;
    this.size = size;

  public int size;
  public int price;

Nah, man. OO based result is way too long. But, wait! Maybe there is a different way? Maybe I can do it nasty, structural, way? Is it possible to create something that will fit inside one Tweet? Yes it is. Here comes the code. Simple, small, and very elegant ;) It has recursion, have you noticed? Thus, it must be a sophisticated one ;)

int l(i,c,p,m){return (i<5)
:((p>mp && c<=10[crg])?((mp=p)&&(mm=m)):1);}
int main(){l(0,0,0,0);
for(int i=0;i<5;i++)mm&(1<<i)

And it fits in a one Tweet ;)

CentOS 7 – issues while using certbot

On CentOS 7 you can face issues related to pyOpenSSL version while running certbot (

ImportError: ‘pyOpenSSL’ module missing required functionality. Try upgrading to v0.14 or newer.

If you can’t force CentOS 7 to use more recent version of this package, try this:

> cd ~
> mkdir virtualenv
> cd virtualenv
> virtualenv --no-site-packages -p /usr/bin/python2.7 certbot
> . ~/virtualenv/certbot/bin/activate
> pip install certbot
> pip install --upgrade setuptools
> pip install --upgrade pyOpenSSL
> pip install ipaddress
> pip install enum34
> pip install cffi
> certbot --version
certbot 0.24.0

If you want to renew the cert, simply type

# if you want to renew certificate, you can run following command
> certbot renew

# in case you want to create new certificate, run it following way
> certbot certonly --standalone --preferred-challenges http -d

Connecting to already running Docker container

> docker ps
abcdef123456        image_name
> docker exec -it abcdef123456 /bin/bash

Calling C code from Python via Cython

If you need more information what Cython is, take a look here:

This sample, is a simple “Hello world” code for macOS based installation of Python and Cython.

First step is to get Cython for your platform. You can use pip to achieve that

# Installation of Cython at macOS
# I prefer to use Virtualenv contrary to OS based installation
# If you need more info about Virtualenv, take a look here

> virtualenv venv
> source venv/bin/activate
> pip install Cython

After you are done with that, you can create sample code. We will call method in C that accepts one argument – char * – and prints the string on stdout.

/* hello.c */
#include <stdio.h>

void f(char *str) {
      printf("str: %s\n", str);

Next thing we need is a Cython based wrapper for the code we want to call

''' hello_caller.pyx '''

cdef extern from "hello.c":
  void f(char *)

    take a look here for details about different Cython declarations
cpdef hello_world(str):

Last thing we need is a script for Cython that will perform the build

''' '''
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

sourcefiles = ['hello_caller.pyx']
ext_modules = [Extension("hello_caller",
                          sourcefiles )]

  name = 'Hello world',
  cmdclass = {'build_ext': build_ext},
  ext_modules = ext_modules

After everything is set up, we can build everything

> python build_ext --inplace

and, eventually, we can call C code from Python code

''' '''

import hello_caller

message = "Hello world"

by running

> python ./
str: Hello world

How to get info which release of CentOS was installed

> cat /etc/centos-release
> cat /etc/redhat-release

The Art of Quitting

Do you want to avoid these awkward moments when you want to do something inside editor but you have no idea how to do it?

Do you want to look like a pro while working with random people?

Do you remember last time you have asked your colleague

– How do I quit this thing?

Don’t you worry no more! Read the best selling leaflet “The Art of Quitting” and act like a pro. Quit editor, you don’t know, and keep your poker face

– Hey, as we are already here, let me start [vim/emacs/nano/pico]

Surviving in Java’s world

JNI Cookbook – Appendix B

uDocker – when there is no root around

Docker (at some point) requires root privileges. However, it’s not always the case you have them. And then, you need to go via sys admin ;)

source: When Sysadmin lends a hand – CommitStrip

If you have found yourself in a situation like this, consider using either uDocker or Singularity.

Using uDocker, you can run image without root privileges at all.

“- Look mum, no root!”

– Anonymous Sysadmin

> curl >
> chmod a+rx
> ./ run hello-world
Downloading layer: sha256:9bb5a5d4561a5511fa7f80718617e67cf2ed2e6cdcd02e31be111a8d0ac4d6b7
Downloading layer: sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4
Warning: check container content: 74d3a6a7-72d2-3615-a1d2-f46ef8811a70
Warning: non-existing user will be created

 *                                                                            *
 *               STARTING 74d3a6a7-72d2-3615-a1d2-f46ef8811a70                *
 *                                                                            *
 executing: hello

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:

For more examples and ideas, visit:

Ansible Container and time out
during the process of storing large image files

If you have encountered the issue related to time out (during the build process of images while using ansible-container), take a look here:

Reproducing the issue (macOS)

$ python2.7 -m ensurepip --default-pip
$ sudo pip install virtualenv
$ virtualenv venv
$ source venv/bin/activate
$ pip install ansible
$ pip install ansible-container[docker]
$ pip install docker==2.7.0

Clone the repo and build image

$ git clone
$ cd ansible-with-big-file
$ ansible-container build --no-cache
# at some point, you will get ReadTimeout (timeout=60) - it is coming from conductor
  File "/usr/lib/python2.7/site-packages/requests/", line 642, in send
    r = adapter.send(request, **kwargs)
  File "/usr/lib/python2.7/site-packages/requests/", line 515, in send
    raise ReadTimeout(e, request=request)
requests.exceptions.ReadTimeout: UnixHTTPConnectionPool(host='localhost', port=None): 
     Read timed out. (read timeout=60)
Conductor terminated. Cleaning up.

How to fix the issue?

git clone
cd ansible-container
pip install -e .[docker]
# Modify file: ansible-container/container/docker/templates/conductor-local-dockerfile.j2
echo "" >> \
# Create image. This time, using custom conductor
cd ansible-with-big-file
ansible-container build --no-cache

Polycom RealPresence Desktop – they can see me, but I can’t see them!

If you encounter this kind of problems, make sure to check port forwarding on your router. Recently, it happened to me that router decided to remove all the port forwarding I have set up in the past. Just make sure to have this list of forwards configured.

You can read more about configuring Polycom with your DSL router here: Polycom m100 and router configuration for correct port forwarding (NAT) – no audio, no video.

Docker and memory settings

If you encounter this kind of issue

g++: internal compiler error: Killed (program cc1plus)
Please submit a full bug report,
with preprocessed source if appropriate.

Make sure to provide way more memory for your Docker