github.com/Cloud-Foundations/Dominator@v0.3.4/lib/objectserver/lib.go (about) 1 package objectserver 2 3 import ( 4 "fmt" 5 "io" 6 "os" 7 "syscall" 8 9 "github.com/Cloud-Foundations/Dominator/lib/hash" 10 ) 11 12 const ( 13 privateFilePerms = syscall.S_IRUSR | syscall.S_IWUSR 14 ) 15 16 func copyObject(filename string, objectsGetter ObjectsGetter, 17 hashVal hash.Hash) error { 18 size, reader, err := getObject(objectsGetter, hashVal) 19 if err != nil { 20 return err 21 } 22 defer reader.Close() 23 iLength := int64(size) 24 file, err := os.OpenFile(filename, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 25 privateFilePerms) 26 if err != nil { 27 return err 28 } 29 defer file.Close() 30 nCopied, err := io.CopyN(file, reader, iLength) 31 if err != nil { 32 os.Remove(filename) 33 return err 34 } 35 if nCopied != iLength { 36 os.Remove(filename) 37 return fmt.Errorf("copied: %d, expected: %d", nCopied, iLength) 38 } 39 return nil 40 } 41 42 func getObject(objSrv ObjectsGetter, hashVal hash.Hash) ( 43 uint64, io.ReadCloser, error) { 44 hashes := make([]hash.Hash, 1) 45 hashes[0] = hashVal 46 objectsReader, err := objSrv.GetObjects(hashes) 47 if err != nil { 48 return 0, nil, err 49 } 50 defer objectsReader.Close() 51 size, reader, err := objectsReader.NextObject() 52 if err != nil { 53 return 0, nil, err 54 } 55 return size, reader, nil 56 } 57 58 func linkObject(filename string, objectsGetter ObjectsGetter, 59 hashVal hash.Hash) (bool, error) { 60 if objectLinker, ok := objectsGetter.(ObjectLinker); ok { 61 return objectLinker.LinkObject(filename, hashVal) 62 } 63 return false, copyObject(filename, objectsGetter, hashVal) 64 }