Search This Blog

Saturday, 29 November 2014

Inter-process Communication for the Half-Initiated (Perl biased)

Communication is, ultimately, about sending and receiving messages. People communicate using messages, so do devices/hardware and applications/software.

An application is a dead beetle unless it's alive when running. A process is a running instance of an application. (For our purposes, I shall be using the words application and process interchangeably.)  For processes to be able to communicate, there needs to be a point through which processes can reach to one another. Similar to an open door through which somebody can come and ask/inform/demand something.

This endpoint is called a socket, which is bound to (associated with) a port (a software construct, whose purpose is to uniquely identify different applications running on a single computer). The Operating System provides an API (Application Programming interface) - an established way, processes can use to manipulate the sockets, ie use them for communication.

There are two types of sockets; one used for local inter-process communication within an Operating System/a single machine (Unix domain socket); the other is Network socket, used for communication of applications distributed over a network. Network sockets are particularly of interest to us. They are uniquely described by :
  1. a combination of local IP address and a port number
  2. Protocol (TCP (reliable, connection oriented)/UDP (unreliable, connectionless, faster)
  3. remote IP address and remote port number (only for established TCP sockets: one local TCP socket can be used by multiple remote TCP clients, each with its own IP address and port)
Processes can use different ways how to communicate with each other. One decisive factor is whether the two processes, that need to talk or share data, run locally, ie on the same machine, or whether they are remote, ie distributed over different machines.
 
Processes running on the same machine can communicate through:
  • files
  • pipes
  • signals
  • locally shared memory
  • local database
on top of methods used by

Processes running on distributed machines:
  • remote database
  • memcachedb
  • memcached
  • web services
  • memory queues

File

use CHI;
my $cache = CHI->new( driver   => 'BerkeleyDB',
                      root_dir => '/path/to/cache'

 

Memory based 


use CHI;
my $cache = CHI->new(
    driver => 'SharedMem',
    size   => 10 * 1024,
    shmkey => 'UniqueNamespace', # This namespace will be used by processes
                                 # wanting to communicate. All caches 
                                 # (in different processes) with this shmkey 
                                 # will be shared
);  

Database

Multiple processes access the database to perform read/create/update/delete (CRUD operations). Database engines allow table or row locking to prevent inconsistencies and corruption of data.

 

memcachedb

Distributed database storage.


memcached 

Distributed memory caching. From application's perpective, the same as in-process memory caching. The difference compared to in-process memory caching is, that memcached will decide on which of the memcached servers to store the value and will know from where to retrieve it later.

 

my $cache = CHI->new( driver  => 'Memcached::libmemcached',
                      servers => [ "192.168.1.150:11211",
                                   "192.168.1.150:11212",
                                   "192.168.1.151:11211", 
                                   "192.168.1.151:11212",],
                      l1_cache => { driver   => 'FastMmap'
                                    root_dir => '/path/to/cache' }
);

 

Web services

  • RPC (Remote Procedure Call)
              allows to call a method implemented in an application
              running on a remote system. RPC protocol can use either
              XML or JSON format for data transfer and uses HTTP as its
              data transport mechanism (lets applications use HTTP to
              make connection, but uses its own RPC protocol to interpret
              the request and the response). A request is sent to a
              server/application implementing the XML-RPC protocol.

  • REST (Representational State Transfer)
               an architectural approach, rather than a protocol,
               a prescribed way of implementation. REST uses the 
               HTTP design instead of inventing a new mechanism.
               In the RESTful world, all revolves around resources (URI/URL), 
               and their recovery and changes : read, created, updated, deleted (CRUD).


Examples of RPC and RESTful requests:

Information is stored about servers in datacentres. A remote application needs to know which servers are currently in use in the US datacentres.

RPC: 
<?xml version="1.0"?>
<methodCall>
  <methodName>get_active_servers</methodName>
  <params>
    <param>
        <value><country>3</country></value>
    </param>
  </params>
</methodCall>
REST:
https://hostname/country/3/server/active/1 (sent with HTTP GET method)
Example: RPC implementation using RabbitMQ

  • SOAP - mentioned for completeness

 

 Message queue (MQ)

Messaging systems are built to asynchronously connect multiple systems, by passing messages between them. (Messaging Anti-Patterns: Part 1). 
Message queues are software components providing asynchronous communication between applications. Applications using the concept of memory queues, need to adhere to one of the message queue protocols, ie need to use a common "language" to understand each other. Some of the most common ones are AMQP (Advanced Message Queue Protocol), STOMP (Streaming Text Oriented Message Protocol), MQTT (Message Queue Telemetry Transport), Web Socket Protocol and WAMP (Web Application Messaging Protocol).

Protocols:

 

AMQP

                 Main features are reliability and interoperability. Offers a wide range of features related to messaging, including reliable queuing, topic-based publish-and-subscribe messaging, flexible routing, transactions, and security.

 

STOMP

                text-based, does not work with queues and topics,  ie does not provide a firm base for interchange

 

MQTT

               provides publish-and-subscribe messaging (no concept of queues despite the name). It was specially designed for resource-constrained devices and low bandwidth. MQTT’s strengths are simplicity (offers only five API methods) and a compact binary packet payload. These make it suitable for connecting devices like Arduino to a web service with MQTT etc.

 

Web Socket

              overcomes limitations of HTTP's design based on one-directional communication. Web Socket Protocol is used by applications requiring  bidirectional, real-time communication. 

 

WAMP

              is a subprotocol, built on top of the Web Socket Protocol. A common protocol for Publish/Subscribe and RPC communication methods (design patterns).


MQ protocols provide a common standard for applications, that want to use this type of communication.  There are different messaging types/design patterns, some of which need or can take advantage of a middle man (called middleware), that has full responsibility for queues: creates them, routes messages to them, handles failures, sends messages to requesters and more.

Examples:

RabbitMQ (message broker/middleware, based on AMQP.)

Example: RPC client/server implementation using RabbitMQ

Fibonacci - using RPC RabbitMQ based server and client - Perl implementation

The implementation presented here, was inspired by rabbitmq-tutorials.

The fibonacci subroutine, in the server code, uses caching to speed up calculations for higher numbers.
The client script sends its requests in a parallelized manner.

The dependencies are:

    Getopt::Long
    Parallel::ForkManager
    AnyEvent
    UUID::Tiny
    Net::RabbitFoot
    Data::Printer         (can be replaced by Data::Dumper)


The scripts are heavily documented to help understand all steps.

RPC Server

#!/usr/bin/perl

=head1 RPC server using RabbitMQ to provide fibonacci series calculation

=cut

use strict;
use warnings;
use v5.010;

$|++;
use AnyEvent;
use Net::RabbitFoot;

use Data::Printer;

# Declare subroutines
# -------------------
sub fib;
sub on_request;

# We shall be caching intermediate results of the recursive fib subroutine
# ------------------------------------------------------------------------
# (if we don't, calculations take an enormous amount of time for higher numbers)

my $cached = {};

# Connection to the RabbitMQ daemon
# ---------------------------------
# (in this case on the same server, the localhost)

my $conn = Net::RabbitFoot->new()->load_xml_spec()->connect(
    host  => 'localhost',
    port  =>  5672,
    user  => 'guest',
    pass  => 'guest',
    vhost => '/',
);

# Create a RabbitMQ communication channel
# ---------------------------------------

my $channel = $conn->open_channel();

# Declare which queue we shall be offering the service on
# -------------------------------------------------------
# (will provide the fibonaci series result. If we don't get any input,
#  then the result will be calculated for n=30 )

$channel->declare_queue(queue => 'rpc_queue');

# Do the calculations, when a request comes
# -----------------------------------------
# (sent to the 'rpc_queue' queue) 

$channel->consume(
    on_consume => \&on_request,
);

print " [x] Awaiting RPC requests\n";

# Wait forever
# ------------
AnyEvent->condvar->recv;

# ---------------------------------- SUBROUTINES ----------------------------------

sub fib {
    my ($n, $padding) = @_
 
    # I used the padding to show the intermediate
    # recursive calculations during development. 
    $padding //= "";

    if ($n == 0 || $n == 1) {
        return $n;
    } else {
        my $n1 = $n-1;
        my $n2 = $n-2;

        $cached->{$n1} //=  fib($n1, "$padding  (-1)");
        $cached->{$n2} //=  fib($n2, "$padding  (-2)");
   
        return $cached->{$n1} + $cached->{$n2};
    }
}

sub on_request {
    my $var   = shift;                      # hashref with Net::AMQP header and 
                                            # body info
    my $body  = $var->{body}->{payload};    # the number for which the fibonacci
                                            # calculation is requested
    my $props = $var->{header};             # has correlation_id and reply_to queue
                                            # details


    my $n = $body;
    print " [.] fib($n)\n";

    my $response = fib($n);

    # publish/send the calculation to the client's queue
    $channel->publish(
        exchange    => '',
        routing_key => $props->{reply_to},
        header      => {
            correlation_id => $props->{correlation_id},
        },
        body => $response,
    );

    $channel->ack();                        # acknoledgement that the calculation  
                                            # was sent, so the message/calculation
                                            # can be deleted from memory
} 

RPC Client

#!/usr/bin/perl

use strict;
use warnings;
use v5.010;

$|++;

use Getopt::Long;
use Parallel::ForkManager;

use AnyEvent;
use UUID::Tiny;
use Net::RabbitFoot;

use Data::Printer;

# Process the command input and setup the default
# for fibonacci processing, if no input provided
# -----------------------------------------------
GetOptions( 
    "numbers|n=s"  => \@nums,
    "help|h"        => sub { say "perl $0 [numbers|n ]" },
);
@nums = (scalar @nums) ? split(/,/,join(',',@nums)) : qw(50 30 20 10 5);

# Declare subroutines
# -------------------

sub fibonacci($);

# -----------------------------------------------
#
# Send parallelized requests to the RPC server
# --------------------------------------------

my $pm = Parallel::ForkManager->new(10);

# 1) set up data structure retrieval and handling
# -----------------------------------------------

$pm->run_on_finish( 
    sub {
      my ($pid, 
          $exit_code, $ident, $exit_signal, $core_dump, 
          $all_child_data_ref) = @_;

      if (defined $all_child_data_ref) {
        p $all_child_data_ref;
      }
      else {
        print qq|No message received from child process $pid!\n|;
      }
    }
);

# 2) send the RPC requests
# ------------------------

FIB_LOOP:
foreach my $num (@nums) {
    my $pid = $pm->start and next FIB_LOOP;
    # ----- start child process

    print " [x] Requesting fib($num)\n";
    my $response  = fibonacci($num);

    # ----- end of child process
    $pm->finish(0, { $num => $response });
}

$pm->wait_all_children;

say "[END] - all children finished";

# ---------------------------------- SUBROUTINES ---------------------------------- 

# The main subroutine for the RPC (asynchronous) request
# ------------------------------------------------------

sub fibonacci($) {
    my $n = shift;

    # set up condition variable to watch for an event (when we receive
    # a result we asked for)
    my $cv = AnyEvent->condvar;

    # create a unique id for our request to the RPC server  
    my $corr_id = UUID::Tiny::create_UUID_as_string(UUID::Tiny::UUID_V4);

    # connect to the RabbitMQ deamon
    # (in this case on the same server, the localhost)
    my $conn = Net::RabbitFoot->new()->load_xml_spec()->connect(
        host  => 'localhost',
        port  =>  5672,
        user  => 'guest',
        pass  => 'guest',
        vhost => '/',
    );

    my $channel = $conn->open_channel();

    # after we disconnect, queue will be deleted
    my $result          = $channel->declare_queue(exclusive => 1);
    my $callback_queue  = $result->{method_frame}->{queue};

    my $on_response = sub {
        my $var     = shift;
        my $body    = $var->{body}->{payload};
        if ($corr_id eq $var->{header}->{correlation_id}) {
            $cv->send($body);
        }
    };

    # callback to execute after the response from the RPC server comes back
    $channel->consume(
        no_ack      => 1,               # turning off message acknowledgment: 
                                        #     we shall not notify the server
        on_consume  => $on_response,    # receives the server response, then 
                                        #     makes the condition variable
                                        #     true, which stops the event loop
    );

    # send the request for the fibonacci calculation to the RPC server
    $channel->publish(
        exchange    => '',
        routing_key => 'rpc_queue',     # to which queue on the server we are
                                        # sending the request 
                                        # (ie the number for which we want the
                                           fibonacci value)
        header      => {
            reply_to        => $callback_queue,     # our queue to which the server
                                                    #      will send its response
            correlation_id  => $corr_id,            # identifier of our request
        },
        body => $n,                     # the number, for which we want the fibonacci
                                        # value calculated
    );

    return $cv->recv;                   # callback->recv blocks until callback->send
                                        # is used
                                        # returns whatever data callback->send 
                                        # supplies 
}

Friday, 28 November 2014

Secure HTTP (HTTPS) conection for the Half-Initiated : SSL/TLS

The goal

I am a client application and want to talk to you, the server application, privately, with nobody eavesdropping or tampering with my messages. I also want to know that you, server, are who you claim to be, because I want to do some serious business with you.

The situation

You and I are using a common language, HTTP (protocol, ie a standard how we talk to each other, what we need to do etc) that we need to follow. As our communication travels over the internet, it can be intercepted, listened to. To prevent this, we need a secure and authenticated channel of communication. Enter SSL/TLS cryptographic protocols: Secure Sockets Layer/Transport Layer Security. These two provide the same, TLS being a newer, safer version. As old habits die hard, many people use SSL to mean any of the two.

SSL/TLS cryptographic protocols

SSL/TLS protocols, being more general, are used as a wrapper around the HTTP (or other Application Layer protocols like FTP, SMTP, XMPP etc). The protocols are based on the X.509 standard. The corresponding PKI - Public Key Infrastructure, a framework for secure communication (based on the standard) - collection of hardware, software, policies and procedures - allows the following to happen:
  1. We shall end up in a secure communication channel where everything, including URLs, HTTP headers and POST data is encrypted. Our communication will be safe from prying eyes and devious minds.
  2. Your identity was verified by a trusted party, so I shall know that you really are you and, if required, you know know I am I. I can trust you.

Public key cryptography

The protocols are based on public key cryptography. Public key cryptography is called asymmetric, because one party (one application) has a pair of keys (essentially two long nonsensical strings), a private one and a public one, and the other party(ies) (application(s) eg browser(s)) is given the mentioned public key.

The public key is used to:
  • encrypt data
  • verify authenticity of the data
The private key is used to:
  • decrypt the encrypted data
  • offer proof of authenticity (of both the data and the data sender) by using this key and the data to be sent to create a digital signature
  • it is important that the private key is kept truly private and never disclosed. 
(In symmetric cryptography both parties share a private key. This key is used for all of the functions mentioned above, hence the word 'symmetric'.)

The public and private keys are mathematically related and have the following properties:
  1. There is 1-to-1 relationship between them, ie one private key is associated with just one public key and vice versa.
  2. The private key cannot be reverse-engineered from the private key

Authenticity

The basis for establishing trust between applications are digital certificates, documents providing all the relevant information for confirming validity of the data and the sender. They contain:
  1. public key
  2. meta data (company info, expiry date, which DNS domains the certificate covers)
  3. trusted CA (Certificate Authority) signature that 1) and 2) are correct
Certificate Authority (CA) is an entity issuing digital certificates, a third party, trusted by those wanting to establish a secure connection. A company can decide which root CAs (the very top ones have a self-signed certificate) they will use. (The browser development team will, for instance, include their chosen CAs in the binary.) Top CAs can create other, intermediate CAs in a chain of trust.

How it works

Obtaining private and public keys and the certificate

  1. Owner of an application creates the key pair
  2. Owner sends a Certificate Signing Request (CSR, a digital file) to a CA, containing:
    1. Public key
    2. Information to identify the owner (fully qualified domains that the owner wants secured, organization name, email, address etc)
  3. Owner obtains the certificate from the CA (signed CSR)
  4. He distributes the certificate to other parties
    1. Root CA certificates are distributed by some type of bootstrapping: browsers come with root certificates, modern operating systems come with root certificates etc

Secure communication - SSL handshake

  1. Browser connects to a website, ie web server, secured with SSL (the URL contains https). Browser requests that the server identify itself
  2. Server sends over a copy of its SSL Certificate. The certificate includes its public key.
  3. Browser checks the certificate root against a list of trusted CAs the validity of the certificate (expired?, revoked?) and also, that its common name is valid for the website that it is connecting to. If the browser is satisfied about the certificate authenticity, it creates and encrypts a symmetric session key using the server’s public key. It send it over to the web server.
  4. Server decrypts the symmetric session key (using its private key). Sends back an acknowledgement encrypted with the session key to start the encrypted session.
  5. From now on, the Server and the Browser encrypt all transmitted data with the session key

The impact of SSL/TLS

Opening a TCP connection for HTTP uses a three-way (3 packet) handshake. The prerequisite is that the server is listening on a port, so clients can bind to it and start a communication. This handshake involves:
  1. client opening a socket
  2. client sending SYN package
  3. server sending back SYN/ACK package
  4. client responding with ACK package
When both the client (phases 2 and 3 ) and server (phases 3 and 4) have received an acknowledgement, the interchange of data can start.

Establishing an SSL/TLS connection happens on top of the three-way TCP connection. After the TCP/HTTP connection is in place, the client requests are forwarded to the SSL/TLS port where the rules of the SSL/TLS protocol are followed. The SSL handshake involves verifying server authenticity etc, after which decrypting and encrypting of transmitted information happens.

https://realtimelogic.com/images/HTTPS-scalability-prob/client-server-handshake.jpg

https://realtimelogic.com/images/HTTPS-scalability-prob/client-server-handshake.jpg

To avoid performing a handshake for each request, an HTTP persistent connection (HTTP keep-alive) can be taken advantage. This is a way of reusing a single TCP connection for multiple requests/responses. This is particularly relevant for SSL/TLS connections (more CPU and network trips needed during the connection startup). All modern browsers implement
HTTP keep-alive.

SSL connection means, that everything sent, headers, urls, images etc, is encrypted. Encryption means number crunching, therefore higher consumption of resources (CPU). The need for resources depends on the cipher (the algorithm used for encryption and decryption), certificate key lengths, type and size of sent data, volume of requests. As a result, a web server serving SSL encrypted traffic, will experience higher load. This can be helped by delegating dealing with SSL to a reverse proxy, where the SSL traffic is terminated and the request is sent further unencrypted to one of the web application servers. The reverse is true for the HTTP response being returned. The load on the web application servers is reduced, however, the users are still affected by the increase of the page load time due to the encryption being performed.

Tuesday, 25 November 2014

Ubuntu Tips & Tricks - WIP

Audio

  • Ubuntu 14.04 does not contain the ffmpeg package any more. Its replacement is libav-tools package. In software, that expects ffmpeg to be able to deal with mp3 format, references to /usr/bin/ffmpeg should be replaced with /usr/bin/avconv.

Perl Packages

  • Ubuntu 14.04 contains an obsolete Mojolicious version:
 perl -MMojolicious -e 'print Mojolicious->VERSION. "\n"'

    gives 4.63

This version, when using $c->delay, produces error:

 Can't locate object method "delay" via package "Mojolicious::Controller" at ...

  The latest one at the time of writing is 5.69.
  Installing the latest Mojolicious version fixes the problem:
  sudo cpanp install Mojolicious

Installation of the latest Go language version

  • bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)
  • add the following line to  ~/.bashrc:   
                   [[ -s "$HOME/.gvm/scripts/gvm" ]] && source "$HOME/.gvm/scripts/gvm"
  • cd; . ./.bashrc
  • gvm version
  • gvm install go1.4
  • gvm use go1.4
  • go version
  • check if  /usr/local/bin/go exists and what it points to
                    sudo ln -s ~/.gvm/gos/go1.4/bin/go  /usr/local/bin/go




Sunday, 23 November 2014

Running One Instance of a Process (Perl implementations)

1) Locking through PID file


use strict;
use warnings;
use utf8;
use v5.10;
use Carp;

# prevent sending of the 'stop' signal to this process,
# if the terminal, from which the script is run, is disconnected
$SIG{HUP} = 'IGNORE';
 
my $lock_file = "$0.lock"; 
 
exit 0 if -e $lock_file;

open my $fhl, '>', $lock_file or die "Cannot proceed: $!";
close $fhl;

# Remove the lock file if the process ended abnormally
for my $signal (qw(INT KILL TERM __DIE__)) {
    $SIG{$signal} = \&sig_handler;
}

while (1) { 
    sleep 13; 
    unlink $lock_file or croak "Cannot delete $lock_file: $!" if -e $lock_file; 
    exit (0);
}

# ------------------- SUBROUTINES ----------------------

sub sig_handler {
    say "\t>>> deleting $lock_file";
    unlink $lock_file or croak "Cannot delete $lock_file: $!";
}

2) Locking the process

a) 
use strict;
use warnings;
use utf8;
use Carp;
use Fcntl ':flock'; 

BEGIN { 
open my $process, '<', $0 or die "Cannot start process $0: $!" ;
    flock $process, LOCK_EX|LOCK_NB or croak "Cannot lock $0, already running  - $!";
} 

while (1) {}

b)

use strict;
use warnings;
use utf8;
use Fcntl ':flock';

BEGIN {
    open  *{0}  or die "Cannot start process $0: $!";
    flock *{0}, LOCK_EX|LOCK_NB or die "Cannot lock $0, already running - $!";
}
 
while (1) {}

c)

use strict;
use warnings;
use utf8;
use Fcntl ':flock';
 
flock DATA, LOCK_EX|LOCK_NB or die "Cannot lock $0- $!";
 
while (1) {}
 
__DATA__

Saturday, 22 November 2014

Arduino LEDs related Tips & Tricks

  •  If a LED (identified as ledPin in the Arduino sketch) does not shine after it is activated by

                     pinMode(ledPin, OUTPUT); 
                     writeDigital(ledPin, HIGH)              
                
                 check the LED is correctly wired:
                           LE ... Light Emitting
                           D ..... Diode

                  In diode, the electric current flows through the bulb in one direction, from plus/+ to minus/-.  The LED has two wires. The long one, called anode, has a positive charge, the shorter wire, cathode, a negative one. We need to use resistors with LEDs. These components provide resistance to the electric current, therefore protecting the bulb. Resistence to the electricity flow is measured in ohms (Ω). As the current flows from + to - in a diode, the resistor must be positioned between Arduino and the LED's longer wire.

 http://www.digikey.com/~/media/Images/Marketing/Resources/Calculators/resistor-color-chart.jpg?la=en-GB

Calculating resistence of a resistor:

The last stripe on the right gives the tolerance (error range), the second from the right provides the amount of Ohm units, by which we need to multiple the number we assembled from the rest of the stripes, to give the resistance value. To find this number, we go from the left of the resistor and find the values corresponding to the rest of the stripes (all but the last two), which we just string together:

For the bottom example:
  1. red ......... first band      => digit 2
  2. orange ... second band => digit 3
  3. violet ..... third band     => digit 7
  4. black ..... Ohm multiplier  :  1Ω
  5. brown .... error tolerance :  +- 1%
therefore 237 * 1Ω = 237 Ω, +-1%

The cathode is connected to the Arduino GRD.

  • If a LED does not shine as strongly as it should, see if the corresponding line

                      pinMode(ledPin, OUTPUT);       

                 is present in the sketch

  • An example of a sketch using two LEDs and a liquid crystal display (LCD 16x2) to show a stream of messages

#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8,9,4,5,6,7);

unsigned char ledPin=1;
unsigned char ledPin2=2;

unsigned char j=0;

char *messages[4] = {
    "Hello child",  
    "Hello husband",  
    "Hello family",  
    "Hello World",  
};

void setup() {
    pinMode(ledPin, OUTPUT);
    pinMode(ledPin2, OUTPUT);

    digitalWrite(ledPin, LOW);
    digitalWrite(ledPin2, LOW);
    digitalWrite(ledPin, HIGH);

    lcd.begin(16,2);

    lcd.setCursor(0,0);
    lcd.print("*** Saying hello");

    lcd.setCursor(0,1);
    lcd.print("from Tamara");

    delay(2000);
}

void loop() {
    unsigned char i;

    if (j>1) { j=0; }
    
    if (j==1) {
        digitalWrite(ledPin, HIGH);
        digitalWrite(ledPin2, LOW);
    } else {
        digitalWrite(ledPin2, HIGH);
        digitalWrite(ledPin, LOW);
    }

    for (i=0;i<4;i++) {
        lcd.clear();
        lcd.begin(16,2);

        lcd.setCursor(0,0);
        lcd.print(messages[i]);

        lcd.setCursor(0,1);
        lcd.print("from Tamara");

        delay(1000);
    }

    lcd.clear();
    
    delay(1000);
    j++;
}

Connecting the LCD 16x2 to Arduino (without potentiometer)

www.fibidi.com

 

The result will be:


It is not be very clear in the video, but whenever each of the LEDs becomes lit up, the four messages:

    "Hello child",  
    "Hello husband",  
    "Hello family",  
    "Hello World"

are displayed in succession, with a second of a pause in between. After the last message, the lights swap, and the messages are shown again, one after another.

Sunday, 16 November 2014

Managing ssh keys for multiple GitHub accounts

  1. Create ssh keys using the following command:
    ssh-keygen -t rsa -C "xxx@youremail.com"
    ssh-keygen -t rsa -C "yyy@youremail.com"
    
    
    Each email corresponds to a different github account. 
    It is also possible to have repository specific deploy keys.
    If a repository does not have its own deploy key, access to it 
    is given by the repo's github account ssh keys. 
  2.  Two pairs of ssh keys are created in ~/.ssh dir:
    1. ~/.ssh/id_rsa_xxx
      ~/.ssh/id_rsa_yyy
      with names chosen in step 1.
  3. Add keys using:
    1.   ssh-add ~/.ssh/id_rsa_xxx
       ssh-add ~/.ssh/id_rsa_yyy
      This adds adds your RSA identities to the authentication agent,  
      ssh-agent, a program for storing private keys used for public key 
      authentication.
  4.  Use ssh-add -l to list all added keys
  5. Associate the keys with the Github accounts according to instructions on:
    1.  https://help.github.com/articles/generating-ssh-keys/
  6. On your local machine configure GitHub settings. Add configuration to ~/.ssh/config:
    1. #xxx account
      Host github.com-xxx
          HostName github.com 
          User git
          IdentityFile ~/.ssh/id_rsa_xxx
      
      #yyy account
      Host github.com-yyy
          HostName github.com
          User git 
          IdentityFile ~/.ssh/id_rsa_yyy
      Hosts github.com-xxx, github.com-yyy are arbitrary names,
      that help distinguish the two accounts 
  7.  Test authorization to connect to GitHub:
    1. ssh -T git@github.com-xxx
    2. ssh -T git@github.com-yyy
  8. Clone a repository, using the relevant Host alias:
    1. git clone git@github.com-xxx:xxx/repo_aaa.git [aaa_dir]
  9.  The general git configuration can be found in ~/.gitconfig. The entries can be either added manually or through git commands:
    1.  git config --global ... (user.email, user.name etc)
  10.  For repository specific configuration (repository's .git/config): 
    1. cd repo_aaa (or aaa_dir)
    2. git config user.name "X XXX
    3. git config user.email "xxx@gmail.com"
    4. git remote set-url origin  git@github.com-xxx:xxx/repo_aaa.git
      1. This will result in the following setup:
        [remote "origin"]
                url = git@github.com-xxx:xxx/repo_aaa.git
        where
        github.com-xxx corresponds to the Host value in step 6
        xxx            corresponds to the github username 

NOTE

  • Configuration, that is present only in the global git config file ~/.gitconfig (setup either through the git config --global comand or manually) and not overriden by cloned repository's .git/config setup, will be used.
  • Setting up the [remote "origin"] block in the global configuration, results in a bizarre situation, where one can be cloning an empty (well, any) github repo, and the local clone will have an unexpected content (corresponding to the remote origin url, ie a different repo).