mirror of
https://github.com/kopia/kopia.git
synced 2026-01-24 06:18:02 -05:00
* tools: upgraded linter to 1.40.1 * lint: fixed nolintlint vionlations * lint: disabled tagliatele linter * lint: fixed remaining warnings
124 lines
3.0 KiB
Go
124 lines
3.0 KiB
Go
package server
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
|
|
"github.com/gorilla/mux"
|
|
|
|
"github.com/kopia/kopia/internal/mount"
|
|
"github.com/kopia/kopia/internal/serverapi"
|
|
"github.com/kopia/kopia/repo/object"
|
|
"github.com/kopia/kopia/snapshot/snapshotfs"
|
|
)
|
|
|
|
func (s *Server) handleMountCreate(ctx context.Context, r *http.Request, body []byte) (interface{}, *apiError) {
|
|
req := &serverapi.MountSnapshotRequest{}
|
|
if err := json.Unmarshal(body, req); err != nil {
|
|
return nil, requestError(serverapi.ErrorMalformedRequest, "malformed request body")
|
|
}
|
|
|
|
oid, err := object.ParseID(req.Root)
|
|
if err != nil {
|
|
return nil, requestError(serverapi.ErrorMalformedRequest, "unable to parse OID")
|
|
}
|
|
|
|
var c mount.Controller
|
|
|
|
v, ok := s.mounts.Load(oid)
|
|
if !ok {
|
|
log(ctx).Debugf("mount controller for %v not found, starting", oid)
|
|
|
|
var err error
|
|
c, err = mount.Directory(ctx, snapshotfs.DirectoryEntry(s.rep, oid, nil), "*", mount.Options{})
|
|
|
|
if err != nil {
|
|
return nil, internalServerError(err)
|
|
}
|
|
|
|
if actual, loaded := s.mounts.LoadOrStore(oid, c); loaded {
|
|
c.Unmount(ctx) // nolint:errcheck
|
|
c = actual.(mount.Controller) // nolint:forcetypeassert
|
|
}
|
|
} else {
|
|
c = v.(mount.Controller) // nolint:forcetypeassert
|
|
}
|
|
|
|
log(ctx).Debugf("mount for %v => %v", oid, c.MountPath())
|
|
|
|
return &serverapi.MountedSnapshot{
|
|
Path: c.MountPath(),
|
|
Root: oid,
|
|
}, nil
|
|
}
|
|
|
|
func (s *Server) handleMountGet(ctx context.Context, r *http.Request, body []byte) (interface{}, *apiError) {
|
|
oid := object.ID(mux.Vars(r)["rootObjectID"])
|
|
|
|
v, ok := s.mounts.Load(oid)
|
|
if !ok {
|
|
return nil, notFoundError("mount point not found")
|
|
}
|
|
|
|
c := v.(mount.Controller) // nolint:forcetypeassert
|
|
|
|
return &serverapi.MountedSnapshot{
|
|
Path: c.MountPath(),
|
|
Root: oid,
|
|
}, nil
|
|
}
|
|
|
|
func (s *Server) handleMountDelete(ctx context.Context, r *http.Request, body []byte) (interface{}, *apiError) {
|
|
oid := object.ID(mux.Vars(r)["rootObjectID"])
|
|
|
|
v, ok := s.mounts.Load(oid)
|
|
if !ok {
|
|
return nil, notFoundError("mount point not found")
|
|
}
|
|
|
|
c := v.(mount.Controller) // nolint:forcetypeassert
|
|
|
|
if err := c.Unmount(ctx); err != nil {
|
|
return nil, internalServerError(err)
|
|
}
|
|
|
|
s.mounts.Delete(oid)
|
|
|
|
return &serverapi.Empty{}, nil
|
|
}
|
|
|
|
func (s *Server) handleMountList(ctx context.Context, r *http.Request, body []byte) (interface{}, *apiError) {
|
|
res := &serverapi.MountedSnapshots{
|
|
Items: []*serverapi.MountedSnapshot{},
|
|
}
|
|
|
|
s.mounts.Range(func(key, val interface{}) bool {
|
|
oid := key.(object.ID) // nolint:forcetypeassert
|
|
c := val.(mount.Controller) // nolint:forcetypeassert
|
|
|
|
res.Items = append(res.Items, &serverapi.MountedSnapshot{
|
|
Path: c.MountPath(),
|
|
Root: oid,
|
|
})
|
|
return true
|
|
})
|
|
|
|
return res, nil
|
|
}
|
|
|
|
func (s *Server) unmountAll(ctx context.Context) {
|
|
s.mounts.Range(func(key, val interface{}) bool {
|
|
c := val.(mount.Controller) // nolint:forcetypeassert
|
|
|
|
log(ctx).Debugf("unmounting %v from %v", key, c.MountPath())
|
|
|
|
if err := c.Unmount(ctx); err != nil {
|
|
log(ctx).Errorf("unable to unmount %v", key)
|
|
}
|
|
|
|
s.mounts.Delete(key)
|
|
return true
|
|
})
|
|
}
|