Пример #1
0
        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();
        }
Пример #2
0
 public DockerContainerResult(
     ContainerListResponse containerListResponse,
     ContainerInspectResponse containerInspectResponse)
 {
     ContainerListResponse    = containerListResponse;
     ContainerInspectResponse = containerInspectResponse;
 }
Пример #3
0
 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);
        }
Пример #5
0
        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());
        }
Пример #6
0
        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);
            }
        }
Пример #7
0
        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();
        }
Пример #8
0
        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);
            }
        }
Пример #9
0
        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);
            }
        }
Пример #10
0
        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");
                }
            }
        }
Пример #11
0
        /// <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");
        }
Пример #12
0
        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;
            }
        }
Пример #15
0
        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);
        }
Пример #16
0
        internal static T GetLabel <T>(this ContainerListResponse container, string label, T @default = default)
        {
            if (!TryGetLabel(container, label, out T val))
            {
                return(@default);
            }

            return(val);
        }
Пример #17
0
        /// <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;
            }
        }
Пример #19
0
        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);
        }
Пример #20
0
        /// <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));
        }
Пример #21
0
        public static IEnumerable <ExposedService> GetExposedServicesFromContainer(ContainerListResponse container)
        {
            var exposedPorts = GetExposedServiceLabelValue(container);

            if (string.IsNullOrWhiteSpace(exposedPorts))
            {
                return(GetAllExposedPorts(container));
            }

            return(ParseExposedLabelValue(exposedPorts, container));
        }
Пример #22
0
        private static async Task RemoveContainer(ContainerListResponse container)
        {
            var removeOptions = new ContainerRemoveParameters
            {
                Force         = true,
                RemoveVolumes = true
            };

            await _client.Containers
            .RemoveContainerAsync(container.ID, removeOptions);
        }
Пример #23
0
        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);
        }
Пример #24
0
        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
     });
 }
Пример #26
0
        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);
        }
Пример #27
0
        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);
        }
Пример #28
0
        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();
            }
        }
Пример #29
0
        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);
        }
Пример #30
0
 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()
         {
         });
     }
 }