100 lines
2.7 KiB
Go
100 lines
2.7 KiB
Go
// Copyright 2019 Drone.IO Inc. All rights reserved.
|
|
// Use of this source code is governed by the Drone Non-Commercial License
|
|
// that can be found in the LICENSE file.
|
|
|
|
// +build !oss
|
|
|
|
package logs
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"net/url"
|
|
|
|
"github.com/Azure/azure-storage-blob-go/azblob"
|
|
"github.com/drone/drone/core"
|
|
)
|
|
|
|
// NewAzureBlobEnv returns a new Azure blob log store.
|
|
func NewAzureBlobEnv(containerName, storageAccountName, storageAccessKey string) core.LogStore {
|
|
return &azureBlobStore{
|
|
containerName: containerName,
|
|
storageAccountName: storageAccountName,
|
|
storageAccessKey: storageAccessKey,
|
|
containerURL: nil,
|
|
}
|
|
}
|
|
|
|
type azureBlobStore struct {
|
|
containerName string
|
|
storageAccountName string
|
|
storageAccessKey string
|
|
containerURL *azblob.ContainerURL
|
|
}
|
|
|
|
func (az *azureBlobStore) Find(ctx context.Context, step int64) (io.ReadCloser, error) {
|
|
err := az.getContainerURL()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
blobURL := az.containerURL.NewBlockBlobURL(fmt.Sprintf("%d", step))
|
|
out, err := blobURL.Download(ctx, 0, azblob.CountToEnd, azblob.BlobAccessConditions{}, false)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return out.Body(azblob.RetryReaderOptions{}), nil
|
|
}
|
|
|
|
func (az *azureBlobStore) Create(ctx context.Context, step int64, r io.Reader) error {
|
|
err := az.getContainerURL()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
opts := &azblob.UploadStreamToBlockBlobOptions{
|
|
BufferSize: 4 * 1024 * 1024,
|
|
MaxBuffers: 5,
|
|
}
|
|
blobURL := az.containerURL.NewBlockBlobURL(fmt.Sprintf("%d", step))
|
|
_, err = azblob.UploadStreamToBlockBlob(ctx, r, blobURL, *opts)
|
|
return err
|
|
}
|
|
|
|
func (az *azureBlobStore) Update(ctx context.Context, step int64, r io.Reader) error {
|
|
return az.Create(ctx, step, r)
|
|
}
|
|
|
|
func (az *azureBlobStore) Delete(ctx context.Context, step int64) error {
|
|
err := az.getContainerURL()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
blobURL := az.containerURL.NewBlockBlobURL(fmt.Sprintf("%d", step))
|
|
_, err = blobURL.Delete(ctx, azblob.DeleteSnapshotsOptionNone, azblob.BlobAccessConditions{})
|
|
return err
|
|
}
|
|
|
|
func (az *azureBlobStore) getContainerURL() error {
|
|
if az.containerURL != nil {
|
|
return nil
|
|
}
|
|
if len(az.storageAccountName) == 0 || len(az.storageAccessKey) == 0 {
|
|
return fmt.Errorf("Either the storage account or storage access key environment variable is not set")
|
|
}
|
|
credential, err := azblob.NewSharedKeyCredential(az.storageAccountName, az.storageAccessKey)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
p := azblob.NewPipeline(credential, azblob.PipelineOptions{})
|
|
URL, err := url.Parse(fmt.Sprintf("https://%s.blob.core.windows.net/%s", az.storageAccountName, az.containerName))
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
containerURL := azblob.NewContainerURL(*URL, p)
|
|
az.containerURL = &containerURL
|
|
return nil
|
|
}
|