private static async Task <bool> ResolveHostPort(IImageSettings settings) { ContainerInspectResponse inspectResponse = await _client .Containers .InspectContainerAsync(settings.ContainerId); if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { string containerPort = $"{settings.ContainerPort}/tcp"; if (!inspectResponse.NetworkSettings.Ports.ContainsKey(containerPort)) { throw new Exception($"Failed to resolve host port for {containerPort}"); } PortBinding binding = inspectResponse .NetworkSettings .Ports[containerPort] .FirstOrDefault(); if (binding == null || string.IsNullOrEmpty(binding.HostPort)) { throw new Exception($"The resolved port binding is empty"); } settings.HostPort = long.Parse(binding.HostPort); } else { settings.HostPort = settings.ContainerPort; } return(inspectResponse.State.Running); }
public DockerContainerResult( ContainerListResponse containerListResponse, ContainerInspectResponse containerInspectResponse) { ContainerListResponse = containerListResponse; ContainerInspectResponse = containerInspectResponse; }
public async Task RemoveContainerAsync_ContainerExists_Succeedes() { var createContainerResponse = await _dockerClient.Containers.CreateContainerAsync( new CreateContainerParameters() { Image = _imageId, Name = Guid.NewGuid().ToString() }, _cts.Token ); ContainerInspectResponse inspectCreatedContainer = await _dockerClient.Containers.InspectContainerAsync( createContainerResponse.ID, _cts.Token ); await _dockerClient.Containers.RemoveContainerAsync( createContainerResponse.ID, new ContainerRemoveParameters { Force = true }, _cts.Token ); Task inspectRemovedContainerTask = _dockerClient.Containers.InspectContainerAsync( createContainerResponse.ID, _cts.Token ); Assert.NotNull(inspectCreatedContainer.State); await Assert.ThrowsAsync <DockerContainerNotFoundException>(() => inspectRemovedContainerTask); }
internal static ModuleRuntimeInfo InspectResponseToModule(ContainerInspectResponse inspectResponse) { // Get the following runtime state: // - name // - exit code // - exit status description // - last start time // - last exit time // - image hash ( string name, int exitCode, string statusDescription, DateTime lastStartTime, DateTime lastExitTime, string imageHash ) = ExtractModuleRuntimeState(inspectResponse); var dockerConfig = new DockerReportedConfig(string.Empty, string.Empty, imageHash); // Figure out module stats and runtime status ModuleStatus runtimeStatus = ToRuntimeStatus(inspectResponse.State); var reportedConfig = new DockerReportedConfig(string.Empty, string.Empty, imageHash); var moduleRuntimeInfo = new ModuleRuntimeInfo <DockerReportedConfig>(name, "docker", runtimeStatus, statusDescription, exitCode, Option.Some(lastStartTime), Option.Some(lastExitTime), reportedConfig); return(moduleRuntimeInfo); }
/// <summary> /// Get INFO about container by Container ID /// </summary> /// <param name="client">httpclient</param> /// <param name="id">Container ID</param> /// <param name="jwt">Token authorization</param> /// <returns></returns> async private Task <ContainerInspectResponse> GetContainerInfoByIDAsync(string id) { try { ContainerInspectResponse containerInfo = null; client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", JWT); var portainerEndpoint = new Uri(client.BaseAddress + $"api/endpoints/1/docker/containers/{id}/json"); var resp = await client.GetAsync(portainerEndpoint); if (resp.IsSuccessStatusCode) { var stream = await resp.Content.ReadAsStreamAsync(); using (StreamReader sr = new StreamReader(stream)) { using (var jsonResult = new JsonTextReader(sr)) { JsonSerializer ser = new JsonSerializer() { NullValueHandling = NullValueHandling.Ignore }; return(ser.Deserialize <ContainerInspectResponse>(jsonResult)); } } } return(containerInfo); } catch (Exception e) { Console.WriteLine(e.Message); throw; } }
public void TestEndpointConstruction() { // Arrange var runspaceId = "test-id"; var ipAddress = "10.10.10.10"; var expectedPort = 80; // Container's port-number and protocol in format: <int>[/<string>] var portKey = $"{expectedPort}/tcp"; var input = new ContainerInspectResponse( id: runspaceId, networkSettings: new NetworkSettings( networks: new Dictionary <string, EndpointSettings> { { DOCKER_NETWORK_NAME, new EndpointSettings(iPAddress: ipAddress) } }, ports: new PortMap { { portKey, new List <string> { "127.0.0.1", "4443" } } })); // Act var actual = DockerRunspaceInfo.FromContainerInspectResponse(input, DOCKER_NETWORK_NAME); // Assert Assert.NotNull(actual); Assert.AreEqual(runspaceId, actual.Id); Assert.AreEqual(ipAddress, actual.Endpoint.Address.ToString()); Assert.AreEqual(expectedPort, actual.Endpoint.Port); }
public void TestMultipleContainerPortsForDifferentProtocols() { // Arrange var runspaceId = "test-id"; var ipAddress = "10.10.10.10"; var expectedPort = 80; var portKey1 = "78"; var portKey2 = $"{expectedPort}/tcp"; var portKey3 = "43/udp"; var input = new ContainerInspectResponse( id: runspaceId, networkSettings: new NetworkSettings( networks: new Dictionary <string, EndpointSettings> { { DOCKER_NETWORK_NAME, new EndpointSettings(iPAddress: ipAddress) } }, ports: new PortMap { { portKey1, new List <string> { "127.0.0.1", "4443" } }, { portKey2, new List <string> { "127.0.0.1", "443" } }, { portKey3, new List <string> { "127.0.0.1", "3344" } } })); // Act var actual = DockerRunspaceInfo.FromContainerInspectResponse(input, DOCKER_NETWORK_NAME); // Assert Assert.AreEqual(expectedPort, actual.Endpoint.Port); }
public static DockerRunspaceInfo FromContainerInspectResponse( ContainerInspectResponse containerInspectResponse, string dockerNetworkName) { if (containerInspectResponse == null) { throw new RunspaceProviderException(Resources.Resources.DockerRunspaceInfo_FromContainerInspectResponse_ContainerInspectResponse_IsNull); } if (containerInspectResponse.NetworkSettings?.Networks == null || string.IsNullOrEmpty(dockerNetworkName) || !containerInspectResponse.NetworkSettings.Networks.ContainsKey(dockerNetworkName) || !IPAddress.TryParse( containerInspectResponse.NetworkSettings.Networks[dockerNetworkName].IPAddress, out var ipAddress)) { throw new RunspaceProviderException( string.Format( Resources.Resources.DockerRunspaceInfo_DockerRunspaceInfo_InvalidIp, dockerNetworkName)); } if (!TryGetContainerTcpPort(containerInspectResponse.NetworkSettings.Ports, out var port)) { throw new RunspaceProviderException(Resources.Resources.DockerRunspaceInfo_DockerRunspaceInfo_NoTcpPort); } return(new DockerRunspaceInfo { Id = containerInspectResponse.Id, Endpoint = new IPEndPoint( ipAddress, port) }); }
public void TestInvalidIp() { // Arrange var ipAddress = "InvalidIPAddress"; var runspaceId = "test-id"; var expectedPort = 80; // Container's port-number and protocol in format: <int>[/<string>] var portKey = $"{expectedPort}/tcp"; var input = new ContainerInspectResponse( id: runspaceId, networkSettings: new NetworkSettings( networks: new Dictionary <string, EndpointSettings> { { DOCKER_NETWORK_NAME, new EndpointSettings(iPAddress: ipAddress) } }, ports: new PortMap { { portKey, new List <string> { "127.0.0.1", "4443" } } })); // Act & Assert Assert.Throws <RunspaceProviderException>( () => { DockerRunspaceInfo.FromContainerInspectResponse(input, DOCKER_NETWORK_NAME); }); }
ExtractModuleRuntimeState(ContainerInspectResponse inspected) { string name = inspected.Name?.Substring(1) ?? CoreConstants.Unknown; int exitCode = (inspected?.State != null) ? (int)inspected.State.ExitCode : 0; string statusDescription = inspected?.State?.Status; string lastStartTimeStr = inspected?.State?.StartedAt; DateTime lastStartTime = DateTime.MinValue; if (lastStartTimeStr != null) { lastStartTime = DateTime.Parse(lastStartTimeStr, null, DateTimeStyles.RoundtripKind); } string lastExitTimeStr = inspected?.State?.FinishedAt; DateTime lastExitTime = DateTime.MinValue; if (!string.IsNullOrEmpty(lastExitTimeStr)) { lastExitTime = DateTime.Parse(lastExitTimeStr, null, DateTimeStyles.RoundtripKind); } string image = inspected.Config.Image; string hash = inspected?.Image; return(name, exitCode, statusDescription, lastStartTime, lastExitTime, hash, image); }
public ContainerStatusResponse( IReadOnlyServiceResponse response, ContainerInspectResponse dockerResponse ) : base(response) { Created = dockerResponse.Created; State = CreateFromDockerContainerState(dockerResponse.State); }
protected override async Task ContainerStarted() { await base.ContainerStarting(); _containerInfo = await _dockerClient.Containers.InspectContainerAsync(ContainerId); await ExecuteCommand("sh", "-c", $"echo \"{StartupScript()}\" > {STARTER_SCRIPT} && chmod +x {STARTER_SCRIPT}"); }
private IEnumerable <int> GetPorts(ContainerInspectResponse response) { var result = from port in response?.NetworkSettings?.Ports ?? Enumerable.Empty <KeyValuePair <string, IList <PortBinding> > >() from portBinding in port.Value ?? Enumerable.Empty <PortBinding>() let hostPort = portBinding.HostPort where int.TryParse(hostPort, out _) select int.Parse(hostPort); return(result); }
// On lance le container avec l'image précédement pull private async Task StartContainer() { // _hostPort et _containerPort sont les ports spécifié par le client (_hostPort:_containerPort) try { var response = await _dockerClient.Containers.CreateContainerAsync(new CreateContainerParameters { Image = _image, ExposedPorts = new Dictionary <string, EmptyStruct> { { _containerPort, default(EmptyStruct) } }, HostConfig = new HostConfig { PortBindings = new Dictionary <string, IList <PortBinding> > { { _containerPort, new List <PortBinding> { new PortBinding { HostPort = _hostPort } } } }, PublishAllPorts = true } }); // Si le container s'est créé correctement, on reçoit l'ID de ce dernier _containerId = response.ID; Console.WriteLine(_containerId); // On regarde le status de l'image qu'on vient de lancer pour voir s'il est "created" ContainerInspectResponse res = await _dockerClient.Containers.InspectContainerAsync(_containerId, CancellationToken.None); Console.WriteLine($"Status for {_image} : {res.State.Status}"); // On lance le container await _dockerClient.Containers.StartContainerAsync(_containerId, null); // On ajoute l'image exécutée associé avec son id dans notre dictionnaire _imagesExecuted.Add(_image, _containerId); Console.WriteLine($"id of image {_image} is : {_imagesExecuted[_image]}"); // On regarde le status de l'image qu'on vient de lancer pour voir s'il est "running" res = await _dockerClient.Containers.InspectContainerAsync(_containerId, CancellationToken.None); Console.WriteLine($"Status for {_image} : {res.State.Status}"); } catch (Exception ex) { Console.WriteLine(ex.Message); } }
private static async Task <bool> ResolveContainerAddress(IImageSettings settings) { ContainerInspectResponse inspectResponse = await _client .Containers .InspectContainerAsync(settings.ContainerId); settings.ContainerAddress = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "localhost" : inspectResponse.NetworkSettings.IPAddress; return(inspectResponse.State.Running); }
private static void WriteHostNames(bool add, FileStream hostsFileStream, string containerId) { try { ContainerInspectResponse response = GetClient().Containers.InspectContainerAsync(containerId).Result; IDictionary <string, EndpointSettings> networks = response.NetworkSettings.Networks; EndpointSettings network = null; if (networks.TryGetValue("nat", out network)) { var hostsLines = new List <string>(); using (StreamReader reader = new StreamReader(hostsFileStream)) using (StreamWriter writer = new StreamWriter(hostsFileStream)) { while (!reader.EndOfStream) { hostsLines.Add(reader.ReadLine()); } hostsFileStream.Position = 0; int removed = hostsLines.RemoveAll(l => l.EndsWith($"#{containerId} {WhwIdentifier}")); foreach (string alias in network.Aliases) { if (add) { hostsLines.Add($"{network.IPAddress}\t{alias}\t\t#{containerId} {WhwIdentifier}"); } } foreach (string line in hostsLines) { writer.WriteLine(line); } hostsFileStream.SetLength(hostsFileStream.Position); } } } catch (Exception ex) { if (_debug) { Console.WriteLine("Something went wrong. Maybe looking for a container that is already gone? Exception is " + ex.Message); Console.WriteLine(ex.StackTrace); if (ex.InnerException != null) { Console.WriteLine(); Console.WriteLine("InnerException is " + ex.InnerException.Message); Console.WriteLine(ex.InnerException.StackTrace); } } } }
public void InspectResponseToModuleTest() { const string StatusText = "Running for 1 second"; DateTime lastStartTime = DateTime.Parse("2017-08-04T17:52:13.0419502Z", null, DateTimeStyles.RoundtripKind); DateTime lastExitTime = lastStartTime.AddDays(1); // Arrange string id = Guid.NewGuid().ToString(); string hash = Guid.NewGuid().ToString(); var inspectContainerResponse = new ContainerInspectResponse { State = new ContainerState { Status = StatusText, ExitCode = 0, StartedAt = lastStartTime.ToString("o"), FinishedAt = lastExitTime.ToString("o"), }, Name = "/sensor", Image = hash, Config = new Config { Image = "ubuntu" } }; var systemInfoResponse = new SystemInfoResponse { OSType = OperatingSystemType, Architecture = Architecture }; var dockerClient = Mock.Of <IDockerClient>( dc => dc.Containers == Mock.Of <IContainerOperations>(co => co.InspectContainerAsync(id, default(CancellationToken)) == Task.FromResult(inspectContainerResponse)) && dc.System == Mock.Of <ISystemOperations>(so => so.GetSystemInfoAsync(default(CancellationToken)) == Task.FromResult(systemInfoResponse))); // Act ModuleRuntimeInfo module = RuntimeInfoProvider.InspectResponseToModule(inspectContainerResponse); // Assert Assert.NotNull(module); var dockerModule = module as ModuleRuntimeInfo <DockerReportedConfig>; Assert.NotNull(dockerModule); Assert.Equal("ubuntu:latest", dockerModule.Config.Image); Assert.Equal("sensor", dockerModule.Name); Assert.Equal(0, dockerModule.ExitCode); Assert.Equal(StatusText, dockerModule.Description); Assert.Equal(lastStartTime, dockerModule.StartTime.OrDefault()); Assert.Equal(lastExitTime, dockerModule.ExitTime.OrDefault()); }
public async Task CollectLogs(string id, string logsFolder, ISessionHostManager sessionHostManager) { try { _logger.LogVerbose($"Collecting logs for container {id}."); string destinationFileName = Path.Combine(logsFolder, ConsoleLogCaptureFileName); if (sessionHostManager.LinuxContainersOnWindows) { // we do this for lcow since containers are running on a Hyper-V Linux machine // which the host Windows machine does not have "copy" access to, to get the logs with a FileCopy // this is only supposed to run on LocalMultiplayerAgent running on lcow StringBuilder sb = new StringBuilder(); Stream logsStream = await _dockerClient.Containers.GetContainerLogsAsync(id, new ContainerLogsParameters() { ShowStdout = true, ShowStderr = true }); using (StreamReader sr = new StreamReader(logsStream)) { Stopwatch sw = new Stopwatch(); while (!sr.EndOfStream) { if (sw.Elapsed.Seconds > 3) // don't flood STDOUT with messages, output one every 3 seconds if logs are too many { _logger.LogVerbose($"Gathering logs for container {id}, please wait..."); sw.Restart(); } _systemOperations.FileAppendAllText(destinationFileName, sr.ReadLine() + Environment.NewLine); } } _logger.LogVerbose($"Written logs for container {id} to {destinationFileName}."); } else { ContainerInspectResponse containerInspectResponse = await _dockerClient.Containers.InspectContainerAsync(id); string dockerLogsPath = containerInspectResponse?.LogPath; if (!string.IsNullOrEmpty(dockerLogsPath) && _systemOperations.FileExists(dockerLogsPath)) { _logger.LogVerbose($"Copying log file {dockerLogsPath} for container {id} to {destinationFileName}."); _systemOperations.FileCopy(dockerLogsPath, destinationFileName); } } } catch (DockerContainerNotFoundException) { _logger.LogInformation($"Docker container {id} not found."); } }
async Task <Option <ContainerInspectResponse> > GetEdgeAgentContainerAsync() { try { ContainerInspectResponse response = await this.client.Containers.InspectContainerAsync(CoreConstants.EdgeAgentModuleName); return(Option.Some(response)); } catch (DockerContainerNotFoundException ex) { Events.EdgeAgentContainerNotFound(ex); return(Option.None <ContainerInspectResponse>()); } }
/// <summary> /// Removes the Testcontainer. /// </summary> /// <param name="ct">Cancellation token.</param> /// <returns>A task that represents the asynchronous clean up operation of a Testcontainer.</returns> public async Task CleanUpAsync(CancellationToken ct = default) { await this.semaphoreSlim.WaitAsync(ct) .ConfigureAwait(false); try { this.container = await this.CleanUp(this.Id, ct) .ConfigureAwait(false); } finally { this.semaphoreSlim.Release(); } }
protected virtual async Task WaitUntilContainerStarted() { var retryUntilContainerStateIsRunning = Policy .HandleResult <ContainerInspectResponse>(c => !c.State.Running) .RetryForeverAsync(); var containerInspectPolicy = await Policy .TimeoutAsync(_startTimeout) .WrapAsync(retryUntilContainerStateIsRunning) .ExecuteAndCaptureAsync(async() => _containerInspectResponse = await _dockerClient.Containers.InspectContainerAsync(_containerId)); if (containerInspectPolicy.Outcome == OutcomeType.Failure) { throw new ContainerException("Container startup failed", containerInspectPolicy.FinalException); } }
/// <inheritdoc /> public virtual async Task StartAsync(CancellationToken ct = default) { await this.semaphoreSlim.WaitAsync(ct) .ConfigureAwait(false); try { this.container = await this.Create(ct) .ConfigureAwait(false); this.container = await this.Start(this.Id, ct) .ConfigureAwait(false); } finally { this.semaphoreSlim.Release(); } }
private void UpdateStateMetrics(ContainerTrackerStateMetrics metrics, ContainerInspectResponse container) { metrics.RestartCount.Set(container.RestartCount); if (container.State.Running) { metrics.RunningState.Set(1); } else if (container.State.Restarting) { metrics.RunningState.Set(0.5); } else { metrics.RunningState.Set(0); } if (container.State.Health != null) { // Publish container health if it exists if (container.State.Health.Status == "healthy") { metrics.HealthState.Set(1); } else if (container.State.Health.Status == "starting") { metrics.HealthState.Set(0.5); } else // "unhealthy" { metrics.HealthState.Set(0); } } else { // Makes sure to unpublish it if it wasn't initially published metrics.HealthState.Unpublish(); } if (container.State.Running && !string.IsNullOrWhiteSpace(container.State.StartedAt)) { metrics.StartTime.SetToTimeUtc(DateTimeOffset.Parse(container.State.StartedAt)); } }
/// <inheritdoc /> public virtual async Task StopAsync(CancellationToken ct = default) { await this.semaphoreSlim.WaitAsync(ct) .ConfigureAwait(false); try { this.container = await this.Stop(this.Id, ct) .ConfigureAwait(false); } catch (DockerContainerNotFoundException) { this.container = new ContainerInspectResponse(); } finally { this.semaphoreSlim.Release(); } }
public async Task TestStartInstance2Async() { GameInstance i = this.AddBlankDir("blank-dir", 54); ExecutionInfo dockerInst = await this._service.StartInstanceAsync("localhost", 9999, i); ContainerInspectResponse containerInfo = await this._dockerClient.Containers.InspectContainerAsync(dockerInst.Key); Assert.Equal("factoriotools/factorio:0.17.54", containerInfo.Config.Image); IList <PortBinding> udpPorts = containerInfo.NetworkSettings.Ports["34197/udp"]; Assert.Single(udpPorts); Assert.Equal("9999", udpPorts[0].HostPort); Assert.Single(containerInfo.Mounts); Assert.Equal("/factorio", containerInfo.Mounts[0].Destination); Assert.Equal("bind", containerInfo.Mounts[0].Type); //Assert.Equal(i.LocalPath, containerInfo.Mounts[0].Source); // On windows this is a weird translation }
public IsRunningStartupCheckStrategyTest() { _mockContainerId = "my_container_id"; var dockerClientMock = new DockerClientMock(); _dockerClientMock = dockerClientMock.MockDockerClient; var mockInspectResponse = new ContainerInspectResponse(); dockerClientMock.MockContainerOperations.Setup(e => e.InspectContainerAsync( _mockContainerId, default(CancellationToken))) .Returns(Task.FromResult(mockInspectResponse)); _containerStateMock = new ContainerState(); mockInspectResponse.State = _containerStateMock; _strategy = new IsRunningStartupCheckStrategy(); }
public string GetDockerHostIpAddress(ContainerInspectResponse containerInfo) { var dockerHostUri = Client().Configuration.EndpointBaseUri; switch (dockerHostUri.Scheme) { case "http": case "https": case "tcp": return(dockerHostUri.Host); case "npipe": //will have to revisit this for LCOW/WCOW case "unix": return(File.Exists("/.dockerenv") ? containerInfo.NetworkSettings.Gateway : "localhost"); default: return(null); } }
private void UpdateStateMetrics(ContainerTrackerStateMetrics metrics, ContainerInspectResponse container) { metrics.RestartCount.Set(container.RestartCount); if (container.State.Running) { metrics.RunningState.Set(1); } else if (container.State.Restarting) { metrics.RunningState.Set(0.5); } else { metrics.RunningState.Set(0); } if (container.State.Running && !string.IsNullOrWhiteSpace(container.State.StartedAt)) { metrics.StartTime.SetToTimeUtc(DateTimeOffset.Parse(container.State.StartedAt)); } }
public void TestInvalidPort() { // Arrange string ipAddress = "10.10.10.10"; var runspaceId = "test-id"; var portKey = "80"; var input = new ContainerInspectResponse( id: runspaceId, networkSettings: new NetworkSettings( networks: new Dictionary <string, EndpointSettings> { { DOCKER_NETWORK_NAME, new EndpointSettings(iPAddress: ipAddress) } }, ports: new PortMap { { portKey, new List <string> { "127.0.0.1", "4443" } } })); // Act & Assert Assert.Throws <RunspaceProviderException>(() => { DockerRunspaceInfo.FromContainerInspectResponse(input, DOCKER_NETWORK_NAME); }); }
private async Task <ContainerInspectResponse> Start(string id, CancellationToken ct = default) { await this.client.AttachAsync(id, this.configuration.OutputConsumer, ct) .ConfigureAwait(false); await this.client.StartAsync(id, ct) .ConfigureAwait(false); this.container = await this.client.InspectContainer(id, ct) .ConfigureAwait(false); await this.configuration.StartupCallback(this, ct) .ConfigureAwait(false); // Do not use a too small frequency. Especially with a lot of containers, // we send many operations to the Docker endpoint. The endpoint may cancel operations. var frequency = (int)TimeSpan.FromSeconds(1).TotalMilliseconds; const int timeout = -1; foreach (var waitStrategy in this.configuration.WaitStrategies) { await WaitStrategy.WaitUntil( async() => { this.container = await this.client.InspectContainer(id, ct) .ConfigureAwait(false); return(await waitStrategy.Until(this, this.Logger) .ConfigureAwait(false)); }, frequency, timeout, ct) .ConfigureAwait(false); } return(this.container); }