// IndexTo writes a list of Keep blocks that are stored in the // container. func (v *AzureBlobVolume) IndexTo(prefix string, writer io.Writer) error { params := storage.ListBlobsParameters{ Prefix: prefix, } for { resp, err := v.bsClient.ListBlobs(v.containerName, params) if err != nil { return err } for _, b := range resp.Blobs { t, err := time.Parse(time.RFC1123, b.Properties.LastModified) if err != nil { return err } if !v.isKeepBlock(b.Name) { continue } if b.Properties.ContentLength == 0 && t.Add(azureWriteRaceInterval).After(time.Now()) { // A new zero-length blob is probably // just a new non-empty blob that // hasn't committed its data yet (see // Get()), and in any case has no // value. continue } fmt.Fprintf(writer, "%s+%d %d\n", b.Name, b.Properties.ContentLength, t.Unix()) } if resp.NextMarker == "" { return nil } params.Marker = resp.NextMarker } }
// EmptyTrash looks for trashed blocks that exceeded trashLifetime // and deletes them from the volume. func (v *AzureBlobVolume) EmptyTrash() { var bytesDeleted, bytesInTrash int64 var blocksDeleted, blocksInTrash int params := storage.ListBlobsParameters{Include: "metadata"} for { resp, err := v.bsClient.ListBlobs(v.containerName, params) if err != nil { log.Printf("EmptyTrash: ListBlobs: %v", err) break } for _, b := range resp.Blobs { // Check if the block is expired if b.Metadata["expires_at"] == "" { continue } blocksInTrash++ bytesInTrash += b.Properties.ContentLength expiresAt, err := strconv.ParseInt(b.Metadata["expires_at"], 10, 64) if err != nil { log.Printf("EmptyTrash: ParseInt(%v): %v", b.Metadata["expires_at"], err) continue } if expiresAt > time.Now().Unix() { continue } err = v.bsClient.DeleteBlob(v.containerName, b.Name, map[string]string{ "If-Match": b.Properties.Etag, }) if err != nil { log.Printf("EmptyTrash: DeleteBlob(%v): %v", b.Name, err) continue } blocksDeleted++ bytesDeleted += b.Properties.ContentLength } if resp.NextMarker == "" { break } params.Marker = resp.NextMarker } log.Printf("EmptyTrash stats for %v: Deleted %v bytes in %v blocks. Remaining in trash: %v bytes in %v blocks.", v.String(), bytesDeleted, blocksDeleted, bytesInTrash-bytesDeleted, blocksInTrash-blocksDeleted) }