Sunday, October 28, 2012

Problem when adding SSH key on github


Recently, I had I problem with github. I couldn't add SSH keys anymore, the web page would just hang and present me a "Connection reset" error after a few (annoying) minutes. I struggled for a week, but have finally found a solution, which is not the best, but at least I can access github from my machine once again.

It all started two weeks ago, when I ran an everyday git push, and got a little surprise. It just sat there forever, and I had to SIGTERM it every time. What I did after was try to reset my key on github. I went to the SSH page and deleted my key, created a new one and tried to add it.

Yes I know it was stupid. The right way to do it would be:
  • back up my key
  • create a new one
  • add it
  • make absolutely sure it works
  • remove the old one in github and on the machine
But I didn't, for one simple reason: adding keys has been such a natural operation, I didn't even think about it. Replacing a key (which I did a lot of times when I was learning how public-key encryption works) only takes a few seconds, and I never had to worry about it. Until now.


Haystacking

I am no ssh expert. So I turned to github's support. And I have to say, the response was really good, fast and to the point. Sadly, it didn't solve the problem. Here is the response:
Hi Bruno,
What size SSH key are you using? We have a known bug where the page will give a 500 error if the SSH key is too large.
I would recommend using the default size key for now, and hopefully we will have this bug fixed soon.

Sorry for the trouble.

Cheers,
Steve

It turns out the problem wasn't the key size, but you can see Steve gave a really polite response. Anyway, I started trying everything to make it work, but in a week I just couldn't do it. Then, yesterday, I decided to give the developer API a try. I didn't have much hope that it would work, because I had tried a lot of different things and because I thought the problem was exactly there. But I was wrong again.

With just a few commands, I was able to add a ssh key to my account and finally access my repositories. And, in the process, I discovered a handy command line utility, so I guess it wasn't all that bad.


curl (a.k.a. cURL)

curl is a program you can use to fetch web pages just as your browser would do. It is present on most distributions, so you can start right away and run 
$ curl iffalse.blogspot.com
And you'll get the HTML output of the page. You can use that to access the github API. To list all the keys of an account, you'd use
$ curl -u bbguimaraes https://api.github.com/user/keys
Use the -u option to set the username. You will be prompted for the password. The switch accepts the form -u user:password, but that just isn't very nice. You will get back a json output, listing all the keys registered for your account. There are several functions on the API, you can take a look at them on the docs page.

But the one that did it for me was the "create a puclib key". A simple post
$ curl -u bbguimaraes -d '{"title": "[...]", "key": "ssh-rsa AAA[...]"}' https://api.github.com/user/keys
and, after a week of awful manual syncing of code, I was finally able to use my beloved github repositories as I always had. I hope this text can save you some time if you ever happen to have the same problem.

Monday, October 22, 2012

perl is beautiful - part 3

In the last post on the subject, I'll show a couple more perl tricks I use everyday. I'll touch on some not-so-basic regex concepts here, so feel free to take a look here if you don't know what some of them mean.

One thing you can do with the regex operators is using them in list context. Every operation in perl is done in a context. When you assign to a variable, the expression is evaluated in scalar context. When you assign to an array, you get list context: 
my @my_array = (2, 3, 4, 5); 
The '@' tells perl that your variable will be an array, and the rhs is thus executed in list context. Try this:
my @my_array = (2, 3, 4, 5);
my $my_var = @my_array;
Or, my personal favorite:
my @my_array = 2..5;
my $my_var = @my_array;
Both do the same thing. When you use an array on the rhs of a scalar assignment, you get the length of that array, which is what's happening here. The regex operators also work this way: 
my $scalar = m/my \$\w+/; 
will put a boolean value on $scalar if a match was or wasn't found (on $_, remember). This will (roughly) find all "use" directives on perl code. Since we are in scalar context, the result will be a boolean, which will be true if any match occurs. But try this:
my @array = m/my \$(\w+)/g;
This will create an array with all the matches found. There are some new things here which need a better explanation. First, the regex modifier g (from global) will make the regex be applied repeatedly, instead of stopping on the first result.

Since we are on a list context, the result is no longer a boolean, but a list of all the matches, here meaning the values captured on $1, $2, and so on. The output for a sample file:
use warnings;
use strict;

local $/;
$_ = <>;
$, = "\n";
$\ = "\n";

my $scalar = m/use (\w+);/;
my @array = m/use (\w+);/g;

print $scalar;
print @array;

# Output
1
warnings
strict
Here we can see, when we incept the code through itself, that the variable gets a value of true, while the array is populated with all the results found. Just to show you another nice feature: if we add some parenthesis around "use":
my @array = m/(use) (\w+);/g;
we get four elements on the array. That's because, for each "pass", all values from ($1, $2, $3, ...) are stored.

Well, I could go on and on writing about all the cool things you can do with perl, but I'm going to stop here. If this short introduction did leave you interested to learn more, there are several sources on-line. Two I use constantly are perldoc and the web version of Programming Perl. If you want to learn more about regular expressions, I highly recommend O'Reilly's Mastering Regular Expressions (but please, don't buy the Brazillian Portuguese translation, just don't).

And as a last note, if you are a vim user, here's something really useful. You can select some text (using v, V or ctrl-v) and press ':'. You will automatically get a filter for the selected text. From there, you can type 'w !' (note the space), which will write the selected text to the standard input of the command. Combining all this with what we learned, we can, for example, use the regex to find python functions, on a single vim command: 
:'<,'>w !perl -ne 'print if m/^\s*def \w+/'
And get a listing of the functions inside the selected text. Or you can do some bizarre things, like sending the output to a file, or changing the name of the functions, changing indentation... Your sanity is the limit.

Low-level language

"Tudo é céu, tudo é mar; torvo negrume sobre as cabeças borrascoso pesa, e horrenda espessa treva enoita as ondas." MARÃO, Públio Virgílio. Eneida.

Thursday, October 18, 2012

perl is beautiful - part 2

We've seen how perl can be used, but you may be wondering, so what? Fasten your seatbelt, for fun begins now.

Interpreter switches

The single most useful tool I'm going to show you. The interpreter accepts many parameters, which alter the way it runs, but most importantly, they can alter the way the code is executed. First, though, I'll show you the -e switch, which will be used on all the other examples.
$ perl -e 'print "hello\n";'
The switch tells the interpreter that, instead reading from stdin or from a file, the program will be contained inside the next argument. Note that,  by perl's definition, you don't need to use a semicolon after the last (here also the only) command. But I've included it to avoid confusion on the quotes. With this switch, it will be easier to show you the others.

Let's start with -n, which will surround your code with the following construct:
while(<>) {
    # your code
}
Try running our previous example but adding this switch. It will start listening on stdin, and after every line it will print the string 'hello' (I call it the nice program). One thing to note is that the -e switch and the program string must be contiguous. You can run the program like the first three lines below, but the fourth will give you an error:
$ perl -ne 'print "hello\n"'
$ perl -n -e 'print "hello\n"'
$ perl -e 'print "hello\n"' -n
$ perl -e -n 'print "hello\n"' # This is wrong!
But what really happened when we ran that program? If you remember the last post, <> is the input operator. So, "while(<>)" means "read lines from the input until it ends". And if you have really good memory (or are already tainted by the perl way of thinking), you'll remember that the input read will go to the variable $_. We can test it with our reimplementation of cat:
$ perl -ne 'print'
See what I did there? I tested your memory again.$_ is used as the default argument to many functions in perl, including print. This allows you to say just "print" here, instead of "print $_". And this code is such a common occurrence that perl already has another switch to do just that: -p.

$ perl -pe ''
Running this, you can see that it is exactly the same as the previous. Just like -n, it surrounds your code with more code, but it adds a little something to what -n adds:
while(<>) {
     # your code
     print
}

Regular expressions revisited

Now, this is already fun. We can make a program that does anything to each line of input (like using ssh -Y, a list of swear words and notify-send on your coworker's computer). But the real power of what I'm showing you comes from combining these techniques with perl's humongous power. Check this:
$ perl -ne 'print if m/=D/'
This will print every happy line on a file. Remember that the default parameter for the m// operator is also $_ (isn't it beautiful?). If you followed me all the way here, you can now start applying it, just by remembering this simple command line. Quick example I use every day: find all python functions on a file. 
$ perl -ne 'print if m/^\s*def /'
From here,  you can go anywhere. The nice thing is now you have the power of a real programming language, and can do all the bizarre things perl can do (and it can do some really bizarre things).One thing that took me a little time to get used to was the "boilerplate" part of the command line. But after I used it a few times, it's now natural, I don't even have to think about it. And it took only a couple of seconds to google "perl command line" anyway (at some point, I only had to type "perl" on firefox's address bar and it would show me the page right away).

Coming next: on the last post on this (unexpectedly long) topic, I'll show you some (kind of ) advanced perl and regexp techniques.

Monday, October 1, 2012

perl is beautiful

Writing the first post on a blog about programming is fairly easy. Now, the second one needed a little thought to come up with. I decided to show a trick I use almost daily, be it at work or on personal projects. And that is perl. Yes, the ancient language from 1987.

If you're familiar with grep (and if you're not, stop reading this right now and get familiarized), you already know the enormous power of a general purpose stream filter. What I want to show you in this post is how you can augment that power using simple (aren't them all?) features from perl, both the language and the homonymous interpreter.

The interpreter

I'll start with the interpreter just to get you started on how to run simple programs. No perl experience is required, since the constructs used here are really simple. So, let's start:

$ perl -v
This is perl 5, version 14, subversion 2 (v5.14.2) built for x86_64-linux-gnu-thread-multi
(with 53 registered patches, see perl -V for more detail)

Copyright 1987-2011, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.
If everything is setup right, you get a nice message along with the version number. If you get something like
perl: command not found
you probably need to install the perl interpreter or set your PATH right. Installing it may be as simple as
$ sudo apt-get install perl
depending on your system. But your platform's documentation is probably a much better resource on how to install programs. Once we have the interpreter, we can start fiddling with it: 
$ perl 
print "Hello world!\n";

Press Ctrl-D and you should get the (in)famous message on your screen. For longer scripts, you can save it to a file and pass the file name as an argument to the interpreter. But my personal favorite is the -e switch. It means that the string following the switch is actually the program to be run.
 $ perl -e 'print "Hello world!\n";
You won't have this problem here, but take care when mixing the quotes used inside the program from the quotes used to pass the command to the shell. You may need to escape some of them.

perl

Let's start building some more interesting examples, exploring one of the strongest side of perl: its support for regular expressions. We create a file to contain our script:

#!/usr/bin/perl

use strict;
use warnings;

my $str = <>;;
print $str if $str =~ m/g w/;

I'll explain what each line does. You should know what line 1 does. Line 3 and 4 turn on useful warnings (if you don't set warnings to the highest level possible on your compiler/interpreter, shame on you). On line 6, we create a variable called str (the $ character is used to indicate simple variables, while the keyword my defines it as a local variable), and initialize it using the diamond operator. Long story short, this operator reads from the standard input (as long as you don't pass any parameters when executing the program, more on this later).

Line 7 deserves a special paragraph. Here I'm using the inverted if syntax (which is a great feature that most languages lack), but don't get fooled by it. It could be written as
if($str =~ m/g w/) {
    print $str;
}
but I find the inverted syntax much clearer and easier to read. The =~ operator is used to apply regular expressions. It is a binary operator, where the left-hand side is a string or a variable containing a string, and the right-hand side is a regex operator (in this case, the m// operator). The syntax to match a string against a regular expression is
string =~ m/regex/;
 Using some of perl's magic, we could rewrite our example as
$_ = <>;
print if m/g w/;
Now things start to get interesting! I decided to go light and present the omnipotent $_ variable explicitly. $_ is a special (a.k.a. magic) variable in perl, which is used as the default value of many functions. Two examples here are print and the match operator.

One last thing before I delegate the rest of this topic to the next post: the diamond operator can be used with a loop to read all the lines from the input:
while(<>) {
    print;
}
Here,<> causes one line from the input to be read and stored on $_. Then, inside the body of the loop, print is called without arguments, causing it to use our old friend $_. Input, when using the diamond operator, can be one of two things. If the program is called with no arguments, input is stdin. If file names are passed as arguments, the input is the content of these files, read sequentially from first to last. The loop keeps reading until the input ends, which means reading until a EOF character on stdin or reading all the files. Congratulations! You have just implemented cat.

Coming next: actually increasing productivity.

99 Bottles of Beer

$ vim hello.asm
    .section        .rodata
string:
    .ascii "Hello, World!\n\0"
length:
    .quad . -string         #Dot = 'here'

    .section        .text
    .globl _start           #Make entry point visible to linker
_start:
    movq $4, %rax           #4=write
    movq $1, %rbx           #1=stdout

    movq $string, %rcx
    movq length, %rdx
    int $0x80               #Call Operating System
    movq %rax, %rbx         #Make program return syscall exit status
    movq $1, %rax           #1=exit
    int $0x80               #Call System Again

:!as % -o %.o
:!ld %.o
:!./a.out