diff --git a/cmd/gitsign-credential-cache/README.md b/cmd/gitsign-credential-cache/README.md index 723cf260..4c99b5c9 100644 --- a/cmd/gitsign-credential-cache/README.md +++ b/cmd/gitsign-credential-cache/README.md @@ -43,6 +43,36 @@ that is used is output by `gitsign-credential-cache` when it is spawned. See [os.UserCacheDir](https://pkg.go.dev/os#UserCacheDir) for details on how the cache directory is selected. +### Systemd service + +There are systemd user units in contrib + +Change path to gitsign-credential-cache in service unit + +```sh +${EDITOR:-vi} ./contrib/gitsign-credential-cache.service +``` + +Install units in home directory for specific user + +```sh +install -m 0660 -D -t $HOME/.config/systemd/user/ ./contrib/gitsign-credential-cache.{socket,service} +systemctl --user daemon-reload +``` + +OR install them for all users + +```sh +sudo install -m 0660 -D -t /etc/systemd/user/ ./contrib/gitsign-credential-cache.{socket,service} +sudo systemctl daemon-reload +``` + +After that you can enable and start socket service + +```sh +systemctl --user enable --now gitsign-credential-cache.socket +``` + ### Forwarding cache over SSH (Requires gitsign >= v0.5) diff --git a/cmd/gitsign-credential-cache/main.go b/cmd/gitsign-credential-cache/main.go index 9b01ddc4..cd74a191 100644 --- a/cmd/gitsign-credential-cache/main.go +++ b/cmd/gitsign-credential-cache/main.go @@ -23,6 +23,7 @@ import ( "path/filepath" "syscall" + "github.com/coreos/go-systemd/v22/activation" "github.com/pborman/getopt/v2" "github.com/sigstore/gitsign/internal/cache/service" @@ -32,6 +33,7 @@ import ( var ( // Action flags versionFlag = getopt.BoolLong("version", 'v', "print the version number") + systemdFlag = getopt.BoolLong("systemd-socket-activation", 's', "use systemd socket activation") ) func main() { @@ -47,31 +49,67 @@ func main() { os.Exit(0) } - user, err := os.UserCacheDir() - if err != nil { - log.Fatalf("error getting user cache directory: %v", err) - } + var connChan = make(chan net.Conn) + if *systemdFlag { + // Stop if we're not running under systemd. + if os.Getenv("LISTEN_PID") == "" { + log.Fatalf("systemd socket activation requested but not running under systemd") + } - dir := filepath.Join(user, "sigstore", "gitsign") - if err := os.MkdirAll(dir, 0700); err != nil { - log.Fatalf("error creating %s: %v", dir, err) - } + listeners, err := activation.Listeners() + if err != nil { + log.Fatalf("error getting systemd listeners: %v", err) + } + var validCount int + for _, l := range listeners { + if l == nil { + continue + } + fmt.Println(l.Addr().String()) + go connToChan(l, connChan) + validCount++ + } + if validCount == 0 { + log.Fatalf("no valid systemd listeners found") + } + } else { + user, err := os.UserCacheDir() + if err != nil { + log.Fatalf("error getting user cache directory: %v", err) + } - path := filepath.Join(dir, "cache.sock") - if _, err := os.Stat(path); err == nil { - os.Remove(path) - } - fmt.Println(path) + dir := filepath.Join(user, "sigstore", "gitsign") + if err := os.MkdirAll(dir, 0700); err != nil { + log.Fatalf("error creating %s: %v", dir, err) + } + + path := filepath.Join(dir, "cache.sock") + if _, err := os.Stat(path); err == nil { + os.Remove(path) + } + fmt.Println(path) - l, err := net.Listen("unix", path) - if err != nil { - log.Fatalf("error opening socket: %v", err) + l, err := net.Listen("unix", path) + if err != nil { + log.Fatalf("error opening socket: %v", err) + } + go connToChan(l, connChan) } srv := rpc.NewServer() if err := srv.Register(service.NewService()); err != nil { log.Fatalf("error registering RPC service: %v", err) } + for conn := range connChan { + go srv.ServeConn(conn) + } +} + +func connToChan(l net.Listener, connChan chan net.Conn) { for { - srv.Accept(l) + conn, err := l.Accept() + if err != nil { + log.Fatalf("error accepting connection: %v", err) + } + connChan <- conn } } diff --git a/contrib/systemd/gitsign-credential-cache.service b/contrib/systemd/gitsign-credential-cache.service new file mode 100644 index 00000000..3bf1d5da --- /dev/null +++ b/contrib/systemd/gitsign-credential-cache.service @@ -0,0 +1,9 @@ +[Unit] +Description=GitSign credential cache + +[Service] +Type=simple +ExecStart=%h/.local/bin/gitsign-credential-cache + +[Install] +WantedBy=default.target diff --git a/contrib/systemd/gitsign-credential-cache.socket b/contrib/systemd/gitsign-credential-cache.socket new file mode 100644 index 00000000..ad14e9f7 --- /dev/null +++ b/contrib/systemd/gitsign-credential-cache.socket @@ -0,0 +1,9 @@ +[Unit] +Description=GitSign credential cache socket + +[Socket] +ListenStream=%C/sigstore/gitsign/cache.sock +DirectoryMode=0700 + +[Install] +WantedBy=default.target diff --git a/go.mod b/go.mod index b78a5af1..100f20ef 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.19 require ( github.com/coreos/go-oidc/v3 v3.5.0 + github.com/coreos/go-systemd/v22 v22.5.0 github.com/github/smimesign v0.2.0 github.com/go-git/go-billy/v5 v5.4.0 github.com/go-git/go-git/v5 v5.5.2 @@ -86,7 +87,6 @@ require ( github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be // indirect github.com/containerd/stargz-snapshotter/estargz v0.12.0 // indirect github.com/coreos/go-semver v0.3.0 // indirect - github.com/coreos/go-systemd/v22 v22.3.2 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/cyberphone/json-canonicalization v0.0.0-20210823021906-dc406ceaf94b // indirect github.com/davecgh/go-spew v1.1.1 // indirect diff --git a/go.sum b/go.sum index 765c808a..4e8b79fb 100644 --- a/go.sum +++ b/go.sum @@ -395,8 +395,9 @@ github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7 github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= -github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=