/* * Copyright 2026 Oleg Borodin */ package fileoper import ( "bytes" "context" "encoding/json" "io" "net/http" "path" "strconv" "mstore/pkg/auxtool" "mstore/pkg/terms" yaml "sigs.k8s.io/yaml" //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) const helmIndexName = "index.yaml" if filename != helmIndexName { 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() url := "https://" + path.Join(oper.hostname, collection) for _, descr := range fileDescrs { if descr.Type == hcMediaType { meta := &chart.Metadata{} err = json.Unmarshal([]byte(descr.HelmMeta), meta) if err != nil { code := http.StatusInternalServerError return code, res, err } index.MustAdd(meta, descr.Name, url, 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 }