Wednesday, November 18, 2020

Using zerofree to reduce Ubuntu/Debian OVA file size

Editor's note [2020-11-21]: this is an update to a 2014 post on the same topic.  Since then, the mount command is also required.

When exporting an OVA file from VirtualBox's "Export Appliance" feature, any disk block that isn't filled with 0 has to be included in the resulting file.  Normally, an OS doesn't create those blocks as it works; when a file is deleted, the space is marked as free, but retains its original contents until it is re-allocated for another file.  If there are a lot of files deleted, a significant amount of non-empty "empty" space can accumulate.

Running the zerofree program writes data of value 0 over all space marked as free, allowing that free space to be excluded from the OVA file again.

The following applies to Ubuntu 18.04 (bionic) and 20.04 (focal) at least; I forget exactly how far back it goes, but the way to get at a command line changed at some point, and there was a period where poweroff didn't actually work in the pre-boot environment.

Regardless, here's how to run zerofree on Debian, Ubuntu, or derivatives.

Sunday, November 15, 2020

State of the Linux Desktop (2009)

Editor's Note: this is a post from my old Serendipity weblog, "Pawprints of the Mind," which was originally posted nearly 12 years ago, on 2009-05-18.  History since then has unfolded differently in some details, but the broad strokes seem to be accurate.  The text below is reproduced verbatim from the original post.

The Linux desktop is a curious thing. Years ago, the annual prediction was that that year was finally going to be the Year of the Linux Desktop, and Windows would be kicked out of market dominance for good. World domination by open source, and all that.

Linux has come a long way since then. Monitors can be largely auto-configured, fonts can be anti-aliased, CDs can be burned without fiddling with ide-scsi, USB works without having to care about your kernel version, and even media keyboards and mice with tilt-wheels seem to work these days.

But the "desktop" has come a long way since then, too. Various OS X versions introduced technologies like Display PDF, Quartz Extreme, Exposé, and other things that Windows Vista copied with WPF and Aero. Linux eventually duplicated them in Compiz, Beryl, Compiz-Fusion, or something. Somewhere in there. It kinda-sorta works now, if you don't want thumbnails of minimized windows.

Now that Linux has joined the current decade, Microsoft is readying Windows 7, with features like thumbnails of windows on the taskbar (with Aero), the 'recent documents' of an application available from the taskbar button, and so forth. Apple certainly has their own plans. And both of them have decent sound and MIDI support, where starting up one audio application is actually not likely to silence another's sound.

So, the "Linux Desktop" is still behind, and always has been. One problem here seems to be that it's not about innovation. It's about copying everyone else's modern technology with ancient components. It's about solving problems again that already have better solutions in other systems, just to see how closely Linux can approximate them with its decades-old core design.

And then someone, or maybe a few people, whine about the solution and come up with an alternative. The alternatives vie for dominance, and the rest of the desktop world moves on while the Linux landscape settles into one predominant choice, if they're lucky. If they're unlucky, you get things like the KDE/Gnome situation.

Due to Linux's philosophy about neither inventing wheels nor including batteries, there's a large number of components with their own maintenance and release schedules, and most of them target "current" versions of other components. For any given complex program, there's a relatively small window of time between the components it uses being released, and becoming obsolete with future releases. Every time components break compatibility, a new version of all programs dependent on them have to be released to deal with the changes. The more changes dealt with, the more complex the program becomes, so compatibility with older versions also gets cut out after a time.

And sometimes, a sweeping change comes through, and no compatibility is maintained between the two versions: App 2.0 will run on Foo 3.0 and newer, and App 1.4 will only run on Foo 2.5 and below.

From a software developer's point of view, then, supporting Linux is a risky proposition. You have to either watch the work in progress on the entire stack, and guess what will be completed and be important to your application, or you end up being taken by surprise when one of your components updates and your application doesn't run on an ever-growing range of Linux systems until you have time to update it.

Apple and Microsoft may have their own problems, but they have the clout and the guts to say, "We need to migrate to doing things this way, and it'll be good for at least 5 years." Look at Windows 95–Me, or NT4–XP. Whereas the rate of change in Linux effectively limits compatibility to about a year at the most. So most serious software gets developed for other platforms, and most serious users are on those platforms as well. Then familiarity begets desire for those platforms over Linux.

In short, Linux is sort of the Perl of operating systems: messy and aging. People working on Linux desktop technologies seem to be doing it to prove that they can. And secretly, they hope to get horses fast enough to put that Ford guy out of business.

Saturday, October 24, 2020

Defense in Depth: Read-Only Document Root

One security rule I live by as a sysadmin, which admittedly causes me a lot of trouble with PHP apps, is that the running web server user is never able to write to files within the document root.

Any user-file upload/download mechanism goes somewhere else, so that read access can do a permission check, and be delivered through readfile() or a redirect to a CDN, not passed through a complex mechanism that may decide to execute the file's contents.

Configuration files are similarly locked down.  A project that configures itself with PHP code is a project that offers arbitrary code execution to anyone who can change that configuration file.

I don't let the web user install new code to /bin; we shouldn't let the web user install new code to /srv/www. It's the server, not a system administrator.

Not coincidentally, our document root is never the root of a git repository.  It's typically placed in a public folder, allowing us to have a special writable folder like cache both within the project/deployment, and outside of the document root.

Saturday, October 17, 2020

MySQL on MacOS: Discoveries

For a long time, I’ve installed MySQL within my development virtual machine (VM), loaded it with a minimal subset of production data, and pointed the database hostname to 127.0.0.1 through the VM’s /etc/hosts file.

However, working from home, I realized that the my slower DSL connection did not affect the amount of time it took to pull a fresh subset of production data into the VM.

I finally went to the trouble of installing MySQL on the host side, and configuring everything to work with that, so that filling it does not require the data to cross any hypervisor boundaries at all.  And I learned some things!

  1. The installer sets it up to launch as _mysql user
  2. Using the wrong CA certificate causes padding errors
  3. MySQL 8.0.14+ allows a separate "administrative management" port
  4. MySQL’s AES_ENCRYPT() function makes the worst possible choice by default
  5. The speedup is dominated by MySQL's disk access

Tuesday, September 8, 2020

(Not) Learning Rust

I want Rust to succeed.  It seems like the best gambit for fixing C, where the slightest mistake is likely to be a security hole… or to be turned into one by a newer compiler version.

On the other hand, actually learning it has proven extremely difficult.  Very little of Rust is explained in terms of something else; and all of the basic mechanics of the language feel weird.

After the Rust Book and the Cookbook and maybe some other stuff from Awesome Rust, I went through the tutorial about writing very bad linked lists; there were places that were like, “Can we do X? [code that does X].”  I would stop there, run that code, and try to solve the error myself.  I never could. I would read on, and it would be, “The error tells us we need to call F” so I’d try to figure out how to call F.  I never could figure it out, even with that hint. And I still didn’t have the capability to go from error message to even discovering F, let alone understanding that F would apply to the error.

I threw myself at the wall several times, and failed to advance past the part where one writes a number-guessing game for the CLI.

Moreover, I don’t have a motivating project to “learn Rust” with.  It’s mostly an exercise in following other people’s code, breaking it, or trying to improve it, and ending up with incomprehensible and unactionable errors.  The compiler errors try to be helpful, but if the code starts out far enough off the rails, it’s just flailing, same as me.

When a survey comes in that says “Opinions of Rust are very favorable, but people aren’t using it,” I understand.  I understand completely.  We all want something to fix entire bug classes, but keep the bare-metal performance, and Rust is basically without competition there.  But we can’t all devote enough time and energy to learning Rust from scratch.

Tuesday, August 25, 2020

Python has descended into chaos

At my employer, Python is not our primary language; the main system was built in Perl and is now a Perl/PHP hybrid. The surrounding systems have been built/replaced with PHP, but the core code is resistant to change. Management doesn't want to mess with the part where the actual money flows in.

For seamless session handling—local memcached on dev machines, but shared storage in production—we have memcache-dynamo. It started life in Perl. I rewrote it in Python, as part of the quest to replace all Perl with something more popular in modern times. (I figured async/await syntax would be easier for future developers than React-PHP.) It's been working fine on Ubuntu 18.04 for some time, but then I wanted to update to Ubuntu 20.04.

It quickly turned irritating. The Python 3.6 dependencies didn't work on 3.8. It turns out that the updated dependencies for 3.8 don't work on 3.6, either. I guess this explains why pipenv is so insistent that "requires 3.6" means "exactly 3.6".

Python 3 isn't just a version with some backward-incompatible changes; it's fundamentally a new culture with new values. And honestly, that probably means less Python in my future. I don't want to promote another language into the main systems, and Python no longer seems to be suitable for fire-and-forget background services.

(In the end, I wrote a new layer on our installer that checks the Python version, then copies e.g. Pipfile-3.8 and Pipfile.lock-3.8 into their standard location before starting pipenv. It's a horrible mess and I hate it so much. Please, don't start a Python 3 transition every year!)

Saturday, August 15, 2020

Black Lives Matter

This is a very focused blog.  One of the few comments I received on my old s9y blog was, “The technical content is great, but it could use fewer political and religious diatribes.”

We don’t exist outside of these social, political, or economic systems, though.  We are not separate from our own unconscious and its biases.  At the end of the day, if I truly believe in equality, in liberty and justice for all, then I must be willing to work for that.

The other crucial problem is that my silence will be interpreted as assent, which is a serious problem when my silence is interpreted as supporting something I deeply oppose.

Black lives matter.  Black quality of life matters.

Defunding and demilitarizing the police is an excellent first step.  But actions speak louder than words, and we really have to change those actions as a society; we have to start believing that petty crime does not justify lethal force, and genuinely prosecute those who act otherwise.  We should find it normal for police to de-escalate a situation.

And police reform (at a level that genuinely impacts the statistics and improves the lives of actual people) itself is only the first step.  Defunding the prison system and releasing non-violent offenders who were swept up in the war on drugs is overdue as well.  This is a problem we made ourselves, and our cultural narrative about it drives it toward being a self-fulfilling prophecy.

What’s next after that?  I don’t know.  That’s where listening to other people is important.  All I can guarantee is that we will accomplish nothing if we deflect or ignore the topic entirely.

Further food for thought: