Migrate from SVN to GIT - step by step tutorial

Lately I faced a new challenge. To fully migrate our SVN environment to GIT. After reading a little bit on internet I come up with this plan:

  1. Deploy a GIT server
  2. Create a new bare repository
  3. Make a SVN Clone on a different machine
  4. Push it on GIT server

Assumptions:

SVN Repository: https://192.168.0.5/svn/documentation

GIT Server: 192.168.0.22

Client: A Microsoft Windows machine with some IP from 192.168.0.1/24

Prerequisite packages for our client: TortoiseGit  and msysgit. For this tutorial I used: TortoiseGit-1.8.4.0-64bit.msi and msysGit-fullinstall-1.8.3-preview20130601.exe

Add C:\msysgit\msysgit\cmd to the %PATH% (I am not going to cover this here, but you can check this website: http://www.computerhope.com/issues/ch000549.htm)

1. Deploy GIT/GITOLINE/GITWEB

Server side - I assume we have a fresh debian/ubuntu installation

1.1. Install required software

[codesyntax lang="bash"]

apt-get install vim git

[/codesyntax]

1.2. Create user git with disabled password and login shell bash

[codesyntax lang="bash"]
adduser \
 --system \
 --shell /bin/bash \
 --gecos 'git version control' \
 --group \
 --disabled-password \
 --home /home/git \
 git

[/codesyntax]

1.3.  Now login with user git

[codesyntax lang="bash"]

su -l git

[/codesyntax]

1.4.  Install Gitolite

[codesyntax lang="bash"]

cd /home/git; git clone git://github.com/sitaramc/gitolite
mkdir $HOME/bin
gitolite/install -ln

[/codesyntax]

Client side

1.5. Generate RSA key (Create RSA key, after hiting the command just press enter when it ask for passphrase.). This key will be transferred to git server.

[codesyntax lang="bash"]

C:\Users\joe>C:\msysgit\msysgit\bin\ssh-keygen -t rsa -C "Git-Admin"
Generating public/private rsa key pair.
Enter file in which to save the key (//.ssh/id_rsa): c:\users\joe\.ssh\id_rsa
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in c:\users\joe\.ssh\id_rsa.
Your public key has been saved in c:\users\joe\.ssh\id_rsa.pub.
The key fingerprint is:
aa:38:be:f9:3c:d0:87:fe:de:5a:a9:71:1d:d3:38:01 Git-Admin

[/codesyntax]

1.6. From client scp the key into git server.

[codesyntax lang="bash"]

C:\msysgit\msysgit\bin\scp C:\Users\joe\.ssh\id_rsa.pub root@192.168.0.22:~

[/codesyntax]

Server side

1.7. Now setup the Git Admin. Please note that we must be logged in with git user. To check this use whoami command

[codesyntax lang="bash"]

whoami
sudo mv /root/id_rsa.pub /home/git/Git-Admin.pub; sudo chown git:git /home/git/Git-Admin.pub
bin/gitolite setup -pk Git-Admin.pub

[/codesyntax]

1.8. Git user should be in the same group as your Apache user

[codesyntax lang="bash"]

sudo usermod -a -G www-data git
sudo chmod ug+rx /home/git/repositories

[/codesyntax]

Client side

1.9. Clone gitolite-admin repository. Now gitolite-admin directory will be present after cloneing from git server. The gitolite.conf is mainly use for User and group ACL for git server. Now from your system you can easily manage the user group ACL. But for this you have to do git push.

[codesyntax lang="bash"]

git clone git@192.168.0.22:gitolite-admin.git
cat gitolite-admin/conf/gitolite.conf

[/codesyntax]

repo gitolite-admin

    RW+     =   Git-Admin
 
repo testing
    RW+     =   @all

Server side

1.10. Edit the /home/git/.gitolite.rc and change the UMASK to 0002 and GIT_CONFIG_KEYS to '.*'

[codesyntax lang="bash"]

vim /home/git/.gitolite.rc
:%s/0077/0002/
:%s/'',/'.*',/
:wq

[/codesyntax]

1.11. Install gitweb

[codesyntax lang="bash"]

sudo apt-get install gitweb

[/codesyntax]

1.12. Configure gitweb. Edit /usr/lib/cgi-bin/gitweb.cgi and change the value of $projectroot as "/home/git/repositories" and $projects_list as "/home/git/projects.list"

[codesyntax lang="bash"]

sudo vim /usr/lib/cgi-bin/gitweb.cgi
:%s/our $projectroot = "\/pub\/git";/our $projectroot = "\/home\/git\/repositories\/";/
:%s/our $projects_list = "";/our $projects_list = "\/home\/git\/projects.list";/
:wq

[/codesyntax]

[codesyntax lang="bash"]

sudo vim /etc/gitweb.conf
:%s/$projectroot = "\/var\/cache\/git";/$projectroot = "\/home\/git\/repositories\/";/
:%s/$projects_list = $projectroot;/$projects_list = "\/home\/git\/projects.list";/
:wq

[/codesyntax]

Note: if the $projects_list is commented, uncomment it (remove the # from the begining of the line)

2. Migrate from SVN to GIT

Server side

2.1. Create a new git bare repository

[codesyntax lang="bash"]

cd /home/git/repositories/
git init --bare documentation.git

[/codesyntax]

Client side

2.2. Getting the author information.

[codesyntax lang="bash"]

svn log --xml | grep -P "^<author" | sort -u | perl -pe 's/<author>(.*?)<\/author>/$1 = /' > users.txt

[/codesyntax]

That gives you the log output in XML format - you can look for the authors, create a unique list, and then strip out the XML. (Obviously this only works on a machine with grep, sort, and perl installed.) Then, redirect that output into your users.txt file so you can add the equivalent Git user data next to each entry. The users.txt file should look like:

(no author) = Alex <alex@example.com>
bear = Bear <kong@example.com>
monika = Monika <cristina@example.com>
igor = Igor <igor@example.com>
joe = Joe <joe@example.com>

You must execute this command on SVN repository folder. If you are using Windows, then the previous command will not work, so I suggest the following approach.

* Generate the file (svn_users.txt), change it as you like and trasfer it to a linux box (I use GIT server for this)

* Connect to GIT server and process the file there using:

[codesyntax lang="bash"]

cat svn_users.txt | grep -P "^<author" | sort -u | perl -pe 's/<author>(.*?)<\/author>/$1 = /' > users.txt
rm svn_users.txt

[/codesyntax]

* Transfer the file users.txt to Windows machine.

2.3. Add the new repo that we want to migrate to gitolite-admin\conf\gitolite.conf. The file should look something like this:

repo gitolite-admin
    RW+     =   Git-Admin
 
repo testing
    RW+     =   @all
 
repo documentation
    RW+     =   @all

At this point all users will have RW access to our git repository.

2.4. Add new users to GIT. For each user you will need to have to a pair of public/private keys. Copy public keys to keydir folder in gitolite-admin clone, add and push the changes.

2.5. Import SVN repository. This is going to take a while, so go and grab a snack or something.

[codesyntax lang="bash"]

git svn clone https://192.168.0.5/svn/documentation --authors-file=users.txt --no-metadata

[/codesyntax]

2.6. The last thing to do is add the Git server as a remote and push to it.

[codesyntax lang="bash"]

git remote add origin git@192.168.0.22:documentation.git
git push origin --all
git push origin --tags

[/codesyntax]

3. Delete the imported SVN repository on client side and re-import it from GIT server

Server side

4. Securing Gitweb with htpasswd. At this point the Gitweb web page is accessible to all, which of course is not a good idea. So, if you would like to have a set of web pages that are protected, requiring a username/password to gain access, you will have to use htpasswd in apache and add users and passwords.

4.1. Configure htpasswd access in Gitweb

[codesyntax lang="bash"]

sudo vim /etc/apache2/conf.d/gitweb

[/codesyntax]

Alias /gitweb /usr/share/gitweb
 
<Directory /usr/share/gitweb>
    Options FollowSymLinks +ExecCGI
    AddHandler cgi-script .cgi
        AllowOverride None
    Order allow,deny
    Allow from all
    AuthType Basic
    AuthName "Git Access"
    Require valid-user
    AuthUserFile /etc/apache2/gitweb-htpasswd
</Directory>

4.2. Create htpasswd username and password.

[codesyntax lang="bash"]
sudo touch /etc/apache2/gitweb-htpasswd
sudo htpasswd -m /etc/apache2/gitweb-htpasswd user1
sudo htpasswd -m /etc/apache2/gitweb-htpasswd user2
sudo htpasswd -m /etc/apache2/gitweb-htpasswd user3

[/codesyntax]

4.3. Restart the apache server

[codesyntax lang="bash"]

sudo /etc/init.d/apache2 restart

[/codesyntax]

Note: You can use TortoiseGIT for doing all git operations on Windows Machine, of course. I was lazy and I didn't take screenshots with steps that you should do with TortoiseGIT :)

Links:

Force Chrome to tunnel DNS requests through a SSH socks proxy

Setup a socks proxy (check this page for more details) on port 8888 (the port is not that important).

Start chrome with the following parameters:

[codesyntax lang="bash"]

chrome --proxy-server="socks5://localhost:8888"

[/codesyntax]

Also we can check if this works and run the following command on the SSH server. The tcpdump will show show dns traffic for any activity in Chrome.

[codesyntax lang="bash"]

tcpdump -i eth0 port 53

[/codesyntax]

Encrypt your traffic from your Android device using a ssh tunnel

As I said with a previous ocasion in China the goverment is filtering the internet traffic (including mobile trafic, dohh) so you can't access different websites and/or services and this thing is very annoying. Well, what do you have to do if you want to navigate to youtube.com for instance? Hmmm... you will have to encrypt your traffic somehow. Bellow I will tell you what do you need and how to accomplish this from your Android device.

First of all you will need a ssh server configured somewhere outside China (preferably on a different port).

After getting a ssh server, you will need to download from Android Market the SSH Tunnel application written by MAX LV.

All you have to do is to complete Host, Port, User and Password filds and thick Use socks proxy, Enable GFW List, Enable DNS Proxy (this one is extremly important) options.

That's it!

OpenVPN through SSH

This is useful if you are behind a restrictive firewall that uses SPI to block services rather than plain old port blocking. An SPI firewall is able to distinguish between one packet type and another, without just checking the port that is in use.

You’ll need root access to the OpenVPN Server, as you have to change some of the server config files.

You need to do the folllowing changes:

  • change the line proto udp to proto tcp on client and server configuration file
  • add socks-proxy localhost 5555 in the OpenVPN client configuration file
  • create an SSH tunnel between the client machine and the OpenVPN Server. Assuming you’re running Linux/Unix with the OpenSSH client binary installed then run the command:

[codesyntax lang="bash"]

ssh -ND5555 user@test.org

[/codesyntax]

 

Note: If you are using Windows please read what this guy wrote here: http://blog.ramin-hossaini.com/2009/10/06/creating-a-tunnel-and-socks-proxy-with-putty/

Encrypt your web browsing session in one command

Recently I accepted a job proposition in Shenzhen/China. So, China here I come. Things are great here, western propaganda has nothing to do with what's going on here, except one thing: internet filtering. Google results are censured, so only "accepted" results are displayed, sites like facebook.com, twiter.com, youtube.com, thepiratebay.org, openvpn.net and so many more... What do you do to pass this filtering? The solution is to encrypt your browsing session.

Using a simple SSH command, I can encrypt all my web browsing traffic and redirect it through a trusted computer when I'm on someone else's network. Today I'll set up a local proxy server that encrypts my online activity from my desktop. Here's how:

What I'll need.

  • a SSH server to act as your proxy
  • a SSH client on the computer you're using

Note: Mac and *nix machines have SSH client built right in at the command line. Windows users can set up OpenSSH with Cygwin or PuTTY

What we are going to do.
What I am doing is setting up a "middle-person" (the SSH server which will act as a proxy) between me and the internet. Using the proxy, my browser hands off web page requests to the proxy server, which handles the request and fetches the page for me from the internet. The web site actually thinks the request is coming from the proxy server, not from my computer, which is a good way to obscure my originating IP address.

The good thing about this is my traffic is over SSH which is an encrypted protocol. This prevents wifi sniffers from seeing what I am doing online.

Setting up the server.
On the computer which is acting as desktop I am going to open up a connection to the SSH server:

[codesyntax lang="bash"]

ssh -ND 9999 user@test.org

[/codesyntax]

What this command does is hand off requests to localhost, port 9999, to the SSH server at test.org to handle.

Note:

  • if your SSH server listen on different port that standard port (22/tcp), it can changed using -p switch
  • the -N tells SSH not to open an interactive prompt, so it will just hang there, waiting. That's exactly what I want.

Setting up the client.
Once proxy's up and running, configure Firefox to use it. From Firefox's Tools menu, choose Options, and from the Advanced section choose the Network tab. Next to "Configure how Firefox connects to the Internet" hit the "Settings" button and enter the SOCKS information, which is the server name (localhost) and the port you used (in the example above, 9999.)

Save those settings and hit up a web page. When it loads, it's actually coming from the proxy server over an encrypted connection.

Tips.

  • Set your proxy server to resolve DNS requests instead of your computer; in Firefox's about:config area, set network.proxy.socks_remote_dns = true.
  • For those with slower connections, you can use the -C command line option to use SSH's compression (gzip).

How to install the same debian packages on another system

The approach is simple: generate a list of installed packages on Debian-based systems and install this list of packages on the new box. This approach is useful when you want to install the same packages on another fresh OS install for example.

1. To export the list of installed packages, proceed as follows:
[codesyntax lang="bash"]

dpkg --get-selections | grep -v deinstall > LIST_FILE

[/codesyntax]

The file LIST_FILE is small so it can be emailed to yourself by using:
[codesyntax lang="bash"]

dpkg --get-selections | grep -v deinstall > LIST_FILE && cat LIST_FILE | mailx -s "`hostname -f`: Package list" "user@test.org"

[/codesyntax]

2. Once you’ve got your server up and running with a fresh base install
[codesyntax lang="bash"]

apt-get update
apt-get dist-upgrade

[/codesyntax]

3. Move your LIST_FILE file into your home directory and run the following commands to recover the previous generated list:
[codesyntax lang="bash"]

dpkg --clear-selections
dpkg --set-selections < LIST_FILE

[/codesyntax]

4. Install the packages
[codesyntax lang="bash"]

aptitude install

[/codesyntax]

How to setup a VPN using ssh and pppd

This is a step by step guide for setting up a VPN using pppd and ssh. To accomplish this you will need two Linux boxes, one acting as server and the second one as client. The "server" must have a static IP address or dynamic dns name. The firewall on both boxes must allow traffic on port that sshd listens.

Server side

1. Install some package to make our job easier later

for deb based linux boxes:
[codesyntax lang="bash"]

apt-get install ipcalc

[/codesyntax]

for rpm based linux boxes:
[codesyntax lang="bash"]

yum install whatmask

[/codesyntax]

2. Create a local account on server to be used by the clients that are connecting.

[codesyntax lang="bash"]

adduser --system --group vpn

[/codesyntax]

3. Modify /etc/passwd file
[codesyntax lang="bash"]

vim /etc/passwd
:%s/\/home\/vpn:\/bin\/false/\/home\/vpn:\/bin\/bash/g
:wq

[/codesyntax]

4. Set a password for vpn account. The vpn account password will only be used while doing the initial configuration of your VPN clients, so I strongly recommend NOT to use a weak password.
[codesyntax lang="bash"]

passwd vpn

[/codesyntax]

5. This vpn account needs rights to bring the ppp connection up and down as well as modify the system routing table. Edit your sudoers file:
[codesyntax lang="bash"]

sudo visudo

[/codesyntax]

and append the following lines to the end of the file:

vpn ALL=NOPASSWD: /usr/sbin/pppd
vpn ALL=NOPASSWD: /sbin/route

6. Finally, we need to log in as the vpn and set up a few bits in its home folder.
[codesyntax lang="bash"]

sudo su - vpn
cd ~
mkdir .ssh

[/codesyntax]

Client side

1. Assuming eth0 is network interface connected to the network determine the local network details
[codesyntax lang="bash"]

CLIENT_LAN_IF="eth0"
LOCAL_IP=`ifconfig ${CLIENT_LAN_IF} | grep inet | awk '{print $2}' | sed 's/addr://'`
LOCAL_MASK=`ifconfig ${CLIENT_LAN_IF} | grep inet | awk '{print $4}' | sed 's/Mask://' | sed 's/Scope:Link//'`
LOCAL_NETWORK=`ipcalc $LOCAL_IP $LOCAL_MASK -n -b | grep Network | awk '{print $2}'`

[/codesyntax]

2. Start vpn to server
[codesyntax lang="bash"]

sudo /usr/sbin/pppd updetach noauth passive pty "/usr/bin/ssh -P host -lvpn -i id_rsa -o Batchmode=yes sudo /usr/sbin/pppd nodetach notty noauth" ipparam vpn 192.168.1.238:192.168.1.237

[/codesyntax]

Note:

  • local IP address 192.168.1.238
  • remote IP address 192.168.1.237

3. Make the server our gateway
[codesyntax lang="bash"]

sudo route add -net $LOCAL_NETWORK gw 192.168.1.238

[/codesyntax]

Links:
http://tuxnetworks.blogspot.ro/2011/05/howto-easiest-vpn-setup-ever.html

How to install TestLink on CentOS 6.3

Few days ago, QA guys asked me to install a tool that will make their work easier. This tool, Testlink, is an open-source management tool which includes test specification, planning, reporting, requirements tracking and collaborate with well-known bug trackers.

Below I will show you step-by-step how to install TestLink on CentOS 6.3, including the troubleshooting steps for most commonly faced issues.

1. Download Testlink. Check if a new version than I used bellow is available (http://sourceforge.net/projects/testlink/files/)
[codesyntax lang="bash"]

mkdir work
cd work
wget -c http://downloads.sourceforge.net/project/testlink/TestLink%201.9/TestLink%201.9.5/testlink-1.9.5.tar.gz
tar xfz testlink-1.9.5.tar.gz
mv testlink-1.9.5/* testlink-1.9.5/.[^.]* /var/www/html/
rm -fr ~/work/testlink-1.9.5
chown -R apache:apache /var/www/html/*

[/codesyntax]

2. Install required packages
[codesyntax lang="bash"]

yum install mysql-server php php-mysql php-gd

[/codesyntax]

Note: if you want authentication against ldap you will have to also install php-ldap package

3. Optimize php configuration for TestLink.
[codesyntax lang="bash"]

vim /etc/php.ini
:%s/max_execution_time = 30/max_execution_time = 120/g
:%s/session.gc_maxlifetime = 1400/session.gc_maxlifetime = 2400/g
:wq

[/codesyntax]

4. Set apache and mysql services to start at boot
[codesyntax lang="bash"]

chkconfig httpd on
chkconfig mysqld on

[/codesyntax]

5. Start apache and mysql services

[codesyntax lang="bash"]

service httpd start
service mysqld start

[/codesyntax]

6. Set mysql root password

[codesyntax lang="bash"]

mysqladmin -u root password YOURPASSWORD

[/codesyntax]

7. Open 80/tcp port in firewall. Add the following rule to /etc/sysconfig/iptables
[codesyntax lang="bash"]

vim /etc/sysconfig/iptables

[/codesyntax]
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
[codesyntax lang="bash"]

:wq

[/codesyntax]

My /etc/sysconfig/iptables on TestLink machine is:
[codesyntax lang="bash"]

cat /etc/sysconfig/iptables

[/codesyntax]

# Firewall configuration written by system-config-firewall
# Manual customization of this file is not recommended.
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT

If you don't want to have firewall on TestLink machine you can disable it
[codesyntax lang="bash"]

chkconfig iptables off
service iptables stop

[/codesyntax]

8. Restart firewall in order to apply the new rule
[codesyntax lang="bash"]

service iptables restart

[/codesyntax]

9. Create directories used by TestLink for logs and to upload files
[codesyntax lang="bash"]

mkdir -p /var/testlink/logs/
mkdir -p /var/testlink/upload_area/
chown apache:apache -R /var/testlink/

[/codesyntax]

11. Assuming all steps were carried out on a machine called testlink.test.org then open a browser and navigate to TestLink page http://testlink.test.org and setup first configuration.

Note: if you don't have a working DNS or this machine doesn't have a proper record in DNS server then you should navigate by the machine's IP: http://x.x.x.x/

12. Click "New installation"

13. Check I agree to the terms set out in this license and click Continue

14. A new checking report will be displayed. In this report shouldn't be fatal errors (maybe some warnings at most). If so, press Continue

15. Fill database access form and press Process TestLink Setup! button

Database host: localhost
Database name: testlink
Database admin login: root
Database admin password: YOURPASSWORD TestLink DB login: testlink
TestLink DB password: TESTLINK_PASSWORD

16. Remove Install directory
[codesyntax lang="bash"]

rm -fr /var/www/html/install/

[/codesyntax]

17. Modify the email settings
[codesyntax lang="bash"]

vim /var/www/html/custom_config.inc.php
:%s/\[smtp_host_not_configured]\/localhost/g
:%s/\[testlink_sysadmin_email_not_configured\]/root/g
:%s/\[from_email_not_configured\]/root/g
:%s/\[return_path_email_not_configured\]/root/g
:wq

[/codesyntax]

19. Set an alias for root, so all emails to root to go the new alias - this step is optional
[codesyntax lang="bash"]

vim /etc/aliases
root: testlink_admin@test.org
:wq

[/codesyntax]

[codesyntax lang="bash"]

newaliases

[/codesyntax]

Note: In my case I have postfix configured as smarthost, so I going to use localhost as email server. I am not going to cover postfix configuration here.

20. Login into application using default credentials (user: admin / password: admin)

21. Change admin default password

22. If TestLink mailing functionality is not working and you see in logs some error like bellow it's very likely that selinux is the issue there. One possible approach is to disable it

[>>][510fe10b8186e953397877][DEFAULT][/lostPassword.php][13/Feb/4 16:25:47]
        [13/Feb/4 16:25:47][WARNING][<nosession>][GUI]
                E_WARNING
fsockopen(): unable to connect to 127.0.0.1:25 (Permission denied) - in /var/www/html/third_party/phpmailer/class.smtp.php - Line 132
        [13/Feb/4 16:25:47][WARNING][<nosession>][GUI]
                E_NOTICE
Undefined variable: note - in /var/www/html/lostPassword.php - Line 49

[codesyntax lang="bash"]

vim /etc/sysconfig/selinux
:%s/SELINUX=enforcing/SELINUX=disabled/g
:wq

[/codesyntax]

[codesyntax lang="bash"]

reboot

[/codesyntax]

Links:

Monitor APC smart-UPS with apcupsd

apcupsd is a daemon which will monitor your APC SmartUPS to shutdown your system when the UPS' power is going to fail. apcupsd will work with most of APC's Smart-UPS models as well as most simple signalling models such a Back-UPS, and BackUPS-Office.

  1. install the daemon: [codesyntax lang="bash"]
    apt-get install apcupsd

    [/codesyntax]

  2. edit /etc/apcupsd/apcupsd.conf and change these lines
    1. UPSNAME myownups
    2. UPSCABLE usb
    3. UPSTYPE usb
    4. comment out DEVICE (it contains a TTY link, which will prevent it from working)
  3. edit /etc/default/apcupsd
    1. change ISCONFIGURED from no to yes
  4. start apcupsd daemon[codesyntax lang="bash"]
    /etc/init.d/apcupsd start

    [/codesyntax]

  5. check ups status[codesyntax lang="bash"]
    apcaccess status

    [/codesyntax]

  6. install APCUPSD-CGI web interface: [codesyntax lang="bash"]
    apt-get install apcupsd-cgi

    [/codesyntax]Note: For this to work you MUST have CGI enabled in your Apache configuration and the CGI directory should be pointed at /usr/lib/cgi-bin/

  7. access the web address: http://localhost/cgi-bin/apcupsd/multimon.cgi

Debian: How to determine services are enabled at boot

If you are using CentOS the answer is pretty simple:

[codesyntax lang="bash"]

chkconfig --list | grep $(runlevel | awk '{ print $2}'):on

[/codesyntax]

But how about Debian Linux? How is this done?

[codesyntax lang="bash"]

R=$(runlevel | awk '{ print $2}')
for s in /etc/rc${R}.d/*; do basename $s | grep '^S' | sed 's/S[0-9].//g' ;done

[/codesyntax]

If you like - and I am sure most of you will - you can use rcconf, Debian Runlevel configuration tool.