Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/Storage/ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@
- Additional information about change #1
-->
## Current Release

* Upgrade to Azure Storage Client Library 8.5.0 and Azure Storage DataMovement Library 0.6.3
* Add File Share Snapshot Support Feature
- Add 'SnapshotTime' parameter to Get-AzureStorageShare
- Add 'IncludeAllSnapshot' parameter to Remove-AzureStorageShare

## Version 3.4.1

## Version 3.4.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,11 @@
<Reference Include="Microsoft.WindowsAzure.Management">
<HintPath>..\..\packages\Microsoft.WindowsAzure.Management.4.1.1\lib\net40\Microsoft.WindowsAzure.Management.dll</HintPath>
</Reference>
<Reference Include="Microsoft.WindowsAzure.Storage, Version=8.4.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\WindowsAzure.Storage.8.4.0\lib\net45\Microsoft.WindowsAzure.Storage.dll</HintPath>
<Reference Include="Microsoft.WindowsAzure.Storage, Version=8.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\WindowsAzure.Storage.8.5.0\lib\net45\Microsoft.WindowsAzure.Storage.dll</HintPath>
</Reference>
<Reference Include="Microsoft.WindowsAzure.Storage.DataMovement, Version=0.6.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.Storage.DataMovement.0.6.1\lib\net45\Microsoft.WindowsAzure.Storage.DataMovement.dll</HintPath>
<Reference Include="Microsoft.WindowsAzure.Storage.DataMovement, Version=0.6.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.Storage.DataMovement.0.6.3\lib\net45\Microsoft.WindowsAzure.Storage.DataMovement.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll</HintPath>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ public void SetsAvailableDirectories(params string[] directoryNames)
this.availableDirectoryNames.AddRange(directoryNames);
}

public CloudFileShare GetShareReference(string shareName)
public CloudFileShare GetShareReference(string shareName, DateTimeOffset? snapshotTime = null)
{
return client.GetShareReference(shareName);
return client.GetShareReference(shareName, snapshotTime);
}

public void FetchShareAttributes(CloudFileShare share, AccessCondition accessCondition, FileRequestOptions options, OperationContext operationContext)
Expand Down Expand Up @@ -136,7 +136,7 @@ public Task DeleteDirectoryAsync(CloudFileDirectory directory, AccessCondition a
return TaskEx.FromResult(true);
}

public Task DeleteShareAsync(CloudFileShare share, AccessCondition accessCondition, FileRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken)
public Task DeleteShareAsync(CloudFileShare share, DeleteShareSnapshotsOption deleteShareSnapshotsOption, AccessCondition accessCondition, FileRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken)
{
return TaskEx.FromResult(true);
}
Expand Down
4 changes: 2 additions & 2 deletions src/Storage/Commands.Storage.Test/packages.config
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<package id="Microsoft.Azure.Common.Dependencies" version="1.0.0" targetFramework="net45" />
<package id="Microsoft.Azure.KeyVault.Core" version="1.0.0" targetFramework="net45" />
<package id="Microsoft.Azure.Management.Resources" version="2.18.11-preview" targetFramework="net45" />
<package id="Microsoft.Azure.Storage.DataMovement" version="0.6.1" targetFramework="net452" />
<package id="Microsoft.Azure.Storage.DataMovement" version="0.6.3" targetFramework="net452" />
<package id="Microsoft.Azure.Test.HttpRecorder" version="1.6.7-preview" targetFramework="net45" />
<package id="Microsoft.Bcl" version="1.1.9" targetFramework="net45" />
<package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net45" />
Expand All @@ -25,7 +25,7 @@
<package id="System.Linq.Queryable" version="4.0.0" targetFramework="net45" />
<package id="System.Net.Requests" version="4.0.11" targetFramework="net45" />
<package id="System.Spatial" version="5.8.2" targetFramework="net45" />
<package id="WindowsAzure.Storage" version="8.4.0" targetFramework="net452" />
<package id="WindowsAzure.Storage" version="8.5.0" targetFramework="net452" />
<package id="xunit" version="2.1.0" targetFramework="net45" />
<package id="xunit.abstractions" version="2.0.0" targetFramework="net45" />
<package id="xunit.assert" version="2.1.0" targetFramework="net45" />
Expand Down
13 changes: 7 additions & 6 deletions src/Storage/Commands.Storage/Commands.Storage.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,12 @@
</Reference>
<Reference Include="Microsoft.WindowsAzure.Configuration, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.WindowsAzure.ConfigurationManager.1.8.0.0\lib\net35-full\Microsoft.WindowsAzure.Configuration.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.WindowsAzure.Storage, Version=8.4.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\WindowsAzure.Storage.8.4.0\lib\net45\Microsoft.WindowsAzure.Storage.dll</HintPath>
<Reference Include="Microsoft.WindowsAzure.Storage, Version=8.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\WindowsAzure.Storage.8.5.0\lib\net45\Microsoft.WindowsAzure.Storage.dll</HintPath>
</Reference>
<Reference Include="Microsoft.WindowsAzure.Storage.DataMovement, Version=0.6.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.Storage.DataMovement.0.6.1\lib\net45\Microsoft.WindowsAzure.Storage.DataMovement.dll</HintPath>
<Reference Include="Microsoft.WindowsAzure.Storage.DataMovement, Version=0.6.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.Storage.DataMovement.0.6.3\lib\net45\Microsoft.WindowsAzure.Storage.DataMovement.dll</HintPath>
</Reference>
<Reference Include="System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
Expand Down Expand Up @@ -242,7 +241,9 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="MSSharedLibKey.snk" />
<None Include="packages.config" />
<None Include="packages.config">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources.resx">
Expand Down
6 changes: 3 additions & 3 deletions src/Storage/Commands.Storage/Common/StorageExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ internal static Uri GenerateUriWithCredentials(

if (string.IsNullOrEmpty(sasToken))
{
return file.Uri;
return file.SnapshotQualifiedUri;
}
else
{
return new Uri(string.Format(CultureInfo.InvariantCulture, "{0}{1}", file.Uri.AbsoluteUri, sasToken));
return new Uri(string.Format(CultureInfo.InvariantCulture, "{0}{1}", file.SnapshotQualifiedUri.AbsoluteUri, sasToken));
}
}

Expand All @@ -57,7 +57,7 @@ internal static CloudFile GenerateCopySourceFile(
return file;
}

return new CloudFile(file.Uri, new StorageCredentials(sasToken));
return new CloudFile(file.SnapshotQualifiedUri, new StorageCredentials(sasToken));
}

private static string GetFileSASToken(CloudFile file)
Expand Down
2 changes: 1 addition & 1 deletion src/Storage/Commands.Storage/Common/Util.cs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ public static string ConvertToString(this object instance)

if (null != file)
{
return file.Uri.AbsoluteUri;
return file.SnapshotQualifiedUri.AbsoluteUri;
}

return instance.ToString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ protected async Task MonitorFileCopyStatusAsync(long taskId)

if (file.CopyState == null)
{
ArgumentException e = new ArgumentException(String.Format(Resources.FileCopyTaskNotFound, file.Uri.ToString()));
ArgumentException e = new ArgumentException(String.Format(Resources.FileCopyTaskNotFound, file.SnapshotQualifiedUri.ToString()));
OutputStream.WriteError(internalTaskId, e);
Interlocked.Increment(ref InternalFailedCount);
taskDone = true;
Expand Down
13 changes: 11 additions & 2 deletions src/Storage/Commands.Storage/File/Cmdlet/GetAzureStorageShare.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ namespace Microsoft.WindowsAzure.Commands.Storage.File.Cmdlet
using Azure.Commands.Common.Authentication.Abstractions;
using Microsoft.WindowsAzure.Commands.Common.Storage;
using Microsoft.WindowsAzure.Storage.File;
using System;
using System.Globalization;
using System.Management.Automation;

Expand All @@ -28,7 +29,7 @@ public class GetAzureStorageShare : AzureStorageFileCmdletBase
Position = 0,
Mandatory = true,
ParameterSetName = Constants.SpecificParameterSetName,
HelpMessage = "Name of the file share to be listed.")]
HelpMessage = "Name of the file share to be received.")]
[ValidateNotNullOrEmpty]
public string Name { get; set; }

Expand All @@ -38,6 +39,14 @@ public class GetAzureStorageShare : AzureStorageFileCmdletBase
HelpMessage = "A prefix of the file shares to be listed.")]
public string Prefix { get; set; }

[Parameter(
Position = 1,
Mandatory = false,
ParameterSetName = Constants.SpecificParameterSetName,
HelpMessage = "SnapshotTime of the file share snapshot to be received.")]
[ValidateNotNullOrEmpty]
public DateTimeOffset? SnapshotTime { get; set; }

[Parameter(
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Expand All @@ -58,7 +67,7 @@ public override void ExecuteCmdlet()
{
case Constants.SpecificParameterSetName:
NamingUtil.ValidateShareName(this.Name, false);
var share = this.Channel.GetShareReference(this.Name);
var share = this.Channel.GetShareReference(this.Name, this.SnapshotTime);
await this.Channel.FetchShareAttributesAsync(share, null, this.RequestOptions, this.OperationContext, this.CmdletCancellationToken).ConfigureAwait(false);
this.OutputStream.WriteObject(taskId, share);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ public override void ExecuteCmdlet()

if (FullUri)
{
string fullUri = SasTokenHelper.GetFullUriWithSASToken(file.Uri.AbsoluteUri.ToString(), sasToken);
string fullUri = SasTokenHelper.GetFullUriWithSASToken(file.SnapshotQualifiedUri.AbsoluteUri.ToString(), sasToken);

WriteObject(fullUri);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ public override void ExecuteCmdlet()

if (FullUri)
{
string fullUri = SasTokenHelper.GetFullUriWithSASToken(fileShare.Uri.AbsoluteUri.ToString(), sasToken);
string fullUri = SasTokenHelper.GetFullUriWithSASToken(fileShare.SnapshotQualifiedUri.AbsoluteUri.ToString(), sasToken);

WriteObject(fullUri);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

namespace Microsoft.WindowsAzure.Commands.Storage.File.Cmdlet
{
using Microsoft.WindowsAzure.Commands.Storage.Common;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.File;
using System.Globalization;
using System.Management.Automation;
Expand Down Expand Up @@ -44,7 +46,10 @@ public class RemoveAzureStorageShare : AzureStorageFileCmdletBase
[ValidateNotNull]
public CloudFileShare Share { get; set; }

[Parameter(HelpMessage = "Force to remove the share and all content in it")]
[Parameter(HelpMessage = "Remove File Share with all of its snapshots")]
public SwitchParameter IncludeAllSnapshot { get; set; }

[Parameter(HelpMessage = "Force to remove the share with all its snapshots, and all content in them.")]
public SwitchParameter Force
{
get { return force; }
Expand All @@ -56,6 +61,15 @@ public SwitchParameter Force

private bool force;

/// <summary>
/// Cmdlet begin processing
/// </summary>
protected override void BeginProcessing()
{
base.BeginProcessing();
OutputStream.ConfirmWriter = (s1, s2, s3) => ShouldContinue(s2, s3);
}

public override void ExecuteCmdlet()
{
CloudFileShare share;
Expand All @@ -77,9 +91,54 @@ public override void ExecuteCmdlet()
{
this.RunTask(async taskId =>
{
if (share.IsSnapshot && IncludeAllSnapshot.IsPresent)
{
throw new PSArgumentException(string.Format(CultureInfo.InvariantCulture, "'IncludeAllSnapshot' should only be specified to delete a base share, and should not be specified to delete a Share snapshot: {0}", share.SnapshotQualifiedUri));
}

if (force || ShareIsEmpty(share) || ShouldContinue(string.Format("Remove share and all content in it: {0}", share.Name), ""))
{
await this.Channel.DeleteShareAsync(share, null, this.RequestOptions, this.OperationContext, this.CmdletCancellationToken).ConfigureAwait(false);
DeleteShareSnapshotsOption deleteShareSnapshotsOption = DeleteShareSnapshotsOption.None;
bool retryDeleteSnapshot = false;

//Force means will delete the share anyway, so use 'IncludeSnapshots' to delete the share even has snapshot, or delete will fail when share has snapshot
// To delete a Share shapshot, must use 'None'
if (IncludeAllSnapshot.IsPresent)
{
deleteShareSnapshotsOption = DeleteShareSnapshotsOption.IncludeSnapshots;
}
else
{
retryDeleteSnapshot = true;
}

try
{
await this.Channel.DeleteShareAsync(share, deleteShareSnapshotsOption, null, this.RequestOptions, this.OperationContext, this.CmdletCancellationToken).ConfigureAwait(false);
retryDeleteSnapshot = false;
}
catch (StorageException e)
{
//If x-ms-delete-snapshots is not specified on the request and the share has associated snapshots, the File service returns status code 409 (Conflict).
if (!(e.IsConflictException() && retryDeleteSnapshot))
Copy link
Contributor

@maddieclayton maddieclayton Oct 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there ever a case where DeleteShareAsync will throw a conflictexception when the deleteShareSnapshotsOption is set to IncludeSnapshots? I'm just curious about whether you need to check if retryDeleteSnapshot is true.

Copy link
Member Author

@blueww blueww Oct 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are cases to throw 419 (conflict) error when the share is being deleted, and try to delete again.

So we need to check the retryDeleteSnapshot is set and the error is 419 error (try to delete a share with snapshot without IncludSnapshot flag will get 419 error). This the best we can do.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, sounds good.

{
throw;
}
}

if (retryDeleteSnapshot)
{
if (force || await OutputStream.ConfirmAsync(string.Format("This share might have snapshots, remove the share and all snapshots?: {0}", share.Name)).ConfigureAwait(false))
{
deleteShareSnapshotsOption = DeleteShareSnapshotsOption.IncludeSnapshots;
await this.Channel.DeleteShareAsync(share, deleteShareSnapshotsOption, null, this.RequestOptions, this.OperationContext, this.CmdletCancellationToken).ConfigureAwait(false);
}
else
{
string result = string.Format("The remove operation of share '{0}' has been cancelled.", share.Name);
OutputStream.WriteVerbose(taskId, result);
}
}
}

if (this.PassThru)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ private void StartCopyFromBlob()
Func<long, Task> taskGenerator = (taskId) => StartAsyncCopy(
taskId,
destFile,
() => this.ConfirmOverwrite(blob.SnapshotQualifiedUri.ToString(), destFile.Uri.ToString()),
() => this.ConfirmOverwrite(blob.SnapshotQualifiedUri.ToString(), destFile.SnapshotQualifiedUri.ToString()),
() => destFile.StartCopyAsync(blob.GenerateCopySourceBlob(), null, null, this.RequestOptions, this.OperationContext, CmdletCancellationToken));

this.RunTask(taskGenerator);
Expand Down Expand Up @@ -321,7 +321,7 @@ private void StartCopyFromFile()
Func<long, Task> taskGenerator = (taskId) => StartAsyncCopy(
taskId,
destFile,
() => this.ConfirmOverwrite(sourceFile.Uri.ToString(), destFile.Uri.ToString()),
() => this.ConfirmOverwrite(sourceFile.SnapshotQualifiedUri.ToString(), destFile.SnapshotQualifiedUri.ToString()),
() => destFile.StartCopyAsync(sourceFile.GenerateCopySourceFile(), null, null, this.RequestOptions, this.OperationContext, this.CmdletCancellationToken));

this.RunTask(taskGenerator);
Expand All @@ -334,7 +334,7 @@ private void StartCopyFromUri()
Func<long, Task> taskGenerator = (taskId) => StartAsyncCopy(
taskId,
destFile,
() => this.ConfirmOverwrite(this.AbsoluteUri, destFile.Uri.ToString()),
() => this.ConfirmOverwrite(this.AbsoluteUri, destFile.SnapshotQualifiedUri.ToString()),
() => destFile.StartCopyAsync(new Uri(this.AbsoluteUri), null, null, this.RequestOptions, this.OperationContext));

this.RunTask(taskGenerator);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ private async Task StopCopyFile(long taskId, IStorageFileManagement localChannel

if (file.CopyState == null || string.IsNullOrEmpty(file.CopyState.CopyId))
{
ArgumentException e = new ArgumentException(String.Format(Resources.FileCopyTaskNotFound, file.Uri.ToString()));
ArgumentException e = new ArgumentException(String.Format(Resources.FileCopyTaskNotFound, file.SnapshotQualifiedUri.ToString()));
OutputStream.WriteError(taskId, e);
}
else
Expand All @@ -109,10 +109,10 @@ private async Task StopCopyFile(long taskId, IStorageFileManagement localChannel

if (!Force)
{
string confirmation = String.Format(Resources.ConfirmAbortFileCopyOperation, file.Uri.ToString(), abortCopyId);
string confirmation = String.Format(Resources.ConfirmAbortFileCopyOperation, file.SnapshotQualifiedUri.ToString(), abortCopyId);
if (!await OutputStream.ConfirmAsync(confirmation).ConfigureAwait(false))
{
string cancelMessage = String.Format(Resources.StopCopyOperationCancelled, file.Uri.ToString());
string cancelMessage = String.Format(Resources.StopCopyOperationCancelled, file.SnapshotQualifiedUri.ToString());
OutputStream.WriteVerbose(taskId, cancelMessage);
}
}
Expand All @@ -123,7 +123,7 @@ private async Task StopCopyFile(long taskId, IStorageFileManagement localChannel
}

await localChannel.AbortCopyAsync(file, abortCopyId, null, requestOptions, OperationContext, CmdletCancellationToken).ConfigureAwait(false);
string message = String.Format(Resources.StopCopyFileSuccessfully, file.Uri.ToString());
string message = String.Format(Resources.StopCopyFileSuccessfully, file.SnapshotQualifiedUri.ToString());
OutputStream.WriteObject(taskId, message);
}
}
Expand Down
Loading