Skip to content
This repository was archived by the owner on Apr 28, 2018. It is now read-only.

Adding -Id and -Name params to Get-Container #85

Merged
merged 1 commit into from
Jun 8, 2016
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
2 changes: 1 addition & 1 deletion src/Docker.DotNet
31 changes: 23 additions & 8 deletions src/Docker.PowerShell/Cmdlets/ContainerArgumentCompleter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Management.Automation.Language;
using System.Linq;
using Docker.DotNet.Models;
using Docker.PowerShell.Objects;
using System;

public class ContainerArgumentCompleter : IArgumentCompleter
Expand All @@ -15,19 +16,32 @@ public IEnumerable<CompletionResult> CompleteArgument(string commandName,
IDictionary fakeBoundParameters)
{
var client = DockerFactory.CreateClient(fakeBoundParameters);

var task = client.Containers.ListContainersAsync(new ContainersListParameters
IList<ContainerListResponse> result;

if (wordToComplete == "")
{
All = true
});

task.Wait();
result = client.Containers.ListContainersAsync(new ContainersListParameters
{
All = true
}).Result;
}
else
{
result = ContainerOperations.GetContainersById(wordToComplete, client).Result;
result = result.Concat(ContainerOperations.GetContainersByName(wordToComplete, client).Result).ToList();
}

return task.Result.SelectMany(container =>
return result.SelectMany(container =>
{
// If the user has already typed part of the name, then include IDs that start
// with that portion. Otherwise, just let the user tab through the names.
if (wordToComplete == "")

// Special handling for Get-Container, where Id an Name are separate parameters.
if (commandName == "Get-Container" && parameterName == "Id")
{
return new List<string> {container.ID};
}
else if (wordToComplete == "" || parameterName == "Name")
{
return container.Names;
}
Expand All @@ -37,6 +51,7 @@ public IEnumerable<CompletionResult> CompleteArgument(string commandName,
}
})
.Select(name => name.StartsWith("/") && !wordToComplete.StartsWith("/") ? name.Substring(1) : name)
.Distinct()
.Where(name => name.StartsWith(wordToComplete, StringComparison.CurrentCultureIgnoreCase))
.OrderBy(name => name)
.Select(name => new CompletionResult(name, name, CompletionResultType.Text, name));
Expand Down
1 change: 1 addition & 0 deletions src/Docker.PowerShell/Cmdlets/DkrCmdlet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ internal class CommonParameterSetNames
{
public const string Default = "Default";
public const string ContainerObject = "ContainerObject";
public const string ContainerName = "ContainerName";
public const string ImageObject = "ImageObject";
public const string ConfigObject = "ConfigObject";
}
Expand Down
41 changes: 36 additions & 5 deletions src/Docker.PowerShell/Cmdlets/GetContainer.cs
Original file line number Diff line number Diff line change
@@ -1,25 +1,56 @@
using System.Management.Automation;
using Docker.DotNet.Models;
using System.Threading.Tasks;
using Docker.PowerShell.Objects;

namespace Docker.PowerShell.Cmdlets
{
[Cmdlet(VerbsCommon.Get, "Container",
DefaultParameterSetName = CommonParameterSetNames.Default)]
DefaultParameterSetName = CommonParameterSetNames.ContainerName)]
[OutputType(typeof(ContainerListResponse))]
public class GetContainer : DkrCmdlet
{
[Parameter(ParameterSetName = CommonParameterSetNames.Default,
ValueFromPipeline = true,
Position = 0)]
[ValidateNotNullOrEmpty]
[ArgumentCompleter(typeof(ContainerArgumentCompleter))]
public string[] Id { get; set; }

[Parameter(ParameterSetName = CommonParameterSetNames.ContainerName,
ValueFromPipeline = true,
Position = 0)]
[ValidateNotNullOrEmpty]
[ArgumentCompleter(typeof(ContainerArgumentCompleter))]
public string[] Name { get; set; }

#region Overrides
/// <summary>
/// Outputs container objects for each container matching the provided parameters.
/// </summary>
protected override async Task ProcessRecordAsync()
{
foreach (var c in await DkrClient.Containers.ListContainersAsync(
new ContainersListParameters() { All = true }))
{
if (Id != null)
{
foreach (var id in Id)
{
WriteObject(await ContainerOperations.GetContainersById(id, DkrClient));
Copy link
Contributor

Choose a reason for hiding this comment

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

What happens in the pipeline if we dont get back a value?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think this is safe; the underlying function returns an array that happens to be empty, as we discussed offline.

}
}
else if (Name != null)
{
foreach (var name in Name)
{
WriteObject(await ContainerOperations.GetContainersByName(name, DkrClient));
}
}
else
{
WriteObject(c);
foreach (var c in await DkrClient.Containers.ListContainersAsync(
new ContainersListParameters() { All = true }))
{
WriteObject(c);
}
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/Docker.PowerShell/Cmdlets/InvokeContainerImage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Docker.PowerShell.Objects;
using Docker.DotNet.Models;
using System.Threading.Tasks;
using System.Linq;

namespace Docker.PowerShell.Cmdlets
{
Expand Down Expand Up @@ -77,7 +78,7 @@ await DkrClient.Containers.RemoveContainerAsync(createResult.ID,
}
else if (PassThru.ToBool())
{
WriteObject(await ContainerOperations.GetContainerById(createResult.ID, DkrClient));
WriteObject((await ContainerOperations.GetContainersById(createResult.ID, DkrClient)).Single());
Copy link
Contributor

Choose a reason for hiding this comment

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

.Single() will return a pretty odd error if it either isnt found or has more than 1. Should we throw a better error?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's a good point... I'll work on something for this as part of #20 rather than fix it as part of this change, since it's consistent with what we were doing before.

}
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/Docker.PowerShell/Cmdlets/NewContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Docker.PowerShell.Objects;
using Docker.DotNet.Models;
using System.Threading.Tasks;
using System.Linq;

namespace Docker.PowerShell.Cmdlets
{
Expand Down Expand Up @@ -38,7 +39,7 @@ protected override async Task ProcessRecordAsync()

if (!String.IsNullOrEmpty(createResult.ID))
{
WriteObject(await ContainerOperations.GetContainerById(createResult.ID, DkrClient));
WriteObject((await ContainerOperations.GetContainersById(createResult.ID, DkrClient)).Single());
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Docker.PowerShell/Cmdlets/StartContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ protected override async Task ProcessRecordAsync()

if (PassThru.ToBool())
{
WriteObject(await ContainerOperations.GetContainerById(id, DkrClient));
WriteObject(await ContainerOperations.GetContainerByIdOrName(id, DkrClient));
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Docker.PowerShell/Cmdlets/StopContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ await DkrClient.Containers.KillContainerAsync(

if (PassThru.ToBool())
{
WriteObject(await ContainerOperations.GetContainerById(id, DkrClient));
WriteObject(await ContainerOperations.GetContainerByIdOrName(id, DkrClient));
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Docker.PowerShell/Cmdlets/WaitContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ protected override async Task ProcessRecordAsync()

if (PassThru.ToBool())
{
WriteObject(await ContainerOperations.GetContainerById(id, DkrClient));
WriteObject(await ContainerOperations.GetContainerByIdOrName(id, DkrClient));
}
}
}
Expand Down
41 changes: 36 additions & 5 deletions src/Docker.PowerShell/Objects/ContainerOperations.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Linq;
using Docker.PowerShell.Cmdlets;
using System.Collections.Generic;

namespace Docker.PowerShell.Objects
{
Expand Down Expand Up @@ -73,18 +74,48 @@ internal static Task<CreateContainerResponse> CreateContainer(
HostConfig = hostConfiguration
});
}

internal static Task<IList<ContainerListResponse>> GetContainersById(string id, DotNet.DockerClient dkrClient)
{
return (dkrClient.Containers.ListContainersAsync(new ContainersListParameters
{
All = true,
Filters = new Dictionary<string, IDictionary<string, bool>>
{
{"id", new Dictionary<string, bool>
{
{id, true}
}
}
}
}));
}

internal static Task<IList<ContainerListResponse>> GetContainersByName(string name, DotNet.DockerClient dkrClient)
{
return (dkrClient.Containers.ListContainersAsync(new ContainersListParameters
{
All = true,
Filters = new Dictionary<string, IDictionary<string, bool>>
{
{"name", new Dictionary<string, bool>
{
{name, true}
}
}
}
}));
}

/// <summary>
/// Gets a single container object from the client by id.
/// Gets a single container object from the client by id or name.
/// </summary>
/// <param name="id">The container identifier to retrieve.</param>
/// <param name="dkrClient">The client to request the container from.</param>
/// <returns>The single container object matching the id.</returns>
internal static async Task<ContainerListResponse> GetContainerById(string id, DotNet.DockerClient dkrClient)
internal static async Task<ContainerListResponse> GetContainerByIdOrName(string id, DotNet.DockerClient dkrClient)
{
// TODO - Have a better way to get the container list response given the ID.
return (await dkrClient.Containers.ListContainersAsync(new ContainersListParameters() { All = true })).
Single(c => c.ID.StartsWith(id) || c.Names.Any(n => n.Equals("/" + id)));
return (await GetContainersByName(id, dkrClient)).Where(c => c.Names.Contains($"/{id}")).Concat(await GetContainersById(id, dkrClient)).Single();
}

/// <summary>
Expand Down