web performance | δικτυακή παράσταση http://www.andmarios.com DO NOT PANIC Mon, 08 Jul 2013 21:28:03 +0000 en-US hourly 1 http://wordpress.org/?v=3.6 Android, Open Source and a self-induced hackathon http://www.andmarios.com/en/2013/04/android-open-source-and-a-self-induced-hackathon/ http://www.andmarios.com/en/2013/04/android-open-source-and-a-self-induced-hackathon/#comments Thu, 11 Apr 2013 17:53:15 +0000 Marios http://www.andmarios.com/?p=1255

tl;dr Android as a whole -from Google’s code repository to cheap Chinese tablets- is open source to a certain extent but, although this acts as a cushion for poor product releases, it isn’t an excuse.

Some weeks ago I had to spend more time than usual to get my Android devices do my binding; more time as in four (4) days!

When it comes to Android, I am an advanced user, having rooted and flashed some ROMs on my devices. Also, due to my Linux knowledge, Android’s lower levels don’t feel that strange to me.

That said, without any specific knowledge, in 4 days I got to resolve a hardware (software related though) issue, write a really basic Android application, submitted it to Play store and create a custom ROM image by using a ready made ROM as base (some orders of magnitude easier than compiling cyanogenmod).

For any Linux user, Android has a low entry hacking barrier.

Day 1: hardware hacking on Samsung’s Galaxy R i9103 phone

I like photography. Since the 1st day, one and a half year ago, being on Android GB 2.3, my Samsung Galaxy R didn’t permit for exposure compensation (and consequently HDR) from any 3rd party app. This was unacceptable. I emailed various app developers about this, but it was a device specific problem they could not solve. The trend continued even when Samsung released Android ICS 4.0.1 for my model.

Since I upgraded to a custom, almost alpha, version of CM 10.1, I thought it was about time to solve it myself. I downloaded kernel sources, CM sources, did some online search, did some grepping and found possible places of failure. Although in the end I could describe perfectly the problem, like which Android framework’s call were failing to provide accurate data, I couldn’t tell where exactly the failure happened. The kernel driver returned correct information, yet Android framework reported them wrong (or probably reported some default Android values).

Samsung had fixed this in their camera apk. Yeap, they knew the problem and instead of fixing it properly, they opt to fix it only for their built-in camera app, breaking any 3rd party app from Google Play. Kudos Samsung for being a douchebag.

I would report the problem to the CM developer but I wanted an easy fix (and proof of concept) for myself. I decided that the easiest way for me, would be to hardcode my device’s capabilities inside Android’s framework. But again, compiling CM from source, isn’t the easiest path possible. So, hello Dalvik assembly. I downloaded an Android jar/apk disassembler, took framework.jar from my phone, disassemble it, hardcoded my device’s data, reassemble it and I was ready. I could now both describe the problem and provide a proof-of-concept fix, since many people didn’t want to aknowledge that their device had a problem.

Suffice it to say, for the next few days, I only took HDR photos. :D

For the technical oriented, you could see my post over XDA which explains the problem: http://forum.xda-developers.com/showpost.php?p=38757391

So, day 1 ended. I learned a bit about Android kernel, CM/Android sources, CM development model, Android’s framework, Android’s Dalvik assembly.

Day 2: hacking on Android Jelly Bean, releasing an app

Day 1 was Monday. On Tuesday I received a chinese Android tablet I had ordered a month before. I spent the best part of this day shooting HDR and playing with the tablet. Day 2 was Wednesday.

I sincerely think that Android can be used for some work, though this may require a hardware keyboard. I connected a usb keyboard to my tablet and was delighted to find that Android JB 4.1 has proper support for hardware keyboards. Unfortunately though, it didn’t support Greek. Thankfully, language layouts could be added via 3rd party apps, but none was available for Greek.

There was one paid app in Play, that supported Greek via a hardware keyboard by implementing a software keyboard. That may be needed for older Android versions but not for Jelly Bean which lets you use any software keyboard (and its correction/prediction methods) with your physical keyboard. Also its cost was about €2.5, which I think is a bit too much for anyone who just want to write in his mother tongue.

Open source wins again and after some search, I found an open source project which added an English variant layout to Jelly Bean. This was a good start.

I downloaded it and tried to compile it since I had Android SDK installed because I needed adb. It couldn’t compile because I had an older Android SDK and also the downloaded project included some configuration files that I should create myself.

After a quick course in Android’s build system and an update to the SDK, I could compile it myself. It took me some trials to understand the format Android uses to describe keyboard layouts. Google’s documentation is good but I think in this case, it could be a little better. When I understood the format,  it took me a couple of hours, at most, to transfer the Greek layout and get something that worked.

But I couldn’t stop there. I wanted to be easy for all people to write in Greek, so I decided to uploaded it to Google Play.

I got myself a Google developer account and paid the $25 fee, a tad ironic since earlier I refused to buy the €2.5 app, but this was different. Then I learned that in order to upload an app to Google Play, I have to add icons to my application, to write descriptions, to add screenshots etc.

All these took about as much time, as the development process. I had to learn about android resources (how to add icons to an app for various resolutions), I had to create an icon, to stage some screenshots from the mobile phone because the tablet had a non standard screen resolution which Google wouldn’t accept, write an accurate description and translate it to Greek.

For the icon, I couldn’t find a decent icon of a keyboard button with a permissive enough license, so I resorted to my camera and used a photo of my keyboard. I am not very happy with the result, but it was the best I could get. We should introduce more artists to free software.

Last, I wrote about my app in a couple of forums that I am a regular, respecting each forum’s rules (aka I didn’t spam).

So, day 2 ended. I learned a bit about Android’s build system, Android’s SDK, Android Programming, Google Play. In the morning I knew nothing about developing an app. In the evening my app was published (and visible) in Google Play. I don’t think Google can lower this barrier any further.

Oh, of course my app’s source code is available. Head over to github to check it out: https://github.com/andmarios/GreekHWKeyboard

Day 3 and 4: ROM/hardware/software hacking over Pipo S2 tablet

This wasn’t as exciting. The chinese tablet (a Pipo Max S2) had a decent ROM but with some shortcomings, like the absence of root and an easy way to root, as well as some built in apps I didn’t need to use my resources.

No one had released an acceptable -for me- ROM for the tablet. There was one ROM available at the time but it was very obtrusive for my taste, masquerading the tablet as a Samsung Galaxy S2 phone and tampering with framework.jar in unknown to me ways. So I thought I should release a ROM (a first for me) for all to enjoy.

I started by learning a bit about the tools you need to flash a RK3066 device. After that it was a matter of mounting an image and using my Android and linux knowledge to do some changes. It took me enough time though, because I would never risk to release a firmware less than perfect. So every step needed much testing.

I wanted to add nfs and smb support, so I downloaded some kernel sources and tried to built them. I couldn’t get working modules, so I used some that I found ready on the net. I needed to run some commands at startup, so I learned a bit about Android’s init. I wanted to add support for usb devices (disabled on Android’s level due to being flakky) so I learned a bit about Android permissions. I found that performance was IO bounded, so I tried to enhance it a bit. The default notification ringtone could cause a heart attack, so I changed it.

It was fun, like hacking around a distribution, but not that great of a learning experience. I posted it to a couple of forums, got some feedback, adjusted some issues and issued an update.

So, days 3 and 4 ended. I learned a bit about Android’s OS level workings, I learned a bit about cross compiling, I learned a bit about proprietary embedded boards.


I am awesome! :p

No, seriously. Open source is awesome. Android is mostly awesome. Android devices are nice but not always awesome.

Should Samsung get away by the fact that they sold me a handset they knew to be broken? They programmed their own app to work around the problem, so they can’t deny that they had knowledge of it. They sold me a smartphone that couldn’t run 3rd party apps properly, so should we still consider it a smartphone?

Should Google get away by the fact that they didn’t include a Greek layout for physical keyboards in Android 4.1 nor in Android 4.2? They do have limited resources, but all it would take for them, would be 2 hours at most for one of their Greek speaking employees to do a completely mechanical task.

As for the Chinese vendor, they are illegal. They do not provide kernel sources as they should (the compiling I mentioned, was for sources provided by other vendors). Due to Android, they are able to sell and make profit of a decent tablet for a low price (below €100) which, because of Android being based on the open source Linux kernel, I was able to tamper with at a (super)user level and adapt partially to my needs. On the other hand, the lack of GPL compliance, means there aren’t serious community efforts to develop a ROM from scratch, or a way to use a more recent Android version, or for someone to try to improve the flakky usb support. We are at the vendor’s mercy to get updates and fixes.

Android shows the way. But we can do better.

http://www.andmarios.com/en/2013/04/android-open-source-and-a-self-induced-hackathon/feed/ 1
Gitlab 4.0 on a Gentoo server, ~amd64, hardened w/ Apache. http://www.andmarios.com/en/2012/12/gitlab-40-on-a-gentoo-server-amd64-hardened-w-apache/ http://www.andmarios.com/en/2012/12/gitlab-40-on-a-gentoo-server-amd64-hardened-w-apache/#comments Fri, 28 Dec 2012 22:15:42 +0000 Marios http://www.andmarios.com/?p=1188 The article about Gitlab on Ubuntu gets some views every day, so I guess it is an interesting subject -and it should be. GitLab is a great project. It could do with less RAM consumption and less frequent updates though, but I am only whining because I am using it and I am not going to uninstall it anytime soon. :p

The thing is I am in love with Gentoo for many years now and my Ubuntu server was more like an one time thing. So I set to install Gitlab on my ~amd64 hardened Gentoo and log the process for anyone interested. It is a great time too since Gitlab recently reached version 4.0 with enhanced project management.


Update (9 July 2013): An excellent article for installing a recent version of Gitlab (5.3 at the time of writing) is available at the official Gentoo Wiki thanks to the commenter with the inspired name 666threesixes666. :) Many thanks!


How to read this tutorial

This tutorial’s purpose is to be used as a generic guide. Gitlab has frequent updates, once every month for both the software and the installation instructions; unfortunately I can’t maintain such a document.

The official installation guide covers Debian and Ubuntu. Since we are on Gentoo, we have to depart here and there. Fortunately, these parts that are different between Linux distributions, doesn’t change much.

So ideally you will open my guide on one half of your screen and the official guide on the other half. You will follow the official guide and when you detect a difference, you will use my guide -but apply some logic too, you are running Gentoo after all.

I will try my best to make it clear when I copy the official guide and when I am doing Gentoo specific parts.

During most of this guide I use the sudo command, even when a command needs to run as root. I assume though that you are already root (Gentoo’s usual way). Using sudo in this case doesn’t harm in any way, I just try to keep my commands similar to Gitlab’s official instructions.

Note: Chances are if you want to run Gitlab, you already run a web server. So, I won’t go into specifics about setting up Apache, MySQL, postfix etc. I will give you only the Gitlab specific parts for these programs. Before running my commands, I expect to you to think a bit and if needed, adjust them to your setup.


1-2. Packages / Dependencies / Ruby (Gentoo way)

Gitlab, as most programs, has dependencies. Emerging them one by one isn’t elegant and won’t help if you ever decide to remove Gitlab from your system.
Download this ebuild instead (gitlab-deps-0.ebuild 4.0-stable), put it on your local overlay, emerge it and you are good to go. If you ever remove Gitlab, unmerge gitlab-deps and do an emerge –depclean.

Important: Gitlab depends on postfix. On my ebuild, I changed this to virtual/mta, so that it won’t ask you to change your setup. I haven’t test it though with anything else other than postfix. If you haven’t set an mta for your server (unlikely), then I encourage you to install and set up postfix before installing gitlab-deps.

If you don’t care about doing things elegantly and just want an emerge oneliner, here it is. It is strongly discouraged though. Gentoo isn’t designed to be used like this (adding dependencies as world entries).

$ emerge app-admin/sudo net-misc/wget net-misc/curl sys-devel/gcc dev-libs/libxml2 dev-libs/libxslt sys-libs/readline virtual/libc sys-devel/make sys-libs/zlib dev-libs/icu dev-db/redis net-misc/openssh dev-vcs/git dev-lang/python dev-lang/ruby:1.9 dev-ruby/rubygems dev-ruby/bundler dev-python/pip dev-libs/libyaml mail-mta/postfix dev-python/pygments

If you went with the oneliner, also emerge the database you want to use (mysql or postgres).


3. System Users (Gentoo way)

Create accounts for Git and Gitolite.

$ useradd -m -U -s /bin/sh -b /home -c "git repositories" git $ useradd -m -U -s /sbin/nologin -b /home -c "gitlab" gitlab

$ usermod -a -G git gitlab $ usermod -a -G gitlab git

$ sudo -H -u gitlab ssh-keygen -q -N ” -t rsa -f /home/gitlab/.ssh/id_rsa

The git account you just created is disabled, so you can’t ssh (or git/ssh) to it. Enable it by giving it a random password (no need to remember it):

$ passwd git


4. Gitolite (Gitlab way)

This is a direct copy from Gitlab’s official installation guide.

$ cd /home/git $ sudo -H -u git git clone -b gl-v304 https://github.com/gitlabhq/gitolite.git /home/git/gitolite

$ sudo -u git -H mkdir bin $ sudo -u git sh -c ‘echo -e “PATH=\$PATH:/home/git/bin\nexport PATH” >> /home/git/.profile’ $ sudo -u git sh -c ‘gitolite/install -ln /home/git/bin’

$ cp /home/gitlab/.ssh/id_rsa.pub /home/git/gitlab.pub $ chmod 0444 /home/git/gitlab.pub

$ sudo -u git -H sh -c “PATH=/home/git/bin:$PATH; gitolite setup -pk /home/git/gitlab.pub” $ sudo chmod 750 /home/git/.gitolite/ $ sudo chown -R git:git /home/git/.gitolite/ $ sudo chmod -R ug+rwXs,o-rwx /home/git/repositories/ $ sudo chown -R git:git /home/git/repositories/


4.1. Disable StrictHostKeyChecking for localhost and your domain (Gitlab way)

$ echo "Host localhost StrictHostKeyChecking no UserKnownHostsFile=/dev/null" | sudo tee -a /etc/ssh/ssh_config

$ echo “Host YOUR_DOMAIN_NAME StrictHostKeyChecking no UserKnownHostsFile=/dev/null” | sudo tee -a /etc/ssh/ssh_config


4.2. Custom ssh port (Gitlab/Gentoo way)

Usually you want your ssh daemon to hear to a non standard port in order to avoid automated port scans. In order for this to work with Gitlab, you have to configure the ssh client for your gitlab account:

$ sudo -u gitlab -H echo -e "Host localhost\n Port CUSTOM_SSH_PORT" >> /home/gitlab/.ssh/config


4.3. Test if everything works so far (Gitlab way)

$ sudo -u gitlab -H git clone git@localhost:gitolite-admin.git /tmp/gitolite-admin $ sudo rm -rf /tmp/gitolite-admin


5. Database

This section exists because it is present on the official guide too. No need to do anything here.


6. Gitlab (Gitlab way with Gentoo specific parts)


6.1-6.2. Clone the source and configure it (Gitlab way)

$ cd /home/gitlab/ $ sudo -H -u gitlab git clone -b stable https://github.com/gitlabhq/gitlabhq.git gitlab $ cd /home/gitlab/gitlab $ sudo -u gitlab -H git checkout 4-0-stable $ sudo -u gitlab -H cp config/gitlab.yml.example config/gitlab.yml $ sudo -u gitlab -H nano -w config/gitlab.yml $ sudo chown -R gitlab log/ $ sudo chown -R gitlab tmp/ $ sudo chmod -R u+rwX log/ $ sudo chmod -R u+rwX tmp/ $ sudo -u gitlab -H cp config/unicorn.rb.example config/unicorn.rb


6.3 Configure GitLab DB settings (Gentoo way)

We are going to use a MySQL database. Create a database and a user for Gitlab, then configure Gitlab.

In case you don’t remember how to create a MySQL database:

$ mysql -uroot -p mysql> CREATE DATABASE IF NOT EXISTS gitlabdb; mysql> GRANT ALL ON gitlabdb.* TO gitlab@localhost IDENTIFIED BY 'gitlabpass';

Now configure Gitlab to use MySQL. Only the production section of database.yml needs to be adjusted.

$ sudo -u gitlab cp config/database.yml.mysql config/database.yml $ sudo -u gitlab -H nano -w config/database.yml


6.4 Install Gems (Gentoo way)

Gentoo has a problem with charlock_holmes due to its LDFLAGS.
In order to fix it, you have to edit rbconfig.rb:

$ nano -w /usr/lib/ruby/1.9.1/x86_64-linux/rbconfig.rb

Find the line below (hint: search for “undefined”, it will be the 1st result) and remove the last ldflag:

CONFIG["LDFLAGS"] = "-L. -Wl,-O1 -Wl,--as-needed -rdynamic -Wl,-export-dynamic -Wl,--no-undefined"

Change to:

CONFIG["LDFLAGS"] = "-L. -Wl,-O1 -Wl,--as-needed -rdynamic -Wl,-export-dynamic"

Now you can install charlock_holmes and gitlab:

$ gem install charlock_holmes $ sudo -u gitlab -H bundle install --deployment --without development test postgres

If you want, revert the changes you made to rbconfig.rb.


6.5 Configure Git (Gitlab way)

$ sudo -u gitlab -H git config --global user.name "GitLab" $ sudo -u gitlab -H git config --global user.email "gitlab@localhost"


6.6 Setup GitLab Hooks (Gitlab way)

$ sudo cp ./lib/hooks/post-receive /home/git/.gitolite/hooks/common/post-receive $ sudo chown git:git /home/git/.gitolite/hooks/common/post-receive


6.7 Initialise Database and Activate Advanced Features (Gentoo way)

If you are on hardened Gentoo using PAX, you have to adjust your ruby by disabling mprotect for it:

$ paxctl -m /usr/bin/ruby19

Start redis and mysql if you haven’t already, and add them to the default runlevel.

$ eselect rc start mysql $ eselect rc start redis $ eselect rc add mysql default $ eselect rc add redis default

Proceed to setup Gitlab:

$ sudo -u gitlab -H bundle exec rake gitlab:app:setup RAILS_ENV=production


6.8 Check Application Status (Gitlab way with a note)

The normal check suggested by the official instructions, may fail:

$ sudo -u gitlab -H bundle exec rake gitlab:env:info RAILS_ENV=production

The thorough one should pass though, complaining only for Gitlab not running yet and missing the init script:

$ sudo -u gitlab -H bundle exec rake gitlab:check RAILS_ENV=production


6.9 Install Init Script (Gentoo way)

Fortunately a Gentoo init script already exists, so I didn’t have to write it from scratch.
Currently you can find it at this gist. In case this link stop working, google for gitlab gentoo init script and you surely get some results with updated versions of this script. ;)

Download the gist, extract the init script and move it to your init.d directory. You may need to adjust the filenames and/or urls below.

$ cd /tmp $ wget https://gist.github.com/2360407/download $ tar xf download $ mv gist2360407-aea491f595955282bdc0a259e9fccc8cae3e7274/gistfile1.sh /etc/init.d/gitlab $ rm -r gist2360407-aea491f595955282bdc0a259e9fccc8cae3e7274 $ chmod 755 /etc/init.d/gitlab

If you installed Gitlab on a different path, adjust your init script:

$ nano -w /etc/init.d/gitlab

Update: Yesterday (22/01/2013) Gitlab 4.1 came out which uses sidekiq instead of resque. I adjusted the init script and you can find it here: Gitlab 4.1 init script for Gentoo.


7. Apache

On my server I use Apache behind varnish. So, I will give you instructions for Apache.

Gitlab is a rails app. It runs on its own server (unicorn in our case) and Apache (or nginx) serve as a proxy.

By default, Gitlab (unicorn) listens on a socket. We want it to listen on a port. Set it below. Also you can set the worker processes to 1 in order to save some RAM. Generally, you don’t want to run Gitlab on a machine with less than 1GiB RAM, unless you only run Gitlab on it. With 1GiB though, your machine will be left with enough free RAM to work as a competent web server hosting many LAMP sites/apps.

$ sudo -u gitlab -H nano -w /home/gitlab/gitlab/config/unicorn.rb

Your Apache should have the proxy modules as well as the byrequests method. These can be enabled by the appropriate APACHE2_MODULES.

If you have to rebuild your Apache to get them, don’t forget to restart it, a reload won’t help.

Also do not forget to enable proxy and ssl (-D PROXY -D SSL -D SSL_DEFAULT_VHOST) for your Apache setup at /etc/conf.d/apache2.

Next you have to set up Apache’s virtual host for Gitlab.

$ nano -w /etc/apache2/vhosts.d/20-gitlab.conf

I hope you can adjust the file below to your setup. Notice that in my example I have set unicorn to listen on port 8080.

  ServerName gitlab.myserver.com
  ServerAlias www.gitlab.myserver.com
  DocumentRoot /home/gitlab/gitlab/public
  ErrorLog /var/log/apache2/gitlab.myserver.com_error_log
  CustomLog /var/log/apache2/gitlab.myserver.com_access_log combined


    AllowOverride All
    Options -MultiViews

  RewriteEngine on
  RewriteRule ^/(.*)$ balancer://unicornservers%{REQUEST_URI} [P,QSA,L]

  ProxyPass /uploads !
  ProxyPass / balancer://unicornservers/
  ProxyPassReverse / balancer://unicornservers/
  ProxyPreserveHost on

      Order deny,allow
      Allow from all

  ServerName gitlab.myserver.com
  ServerAlias www.gitlab.myserver.com
  DocumentRoot /home/gitlab/gitlab/public
  ErrorLog /var/log/apache2/gitlab.myserver.com_error_log
  CustomLog /var/log/apache2/gitlab.myserver.com_access_log combined

      Header add X-Forwarded-Proto "https"

    AllowOverride All
    Options -MultiViews

  RewriteEngine on
  RewriteRule ^/(.*)$ balancer://unicornservers%{REQUEST_URI} [P,QSA,L]

  ProxyPass /uploads !
  ProxyPass / balancer://unicornservers/
  ProxyPassReverse / balancer://unicornservers/
  ProxyPreserveHost on

      Order deny,allow
      Allow from all

  SSLEngine on
  SSLCertificateFile /etc/ssl/apache2/server.cert
  SSLCertificateKeyFile /etc/ssl/apache2/server.key

If you want to restrict Gitlab to ssl for enhanced security, add this to the plain http section of your vhost configuration and remove the proxy/rewrite lines:

RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

You are almots ready to use Gitlab!

Start gitlab service and add it to the default runlevel. Also start or reload Apache:

$ eselect rc start gitlab $ eselect rc add gitlab default $ eselect rc reload apache2

Now open your browser and visit your new Gitlab installation.
Your credentials are admin@local.host / 5iveL!fe.

I hope everything went ok and you can start using Gitlab right away.

Remember, Gitlab updates on 22th every month. To upgrade your installation visit Gitlab’s wiki and follow their instructions.

Update: Gitlab on a rolling distribution

When you install gems, you compile them for your system, tying them to your system’s libraries. As we know very well on Gentoo, sometimes an update to a library can brake a program that depends on it.
Same goes for Gitlab, only, because we install it for a local user instead system wide, revdep-rebuild can’t detect the breakage automatically (but it will detect it for packages installed with gem system wide at /usr/local).

Let’s try to fix this!

Condition: After an emerge -u you find Gitlab stopped working.

First make sure that there are broken files, in /usr/local and/or in /home/gitlab:

$ revdep-rebuild $ SEARCH_DIRS="/home/gitlab/" revdep-rebuild

If charlock_holmes or a system wide gem is broken, reinstall it:

$ gem install BROKEN_SYSTEM_WIDE_GEM $ sudo -u gitlab -H gem install charlock_holmes

If another user gem is broken, it is part of bundle. We have to remove bundle’s files, to force a rebuild in the next command:

$ rm -rf /home/gitlab/gitlab/vendor/bundle

Last, create a fresh bundle for Gitlab.

$ cd /home/gitlab/gitlab/ $ sudo -u gitlab -H bundle install --deployment --without development test postgres

That’s it. Now your Gitlab should once again work fine.
A final note; Gitlab may be the UI/Wiki/Emailer etc but it is not your git server. So while you try to fix Gitlab, your repositories still work fine.

http://www.andmarios.com/en/2012/12/gitlab-40-on-a-gentoo-server-amd64-hardened-w-apache/feed/ 4
GitLab on an Ubuntu 10.04 server with Apache http://www.andmarios.com/en/2012/06/gitlab-on-an-ubuntu-10-04-server-with-apache/ http://www.andmarios.com/en/2012/06/gitlab-on-an-ubuntu-10-04-server-with-apache/#comments Sat, 23 Jun 2012 23:08:34 +0000 Marios http://www.andmarios.com/?p=987 Recently I saw the light, or something very bright at least, and decided it is time to use a central git repository to store my personal projects which span across many categories (code, documentation, translations, scripts, etc). Alas, as it usually is the case when you decide to change your workflow, you have to give it a bit more thought.

The thing about personal projects, is that there are too many of them and none has a known or at least certain development timeline. I may work on my backup script (mrbStudio) today and touch it again after two years, when I’ll need a new feature. Thus, the need for project management: documentation, issues, code snippets, etc. Anything that can help me get on track with a project I abandoned for some months -or more.

The simple (and probably correct) way would be to use a flat file policy, just add a README, ISSUES etc text file in the project’s directory. But I thought a dedicated solution could be better at this, making my workflow more efficient. It would make my projects index better looking too.

I checked some open source project management solutions, like Redmine and its fork, the ChiliProject, as well as indefero and others, but decided that for what would mostly be personal use, GitLab is the best choice out there.

GitLab is essentially a personal GitHub. You set up git and gitolite, and then GitLab sits on top of that, managing gitolite (users, projects, ssh keys), giving you a nice web interface and providing you some extra features, like wiki pages, a wall, issues management and others. It even recognizes and formats documents written in markdown (like the README.md files you see on GitHub) which is great for documentation writing.

To the code!

GitLab has a very good installation documentation but in order to keep it simple, the writers describe the process of installing GitLab mostly on a dedicated to GitLab server.

I chose to install it on a normal Ubuntu 10.04 based webserver which hosts some domains and is using Apache. So I will show you how to set (and manage) GitLab for such a setup while maintaining your style.

Through this guide, no reboots nor Apache downtime will occur.

Disclaimer: To use this guide, you must have the super power of… thinking. If you want to just copy – paste, it will probably not work for you and certainly you shouldn’t perform administration tasks on a public server. At every step check the possible variables of each command and set them for your setup.

1. Installing gitolite and GitLab

The developers of GitLab did a great job writing their installation guide and do their best to keep it updated. So it would be foul of me to just copy paste their work.

Just head over their GitHub page and read their installation instructions apart from the parts for the resque process and the web server (nginx, unicorn, init script) for the time being.

At the time of the writing of this article, GitLab is at version 2.6.0. You can find the installation instructions for the most recent stable release at the project’s wiki.

2. Deviating from the official guide for GitLab installation

As good as the above guide may be, you may have to deviate a bit or perform additional steps. Here are some I can think of.

Important: These steps would be better to be performed before you reach the Setup DB step of the official installation guide.

2.1. Installing the latest version of Ruby

The latest Ruby version for now is 1.9.3-p194, so you could use that instead of the 1.9.2-p290.

$ wget http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p194.tar.gz $ tar xzvf ruby-1.9.3-p194.tar.gz $ cd ruby-1.9.3-p194 $ ./configure $ make $ sudo make install

2.2. Configure gitlab.yml

You should edit your gitlab/config/gitlab.yml to at least reflect your real host under the git_host section. This is useful because it sets how GitLab will show your project’s URIs. Also set anything else you think of use.

2.3. If you use a custom ssh port

Usually in public servers we don’t use the default ssh port (22) in order to avoid some of the automated attacks out there, targeting known ports.

If that’s your case, start by setting your ssh port in gitlab.yml under the git_host section.

Then create the file:


And set it like this (assuming your ssh port is 10001):
Host localhost Port 100001

2.4. Create a MySQL database if you need one

GitLab’s installation guide doesn’t deal with that but you probably should know how to create a MySQL database and a user for it.

In case you don’t remember, you run MySQL:

$ mysql -u root -p

In the MySQL prompt that will appear, you type (change any variable you may need, like *password*):

mysql> create database gitlabdb; mysql> create user 'gitlab'@'localhost' identified by 'password'; mysql> grant all privileges on gitlabdb.* to 'gitlab'@'localhost' with grant option; mysql> exit;

Set your database credentials in gitlab/config/database.yml

3. Apache setup

Update: Originally this guide suggested to use Phusion Passenger to serve GitLab instead of Unicorn. Since then (yesterday that would be) I’ve found that Unicorn performs considerably faster and maybe consumes a bit less RAM. So we are going to use Unicorn.

3.1. Configure Unicorn

As the official installation guide instructs, create the unicorn configuration file:

$ sudo -u gitlab -H cp /home/gitlab/gitlab/config/unicorn.rb.orig /home/gitlab/gitlab/config/unicorn.rb

Now edit gitlab/config/unicorn.rb and add a listening port. Just uncomment the following line and set a custom port if you want:

listen ""

3.2. Enable and load needed Apache modules

We need the proxy, proxy_balancer and proxy_http Apache modules. Enable them:

$ sudo a2enmod proxy proxy_balancer proxy_http

In order for Apache to load the new modules, it has to be restarted. This is the only restart of the Apache service we are going to need:

$ sudo /etc/init.d/apache2 restart

3.3. Create a virtualhost for GitLab

Create a configuration file for GitLab’s virtualhost:


Insert the lines below (adjusted accordingly) to your GitLab site’s configuration file (the one we created). If you don’t need a ssl section, remove it. If you want to keep it, I assume you know where your ssl certificates are. Notice that the SSL virtualhost needs a specific IP instead of generic. Also if you set a custom port for Unicorn, do not forget to set it at the BalanceMember line.

<VirtualHost *:80>
  ServerName gitlab.myserver.com
  ServerAlias www.gitlab.myserver.com
  DocumentRoot /home/gitlab/gitlab/public
  ErrorLog /var/log/apache2/gitlab.myserver.com_error_log
  CustomLog /var/log/apache2/gitlab.myserver.com_access_log combined

  <Proxy balancer://unicornservers>

  <Directory /home/gitlab/gitlab/public>
    AllowOverride All
    Options -MultiViews

  RewriteEngine on
  RewriteRule ^/(.*)$ balancer://unicornservers%{REQUEST_URI} [P,QSA,L]

  ProxyPass /uploads !
  ProxyPass / balancer://unicornservers/
  ProxyPassReverse / balancer://unicornservers/
  ProxyPreserveHost on

   <Proxy *>
      Order deny,allow
      Allow from all

<VirtualHost MY_IP:443>
  ServerName gitlab.myserver.com
  ServerAlias www.gitlab.myserver.com
  DocumentRoot /home/gitlab/gitlab/public
  ErrorLog /var/log/apache2/gitlab.myserver.com_error_log
  CustomLog /var/log/apache2/gitlab.myserver.com_access_log combined

  <Proxy balancer://unicornservers>
      Header add X-Forwarded-Proto "https"

  <Directory /home/gitlab/gitlab/public>
    AllowOverride All
    Options -MultiViews

  RewriteEngine on
  RewriteRule ^/(.*)$ balancer://unicornservers%{REQUEST_URI} [P,QSA,L]

  ProxyPass /uploads !
  ProxyPass / balancer://unicornservers/
  ProxyPassReverse / balancer://unicornservers/
  ProxyPreserveHost on

   <Proxy *>
      Order deny,allow
      Allow from all

  SSLEngine on
  SSLCertificateFile /home/gitlab/gitlab/ssl.cert
  SSLCertificateKeyFile /home/gitlab/gitlab/ssl.key

Enable your GitLab virtual host for Apache:

$ sudo a2ensite gitlab.myserver.conf

Reload Apache for your GitLab virtualhost to start:

$ sudo /etc/init.d/apache2 reload

While your GitLab virtual host is up now, it doesn’t work as GitLab hasn’t started yet. To the next section!

4. GitLab Unicorn and Resque init script

This part is almost identical to the official guide except the insserv directive which doesn’t work for Ubuntu.

Create the file:


Put these lines inside it. They are copied from the official installation guide, so check the official installation guide for possible updates.

#! /bin/bash ### BEGIN INIT INFO # Provides: gitlab # Required-Start: $local_fs $remote_fs $network $syslog redis-server # Required-Stop: $local_fs $remote_fs $network $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: GitLab git repository management # Description: GitLab git repository management ### END INIT INFO

DAEMON_OPTS="-c /home/gitlab/gitlab/config/unicorn.rb -E production -D" NAME=unicorn DESC="Gitlab service" PID=/home/gitlab/gitlab/tmp/pids/unicorn.pid RESQUE_PID=/home/gitlab/gitlab/tmp/pids/resque_worker.pid

case "$1" in start) CD_TO_APP_DIR="cd /home/gitlab/gitlab" START_DAEMON_PROCESS="bundle exec unicorn_rails $DAEMON_OPTS" START_RESQUE_PROCESS="./resque.sh"

echo -n "Starting $DESC: " if [ `whoami` = root ]; then sudo -u gitlab sh -l -c "$CD_TO_APP_DIR > /dev/null 2>&1 && $START_DAEMON_PROCESS && $START_RESQUE_PROCESS" else $CD_TO_APP_DIR > /dev/null 2>&1 && $START_DAEMON_PROCESS && $START_RESQUE_PROCESS fi echo "$NAME." ;; stop) echo -n "Stopping $DESC: " kill -QUIT `cat $PID` kill -QUIT `cat $RESQUE_PID` echo "$NAME." ;; restart) echo -n "Restarting $DESC: " kill -USR2 `cat $PID` kill -USR2 `cat $RESQUE_PID` echo "$NAME." ;; reload) echo -n "Reloading $DESC configuration: " kill -HUP `cat $PID` kill -HUP `cat $RESQUE_PID` echo "$NAME." ;; *) echo "Usage: $NAME {start|stop|restart|reload}" >&2 exit 1 ;; esac

exit 0

Make the script executable:

$ sudo chmod +x /etc/init.d/gitlab

For this time only, start GitLab manually by invoking our init script:

$ sudo /etc/init.d/gitlab start

Set GitLab’s init script to start automatically upon boot:

$ sudo update-rc.d gitlab defaults

Note: For the above script, I think the reload and restart commands won’t probably work. You don’t need them anyway, just do a start/stop when you need to.

Congratulations! Your GitLab is up and running!

5. Updating GitLab without interrupting the web server

Since you are on a proper webserver, hosting more than one sites, you cannot afford downtime.

The official guide about upgrading GitLab goes like this (official way to upgrade from 2.5.0 to 2.6.0).

For our setup, we can avoid Apache downtime and only have GitLab downtime which should be ok.

Just follow the commands below while adjusting for your setup if needed, they are easy to understand. They are the commands from the official upgrade guide but first we stop only the GitLab virtualhost and service, make the upgrade and restart them.

Update: While the commands below serve as a nice “update skeleton”, it would be sane to check gitlab’s documentation for version specific upgrade tasks. For example during the upgrade from 2.6.x to 2.7.0, the gitlab.yml format changed, so on top of the commands below, you had to update this file.

$ sudo su # you just became root, be careful $ a2dissite gitlab.myserver.conf $ /etc/init.d/apache2 reload $ /etc/init.d/gitlab stop $ cd /home/gitlab/gitlab $ sudo -u gitlab -H git pull origin stable $ sudo -u gitlab -H bundle install --without development test $ sudo -u gitlab -H bundle exec rake db:migrate RAILS_ENV=production $ a2ensite gitlab.myserver.conf $ /etc/init.d/apache2 reload $ /etc/init.d/gitlab start

That’s all folks, hope I helped some of you.

http://www.andmarios.com/en/2012/06/gitlab-on-an-ubuntu-10-04-server-with-apache/feed/ 29
Yet Another Backup Script: mrbStudio http://www.andmarios.com/en/2012/06/yet-another-backup-script-mrbstudio/ http://www.andmarios.com/en/2012/06/yet-another-backup-script-mrbstudio/#comments Wed, 13 Jun 2012 19:43:53 +0000 Marios http://www.andmarios.com/?p=961 Some years ago I decided that I needed backups. Our systems are more fragile than we tend to think; hardware break downs, hard disks failures, laptop thefts, accidents, software malfunctions or user errors can strip us of our precious data. By data I mean both things we can’t afford to lose (like your work files or photographs) or things it would take a great amount of time to replace (like your OS installation along with a ton of custom settings).

I tried to think of a backup policy that would work for me, an advanced user. I knew I wanted something that would be easy to access, like a copy of an original directory and maybe versions, so I can return my files to a point in time. After that I searched the net for tested policies and solutions on the matter. What I liked best was rsync (which I already used for simple backups) and hard links. I think this guide was the one that grabbed my attention. I didn’t use the script which it includes, but I learnt all about hard links and how to use them to reserve space.

After that I proceeded to write my own script, mrbStudio, which I use since then for my backups and that have saved my ass more than a few times.

What it does? It copies the directory you want to backup to a backup directory, while preserving any special information you may need (file attributes, ownerships, links, devices, etc). Only the first time though it copies the whole directory. Next time, it uses the most recent backup as a starting point (hard-linking to it or snapshotting if you use btrfs) and copies only the files that have changed since. This saves time and space. It could save more space if something like rdiff was used but that would make my backups inaccessible through easy means. I want my backups accessible, that is a priority.

I won’t go in much detail. Since mrbStudio helped me many times and became part of my system maintenance routine, I thought I should share it. Cleaning, restructuring the code and adding documentation for this task, also helped me make it better.

Its features:

  •  Versioned backups of local and remote filesystems (through ssh) to a local filesystem.
  •  Easy to run once you create your configuration files, no need to postpone your backups again.
  •  Hard links or btrfs snapshots are used for backup versions in order to save time and space.
  •  Easy way to exclude files from backups.
  •  Automatic mounting of local and/or remote filesystems if needed.
  •  Backups are exact copies of the original directories, no special software needed to access them, only a shell.
  •  Script is compact and easy to modify. You need an extra feature? You can implement it fast.

Running it is easy. First you have to create a configuration file. Let’s say you want to backup your home to /media/backups/. Create a home.mrbStudio text file like this:


Now call mrbStudio with the above file as parameter:

$ mrbStudio home.mrbStudio

That’s it, congratulations, your first backup is ready. Next one will take less time (and space).

You will understand it much better once you take a look at the examples that come with the script.

You can find the latest version at github: https://github.com/andmarios/mrbStudio

Extra tip!

Btrfs is almost mainstream these days and performs so well that I use it for my rootfs and for one of my backup disks. A cool feature of btrfs is subvolumes, which you can mount as partitions. Getting what am I going to say? I just installed grub in a small partition on my usb hard disk I use for backups and now, by editing just two files (fstab and grub.conf), I can boot into my backups through usb! How cool is that?

I get my main system (a laptop) stolen? I find a replacement system, I edit two lines of two files on my usb disk and I can boot into my system and continue my work like nothing happened. When I find the time I can make the system more permanent, like copy it to the internal disk of the new system.

http://www.andmarios.com/en/2012/06/yet-another-backup-script-mrbstudio/feed/ 1
adversities: dog day http://www.andmarios.com/en/2011/10/adversities-dog-day/ http://www.andmarios.com/en/2011/10/adversities-dog-day/#comments Mon, 10 Oct 2011 11:20:42 +0000 Marios http://www.andmarios.com/?p=883 Yesterday afternoon I took my camera with my favorite -and only prime- lens, the EF 50mm f/1.8, to exploit the rare light of the upcoming storm.

The weather conditions were difficult and the beach isn’t a good place to be with an entry level camera when heavy wind duels around you.

I was hoping for a good static shot, when suddenly I saw this black dog heading into my frame. I shot immediately without thinking and the shutter clicked at the right moment.

Definitely one of my favorite photographs. Click to enlarge.

http://www.andmarios.com/en/2011/10/adversities-dog-day/feed/ 0
before instagram -and a bit of a rant http://www.andmarios.com/en/2011/09/before-instagram-and-a-bit-of-a-rant/ http://www.andmarios.com/en/2011/09/before-instagram-and-a-bit-of-a-rant/#comments Thu, 22 Sep 2011 17:25:08 +0000 Marios http://www.andmarios.com/?p=801 These days social networks’ inhabitants can often be divided into pro-instagram and anti-instagram.

The former usually don’t put much thought into it, they just post happily their photographs after a quick post-processing with instagram’s filters. The latter are either tired of the way more than we need and are able to follow through human measure instagram posts or can’t put up with the fact that instagram processed photographs are often mistaken (a strong word, I know, a stronger one comes soon) for art and, as a further consequence, sometimes act as an excuse for pro-instagrammers to post complete and utter bullshit (I told you).

Let’s start with the easiest case to understand; when someone thinks of something as art, automatically drops any logical thresholds that may apply prior to sharing it on a social network. A bad photograph won’t get any better with instagram. You can’t filter out a bad shot. It is as simple as that.

The other case is when we have a photograph worthy to share on a social network but not in the form of art per se. There are many definitions for art and I wouldn’t dare to choose any single one to present as the norm. What I believe though to be a prerequisite for it, is a mix of self creativity -even in the form of imitation- and the investment of personal time. Instagram, in the common case, almost minimizes these two conditions to null. When prerequisites for art are minimized to such an extend, the result unavoidably becomes kitch and bothers.

Of course I have to admit that there are numerous talented people using instagram and the above doesn’t apply to them. Also there are people not that talented but with an understanding of which photo can be instagrammed and which should be uploaded to other photo-hosts without any effects applied. The problem is that the vast majority of instagram bombing we get daily, isn’t coming from them.

Below is an old post-processed photograph of mine. I shot it and edited it about 6 years before instagram was born. It may not qualify as art but I can assure you that a certain amount of time and thought was invested during both the scene composition and the edit process.


http://www.andmarios.com/en/2011/09/before-instagram-and-a-bit-of-a-rant/feed/ 0
Granny Hair http://www.andmarios.com/en/2011/09/granny-hair/ http://www.andmarios.com/en/2011/09/granny-hair/#comments Wed, 21 Sep 2011 13:44:11 +0000 Marios http://www.andmarios.com/?p=791 The Greek phrase for cotton candy is granny hair. This photo was shot in June, at the old harbor of Chania, during a blackout. I like it because I see in it many values which would be nice to apply in our everyday life; family, hard work, respect of our past.

http://www.andmarios.com/en/2011/09/granny-hair/feed/ 0
What is your favorite… http://www.andmarios.com/en/2011/09/what-is-your-favorite/ http://www.andmarios.com/en/2011/09/what-is-your-favorite/#comments Tue, 20 Sep 2011 20:55:29 +0000 Marios http://www.andmarios.com/?p=779 Sorry, this entry is only available in Ελληνικά.

http://www.andmarios.com/en/2011/09/what-is-your-favorite/feed/ 2
how to choose who to follow on twitter http://www.andmarios.com/en/2011/08/how-to-choose-who-to-follow-on-twitter/ http://www.andmarios.com/en/2011/08/how-to-choose-who-to-follow-on-twitter/#comments Tue, 23 Aug 2011 19:02:04 +0000 Marios http://www.andmarios.com/?p=553 You are a heterosexual male. Your EQ (emotional quotient) isn’t something to brag about and most probably you wouldn’t want to brag about it anyway.

But here comes the difficult time of having to decide who to follow on twitter. Fear not my hairy friend. The illustrated algorithm below, which I devised upon whole minutes of research (but they seemed like ages mind you), can be your safe guide to choosing followers. It covers only 99% of cases but I had to keep it short, because I respect your short attention span and that’s the kind of man I am.

Without any further delay, I present you the algorithm of how to choose who to follow on twitter [for heterosexual males].

Right click, open link in new tab to enjoy in full size. ;)

As long as the copyright notice remains visible in the image, feel free to use it for your own dirty purposes.

http://www.andmarios.com/en/2011/08/how-to-choose-who-to-follow-on-twitter/feed/ 0
Porn vs War http://www.andmarios.com/en/2011/03/porn-vs-war/ http://www.andmarios.com/en/2011/03/porn-vs-war/#comments Fri, 04 Mar 2011 18:55:14 +0000 Marios http://www.andmarios.com/?p=509 Warning #1: This post may change the image you have for me, but it shouldn’t. Humor, in all of its instances, is a sign of a healthy mind.
Warning #2: If you aren’t comfortable reading about porn and despicable sex acts, please, do not read any further!

I’ve given a fair amount of thought in this post’s subject. What are the differences between war and porn, if any? Actually there are many. I won’t tire you with a long prologue, here are some of the differences I’ve found. If you can think of any more, post them!

  • Warlords come and conquer. Porn stars conquer and cum.
  • In war they provide you with a gun. In porn you come with your own.
  • In porn the enemy helps you get a headshot.
  • You can make war in the dark.
  • In porn you try to look good in the camera. In war you don’t want to look good.
  • In war everyone hates assholes. In porn everyone licks them.
  • In war women are spared. In porn there is no mercy for them.
  • In the army you shave your face. In the porn industry your genitals.
  • In war privates doesn’t get much publicity. In porn it is all about privates.
  • In war the enemy tries to avoid your load. In porn she tries to swallow it.
  • In porn you can’t wait to stand in front of enemy’s canons.
  • In porn the other side easily turns their backs on you.
  • In porn your enemy may ask you to violate her human rights.
  • In porn pain can be an aphrodisiac.
  • In porn you don’t see many helmets.
  • In porn 2 vs 1 is fair.
  • In war impalement is used as capital punishment.
  • In war you don’t want many opened fronts.

I may or may not update it in the future!


PS. Since I feel good about this, here is a photo for your viewing pleasure.


http://www.andmarios.com/en/2011/03/porn-vs-war/feed/ 1
old photo, new post processing http://www.andmarios.com/en/2010/11/old-photo-new-post-processing/ http://www.andmarios.com/en/2010/11/old-photo-new-post-processing/#comments Thu, 18 Nov 2010 17:45:33 +0000 Marios http://www.andmarios.com/?p=490 Too much time has passed since my last published post -though my drafts keep piling. Today I want to share with you a photograph I took a long time ago, during a trip to Heraklion, Crete.

I knew from the moment my finger started moving toward the shutter button that I would love this shot. For some reason though I never post processed it till yesterday. I usually do not post process my photos but this one was shot at harsh conditions and needed some “repairs”.  In the end my “repairs” were more creative than what I originally planned but I am satisfied with the result.

Sad [melancholic] Dog, click to enlarge

http://www.andmarios.com/en/2010/11/old-photo-new-post-processing/feed/ 0
Wallpaper: KDE – permanent type http://www.andmarios.com/en/2010/03/wallpaper-kde-permanent-type/ http://www.andmarios.com/en/2010/03/wallpaper-kde-permanent-type/#comments Thu, 18 Mar 2010 22:05:03 +0000 Marios http://www.andmarios.com/?p=448 This is the fourth and last wallpaper of the KDE wallpapers week. It is the less “clean” image in this series. I think that it doesn’t match up well with widgets but if you have a virtual desktop clean of plasmoids you will love it. It is so good it may even get you a girlfriend! :p

Creative Commons License

KDE – permanent type by Marios Andreopoulos is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License.

Permissions beyond the scope of this license may be available at http://www.andmarios.com/lang/en/contact/.

KDE and the KDE logo are trademarks of KDE e.V.

http://www.andmarios.com/en/2010/03/wallpaper-kde-permanent-type/feed/ 0