|
|
package filer
import ( "context" "fmt" "os" "time"
"github.com/seaweedfs/seaweedfs/weed/operation" "github.com/seaweedfs/seaweedfs/weed/pb/filer_pb" "github.com/seaweedfs/seaweedfs/weed/util" )
func (f *Filer) appendToFile(targetFile string, data []byte) error {
assignResult, uploadResult, err2 := f.assignAndUpload(targetFile, data) if err2 != nil { return err2 }
// find out existing entry
fullpath := util.FullPath(targetFile) entry, err := f.FindEntry(context.Background(), fullpath) var offset int64 = 0 if err == filer_pb.ErrNotFound { entry = &Entry{ FullPath: fullpath, Attr: Attr{ Crtime: time.Now(), Mtime: time.Now(), Mode: os.FileMode(0644), Uid: OS_UID, Gid: OS_GID, }, } } else if err != nil { return fmt.Errorf("find %s: %v", fullpath, err) } else { offset = int64(TotalSize(entry.GetChunks())) }
// append to existing chunks
entry.Chunks = append(entry.GetChunks(), uploadResult.ToPbFileChunk(assignResult.Fid, offset, time.Now().UnixNano()))
// update the entry
err = f.CreateEntry(context.Background(), entry, false, false, nil, false, f.MaxFilenameLength)
return err }
func (f *Filer) assignAndUpload(targetFile string, data []byte) (*operation.AssignResult, *operation.UploadResult, error) { // assign a volume location
rule := f.FilerConf.MatchStorageRule(targetFile) assignRequest := &operation.VolumeAssignRequest{ Count: 1, Collection: util.Nvl(f.metaLogCollection, rule.Collection), Replication: util.Nvl(f.metaLogReplication, rule.Replication), WritableVolumeCount: rule.VolumeGrowthCount, }
assignResult, err := operation.Assign(f.GetMaster, f.GrpcDialOption, assignRequest) if err != nil { return nil, nil, fmt.Errorf("AssignVolume: %v", err) } if assignResult.Error != "" { return nil, nil, fmt.Errorf("AssignVolume error: %v", assignResult.Error) }
// upload data
targetUrl := "http://" + assignResult.Url + "/" + assignResult.Fid uploadOption := &operation.UploadOption{ UploadUrl: targetUrl, Filename: "", Cipher: f.Cipher, IsInputCompressed: false, MimeType: "", PairMap: nil, Jwt: assignResult.Auth, }
uploader, err := operation.NewUploader() if err != nil { return nil, nil, fmt.Errorf("upload data %s: %v", targetUrl, err) }
uploadResult, err := uploader.UploadData(data, uploadOption) if err != nil { return nil, nil, fmt.Errorf("upload data %s: %v", targetUrl, err) } // println("uploaded to", targetUrl)
return assignResult, uploadResult, nil }
|