m/c/p/context: add CLI context package

This adds a package for getting contexts useful in a CLI application.
The context inherits from a parent (usually contxt.Background in CLIs)
and is cancelled when the user cancels the application by interrupting it
(most commonly by pressing Ctrl+C, but sending a SIGINT will also do).

Change-Id: Ibfeee17f3f6284745d3fbf3395d4b3ca9805258f
Reviewed-on: https://review.monogon.dev/c/monogon/+/486
Reviewed-by: Sergiusz Bazanski <serge@monogon.tech>
diff --git a/metropolis/cli/pkg/context/context.go b/metropolis/cli/pkg/context/context.go
new file mode 100644
index 0000000..bad24ea
--- /dev/null
+++ b/metropolis/cli/pkg/context/context.go
@@ -0,0 +1,21 @@
+package clicontext
+
+import (
+	"context"
+	"os"
+	"os/signal"
+)
+
+// WithInterrupt returns a context for use in a command-line utility. It gets
+// cancelled if the user interrupts the command, for example by pressing
+// Ctrl+C.
+func WithInterrupt(parent context.Context) context.Context {
+	ctx, cancel := context.WithCancel(parent)
+	c := make(chan os.Signal, 1)
+	signal.Notify(c, os.Interrupt)
+	go func() {
+		<-c
+		cancel()
+	}()
+	return ctx
+}