Skip to content

Instantly share code, notes, and snippets.

@thesyncim
Created April 8, 2015 17:08
Show Gist options
  • Save thesyncim/62d1a8c6d657f665a535 to your computer and use it in GitHub Desktop.
Save thesyncim/62d1a8c6d657f665a535 to your computer and use it in GitHub Desktop.
package backup
import (
"io"
"log"
"os"
"path/filepath"
"time"
"github.com/juju/arrar"
"gopkg.in/mgo.v2/bson"
)
var _ = Store(&store{})
func NewS3qlStore(root string) Store {
err := os.MkdirAll(root, 777)
if err != nil {
log.Fatalln(err)
}
return &store{root, map[bson.ObjectId]*Snapshot{}}
}
type Store interface {
GetRoot() string
CreateSnapshot(owner bson.ObjectId) *Snapshot
GetSnapshot(owner, id bson.ObjectId) *Snapshot
}
func (s *store) GetRoot() string {
return s.root
}
type Snapshot struct {
Id bson.ObjectId
Owner bson.ObjectId
StartedTime time.Time
EndTime time.Time
Error string
Nodes *NodeSlice
store Store
}
func (b *store) CreateSnapshot(owner bson.ObjectId) *Snapshot {
return &Snapshot{
Id: bson.NewObjectId(),
Owner: owner,
StartedTime: time.Now(),
Nodes: &NodeSlice{},
store: b,
}
}
//return /create(if necessary) a snaphotfor for the current user
func (s *store) GetSnapshot(owner, id bson.ObjectId) *Snapshot {
snapshot, ok := s.snapshots[id]
os.MkdirAll(filepath.Join(s.root, owner.Hex(), id.Hex()), 777)
if !ok {
return s.CreateSnapshot(owner)
}
return snapshot
}
type store struct {
root string
snapshots map[bson.ObjectId]*Snapshot
}
func (b *Snapshot) CreateNode(node *Node, in io.Reader) error {
*b.Nodes = append(*b.Nodes, node)
switch node.Type {
case "file":
relpath := filepath.Join(
b.store.GetRoot(),
b.Owner.Hex(),
node.SnapshotID,
node.Path[len(node.Basepath)+1:],
)
log.Println(relpath)
outfile, err := os.Create(relpath)
if err != nil {
return err
}
n, err := io.Copy(outfile, in)
outfile.Close()
if err != nil {
return err
}
if uint64(n) != node.Size {
return io.ErrShortWrite
}
return node.setUtimes(relpath)
case "dir":
relpath := filepath.Join(
b.store.GetRoot(),
b.Owner.Hex(),
node.SnapshotID,
node.Path[len(node.Basepath):],
)
//create the directory
err := os.MkdirAll(relpath, os.FileMode(node.Mode))
if err != nil {
return arrar.Annotate(err, "Mkdir")
}
return node.setUtimes(relpath)
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment