Here's how you check the syntax of your Apache configuration:
/usr/sbin/apache2ctl -t
What's the equivalent in Varnish? Well, if you do a bit of Googling you discover that the nearest equivalent is:
- Run
varnishd -C /etc/varnish/default.vcl to turn the file into C code that Varnish would understand.
- If the file compiles, you have to ignore the result as it scrolls past.
- If the file doesn't compile, it will raise an arcane and fairly verbose error, which you have to not ignore.
Whereas Apache has a simple "one parameter, simple result" method, Varnish doesn't; as far as its creator is concerned, Varnish doesn't need one either.
I want to explain why Varnish's solution is problematic and bad usability, but I should start off by saying that Varnish is an amazing piece of software: if you haven't installed it on your live servers yet, but you think you might have the tiniest chance of performance issues, then do it now. This blogpost can wait for you to finish. Go on.
In explaining why their method is a problem, I want to look at the user experience of using Varnish, of using its documentation and of encountering the "universe of all possible documentation" on the web. I don't want to dismiss anything as a user training issue as such, and I don't want to be told how what seems to be standard user practice is wrong. Good usability research consists in assessing the user's experience without judging it, in order to fix the tool to the user's tendencies, and not the other way around.
Objection #0: it's not obvious
This is the clearest objection, but it's the one that's most difficult to defend in the face of people saying "you don't need a dedicated check, because of -C". Steve Krug's seminal usability tome was even named after this core principle: don't make me think. If the user is already thinking about getting their VCL file working, they shouldn't have to also think about how to use your tool. The tool use should be obvious, rather than requiring the same counterintuitive thinking every time.
To me, the honest answer to the question "how do I check a VCL file syntax in Varnish?" really should be "You can't." Because you can't, not really. Running a compiler and looking at the output is not the same as requesting your system perform a simple check and return a straightforward response.
Imagine if Varnish were a car, and the VCL file were the oil level. If you were to ask me "how do I check the oil level in my car?" and I replied "Well, you need to warm the car up; then get it on axle stands; then crawl underneath with a big tupperware box and undo the sump pan drain bolt; then, once it's drained, work out how much oil your car has versus how much it should have...." If I said all this, then you'd quite rightly (a) tell me that that's not a check, but an engineering job! and (b) ask if someone could put an oil dipstick in future cars.
As far as I can see, the main reason why there's no -t option for Varnish, is that the people who maintain Varnish know their car so well that they themselves don't see the need for dipsticks. User testing, and user requests, are how you work out that you need dipsticks.
Objection #2: it's noisy
What do we want from a check? Let's say we want the same thing as we'd want from unit tests: when all is OK, we want simple and terse; if at all possible, silent. Lots of unit testing frameworks are very quiet indeed, showing maybe a handful of dots or green lights: until something goes wrong, at which point you want to be notified.
Or think about how a notification system like nagios works: only when there's a problem with your machine, do you even know it's running (to the point where sometimes it's nice to set up a heartbeat notification - similar to Apache's "Syntax OK" - to monitor your monitoring!) When a notification framework gets noisy - when you have to set up filters to remove emails from your inbox - you're training yourself to ignore the alarm; your application is shouting "fire!"
If the behaviour of a check on success should be quiet, then the default behaviour of Varnish's syntax checking is just plain wrong. You can make it quieter on success:
$ varnishd -C /etc/varnish/default.vcl >/dev/null
but why? Why is a syntax check outputting code to the screen? Because it's not a syntax check, not really: it's a code compile function that's being shoehorned into a syntax check.
Objection #3: it's unscriptable
Let's look a bit more closely at what apache2ctl does to the shell environment:
$ /usr/sbin/apache2ctl -t
Syntax OK
$ echo $?
0
# Now put some syntax error in your Apache config and try again
$ /usr/sbin/apache2ctl -t
/usr/sbin/apache2ctl: 87: ulimit: error setting limit (Operation not permitted)
Syntax error on line 2 of /etc/apache2/sites-enabled/000-default:
Invalid command 'ThisDirectiveDoesNotExist', perhaps misspelled or defined by a module not included in the server configuration
Action '-t' failed.
The Apache error log may have more information.
$ echo $?
1
See how "all OK" returned 0, while "warning!" returned 1, a non-zero result? This is all part of being a "good shell citizen": the shell and its processes can only really communicate by zero/non-zero exit status; so it's a kind of "interprocess politeness" for processes to return a non-zero code, if anything goes "wrong". It means that commands can be trusted to report errors in a way that the shell can understand, and can therefore be scripted; for example, this command reloads Apache's configuration only if its syntax is OK:
$ /usr/sbin/apache2ctl -t && sudo /etc/init.d/apache2 reload
What about Varnish?
$ varnishd -C /etc/varnish/default.vcl > /dev/null
$ echo $?
0
# Now put some syntax error in your Varnish config and try again
$ varnishd -C /etc/varnish/default.vcl > /dev/null
/usr/sbin/apache2ctl: 87: ulimit: error setting limit (Operation not permitted)
Syntax error on line 2 of /etc/apache2/sites-enabled/000-default:
Invalid command 'ThisDirectiveDoesNotExist', perhaps misspelled or defined by a module not included in the server configuration
Action '-t' failed.
The Apache error log may have more information.
$ echo $?
0
This means that Varnish's "syntax checking" mode is unscriptable, as it behaves in a non-standard way to the shell.
Objection #3: it's dangerous
Objection #3.5: you'll have a damn hard time finding it, but there's actually a slightly better way to do this
Why are we here?
Lots of open-source projects have this reluctance to implement features that the maintainers don't see are necessary. I've picked on Varnish here because it was our most immediate problem, but the feature request queue of many an open-source project is littered with worksforme ticket closures: Psi always used to be my go-to example for this behaviour, although I can no longer find a link to the thread where people were pleading with the maintainers to stop the vCard from popping up on every server login just because you haven't yet filled in (unnecessary) details.
Whereas software development is gradually moving to much more user-focused development - UX is big in online applications - there's a sense in which command-line applications still either consider themselves too hardcore to worry about the people who are actually using them and their experience of doing so. I grant that some tools are difficult or dangerous to use: but that's why we have up-to-date documentation; and safety checks that provide a clear, unambiguous user experience.