During FUDCon, I got to wondering: with all the rewriting and refactoring and fixing we’ve done on anaconda in the past couple years, is there any of the old code left anymore?
git blame --line-porcelain and a little python later:
There’s two things to point out here:
- About 90% of the code in current anaconda
HEAD was committed (note: not necessarily written) in the year-plus-a-bit since Fedora 16.
- Nearly half of the new code was added in Fedora 17.
But this just shows when the code was committed – not when it was designed or written. Or, for that matter, why.
Why rewrite, anyway?
Back in August 2009 we were trying to redesign the storage UI to handle modern storage needs. This turned out to require rewriting a lot of the storage backend code (again) because the existing anaconda code was basically all duct tape and bubble gum, creaking under the strain of modern demands.
You might think I’m exaggerating, but keep in mind that anaconda was originally written in 1999, for Red Hat Linux 6.1, It was designed to run off a 1.44MB floppy, using the still-newish Linux 2.2.x kernel.
In 2009 it still had its own custom initrd init system – called “
loader” – written entirely in C. (Statically-linked, too, until 2007.) So anaconda had its own copy of stuff like
mknod.. but no
bash before the GUI started. (Good luck trying to debug anything!)
The design predated
/sys – and
dbus – and had its own builtin module loading stuff instead of
modprobe. So anaconda was doing all the hardware setup (probing, module loading and unloading, network setup, disk setup, RAID setup, etc., etc.) by itself… and not always doing it well. And every time there was a new device driver for anything we had to manually add support for it to the installer.
And then there’s the GUI. It was single-threaded, so (for example) while we waited for
yum to do something the UI would just.. stop drawing. If you dragged a window around you just ended up with big empty gray blotches until
lvm finished and let us start refreshing the UI again.
It was also designed for much smaller screens – 640×480, or 800×600 if you were lucky. You can’t fit much on a screen that size (smaller than your average smartphone!), so it made sense to break the process into a series of steps. Except by 2009 you ended up with screens that looked like this:
Great use of space there!
The logic for moving between steps had also gotten really hairy and fragile. Like, as soon as you finished partitioning the disk (but before you picked software to install!) we formatted the disks, because we used to need swap space to even think about running
yum. But then what happens if it turns out you need more hard drive space to install the stuff you want? TOO BAD, YOU CAN’T GO BACK NOW!
Even code that worked OK was still crusty and weird. There were still places in anaconda where it did things like:
if f[0:5] == "/dev/":
count = count + 1
because Python 1.x didn’t have “
+=” or “
The long-overdue redesign
By January 2011 we’d started serious planning to redesign the UI and rework a lot of the backend pieces. That FUDCon is the one where I did the first whiteboard sketch of the current hub-and-spoke design:
We started laying the groundwork immediately. We changed the way the installer images were built, so all of anaconda was crammed into
initrd.img. This landed in Fedora 15 (May 2011), paving the way for us to gradually remove
loader from the installer.
We also spent a full year doing lots of prototyping and design work, all in public view, reaching out for feedback in any way we could think of - at one point, Máirín printed out the mockups and taped them to the wall of the office so passers-by could comment on it.
After a year of development, an early
NewUI prototype was first made public in November 2011, just before Fedora 16 was released and Fedora 17 development started.
As time went on, it became clear that handling upgrades and installation in the same tool made everything a lot more complicated. Every discussion seemed to get stuck in this loop:
“Yeah, that seems like it would work… oh, but what about upgrades?”
“…oh. Right. Damn, that makes this much harder.”
“Oh, maybe we could do it like this?”
“Yeah, that seems like it would work…”
By January 2012 we decided that it would make a lot more sense to handle upgrades with a separate tool, to be written later – like as soon as we finished Fedora 17.
The longest year
Working feverishly through the Fedora 17 development cycle, we continued design and development on
NewUI while also replacing all 18,000 lines (or so) of
loader with a normal initramfs.. you know, with
bash so you can actually debug things). Fedora 17 was released at the end of May 2012.
Two weeks before we even finished Fedora 17, the new Anaconda UI was proposed for Fedora 18. We wanted to do this as early as possible, to make sure everyone was aware of the scope of the changes and the risks involved. FESCo approved it unanimously, as-is (without any text UI planned).
We started merging
NewUI into the main development branch a few days after the Fedora 17 release. Meanwhile, I went straight from rewriting
loader to writing
The Fedora 18 release cycle was grueling, but progress continued. As the Fedora 18 Alpha release approached, someone proposed delaying
NewUI until Fedora 19. FESCo considered the idea, but decided to go forward with
NewUI. We worked later and later nights. There was spirited and occasionally unkind feedback. The text UI suddenly became a requirement, so that had to be added. We worked through vacations and holidays. The release dragged on and on.
After two months of !!RELEASE PANIC!!,
fedup were declared finished enough to satisfy the release criteria, and shortly thereafter Fedora 18 was actually released.
And how was it received? Well, some people really like it. Some don’t:
[...] fills the needs of novice users admirably by clarifying the most problematic features [...], it fails almost everyone else, particularly experienced and/or advanced users with sophisticated needs.
[...] a total failure in that it not only fails to improve upon any aspect of [previous versions'] equivalent GUI features, it actually makes every single one of them substantially worse.
I continue to enjoy the technical aspects [...] and I hold out hope that they will listen to users and reconsider some of the UI decisions
Oh, my mistake – these are actually from early reviews of Mac OS X. Whoops!
Dumb jokes aside, the bottom line is this:
The redesign/rewrite was sorely needed. It’s not perfect – what 1.0 release is? – but it still does what it’s supposed to: get the bits onto your disk. It does everything most folks need it to do, and does it quicker and easier than any previous version.
And it still has the most advanced storage management of anything I’ve ever seen (let me know when gparted can set up iSCSI, for example). And it still has full backwards compatibility for Kickstart-scripted installs.
Most importantly: unlike the old anaconda, we can actually work on this code. It’s vastly more flexible, and sane, and modular – the storage library has been split into its own separate package, for example.
So sure, there’s room to improve. But now we’re in a place where we can actually make improvements, which is far, far more important. And we’ve got plenty of improvements planned for the next release already.
But if you’re dead-set on keeping the old installer, or you think we’re a bunch of idiots who got the UI all wrong, well, that’s the beauty of Open Source: the code’s right here. Feel free to show us how it should be done! Enjoy! I look forward to seeing what you come up with!
(This discussion continues in Package handling in anaconda – another retrospective)