public async void CreateContainerAndWaitBeforeItStartedTest() { var mongoDbImageName = "mongo"; var mongoDbImageTag = "4.0"; var mongodDbImage = $"{mongoDbImageName}:{mongoDbImageTag}"; var mongoDbContainerName = "mongo-tests"; var exposedPort = $"27017/tcp"; DockerClient client = new DockerClientConfiguration(new Uri("npipe://./pipe/docker_engine")) .CreateClient(); await CreateImageIfNotExist(client, mongoDbImageName, mongoDbImageTag); await RemoveContainerIfExist(client, "mongo-tests"); // docker run --name mongo-tests -p 33381:27017 -d mongo:4; var containerId = await RunContainer(client, mongodDbImage, mongoDbContainerName, exposedPort, "33381"); await WaitBeforeContainerInit(client, containerId, "waiting for connections on port 27017"); ContainerListResponse container = await GetContainerByName(client, mongoDbContainerName); Assert.NotNull(container); await RemoveContainerIfExist(client, "mongo-tests"); client.Dispose(); }
public DockerContainerResult( ContainerListResponse containerListResponse, ContainerInspectResponse containerInspectResponse) { ContainerListResponse = containerListResponse; ContainerInspectResponse = containerInspectResponse; }
public static ContainerBackupFields Create(ContainerListResponse container) { return(new ContainerBackupFields( project: container.Labels.FirstOrDefault(x => x.Key.ToLower() == "project").Value, role: container.Labels.FirstOrDefault(x => x.Key.ToLower() == "role").Value )); }
public void ShouldReturnLabelPortsWhenLabelHasMultipleValues() { var response = new ContainerListResponse { ID = "test", Labels = new Dictionary <string, string> { [ExposedServiceLabelParser.ExposedServiceLabel] = "22, 20 , 30" }, Ports = new List <Port> { new Port { IP = "127.0.0.1", PrivatePort = 20, PublicPort = 80 }, new Port { IP = "127.0.0.1", PrivatePort = 21, PublicPort = 81 } } }; var exposedServices = ExposedServiceLabelParser.GetExposedServicesFromContainer(response).ToList(); exposedServices.Count.Should().Be(3); exposedServices[0].ContainerId.Should().Be("test"); exposedServices[0].Port.Should().Be(22); exposedServices[1].ContainerId.Should().Be("test"); exposedServices[1].Port.Should().Be(20); exposedServices[2].ContainerId.Should().Be("test"); exposedServices[2].Port.Should().Be(30); }
public ContainerViewModel(DockerService docker, ContainerListResponse container) { _docker = docker; ID = container.ID; Name = container.Names[0]; ImageName = container.Image; void UpdateContainerDetails() => Task.Run(async() => { var d = await docker.Client.Containers.InspectContainerAsync(ID); IsStarted = d.State.Running; IsRemovable = !IsStarted || !d.HostConfig.AutoRemove; string FormatHostPort(PortBinding b) => $"{b.HostIP}:{b.HostPort}".Replace("0.0.0.0", docker.Name); PublicPorts = d.NetworkSettings.Ports.Values .SelectMany(bs => bs.Select(FormatHostPort)) .ToArray(); }); UpdateContainerDetails(); docker.Events .Where(e => e.Type == DockerEventType.Container && e.Subject == ID) .Subscribe(e => UpdateContainerDetails()); }
public static async Task <bool> StopAndRemoveContainer(string containerName) { try { ContainerListResponse container = await GetContainer(containerName); if (container == null) { return(false); } bool success = await StopContainer(container); if (success) { await RemoveContainer(container); } return(success); } catch { // Should not fail tests if cannot stop container. return(false); } }
public async void CreateContainerTest() { var mongoDbImageName = "mongo"; var mongoDbImageTag = "4.0"; var mongodDbImage = $"{mongoDbImageName}:{mongoDbImageTag}"; var mongoDbContainerName = "mongo-tests"; var exposedPort = "27017/tcp"; var hostPort = "33381"; DockerClient docker = new DockerClientConfiguration(new Uri("npipe://./pipe/docker_engine")) .CreateClient(); await docker.CreateImageIfNotExist(mongoDbImageName, mongoDbImageTag); await docker.RemoveContainerIfExist(mongoDbContainerName); // docker run --name mongo-tests -p 33381:27017 -d mongo:4; var containerId = await docker.RunContainer(mongodDbImage, mongoDbContainerName, exposedPort, hostPort); await docker.WaitBeforeContainerInit(containerId); ContainerListResponse container = await docker.GetContainerByName(mongoDbContainerName); Assert.NotNull(container); await docker.RemoveContainerIfExist(mongoDbContainerName); docker.Dispose(); }
public static Status GetStatus(this ContainerListResponse container) { if (container is null) { throw new ArgumentNullException(nameof(container)); } switch (container.State) { case "created": return(Status.None); case "restarting": return(Status.None); case "running": return(Status.OK); case "paused": return(Status.Paused); case "exited": return(Status.Stopped); case "removing": return(Status.Unknown); case "dead": return(Status.Unknown); default: return(Status.Unknown); } }
private async Task Run(ContainerListResponse c) { var replaceRunning = DetermineReplaceRunning(c); if (!IsStopped(c.State)) { logger.Warning("Container not in stopped state {ImageName} [{ContainerId}] - ReplaceRunning is set to {ReplaceRunning}", c.Image, c.ID, replaceRunning); if (replaceRunning) { await dockerClient.Containers.StopContainerAsync(c.ID, null); } else { return; } } logger.Information("Running container {ImageName} [{ContainerId}]", c.Image, c.ID); try { await dockerClient.Containers.StartContainerAsync(c.ID, null); } catch (Exception ex) { logger.Error(ex, "Failed to run container {ImageName} [{ContainerId}]", c.Image, c.ID); } }
public static async Task EnsureKilledAndRemoved(string dockerApiUrl, string containerName) { using (var client = new DockerClientConfiguration(new Uri(dockerApiUrl)).CreateClient()) { var containersListParameters = new ContainersListParameters { All = true, Filters = new Dictionary <string, IDictionary <string, bool> > { { "name", new Dictionary <string, bool> { { "^/" + containerName + "$", true }, } } }, }; ContainerListResponse container = (await client.Containers.ListContainersAsync(containersListParameters)).FirstOrDefault(); if (container != null) { if (container.State == "running") { Logger.Info($"Killing container {container.ID}"); await client.Containers.KillContainerAsync(container.ID, new ContainerKillParameters()); Logger.Info($"Container {container.ID} killed"); } Logger.Info($"Removing container {container.ID}"); await client.Containers.RemoveContainerAsync(container.ID, new ContainerRemoveParameters()); Logger.Info($"Container {container.ID} removed"); } } }
/// <summary> /// Check if a container is running. /// </summary> /// <param name="id">ID of the container to be checked.</param> private async Task <bool> IsRunning(string id) { IDictionary <string, bool> idFilter = new Dictionary <string, bool>() { { id, true } }; Dictionary <string, IDictionary <string, bool> > filters = new Dictionary <string, IDictionary <string, bool> >() { { "id", idFilter } }; ContainersListParameters parameters = new ContainersListParameters() { All = true, Filters = filters }; IList <ContainerListResponse> containers = await client.Containers.ListContainersAsync(parameters); // If it doesn't exist it's not running. if (containers.Count < 1) { return(false); } // todo: could we ever have >1 container matching these filters? ContainerListResponse response = containers[0]; return(response.State == "running"); }
public async Task StartAsync() { await this.Create(); await this.Start(); this.container = await DockerApiClientContainer.Instance.ByIdAsync(this.Id); }
public async Task StartAsync() { await this.Create(); await this.Start(); this.container = await MetaDataClientContainers.Instance.ByIdAsync(this.Id); }
private async Task Stop() { if (this.HasId) { await TestcontainersClient.Instance.StopAsync(this.Id); this.container = null; } }
public static string GetName(this ContainerListResponse container) { if (container is null) { throw new ArgumentNullException(nameof(container)); } return(container.Names?.Count > 0 ? container.Names[0].Remove(0, 1) : container.ID); }
internal static T GetLabel <T>(this ContainerListResponse container, string label, T @default = default) { if (!TryGetLabel(container, label, out T val)) { return(@default); } return(val); }
/// <summary> /// Convert a <see cref="ContainerListResponse">container listing</see> to a <see cref="Deployment"/>. /// </summary> /// <param name="containerListing"> /// The <see cref="ContainerListResponse">container listing</see> to convert. /// </param> /// <returns> /// The converted <see cref="Deployment"/>. /// </returns> Deployment ToDeploymentModel(ContainerListResponse containerListing) { if (containerListing == null) { throw new ArgumentNullException(nameof(containerListing)); } string deploymentId = containerListing.Labels["deployment.id"]; DirectoryInfo deploymentStateDirectory = GetLocalStateDirectory(deploymentId); Deployment deployment = new Deployment { Id = deploymentId, ContainerId = containerListing.ID, Action = containerListing.Labels["deployment.action"] }; switch (containerListing.State) { case "running": { deployment.State = DeploymentState.Running; break; } case "exited": { if (containerListing.Status != null && containerListing.Status.StartsWith("Exited (0)")) { deployment.State = DeploymentState.Successful; } else { deployment.State = DeploymentState.Failed; } deployment.Logs.AddRange( ReadDeploymentLogs(deploymentStateDirectory) ); deployment.Outputs = ReadOutputs(deploymentStateDirectory); break; } default: { Log.LogInformation("Unexpected container state '{State}'.", containerListing.State); deployment.State = DeploymentState.Unknown; break; } } return(deployment); }
private async Task CleanUp() { if (this.HasId) { await TestcontainersClient.Instance.RemoveAsync(this.Id); this.container = null; this.id = null; } }
private static async Task <ContainerListResponse> GetContainer(string containerName) { IList <ContainerListResponse> containers = await GetAllContainers(); ContainerListResponse container = containers .SingleOrDefault(c => c.Names.Select(n => n.Trim('/')) .Any(n => n == containerName)); return(container); }
/// <summary> /// If the container has a name assigned, it is used. /// Otherwise, the first 12 characters of the ID are used. /// </summary> private static string GetDisplayName(ContainerListResponse container) { var name = container.Names.FirstOrDefault(); if (!string.IsNullOrWhiteSpace(name)) { return(name.Trim('/')); } return(container.ID.Substring(0, 12)); }
public static IEnumerable <ExposedService> GetExposedServicesFromContainer(ContainerListResponse container) { var exposedPorts = GetExposedServiceLabelValue(container); if (string.IsNullOrWhiteSpace(exposedPorts)) { return(GetAllExposedPorts(container)); } return(ParseExposedLabelValue(exposedPorts, container)); }
private static async Task RemoveContainer(ContainerListResponse container) { var removeOptions = new ContainerRemoveParameters { Force = true, RemoveVolumes = true }; await _client.Containers .RemoveContainerAsync(container.ID, removeOptions); }
internal static bool TryGetLabel <T>(this ContainerListResponse container, string label, out T value) { if (!container.Labels.TryGetValue(label, out var val)) { value = default; return(false); } value = (T)Convert.ChangeType(val, typeof(T)); return(true); }
public static async Task RemoveContainerIfExist(this DockerClient client, string name) { ContainerListResponse container = await GetContainerByName(client, name); if (container != null) { await client.Containers.RemoveContainerAsync(container.ID, new ContainerRemoveParameters() { Force = true }); } }
public static TunnelInformationDto MapContainerResponse(ContainerListResponse containerResponse) { return(new TunnelInformationDto { ID = containerResponse.ID, Name = containerResponse.Names.FirstOrDefault()?.Remove(0, 1), Host = containerResponse.Labels["Host"] ?? "Unknown", Target = containerResponse.Labels["Target"] ?? "Unknown", // ToDo: get the status of the tunnel instead of the container Status = containerResponse.State }); }
private static async Task <bool> StopContainer(ContainerListResponse container) { var stopOptions = new ContainerStopParameters { WaitBeforeKillSeconds = 5 }; bool stopped = await _client.Containers .StopContainerAsync(container.ID, stopOptions, CancellationToken.None); return(stopped); }
private async Task <ContainerListResponse> container() { var results = await client.Containers.ListContainersAsync(this.containerListParams, this.cancelTokenSource.Token); ContainerListResponse result = null; try { result = results.First(); } catch (InvalidOperationException) { } return(result); }
public async Task CleanUpAsync(CancellationToken ct = default) { await new SynchronizationContextRemover(); await this.semaphoreSlim.WaitAsync(ct); try { this.container = await this.CleanUp(this.Id, ct); } finally { this.semaphoreSlim.Release(); } }
private IList <FileSystemWatcher> CreateWatchersForContainer(ContainerListResponse container) { var watchers = new List <FileSystemWatcher>(); var id = container.ID; var name = container.Names .Select(n => n.Substring(1)) .FirstOrDefault(); foreach (var mount in container.Mounts) { var source = mount.Source; var destination = mount.Destination; if (string.IsNullOrWhiteSpace(source) || string.IsNullOrWhiteSpace(destination)) { continue; } try { #if !NETFULL if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) #endif { if (source.StartsWith("/host_mnt/")) { source = $"{source.Substring(10, 1)}:{source.Substring(11)}"; } else { source = $"{source.Substring(1, 1)}:{source.Substring(2)}"; } } if (Directory.Exists(source)) { source = $"{source}/"; destination = $"{destination}/"; watchers.Add(new FileSystemWatcher(id, name, source, destination)); } } catch (Exception e) { Logger.Write($"Failed mapping {mount.Source} to {mount.Destination}"); } } return(watchers); }
public async Task StopOrStartContainerAsync(ContainerListResponse container) { if (container.State.Equals("running")) { await _dockerProvider.Containers.KillContainerAsync(container.ID, new ContainerKillParameters() { }); } else { await _dockerProvider.Containers.StartContainerAsync(container.ID, new ContainerStartParameters() { }); } }