You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							92 lines
						
					
					
						
							2.6 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							92 lines
						
					
					
						
							2.6 KiB
						
					
					
				
								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(context.Background(), f.GetMaster, f.GrpcDialOption, assignRequest)
							 | 
						|
									if err != nil {
							 | 
						|
										return nil, nil, fmt.Errorf("AssignVolume: %w", 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(context.Background(), data, uploadOption)
							 | 
						|
									if err != nil {
							 | 
						|
										return nil, nil, fmt.Errorf("upload data %s: %v", targetUrl, err)
							 | 
						|
									}
							 | 
						|
									// println("uploaded to", targetUrl)
							 | 
						|
									return assignResult, uploadResult, nil
							 | 
						|
								}
							 |