Skip to content

Commit

Permalink
Support systemd socket activation
Browse files Browse the repository at this point in the history
This change adds 2 features:
1) the --address flag of the soci snapshotter supports a network prefix
2) The soci snapshotter can listen on a file descriptor passed by
   systemd socket activation.

If the user tells soci to listen on a file descriptor, but doesn't use
systemd socket activation to launch the process, the snapshotter will
fall back to the default address as a unix socket.

The example systemd service file is updated to use systemd activation if
possible. There is an example systemd socket file, but no strict
dependency from the service file so that users who are always starting
SOCI on boot won't get a warning from systemd.

Signed-off-by: Kern Walster <walster@amazon.com>
  • Loading branch information
Kern-- committed Sep 18, 2024
1 parent 375a699 commit 9db5fdf
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 2 deletions.
39 changes: 38 additions & 1 deletion cmd/soci-snapshotter-grpc/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ package main

import (
"context"
"errors"
"flag"
"fmt"
"io"
Expand All @@ -43,6 +44,7 @@ import (
"os"
"os/signal"
"path/filepath"
"strings"
"time"

_ "net/http/pprof"
Expand All @@ -66,6 +68,7 @@ import (
"github.com/containerd/containerd/snapshots"
runtime_alpha "github.com/containerd/containerd/third_party/k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
"github.com/containerd/log"
"github.com/coreos/go-systemd/v22/activation"
sddaemon "github.com/coreos/go-systemd/v22/daemon"
metrics "github.com/docker/go-metrics"
"github.com/sirupsen/logrus"
Expand Down Expand Up @@ -252,7 +255,7 @@ func serve(ctx context.Context, rpc *grpc.Server, addr string, rs snapshots.Snap
}

// Listen and serve
l, err := net.Listen("unix", addr)
l, err := getListener(ctx, addr)
if err != nil {
return false, fmt.Errorf("error on listen socket %q: %w", addr, err)
}
Expand Down Expand Up @@ -337,3 +340,37 @@ func getCriConn(criAddr string) (*grpc.ClientConn, error) {
}
return grpc.Dial(dialer.DialAddress(criAddr), gopts...)
}

func getListener(ctx context.Context, address string) (net.Listener, error) {
protocol, addr, found := strings.Cut(address, "://")
if !found {
// The address doesn't start with a protocol, assume it's a path to a unix socket
return net.Listen("unix", address)
}
switch protocol {
case "unix":
return net.Listen(protocol, addr)
case "fd":
return listenFd(ctx)
default:
return nil, fmt.Errorf("unkown protocol for address %s", address)
}
}

func listenFd(ctx context.Context) (net.Listener, error) {
listeners, err := activation.Listeners()
if err != nil {
return nil, err
}
if len(listeners) == 0 {
log.G(ctx).Info("Address was set to listen on a file descriptor, but no file descriptors were passed. Perhaps soci was launched directly without using systemd socket activation? Using the default address.")
return net.Listen("unix", defaultAddress)
}
if len(listeners) > 1 {
for _, socket := range listeners {
socket.Close()
}
return nil, errors.New("soci only supports a single systemd socket on activation")
}
return listeners[0], nil
}
2 changes: 1 addition & 1 deletion soci-snapshotter.service
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Before=containerd.service

[Service]
Type=notify
ExecStart=/usr/local/bin/soci-snapshotter-grpc
ExecStart=/usr/local/bin/soci-snapshotter-grpc --address fd://
Restart=always
RestartSec=5

Expand Down
10 changes: 10 additions & 0 deletions soci-snapshotter.socket
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[Unit]
Description=soci snapshotter containerd plugin (socket)
Documentation=https://github.com/awslabs/soci-snapshotter

[Socket]
ListenStream=/run/soci-snapshotter-grpc/soci-snapshotter-grpc.sock
SocketMode=0660

[Install]
WantedBy=sockets.target

0 comments on commit 9db5fdf

Please sign in to comment.