Re: Succinct, idiomatic abort in execlineb scripts?

2022-09-06 Thread Saj Goonatilleke via skaware
On 6 Sep 2022, at 10:35, cat æscling via skaware wrote:
> using if instead of foreground sounds like what is wanted here

Indeed, thanks.  That makes sense now that you mention it.

(I'm not entirely sure why my brain failed to make the connection.
Maybe because of preconceived notions of 'if' coming from other languages.
Briefly picturing an 'exit-unless' helped it sink in.)


Re: Succinct, idiomatic abort in execlineb scripts?

2022-09-05 Thread Laurent Bercot



 As other people said, using "if" instead of "foreground" is the
idiomatic way to exit on child error. I myself am a staunch
"#!/bin/sh -e" user, and almost never use "foreground" in execline
scripts - only when I specifically need the exit code of some command.

 Forwarding signals to a child is only desirable in two cases: when
you're performing job control, and when for some reason you cannot exec
a long-lived process and have to run it as a child.
 execline isn't supposed to be an interactive language so job control
is out of its scope. And to perform signal forwarding on long-lived
children, it provides the "trap" binary.

 Hope this helps,

--
 Laurent



Re: Succinct, idiomatic abort in execlineb scripts?

2022-09-05 Thread cat æscling via skaware
The point is correct; using if instead of foreground sounds like what is wanted 
here

(Though in this case the rest of the script wouldn’t run in the data directory; 
besides,`execline-cd data [etc]` would just error out immediately.)


Re: Succinct, idiomatic abort in execlineb scripts?

2022-09-05 Thread Brett Neumeier
Perhaps just wrap each preparation command in an if block?

if { execline-cd data }

Will continue the script if execline-cd succeeds, and abort if it does not.

On Mon, Sep 5, 2022, 1:54 PM Saj Goonatilleke via skaware <
skaware@list.skarnet.org> wrote:

> Hello,
>
> Within the context of, say, an s6 run script that needs to do a little bit
> of
> prep work before execing into a server, it is often helpful to abort early
> if
> any of said prep work stumbles upon an unexpected problem.
>
> Maybe the filesystem is R/O.  Or full.
> Maybe an operator has fat-fingered something we need.
> Who knows!  Production is full of surprises.
>
> sh provides set -e, which is often satisfactory for simple prep scripts
> (if one is aware of its footguns).
>
> Is there a succinct, idiomatic set -e equivalent in the execline suite?
>
> I have included an example s6 run script below, which demonstrates the
> closest I
> have come so far.  fgsigwait is my alternative take on foreground[1].
> fgsigwait
> behaviour differs in the following respects:
>
> * fgsigwait exits[2] if prog1 exits with non-zero status.
>   foreground, by comparison, sets the ? environment variable and continues.
>   (fgsigwait -! reverts to foreground-ish behaviour.)
>
> * fgsigwait forwards some trappable signals to its child.  HUP, INT, etc.
>   This is where its name comes from.
>   (PID 1 is broken on some of our systems, which provided the initial
> motivation
>   for this hack.  fgsigwait always waits on prog1 after forwarding a
> signal.
>   This, plus execline's execution model, gave me fine control over when
> stuff
>   is forked -- and helped us avoid some Z process leaks.  Anyhoo.)
>
> fgsigwait otherwise aims to be a syntactic execlineb drop-in for
> foreground in
> cases where these features are desired.  Chaining stuff with fgsigwait
> emulates
> sh set -e without needing to repeatedly and explicitly test the ? env var.
>
> --- 8< ---
> #!/usr/bin/env -S execlineb -WP
>
> fdmove -c 2 1
>
> # slow-deathroll is a simple wrapper around
> # github.com/leahneukirchen/snooze
> # extends the s6 one-second restart penalty if we crash too soon
> fgsigwait { slow-deathroll }
>
> # Here is a simple example of some prep work.
> # We want to bail here if any of these things exit non-zero.
> fgsigwait {
>   execline-cd data
>   if -t { test ! -e live } fgsigwait { mkdir -p empty } ln -s empty live
> }
>
> # maybe a smidge more prep here...
>
> # all prep done.  exec into our server.
> nsd -d -c nsd.conf
> --- >8 ---
>
> This does work OK, but, every time I reach for my little program, I can't
> shake
> the feeling that I am probably reinventing some wheel.
>
> fgsigwait was implemented in Go, as is personal tradition when something
> need be
> hacked up in a hurry on the clock.  Spooling up the Go runtime eats a few
> extra
> milliseconds of time, and a few megabytes of memory.  While not practically
> significant to us -- we don't deploy to tiny machines -- a small part of
> me was
> sad to add bloat.  It would be nice if I could get rid of it.
>
> Is there a better way to abort?
>
> I suppose I could just fork sh, but inlining is pleasant when the prep is
> short.
>
> Thanks!
>
>
> [1]: https://skarnet.org/software/execline/foreground.html
> [2]: https://skarnet.org/software/execline/exitcodes.html
>


Succinct, idiomatic abort in execlineb scripts?

2022-09-05 Thread Saj Goonatilleke via skaware
Hello,

Within the context of, say, an s6 run script that needs to do a little bit of
prep work before execing into a server, it is often helpful to abort early if
any of said prep work stumbles upon an unexpected problem.

Maybe the filesystem is R/O.  Or full.
Maybe an operator has fat-fingered something we need.
Who knows!  Production is full of surprises.

sh provides set -e, which is often satisfactory for simple prep scripts
(if one is aware of its footguns).

Is there a succinct, idiomatic set -e equivalent in the execline suite?

I have included an example s6 run script below, which demonstrates the closest I
have come so far.  fgsigwait is my alternative take on foreground[1].  fgsigwait
behaviour differs in the following respects:

* fgsigwait exits[2] if prog1 exits with non-zero status.
  foreground, by comparison, sets the ? environment variable and continues.
  (fgsigwait -! reverts to foreground-ish behaviour.)

* fgsigwait forwards some trappable signals to its child.  HUP, INT, etc.
  This is where its name comes from.
  (PID 1 is broken on some of our systems, which provided the initial motivation
  for this hack.  fgsigwait always waits on prog1 after forwarding a signal.
  This, plus execline's execution model, gave me fine control over when stuff
  is forked -- and helped us avoid some Z process leaks.  Anyhoo.)

fgsigwait otherwise aims to be a syntactic execlineb drop-in for foreground in
cases where these features are desired.  Chaining stuff with fgsigwait emulates
sh set -e without needing to repeatedly and explicitly test the ? env var.

--- 8< ---
#!/usr/bin/env -S execlineb -WP

fdmove -c 2 1

# slow-deathroll is a simple wrapper around
# github.com/leahneukirchen/snooze
# extends the s6 one-second restart penalty if we crash too soon
fgsigwait { slow-deathroll }

# Here is a simple example of some prep work.
# We want to bail here if any of these things exit non-zero.
fgsigwait {
  execline-cd data
  if -t { test ! -e live } fgsigwait { mkdir -p empty } ln -s empty live
}

# maybe a smidge more prep here...

# all prep done.  exec into our server.
nsd -d -c nsd.conf
--- >8 ---

This does work OK, but, every time I reach for my little program, I can't shake
the feeling that I am probably reinventing some wheel.

fgsigwait was implemented in Go, as is personal tradition when something need be
hacked up in a hurry on the clock.  Spooling up the Go runtime eats a few extra
milliseconds of time, and a few megabytes of memory.  While not practically
significant to us -- we don't deploy to tiny machines -- a small part of me was
sad to add bloat.  It would be nice if I could get rid of it.

Is there a better way to abort?

I suppose I could just fork sh, but inlining is pleasant when the prep is short.

Thanks!


[1]: https://skarnet.org/software/execline/foreground.html
[2]: https://skarnet.org/software/execline/exitcodes.html