<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>NotANumber &#187; Engineering</title>
	<atom:link href="http://www.pedro.kiefer.com.br/category/engineering/feed" rel="self" type="application/rss+xml" />
	<link>http://www.pedro.kiefer.com.br</link>
	<description>Rambles of an Engineer</description>
	<lastBuildDate>Sun, 15 Jan 2012 15:33:16 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Asterisk, OpenVPN and QoS</title>
		<link>http://www.pedro.kiefer.com.br/2011/09/asterisk-openvpn-and-qos</link>
		<comments>http://www.pedro.kiefer.com.br/2011/09/asterisk-openvpn-and-qos#comments</comments>
		<pubDate>Wed, 28 Sep 2011 14:00:39 +0000</pubDate>
		<dc:creator>Pedro Kiefer</dc:creator>
				<category><![CDATA[Engineering]]></category>
		<category><![CDATA[Infraestrutura]]></category>
		<category><![CDATA[Servers]]></category>
		<category><![CDATA[Asterisk]]></category>
		<category><![CDATA[iax2]]></category>
		<category><![CDATA[openvpn]]></category>
		<category><![CDATA[qos]]></category>
		<category><![CDATA[voip]]></category>

		<guid isPermaLink="false">http://www.pedro.kiefer.com.br/?p=337</guid>
		<description><![CDATA[Installing a VoIP system is nowadays an easy task, just install Asterisk, have a few SIP clients and you have an &#8216;instant&#8217; telephone system. But your system will not be as reliable as the one offered by any telecom company. Why? Quality of Service, or for short, QoS. Telecom companies use sophisticated hierarchies of systems [...]]]></description>
			<content:encoded><![CDATA[<p>Installing a VoIP system is nowadays an easy task, just install Asterisk, have a few SIP clients and you have an &#8216;instant&#8217; telephone system. But your system will not be as reliable as the one offered by any telecom company. Why? Quality of Service, or for short, QoS. </p>
<p>Telecom companies use sophisticated hierarchies of systems to deliver the needed QoS. Backbones uses SDH systems, where one can guarantee the bandwidth and throughput for any kind of data. So if you specify that a voice packet should be delivered in 10ms, it will get delivered in that time span. Now when it comes to IP networks, you have no guarantee that your packet will be delivered in that time frame, which is a good thing when you&#8217;re downloading files, opening web pages, and so on. But when it comes to voice and video streaming, it&#8217;s a real mess. So you must create some QoS rules for your packets.</p>
<p>Asterisk has this real nice feature for aggregating multiple servers so that it works as a single phone network. The only problem is that this feature is not really secure, so as to mitigate that, one can always create VPN&#8217;s (Virtual Private Networks). But how does that impact your QoS solution? Well, depends on what kind, or how you configure your VPN, with OpenVPN it&#8217;s quite simple.</p>
<p>Just as a reminder, for the rest of the article when I say QoS, I really mean the QoS of the gateway of your network. The gateway is the one place that will enforce the needed quality of service (okay, on bigger networks you will have multiple routers which will need to be configured for QoS too).</p>
<p>Don&#8217;t get too excited with QoS, even though you did everything by the book that doesn&#8217;t mean that your ISP will use TOS field the same way you did. By that I mean, you won&#8217;t solve any problem with QoS if the problem is not on how you route packets to the internet. If you have full control of your link and all the router in between your networks, you&#8217;re a lucky guy!</p>
<h2>The Network</h2>
<p>We have some computers, servers, and IP phones on each network. The OpenVPN tunnel server doesn&#8217;t need to be the same as the gateway, as long as you export the correct ports to that server. Make sure you also add the correct gateway for the packets that should be tunneled (ie. packets for the network 10.2.1.0 that originates on the 10.1.1.0 network). On the image, the tunnel is represented by the red lines. </p>
<div id="attachment_360" class="wp-caption aligncenter" style="width: 725px"><a href="http://www.pedro.kiefer.com.br/wp-content/uploads/2011/09/sample_network.png" class="tt-flickr tt-flickr-Medium"><img src="http://www.pedro.kiefer.com.br/wp-content/uploads/2011/09/sample_network.png" alt="" title="Sample Network" width="715" height="196" class="size-full" /></a><p class="wp-caption-text">A sample network using Asterisk and OpenVPN</p></div>
<h2>OpenVPN</h2>
<p>I don&#8217;t intend to give a full how-to on OpenVPN, just a basic configuration, with a highlight on how to get QoS for the tunneled packets. Besides that, configuring OpenVPN is really simple.</p>
<p>First you have to create your own Certificate Authority (CA). You can use something like <a href="http://tinyca.sm-zone.net/">tinyca</a> or <a href="http://code.google.com/p/minica/">minica</a>, or the command line version, described <a href="https://help.ubuntu.com/community/OpenVPN#Generating_Certificates">here</a>. Remember that you will need one certificate per client. After that is just a matter of writing a really simple text file. Below are a sample configuration, known to work well integrating two Asterisk servers.</p>
<h3>Server</h3>
<pre>
# OpenVPN server
# Listen to local ip address only
local 10.1.1.2

# Should be exported on the router
port 1194
proto udp
dev tun

# SSL/TLS CA and keys
ca ca.crt
cert server.network.crt
key server.network.key

# Diffie Hellman Parameters
dh dh1024.pem

# Server tunnel
server 10.3.1.0 255.255.255.0
ifconfig-pool-persist ipp.txt

push "route 10.1.1.0 255.255.255.0"
route 10.2.1.0 255.255.255.0
client-config-dir client-configs
keepalive 10 120

# Drop privileges
user nobody
group nogroup

# Persist
persist-key
persist-tun

# Logs
verb 5
status /var/log/openvpn.log

# Fork to the background
daemon
</pre>
<h3>Client</h3>
<p>The highlighted line is the one which will make the QoS work for the encrypted packets. If you think that passing the TOS (Type of service) is a security fault, don&#8217;t panic, just create another tunnel for passing your sensitive data &#8211; and that&#8217;s really easy to do with OpenVPN.</p>
<pre>
# OpenVPN client
client

# Interface for tunnel
# Protocol and Port
dev tun0
proto udp
port 1194

# SSL/TLS CA and keys
ca /etc/openvpn/certs/ca.crt
cert /etc/openvpn/certs/remote1.mynetwork.crt
key /etc/openvpn/keys/remote1.mynetwork.key

# Symmetric cipher
cipher BF-CBC

# Remote server to connect to. Can be domain name or IP address.
remote remote1.mynetwork.com

# Check if the tunnel went down and restart it.
# 10 is the ping interval number and 120 is the timeout to restart.
keepalive 10 120
route 10.1.1.0 255.255.255.0

<b># This is need so we can apply QoS to the tunnel
passtos</b>

# Drop privileges
user nobody
group nogroup

# Use a persistent key and tunnel interface.
persist-tun
persist-key

# Log to file instead of syslog
log-append /var/log/openvpn.log
verb 4

# Fork to the background
daemon
</pre>
<p>If you can ping the remote server, using the internal IP address, then your tunnel is up and running.</p>
<h2>Asterisk</h2>
<p>I suppose that you already know how to configure an Asterisk server, if you don&#8217;t you can follow my <a href="/2011/02/asterisk-and-freepbx-on-ubuntu-server-10-10">guide</a> (it&#8217;s a bit outdated, I might update it soon).</p>
<p>Getting IAX2 working is really simple too, so I won&#8217;t describe it. If you&#8217;re using FreePBX, you can follow this <a href="http://www.cadvision.com/blanchas/Asterisk/IAX2Trunk.html">guide</a>. Remember to use the internal IP&#8217;s from your network.</p>
<p>Make sure your asterisk installation is tagging the correct TOS for the packets. On my FreePBX install it already had the correct configuration set on <code>/etc/asterisk/sip_general_additional.conf</code>. Check your asterisk configuration for the following lines:</p>
<pre>
tos_sip=cs3
tos_audio=ef
tos_video=af41
</pre>
<p>This tags your voice data as <b>Expedited Forwarding</b>, normal SIP packets get <b>Class Selector 3</b> and video data gets <b>Assured Forwarding, Class 4,</b> with drop precedence 1. More on what all this means shortly.</p>
<h2>QoS</h2>
<p>Getting the right choice of tools for your specific QoS application is a hard problem. You can have some traffic shaping algorithms, congestion avoidance mechanisms and quite a few packet scheduling algorithms. I&#8217;m not an expert on how all these different types of algorithms work, or what is the best solution for your case. I&#8217;m just putting together some information that I think is relevant. One can always read all the RFC&#8217;s about QoS.</p>
<p>First things first, the mentioned TOS field is now called <b>DSCP</b> (Differentiated Services Code Point), it replaces the TOS field and is specified for IPv4 and IPv6 (for reference <a href="http://tools.ietf.org/html/rfc2474">RFC2474</a> is the specification). It tries to maintain backward compatibility with the TOS field. Most networks use the following traffic classes:</p>
<ul>
<li>Default PHB — which is typically best-effort traffic</li>
<li>Expedited Forwarding (EF) PHB — dedicated to low-loss, low-latency traffic</li>
<li>Assured Forwarding (AF) PHB — gives assurance of delivery under prescribed conditions</li>
<li>Class Selector PHBs — which maintain backward compatibility with the IP Precedence field.</li>
</ul>
<p>That is what EF, CS3 and AF41 means, just a common way of signalling that your packet is important, or not that much. But just tagging your packets won&#8217;t get you far. For now, you&#8217;ve got your Asterisk correctly tagging the packets, and your tunnel to preserve them. Time to add the magic to classify and prioritise the packets!</p>
<h3>Linux Traffic Control</h3>
<p>Linux has the <a href="http://linux.die.net/man/8/tc">tc</a> tool for configuring and setting up a QoS policy. With it you can configure different kinds of queueing disciplines and classes. This queues acts directly on net devices, so you have to configure it per device. In the example below we have an ADSL modem on ppp0 device. </p>
<p>TC allows you to configure classful and classless disciples, each one supporting different scheduling algorithms. We will use <b>Hierarchy Token Bucket</b> (HTB) for the classful packets (the ones that got tagged by Asterisk), and <b>Stochastic Fairness Queueing</b> (SFQ) for the classless packets. After getting your queues configured you have to inform <i>iptables</i> that it should use the queue, that&#8217;s basically setting up some CLASSIFY targets. You definitely can add some MARK rules to tag your packets, but we don&#8217;t need it, Asterisk is doing that job for us.</p>
<p>First we will configure what is the maximum bandwidth allowed, in this case we have an 1000kbps uplink that we want to add a QoS policy. The following table illustrates the QoS policy required for the network. As we are using an asymmetric connection, we will limit the upload bandwidth to 95% of the nominal speed. </p>
<table class="fancytable">
<thead>
<tr>
<th>Class</th>
<th>Nominal rate</th>
<th>Maximum rate</th>
<th>Priority</th>
<th>Packets</th>
</tr>
</thead>
<tbody>
<tr>
<td>Real time</td>
<td>47.5kbps</td>
<td>95kbps</td>
<td>0</td>
<td>ICMP, SYN, RST, ACK</td>
</tr>
<tr>
<td>High</td>
<td>522.5kbps</td>
<td>950kbps</td>
<td>1</td>
<td>EF and CS3 packets</td>
</tr>
<tr>
<td>Regular</td>
<td>190kbps</td>
<td>950kbps</td>
<td>2</td>
<td>Regular traffic, HTTP, SSH, etc</td>
</tr>
<tr>
<td>Bulk</td>
<td>190kbps</td>
<td>950kbps</td>
<td>3</td>
<td>&nbsp;</td>
</tr>
</tbody>
<caption>QoS Policy</caption>
</table>
<p>With the queues in place you just have to add the necessary <b>iptable</b> rules. The rules will classify the packets that have the DSCP tag using the same classes that you defined using <b>tc</b>. That&#8217;s it, your QoS is now in place. Just make sure you add and remove the rules according to the status of your link (in this case <i>ppp0</i>). The script bellow is called by <code>/etc/ppp/ip-up.d</code> and <code>/etc/ppp/ip-down.d</code>, with the start and stop targets respectively.</p>
<pre class="brush: bash">
# !/bin/bash
# 20110916 - Leonardo Santos &lt;leonardo at aligera dot com dot br&gt;
# Initial version. It only uses the iptables target CLASSIFY.
# For the QoS to work, Asterisk has to tag the packets with the right DSCP.
# The OpenVPN tunnel must be passing along the DSCP field, and not blanking it out.
#
PATH=$PATH:/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin

# uplink in kbps
UPLINK=1000
DEV=ppp0

CEIL=$(($UPLINK*95/100))

CLASS_RT=&quot;10&quot;
CLASS_HIGH=&quot;11&quot;
CLASS_REG=&quot;12&quot;
CLASS_BULK=&quot;13&quot;

do_iptables() {
        iptables -$1 POSTROUTING -t mangle -p icmp -j CLASSIFY --set-class 1:$CLASS_RT
        iptables -$1 POSTROUTING -t mangle -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j CLASSIFY --set-class 1:$CLASS_RT
        iptables -$1 POSTROUTING -t mangle -p udp -m dscp --dscp-class cs3 -j CLASSIFY --set-class 1:$CLASS_HIGH
        iptables -$1 POSTROUTING -t mangle -p udp -m dscp --dscp-class ef -j CLASSIFY --set-class 1:$CLASS_HIGH
}
add_rules() {
        tc qdisc add dev $DEV root handle 1: htb default $CLASS_BULK
        tc class add dev $DEV parent 1: classid 1:1 htb rate ${CEIL}kbit ceil ${CEIL}kbit
        tc class add dev $DEV parent 1:1 classid 1:$CLASS_RT   htb rate $((1*$CEIL/20))kbit  ceil $(($CEIL/10))kbit prio 0
        tc class add dev $DEV parent 1:1 classid 1:$CLASS_HIGH htb rate $((11*$CEIL/20))kbit ceil ${CEIL}kbit       prio 1
        tc class add dev $DEV parent 1:1 classid 1:$CLASS_REG  htb rate $((4*$CEIL/20))kbit  ceil ${CEIL}kbit       prio 2
        tc class add dev $DEV parent 1:1 classid 1:$CLASS_BULK htb rate $((4*$CEIL/20))kbit  ceil ${CEIL}kbit       prio 3
        tc qdisc add dev $DEV parent 1:$CLASS_HIGH handle 120: sfq perturb 10
        tc qdisc add dev $DEV parent 1:$CLASS_BULK handle 130: sfq perturb 10
        do_iptables A
}
del_rules() {
        tc qdisc del dev $DEV root
        do_iptables D
}
show_status() {
        tc -s -d class show dev $DEV
        tc -s -d qdisc show dev $DEV
}
case $1 in
        start)
                add_rules
        ;;
        stop)
                del_rules
        ;;
        status)
                show_status
        ;;
        restart)
                del_rules
                add_rules
        ;;
        *)
                echo &quot;Usage: $0 {start|stop|restart|status}&quot;
                exit 1
        ;;
esac
</pre>
<p>I would like to thank Leonardo Santos for putting the script together and letting me publish it, and for being a good friend.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pedro.kiefer.com.br/2011/09/asterisk-openvpn-and-qos/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Working with LCD glyphs</title>
		<link>http://www.pedro.kiefer.com.br/2011/05/working-with-lcd-glyphs</link>
		<comments>http://www.pedro.kiefer.com.br/2011/05/working-with-lcd-glyphs#comments</comments>
		<pubDate>Tue, 31 May 2011 17:53:51 +0000</pubDate>
		<dc:creator>Pedro Kiefer</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Engineering]]></category>

		<guid isPermaLink="false">http://www.pedro.kiefer.com.br/?p=334</guid>
		<description><![CDATA[Reading a diff today I found this piece of code for defining a font for a matrix LCD display. The code is interesting, it lets the developer see what the font looks like, so fixing your alphabet is really easy. unsigned char font5x7[][8] = { /* z */ ,{ ________, ________, XXXXX___, ___X____, __X_____, _X______, [...]]]></description>
			<content:encoded><![CDATA[<p>Reading a diff today I found this piece of code for defining a font for a matrix LCD display. The code is interesting, it lets the developer see what the font looks like, so fixing your alphabet is really easy. </p>
<pre class="brush: c">
unsigned char font5x7[][8] =
{
/* z */
 ,{
   ________,
   ________,
   XXXXX___,
   ___X____,
   __X_____,
   _X______,
   XXXXX___,
   ________}

/* s */
 ,{
   ________,
   ________,
   _XXX____,
   X_______,
   _XX_____,
   ___X____,
   XXX_____,
   ________}
}
</pre>
<p>But something is fishy here, how do the compiler understand ________ as being 0&#215;00, or 0xFF? So I went on to see the included header&#8230; and ouch, this is what I found.</p>
<pre class="brush: c">
#define	_XX_____	0x60
#define	_XX____X	0x61
#define	_XX___X_	0x62
#define	_XX___XX	0x63
#define	_XX__X__	0x64
#define	_XX__X_X	0x65
#define	_XX__XX_	0x66
#define	_XX__XXX	0x67
#define	_XX_X___	0x68
#define	_XX_X__X	0x69
#define	_XX_X_X_	0x6a
#define	_XX_X_XX	0x6b
#define	_XX_XX__	0x6c
#define	_XX_XX_X	0x6d
#define	_XX_XXX_	0x6e
#define	_XX_XXXX	0x6f
</pre>
<p>This is ugly as code and pretty as ASCII art. When we are coding we want beautiful code, but not pretty ASCII art. Let that to all the artists, they do better art than we do. So, how do we fix the code? Simple, macros to the rescue!</p>
<pre class="brush: c">
#define _	0
#define X	1
#define b(a,b,c,d,e,f,g,h)	(a &lt;&lt; 7| b &lt;&lt; 6 | c &lt;&lt; 5 | d &lt;&lt; 4 | e &lt;&lt; 3 | f &lt;&lt; 2 | g &lt;&lt; 1 | h)
</pre>
<p>With this we let the compiler do the dirty job of creating all those values. Using the macros above, the code becomes easier to maintain and read. Just remember to undef the macros after using it, as you don&#8217;t want all your X&#8217;s, _&#8217;s and b&#8217;s being changed!</p>
<pre class="brush: c">
unsigned char font5x7[][8] = {
	/* z */ {
	b(_,_,_,_,_,_,_,_),
	b(_,_,_,_,_,_,_,_),
	b(X,X,X,X,X,_,_,_),
	b(_,_,_,X,_,_,_,_),
	b(_,_,X,_,_,_,_,_),
	b(_,X,_,_,_,_,_,_),
	b(X,X,X,X,X,_,_,_),
	b(_,_,_,_,_,_,_,_)
	},

	/* s */ {
	b(_,_,_,_,_,_,_,_),
	b(_,_,_,_,_,_,_,_),
	b(_,X,X,X,_,_,_,_),
	b(X,_,_,_,_,_,_,_),
	b(_,X,X,_,_,_,_,_),
	b(_,_,_,X,_,_,_,_),
	b(X,X,X,_,_,_,_,_),
	b(_,_,_,_,_,_,_,_)
	},
};
</pre>
<p>By the way, you can apply this idea for creating small graphics on code. It&#8217;s easy and self-documenting. Happy hacking!</p>
<p><strong>Update:</strong><br />
I just remembered the section <em>Making a Glyph from Bit Patterns</em> from <strong>Expert C Programming</strong> (<a href="http://www.amazon.com/Expert-Programming-Peter-van-Linden/dp/0131774298">buy</a> this book if you don&#8217;t have it yet!), it gives a solution similar to mine. The macros defined there are:</p>
<pre class="brush: c">
#define _ )*2
#define X )*2 + 1
#define s ((((((((0
</pre>
<p>So the code looks like this:</p>
<pre class="brush: c">
unsigned char font5x7[][8] = {
	/* z */ {
	s _ _ _ _ _ _ _ _,
	s _ _ _ _ _ _ _ _,
	s X X X X X _ _ _,
	s _ _ _ X _ _ _ _,
	s _ _ X _ _ _ _ _,
	s _ X _ _ _ _ _ _,
	s X X X X X _ _ _,
	s _ _ _ _ _ _ _ _,
	},
	/* s */ {
	s _ _ _ _ _ _ _ _,
	s _ _ _ _ _ _ _ _,
	s _ X X X _ _ _ _,
	s X _ _ _ _ _ _ _,
	s _ X X _ _ _ _ _,
	s _ _ _ X _ _ _ _,
	s X X X _ _ _ _ _,
	s _ _ _ _ _ _ _ _,
	}
};
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.pedro.kiefer.com.br/2011/05/working-with-lcd-glyphs/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>From CVS to Git to Gitorious!</title>
		<link>http://www.pedro.kiefer.com.br/2011/02/from-cvs-to-git-to-gitorious</link>
		<comments>http://www.pedro.kiefer.com.br/2011/02/from-cvs-to-git-to-gitorious#comments</comments>
		<pubDate>Tue, 22 Feb 2011 00:40:00 +0000</pubDate>
		<dc:creator>Pedro Kiefer</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Engineering]]></category>
		<category><![CDATA[Infraestrutura]]></category>
		<category><![CDATA[Servers]]></category>
		<category><![CDATA[cvs]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[gitorious]]></category>
		<category><![CDATA[migration]]></category>
		<category><![CDATA[repository]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[scripts]]></category>

		<guid isPermaLink="false">http://www.pedro.kiefer.com.br/?p=271</guid>
		<description><![CDATA[Migrating from CVS to Git Last week I&#8217;ve offered myself to migrate some ~300 repositories to git. Not an easy task at first, but with the right tools at hand the task becomes manageable. Installing cvs2git, and following its documentation will get you started. In Ubuntu that is as simples as: sudo apt-get install cvs2svn [...]]]></description>
			<content:encoded><![CDATA[<h2>Migrating from CVS to Git</h2>
<p>Last week I&#8217;ve offered myself to migrate some ~300 repositories to git. Not an easy task at first, but with the right tools at hand the task becomes manageable. Installing <a href="http://cvs2svn.tigris.org/">cvs2git</a>, and following its documentation will get you started. In Ubuntu that is as simples as:</p>
<pre>
sudo apt-get install cvs2svn
</pre>
<p>I know it&#8217;s weird, but cvs2git is bundled in cvs2svn&#8230; go figure.</p>
<p>But migrating hundreds of repositories isn&#8217;t a task to do manually, so I created a script for automating the process. As I had access to the server files, migrating was easier then I expected. My directory structure was something like:</p>
<ul>
<li>cvs_project_1</li>
<ul>
<li>repo_1</li>
<li>repo_2</li>
<li>repo_3</li>
</ul>
<li>cvs_project_2</li>
<ul>
<li>&#8230;</li>
</ul>
</ul>
<p>I&#8217;ve decided to migrate one project at a time, making it straightforward to verify each repo. My script is the following, bare in mind that it my have some flaws, it worked for me. Test it before erasing your old CVS data.</p>
<pre class="brush: bash">
#!/bin/bash
# Copyright (C) Pedro Kiefer

for f in `cat repo_list`;
do
	FOP=${f/\//\-}
	echo &quot;===== Creating git repository for ${f/\//\-/}/&quot;;
	sed -e &quot;s/__REPO__/${f/\//\\/}/g&quot; my-default.options &gt; $FOP.options;
	cvs2git --options=$FOP.options
	rm $FOP.options
	mkdir $FOP.git
	cd $FOP.git
	git init --bare
	cat ../cvs2svn-tmp/git-blob.dat ../cvs2svn-tmp/git-dump.dat | git fast-import
	cd ..
done
</pre>
<p>The script takes a <code>repo_list</code> file with a list of paths to the CVS repositories. Creating this list is quite easy, something like this should work. Be sure to remove <code>CVSROOT</code> and the root directory.</p>
<pre>
find cvs_project_1/ -maxdepth 1 -type d | sort > repo_list
vim repo_list
</pre>
<p>The other file the script need is <code>my-default.options</code>, which is the configuration file used by cvs2git. Most of the default values are good, but you really want to add a list of cvs commiters &#8211; so you can map the cvs login to a name + email. The other change need is on the line that sets the repository path. For the script to work you need to have it set as <code>__REPO__</code>. Like this:</p>
<pre>
run_options.set_project(
    # The filesystem path to the part of the CVS repository (*not* a
    # CVS working copy) that should be converted.  This may be a
    # subdirectory (i.e., a module) within a larger CVS repository.
    <strong>r'__REPO__',</strong>
</pre>
<p>That&#8217;s it, just run the script, and voilà, git repositories for all your cvs modules.</p>
<h2>From Git to Gitorious</h2>
<p>The second part of my task was importing all of those git repositories to my local <a href="http://gitorious.org">Gitorious</a> install. Again, doing it manually is not the right way to do it. After asking about it on gitorious mailing list and learning some ruby, I&#8217;ve created this little script. It creates all the repositories for a given project. The projects were created manually on gitorious, as I had only 6 projects &#8211; extending the tool to support the creating of projects should be easy. </p>
<p>After using the script above, I had the following directory structure:</p>
<ul>
<li>project_1/</li>
<ul>
<li>repo_1.git</li>
<li>repo_2.git</li>
<li>repo_3.git</li>
<ul>
</ul>
<p>The scripts takes as argument the project name, which should be equal to the one you created on gitorious web interface. The script scan the project directory and creates the matching gitorious repositories, copying the data to the newly created repository. Some magic regexp was added to remove version numbers and set uniform names to the new repositories. You might want to edit this to your taste. </p>
<p>By the way, this is my very first ruby programming, don&#8217;t expect it to be pretty!</p>
<pre class="brush: ruby">
#!/usr/bin/env ruby
# encoding: utf-8
#--
# Copyright (C) Pedro Kiefer
#
# Mass migrate git repositories to gitorious
#
#++

require &quot;/path/to/gitorious/config/environment.rb&quot;
require &quot;optparse&quot;

def new_repos(opts={})
  Repository.new({
    :name =&gt; &quot;foo&quot;
    }.merge(opts))
end

current_proj = ARGV[0]

@project = Project.find_by_slug(current_proj)

Dir.chdir(current_proj)
puts Dir.pwd
files = Dir.glob(&quot;*.git&quot;)

files.each do |f|
  orig_repo = f
  f = f.gsub(/\.git$/, &quot;&quot;)
  f = f.gsub(/_/,&quot;-&quot;)

  # has version?
  version = f.match(/-([0-9](.[0-9][0-9]*)+)(-)?/)
  f = f.gsub(/-([0-9](.[0-9][0-9]*)+)(-)?/, &quot;&quot;)

  desc = &quot;Repository for package #{f.downcase}\n&quot;
  desc &lt;&lt; &quot;Package version #{version[1]}\n&quot; if version

  print &quot;Creating repository for package #{f} ... &quot; 

  @repo = new_repos(:name =&gt; f.downcase, :project =&gt; @project, :owner =&gt; @project.owner, :user =&gt; @project.user, :description =&gt; desc)
  @repo.save
  path = @repo.full_repository_path
  Repository.git_backend.create(path)
  Repository.create_git_repository(@repo.real_gitdir)
  @repo.ready = true
  @repo.save 

  FileUtils.cp_r([&quot;#{orig_repo}/branches&quot;, &quot;#{orig_repo}/info&quot;, &quot;#{orig_repo}/objects&quot;, &quot;#{orig_repo}/refs&quot;], @repo.full_repository_path)
  puts &quot;Ok!&quot;
end
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.pedro.kiefer.com.br/2011/02/from-cvs-to-git-to-gitorious/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Asterisk and FreePBX on Ubuntu Server 10.10</title>
		<link>http://www.pedro.kiefer.com.br/2011/02/asterisk-and-freepbx-on-ubuntu-server-10-10</link>
		<comments>http://www.pedro.kiefer.com.br/2011/02/asterisk-and-freepbx-on-ubuntu-server-10-10#comments</comments>
		<pubDate>Mon, 14 Feb 2011 02:57:23 +0000</pubDate>
		<dc:creator>Pedro Kiefer</dc:creator>
				<category><![CDATA[Engineering]]></category>
		<category><![CDATA[Servers]]></category>
		<category><![CDATA[Asterisk]]></category>
		<category><![CDATA[FreePBX]]></category>
		<category><![CDATA[Ubuntu Server 10.10]]></category>

		<guid isPermaLink="false">http://www.pedro.kiefer.com.br/?p=241</guid>
		<description><![CDATA[This is just a small gathering of commands and best practices for installing Asterisk and FreePBX on Ubuntu. This worked for me, it has some shortcomings but should work on most of the cases. Feel free to add some comments on better ways of installing it. The following packages will be installed: Asterisk 1.6.2.7 FreePBX [...]]]></description>
			<content:encoded><![CDATA[<p>This is just a small gathering of commands and best practices for installing Asterisk and FreePBX on Ubuntu. This worked for me, it has some shortcomings but should work on most of the cases. Feel free to add some comments on better ways of installing it.</p>
<p>The following packages will be installed:</p>
<ul>
<li>Asterisk 1.6.2.7</li>
<li>FreePBX 2.8.1</li>
</ul>
<p>I started with a fresh install of Ubuntu Server 10.10, but if you already have it installed, results should be similar. While installing I selected the LAMP and SSH services, those are pretty basic services which you will need. If you have finished a fresh install, or haven&#8217;t updated your system in a while, I suggest running the following lines before continuing with this guide.</p>
<pre>
sudo apt-get update
sudo apt-get upgrade
</pre>
<h2>Postfix</h2>
<p>Although not necessary for running Asterisk and FreePBX, I suggest that you install a <b>MTA</b> agent. If you think this is unnecessary on your setup skip to the next section. Postfix is my MTA of choice, so we are going to install it. When prompt about which configuration should be done to it, select <b>Internet with smarthost</b>, just confirm the other options.</p>
<pre>
sudo apt-get install postfix
</pre>
<p>Okey, postfix installed, time to edit the basic configuration, add or change the following lines to <code>/etc/postfix/main.cf</code>:</p>
<pre>
relayhost = [smtp.gmail.com]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_tls_CAfile = /etc/postfix/cacert.pem
smtp_use_tls = yes
</pre>
<p>The password for accessing your external relay must be saved to<br />
<code>/etc/postfix/sasl_passwd</code>, add the following this file:</p>
<pre>
[smtp.gmail.com]:587    user.name@gmail.com:password
</pre>
<p>Fix the permissions on this file:</p>
<pre>
sudo chmod 400 /etc/postfix/sasl_passwd
sudo postmap /etc/postfix/sasl_passwd
</pre>
<p>Add the appropriate ca-certificate to <code>/etc/postfix/cacert.pem</code>. For gmail, that&#8217;s Thawte Consulting, so add their ca-certificate. </p>
<pre>
cat /etc/ssl/certs/Thawte_Premium_Server_CA.pem | sudo tee -a /etc/postfix/cacert.pem
</pre>
<p>Restart postfix:</p>
<pre>
sudo /etc/init.d/postfix restart
</pre>
<h3>Avoid sending mail as root</h3>
<p>Edit /etc/aliases, add the following:</p>
<pre>
root: server@domain.tld
</pre>
<p>Run the new alias command:</p>
<pre>
newaliases
</pre>
<p>Create a /etc/postfix/sender_canonical file mapping user -> email such as:</p>
<pre>
root            server@domain.tld
</pre>
<p>Run the following lines:</p>
<pre>
sudo postmap hash:/etc/postfix/sender_canonical
</pre>
<p>Add the following line to /etc/postfix/main.cf:</p>
<pre>
sender_canonical_maps=hash:/etc/postfix/sender_canonical
</pre>
<p>Restart postfix:</p>
<pre>
sudo /etc/init.d/postfix restart
</pre>
<h2>PHP</h2>
<p>When you selected the LAMP service on your Ubuntu install, you automatically got PHP5 installed. Now you just have to install some additional packages that didn&#8217;t get installed.  So run the following line to install them.</p>
<pre>
sudo apt-get install php5-gd php-pear php-db sox curl
</pre>
<h3>phpMyAdmin</h3>
<p>One might find useful to have phpMyAdmin installed for managing the MySQL database used by FrePBX and Asterisk. If you don&#8217;t know what phpMyAdmin is, you can skip to the next section.</p>
<h2>Asterisk</h2>
<p>Ubuntu 10.10 provides pre-compiled asterisk packages, using that is way more easier than backing your own asterisk. Run the following to install it, and all of its dependencies. </p>
<pre>
sudo apt-get install asterisk asterisk-mysql asterisk-mp3 asterisk-sounds-extra
</pre>
<h3>Dahdi</h3>
<p>This is a really short how-to for configuring Dahdi, it just covers the bare minimum, but it works ok. First of all, load the necessary kernel modules, in my case for a TDM400P it was the following line:</p>
<pre>
sudo modprobe wctdm
</pre>
<p>You might wanna check if the module was loaded and configured your hardware properly, so run a <code>dmesg</code>. If everything is alright, you have to create the dadhi configuration file. That&#8217;s really easy, just run:</p>
<pre>
sudo dahdi_genconf -vvvv
</pre>
<p><b>Warning</b>: Be careful when you run this on a production system, it will override the current dahdi configuration file.</p>
<p>Edit <code>/etc/dahdi/system.conf</code> and set the correct loadzone and defaultzone for your country code. I like to use vim to edit configuration files, but you can use any text editor.</p>
<pre>
sudo vim /etc/dahdi/system.conf
</pre>
<p>Now check if channels are up an running, run dahdi_cfg:</p>
<pre>
sudo dahdi_cfg -vvv
</pre>
<p>Next you have to edit <code>/etc/asterisk/chan_dahdi.conf</code> to configure the channels, this is what asterisk will see and use to send and receive calls.</p>
<h2>Apache</h2>
<p>Before running the install command, you have to configure your apache server. I prefer to use virtual host, and as of lately I have adopted the following layout for my server:</p>
<ul>
<li>/var/www/address/conf</li>
<li>/var/www/address/public</li>
<li>/var/www/address/log</li>
</ul>
<p>In the <code>conf</code> I store the necessary vhost configuration, in <code>public</code> lives the public accessible files, and <code>log</code> hosts the logging files. Feel free to use your own personal taste on installing webapps. For those who want to stick with the how-to, create the needed directories:</p>
<pre>
sudo mkdir /var/www/pabx.domain/
sudo mkdir /var/www/pabx.domain/conf
sudo mkdir /var/www/pabx.domain/log
sudo mkdir /var/www/pabx.domain/public
</pre>
<p>Now create a /var/www/pabx.domain/conf/vhost.conf file:</p>
<pre>
sudo vim /var/www/pabx.domain/conf/vhost.conf
</pre>
<p>And paste the following lines, change it accordingly to your domain.</p>
<pre class="brush: xml">
&lt;VirtualHost *:80&gt;
   ServerName pabx.domain
   ServerAlias pabx.domain

   ServerAdmin admin@domain.tld
   ErrorLog /var/www/pabx.domain/log/error.log
   CustomLog /var/www/pabx.domain/log/access.log combined

   DocumentRoot /var/www/pabx.domain/public
   &lt;Directory /var/www/pabx.domain/public&gt;
       Options Indexes FollowSymLinks MultiViews
       Order allow,deny
       AllowOverride All
       Allow from all
   &lt;/Directory&gt;

   &lt;Directory /var/www/pabx.domain/public/admin&gt;
       AuthType Basic
       AuthName &quot;Restricted Area&quot;
       AuthUserFile freepbx-passwd
       Require user admin
   &lt;/Directory&gt;
&lt;/VirtualHost&gt;
</pre>
<p>With the file created, add the vhost to the sites-enabled directory, with:</p>
<pre>
sudo ln -s /var/www/pabx.domain/conf/vhost.conf /etc/apache2/sites-available/pabx.domain
cd /etc/apache2/sites-enabled/
sudo ln -s ../sites-available/pabx.domain
</pre>
<p>For now, create an htpasswd file to protect the access to freepbx. </p>
<pre>
sudo htpasswd -c /etc/apache2/freepbx-passwd admin
</pre>
<p>And finally, restart apache.</p>
<pre>
sudo /etc/init.d/apache2 restart
</pre>
<h2>FreePBX</h2>
<p>Your Asterisk install should be working by now, so it&#8217;s time to install a nice web user interface. Ubuntu doesn&#8217;t provide a package for FreePBX, so grab the latest stable source code from FreePBX <a href="http://www.freepbx.org">site</a>.</p>
<pre>
cd /tmp
wget http://mirror.freepbx.org/freepbx-2.8.1.tar.gz
cd /usr/src
sudo tar xvzf /tmp/freepbx-2.8.1.tar.gz
cd freepbx-2.8.1/
</pre>
<p>You can equally extract the tarball on your home directory. It doesn&#8217;t make any difference. Now it&#8217;s time to create the database, the user used to access it, and populate the basic tables. This will create and import the basic tables to asterisk and asterisk cdr database, run this from the recently extracted directory.</p>
<pre>
mysqladmin create asterisk -u root -p
mysqladmin create asteriskcdrdb -u root -p
mysql -u root -p asterisk < SQL/newinstall.sql
mysql -u root -p asteriskcdrdb < SQL/cdr_mysql_table.sql
</pre>
<p>With the tables in-place, it's time to create the user with privileges to access and edit those tables.  Open a mysql prompt with:</p>
<pre>
mysql -u root -p
</pre>
<p>On the prompt run the following queries:</p>
<pre>
GRANT ALL PRIVILEGES ON asterisk.* TO asterisk@localhost IDENTIFIED BY 'badasspassword';
GRANT ALL PRIVILEGES ON asteriskcdrdb.* TO  asterisk@localhost IDENTIFIED BY 'badasspassword';
flush privileges;
quit;
</pre>
<p><b>Don't forget to change the password!</b></p>
<p>Before running the install command, make a copy of /etc/asterisk/modules.conf. FreePBX rewrites the file and trashes Asterisk installation. If you restart Asterisk after installing FreePBX Asterisk dies with no message.</p>
<pre>
sudo cp /etc/asterisk/modules.conf ~/asterisk-modules.conf
</pre>
<p>Ok, we are ready to install freepbx to /var/www/pabx.domain/public:</p>
<pre>
sudo ./install_amp
</pre>
<p>The install script will ask for some configuration data, eg. were to install freepbx (/var/www/pabx.domain/public), sql password, asterisk password, etc. Take note of the passwords you used, you might need them later. </p>
<p>The output from the install script is somewhat like this:</p>
<pre>
...
Enter your USERNAME to connect to the 'asterisk' database:
 [asteriskuser] asterisk
Enter your PASSWORD to connect to the 'asterisk' database:
 [amp109] badasspassword
Enter the hostname of the 'asterisk' database:
 [localhost]
Enter a USERNAME to connect to the Asterisk Manager interface:
 [admin]
Enter a PASSWORD to connect to the Asterisk Manager interface:
 [amp111]
Enter the path to use for your AMP web root:
 [/var/www/html]
/var/www/pabx.domain/public
Enter the IP ADDRESS or hostname used to access the AMP web-admin:
 [xx.xx.xx.xx] pabx.domain
Enter a PASSWORD to perform call transfers with the Flash Operator Panel:
 [passw0rd] password
Use simple Extensions [extensions] admin or separate Devices and Users [deviceanduser]?
 [extensions]
Enter directory in which to store AMP executable scripts:
 [/var/lib/asterisk/bin]
...
</pre>
<p>Restore asterisk-modules.conf file, which you backed up before installing FreePBX:</p>
<pre>
sudo cp ~/asterisk-modules.conf /etc/asterisk/modules.conf
</pre>
<p>Apache runs as www-data, Asterisk as user asterisk, so we have to change some permission to make both programs work together. First, add www-data to asterisk group:</p>
<pre>
sudo adduser www-data asterisk
</pre>
<p>Fix the permissions from amportal, add these lines to the end of <code>/etc/amportal.conf</code>:</p>
<pre>
AMPASTERISKUSER=www-data
AMPASTERISKGROUP=asterisk
AMPASTERISKWEBUSER=www-data
AMPASTERISKWEBGROUP=asterisk
</pre>
<p>Everything in place, time to start amportal:</p>
<pre>
sudo amportal start
</pre>
<p>Open your web browser and go to http://pabx.domain/ and you will be greeted with FreePBX site. I strongly suggest you to upgrade and install the FreePBX modules you will need, so go to <b>Modules Admin</b> and click on <b>Check for online updates</b>.</p>
<h3>Start asterisk with amportal</h3>
<p>Before we finish, lets make amportal script to manage asterisk and run it through the <strong>safe_asterisk</strong> script, for that, we have to remove asterisk from rc.d:</p>
<pre>
sudo update-rc.d -f asterisk remove
</pre>
<p>Now edit <strong>safe_asterisk</strong>, to make sure it runs on background, edit the variable <b>BACKGROUND</b> to zero:</p>
<pre>
sudo sed -e s/BACKGROUND=0/BACKGROUND=1/ -i /usr/sbin/safe_asterisk
</pre>
<p>We have to start amportal after booting, so call <b>amportal start</b> in <code>/etc/rc.local</code>. Edit your /etc/rc.local and add the following line before the exit 0 line.</p>
<pre>
/usr/local/sbin/amportal start
</pre>
<p>Reboot your machine, and check that everything is still working. Have fun!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pedro.kiefer.com.br/2011/02/asterisk-and-freepbx-on-ubuntu-server-10-10/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Histórias de ninar de um engenheiro</title>
		<link>http://www.pedro.kiefer.com.br/2009/12/historias-de-ninar-de-um-engenheiro</link>
		<comments>http://www.pedro.kiefer.com.br/2009/12/historias-de-ninar-de-um-engenheiro#comments</comments>
		<pubDate>Tue, 15 Dec 2009 00:37:30 +0000</pubDate>
		<dc:creator>Pedro Kiefer</dc:creator>
				<category><![CDATA[Engineering]]></category>

		<guid isPermaLink="false">http://www.pedro.kiefer.com.br/?p=105</guid>
		<description><![CDATA[Hoje no trabalho, enquanto escrevia um driver novo pra kernel do linux, tivemos uma discussão sobre histórias de ninar de engenheiros, físicos, computólogos, matemáticos, etc&#8230; esse povo todo das exatas. A primeira história que lembramos foi a versão &#8216;exatas&#8217; para os três porquinhos que começa assim: &#8230; Era uma vez três porquinhos ( P1, P2 [...]]]></description>
			<content:encoded><![CDATA[<p>Hoje no trabalho, enquanto escrevia um driver novo pra kernel do linux, tivemos uma discussão sobre histórias de ninar de engenheiros, físicos, computólogos, matemáticos, etc&#8230; esse povo todo das exatas. A primeira história que lembramos foi a versão &#8216;exatas&#8217; para os três porquinhos que começa assim:</p>
<blockquote><p>&#8230; Era uma vez três porquinhos ( P1, P2 e P3) e um Lobo Mau, por definição, LM, que vivia os atormentando. P1 era sabido e fazia Engenharia Elétrica e já era formado em Engenharia Civil.<br />
P2 era arquiteto e vivia em fúteis devaneios estéticos absolutamente desprovidos de cálculos rigorosos. P3 fazia Comunicação e Expressão Visual na ECA. LM, na Escala Oficial da ABNT, para medição da Maldade (EOMM) era Mau nível 8,75 (arredondando a partir da 3ª casa decimal para cima)&#8230;</p></blockquote>
<p>Obviamente começamos a pensar em outras histórias, contando as coisas divertidas que fazemos diariamente. Falando de Linux, transistores, FPGAs, spinlock&#8217;s, threads, BUG_ON()&#8230; não sei se daria uma história muito engraçada, afinal, que criança iria entender! Mas com certeza demos muitas risadas. Algo nessa linha representa as bobagens que inventamos:</p>
<blockquote><p>Era uma vez um Driver feliz, que funcionava perfeitamente na sua kernel 2.6.18&#8230; mas os tempos passaram, e melhorias foram feitas no código da kernel. O Driver feliz estava ficando triste por estar desatualizado, então seu fiel programador resolveu atualizar suas funcionalidades para ele ser ainda mais feliz.</p>
<p>O seu fiel programador não sabia muito sobre as grandes novidades do kernel, e também tinha dormindo nas aulas sobre kernel threads e spinlock&#8217;s. Não sabendo dessas novidades, o programador achou melhor não incluir todos aqueles spinlock&#8217;s que o Driver feliz tinha.</p>
<p>O Driver feliz então ficou muito triste, pois só fazia kernel panic&#8217;s, não conseguia mais ser feliz. Era agora um Driver infeliz&#8230; Mas eis que então um superprogramador surge para salvar o Driver feliz da sua infelicidade. O superprogramador não tinha dormido nas aulas de spinlock&#8217;s, e em pouco tempo fez o Driver feliz voltar a ser o mais feliz de todos os drivers.</p></blockquote>
<p>Espero nunca contar algo tipo isso pros meus futuros filhos! Mas, talvez seja inevitável&#8230; vou ter que esperar para descobrir.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pedro.kiefer.com.br/2009/12/historias-de-ninar-de-um-engenheiro/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

