Files
tiny-forge/internal/volume/resolver.go
T
alexei.dolgolyov 4a0f223d61 feat(volume-browser): phase 1 - path resolver & file system API
- Extract volume path resolution into shared internal/volume/resolver.go
- File browser operations: ListDir, OpenFile, WriteZip, SaveFile
- Strict path traversal protection (double-validated)
- API endpoints: browse, download (file or zip), upload (multipart)
- Refactor deployer to use shared resolver
2026-04-01 22:59:02 +03:00

56 lines
1.7 KiB
Go

package volume
import (
"fmt"
"path/filepath"
"github.com/alexei/docker-watcher/internal/store"
)
// ResolveParams holds the parameters needed to resolve a volume's host path.
type ResolveParams struct {
BasePath string
ProjectName string
StageName string // required for instance and stage scopes
ImageTag string // required for instance scope
}
// ResolvePath returns the absolute host path for a volume based on its scope.
// Returns an error for ephemeral volumes (no host path) or missing parameters.
func ResolvePath(vol store.Volume, params ResolveParams) (string, error) {
scope := vol.Scope
if scope == "" {
switch vol.Mode {
case "isolated":
scope = "instance"
default:
scope = "project"
}
}
if scope == "ephemeral" {
return "", fmt.Errorf("ephemeral volumes have no host path")
}
switch scope {
case "instance":
if params.StageName == "" || params.ImageTag == "" {
return "", fmt.Errorf("instance scope requires stage and tag parameters")
}
return filepath.Join(params.BasePath, params.ProjectName, fmt.Sprintf("%s-%s", params.StageName, params.ImageTag), vol.Source), nil
case "stage":
if params.StageName == "" {
return "", fmt.Errorf("stage scope requires stage parameter")
}
return filepath.Join(params.BasePath, params.ProjectName, params.StageName, vol.Source), nil
case "project":
return filepath.Join(params.BasePath, params.ProjectName, vol.Source), nil
case "project_named":
return filepath.Join(params.BasePath, params.ProjectName, "_named", vol.Name, vol.Source), nil
case "named":
return filepath.Join(params.BasePath, "_named", vol.Name, vol.Source), nil
default:
return filepath.Join(params.BasePath, params.ProjectName, vol.Source), nil
}
}