github.com/cloud-foundations/dominator@v0.0.0-20221004181915-6e4fee580046/cmd/objecttool/getObjects.go (about)

     1  package main
     2  
     3  import (
     4  	"bufio"
     5  	"fmt"
     6  	"io"
     7  	"os"
     8  	"syscall"
     9  
    10  	"github.com/Cloud-Foundations/Dominator/lib/fsutil"
    11  	"github.com/Cloud-Foundations/Dominator/lib/hash"
    12  	"github.com/Cloud-Foundations/Dominator/lib/log"
    13  	"github.com/Cloud-Foundations/Dominator/lib/objectcache"
    14  	"github.com/Cloud-Foundations/Dominator/lib/objectserver"
    15  )
    16  
    17  func getObjectsSubcommand(args []string, logger log.DebugLogger) error {
    18  	if err := getObjects(getObjectServer(), args[0], args[1]); err != nil {
    19  		return fmt.Errorf("Error getting objects: %s", err)
    20  	}
    21  	return nil
    22  }
    23  
    24  func getObjects(objSrv objectserver.ObjectServer,
    25  	hashesFilename, outputDirectory string) error {
    26  	hashesFile, err := os.Open(hashesFilename)
    27  	if err != nil {
    28  		return err
    29  	}
    30  	defer hashesFile.Close()
    31  	scanner := bufio.NewScanner(hashesFile)
    32  	var hashes []hash.Hash
    33  	for scanner.Scan() {
    34  		hashval, err := objectcache.FilenameToHash(scanner.Text())
    35  		if err != nil {
    36  			return err
    37  		}
    38  		hashes = append(hashes, hashval)
    39  	}
    40  	if err := scanner.Err(); err != nil {
    41  		return err
    42  	}
    43  	objectsReader, err := objSrv.GetObjects(hashes)
    44  	if err != nil {
    45  		return err
    46  	}
    47  	defer objectsReader.Close()
    48  	tmpDirname := outputDirectory + "~"
    49  	if err := os.Mkdir(tmpDirname, syscall.S_IRWXU); err != nil {
    50  		return err
    51  	}
    52  	defer os.RemoveAll(tmpDirname)
    53  	for _, hash := range hashes {
    54  		length, reader, err := objectsReader.NextObject()
    55  		if err != nil {
    56  			return err
    57  		}
    58  		err = readOne(tmpDirname, hash, length, reader)
    59  		reader.Close()
    60  		if err != nil {
    61  			return err
    62  		}
    63  	}
    64  	return os.Rename(tmpDirname, outputDirectory)
    65  }
    66  
    67  func readOne(dirname string, hash hash.Hash, length uint64,
    68  	reader io.Reader) error {
    69  	filename := fmt.Sprintf("%s/%x", dirname, hash)
    70  	return fsutil.CopyToFile(filename, filePerms, reader, length)
    71  }