Beispiel #1
0
// Del deletes the object from the bucket
func (m master) Del(owner s3intf.Owner, bucket, object string) (err error) {
	m.Lock()
	o, ok := m.owners[owner.ID()]
	m.Unlock()
	if !ok {
		return errors.New("cannot find owner " + owner.ID())
	}
	o.Lock()
	b, ok := o.buckets[bucket]
	o.Unlock()
	if !ok {
		return errors.New("cannot find bucket " + bucket)
	}

	if err = b.db.BeginTransaction(); err != nil {
		return fmt.Errorf("cannot start transaction: %s", err)
	}
	defer func() {
		if err != nil {
			b.db.Rollback()
		}
	}()

	val, e := b.db.Extract(nil, []byte(object))
	if e != nil {
		err = fmt.Errorf("cannot get %s object: %s", object, e)
		return
	}
	if val == nil {
		err = s3intf.NotFound
		return
	}
	vi := new(weedutils.ValInfo)
	if err = vi.Decode(val); err != nil {
		err = fmt.Errorf("error deserializing %s: %s", val, err)
		return
	}
	if err = m.wm.Delete(vi.Fid); err != nil {
		return
	}
	err = nil
	return b.db.Commit()
}
Beispiel #2
0
// Get retrieves an object from the bucket
func (m master) Get(owner s3intf.Owner, bucket, object string) (
	filename, media string, body io.ReadCloser, size int64, md5 []byte, err error) {

	m.Lock()
	o, ok := m.owners[owner.ID()]
	m.Unlock()
	if !ok {
		err = errors.New("cannot find owner " + owner.ID())
		return
	}
	o.Lock()
	b, ok := o.buckets[bucket]
	o.Unlock()
	if !ok {
		err = errors.New("cannot find bucket " + bucket)
		return
	}

	val, e := b.db.Get(nil, []byte(object))
	if e != nil {
		err = fmt.Errorf("cannot get %s object: %s", object, e)
		return
	}
	if val == nil {
		err = s3intf.NotFound
		return
	}
	vi := new(weedutils.ValInfo)
	if err = vi.Decode(val); err != nil {
		err = fmt.Errorf("error deserializing %s: %s", val, err)
		return
	}
	filename, media, size, md5 = vi.Filename, vi.ContentType, vi.Size, vi.MD5

	body, err = m.wm.Download(vi.Fid)
	return
}
Beispiel #3
0
func dumpBucket(w io.Writer, db *kv.DB) (err error) {
	//log.Printf("dumping %s", db)
	io.WriteString(w, `{"name": "`+db.Name()+`", "records": [`)
	enc := json.NewEncoder(w)
	enum, e := db.SeekFirst()
	if e != nil {
		if e != io.EOF {
			err = e
			log.Printf("error getting first: %s", err)
		}
		return
	}
	vi := new(weedutils.ValInfo)
	for {
		k, v, err := enum.Next()
		if err != nil {
			if err != io.EOF {
				log.Printf("error getting next: %s", err)
			}
			break
		}
		if err = vi.Decode(v); err != nil {
			log.Printf("error decoding %s: %s", v, err)
			continue
		}
		fmt.Fprintf(w, `{"object": %q, "value": `, k)
		if err = enc.Encode(vi); err != nil {
			log.Printf("error printing %v to json: %s", vi, err)
			continue
		}
		io.WriteString(w, "},\n")

	}
	io.WriteString(w, "]},\n")
	io.WriteString(w, "]},\n")
	return nil
}
Beispiel #4
0
// Put puts a file as a new object into the bucket
func (m master) Put(owner s3intf.Owner, bucket, object, filename, media string,
	body io.Reader, size int64, md5hash []byte) (
	err error) {

	m.Lock()
	o, ok := m.owners[owner.ID()]
	m.Unlock()
	if !ok {
		err = errors.New("cannot find owner " + owner.ID())
		return
	}
	o.Lock()
	b, ok := o.buckets[bucket]
	o.Unlock()
	if !ok {
		err = errors.New("cannot find bucket " + bucket)
		return
	}

	if err = b.db.BeginTransaction(); err != nil {
		return fmt.Errorf("cannot start transaction: %s", err)
	}
	defer func() {
		if err != nil {
			b.db.Rollback()
		}
	}()
	//upload
	fid, publicURL, err := m.wm.AssignFid()
	if err != nil {
		err = fmt.Errorf("error getting fid: %s", err)
		return
	}
	vi := weedutils.ValInfo{Filename: filename, ContentType: media,
		Fid: fid, Created: time.Now(), Size: size, MD5: md5hash}
	val, err := vi.Encode(nil)
	if err != nil {
		err = fmt.Errorf("error serializing %v: %s", vi, err)
		return
	}
	if err = b.db.Set([]byte(object), val); err != nil {
		err = fmt.Errorf("error storing key in db: %s", err)
		return
	}
	//log.Printf("filename=%q", filename)
	var hsh hash.Hash
	if vi.MD5 == nil {
		hsh = md5.New()
		body = io.TeeReader(body, hsh)
	}
	if _, err = m.wm.UploadAssigned(fid, publicURL, filename, media, body); err != nil {
		b.db.Rollback()
		err = fmt.Errorf("error uploading to %s: %s", fid, err)
		return
	}
	if vi.MD5 == nil {
		vi.MD5 = hsh.Sum(nil)
		if val, err = vi.Encode(nil); err != nil {
			err = fmt.Errorf("error serializing %v: %s", vi, err)
			return
		}
		if err = b.db.Set([]byte(object), val); err != nil {
			err = fmt.Errorf("error storing key in db: %s", err)
			return
		}
	}

	//log.Printf("uploading %s [%d] resulted in %s", filename, size, resp)
	err = nil
	return b.db.Commit()
}
Beispiel #5
0
// List lists a bucket, all objects Key starts with prefix, delimiter segments
// Key, thus the returned commonprefixes (think a generalized filepath
// structure, where / is the delimiter, a commonprefix is a subdir)
func (m master) List(owner s3intf.Owner, bucket, prefix, delimiter, marker string,
	limit, skip int) (
	objects []s3intf.Object, commonprefixes []string,
	truncated bool, err error) {

	m.Lock()
	o, ok := m.owners[owner.ID()]
	if !ok {
		m.Unlock()
		err = fmt.Errorf("unknown owner %s", owner.ID())
		return
	}
	o.Lock()
	b, ok := o.buckets[bucket]
	o.Unlock()
	m.Unlock()
	if !ok {
		err = fmt.Errorf("unknown bucket %s", bucket)
		return
	}

	err = nil
	enum, e := b.db.SeekFirst()
	if e != nil {
		if e == io.EOF { //empty
			return
		}
		err = fmt.Errorf("error getting first: %s", e)
		return
	}
	var (
		key, val []byte
		vi       = new(weedutils.ValInfo)
		etag     string
	)
	objects = make([]s3intf.Object, 0, 64)
	f := s3intf.NewListFilter(prefix, delimiter, marker, limit, skip)
	for {
		if key, val, e = enum.Next(); e != nil {
			if e == io.EOF {
				break
			}
			err = fmt.Errorf("error seeking next: %s", e)
			return
		}
		//log.Printf("key=%q", key)
		if ok, e = f.Check(string(key)); e != nil {
			if e == io.EOF {
				break
			}
			err = fmt.Errorf("error checking %s: %s", key, e)
			return
		} else if ok {
			if err = vi.Decode(val); err != nil {
				return
			}
			if vi.MD5 != nil && len(vi.MD5) == 16 {
				etag = hex.EncodeToString(vi.MD5)
			} else {
				etag = ""
			}
			objects = append(objects,
				s3intf.Object{Key: string(key), Owner: owner,
					ETag: etag, LastModified: vi.Created, Size: vi.Size})
		}
	}
	commonprefixes, truncated = f.Result()
	return
}