Files
mstore/app/fileoper/getfile.go
T
2026-03-13 19:02:42 +02:00

126 lines
3.1 KiB
Go

/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*
* This work is published and licensed under a Creative Commons
* Attribution-NonCommercial-NoDerivatives 4.0 International License.
*
* Distribution of this work is permitted, but commercial use and
* modifications are strictly prohibited.
*/
package fileoper
import (
"bytes"
"context"
"encoding/json"
"io"
"net/http"
"path"
"strconv"
"mstore/pkg/auxtool"
"mstore/pkg/terms"
yaml "go.yaml.in/yaml/v4"
chart "helm.sh/helm/v4/pkg/chart/v2"
repo "helm.sh/helm/v4/pkg/repo/v1"
)
// GetFile
type GetFileParams struct {
Filepath string
}
type GetFileResult struct {
ContentType string
ContentSize string
ContentDigest string
Source io.ReadCloser
ContentCreatedAt string
ContentCreatedBy string
ContentUpdatedAt string
ContentUpdatedBy string
}
func (oper *Operator) GetFile(ctx context.Context, operatorID string, params *GetFileParams) (int, *GetFileResult, error) {
var err error
res := &GetFileResult{}
xfilepath, err := cleanFilepath(params.Filepath)
if err != nil {
code := http.StatusInternalServerError
return code, res, err
}
filename := path.Base(xfilepath)
collection := path.Dir(xfilepath)
resName := params.Filepath
oper.iLock.WaitAndLock(resName)
defer oper.iLock.Done(resName)
if filename != "index.yaml" {
descrExists, fileDescr, err := oper.mdb.GetFileByCollectionName(ctx, collection, filename)
if err != nil {
code := http.StatusInternalServerError
return code, res, err
}
if !descrExists {
code := http.StatusNotFound
return code, res, err
}
reader, err := oper.store.GetFileReader(collection, filename)
if err != nil {
code := http.StatusInternalServerError
return code, res, err
}
res = &GetFileResult{
ContentSize: strconv.FormatInt(fileDescr.Size, 10),
ContentType: fileDescr.Type,
ContentDigest: fileDescr.Checksum,
Source: reader,
ContentCreatedAt: fileDescr.CreatedAt,
ContentCreatedBy: fileDescr.CreatedBy,
ContentUpdatedAt: fileDescr.UpdatedAt,
ContentUpdatedBy: fileDescr.UpdatedBy,
}
code := http.StatusOK
return code, res, err
}
fileDescrs, err := oper.mdb.ListFilesByCollection(ctx, collection)
index := repo.NewIndexFile()
for _, descr := range fileDescrs {
if descr.Type == hcMediaType {
meta := &chart.Metadata{}
oper.logg.Debugf("=== %s", descr.HelmMeta)
err = json.Unmarshal([]byte(descr.HelmMeta), meta)
if err != nil {
code := http.StatusInternalServerError
return code, res, err
}
index.MustAdd(meta, descr.Name, "aaa", descr.HelmHash)
}
}
indexdata, err := yaml.Marshal(index)
if err != nil {
code := http.StatusInternalServerError
return code, res, err
}
reader := io.NopCloser(bytes.NewReader(indexdata))
now := auxtool.TimeNow()
size := int64(len(indexdata))
res = &GetFileResult{
ContentSize: strconv.FormatInt(size, 10),
ContentType: "application/yaml",
Source: reader,
ContentCreatedAt: now,
ContentCreatedBy: terms.ServerID,
ContentUpdatedAt: now,
ContentUpdatedBy: terms.ServerID,
}
code := http.StatusOK
return code, res, err
}