This is a personal blog, the opinions expressed here are my own, and do not necessarily reflect those of my employer. Este é um blog pessoal e por isso o que é escrito aqui, pode não refletir as idéias das empresas em que eu trabalho e nem dos parceiros com quem eu faço negócios. Bem vindo e espero que aproveite algo. Be welcome and I hoje you enjoy 🙂

Last #10

IMG_20170322_140523390In this month I completed exactly two years of remote working, what adventure! To remind me about this in future and also to share with you all I resolve to write about that here.

FEAR, that was the first emotion that I felt when I decide to abandon my last physical work where I was in job for at least 5 (five) years. I was not happy at all but only who pass for something like that knows what I am talking about, it is not easy to change.

Do I have all the skills to make a change?
Would I get the same status of my work in another company?
Would I have the same stability in another company?
And if I lose my job after the change?
And if I don’t achieve do the new job that I will be contracted?

FREEDOM, was the first feeling that I felt when I subjugate all those doubts. Why we have so much fear of changes? After reading some books I thought about this for a lot of time and it seems to me that is something that we acquire after youthness, at school we are taught so hard that we need something stable, something to catch us, that we forget about how importantly if sometimes we take risks.

Ohh, the changes! In these two years my whole life changed a lot! I had my first kid, my marriage get even better, my financial life is growing exponencial because now I have the time to study and make investments in market, and I just have to thanks God for all that. I always ask myself: “and if I wouldnt change ten years ago? and if I wouldnt change my last job five years ago too? Would I had the same happiness that I have now?”. Changes are important, you have to make a move sometimes, you need to take risks. You need to make mistakes but you have to fix your life before get old and frustrated.

I mean, I already worked for about 15 (fiveteen) years. So I know how is lose a job, unjustly and justly. It is a type of change too but you don’t decide about that at least almost every time. So I had a sensation of freedom when I choice to quit my stable job to a new adventure that would test my skills.

The first thing that almost everyone asks me when I say that I work in my home is: “How is to work at home? Seems pretty awesome!” and I always answer at this with “Indeed, it is, but it is not too easy as you think.”

  • You have to be organized.
  • You have to motivate yourself everyday.
  • You have to adapt to changes in your company.
  • You need to be sociable with the people you work.
  • You NEED to document all you do and log your hours and your work.
  • And principally, you need to organize your life: do some exercises, organize your food and separate your free time from your job time. Don’t be mad.

Be warned, If you work remote and other people don’t, some changes will happen and sometimes they will forget to consult you, you need to adapt. Some people, like any other job, will had envy or just will try to turn things dificult for you, you have to adapt.

Be trustable, be productive.
Don’t bother yourself with little things.
Instead, be clever. Work on solutions and be the solutions.

If you do a little half of that perhaps you enjoy working remotely too. Otherwise probably you will get disappointed and be the same you was when you decide change, a person with a lot of fears hidden.

Do you need a change too? Do your soul claims for that?
Start now, put the things you need to do in a paper and after some time, be the change!

Ansible is one of the best tools in DevOps that I like, he just need a simply configuration and can help you with a lot of tasks in your day by day on your infrastructure, today I will show to you how to configure him to work with a lot of servers and how to automate some simple tasks.

Advantages of Ansible

  • Easy to use and fast response
  • Highly configurable to almost every task you need to do
  • SSH based, just use ssh-keygen, ssh-copy-id and ssh-add
  • Free software sponsored by Red Hat
  • Playbooks to make complex tasks

So how we begin use this tool?

The very first thing you need to do is obviously install Ansible on your system. You can do this by typing on linux

# yum install ansible # (redhat)
# apt-get install ansible # (debian/ubuntu)

Or on your OSX:

$ /usr/bin/ruby -e "$(curl -fsSL \"
$ brew install ansible

The inventory file

Ansible needs a file to specify all servers you want to control, you can use a tag name to make an group  to all servers you want by category, below we set two groups: appservers and databases, note that you don’t need to specify one by one in a line, you can use regex to simplify (this is awesome!)



After that, or perhaps before that, as told before Ansible needs a SSH master key that need to be added on ~/.ssh/authorize_keys file into each of your slave servers, to do that you just need to proceed like this:

$ ssh-keygen -t rsa # (to generate your key, enter until finish)

And you will get a ~/.ssh/ public key file in your $HOME directory; So now you need to distribute your public-key to all servers you need control, this can be easy if you have only ten servers to administer or a pain if you have to do this in more than 100+ servers, so here’s a tip:

  1. Create a file with all your servers like this:

    (I will not show to you how to make this with inventory file as input, but you can!)

  2. Use this command-line to copy your keys to each server and insert root-password
    $ while read LINE; do ssh-copy-id $LINE; done < /tmp/servers

Using Ansible in command-line

All set? So lets try do something really cool here. This is the most basic syntax of ansible:

$ ansible :target: -i inventory-file :actions:

Where :target: is the group of servers in your inventory file or just an string all to contemplate all servers in your inventory, the :actions: can be a simply command like below or a more complex command-line using ansible modules.

  • Get all kernel versions of our servers
    $ ansible all -i yourcompany.conf -u root -a "uname -a" | SUCCESS | rc=0 >>
    Linux 3.13.0-92-generic #139-Ubuntu SMP Tue Jun 28 20:42:26 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux | SUCCESS | rc=0 >>
    Linux 3.13.0-92-generic #139-Ubuntu SMP Tue Jun 28 20:42:26 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux | SUCCESS | rc=0 >>
    Linux 3.13.0-92-generic #139-Ubuntu SMP Tue Jun 28 20:42:26 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux | SUCCESS | rc=0 >>
    Linux 3.13.0-92-generic #139-Ubuntu SMP Tue Jun 28 20:42:26 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

    (Note that all servers responded with your kernel)

  • Use a default module ping to check if databases are alive
    $ ansible databases -i yourcompany.conf -m ping | SUCCESS => {
        "changed": false, 
        "ping": "pong"
    } | SUCCESS => {
        "changed": false, 
        "ping": "pong"
  • Use a default module apt to install a mysql database
    $ ansible databases -i yourcompany.conf \
    -m apt -a "name=mysql-server state=latest"

So how can I know what modules are available?

They are listed here ->

Playbooks: The real thing

Okay, now you know that you can send commands and use modules to process in all your servers with just one command line, thats cool! But what really amazing in Ansible are the playbooks! A playbook is just a file with a template engine called YAML and Jinja to apply some filters, variables and others, with that you can do a lot of automate complex tasks in your servers. Lets take a look into a sample file called ‘install_apache.yml‘:

- hosts: appservers
    http_port: 80
    max_clients: 200
  remote_user: root
  - name: install or upgrade apache to latest version
    yum: name=httpd state=latest
  - name: write the apache config file
    template: src=./httpd.j2 dest=/etc/httpd.conf
    - restart apache
  - name: ensure apache is running (and enable it at boot)
    service: name=httpd state=started enabled=yes
    - name: restart apache
      service: name=httpd state=restarted

There’s a lot of information and process automation here.

  1. hosts -> means that all these tasks will only be executed in the group defined after the word, here appservers, defined by our inventory file in the begin of this post.
  2. vars -> are variables you define to process tasks with it, note that variables are defined line by line.
  3. remote_user -> another way to use -u root without need to put in cmd.
  4. name -> is just a name you define to implement a task
  5. template -> in this case is just a way to say, copy my source file defined as ./httpd.j2 to destination server on /etc/httpd.conf
  6. notify -> is a tag that call a job (restart apache) in handlers block at the end of execution of the current block

Or, to resume this playbook will:

  1. Install the latest version of httpd apache on all your appservers
  2. Copy your local httpd.j2 file to remote server on /etc/httpd.conf
    1. Put your variables where you set in httpd.j2 file
    2. Restart apache after that
  3. Set apache to run automatically after a boot/reboot

As you see you can do a lot with this, without this you would need to enter in each server and make these tasks one by one without any human mistake, with ansible you just need to type this:

$ ansible-playbook -i yourcompany.conf install_apache.yml

On next time we will show to you how to do more complex examples, best practices and directory structure to help on your day tasks.

Thats it for now! What are you waiting for? Use ansible to automate your tasks now!! 🙂

Hello friends!

Look on the internet a alternative way to upload files on Amazon S3 without AWS-SDK and then you will know that is a dificult thing for many; Wait a second, why someone will need to use S3 without the Amazon SDK? That’s the problem! We all know that sometimes you can’t do simple a import/require in some lib written by another guy/girl to turn things to into a easy way. That’s the beauty of an challenge.

So to win that, all you need to do is read two docs of Amazon:

The first documentation describes how you handle the HTTP PUT using simple REST and the second describes how to implements the Amazon signature based on AWS_ACCESS_KEY and AWS_SECRET_KEY;

Backing to the problem, days ago in my work we need to face this problem: the development version of a framework that we use can’t import AWS-SDK into project and after the mess that this problem caused, it make me think in do this post on blog;

I was already do it a year ago using shell-script when I need to automatize a build process of MacOS to send the .IPA into S3, so I start to do some changes in code and finally written two new version: one in shell script and other in node.js; The principal problem found, the root of many problems to some guys is the signature process, as described on Amazon docs all you need to sign is:

  • MD5_BASE64_HASH is one of the tricks of Amazon Doc (bad trick)
  • mimetype i just use application/octet-stream works for all types of file
  • DateInIsoUTCTime like -> Wed, 26 Oct 2016 12:09:45 +0000
  • someHeadersOfAmazon extra header of Amazon that you need to pass
  • fullPathOfObjectFile /yourBucketName/dir1/subdir2/yourFile.jpg

Or in resume:

Fri, 25 Nov 2016 14:27:42 +0000

If you type one character byte wrong then your signature will receive the error below when you try to send your file:

<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message><AWSAccessKeyId>AKIAIJ5QILNVUULONEGQ</AWSAccessKeyId>

So, later I will post more details here if someone needs and also the node.js code using just the builtin libs: crypto, fs, https and buffer; until then that’s the cURL version

And the node.JS version, using just native modules;

Hope it helps someone! 🙂

taoofprogrammingI’m back from holidays! And with a new job! 😀 Still working remote now with something that I like more, Linux and software development! Just a little change: now its for web! When I get things okay here I will continue write some articles here.

For now just a good quote from a book that I recommend: The Tao of Programming. I hope you get a copy and have a good read!

Price Wang’s programmer was coding software. His fingers danced upon the keyboard. The program compiled without an error message, and the program ran like a gentle wind. Excellent!” the Price exclaimed, “Your technique is faultless!”

“Technique?” said the programmer, turning from his terminal, “What I 
follow is the Tao — beyond all technique. When I first began to program I would see before me the whole program in one mass. After three years I no longer saw this mass. Instead, I used subroutines. But now I  see nothing.

My whole being exists in a formless void. My senses are idle. My spirit, free to work without a plan, follows its own instinct. In short, my program writes itself. True, sometimes there are difficult problems. I see them coming, I slow down, I watch silently. Then I change a single line of code and the difficulties vanish like puffs of idle smoke. I then compile the program. I sit still and let the joy of the work fill my being. I close myeyes for a moment and then log off.”

Price Wang said, “Would that all of my programmers were as wise!”
— Geoffrey James, “The Tao of Programming”

Hello friends!

Today is 2016/08/25, 25 years of Linux! Happy Birthday!! 😀 😀

Today we gonna talk about how to upgrade a Slackware, we will use just the official slackware package management tool (slackpkg), lets upgrade a slackware 14.2 to a -current for example (this also works with other versions too, but try upgrade to the next always or deal with consequences).

What is slackpkg?

Slackpkg is a system package management tool developed by PiterPunk and oficially supported by Slackware, some of the most common subcommands are:

slackpkg update          -> synchronize with your mirror 
slackpkg search package  -> looks for 'package' into mirror
slackpkg install package -> install 'package' from mirror
slackpkg upgrade package -> upgrade 'package' from mirror
slackpkg upgrade-all     -> upgrade all packages installed
slackpkg install-new     -> install new software available in repository

First, install and upgrade your slackpkg

# slackpkg update  #(choose a mirror in /etc/slackpkg/mirrors)
# slackpkg upgrade slackpkg

I like the TDS Mirror but you can choice any -current mirror you like there. Then add the kernel packages into blacklist (/etc/slackpkg/blacklist) make sure that looks like this:


(this is not totally necessary but I like to upgrade kernels after upgrade all other softwares)

Second, then upgrade your glibc-solibs, this is EXTREMELY NECESSARY to not crash your system after some upgrades of software.

# slackpkg upgrade glibc-solibs

Third, install and upgrade all your new software

# slackpkg install-new
# slackpkg upgrade-all


Now, if you dont build your kernel youself, uncomment lines of blacklist (/etc/slackpkg/blacklist) to build the new kernel of Slackware repository. Check your lilo.conf or grub and apply the new kernel if you like (take care here, confirm that a new kernel was installed and check the images)

# cp /boot/vmlinuz /boot/vmlinuz-backup
# sed -i '/#kernel/s/^#//g' /etc/slackpkg/blacklist
# slackpkg upgrade-all 
# vim /etc/lilo.conf

The huge.s Slackware default kernel (built-in) have a lot of issues when we need use some softwares that require some modules/built-in by default, an example is the Docker. (huge.s default slackware kernel doesn’t support Docker very good). So you can choose use the generic kernel that has almost any module to load after boot the kernel, solving some of these issues. If you choose to do that, type the commands below, if you dont know what are you doing skip this part and use default /boot/vmlinuz.

# /usr/share/mkinitrd/ 
mkinitrd -c -k 4.4.16 -f ext4 -r /dev/sda1 -m xhci-pci:ohci-pci:ehci-pci:xhci-hcd:uhci-hcd:ehci-hcd:hid:usbhid:i2c-hid:hid_generic:hid-cherry:hid-logitech:hid-logitech-dj:hid-logitech-hidpp:hid-lenovo:hid-microsoft:hid_multitouch:jbd2:mbcache:ext4 -u -o /boot/initrd.gz
(this will generate this command to build a initrd.gz image, run this)
(it also, of course, creates '/boot/initrd.gz' with your def modules)
# vim /etc/lilo.conf # or your grub. i dont use this
(put your initrd image here and choice a vmlinuz-generic as default image)

Your lilo.conf should now look like this (tip: create another entry with old kernel, so if this fail to boot you can boot with the older)

image = /boot/vmlinuz-generic  # re-check if you use vmlinuz
 root = /dev/sda1              # change if not your root disk
 initrd = /boot/initrd.gz
 label = Slack64-Generic
image = /boot/vmlinuz-backup
 root = /dev/sda1
 label = Slack64-Okay

Then save your MBR and reboot your system!

# lilo -v  (check this with attention)
# reboot

And welcome to the -current version of Slackware, keep it upgraded 🙂

Dona Fernanda resolveu casar-se com Carlos, o padre porém disse que os noivos não poderiam escolher a data de casamento devido a grande quantidade de solicitações na igreja. Vários noivos também estavam ansiosos para saber quando poderiam se casar naquela linda igreja, para dizer a cada casal o dia exato em que eles poderiam se casar o padre solicitou que eles fornecessem de 1 até 5 dias no mês de sua preferência e desenvolveu um algoritmo que ajudaria a resolver este impasse de forma aleatória e justa agora e no futuro, ele definiu:

  • T – quantidade de casamentos na fila
  • M – mês do casamento
  • N – quantidade de dias do mês disponível
  • Vx – Valor do dia na posição X (V1, V2, V3…)


N V1 V2 V3 … Vx

Cada linha corresponde a uma entrada do casal, então se T for igual 10, existiriam 10 casais para casar na igreja em determinado mês, e por consequência, haveriam 10 linhas de entrada informando os dias preferidos do casal.


5 2 7 5 8 14
5 2 4 14 8 15
1 4
3 2 7 9


T > 0 && T <= 20
M > 0 && M <= 12
N > 0 && N <= 5
V > 0 && V < 32 

  • O dia a ser escolhido deve ser o menor do grupo
  • Caso um casal tenha selecionado um dia já escolhido por outro ele ficará com o próximo dia possível, se houver (por exemplo, A = 4 = { 1, 3, 4, 6 } se os dias 1, 3 e 4 já tiverem sido escolhidos, o casal poderá tentar o próximo item, o quarto número, o dia 6), mas precisa ser sempre o menor número do grupo.
  • Em caso de não haver outro dia disponível para o casal deverá ser escrito:
    • “O casal número N só pode casar no próximo mês pois já tem um casal nos dias selecionados”

  • Em caso de violação de restrição deverá ser escrito
    • “Padre, foi encontrado uma inconsistência nos dados.”


Padre, são 5 Casamentos em Fevereiro
O casal número 1 ficou de casar no dia 2 de Fevereiro
O casal número 2 ficou de casar no dia 4 de Fevereiro
O casal número 3 só pode casar no próximo mês pois já tem um casal nos dias selecionados
Padre, foi encontrado uma inconsistência nos dados.
O casal número 5 ficou de casar no dia 7 de Fevereiro


“Padre, são 5 casamentos em Fevereiro”
 é o número T de casamentos de entrada e o mês M da entrada

“O casal número 1 ficou de casar no dia 2 de Fevereiro”
é o primeiro casal que tem os dias N = {2, 7, 5, 8, 14} disponíveis e o menor possível é o dia 2 de Fevereiro

“O casal número 2 ficou de casar no dia 4 de Fevereiro”
 é o segundo casal que tem os dias N = {2, 4, 14, 8, 15} disponíveise o menor possível é o dia 4 de Fevereiro

“O casal número 3 só pode casar no próximo mês pois já tem um casal nos dias selecionados”
é o terceiro casal que tem os dias N = {4} disponíveis mas como já existia um casal com o dia 4, não é possível realizar o casamento

“Padre, foi encontrado uma inconsistência nos dados do casal 4.  :(”
é a mensagem de erro em caso de violação de restrição

“O casal número 5 ficou de casar no dia 7 de Fevereiro”
é o quinto casal que tem os dias N = {2 7 9} disponíveis e o menor possível é o dia 7 de Fevereiro


Gerador de testes aleatórios válidos

bash$ ( T=$(( (RANDOM % 20) + 1 )); echo $T; \
for i in `seq 1 $T`; \
do N=$(( (RANDOM % 5) + 1 )) ; echo -n "$N "; \
for x in `seq 1 $N`; do V=$(( (RANDOM % 31) + 1)); echo -n "$V "; done; \
echo; done; echo $(( (RANDOM % 12) +1 )) )

Teste #01

5 21 26 4 1 15 
5 19 11 7 16 17 
1 28 
4 29 6 21 25 
1 11 

Teste #02

3 28 26 7 
2 29 16 
3 8 14 15 

Teste #03

3 17 31 16 
1 15 
1 7 
4 31 30 12 1 
2 20 27 

Teste #04

1 21 
3 23 24 5 
5 15 11 19 28 8 
5 11 9 16 16 5 
1 4 
1 4 
4 4 8 7 26 
4 23 12 11 28 
1 7 
2 28 27 
3 27 13 31 
3 30 29 11 
5 2 5 10 20 14 
5 4 16 5 17 25 
2 3 20 
2 17 2 
5 19 21 2 24 25 
5 16 8 18 23 28 

Teste #05

5 7 19 30 2 22 
3 8 23 30 
5 25 4 16 17 31 
3 18 31 14 
3 6 3 19 
2 20 1 
2 27 22 
2 16 19 
4 9 28 18 21 
2 10 20 
2 29 9 

Quer ver a minha versão com entradas e saídas funcionando??

Conseguiu resolver? Poste suas respostas nos comentários! Quer saber a solução? Entre em contato comigo ou procure na lista de Shell-Script a thread “Desafio Shell-Script #001 do Mulato” 😉

%d blogueiros gostam disto: