mirror of
https://github.com/chrislusf/seaweedfs
synced 2024-07-06 09:07:08 +02:00
add mime, use simple insert and update filer store API
1. add mime type to file in filer 2. purge old chunks if overwrite during insert
This commit is contained in:
parent
26e7cd8c75
commit
0301504184
|
@ -174,7 +174,7 @@ func uploadFileAsOne(filerUrl string, urlFolder string, f *os.File, fi os.FileIn
|
||||||
fmt.Printf("uploaded %s to %s\n", f.Name(), targetUrl)
|
fmt.Printf("uploaded %s to %s\n", f.Name(), targetUrl)
|
||||||
|
|
||||||
if err = filer_operation.RegisterFile(filerUrl, filepath.Join(urlFolder, f.Name()), assignResult.Fid, fi.Size(),
|
if err = filer_operation.RegisterFile(filerUrl, filepath.Join(urlFolder, f.Name()), assignResult.Fid, fi.Size(),
|
||||||
os.Getuid(), os.Getgid(), copy.secret); err != nil {
|
mimeType, os.Getuid(), os.Getgid(), copy.secret); err != nil {
|
||||||
fmt.Printf("Failed to register file %s on %s: %v\n", f.Name(), filerUrl, err)
|
fmt.Printf("Failed to register file %s on %s: %v\n", f.Name(), filerUrl, err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -185,6 +185,8 @@ func uploadFileAsOne(filerUrl string, urlFolder string, f *os.File, fi os.FileIn
|
||||||
|
|
||||||
func uploadFileInChunks(filerUrl string, urlFolder string, f *os.File, fi os.FileInfo, chunkCount int, chunkSize int64) bool {
|
func uploadFileInChunks(filerUrl string, urlFolder string, f *os.File, fi os.FileInfo, chunkCount int, chunkSize int64) bool {
|
||||||
|
|
||||||
|
mimeType := detectMimeType(f)
|
||||||
|
|
||||||
var chunks []*filer_pb.FileChunk
|
var chunks []*filer_pb.FileChunk
|
||||||
|
|
||||||
for i := int64(0); i < int64(chunkCount); i++ {
|
for i := int64(0); i < int64(chunkCount); i++ {
|
||||||
|
@ -235,6 +237,7 @@ func uploadFileInChunks(filerUrl string, urlFolder string, f *os.File, fi os.Fil
|
||||||
Uid: uint32(os.Getuid()),
|
Uid: uint32(os.Getuid()),
|
||||||
FileSize: uint64(fi.Size()),
|
FileSize: uint64(fi.Size()),
|
||||||
FileMode: uint32(fi.Mode()),
|
FileMode: uint32(fi.Mode()),
|
||||||
|
Mime: mimeType,
|
||||||
},
|
},
|
||||||
Chunks: chunks,
|
Chunks: chunks,
|
||||||
},
|
},
|
||||||
|
|
|
@ -77,26 +77,21 @@ func (store *AbstractSqlStore) FindEntry(fullpath filer2.FullPath) (*filer2.Entr
|
||||||
return entry, nil
|
return entry, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (store *AbstractSqlStore) DeleteEntry(fullpath filer2.FullPath) (*filer2.Entry, error) {
|
func (store *AbstractSqlStore) DeleteEntry(fullpath filer2.FullPath) (error) {
|
||||||
|
|
||||||
entry, err := store.FindEntry(fullpath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
dir, name := fullpath.DirAndName()
|
dir, name := fullpath.DirAndName()
|
||||||
|
|
||||||
res, err := store.DB.Exec(store.SqlDelete, hashToLong(dir), name, dir)
|
res, err := store.DB.Exec(store.SqlDelete, hashToLong(dir), name, dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("delete %s: %s", fullpath, err)
|
return fmt.Errorf("delete %s: %s", fullpath, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = res.RowsAffected()
|
_, err = res.RowsAffected()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("delete %s but no rows affected: %s", fullpath, err)
|
return fmt.Errorf("delete %s but no rows affected: %s", fullpath, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return entry, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (store *AbstractSqlStore) ListDirectoryEntries(fullpath filer2.FullPath, startFileName string, inclusive bool, limit int) (entries []*filer2.Entry, err error) {
|
func (store *AbstractSqlStore) ListDirectoryEntries(fullpath filer2.FullPath, startFileName string, inclusive bool, limit int) (entries []*filer2.Entry, err error) {
|
||||||
|
|
|
@ -88,22 +88,17 @@ func (store *CassandraStore) FindEntry(fullpath filer2.FullPath) (entry *filer2.
|
||||||
return entry, nil
|
return entry, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (store *CassandraStore) DeleteEntry(fullpath filer2.FullPath) (entry *filer2.Entry, err error) {
|
func (store *CassandraStore) DeleteEntry(fullpath filer2.FullPath) error {
|
||||||
|
|
||||||
entry, err = store.FindEntry(fullpath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
dir, name := fullpath.DirAndName()
|
dir, name := fullpath.DirAndName()
|
||||||
|
|
||||||
if err := store.session.Query(
|
if err := store.session.Query(
|
||||||
"DELETE FROM filemeta WHERE directory=? AND name=?",
|
"DELETE FROM filemeta WHERE directory=? AND name=?",
|
||||||
dir, name).Exec(); err != nil {
|
dir, name).Exec(); err != nil {
|
||||||
return entry, fmt.Errorf("delete %s : %v", entry.FullPath, err)
|
return fmt.Errorf("delete %s : %v", fullpath, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return entry, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (store *CassandraStore) ListDirectoryEntries(fullpath filer2.FullPath, startFileName string, inclusive bool,
|
func (store *CassandraStore) ListDirectoryEntries(fullpath filer2.FullPath, startFileName string, inclusive bool,
|
||||||
|
|
|
@ -13,6 +13,7 @@ type Attr struct {
|
||||||
Mode os.FileMode // file mode
|
Mode os.FileMode // file mode
|
||||||
Uid uint32 // owner uid
|
Uid uint32 // owner uid
|
||||||
Gid uint32 // group gid
|
Gid uint32 // group gid
|
||||||
|
Mime string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (attr Attr) IsDirectory() bool {
|
func (attr Attr) IsDirectory() bool {
|
||||||
|
|
|
@ -17,6 +17,7 @@ func (entry *Entry) EncodeAttributesAndChunks() ([]byte, error) {
|
||||||
FileMode: uint32(entry.Attr.Mode),
|
FileMode: uint32(entry.Attr.Mode),
|
||||||
Uid: entry.Uid,
|
Uid: entry.Uid,
|
||||||
Gid: entry.Gid,
|
Gid: entry.Gid,
|
||||||
|
Mime: entry.Mime,
|
||||||
},
|
},
|
||||||
Chunks: entry.Chunks,
|
Chunks: entry.Chunks,
|
||||||
}
|
}
|
||||||
|
@ -36,6 +37,7 @@ func (entry *Entry) DecodeAttributesAndChunks(blob []byte) error {
|
||||||
entry.Attr.Mode = os.FileMode(message.Attributes.FileMode)
|
entry.Attr.Mode = os.FileMode(message.Attributes.FileMode)
|
||||||
entry.Attr.Uid = message.Attributes.Uid
|
entry.Attr.Uid = message.Attributes.Uid
|
||||||
entry.Attr.Gid = message.Attributes.Gid
|
entry.Attr.Gid = message.Attributes.Gid
|
||||||
|
entry.Attr.Mime = message.Attributes.Mime
|
||||||
|
|
||||||
entry.Chunks = message.Chunks
|
entry.Chunks = message.Chunks
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
"github.com/chrislusf/seaweedfs/weed/operation"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Filer struct {
|
type Filer struct {
|
||||||
|
@ -101,6 +102,10 @@ func (f *Filer) CreateEntry(entry *Entry) error {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if oldEntry, err := f.FindEntry(entry.FullPath); err == nil {
|
||||||
|
f.deleteChunks(oldEntry)
|
||||||
|
}
|
||||||
|
|
||||||
if err := f.store.InsertEntry(entry); err != nil {
|
if err := f.store.InsertEntry(entry); err != nil {
|
||||||
return fmt.Errorf("insert entry %s: %v", entry.FullPath, err)
|
return fmt.Errorf("insert entry %s: %v", entry.FullPath, err)
|
||||||
}
|
}
|
||||||
|
@ -116,26 +121,30 @@ func (f *Filer) FindEntry(p FullPath) (entry *Entry, err error) {
|
||||||
return f.store.FindEntry(p)
|
return f.store.FindEntry(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Filer) DeleteEntry(p FullPath) (fileEntry *Entry, err error) {
|
func (f *Filer) DeleteEntryMetaAndData(p FullPath) (err error) {
|
||||||
entry, err := f.FindEntry(p)
|
entry, err := f.FindEntry(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if entry.IsDirectory() {
|
if entry.IsDirectory() {
|
||||||
entries, err := f.ListDirectoryEntries(p, "", false, 1)
|
entries, err := f.ListDirectoryEntries(p, "", false, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("list folder %s: %v", p, err)
|
return fmt.Errorf("list folder %s: %v", p, err)
|
||||||
}
|
}
|
||||||
if len(entries) > 0 {
|
if len(entries) > 0 {
|
||||||
return nil, fmt.Errorf("folder %s is not empty", p)
|
return fmt.Errorf("folder %s is not empty", p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
f.deleteChunks(entry)
|
||||||
|
|
||||||
return f.store.DeleteEntry(p)
|
return f.store.DeleteEntry(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Filer) ListDirectoryEntries(p FullPath, startFileName string, inclusive bool, limit int) ([]*Entry, error) {
|
func (f *Filer) ListDirectoryEntries(p FullPath, startFileName string, inclusive bool, limit int) ([]*Entry, error) {
|
||||||
if strings.HasSuffix(string(p), "/") && len(p) > 1 {
|
if strings.HasSuffix(string(p), "/") && len(p) > 1 {
|
||||||
p = p[0 : len(p)-1]
|
p = p[0: len(p)-1]
|
||||||
}
|
}
|
||||||
return f.store.ListDirectoryEntries(p, startFileName, inclusive, limit)
|
return f.store.ListDirectoryEntries(p, startFileName, inclusive, limit)
|
||||||
}
|
}
|
||||||
|
@ -164,3 +173,17 @@ func (f *Filer) cacheSetDirectory(dirpath string, dirEntry *Entry, level int) {
|
||||||
|
|
||||||
f.directoryCache.Set(dirpath, dirEntry, time.Duration(minutes)*time.Minute)
|
f.directoryCache.Set(dirpath, dirEntry, time.Duration(minutes)*time.Minute)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *Filer) deleteChunks(entry *Entry) {
|
||||||
|
if f.master == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if entry == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, chunk := range entry.Chunks {
|
||||||
|
if err := operation.DeleteFile(f.master, chunk.FileId, ""); err != nil {
|
||||||
|
glog.V(0).Infof("deleting file %s: %v", chunk.FileId, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ type FilerStore interface {
|
||||||
InsertEntry(*Entry) error
|
InsertEntry(*Entry) error
|
||||||
UpdateEntry(*Entry) (err error)
|
UpdateEntry(*Entry) (err error)
|
||||||
FindEntry(FullPath) (entry *Entry, err error)
|
FindEntry(FullPath) (entry *Entry, err error)
|
||||||
DeleteEntry(FullPath) (fileEntry *Entry, err error)
|
DeleteEntry(FullPath) (err error)
|
||||||
ListDirectoryEntries(dirPath FullPath, startFileName string, inclusive bool, limit int) ([]*Entry, error)
|
ListDirectoryEntries(dirPath FullPath, startFileName string, inclusive bool, limit int) ([]*Entry, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,20 +93,15 @@ func (store *LevelDBStore) FindEntry(fullpath filer2.FullPath) (entry *filer2.En
|
||||||
return entry, nil
|
return entry, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (store *LevelDBStore) DeleteEntry(fullpath filer2.FullPath) (entry *filer2.Entry, err error) {
|
func (store *LevelDBStore) DeleteEntry(fullpath filer2.FullPath) (err error) {
|
||||||
key := genKey(fullpath.DirAndName())
|
key := genKey(fullpath.DirAndName())
|
||||||
|
|
||||||
entry, err = store.FindEntry(fullpath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
err = store.db.Delete(key, nil)
|
err = store.db.Delete(key, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return entry, fmt.Errorf("delete %s : %v", entry.FullPath, err)
|
return fmt.Errorf("delete %s : %v", fullpath, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return entry, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (store *LevelDBStore) ListDirectoryEntries(fullpath filer2.FullPath, startFileName string, inclusive bool,
|
func (store *LevelDBStore) ListDirectoryEntries(fullpath filer2.FullPath, startFileName string, inclusive bool,
|
||||||
|
|
|
@ -56,13 +56,9 @@ func (store *MemDbStore) FindEntry(fullpath filer2.FullPath) (entry *filer2.Entr
|
||||||
return entry, nil
|
return entry, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (store *MemDbStore) DeleteEntry(fullpath filer2.FullPath) (entry *filer2.Entry, err error) {
|
func (store *MemDbStore) DeleteEntry(fullpath filer2.FullPath) (err error) {
|
||||||
item := store.tree.Delete(entryItem{&filer2.Entry{FullPath: fullpath}})
|
store.tree.Delete(entryItem{&filer2.Entry{FullPath: fullpath}})
|
||||||
if item == nil {
|
return nil
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
entry = item.(entryItem).Entry
|
|
||||||
return entry, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (store *MemDbStore) ListDirectoryEntries(fullpath filer2.FullPath, startFileName string, inclusive bool, limit int) (entries []*filer2.Entry, err error) {
|
func (store *MemDbStore) ListDirectoryEntries(fullpath filer2.FullPath, startFileName string, inclusive bool, limit int) (entries []*filer2.Entry, err error) {
|
||||||
|
|
|
@ -134,7 +134,7 @@ func TestCreateFileAndList(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete file and count
|
// delete file and count
|
||||||
filer.DeleteEntry(file3Path)
|
filer.DeleteEntryMetaAndData(file3Path)
|
||||||
entries, _ = filer.ListDirectoryEntries(filer2.FullPath("/home/chris/this/is"), "", false, 100)
|
entries, _ = filer.ListDirectoryEntries(filer2.FullPath("/home/chris/this/is"), "", false, 100)
|
||||||
if len(entries) != 1 {
|
if len(entries) != 1 {
|
||||||
t.Errorf("list entries count: %v", len(entries))
|
t.Errorf("list entries count: %v", len(entries))
|
||||||
|
|
|
@ -94,28 +94,23 @@ func (store *RedisStore) FindEntry(fullpath filer2.FullPath) (entry *filer2.Entr
|
||||||
return entry, nil
|
return entry, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (store *RedisStore) DeleteEntry(fullpath filer2.FullPath) (entry *filer2.Entry, err error) {
|
func (store *RedisStore) DeleteEntry(fullpath filer2.FullPath) (err error) {
|
||||||
|
|
||||||
entry, err = store.FindEntry(fullpath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = store.Client.Del(string(fullpath)).Result()
|
_, err = store.Client.Del(string(fullpath)).Result()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return entry, fmt.Errorf("delete %s : %v", entry.FullPath, err)
|
return fmt.Errorf("delete %s : %v", fullpath, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
dir, name := fullpath.DirAndName()
|
dir, name := fullpath.DirAndName()
|
||||||
if name != "" {
|
if name != "" {
|
||||||
_, err = store.Client.SRem(genDirectoryListKey(dir), name).Result()
|
_, err = store.Client.SRem(genDirectoryListKey(dir), name).Result()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("delete %s in parent dir: %v", entry.FullPath, err)
|
return fmt.Errorf("delete %s in parent dir: %v", fullpath, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return entry, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (store *RedisStore) ListDirectoryEntries(fullpath filer2.FullPath, startFileName string, inclusive bool,
|
func (store *RedisStore) ListDirectoryEntries(fullpath filer2.FullPath, startFileName string, inclusive bool,
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"github.com/chrislusf/seaweedfs/weed/util"
|
"github.com/chrislusf/seaweedfs/weed/util"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FileHandle struct {
|
type FileHandle struct {
|
||||||
|
@ -18,10 +19,6 @@ type FileHandle struct {
|
||||||
dirtyPages *ContinuousDirtyPages
|
dirtyPages *ContinuousDirtyPages
|
||||||
dirtyMetadata bool
|
dirtyMetadata bool
|
||||||
|
|
||||||
cachePath string
|
|
||||||
|
|
||||||
handle uint64
|
|
||||||
|
|
||||||
f *File
|
f *File
|
||||||
RequestId fuse.RequestID // unique ID for request
|
RequestId fuse.RequestID // unique ID for request
|
||||||
NodeId fuse.NodeID // file or directory the request is about
|
NodeId fuse.NodeID // file or directory the request is about
|
||||||
|
@ -135,6 +132,11 @@ func (fh *FileHandle) Write(ctx context.Context, req *fuse.WriteRequest, resp *f
|
||||||
|
|
||||||
resp.Size = len(req.Data)
|
resp.Size = len(req.Data)
|
||||||
|
|
||||||
|
if req.Offset == 0 {
|
||||||
|
fh.f.attributes.Mime = http.DetectContentType(req.Data)
|
||||||
|
fh.dirtyMetadata = true
|
||||||
|
}
|
||||||
|
|
||||||
if chunk != nil {
|
if chunk != nil {
|
||||||
fh.f.Chunks = append(fh.f.Chunks, chunk)
|
fh.f.Chunks = append(fh.f.Chunks, chunk)
|
||||||
glog.V(1).Infof("uploaded %s/%s to %s [%d,%d)", fh.f.dir.Path, fh.f.Name, chunk.FileId, chunk.Offset, chunk.Offset+int64(chunk.Size))
|
glog.V(1).Infof("uploaded %s/%s to %s [%d,%d)", fh.f.dir.Path, fh.f.Name, chunk.FileId, chunk.Offset, chunk.Offset+int64(chunk.Size))
|
||||||
|
|
|
@ -17,7 +17,7 @@ type SubmitResult struct {
|
||||||
Error string `json:"error,omitempty"`
|
Error string `json:"error,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func RegisterFile(filer string, path string, fileId string, fileSize int64, uid, gid int, secret security.Secret) error {
|
func RegisterFile(filer string, path string, fileId string, fileSize int64, mime string, uid, gid int, secret security.Secret) error {
|
||||||
// TODO: jwt need to be used
|
// TODO: jwt need to be used
|
||||||
_ = security.GenJwt(secret, fileId)
|
_ = security.GenJwt(secret, fileId)
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ func RegisterFile(filer string, path string, fileId string, fileSize int64, uid,
|
||||||
values.Add("fileSize", strconv.FormatInt(fileSize, 10))
|
values.Add("fileSize", strconv.FormatInt(fileSize, 10))
|
||||||
values.Add("uid", strconv.Itoa(uid))
|
values.Add("uid", strconv.Itoa(uid))
|
||||||
values.Add("gid", strconv.Itoa(gid))
|
values.Add("gid", strconv.Itoa(gid))
|
||||||
|
values.Add("mime", mime)
|
||||||
_, err := util.Post("http://"+filer+"/admin/register", values)
|
_, err := util.Post("http://"+filer+"/admin/register", values)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to register path %s on filer %s to file id %s : %v", path, filer, fileId, err)
|
return fmt.Errorf("Failed to register path %s on filer %s to file id %s : %v", path, filer, fileId, err)
|
||||||
|
|
|
@ -72,6 +72,7 @@ message FuseAttributes {
|
||||||
uint32 uid = 4;
|
uint32 uid = 4;
|
||||||
uint32 gid = 5;
|
uint32 gid = 5;
|
||||||
int64 crtime = 6;
|
int64 crtime = 6;
|
||||||
|
string mime = 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetEntryAttributesRequest {
|
message GetEntryAttributesRequest {
|
||||||
|
|
|
@ -214,6 +214,7 @@ type FuseAttributes struct {
|
||||||
Uid uint32 `protobuf:"varint,4,opt,name=uid" json:"uid,omitempty"`
|
Uid uint32 `protobuf:"varint,4,opt,name=uid" json:"uid,omitempty"`
|
||||||
Gid uint32 `protobuf:"varint,5,opt,name=gid" json:"gid,omitempty"`
|
Gid uint32 `protobuf:"varint,5,opt,name=gid" json:"gid,omitempty"`
|
||||||
Crtime int64 `protobuf:"varint,6,opt,name=crtime" json:"crtime,omitempty"`
|
Crtime int64 `protobuf:"varint,6,opt,name=crtime" json:"crtime,omitempty"`
|
||||||
|
Mime string `protobuf:"bytes,7,opt,name=mime" json:"mime,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *FuseAttributes) Reset() { *m = FuseAttributes{} }
|
func (m *FuseAttributes) Reset() { *m = FuseAttributes{} }
|
||||||
|
@ -263,6 +264,13 @@ func (m *FuseAttributes) GetCrtime() int64 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *FuseAttributes) GetMime() string {
|
||||||
|
if m != nil {
|
||||||
|
return m.Mime
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
type GetEntryAttributesRequest struct {
|
type GetEntryAttributesRequest struct {
|
||||||
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
|
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
|
||||||
ParentDir string `protobuf:"bytes,2,opt,name=parent_dir,json=parentDir" json:"parent_dir,omitempty"`
|
ParentDir string `protobuf:"bytes,2,opt,name=parent_dir,json=parentDir" json:"parent_dir,omitempty"`
|
||||||
|
@ -931,62 +939,62 @@ var _SeaweedFiler_serviceDesc = grpc.ServiceDesc{
|
||||||
func init() { proto.RegisterFile("filer.proto", fileDescriptor0) }
|
func init() { proto.RegisterFile("filer.proto", fileDescriptor0) }
|
||||||
|
|
||||||
var fileDescriptor0 = []byte{
|
var fileDescriptor0 = []byte{
|
||||||
// 899 bytes of a gzipped FileDescriptorProto
|
// 906 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x56, 0xdd, 0x6e, 0xdc, 0x44,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x56, 0x5b, 0x6f, 0xdc, 0x44,
|
||||||
0x14, 0x8e, 0xd7, 0xf1, 0x26, 0x3e, 0xbb, 0xe1, 0x67, 0x36, 0x2d, 0x66, 0x9b, 0x54, 0x61, 0xa0,
|
0x14, 0x8e, 0xd7, 0xd9, 0x4d, 0x7c, 0x76, 0xc3, 0x65, 0x36, 0x2d, 0x66, 0x9b, 0x54, 0x61, 0xa0,
|
||||||
0xa8, 0x15, 0x52, 0x14, 0x05, 0x2e, 0x2a, 0x10, 0x12, 0x55, 0x53, 0xaa, 0x4a, 0xa9, 0x2a, 0xb9,
|
0xa8, 0x15, 0x52, 0x14, 0x05, 0x1e, 0x2a, 0x10, 0x12, 0x55, 0x53, 0xaa, 0x4a, 0xa9, 0x2a, 0xb9,
|
||||||
0x04, 0x89, 0xab, 0x95, 0x63, 0x9f, 0x5d, 0x46, 0xf1, 0xda, 0xc6, 0x33, 0x0e, 0x0a, 0xb7, 0xbc,
|
0x04, 0x89, 0xa7, 0x95, 0x63, 0x9f, 0x5d, 0x46, 0xf1, 0x0d, 0xcf, 0x38, 0x28, 0xbc, 0xf2, 0x5b,
|
||||||
0x06, 0xb7, 0xbc, 0x01, 0x6f, 0xc0, 0x8b, 0xa1, 0xf9, 0xb1, 0x3d, 0x8e, 0xbd, 0xfd, 0xb9, 0xe0,
|
0x78, 0xe7, 0x81, 0x7f, 0xc0, 0x1f, 0x43, 0x73, 0xb1, 0x3d, 0x8e, 0xbd, 0xbd, 0x3c, 0xf0, 0x36,
|
||||||
0x6e, 0xe6, 0xfc, 0x7c, 0xe7, 0x3b, 0x33, 0x67, 0x3e, 0x1b, 0x26, 0x4b, 0x96, 0x62, 0x79, 0x5c,
|
0x73, 0x2e, 0xdf, 0xf9, 0xce, 0xcc, 0x99, 0xcf, 0x86, 0xe9, 0x8a, 0x25, 0x58, 0x1e, 0x17, 0x65,
|
||||||
0x94, 0xb9, 0xc8, 0xc9, 0xae, 0xda, 0x2c, 0x8a, 0x4b, 0xfa, 0x0a, 0xee, 0x9d, 0xe7, 0xf9, 0x55,
|
0x2e, 0x72, 0xb2, 0xab, 0x36, 0xcb, 0xe2, 0x92, 0xbe, 0x82, 0x7b, 0xe7, 0x79, 0x7e, 0x55, 0x15,
|
||||||
0x55, 0x9c, 0xb1, 0x12, 0x63, 0x91, 0x97, 0x37, 0xcf, 0x32, 0x51, 0xde, 0x84, 0xf8, 0x5b, 0x85,
|
0x67, 0xac, 0xc4, 0x48, 0xe4, 0xe5, 0xcd, 0xb3, 0x4c, 0x94, 0x37, 0x01, 0xfe, 0x56, 0x21, 0x17,
|
||||||
0x5c, 0x90, 0x03, 0xf0, 0x93, 0xda, 0x11, 0x38, 0x47, 0xce, 0x43, 0x3f, 0x6c, 0x0d, 0x84, 0xc0,
|
0xe4, 0x00, 0xbc, 0xb8, 0x76, 0xf8, 0xce, 0x91, 0xf3, 0xd0, 0x0b, 0x5a, 0x03, 0x21, 0xb0, 0x9d,
|
||||||
0x76, 0x16, 0xad, 0x31, 0x18, 0x29, 0x87, 0x5a, 0xd3, 0x67, 0x70, 0x30, 0x0c, 0xc8, 0x8b, 0x3c,
|
0x85, 0x29, 0xfa, 0x23, 0xe5, 0x50, 0x6b, 0xfa, 0x0c, 0x0e, 0x86, 0x01, 0x79, 0x91, 0x67, 0x1c,
|
||||||
0xe3, 0x48, 0x1e, 0x80, 0x87, 0xd2, 0xa0, 0xd0, 0x26, 0xa7, 0x1f, 0x1e, 0xd7, 0x54, 0x8e, 0x75,
|
0xc9, 0x03, 0x18, 0xa3, 0x34, 0x28, 0xb4, 0xe9, 0xe9, 0x87, 0xc7, 0x35, 0x95, 0x63, 0x1d, 0xa7,
|
||||||
0x9c, 0xf6, 0xd2, 0x53, 0x20, 0xe7, 0x8c, 0x0b, 0x69, 0x63, 0xc8, 0xdf, 0x89, 0x0e, 0xfd, 0x01,
|
0xbd, 0xf4, 0x14, 0xc8, 0x39, 0xe3, 0x42, 0xda, 0x18, 0xf2, 0x77, 0xa2, 0x43, 0x7f, 0x80, 0x79,
|
||||||
0x66, 0x9d, 0x1c, 0x53, 0xf1, 0x11, 0xec, 0xa0, 0x36, 0x05, 0xce, 0x91, 0x3b, 0x54, 0xb3, 0xf6,
|
0x27, 0xc7, 0x54, 0x7c, 0x04, 0x3b, 0xa8, 0x4d, 0xbe, 0x73, 0xe4, 0x0e, 0xd5, 0xac, 0xfd, 0xf4,
|
||||||
0xd3, 0xbf, 0x1d, 0xf0, 0x94, 0xa9, 0x69, 0xcd, 0x69, 0x5b, 0x23, 0x9f, 0xc1, 0x94, 0xf1, 0x45,
|
0x2f, 0x07, 0xc6, 0xca, 0xd4, 0xb4, 0xe6, 0xb4, 0xad, 0x91, 0xcf, 0x60, 0xc6, 0xf8, 0xb2, 0x25,
|
||||||
0x4b, 0x40, 0xb6, 0xbd, 0x1b, 0x4e, 0x18, 0x6f, 0x5a, 0x25, 0x5f, 0xc1, 0x38, 0xfe, 0xb5, 0xca,
|
0x20, 0xdb, 0xde, 0x0d, 0xa6, 0x8c, 0x37, 0xad, 0x92, 0xaf, 0x60, 0x12, 0xfd, 0x5a, 0x65, 0x57,
|
||||||
0xae, 0x78, 0xe0, 0xaa, 0x52, 0xb3, 0xb6, 0xd4, 0x8f, 0x2c, 0xc5, 0xa7, 0xd2, 0x17, 0x9a, 0x10,
|
0xdc, 0x77, 0x55, 0xa9, 0x79, 0x5b, 0xea, 0x47, 0x96, 0xe0, 0x53, 0xe9, 0x0b, 0x4c, 0x08, 0x79,
|
||||||
0xf2, 0x18, 0x20, 0x12, 0xa2, 0x64, 0x97, 0x95, 0x40, 0x1e, 0x6c, 0xab, 0xf3, 0x08, 0xac, 0x84,
|
0x0c, 0x10, 0x0a, 0x51, 0xb2, 0xcb, 0x4a, 0x20, 0xf7, 0xb7, 0xd5, 0x79, 0xf8, 0x56, 0x42, 0xc5,
|
||||||
0x8a, 0xe3, 0x93, 0xc6, 0x1f, 0x5a, 0xb1, 0x74, 0x09, 0x7e, 0x03, 0x47, 0x3e, 0x81, 0x1d, 0x99,
|
0xf1, 0x49, 0xe3, 0x0f, 0xac, 0x58, 0xba, 0x02, 0xaf, 0x81, 0x23, 0x9f, 0xc0, 0x8e, 0xcc, 0x59,
|
||||||
0xb3, 0x60, 0x89, 0x61, 0x3b, 0x96, 0xdb, 0x17, 0x09, 0xb9, 0x0b, 0xe3, 0x7c, 0xb9, 0xe4, 0x28,
|
0xb2, 0xd8, 0xb0, 0x9d, 0xc8, 0xed, 0x8b, 0x98, 0xdc, 0x85, 0x49, 0xbe, 0x5a, 0x71, 0x14, 0x8a,
|
||||||
0x14, 0x53, 0x37, 0x34, 0x3b, 0xd9, 0x1b, 0x67, 0x7f, 0x60, 0xe0, 0x1e, 0x39, 0x0f, 0xb7, 0x43,
|
0xa9, 0x1b, 0x98, 0x9d, 0xec, 0x8d, 0xb3, 0x3f, 0xd0, 0x77, 0x8f, 0x9c, 0x87, 0xdb, 0x81, 0x5a,
|
||||||
0xb5, 0x26, 0xfb, 0xe0, 0xad, 0x05, 0x5b, 0xa3, 0xa2, 0xe1, 0x86, 0x7a, 0x43, 0xff, 0x72, 0xe0,
|
0x93, 0x7d, 0x18, 0xa7, 0x82, 0xa5, 0xa8, 0x68, 0xb8, 0x81, 0xde, 0xd0, 0xbf, 0x1d, 0xf8, 0xa0,
|
||||||
0x83, 0x2e, 0x0d, 0x72, 0x0f, 0x7c, 0x55, 0x4d, 0x21, 0x38, 0x0a, 0x41, 0x4d, 0xd3, 0xeb, 0x0e,
|
0x4b, 0x83, 0xdc, 0x03, 0x4f, 0x55, 0x53, 0x08, 0x8e, 0x42, 0x50, 0xd3, 0xf4, 0xba, 0x83, 0x32,
|
||||||
0xca, 0xc8, 0x42, 0x69, 0x52, 0xd6, 0x79, 0xa2, 0x8b, 0xee, 0xe9, 0x94, 0x97, 0x79, 0x82, 0xe4,
|
0xb2, 0x50, 0x9a, 0x94, 0x34, 0x8f, 0x75, 0xd1, 0x3d, 0x9d, 0xf2, 0x32, 0x8f, 0x91, 0x7c, 0x04,
|
||||||
0x23, 0x70, 0x2b, 0x96, 0xa8, 0xb2, 0x7b, 0xa1, 0x5c, 0x4a, 0xcb, 0x8a, 0x25, 0x81, 0xa7, 0x2d,
|
0x6e, 0xc5, 0x62, 0x55, 0x76, 0x2f, 0x90, 0x4b, 0x69, 0x59, 0xb3, 0xd8, 0x1f, 0x6b, 0xcb, 0x9a,
|
||||||
0x2b, 0xa6, 0x1a, 0x89, 0x4b, 0x85, 0x3b, 0xd6, 0x8d, 0xe8, 0x1d, 0x5d, 0xc1, 0xa7, 0xcf, 0x51,
|
0xa9, 0x46, 0xa2, 0x52, 0xe1, 0x4e, 0x74, 0x23, 0x7a, 0x27, 0x1b, 0x49, 0xa5, 0x75, 0x47, 0x5f,
|
||||||
0xdd, 0xf7, 0x8d, 0x75, 0x50, 0x66, 0x56, 0x86, 0x6e, 0xf0, 0x10, 0xa0, 0x88, 0x4a, 0xcc, 0x84,
|
0x92, 0x5c, 0xd3, 0x35, 0x7c, 0xfa, 0x1c, 0xd5, 0x0c, 0xdc, 0x58, 0x87, 0x67, 0xe6, 0x67, 0xe8,
|
||||||
0xbc, 0x45, 0x33, 0xb6, 0xbe, 0xb6, 0x9c, 0xb1, 0xd2, 0x3e, 0x49, 0xd7, 0x3e, 0x49, 0xfa, 0xa7,
|
0x56, 0x0f, 0x01, 0x8a, 0xb0, 0xc4, 0x4c, 0xc8, 0x9b, 0x35, 0xa3, 0xec, 0x69, 0xcb, 0x19, 0x2b,
|
||||||
0x03, 0xf3, 0xa1, 0x4a, 0x66, 0xc2, 0xba, 0x17, 0xe9, 0xbc, 0xfb, 0x45, 0x5a, 0xf3, 0x32, 0x7a,
|
0xed, 0xd3, 0x75, 0xed, 0xd3, 0xa5, 0x7f, 0x3a, 0xb0, 0x18, 0xaa, 0x64, 0xa6, 0xae, 0x7b, 0xb9,
|
||||||
0xeb, 0xbc, 0xd0, 0x13, 0xb8, 0xf3, 0x1c, 0x85, 0xb2, 0xe7, 0x99, 0xc0, 0x4c, 0xd4, 0xad, 0x6e,
|
0xce, 0xbb, 0x5f, 0xae, 0x35, 0x43, 0xa3, 0xb7, 0xce, 0x10, 0x3d, 0x81, 0x3b, 0xcf, 0x51, 0x28,
|
||||||
0x9a, 0x00, 0x7a, 0x0a, 0x77, 0x6f, 0x67, 0x18, 0xca, 0x01, 0xec, 0xc4, 0xda, 0xa4, 0x52, 0xa6,
|
0x7b, 0x9e, 0x09, 0xcc, 0x44, 0xdd, 0xea, 0xa6, 0xa9, 0xa0, 0xa7, 0x70, 0xf7, 0x76, 0x86, 0xa1,
|
||||||
0x61, 0xbd, 0xa5, 0xbf, 0x00, 0x79, 0x5a, 0x62, 0x24, 0xf0, 0x3d, 0x84, 0xa0, 0x79, 0xd4, 0xa3,
|
0xec, 0xc3, 0x4e, 0xa4, 0x4d, 0x2a, 0x65, 0x16, 0xd4, 0x5b, 0xfa, 0x0b, 0x90, 0xa7, 0x25, 0x86,
|
||||||
0x37, 0x3e, 0xea, 0x3b, 0x30, 0xeb, 0x40, 0x6b, 0x2e, 0xb2, 0xe2, 0x45, 0x91, 0xfc, 0x5f, 0x15,
|
0x02, 0xdf, 0x43, 0x1c, 0x9a, 0x87, 0x3e, 0x7a, 0xe3, 0x43, 0xbf, 0x03, 0xf3, 0x0e, 0xb4, 0xe6,
|
||||||
0x3b, 0xd0, 0xa6, 0x22, 0x03, 0x72, 0x86, 0x29, 0xbe, 0x57, 0xc5, 0x01, 0xb1, 0xeb, 0x29, 0x82,
|
0x22, 0x2b, 0x5e, 0x14, 0xf1, 0xff, 0x55, 0xb1, 0x03, 0x6d, 0x2a, 0x32, 0x20, 0x67, 0x98, 0xe0,
|
||||||
0xdb, 0x53, 0x04, 0xc9, 0xa0, 0x53, 0xca, 0x30, 0x58, 0xc3, 0xec, 0x09, 0xe7, 0x6c, 0x95, 0xfd,
|
0x7b, 0x55, 0x1c, 0x10, 0xc0, 0x9e, 0x4a, 0xb8, 0x3d, 0x95, 0x90, 0x0c, 0x3a, 0xa5, 0x0c, 0x83,
|
||||||
0x9c, 0xa7, 0xd5, 0x1a, 0x6b, 0x0a, 0xfb, 0xe0, 0xc5, 0x79, 0x65, 0x2e, 0xc5, 0x0b, 0xf5, 0x86,
|
0x14, 0xe6, 0x4f, 0x38, 0x67, 0xeb, 0xec, 0xe7, 0x3c, 0xa9, 0x52, 0xac, 0x29, 0xec, 0xc3, 0x38,
|
||||||
0xdc, 0x07, 0x88, 0xf3, 0x34, 0xc5, 0x58, 0xb0, 0x3c, 0x33, 0x04, 0x2c, 0x0b, 0x39, 0x82, 0x49,
|
0xca, 0x2b, 0x73, 0x29, 0xe3, 0x40, 0x6f, 0xc8, 0x7d, 0x80, 0x28, 0x4f, 0x12, 0x8c, 0x04, 0xcb,
|
||||||
0x89, 0x45, 0xca, 0xe2, 0x48, 0x05, 0xe8, 0xd9, 0xb5, 0x4d, 0xf4, 0x1a, 0xf6, 0xbb, 0xe5, 0xcc,
|
0x33, 0x43, 0xc0, 0xb2, 0x90, 0x23, 0x98, 0x96, 0x58, 0x24, 0x2c, 0x0a, 0x55, 0x80, 0x9e, 0x5d,
|
||||||
0x18, 0x6c, 0xd4, 0x0e, 0xf9, 0x2c, 0xcb, 0xd4, 0xd4, 0x92, 0x4b, 0xf5, 0x76, 0xaa, 0xcb, 0x94,
|
0xdb, 0x44, 0xaf, 0x61, 0xbf, 0x5b, 0xce, 0x8c, 0xc1, 0x46, 0x3d, 0x91, 0x4f, 0xb5, 0x4c, 0x4c,
|
||||||
0xc5, 0x0b, 0xe9, 0x70, 0xcd, 0xdb, 0x51, 0x96, 0x8b, 0x32, 0x6d, 0x99, 0x6f, 0x5b, 0xcc, 0xe9,
|
0x2d, 0xb9, 0x54, 0x6f, 0xa7, 0xba, 0x4c, 0x58, 0xb4, 0x94, 0x0e, 0xd7, 0xbc, 0x1d, 0x65, 0xb9,
|
||||||
0x37, 0x30, 0xd3, 0x5f, 0x83, 0x6e, 0x9b, 0x87, 0x00, 0xd7, 0xca, 0xb0, 0x60, 0x89, 0x56, 0x65,
|
0x28, 0x93, 0x96, 0xf9, 0xb6, 0xc5, 0x9c, 0x7e, 0x03, 0x73, 0xfd, 0x85, 0xe8, 0xb6, 0x79, 0x08,
|
||||||
0x3f, 0xf4, 0xb5, 0xe5, 0x45, 0xc2, 0xe9, 0xf7, 0xe0, 0x9f, 0xe7, 0x9a, 0x39, 0x27, 0x27, 0xe0,
|
0x70, 0xad, 0x0c, 0x4b, 0x16, 0x6b, 0xa5, 0xf6, 0x02, 0x4f, 0x5b, 0x5e, 0xc4, 0x9c, 0x7e, 0x0f,
|
||||||
0xa7, 0xf5, 0xc6, 0x08, 0x38, 0x69, 0x6f, 0xbb, 0x8e, 0x0b, 0xdb, 0x20, 0xfa, 0x1d, 0xec, 0xd6,
|
0xde, 0x79, 0xae, 0x99, 0x73, 0x72, 0x02, 0x5e, 0x52, 0x6f, 0x8c, 0xa8, 0x93, 0xf6, 0xb6, 0xeb,
|
||||||
0xe6, 0xba, 0x0f, 0x67, 0x53, 0x1f, 0xa3, 0x5b, 0x7d, 0xd0, 0x7f, 0x1d, 0xd8, 0xef, 0x52, 0x36,
|
0xb8, 0xa0, 0x0d, 0xa2, 0xdf, 0xc1, 0x6e, 0x6d, 0xae, 0xfb, 0x70, 0x36, 0xf5, 0x31, 0xba, 0xd5,
|
||||||
0x47, 0x75, 0x01, 0x7b, 0x4d, 0x89, 0xc5, 0x3a, 0x2a, 0x0c, 0x97, 0x13, 0x9b, 0x4b, 0x3f, 0xad,
|
0x07, 0xfd, 0xd7, 0x81, 0xfd, 0x2e, 0x65, 0x73, 0x54, 0x17, 0xb0, 0xd7, 0x94, 0x58, 0xa6, 0x61,
|
||||||
0x21, 0xc8, 0x5f, 0x46, 0x85, 0x1e, 0x81, 0x69, 0x6a, 0x99, 0xe6, 0x3f, 0xc1, 0xc7, 0xbd, 0x10,
|
0x61, 0xb8, 0x9c, 0xd8, 0x5c, 0xfa, 0x69, 0x0d, 0x41, 0xfe, 0x32, 0x2c, 0xf4, 0x08, 0xcc, 0x12,
|
||||||
0xc9, 0xfa, 0x0a, 0xeb, 0x19, 0x94, 0x4b, 0xf2, 0x08, 0xbc, 0xeb, 0x28, 0xad, 0xd0, 0xcc, 0xfb,
|
0xcb, 0xb4, 0xf8, 0x09, 0x3e, 0xee, 0x85, 0x48, 0xd6, 0x57, 0x58, 0xcf, 0xa0, 0x5c, 0x92, 0x47,
|
||||||
0xac, 0x7f, 0x02, 0x3c, 0xd4, 0x11, 0xdf, 0x8e, 0x1e, 0x3b, 0xa7, 0xff, 0x78, 0x30, 0x7d, 0x8d,
|
0x30, 0xbe, 0x0e, 0x93, 0x0a, 0xcd, 0xbc, 0xcf, 0xfb, 0x27, 0xc0, 0x03, 0x1d, 0xf1, 0xed, 0xe8,
|
||||||
0xd1, 0xef, 0x88, 0x89, 0x7c, 0xfd, 0x25, 0x59, 0xd5, 0x5d, 0x75, 0x3f, 0xcb, 0xe4, 0xc1, 0x6d,
|
0xb1, 0x73, 0xfa, 0xcf, 0x18, 0x66, 0xaf, 0x31, 0xfc, 0x1d, 0x31, 0x96, 0xaf, 0xbf, 0x24, 0xeb,
|
||||||
0xfa, 0x83, 0xff, 0x01, 0xf3, 0x2f, 0xdf, 0x16, 0x66, 0xc6, 0x7a, 0x8b, 0x9c, 0xc3, 0xc4, 0xfa,
|
0xba, 0xab, 0xee, 0xa7, 0x9a, 0x3c, 0xb8, 0x4d, 0x7f, 0xf0, 0xdf, 0x60, 0xf1, 0xe5, 0xdb, 0xc2,
|
||||||
0x08, 0x93, 0x03, 0x2b, 0xb1, 0xf7, 0x3d, 0x9f, 0x1f, 0x6e, 0xf0, 0x36, 0x68, 0x11, 0x90, 0xbe,
|
0xcc, 0x58, 0x6f, 0x91, 0x73, 0x98, 0x5a, 0x1f, 0x66, 0x72, 0x60, 0x25, 0xf6, 0xbe, 0xf1, 0x8b,
|
||||||
0xee, 0x92, 0xcf, 0xdb, 0xb4, 0x8d, 0xfa, 0x3f, 0xff, 0xe2, 0xcd, 0x41, 0x36, 0x61, 0x4b, 0x94,
|
0xc3, 0x0d, 0xde, 0x06, 0x2d, 0x04, 0xd2, 0xd7, 0x5d, 0xf2, 0x79, 0x9b, 0xb6, 0x51, 0xff, 0x17,
|
||||||
0x6c, 0xc2, 0x7d, 0x19, 0xb4, 0x09, 0x0f, 0x29, 0x99, 0x42, 0xb3, 0x04, 0xc7, 0x46, 0xeb, 0x4b,
|
0x5f, 0xbc, 0x39, 0xc8, 0x26, 0x6c, 0x89, 0x92, 0x4d, 0xb8, 0x2f, 0x83, 0x36, 0xe1, 0x21, 0x25,
|
||||||
0x9c, 0x8d, 0x36, 0xa4, 0x52, 0x0a, 0xcd, 0x12, 0x0f, 0x1b, 0xad, 0x2f, 0x5f, 0x36, 0xda, 0x90,
|
0x53, 0x68, 0x96, 0xe0, 0xd8, 0x68, 0x7d, 0x89, 0xb3, 0xd1, 0x86, 0x54, 0x4a, 0xa1, 0x59, 0xe2,
|
||||||
0xe2, 0x6c, 0x91, 0x57, 0x30, 0xb5, 0x45, 0x80, 0x58, 0x09, 0x03, 0x5a, 0x34, 0xbf, 0xbf, 0xc9,
|
0x61, 0xa3, 0xf5, 0xe5, 0xcb, 0x46, 0x1b, 0x52, 0x9c, 0x2d, 0xf2, 0x0a, 0x66, 0xb6, 0x08, 0x10,
|
||||||
0x6d, 0x03, 0xda, 0x33, 0x6f, 0x03, 0x0e, 0xbc, 0x7a, 0x1b, 0x70, 0xe8, 0xa9, 0xd0, 0xad, 0xcb,
|
0x2b, 0x61, 0x40, 0x8b, 0x16, 0xf7, 0x37, 0xb9, 0x6d, 0x40, 0x7b, 0xe6, 0x6d, 0xc0, 0x81, 0x57,
|
||||||
0xb1, 0xfa, 0x3d, 0xfd, 0xfa, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x83, 0x92, 0xde, 0x64, 0xad,
|
0x6f, 0x03, 0x0e, 0x3d, 0x15, 0xba, 0x75, 0x39, 0x51, 0xbf, 0xac, 0x5f, 0xff, 0x17, 0x00, 0x00,
|
||||||
0x0a, 0x00, 0x00,
|
0xff, 0xff, 0xf1, 0x42, 0x51, 0xbb, 0xc1, 0x0a, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@ func (fs *FilerServer) ListEntries(ctx context.Context, req *filer_pb.ListEntrie
|
||||||
Gid: entry.Gid,
|
Gid: entry.Gid,
|
||||||
Uid: entry.Uid,
|
Uid: entry.Uid,
|
||||||
FileMode: uint32(entry.Mode),
|
FileMode: uint32(entry.Mode),
|
||||||
|
Mime: entry.Mime,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -75,6 +76,7 @@ func (fs *FilerServer) GetEntryAttributes(ctx context.Context, req *filer_pb.Get
|
||||||
attributes.Gid = entry.Gid
|
attributes.Gid = entry.Gid
|
||||||
attributes.Mtime = entry.Mtime.Unix()
|
attributes.Mtime = entry.Mtime.Unix()
|
||||||
attributes.Crtime = entry.Crtime.Unix()
|
attributes.Crtime = entry.Crtime.Unix()
|
||||||
|
attributes.Mime = entry.Mime
|
||||||
|
|
||||||
glog.V(3).Infof("GetEntryAttributes %v size %d chunks %d: %+v", fullpath, attributes.FileSize, len(entry.Chunks), attributes)
|
glog.V(3).Infof("GetEntryAttributes %v size %d chunks %d: %+v", fullpath, attributes.FileSize, len(entry.Chunks), attributes)
|
||||||
|
|
||||||
|
@ -120,6 +122,7 @@ func (fs *FilerServer) CreateEntry(ctx context.Context, req *filer_pb.CreateEntr
|
||||||
Mode: os.FileMode(req.Entry.Attributes.FileMode),
|
Mode: os.FileMode(req.Entry.Attributes.FileMode),
|
||||||
Uid: req.Entry.Attributes.Uid,
|
Uid: req.Entry.Attributes.Uid,
|
||||||
Gid: req.Entry.Attributes.Gid,
|
Gid: req.Entry.Attributes.Gid,
|
||||||
|
Mime: req.Entry.Attributes.Mime,
|
||||||
},
|
},
|
||||||
Chunks: req.Entry.Chunks,
|
Chunks: req.Entry.Chunks,
|
||||||
})
|
})
|
||||||
|
@ -162,6 +165,7 @@ func (fs *FilerServer) UpdateEntry(ctx context.Context, req *filer_pb.UpdateEntr
|
||||||
}
|
}
|
||||||
newEntry.Attr.Uid = req.Entry.Attributes.Uid
|
newEntry.Attr.Uid = req.Entry.Attributes.Uid
|
||||||
newEntry.Attr.Gid = req.Entry.Attributes.Gid
|
newEntry.Attr.Gid = req.Entry.Attributes.Gid
|
||||||
|
newEntry.Attr.Mime = req.Entry.Attributes.Mime
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,14 +184,7 @@ func (fs *FilerServer) UpdateEntry(ctx context.Context, req *filer_pb.UpdateEntr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fs *FilerServer) DeleteEntry(ctx context.Context, req *filer_pb.DeleteEntryRequest) (resp *filer_pb.DeleteEntryResponse, err error) {
|
func (fs *FilerServer) DeleteEntry(ctx context.Context, req *filer_pb.DeleteEntryRequest) (resp *filer_pb.DeleteEntryResponse, err error) {
|
||||||
entry, err := fs.filer.DeleteEntry(filer2.FullPath(filepath.Join(req.Directory, req.Name)))
|
err = fs.filer.DeleteEntryMetaAndData(filer2.FullPath(filepath.Join(req.Directory, req.Name)))
|
||||||
if err == nil {
|
|
||||||
for _, chunk := range entry.Chunks {
|
|
||||||
if err = operation.DeleteFile(fs.getMasterNode(), chunk.FileId, fs.jwt(chunk.FileId)); err != nil {
|
|
||||||
glog.V(0).Infof("deleting file %s: %v", chunk.FileId, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return &filer_pb.DeleteEntryResponse{}, err
|
return &filer_pb.DeleteEntryResponse{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ func (fs *FilerServer) registerHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
writeJsonError(w, r, http.StatusInternalServerError, fmt.Errorf("parsing gid: %v", err))
|
writeJsonError(w, r, http.StatusInternalServerError, fmt.Errorf("parsing gid: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
mime := r.FormValue("mime")
|
||||||
entry := &filer2.Entry{
|
entry := &filer2.Entry{
|
||||||
FullPath: filer2.FullPath(path),
|
FullPath: filer2.FullPath(path),
|
||||||
Attr: filer2.Attr{
|
Attr: filer2.Attr{
|
||||||
|
@ -40,6 +41,7 @@ func (fs *FilerServer) registerHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
Mtime: time.Now(),
|
Mtime: time.Now(),
|
||||||
Uid: uint32(uid),
|
Uid: uint32(uid),
|
||||||
Gid: uint32(gid),
|
Gid: uint32(gid),
|
||||||
|
Mime: mime,
|
||||||
},
|
},
|
||||||
Chunks: []*filer_pb.FileChunk{{
|
Chunks: []*filer_pb.FileChunk{{
|
||||||
FileId: fileId,
|
FileId: fileId,
|
||||||
|
|
|
@ -111,9 +111,11 @@ func (fs *FilerServer) handleSingleChunk(w http.ResponseWriter, r *http.Request,
|
||||||
|
|
||||||
func (fs *FilerServer) handleMultipleChunks(w http.ResponseWriter, r *http.Request, entry *filer2.Entry) {
|
func (fs *FilerServer) handleMultipleChunks(w http.ResponseWriter, r *http.Request, entry *filer2.Entry) {
|
||||||
|
|
||||||
mimeType := ""
|
mimeType := entry.Mime
|
||||||
if ext := path.Ext(entry.Name()); ext != "" {
|
if mimeType == "" {
|
||||||
mimeType = mime.TypeByExtension(ext)
|
if ext := path.Ext(entry.Name()); ext != "" {
|
||||||
|
mimeType = mime.TypeByExtension(ext)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if mimeType != "" {
|
if mimeType != "" {
|
||||||
w.Header().Set("Content-Type", mimeType)
|
w.Header().Set("Content-Type", mimeType)
|
||||||
|
|
|
@ -195,19 +195,12 @@ func (fs *FilerServer) PostHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
// curl -X DELETE http://localhost:8888/path/to
|
// curl -X DELETE http://localhost:8888/path/to
|
||||||
func (fs *FilerServer) DeleteHandler(w http.ResponseWriter, r *http.Request) {
|
func (fs *FilerServer) DeleteHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
entry, err := fs.filer.DeleteEntry(filer2.FullPath(r.URL.Path))
|
err := fs.filer.DeleteEntryMetaAndData(filer2.FullPath(r.URL.Path))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.V(4).Infoln("deleting", r.URL.Path, ":", err.Error())
|
glog.V(4).Infoln("deleting", r.URL.Path, ":", err.Error())
|
||||||
writeJsonError(w, r, http.StatusInternalServerError, err)
|
writeJsonError(w, r, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if entry != nil && !entry.IsDirectory() {
|
|
||||||
for _, chunk := range entry.Chunks {
|
|
||||||
oldFid := chunk.FileId
|
|
||||||
operation.DeleteFile(fs.getMasterNode(), oldFid, fs.jwt(oldFid))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
writeJsonQuiet(w, r, http.StatusAccepted, map[string]string{"error": ""})
|
writeJsonQuiet(w, r, http.StatusAccepted, map[string]string{"error": ""})
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,9 +47,15 @@ var StatusTpl = template.Must(template.New("status").Parse(`<!DOCTYPE html>
|
||||||
</td>
|
</td>
|
||||||
<td align="right">
|
<td align="right">
|
||||||
{{if $entry.IsDirectory}}
|
{{if $entry.IsDirectory}}
|
||||||
|
{{else}}
|
||||||
|
{{ $entry.Mime }}
|
||||||
|
{{end}}
|
||||||
|
</td>
|
||||||
|
<td align="right">
|
||||||
|
{{if $entry.IsDirectory}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{ $entry.Size }} bytes
|
{{ $entry.Size }} bytes
|
||||||
|
|
||||||
{{end}}
|
{{end}}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
Loading…
Reference in a new issue