ubuntian crossgrade
Sometimes you have an Ubuntu server. But what you need a Debian server. And you could reinstall the system with Debian but you either can't or do not want to (i.e. you are lazy). In a future post I will expand on how and why I find myself in this situation, but suffice it to say that I have a few times. But what to do about it?
The thought may have crossed your mind: Can you [up/down/cross]-grade an Ubuntu system to a Debian system*? I prefer the term crossgrade. After all, Ubuntu is based on Debian and they both use the apt package manager and so they have quite a bit in common.
So, the answer? Yes, Virginia; you can!!... maybe... possibly... there is a chance it could work, anyway.
* You may also wonder whether you can go the other direction; Debian to Ubuntu. I would guess that it would work as well as the Ubuntu to Debian procedure (i.e. I hope you have an ample supply of four-leaf clovers on hand) but I haven't tried it, as I personally have no reason to.
DISCLAIMER: This is probably a crazy stupid thing to do. Especially on an important system and even more so if you are planning to try it on a remote system (WTF is wrong with you??). Stop being so lazy and just back up the system and config and reinstall it properly. There is no guarantee that this will work. It's totally NOT supported. If you ask most people they will probably just tell you that it doesn't or won't work. Just because it worked for me doesn't mean it will work for you.
...You read the DISCLAIMER and continued on? Okeydokey... don't blame me when this doesn't work out for you!
The patient(s):
So far I have performed this procedure (remotely, via ssh) on three Ubuntu servers, all of which were running Ubuntu 8.04 LTS - Hardy Heron. One was a standalone server and the other were virtual/guest machines on a Linux QEMU/KVM server. In both cases the transdistro destination OS was Debian Linux Squeeze.
First: use screen--ESPECIALLY if you are dumb enough to attempt this crossgrade remotely (and apparently I am).
Getting started:
Backup and then replace the contents of /etc/apt/sources.list with: (using your closest mirror: http://www.debian.org/mirror/list)
deb http://ftp.us.debian.org/debian/ squeeze main
deb http://security.debian.org/ squeeze/updates main
(I assume you don't have need for -src or other repos. If you do, then you should know what to add)
Get the show on the road already:
screen
apt-get update
Oh noes! (I've always wanted to say that) The first hiccup:
...
Reading package lists... Done
W: GPG error: http://security.debian.org squeeze/updates Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 9AA38DCD55BE302B
W: GPG error: http://ftp.us.debian.org squeeze Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 9AA38DCD55BE302B
W: You may want to run apt-get update to correct these problems
This one is easy to fix. Just obtain and import the Debian signing key. Duh.
gpg --keyserver subkeys.pgp.net --recv 9AA38DCD55BE302B
gpg --export --armor 9AA38DCD55BE302B | apt-key add -
Update package lists again and ensure we have no more key errors:
apt-get update
And now... Crossgrade: Engage!
apt-get dist-upgrade
You might have to tell it "[Y]es, I really am crazy enough to attempt this up(cross)grade!"
And along the way you may get asked: Can we restart this and that? Do you want to replace this config? Are you sure about blah blah blah? The answer is yes, Yes, and YES! Because in some cases we are replacing Ubuntu default configs with Debian ones (and in this case much newer versions of many packages). In other cases you might be overwriting your custom config with the Debian default config. I backup any changed/customized configs and then allow them to be overwritten and then reincorporate my changes later; because my modifications were based on the Ubuntu config not the Debian, and there might be important changes in the default config that otherwise would be missed. Of course, depending on your system/packages/config this policy may not make sense for you.
Anyway, our crossgrade is now under way.
Until...
dpkg: `ldconfig' not found on PATH.
dpkg: 1 expected program(s) not found on PATH.
NB: root's PATH should usually contain /usr/local/sbin, /usr/sbin and /sbin.
E: Sub-process /usr/bin/dpkg returned an error code (2)
Uh oh-- it seems we 86'ed ubuntu's ldconfig (libc6 pkg) and the debian ldconfig hasn't yet been installted. OOPS. dpkg just became unusable so it's kind of impossible to get out of this jam by installing or replacing any more packages. So what do we do now? Well I cheated and copied /sbin/ldconfig from another Debian Squeeze box to /usr/local/sbin/ldconfig on the now crippled, partially upgraded box. You could just as well extract ldconfig from the libc6 package that's already sitting in /var/cache/apt/archives but that requires marginally more work, so I didn't.
scp /sbin/ldconfig root@ubuntian:/usr/local/sbin/
And we're back in business again:
apt-get -f dist-upgrade
Until... oh snap, not again!
Unpacking libc-bin (from .../libc-bin_2.10.2-6_amd64.deb) ...
dpkg: error processing /var/cache/apt/archives/libc-bin_2.10.2-6_amd64.deb (--unpack):
trying to overwrite `/usr/share/man/man1/localedef.1.gz', which is also in package belocs-locales-bin
dpkg-deb: subprocess paste killed by signal (Broken pipe)
Errors were encountered while processing:
/var/cache/apt/archives/libc-bin_2.10.2-6_amd64.deb
OK, so our Debian package is going to overwrite something which belongs to the Ubuntu package we are replacing anyway... I think we can ignore that error. How do you ignore that error? Use the force, Luke!
dpkg -i --force-all /var/cache/apt/archives/libc-bin_2.10.2-6_amd64.deb
Somebody once said: "If it doesn't work, force it. If it breaks, then it must have needed replacing anyway"
That's never been more true than now, during this crossgrade.
Getting back on track:
apt-get -f dist-upgrade
ARGH. This isn't going to be easy is it...
dpkg: error processing /var/cache/apt/archives/sysvinit-utils_2.87dsf-10_amd64.deb (--unpack):
trying to overwrite '/sbin/killall5', which is also in package sysvutils 2.86.ds1-14.1ubuntu45.1
dpkg-deb: subprocess paste killed by signal (Broken pipe)
Errors were encountered while processing:
/var/cache/apt/archives/sysvinit-utils_2.87dsf-10_amd64.deb
E: Sub-process /usr/bin/dpkg returned an error code (1)
And what are we going to do about that? Yup, you guessed it:
dpkg -i --force-all /var/cache/apt/archives/sysvinit-utils_2.87dsf-10_amd64.deb
Back to business:
apt-get -f dist-upgrade
Until...
xargs: xargs.c:443: main: Assertion `bc_ctl.arg_max <= (131072-2048)' failed.
Aborted
dpkg: warning: subprocess old pre-removal script returned error exit status 134
dpkg - trying script from the new package instead ...
xargs: xargs.c:443: main: Assertion `bc_ctl.arg_max <= (131072-2048)' failed.
Aborted
dpkg: error processing /var/cache/apt/archives/debconf_1.5.32_all.deb (--unpack):
subprocess new pre-removal script returned error exit status 134
Errors were encountered while processing:
/var/cache/apt/archives/debconf_1.5.32_all.deb
E: Sub-process /usr/bin/dpkg returned an error code (1)
Oh really? Well, force you too! ......alas, you'll find that Forcing doesn't help this time.
But googling does:
http://www.google.com/search?blah-blah-blah...
"This should be fixed in xargs 4.3.5-1 and later:
#19391: When xargs knows that the system's actual exec limit is larger
than the compiled-in ARG_MAX, use the system's limit without
generating an assertion failure.
Upgrading findutils should theefore do as a workaround."
Therefore, we just have to update findutils specifically before we can move on:
apt-get install findutils
apt-get -f dist-upgrade
At some point we may get messages about:
1) Unable to migrate to dependency-based boot system
...
To reattempt the migration process after the problems have been fixed, run "dpkg-reconfigure sysv-rc".
Dependency-based boot is new for Debian Squeeze. But obviously its setup script isn't prepared to handle our now distro-confused formerly-Ubuntu server. So we say OK and we can later try to fix the problem and run the command above... or not. If you value dependency-based boot then go ahead. Since I am working with servers and reboot very infrequently, this doesn't have much value for me. I'm not going work worry about it. At least not now.
2) Grub2 upgrade:
Since our old Ubuntu system had old/legacy grub and Debian Squeeze has grub2, grub2 is installed "chained" from the old grub. After you are sure grub2 is working (i.e. after you reboot and sucessfully boot from old grub>grub2>Debian), then you can completely replace old grub with grub2 on the MBR. So make a note to do this later AFTER you reboot:
/usr/sbin/upgrade-from-grub-legacy
Eventually, with an insane about of luck, our upgrade might complete without further errors!
We are almost done. But we should check for any more updates:
apt-get update
apt-get dist-upgrade
Finally: we need to update the kernel. Only the ubuntu kernel(s) are installed currently.
apt-get install linux-image-amd64
(obviously this assumes you are working on an amd64 compatible system)
Now for the real test:
Will it
To find out, we must REboot. But this can be surprisingly tricky, as you can see:
# reboot
The system is going down for reboot NOW!er.local (pts/0) (Sat Jun 31 10:35:27
shutdown: timeout opening/writing control channel /dev/initctl
init: timeout opening/writing control channel /dev/initctl
#
So what now? If you are sitting at the computer you could punch the reset button, but not if you are doing all this remotely! And besides, I like a challenge. Alas, the solution is quite simple, but it did take me some googling to find it:
reboot -f
Bam. Connection lost and system rebooted (we hope) in short order... then an anxious minute while we wait and try to reconnect... and find it has booted up as a Debian Squeeze box! Yay--the operation was a success!!
So what does reboot -f do different? The man page for reboot says it skips calling shutdown. OK, I guess that means it also communicates with init in some way other than using /dev/initctl, but I am not sure how. Another adventure for another day I guess.
Cleanup.
Don't forget to clean up your mess!
First, get rid of your temporary copy of ldconfig. The proper package-supplied one should now be present at /sbin/ldconfig, so we should now do:
# rm /usr/local/sbin/ldconfig
Next, you haven't forgotten about replacing old grub with grub2 have you? Good. This is assuming you had no problems booting up with grub2. Then you are ready to:
/usr/sbin/upgrade-from-grub-legacy
After you are booted into your fresh debian system, you might consider scraping some remaining ubuntucruft from the wheelwells.
There should be at least one ubuntu kernel left behind, and probably some other ubuntu packages as well. You can find some of them using:
apt-show-versions | grep -v /squeeze
(you might need to install apt-show-version first)
Feel free to apt-get remove these away!
Celebrate!
This is the final step. You can celebrate your laziness and start having fun (what do you mean you don't know how to have fun with a Linux server? Are you thick??) with your transdistro Debian server. It may still resemble an Ubuntu server to some people, but you will know deep down that it is, and always was, a Debian server at heart. <3 (I've always wanted a good reason to type less-than three)

