fix: delete instance data and remove legacy shared workspace support
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"git.misaka.ren/m1saka/dsh-web/internal/store"
|
||||
)
|
||||
|
||||
// Call only with the instance lock held, after Docker resources are removed.
|
||||
func (a *API) removeInstanceData(i store.Instance) error {
|
||||
for _, id := range []string{i.UID, i.ID} {
|
||||
if id == "" || id == "." || id == ".." || strings.ContainsAny(id, "/\\") {
|
||||
return errors.New("invalid instance storage path")
|
||||
}
|
||||
}
|
||||
for _, parts := range [][]string{{"workspaces", i.UID, "instances", i.ID}, {"backups", i.UID, i.ID}} {
|
||||
if err := a.removeDataDirectory(parts); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Walk parents without following symlinks; RemoveAll unlinks child symlinks.
|
||||
func (a *API) removeDataDirectory(parts []string) error {
|
||||
root, err := os.OpenRoot(a.root)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() { root.Close() }()
|
||||
for _, part := range parts[:len(parts)-1] {
|
||||
st, err := root.Lstat(part)
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !st.IsDir() {
|
||||
return errors.New("unsafe storage path")
|
||||
}
|
||||
next, err := root.OpenRoot(part)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
actual, err := next.Stat(".")
|
||||
if err != nil || !os.SameFile(st, actual) {
|
||||
next.Close()
|
||||
return errors.New("storage path changed")
|
||||
}
|
||||
root.Close()
|
||||
root = next
|
||||
}
|
||||
return root.RemoveAll(parts[len(parts)-1])
|
||||
}
|
||||
Reference in New Issue
Block a user