Docker as builder system for C++

hacktober

Abstract

In this post I’ll show how to avoid to wasting your time rebuilding a fresh new image every time you make a small change in your code. The reference language is C ++ but the proposed solution can be used for  every compiled languages and project which require time consuming building process.

Problem

Best practices suggest to use multi-stage Dockerfile copying all the source code in the builder stage, compile it and then copy the binary file on next stage. This approach makes sense in production instead while you’re in dev mode and you’re forced to use the container to compile and makes test has a great problem.
Every time you make a small change in the source code this means a fresh new Docker image; even if the rebuild uses previous layer and just recompile whole the project this can be a problem if it is time consuming requiring several minutes to recompile.

If you’re in dev mode waiting for several minutes every time you make a simple change can be annoying.

Idea

It will be great to recompile only the files with the changes just like when you’re developing and compiling on your system. In order to do this the source code is stored inside the host’s file system and mounted as volume by the container. This guarantee that all the object files are not looses and b reused on next compile processes.

Hence the idea is to have a container with the following features:

  • have all the necessary to compile
  • recompile only the changes on source code
  • generate the binary file on host’s file system
  • there is no need to rebuild the image to generate the binary file.

This container will be a “binary generator” and it’s purpose  its to generate a new binary file without recompile whole the project. Then use new binary file to create the runtime docker image.

Solution

In order to better explain my solution I have created a simple “Hello world” project that you can find here. The tree of the project is the following:
    .
    ├── core.cpp
    ├── core.hpp
    ├── dev_env
    │   ├── builder
    │   │   ├── docker-compose.yml
    │   │   └── Dockerfile
    │   └── runtime
    │       ├── docker-compose.yml
    │       └── Dockerfile
    ├── docker-compose.yml
    ├── Dockerfile
    ├── main.cpp
    ├── Makefile
    └── README.md

The Dockerfile and docker-compose.yml at the root level show a single stage build process that will show the original problem: changing one file will rebuild the the whole process, which is what we are trying to avoid.

In the dev_env directory we can find the proposed solution:

  • the builder directory contains the Dockerfile and docker-compose to generate the builder container (the one used to generate the binary file).
  •  the runtime directory contains all the necessary to build test or runtime image.
    Instead the runtime contains all the necessary to build test or runtime image.

Builder directory

docker-compose.yml

version: '2.3'

services:
   
    binary_builder:
        container_name: "binary_builder"
        image: binary_builder
        build:
            dockerfile: ./dev_env/builder/Dockerfile
            context: ../../
            args:
                src_path: /src
        volumes:
            - ../.././:/src:rw

As you can see on the src directory, on container, is mounted the root of the project, source code included.

Dockerfile

    FROM ubuntu:18.04
    ARG src_path=/src
            
    RUN apt-get update                          && \ 
        apt-get install -y                         \
        g++ build-essential
     
     RUN mkdir -p $src_path
     WORKDIR $src_path
     CMD     make

The Dockerfile is quite simple it takes the source code from $src_path and the compile it (if necessary) every time it will be started. Another advantage is that it is not necessary to rebuild the builder container to generate a new binary.

Runtime directory

The Dockerfile is very simple, use the same base image used in builder level and copy the binary file from the host file system.

Dockerfile

    FROM ubuntu:18.04 as run_time
    COPY  hello_world /hello_world
    WORKDIR /
    CMD ./hello_world

The advantage is that to rebuild the runtime container you have to generate a new binary file and copy it on the new image saving time.

 

Conclusion

I hope this article has helped you.

Pubblicato in Uncategorized | 1 commento

Hacktoberfest 2018… …achived !!

hacktober

After a failure Hacktoberfest 2016 and forget to partecipate to Hacktoberfest 2017 finally I’ve completed the Hacktoberfest “challenge” on 2018.

 

dav

dav

 

Pubblicato in Uncategorized | Lascia un commento

GitHub Text Search Chrome Extension

icon128Hi,

recentely I’ve the need to search code in some repositories hosted by GitHub but I don’t want to clone them and search in it using grep or similar. The fact is that the code is already in front of my eyes (on GitHub repository’s page) so I thought that it will be usefull (at least for me) to have some utility to search code or text directly on current repo. Well, long story short I’ve wrote a Chrome extension called “Github Text Search” which add a search bar on repository’s page which allow the user to search some text, the matches are listed as file names.

screenshot_ext_2

Due the fact that it use GitHub API there these limitations:

  • the search can be done only on master branch
  • do not support forks.

The source code is available on GitHub at this link. instead this is the link to the extension.

 

Pubblicato in Uncategorized | Lascia un commento

GitHub Battle is reborn

Some weeks ago I’ve restarted an old (about 3 years now) project called github-battle (you can find here the old article about it).

This project only had a client side in JS which makes some ajax request to github API, now I’ve added a back-end part which stores the fights and compute stats about github users.

You can try it clicking here.

 

Bye

Pubblicato in Uncategorized | Lascia un commento

Job offer and recruiter

In the last 2 years I received e-mail from recruiters who wants offer me a job position. Unfortunately I did reject almost 90% of them before begin the interview phase and I want to explain here why I did that.

Wrong match profile

If  you contact me by e-mail or worst by phone saying “I saw your profile on Linkedin, or your resume on your site, and it is perfect for this position…” and the 70% (or none, it is happened) of required skills do not match my profile… well you’re wasting my time.
If you’re an external recruiter (or head hunter) and you do this you’re loosing  credibility and probably I will be more prepared to reject you in the future. I understand that more candidates you give to the company higher is the probability that one of them will be hired but if I was the company who ask you to find some candidates and you give me  these kind of candidates well I will no happy too.

Required skills in everything

One of the last positions was for a web developer. The required skills begin well each of them was about the field, but after a while starts to compare:

  • experience with app mobile
  • machine learning
  • Golang
  • C#
  • SDK social network (Facebook, Twitter, Linkedin) and Google Services
  • configuration and maintenance of server Linux

To me it seems a quite wide required skills for a “web developer” position. Please specify a set of skill which match the position you’re looking for.

Choose carefully third party recruiting web service

Some platforms for recruiting are bad, really bad or may happens that they are used in a wrong way. I’m registered in some of them and may happens that the procedure of selecting is disputable and discouraging. In the last 3 months from one of them I received about 4 application’s request, the procedure consist about a set of few questions like “Set below your Python level” and 3 radio button with “low, medium, high” or “Do you know Django? [Y/N]” and even worst questions. For each “correct” answer you gain 1 point and for wrong one you loose a point. Please do not use them or at least try to write some good question, not generic ones.

These too are the main reasons which cause my reject, there are others but I’d like to put them as list of advices about what and how write in a job announce.

1 – Please write the range of salary for the position, specially if you’re looking for an employee with high skills level.

2 – Avoid to say “Fresh new super tech ninja startup” and try to describes the company.

3 – Write a typical day of work for the position.

4 – Avoid to say “If you have a great passion for new technologies and looking for place where you can use them” if the required skills are PHP 5.X, CSS, HTML.

5 – The fact you have videogames, bowling, free beer, barbecue on the beach during weekend etc do not convince me.

6 – Saying “We’re looking for person who sacrifices his life to the company, like work overtime etc” means you’re looking for slaves not employees.

7 – Write the technologies used in the company.

8 – Do not hide the company name.

These are just some advices, please feel free to use them.

 

 

 

 

Pubblicato in Uncategorized | Lascia un commento

Hacktoberfest 2016

hacktoberSome days ago ended Hacktoberfest 2016 an event created by DigitalOcean in partnership with GitHub.  The event is a month-long celebration of open source software where  the people are invited to contribute towards issues on projects hosted on GitHub in order to help move the them forward. The contributes can be bug fixes and documentation updates. Who contributes with 4 pull-request win a free, limited edition Hacktoberfest T-shirt.

Unfortunately I win just the sticker pack (like the other participants), but I like to participate to it. I always think that is important to participate on open sourced project but usually I do very few things about it… probably due of my bad time management, too many ideas that I want to do and sometimes the need to just relax on couch or go around somewhere (if I remember correctly it is called “live”). Anyway I really appreciated the initiative and I will participate again the next year, hopefully to win the T-shirt :).

[UPDATE 11/January/2017]

nor

Pubblicato in open source, programming | Contrassegnato , | 1 commento

Passing a Python callback to C++ in Cython

Hi,

in these days my work involve the porting of one of mine C++ library to Python, to accomplish this I’ve used Cython. The use of Cython is simple and very well documented but I’ve encountered a problem porting a callback from C++ to Python so I’ve decided to write down a post about my problem and the solution that I’ve adopted.

C++ Library

The library that I’ve wrote is a client library used to communicate with a server, it provide a class with a very poor API, the meaning of this library is out of scope but below you can find the basic actions provided by the library.

class ClientLibrary{
    ClientLibrary();
    init(std::function<void(const unsigned int &, 
                            const std::string &)> log = nullptr,
         unsigned int log_level=NORMAL_LVL);
    connect(const std::string &ip, unsigned int port);
    disconnect();
    ...  // others methods
};

As said it has a simple API, just one function has need of explanation, the init(). This method initializes the library (or class) itself, it accept a function pointer and an unsigned int. The first parameter is used in order to let the user specify its own  custom log method and the second to set the level of the log in which is interested.

Let the user to specify its own log method is important, in this way it can save it on file or handle some casuistry in some way. The constraint is that the function specified must accept as first parameter an unsigned int and for second parameter a string, these are the log level  and log message.

Problem

The problem is that the porting in Python use Python code (well… kinda obvious) which C++ library don’t understand. In fact even if you use Cython some where you call the C++ code of the original library, in this case it means that when the user pass the callback in Python the C++ part get angry because it expects a function pointer.

Solution

To avoid it I’ve created a  Men In the Middle function with the same interface expected from a log callback function in C++ which call the Python callback.

# create a MIM function for log callback
# it has the same interface expected from C++ version
cdef void log_mim(unsigned int log_level, const string message)
    pylog_cb(log_level, message)

# Python class
cdef class PyClient:
    ....
    def init(self, log_cb=None, log_lvl=0):

        if log_cb is not None:
            # Python 2.x support
            if not callable(log_cb):
                raise TypeError("""The first parameter MUST
                                   be a function.""")
            # store the Python callback on global variable
            # pylog_cb
            global pylog_cb
            pylog_cb = log_cb
        return self.client_ptr.init(log_mim, log_lvl)

The init method accept a callback  log_cb and the log level log_lvl, the first is stored on the global variable pylog_cb. At the end it will call the C++ init passing the function log_mim. When the C++ code will call the callback log_mim (C++ function pointer) it will call the Python pylog_cb.

Conclusion

This solution to “callback problem” works pretty well, the MIM function allows to avoid the incompatibility between the 2 languages.

On PyClient is missing all the source code about the allocation/deallocation of the object and how to link Python and C++ code cause it is beyond the scope of the post.

Pubblicato in programming | Contrassegnato , , , | 2 commenti

Linkedin is not Facebook

lnotFHi,
today I’ve received the N e-mail from Linkedin which says that someone on my Linkedin network has confirmed or “added” a skill on my profile even if he/she doesn’t know the field in which I work and/or doesn’t know anything about my skill. so I’ve decided to write down a post about how the people is using Linkedin. First of all Linkedin is not Facebook hence stop adding useless post which not regards your work, field, hobby or something that has any sense; I don’t belive that a video with kittens has something to do with your job unless you’re a vet. As others social networks which makes use of reputation (that will be ‘like’, karma points and so on ) on Linkedin happens that the people share the ‘skill validation’ between them, a user endorses the skill of another in order to have a skill validation too. This kind of behavior do not help Linkedin and its users because the skill endorsement lost its value… ok in my work (sw developer) I don’t belive in something like ‘skill validation’ on social network anyway, in fact I prefer to see the source code or something else (documentation, tests etc) that give to me the idea of the capabilities of a person. For these reasons I don’t accept the endorsement of persons that don’t have the skill to understand my work (even if they don’t do my same job they can be a great developer even if they do it for hobby) or that haven’t see one single line of my code or haven’t worked with me (for hobby or job). I guess that everyone should at least ask himself  if the ‘skill validation’ of someone has any sense and not try to collect as many as he can ( we’re not playing to Pokemon so we can’t have to ‘catch em all’). So be honest with yourself and accept only the endorsement from people who you know and make honest endorsements.

Pubblicato in Uncategorized | Contrassegnato , | Lascia un commento

An unexpected Alibaba

logo
Hi,

today a friends of mine suggests me to make a challenge between Google and Alibaba on my site GitHub Battle. Well long story short the challenge was won by Alibaba; OK I admit that the formula used to compute the score isn’t perfect and some parameters may missing but anyway it has highlighted the fact that Alibaba is a great contributor about open source and has a great number of repositories. This is an unexpected event, well at least for me, and this made me think that GitHub Battle can be used in some way to discover some particular/funny event. So until I make some improvements I will ask you to notify me if you find something that seems interesting while you are using GitHub Battle :). At the end of this post you can find a screenshot about the “challenge” between Google and Alibaba.
Bye

GoogleVSAlibaba

Pubblicato in Uncategorized | Contrassegnato , , | 1 commento

GitHub Battle

logo
Hi,

some time ago I’ve seen the site Github Awards. This site shows the rank of GitHub’s users, you just need to write the username of a user and it shows his world, national and city ranks for each programming languages that he used. I’ve played a little with it, looking my ranks and the ones of my friends so after a while I’ve started to thought to see who, between me and my friends, have the highest rank. Well from that idea I came up with a site which allows anyone to make challenge 2 GitHub’s users and see which one has the highest score. The way in which the score is computed is quite simple and different from the one used in GitHub Awards. The site compute the score for each repository using the following formula:

repo_score = stars + 1.5*forks + 0.2*watchers

the scores are grouped by programming languages and the total score is the sum of all programming languages score.
For which is interested to play the site is available at GitHub Battle instead for which wants to contribute can find the repository on GitHub.

Pubblicato in programming, Projects | Contrassegnato , | 2 commenti