isle/go/cmd/entrypoint/daemon_util.go

75 lines
1.6 KiB
Go

package main
import (
"context"
"errors"
"fmt"
"io/fs"
"isle/daemon"
"isle/daemon/jsonrpc2"
"net"
"net/http"
"os"
"dev.mediocregopher.com/mediocre-go-lib.git/mctx"
"dev.mediocregopher.com/mediocre-go-lib.git/mlog"
)
const daemonHTTPRPCPath = "/rpc/v0.json"
func newHTTPServer(
ctx context.Context, logger *mlog.Logger, rpc daemon.RPC,
) (
*http.Server, error,
) {
socketPath := daemon.HTTPSocketPath()
ctx = mctx.Annotate(ctx, "socketPath", socketPath)
if err := os.Remove(socketPath); errors.Is(err, fs.ErrNotExist) {
// No problem
} else if err != nil {
return nil, fmt.Errorf(
"removing %q prior to listening: %w", socketPath, err,
)
} else {
logger.WarnString(
ctx, "Deleted existing socket file prior to listening, it's possible a previous daemon failed to shutdown gracefully",
)
}
l, err := net.Listen("unix", socketPath)
if err != nil {
return nil, fmt.Errorf(
"listening on socket %q: %w", socketPath, err,
)
}
if err := os.Chmod(socketPath, 0660); err != nil {
return nil, fmt.Errorf(
"setting permissions of %q to 0660: %w", socketPath, err,
)
}
logger.Info(ctx, "HTTP server socket created")
rpcHandler := jsonrpc2.Chain(
jsonrpc2.NewMLogMiddleware(logger.WithNamespace("rpc")),
jsonrpc2.ExposeServerSideErrorsMiddleware,
)(
jsonrpc2.NewDispatchHandler(&rpc),
)
httpMux := http.NewServeMux()
httpMux.Handle(daemonHTTPRPCPath, jsonrpc2.NewHTTPHandler(rpcHandler))
srv := &http.Server{Handler: httpMux}
go func() {
if err := srv.Serve(l); !errors.Is(err, http.ErrServerClosed) {
logger.Fatal(ctx, "HTTP server unexpectedly shut down", err)
}
}()
return srv, nil
}