fix storage pool, datasets,volume and disk
Some checks failed
CI / test-build (push) Has been cancelled

This commit is contained in:
2025-12-20 02:18:51 +00:00
parent 8029bcfa15
commit 98bedf6487
333 changed files with 352 additions and 64 deletions

View File

@@ -106,18 +106,13 @@ func (a *App) handleCreatePool(w http.ResponseWriter, r *http.Request) {
// Pool doesn't exist - return the error with detailed context
if err != nil {
log.Printf("error: pool %s creation failed - CreatePool error: %v, GetPool error: %v", req.Name, err, getErr)
writeJSON(w, http.StatusInternalServerError, map[string]string{
"error": err.Error(),
"details": fmt.Sprintf("Pool '%s' was not created. Check logs for zpool command output.", req.Name),
})
writeError(w, errors.ErrInternal("failed to create pool").WithDetails(fmt.Sprintf("Pool '%s' was not created: %v. Check logs for zpool command output.", req.Name, err)))
return
}
// No error but pool doesn't exist (shouldn't happen, but handle it)
log.Printf("warning: pool %s creation reported no error but pool was not found", req.Name)
writeJSON(w, http.StatusInternalServerError, map[string]string{
"error": fmt.Sprintf("Pool '%s' creation reported success but pool was not found", req.Name),
})
writeError(w, errors.ErrInternal(fmt.Sprintf("Pool '%s' creation reported success but pool was not found", req.Name)))
}
func (a *App) handleGetPool(w http.ResponseWriter, r *http.Request) {
@@ -296,15 +291,15 @@ func (a *App) handleCreateDataset(w http.ResponseWriter, r *http.Request) {
}
func (a *App) handleGetDataset(w http.ResponseWriter, r *http.Request) {
name := pathParam(r, "/api/v1/datasets/")
name := pathParamFull(r, "/api/v1/datasets/")
if name == "" {
writeJSON(w, http.StatusBadRequest, map[string]string{"error": "dataset name required"})
writeError(w, errors.ErrBadRequest("dataset name required"))
return
}
datasets, err := a.zfs.ListDatasets("")
if err != nil {
writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
writeError(w, errors.ErrInternal("failed to list datasets").WithDetails(err.Error()))
return
}
@@ -315,7 +310,7 @@ func (a *App) handleGetDataset(w http.ResponseWriter, r *http.Request) {
}
}
writeJSON(w, http.StatusNotFound, map[string]string{"error": "dataset not found"})
writeError(w, errors.ErrNotFound("dataset"))
}
func (a *App) handleUpdateDataset(w http.ResponseWriter, r *http.Request) {
@@ -325,9 +320,9 @@ func (a *App) handleUpdateDataset(w http.ResponseWriter, r *http.Request) {
}
func (a *App) handleDeleteDataset(w http.ResponseWriter, r *http.Request) {
name := pathParam(r, "/api/v1/datasets/")
name := pathParamFull(r, "/api/v1/datasets/")
if name == "" {
writeJSON(w, http.StatusBadRequest, map[string]string{"error": "dataset name required"})
writeError(w, errors.ErrBadRequest("dataset name required"))
return
}
@@ -335,7 +330,7 @@ func (a *App) handleDeleteDataset(w http.ResponseWriter, r *http.Request) {
if err := a.zfs.DestroyDataset(name, recursive); err != nil {
log.Printf("destroy dataset error: %v", err)
writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
writeError(w, errors.ErrInternal("failed to destroy dataset").WithDetails(err.Error()))
return
}
@@ -399,15 +394,15 @@ func (a *App) handleCreateZVOL(w http.ResponseWriter, r *http.Request) {
}
func (a *App) handleGetZVOL(w http.ResponseWriter, r *http.Request) {
name := pathParam(r, "/api/v1/zvols/")
name := pathParamFull(r, "/api/v1/zvols/")
if name == "" {
writeJSON(w, http.StatusBadRequest, map[string]string{"error": "zvol name required"})
writeError(w, errors.ErrBadRequest("zvol name required"))
return
}
zvols, err := a.zfs.ListZVOLs("")
if err != nil {
writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
writeError(w, errors.ErrInternal("failed to list zvols").WithDetails(err.Error()))
return
}
@@ -418,19 +413,19 @@ func (a *App) handleGetZVOL(w http.ResponseWriter, r *http.Request) {
}
}
writeJSON(w, http.StatusNotFound, map[string]string{"error": "zvol not found"})
writeError(w, errors.ErrNotFound("zvol"))
}
func (a *App) handleDeleteZVOL(w http.ResponseWriter, r *http.Request) {
name := pathParam(r, "/api/v1/zvols/")
name := pathParamFull(r, "/api/v1/zvols/")
if name == "" {
writeJSON(w, http.StatusBadRequest, map[string]string{"error": "zvol name required"})
writeError(w, errors.ErrBadRequest("zvol name required"))
return
}
if err := a.zfs.DestroyZVOL(name); err != nil {
log.Printf("destroy zvol error: %v", err)
writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
writeError(w, errors.ErrInternal("failed to destroy zvol").WithDetails(err.Error()))
return
}

View File

@@ -2,6 +2,7 @@ package httpapp
import (
"net/http"
"net/url"
"strings"
"gitea.avt.data-center.id/othman.suseno/atlas/internal/errors"
@@ -58,6 +59,22 @@ func pathParam(r *http.Request, prefix string) string {
return ""
}
// pathParamFull extracts the full path after prefix (for dataset/zvol names that may contain slashes)
func pathParamFull(r *http.Request, prefix string) string {
path := strings.TrimPrefix(r.URL.Path, prefix)
path = strings.Trim(path, "/")
if path == "" {
return ""
}
// URL decode the path
decoded, err := url.PathUnescape(path)
if err != nil {
// If decoding fails, return original path
return path
}
return decoded
}
// handlePoolOps routes pool operations by method
func (a *App) handlePoolOps(w http.ResponseWriter, r *http.Request) {
// Extract pool name from path like /api/v1/pools/tank