Hacker News new | comments | show | ask | jobs | submit login

Systemd ideas I'm all for but it only hints at linux lack of clean abstraction power. sysvinit was full of redundancy; apparently BSD found a way to make a thin abstraction layer to make init files clean.

Bash isn't "good" at hinting proper abstractions, I rarely see talks about this, maybe gurus can see through the rain.

I keep seeing a place for a tiny lambda friendly intermediate layer .. Just so you can compose properties of your services like clojure ring middleware.

   (->
     (path "/usr/bin/some-service" "arg0" ...)
     (wrap :pre (lambda () ...)
           :post (lambda () ..))
     (retry 5)
     ...
     (timeout 5))
Is this ugly to your eyes ?

ps: the idea is that (retry 5) is a normal language function, and not a systemd opaque built-in, you can write your own thing, and the most used can go upstream. Hoping to avoid the sysvinit fragility and redundancy.




Shell and bash are actually excellent at this, but people don't like writing shell scripts. This is just process chaining. Take a look at DJB's or the more modern runit for init toolkits that compose.

https://cr.yp.to/daemontools.html

http://smarden.org/runit/

Here is a bash function that retries N times:

    retry() {
      local n=$1
      shift
      for i in $(seq $n); do
        "$@"
      done
    }

    retry 5 echo hi
    
Then you can compose with a timeout function, which already exists:

    timeout-demo() {
      timeout 0.1 $0 retry 5 echo hi
    }
You can pass the names of other functions as pre and post hooks as well.

https://www.gnu.org/software/coreutils/manual/html_node/time...

Shell has a very forth-like quality to it, and Forth is sort of like a backwards Lisp as well (postfix rather than prefix).


Isn't it just repeats the command 5 times instead of retrying?

IMO Bash with it's multitude of annoying quoting and field splitting rules, many irrelevant features focusing on interactive use, and error handling as an afterthought is just wrong choice for writing robust systems. It's too easy to make mistakes. And it still works only in the simplest cases, until somebody evil deliberately pass you newline delimited string or something with patterns which expands in unexpected place, etc. Properly handling those cases will make your script ugly mess. Actually I find the mental burden when writing shell scripts is very akin to programming in C.


> Bash with it's multitude of annoying quoting and field splitting rules

So don't use the Bourne Again shell. After all and to start with, if you live in the Debian or Ubuntu worlds, your van Smoorenburg rc scripts have not been using the Bourne Again shell for about a decade.

There's no reason at all that run programs need be written in any shell script at all, let alone in the Bourne Shell script. Laurent Bercot publishes a tool named execline that takes the ideas of the old Thompson shell ("if" being an external command and so forth) to their logical conclusions, which is far better suited to what's being discussed here. One can also write run programs in Perl or Python, or write them as nosh scripts.

* http://blog.infinitenegativeutility.com/2015/2/celebrating-d...


If the command is a daemon, that's basically retrying. But if you want to check the exit code, that's easy to do inside retry().

I totally agree with your second paragraph, that is why I'm working on fixing shell :)

http://www.oilshell.org/blog/

This entry in particular is relevant to your concerns:

http://www.oilshell.org/blog/2016/11/06.html


I guess it's a bit like advanced perl5, you need to be taught the "right way" otherwise you pile up overlapping imperative code.


Thanks for the suggestion -- I expanded on this idea in a blog post:

http://www.oilshell.org/blog/2017/01/13.html

Feedback appreciated!


You forgot rtprio, idprio, chrt, and numactl; the s6, perp, daemontools-encore, and nosh toolsets; and execline.

* http://wiki.tcl.tk/15088

Then of course there are TCL and the Thompson shell.

* http://v6shell.org/


> sysvinit was full of redundancy; apparently BSD found a way to make a thin abstraction layer to make init files clean.

They are completely different systems of init scripts. Just for starters, BSD does not have run levels, so the rcn.d directories and the maze of symlinks do not exist.

BSD init scripts themselves are much simpler mostly because there is a good system of helper functions which they all use, rather than every single script inventing its own wheel in sysvinit. Of course, this is just a discipline or convention, and sysvinit could be vastly improved if anybody was similarly industrious.

BSD init scripts also have completely different dependency management (PROVIDE and REQUIRE instead of numerical priorities). And the mechanism for disabling and enabling a script is via dead simple definitions in the single file /etc/rc.


Why i can't stop thinking that when Freedesktop people say there is a problem with Linux, they really mean there is a problem with Fedora...


Have you looked at the runit init system? Here is /etc/sv/sshd/run on void linux:

    #!/bin/sh
    ssh-keygen -A >/dev/null 2>&1 # Will generate host keys if they don't already exist
    [ -r conf ] && . ./conf
    exec /usr/bin/sshd -D $OPTS
Service scripts are dead simple on Void.


Where do you specify laziness, failure policy etc ?


Why would I specify those in an init script? openssh has been doing The Right Thing(TM) for about two decades.

Also, openssh has protocol-specific (and secure by default) configuration options around connection lifecycle, etc. that no general purpose init system should try to replicate and then blindly apply to unrelated services.


OpenSSH is the unusual case. Most the the services I run don't do the right thing. That's why, for instance, Debian wrote the start-stop-daemon utility years before anyone ever dreamed of systemd.

I've been greatly enjoying systemd for the ability to write services and startup jobs in languages that don't have great libraries for doing all the right things, like Python and shell, because it gives me all those Right Things as effectively a library. I don't have to manage pid file handling and daemonization and restarts on my own; systemd will do it, and will do it well and Right. (I used to do this with start-stop-daemon, and it did it poorly and only okay.) It will also get out of the way of OpenSSH, which does it well and Right, and get in the way of the dozens of services that think they're doing it well and Right but aren't.

Easy things should be easy, and hard things should be possible. systemd supports both. If that's the extent of what runit can in fact do, it only supports the former. (SysV-style init, of course, just makes easy things hard and hard things confusing, but as everyone else is saying, it's very not the standard of comparison here.)


I recall seeing something like that, which included a Scheme dialect, but I can't for the life of me remember what it was called.


maybe guix OS service dsl ? ex dmd, now shepherd https://lists.gnu.org/archive/html/guix-devel/2016-01/msg002...




Applications are open for YC Winter 2019

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: