mirror of
https://github.com/garethgeorge/backrest.git
synced 2025-12-13 17:25:38 +00:00
Initial commit
This commit is contained in:
64
internal/api/api.go
Normal file
64
internal/api/api.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
v1 "github.com/garethgeorge/resticui/gen/go/v1"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
)
|
||||
|
||||
func serveGRPC(ctx context.Context, socket string) error {
|
||||
lis, err := net.Listen("unix", socket)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to listen: %w", err)
|
||||
}
|
||||
grpcServer := grpc.NewServer()
|
||||
v1.RegisterResticUIServer(grpcServer, &server{})
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
grpcServer.GracefulStop()
|
||||
}()
|
||||
err = grpcServer.Serve(lis)
|
||||
if err != nil {
|
||||
return fmt.Errorf("grpc serving error: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func serveHTTPHandlers(ctx context.Context, mux *runtime.ServeMux) error {
|
||||
tmpDir, err := os.MkdirTemp("", "resticui")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create temp dir for unix domain socket: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
os.RemoveAll(tmpDir)
|
||||
}()
|
||||
|
||||
socket := filepath.Join(tmpDir, "resticui.sock")
|
||||
|
||||
opts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}
|
||||
err = v1.RegisterResticUIHandlerFromEndpoint(ctx, mux, fmt.Sprintf("unix:%v", socket), opts)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to register gateway: %w", err)
|
||||
}
|
||||
|
||||
if err := serveGRPC(ctx, socket); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Handler returns an http.Handler serving the API, cancel the context to cleanly shut down the server.
|
||||
func ServeAPI(ctx context.Context, mux *http.ServeMux) error {
|
||||
apiMux := runtime.NewServeMux()
|
||||
mux.Handle("/api/", http.StripPrefix("/api", apiMux))
|
||||
return serveHTTPHandlers(ctx, apiMux)
|
||||
}
|
||||
55
internal/api/server.go
Normal file
55
internal/api/server.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
v1 "github.com/garethgeorge/resticui/gen/go/v1"
|
||||
"github.com/garethgeorge/resticui/internal/config"
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/protobuf/types/known/emptypb"
|
||||
)
|
||||
|
||||
type server struct {
|
||||
*v1.UnimplementedResticUIServer
|
||||
}
|
||||
|
||||
var _ v1.ResticUIServer = &server{}
|
||||
|
||||
func (s *server) GetConfig(ctx context.Context, empty *emptypb.Empty) (*v1.Config, error) {
|
||||
return config.Default.Get()
|
||||
}
|
||||
|
||||
func (s *server) SetConfig(ctx context.Context, c *v1.Config) (*v1.Config, error) {
|
||||
err := config.Default.Update(c)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to update config: %w", err)
|
||||
}
|
||||
return config.Default.Get()
|
||||
}
|
||||
|
||||
func (s *server) GetEvents(_ *emptypb.Empty, stream v1.ResticUI_GetEventsServer) error {
|
||||
for {
|
||||
zap.S().Info("Sending event")
|
||||
stream.Send(&v1.Event{
|
||||
Timestamp: 0,
|
||||
Event: &v1.Event_BackupStatusChange{
|
||||
BackupStatusChange: &v1.BackupStatusEvent{
|
||||
Status: v1.Status_IN_PROGRESS,
|
||||
Percent: 0,
|
||||
Plan: "myplan",
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
timer := time.NewTimer(time.Second * 1)
|
||||
|
||||
select {
|
||||
case <-stream.Context().Done():
|
||||
zap.S().Info("Get events hangup")
|
||||
return nil
|
||||
case <-timer.C:
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user