snapshot of https://github.com/cortezaproject/corteza.git (2024.9.x, 2026-09-18; blobs > 131072B omitted)
Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s
Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s
This commit is contained in:
138
server/pkg/objstore/plain/store.go
Normal file
138
server/pkg/objstore/plain/store.go
Normal file
@@ -0,0 +1,138 @@
|
||||
package plain
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/afero"
|
||||
)
|
||||
|
||||
type (
|
||||
store struct {
|
||||
fs afero.Fs
|
||||
|
||||
namespace string
|
||||
|
||||
originalFn func(id uint64, ext string) string
|
||||
previewFn func(id uint64, ext string) string
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
defPreviewFn = func(id uint64, ext string) string {
|
||||
return fmt.Sprintf("%d_preview.%s", id, ext)
|
||||
}
|
||||
|
||||
defOriginalFn = func(id uint64, ext string) string {
|
||||
return fmt.Sprintf("%d.%s", id, ext)
|
||||
}
|
||||
)
|
||||
|
||||
func New(namespace string) (*store, error) {
|
||||
return NewWithAfero(afero.NewOsFs(), namespace)
|
||||
}
|
||||
|
||||
func NewWithAfero(fs afero.Fs, namespace string) (*store, error) {
|
||||
return &store{
|
||||
fs: fs,
|
||||
namespace: namespace,
|
||||
|
||||
originalFn: defOriginalFn,
|
||||
previewFn: defPreviewFn,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *store) check(filename string) error {
|
||||
if len(filename) == 0 {
|
||||
return fmt.Errorf("Invalid filename when trying to store file: '%s' (for %s)", filename, s.namespace)
|
||||
}
|
||||
|
||||
if filename[:len(s.namespace)+1] != s.namespace+"/" {
|
||||
return fmt.Errorf("Invalid namespace when trying to store file: '%s' (for %s)", filename, s.namespace)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *store) Original(id uint64, ext string) string {
|
||||
return path.Join(s.namespace, s.originalFn(id, ext))
|
||||
}
|
||||
|
||||
func (s *store) Preview(id uint64, ext string) string {
|
||||
return path.Join(s.namespace, s.previewFn(id, ext))
|
||||
}
|
||||
|
||||
func (s *store) Save(filename string, contents io.Reader) (err error) {
|
||||
// check filename for validity
|
||||
if err = s.check(filename); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
folder := path.Dir(filename)
|
||||
|
||||
if err = s.fs.MkdirAll(folder, 0755); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return afero.WriteReader(s.fs, filename, contents)
|
||||
}
|
||||
|
||||
func (s *store) Remove(filename string) error {
|
||||
// check filename for validity
|
||||
if err := s.check(filename); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return s.fs.Remove(filename)
|
||||
}
|
||||
|
||||
func (s *store) Open(filename string) (out io.ReadSeekCloser, err error) {
|
||||
// check filename for validity
|
||||
if err := s.check(filename); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i := 1; i <= 3; i++ {
|
||||
out, err = s.fs.Open(filename)
|
||||
if err != nil {
|
||||
time.Sleep(time.Millisecond * 500 * time.Duration(i))
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (s *store) Healthcheck(ctx context.Context) error {
|
||||
var (
|
||||
fname = fmt.Sprintf("%s/.healthcheck_%d", s.namespace, time.Now().UnixNano())
|
||||
buf = &bytes.Buffer{}
|
||||
)
|
||||
|
||||
if s == nil {
|
||||
return fmt.Errorf("uninitialized")
|
||||
}
|
||||
|
||||
buf.Write([]byte("healthcheck"))
|
||||
|
||||
if err := s.Save(fname, buf); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := s.Open(fname); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := s.Remove(fname); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
73
server/pkg/objstore/plain/store_test.go
Normal file
73
server/pkg/objstore/plain/store_test.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package plain
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
"github.com/spf13/afero"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestStore(t *testing.T) {
|
||||
readerToString := func(r io.Reader) string {
|
||||
b := new(bytes.Buffer)
|
||||
b.ReadFrom(r)
|
||||
return b.String()
|
||||
}
|
||||
|
||||
store, err := NewWithAfero(afero.NewMemMapFs(), "test")
|
||||
|
||||
require.True(t, err == nil, "Unexpected error when creating store: %+v", err)
|
||||
require.True(t, store != nil, "Expected non-nil return for new store")
|
||||
|
||||
{
|
||||
fn := store.Original(123, "jpg")
|
||||
expected := "test/123.jpg"
|
||||
require.True(t, fn == expected, "Unexpected filename returned: %s != %s", expected, fn)
|
||||
}
|
||||
|
||||
{
|
||||
fn := store.Preview(123, "jpg")
|
||||
expected := "test/123_preview.jpg"
|
||||
require.True(t, fn == expected, "Unexpected filename returned: %s != %s", expected, fn)
|
||||
}
|
||||
|
||||
// write a file
|
||||
{
|
||||
buf := bytes.NewBuffer([]byte("This is a testing buffer"))
|
||||
err := store.Save("test/123.jpg", buf)
|
||||
require.True(t, err == nil, "Error saving file, %+v", err)
|
||||
|
||||
err = store.Save("test123/123.jpg", buf)
|
||||
require.True(t, err != nil, "Expected error when saving file outside of namespace")
|
||||
}
|
||||
|
||||
// read a file
|
||||
{
|
||||
buf, err := store.Open("test/123.jpg")
|
||||
require.True(t, err == nil, "Unexpected error when reading file: %+v", err)
|
||||
s := readerToString(buf)
|
||||
require.True(t, s == "This is a testing buffer", "Unexpected response when reading file: %s", s)
|
||||
|
||||
_, err = store.Open("test/1234.jpg")
|
||||
require.True(t, err != nil, "Expected error when opening non-existent file")
|
||||
_, err = store.Open("test123/123.jpg")
|
||||
require.True(t, err != nil, "Expected error when opening file outside of namespace")
|
||||
}
|
||||
|
||||
// delete a file
|
||||
{
|
||||
err := store.Remove("test/123.jpg")
|
||||
require.True(t, err == nil, "Unexpected error when removing file: %+v", err)
|
||||
err = store.Remove("test/123.jpg")
|
||||
require.True(t, err != nil, "Expected error when removing missing file")
|
||||
err = store.Remove("test123/123.jpg")
|
||||
require.True(t, err != nil, "Expected error when deleting file outside of namespace")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoreCheckFunc(t *testing.T) {
|
||||
// Should not cause panic
|
||||
require.True(t, (&store{}).check("") != nil, "Expecting an error to be returned on empty filename check")
|
||||
}
|
||||
Reference in New Issue
Block a user