isle/go/cmd/entrypoint/daemon_util.go

78 lines
1.7 KiB
Go

package main
import (
"context"
"errors"
"fmt"
"io/fs"
"isle/daemon"
"isle/toolkit"
"net"
"net/http"
"os"
"dev.mediocregopher.com/mediocre-go-lib.git/mctx"
"dev.mediocregopher.com/mediocre-go-lib.git/mlog"
)
const (
daemonHTTPSocketDefaultPath = "/tmp/isle-daemon.sock"
daemonHTTPSocketPathEnvVar = "ISLE_DAEMON_HTTP_SOCKET_PATH"
daemonHTTPRPCPath = "/rpc/v0.json"
)
func httpSocketPath() string {
return toolkit.EnvOr(
daemonHTTPSocketPathEnvVar,
func() string { return daemonHTTPSocketDefaultPath },
)
}
func newHTTPServer(
ctx context.Context, logger *mlog.Logger, daemonInst *daemon.Daemon,
) (
*http.Server, error,
) {
socketPath := 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")
httpMux := http.NewServeMux()
httpMux.Handle(daemonHTTPRPCPath, daemonInst.HTTPRPCHandler())
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
}