c76ad94492
This commit adds a build step to travis to auto-delete unstable archives older than 14 days (our regular release schedule) from Azure via ci.go purge. The commit also pulls in the latest Azure storage code, also switching over from the old import path (github.com/Azure/azure-sdk-for-go) to the new split one (github.com/Azure/azure-storage-go).
187 lines
5.6 KiB
Go
187 lines
5.6 KiB
Go
package storage
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"net/url"
|
|
"strconv"
|
|
)
|
|
|
|
// Share represents an Azure file share.
|
|
type Share struct {
|
|
fsc *FileServiceClient
|
|
Name string `xml:"Name"`
|
|
Properties ShareProperties `xml:"Properties"`
|
|
Metadata map[string]string
|
|
}
|
|
|
|
// ShareProperties contains various properties of a share.
|
|
type ShareProperties struct {
|
|
LastModified string `xml:"Last-Modified"`
|
|
Etag string `xml:"Etag"`
|
|
Quota int `xml:"Quota"`
|
|
}
|
|
|
|
// builds the complete path for this share object.
|
|
func (s *Share) buildPath() string {
|
|
return fmt.Sprintf("/%s", s.Name)
|
|
}
|
|
|
|
// Create this share under the associated account.
|
|
// If a share with the same name already exists, the operation fails.
|
|
//
|
|
// See https://msdn.microsoft.com/en-us/library/azure/dn167008.aspx
|
|
func (s *Share) Create() error {
|
|
headers, err := s.fsc.createResource(s.buildPath(), resourceShare, nil, mergeMDIntoExtraHeaders(s.Metadata, nil), []int{http.StatusCreated})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
s.updateEtagAndLastModified(headers)
|
|
return nil
|
|
}
|
|
|
|
// CreateIfNotExists creates this share under the associated account if
|
|
// it does not exist. Returns true if the share is newly created or false if
|
|
// the share already exists.
|
|
//
|
|
// See https://msdn.microsoft.com/en-us/library/azure/dn167008.aspx
|
|
func (s *Share) CreateIfNotExists() (bool, error) {
|
|
resp, err := s.fsc.createResourceNoClose(s.buildPath(), resourceShare, nil, nil)
|
|
if resp != nil {
|
|
defer readAndCloseBody(resp.body)
|
|
if resp.statusCode == http.StatusCreated || resp.statusCode == http.StatusConflict {
|
|
if resp.statusCode == http.StatusCreated {
|
|
s.updateEtagAndLastModified(resp.headers)
|
|
return true, nil
|
|
}
|
|
return false, s.FetchAttributes()
|
|
}
|
|
}
|
|
|
|
return false, err
|
|
}
|
|
|
|
// Delete marks this share for deletion. The share along with any files
|
|
// and directories contained within it are later deleted during garbage
|
|
// collection. If the share does not exist the operation fails
|
|
//
|
|
// See https://msdn.microsoft.com/en-us/library/azure/dn689090.aspx
|
|
func (s *Share) Delete() error {
|
|
return s.fsc.deleteResource(s.buildPath(), resourceShare)
|
|
}
|
|
|
|
// DeleteIfExists operation marks this share for deletion if it exists.
|
|
//
|
|
// See https://msdn.microsoft.com/en-us/library/azure/dn689090.aspx
|
|
func (s *Share) DeleteIfExists() (bool, error) {
|
|
resp, err := s.fsc.deleteResourceNoClose(s.buildPath(), resourceShare)
|
|
if resp != nil {
|
|
defer readAndCloseBody(resp.body)
|
|
if resp.statusCode == http.StatusAccepted || resp.statusCode == http.StatusNotFound {
|
|
return resp.statusCode == http.StatusAccepted, nil
|
|
}
|
|
}
|
|
return false, err
|
|
}
|
|
|
|
// Exists returns true if this share already exists
|
|
// on the storage account, otherwise returns false.
|
|
func (s *Share) Exists() (bool, error) {
|
|
exists, headers, err := s.fsc.resourceExists(s.buildPath(), resourceShare)
|
|
if exists {
|
|
s.updateEtagAndLastModified(headers)
|
|
s.updateQuota(headers)
|
|
}
|
|
return exists, err
|
|
}
|
|
|
|
// FetchAttributes retrieves metadata and properties for this share.
|
|
func (s *Share) FetchAttributes() error {
|
|
headers, err := s.fsc.getResourceHeaders(s.buildPath(), compNone, resourceShare, http.MethodHead)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
s.updateEtagAndLastModified(headers)
|
|
s.updateQuota(headers)
|
|
s.Metadata = getMetadataFromHeaders(headers)
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetRootDirectoryReference returns a Directory object at the root of this share.
|
|
func (s *Share) GetRootDirectoryReference() *Directory {
|
|
return &Directory{
|
|
fsc: s.fsc,
|
|
share: s,
|
|
}
|
|
}
|
|
|
|
// ServiceClient returns the FileServiceClient associated with this share.
|
|
func (s *Share) ServiceClient() *FileServiceClient {
|
|
return s.fsc
|
|
}
|
|
|
|
// SetMetadata replaces the metadata for this share.
|
|
//
|
|
// Some keys may be converted to Camel-Case before sending. All keys
|
|
// are returned in lower case by GetShareMetadata. HTTP header names
|
|
// are case-insensitive so case munging should not matter to other
|
|
// applications either.
|
|
//
|
|
// See https://msdn.microsoft.com/en-us/library/azure/dd179414.aspx
|
|
func (s *Share) SetMetadata() error {
|
|
headers, err := s.fsc.setResourceHeaders(s.buildPath(), compMetadata, resourceShare, mergeMDIntoExtraHeaders(s.Metadata, nil))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
s.updateEtagAndLastModified(headers)
|
|
return nil
|
|
}
|
|
|
|
// SetProperties sets system properties for this share.
|
|
//
|
|
// Some keys may be converted to Camel-Case before sending. All keys
|
|
// are returned in lower case by SetShareProperties. HTTP header names
|
|
// are case-insensitive so case munging should not matter to other
|
|
// applications either.
|
|
//
|
|
// See https://msdn.microsoft.com/en-us/library/azure/mt427368.aspx
|
|
func (s *Share) SetProperties() error {
|
|
if s.Properties.Quota < 1 || s.Properties.Quota > 5120 {
|
|
return fmt.Errorf("invalid value %v for quota, valid values are [1, 5120]", s.Properties.Quota)
|
|
}
|
|
|
|
headers, err := s.fsc.setResourceHeaders(s.buildPath(), compProperties, resourceShare, map[string]string{
|
|
"x-ms-share-quota": strconv.Itoa(s.Properties.Quota),
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
s.updateEtagAndLastModified(headers)
|
|
return nil
|
|
}
|
|
|
|
// updates Etag and last modified date
|
|
func (s *Share) updateEtagAndLastModified(headers http.Header) {
|
|
s.Properties.Etag = headers.Get("Etag")
|
|
s.Properties.LastModified = headers.Get("Last-Modified")
|
|
}
|
|
|
|
// updates quota value
|
|
func (s *Share) updateQuota(headers http.Header) {
|
|
quota, err := strconv.Atoi(headers.Get("x-ms-share-quota"))
|
|
if err == nil {
|
|
s.Properties.Quota = quota
|
|
}
|
|
}
|
|
|
|
// URL gets the canonical URL to this share. This method does not create a publicly accessible
|
|
// URL if the share is private and this method does not check if the share exists.
|
|
func (s *Share) URL() string {
|
|
return s.fsc.client.getEndpoint(fileServiceName, s.buildPath(), url.Values{})
|
|
}
|