public static async Task <string> RunContainer(this DockerClient client, string image, string containerName, string exposedPort, string hostPort)
        {
            CreateContainerResponse container = await CreateContainer(client, image, containerName, exposedPort, hostPort);

            await client.Containers.StartContainerAsync(containerName, new ContainerStartParameters());

            return(container.ID);
        }
示例#2
0
        private async Task CreateContainerAsync()
        {
            var hostConfig = new HostConfig
            {
                PublishAllPorts = true
            };

            if (_settings.ExternalPort > 0)
            {
                hostConfig.PublishAllPorts = false;
                hostConfig.PortBindings    = new Dictionary <string, IList <PortBinding> > {
                    {
                        _settings.InternalPort + "/tcp", new List <PortBinding> {
                            new PortBinding {
                                HostPort = _settings.ExternalPort.ToString()
                            }
                        }
                    }
                };
            }

            var startParams = new CreateContainerParameters
            {
                Name         = _settings.UniqueContainerName,
                Image        = _settings.ImageFullname,
                AttachStdout = true,
                AttachStderr = true,
                AttachStdin  = false,
                Tty          = false,
                HostConfig   = hostConfig,
                Env          = _settings.EnvironmentVariables,
                Cmd          = _settings.Cmd
            };


            try
            {
                await retryPolicy
                .ExecuteAsync(async() =>
                {
                    CreateContainerResponse response = await _client
                                                       .Containers
                                                       .CreateContainerAsync(startParams);

                    if (string.IsNullOrEmpty(response.ID))
                    {
                        throw new ContainerException(
                            "Could not create the container");
                    }
                    Instance.Id = response.ID;
                });
            }
            catch (Exception ex)
            {
                throw new ContainerException(
                          $"Error in CreateContainer: {_settings.UniqueContainerName}", ex);
            }
        }
示例#3
0
        private async Task <string> CriarContainer()
        {
            CreateContainerParameters parametros = CriarParametros();
            CreateContainerResponse   container  = await _dockerClient
                                                   .Containers
                                                   .CreateContainerAsync(parametros);

            return(container.ID);
        }
示例#4
0
        /// <summary>
        ///		Create a new <see cref="ContainerCreated"/>.
        /// </summary>
        /// <param name="correlationId">
        ///		The message correlation Id that was assigned to the original <see cref="CreateContainer"/> request.
        /// </param>
        /// <param name="apiResponse">
        ///		The response from the Docker API.
        /// </param>
        public ContainerCreated(string correlationId, CreateContainerResponse apiResponse)
            : base(correlationId)
        {
            if (apiResponse == null)
            {
                throw new ArgumentNullException(nameof(apiResponse));
            }

            ApiResponse = apiResponse;
        }
示例#5
0
        private async Task <string> CreateContainer(
            string imageName,
            IList <string> environmentVariables,
            IList <string> volumeBindings,
            IList <PortMapping> portMappings,
            IList <string> startCmd,
            HostConfig hostConfigOverrides,
            string workingDirectory)
        {
            HostConfig hostConfig = hostConfigOverrides ?? new HostConfig();

            hostConfig.NetworkMode  = SessionHostContainerConfiguration.DockerNetworkName;
            hostConfig.Binds        = volumeBindings;
            hostConfig.PortBindings = portMappings?.ToDictionary(p => $"{p.GamePort.Number}/{p.GamePort.Protocol}",
                                                                 p => (IList <PortBinding>)(new List <PortBinding>()
            {
                new PortBinding()
                {
                    HostPort = $"{p.NodePort}/{p.GamePort.Protocol}"
                }
            }));

            if (hostConfig.LogConfig == null)
            {
                hostConfig.LogConfig        = new LogConfig();
                hostConfig.LogConfig.Type   = "json-file";
                hostConfig.LogConfig.Config = new Dictionary <string, string>()
                {
                    { "max-size", "200m" }
                };
            }

            CreateContainerParameters containerParams = new CreateContainerParameters
            {
                Image        = imageName,
                Env          = environmentVariables,
                ExposedPorts = portMappings?.ToDictionary(p => $"{p.GamePort.Number}/{p.GamePort.Protocol}", p => new EmptyStruct()),
                HostConfig   = hostConfig,
                WorkingDir   = workingDirectory,
                Cmd          = startCmd
            };

            _logger.LogInformation($"Creating container. Image='{imageName}'");
            CreateContainerResponse response =
                await TaskUtil.TimedExecute(
                    async() => await _dockerClient.Containers.CreateContainerAsync(containerParams).ConfigureAwait(false),
                    _logger,
                    MetricConstants.ContainerStats,
                    MetricConstants.ContainerCreationTime);

            _logger.LogInformation($"Created a container with session host id: {response.ID}");

            return(response.ID);
        }
示例#6
0
        public async Task <string> StartContainerNode(string ImageName, string NodeName, string DriverPort, string VNCPort)
        {
            var CreateParameters = new CreateContainerParameters
            {
                Image        = ImageName,
                Name         = NodeName,
                ExposedPorts = new Dictionary <string, EmptyStruct>
                {
                    {
                        "4444", default(EmptyStruct)
                    },
                    {
                        "5900", default(EmptyStruct)
                    }
                },

                HostConfig = new HostConfig
                {
                    ShmSize      = 134217728,
                    PortBindings = new Dictionary <string, IList <PortBinding> >
                    {
                        { "4444", new List <PortBinding> {
                              new PortBinding {
                                  HostPort = DriverPort
                              }
                          } },
                        { "5900", new List <PortBinding> {
                              new PortBinding {
                                  HostPort = VNCPort
                              }
                          } },
                    },
                },
                ArgsEscaped  = true,
                AttachStderr = true,
                AttachStdin  = true,
                AttachStdout = true,
            };

            CreateContainerResponse response = await client.Containers.CreateContainerAsync(CreateParameters);

            try
            {
                Task t = client.Containers.StartContainerAsync(response.ID, null);
                t.Wait();
                Console.WriteLine($"{NodeName} container created: {DateTime.Now}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"{NodeName} {ex.Message}");
            }

            return(response.ID);
        }
        /// <summary>
        /// TODO
        /// </summary>
        /// <param name="instance"></param>
        /// <param name="port"></param>
        /// <param name="sourcePath"></param>
        /// <returns></returns>
        private async Task <string> StartImageAsync(string key, int port, string sourcePath, string version)
        {
            this._logger.LogInformation("Trying to start image {imageKey} {version} on {port} with {URL}", key, version, port, sourcePath);

            CreateContainerResponse newContainer = null;

            try
            {
                newContainer = await this._dockerClient.Containers.CreateContainerAsync(new CreateContainerParameters
                {
                    Labels = new Dictionary <string, string>
                    {
                        { DOCKER_LABEL_KEY, key }
                    },
                    Volumes = new Dictionary <string, EmptyStruct> {
                        { "/factorio", new EmptyStruct() }
                    },
                    Image        = "factoriotools/factorio:" + version,
                    ExposedPorts = new Dictionary <string, EmptyStruct> {
                        { "34197/udp", new EmptyStruct() }
                    },
                    Name       = "factorio-server-" + key,
                    HostConfig = new HostConfig
                    {
                        PortBindings = new Dictionary <string, IList <PortBinding> > {
                            { "34197/udp", new[] { new PortBinding {
                                                       HostPort = string.Format("{0}", port)
                                                   } } }
                        },
                        Mounts = new List <Mount>
                        {
                            new Mount
                            {
                                Target = "/factorio",
                                Type   = "bind",
                                Source = sourcePath
                            }
                        }
                    }
                });
            }
            catch (DockerApiException e)
            {
                throw new Exception("Failed to start instance", e);
            }


            await this._dockerClient.Containers.StartContainerAsync(newContainer.ID, new ContainerStartParameters());

            return(newContainer.ID);
        }
示例#8
0
        public async Task CanAttachContainer()
        {
            var sut = new ContainerHelper();

            CreateContainerResponse createContainerResponse = await sut.CreateContainer(@"shawnseabrook/build:50", "canattach", new List <string> {
                "ListTests"
            });

            await sut.StartContainer(createContainerResponse.ID);

            string res = await sut.AttachContainer(createContainerResponse.ID);

            Console.WriteLine(res);
        }
        public async Task CreateContainer()
        {
            if (await DoesContainerExist(_containerName))
            {
                return;
            }

            await _client.Images.CreateImageAsync(new ImagesCreateParameters()
            {
                FromImage = _imageName, Tag = _imageTag
            },
                                                  new AuthConfig(),
                                                  new Progress <JSONMessage>());

            var config = new Config()
            {
                Hostname = "localhost"
            };

            var hostConfig = new HostConfig()
            {
                PortBindings = new Dictionary <string, IList <PortBinding> >
                {
                    { "1113/tcp", new List <PortBinding> {
                          new PortBinding {
                              HostIP = "127.0.0.1", HostPort = "1113"
                          }
                      } },
                    { "2113/tcp", new List <PortBinding> {
                          new PortBinding {
                              HostIP = "127.0.0.1", HostPort = "2113"
                          }
                      } }
                }
            };

            // Create the container
            try
            {
                CreateContainerResponse response = await _client.Containers.CreateContainerAsync(
                    new CreateContainerParameters(config)
                {
                    Image = _imageName + ":" + _imageTag, Name = _containerName, Tty = false, HostConfig = hostConfig,
                });
            }
            catch (Exception e)
            {
                Console.WriteLine($"Summat went wrong {e.Message}");
            }
        }
示例#10
0
        public void Create(CreateContainerParameters createParameters)
        {
            this.Docker.Images.CreateImageAsync(new ImagesCreateParameters()
            {
                FromImage = createParameters.Image
            }, null, this).GetAwaiter().GetResult();
            this.CreateResponse = this.Docker.Containers.CreateContainerAsync(createParameters).GetAwaiter().GetResult();
            if (this.CreateResponse.Warnings != null && this.CreateResponse.Warnings.Any())
            {
                throw new InvalidOperationException(string.Join(" | ", this.CreateResponse.Warnings));
            }

            Console.WriteLine($"Container Created {this.CreateResponse.ID}");
        }
示例#11
0
        private static async Task CreateContainer(
            IImageSettings settings)
        {
            CreateContainerResponse response = await _client
                                               .Containers
                                               .CreateContainerAsync(settings.ToCreateContainerParameters());

            if (string.IsNullOrEmpty(response.ID))
            {
                throw new ContainerException(
                          "Could not create the container");
            }

            settings.ContainerId = response.ID;
        }
示例#12
0
        public async System.Threading.Tasks.Task InitAsync(string parent, string tag, string containerId)
        {
            Console.WriteLine("Pulling image " + parent + ":" + tag);

            await client.Images.CreateImageAsync(new ImagesCreateParameters()
            {
                FromImage = parent,
                Tag       = tag
            }, null, new Progress());

            CreateContainerResponse response = await CreateContainer(parent, containerId, null);

            await StartContainer(containerId);

            var buffer = new byte[1024];

            using (var stream1 = await client.Containers.AttachContainerAsync(response.ID, false, new ContainerAttachParameters()
            {
                Stream = true,
                Stderr = true,
                Stdin = false,
                Stdout = true,
                Logs = "1"
            }))
            {
                (string output, string stderr) = await stream1.ReadOutputToEndAsync(default(CancellationToken));

                Console.WriteLine(output);
            }


            Stream stream = await client.Containers.GetContainerLogsAsync(containerId, new ContainerLogsParameters()
            {
                ShowStdout = true,
                ShowStderr = true
            });

            StreamReader streamReader = new StreamReader(stream);

            Console.WriteLine(streamReader.ReadToEnd());

            await StopContainer(containerId);

            await RemoveContainer(containerId);

            Console.WriteLine("Done!");
        }
示例#13
0
        public async void Post()
        {
            Uri dockerSocket = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
                ? new Uri("npipe://./pipe/docker_engine")
                : new Uri("unix:///var/run/docker.sock");

            DockerClient client = new DockerClientConfiguration(dockerSocket).CreateClient();

            await client.Images.CreateImageAsync(new ImagesCreateParameters
            {
                FromImage = "containrrr/watchtower:latest",
                FromSrc   = "https://registry-1.docker.io",
                Repo      = "containrrr/watchtower",
                Tag       = "latest"
            }, null, new Progress <JSONMessage>());

            CreateContainerResponse wtcontainer = await client.Containers.CreateContainerAsync(new CreateContainerParameters
            {
                Image = "containrrr/watchtower",
                Name  = "watchtower",
                Cmd   = new List <String>()
                {
                    "wiki",
                    "--cleanup",
                    "--run-once",
                    "--debug"
                },
                HostConfig = new HostConfig
                {
                    AutoRemove = true,
                    Mounts     = new Mount[] {
                        new Mount()
                        {
                            ReadOnly = true,
                            Source   = "/var/run/docker.sock",
                            Target   = "/var/run/docker.sock",
                            Type     = "bind"
                        }
                    }
                },
                AttachStderr = true,
                AttachStdout = true
            });

            await client.Containers.StartContainerAsync(wtcontainer.ID, new ContainerStartParameters());
        }
示例#14
0
        /// <summary>
        /// Unmarshaller the response from the service to the response class.
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override AmazonWebServiceResponse Unmarshall(JsonUnmarshallerContext context)
        {
            CreateContainerResponse response = new CreateContainerResponse();

            context.Read();
            int targetDepth = context.CurrentDepth;

            while (context.ReadAtDepth(targetDepth))
            {
                if (context.TestExpression("Container", targetDepth))
                {
                    var unmarshaller = ContainerUnmarshaller.Instance;
                    response.Container = unmarshaller.Unmarshall(context);
                    continue;
                }
            }

            return(response);
        }
        private static async Task <string> WriteLog(DockerClient client, CreateContainerResponse container, ContainerLogsParameters op, CancellationToken token)
        {
            var log = await client.Containers.GetContainerLogsAsync(container.ID, op, token);

            var sb = new StringBuilder();

            using (var reader = new StreamReader(log))
            {
                while (!reader.EndOfStream)
                {
                    var line = await reader.ReadLineAsync();

                    if (op.ShowStderr.HasValue && op.ShowStderr.Value)
                    {
                        Console.WriteLine(line);
                    }
                    sb.AppendLine(line.TrimEnd(Environment.NewLine.ToCharArray()));
                }
            }
            return(sb.ToString());
        }
 public async Task <string> CreateContainer(SandboxCreationConfig sandboxConfig)
 {
     CreateContainerResponse response = await client.Containers.CreateContainerAsync(new CreateContainerParameters()
     {
         Image      = sandboxConfig.Image,
         Tty        = true, // -it
         HostConfig = new HostConfig
         {
             PortBindings = new Dictionary <string, IList <PortBinding> >
             {
                 { "8080/tcp", new List <PortBinding>
                   {
                       new PortBinding
                       {
                           HostPort = sandboxConfig.Port
                       }
                   } }
             }
         },
         Volumes = new Dictionary <string, EmptyStruct>()
         {
             { $"{sandboxConfig.ConfigDir}:/home/coder/.local/share/code-server", default },
示例#17
0
        public async void StartContainerHub(string ImageName)
        {
            var CreateParameters = new CreateContainerParameters
            {
                Image        = ImageName,
                Name         = "selenium-hub",
                ExposedPorts = new Dictionary <string, EmptyStruct>
                {
                    {
                        "4444", default(EmptyStruct)
                    }
                },

                HostConfig = new HostConfig
                {
                    PortBindings = new Dictionary <string, IList <PortBinding> >
                    {
                        { "4444", new List <PortBinding> {
                              new PortBinding {
                                  HostPort = "4444"
                              }
                          } }
                    },
                    PublishAllPorts = true
                },
                ArgsEscaped  = true,
                AttachStderr = true,
                AttachStdin  = true,
                AttachStdout = true,
            };

            try
            {
                CreateContainerResponse response = await client.Containers.CreateContainerAsync(CreateParameters);

                await client.Containers.StartContainerAsync(response.ID, null);
            }
            catch (Exception ex) { }
        }
示例#18
0
        //MIT License Code from: https://github.com/Activehigh/Atl.GenericRepository/blob/master/Atl.Repository.Standard.Tests/Repositories/ReadRepositoryTestsWithNpgsql.cs
        //for initializing the docker client
        public async Task InitializeAsync()
        {
            bool isWindows = System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(OSPlatform.Windows);

            //This is the windows only pipe "npipe://./pipe/docker_engine"
            //Unix pipe is "unix:///var/run/docker.sock" - don'tmknow if it works for OSX
            _client = new DockerClientConfiguration(new Uri(isWindows ? "npipe://./pipe/docker_engine" : "unix:///var/run/docker.sock")).CreateClient();

            var(containerRespose, port) = await GetContainer(_client, "postgres", "latest");

            _containerResponse = containerRespose;

            var connectionStringBuilder = new NpgsqlConnectionStringBuilder()
            {
                ConnectionString = $"User ID=postgres;Password=password;Server=127.0.0.1;Port={port};Database=repotest;Integrated Security=true;Pooling=false;CommandTimeout=300"
            };

            Db = new NpgsqlConnection(connectionStringBuilder.ConnectionString);
            Db.Open();

            await InitializeTableStructure(Db);
            await PopulateTable(Db);
        }
        public static async Task <IDisposable> StartContainerAsync(
            string image,
            IReadOnlyCollection <int> ports = null,
            IReadOnlyDictionary <string, string> environment = null)
        {
            using (var ts = new CancellationTokenSource(TimeSpan.FromMinutes(5)))
            {
                var env = environment
                          ?.OrderBy(kv => kv.Key)
                          .Select(kv => $"{kv.Key}={kv.Value}")
                          .ToList();

                Log.Info($"Starting container with image '{image}'");

                Log.Info($"Pulling image {image}");
                var imageAndTag = image.Split(':');
                await DockerClient.Images.CreateImageAsync(
                    new ImagesCreateParameters
                {
                    FromImage = imageAndTag[0],
                    Tag       = imageAndTag.Length > 1 ? imageAndTag[1] : null
                },
                    null,
                    new Progress <JSONMessage>(m =>
                {
                    Log.Trace($"{m.ProgressMessage} ({m.ID})");
                }),
                    ts.Token)
                .ConfigureAwait(false);

                while (true)
                {
                    IList <ImagesListResponse> imagesListResponses = await DockerClient.Images.ListImagesAsync(new ImagesListParameters(), ts.Token).ConfigureAwait(false);

                    if (imagesListResponses.Any(i =>
                                                i.RepoTags != null &&
                                                i.RepoTags.Any(t => string.Equals(t, image, StringComparison.OrdinalIgnoreCase))))
                    {
                        break;
                    }

                    Thread.Sleep(TimeSpan.FromSeconds(1));
                }

                CreateContainerResponse createContainerResponse = await DockerClient.Containers.CreateContainerAsync(
                    new CreateContainerParameters(
                        new Config
                {
                    Image = image,
                    Env = env,
                    ExposedPorts = ports?
                                   .ToDictionary(p => $"{p}/tcp", p => new EmptyStruct())
                })
                {
                    HostConfig = new HostConfig
                    {
                        PortBindings = ports?.ToDictionary(
                            p => $"{p}/tcp",
                            p => (IList <PortBinding>) new List <PortBinding>
                        {
                            new PortBinding {
                                HostPort = p.ToString()
                            }
                        })
                    }
                },
                    ts.Token)
                                                                  .ConfigureAwait(false);

                Log.Info($"Successfully created container '{createContainerResponse.ID}'");

                await DockerClient.Containers.StartContainerAsync(
                    createContainerResponse.ID,
                    new ContainerStartParameters(),
                    ts.Token)
                .ConfigureAwait(false);

                Log.Info($"Successfully started container '{createContainerResponse.ID}'");

                return(new DisposableAction(() => StopContainer(createContainerResponse.ID)));
            }
        }
示例#20
0
文件: Docker.cs 项目: lie112/ApsimX
        /// <summary>
        /// Run a container. Does NOT pull the container - the assumption is that
        /// the container already exists..
        /// </summary>
        /// <param name="image"></param>
        /// <param name="entrypoint"></param>
        /// <param name="args"></param>
        /// <param name="volumes"></param>
        /// <param name="environment"></param>
        /// <param name="workingDir"></param>
        /// <param name="cancelToken"></param>
        /// <returns></returns>
        public async Task RunContainerAsync(string image, string entrypoint, IEnumerable <string> args, IReadOnlyList <Volume> volumes, Dictionary <string, string> environment, string workingDir, CancellationToken cancelToken)
        {
            CreateContainerParameters parameters = new CreateContainerParameters()
            {
                Image      = image,
                Entrypoint = entrypoint.ToEnumerable().AppendMany(args).ToList(),
                Env        = environment?.Select((x, y) => $"{x}={y}")?.ToList(),
                Tty        = false,
                HostConfig = new HostConfig()
                {
                    Binds = volumes.Select(v => $"{v.SourcePath}:{v.DestinationPath}").ToList()
                },
                WorkingDir = workingDir
            };

            // Create the container.
            CreateContainerResponse container = await client.Containers.CreateContainerAsync(parameters, cancelToken);

            try
            {
                // Report any warnings from the docker daemon.
                foreach (string warning in container.Warnings)
                {
                    warningHandler(warning);
                }

                // Start the container, and wait for it to exit.
                await client.Containers.StartContainerAsync(container.ID, new ContainerStartParameters(), cancelToken);

                // Watch stdout and/or stderr as necessary.
                Task stdoutListener = WatchStdoutStreamAsync(container.ID, cancelToken);
                Task stderrListener = WatchStderrStreamAsync(container.ID, cancelToken);

                // Wait for the container to exit.
                ContainerWaitResponse waitResponse = await client.Containers.WaitContainerAsync(container.ID, cancelToken);

                // Wait for output listeners if cancellation has not been requested.
                if (!cancelToken.IsCancellationRequested)
                {
                    await stdoutListener.ConfigureAwait(false);

                    await stderrListener.ConfigureAwait(false);
                }

                // If cancellation isn't requested, ensure the container exited gracefully.
                if (!cancelToken.IsCancellationRequested && waitResponse.StatusCode != 0)
                {
                    (string stdout, string stderr) = await GetContainerLogsAsync(container.ID, parameters.Tty, cancelToken);

                    StringBuilder output = new StringBuilder();
                    output.AppendLine(stdout);
                    output.AppendLine(stderr);
                    throw new Exception($"Container exited with non-zero exit code. Container log:\n{output}");
                }
            }
            finally
            {
                ContainerRemoveParameters removeParameters = new ContainerRemoveParameters()
                {
                    RemoveVolumes = true,
                    Force         = true
                };
                ContainerKillParameters killParameters = new ContainerKillParameters()
                {
                };
                // Only attempt to kill the container if it's still running.
                if (await IsRunning(container.ID))
                {
                    await client.Containers.KillContainerAsync(container.ID, killParameters);
                }
                await client.Containers.RemoveContainerAsync(container.ID, removeParameters);
            }
        }
示例#21
0
        private static async Task InitializeDatabaseServer()
        {
            const string image         = "mcr.microsoft.com/mssql/server:2017-latest";
            const string containerName = "dotnet-03-int-tests";

            DockerClient dockerClient = new DockerClientConfiguration().CreateClient();

            IList <ContainerListResponse> runningContainers = await dockerClient.Containers.ListContainersAsync(new ContainersListParameters());

            IEnumerable <ContainerListResponse> testContainers =
                runningContainers.Where(container => container.Names.Any(name => name.Contains(containerName)));

            foreach (ContainerListResponse container in testContainers)
            {
                await dockerClient.Containers.StopContainerAsync(container.ID, new ContainerStopParameters());

                await dockerClient.Containers.RemoveContainerAsync(container.ID, new ContainerRemoveParameters());
            }

            await dockerClient.Images.CreateImageAsync(new ImagesCreateParameters
            {
                FromImage = image
            },
                                                       null,
                                                       new Progress <JSONMessage>());

            CreateContainerResponse sqlContainer =
                await dockerClient
                .Containers
                .CreateContainerAsync(
                    new CreateContainerParameters
            {
                Name  = containerName,
                Image = image,
                Env   = new List <string>
                {
                    "ACCEPT_EULA=Y",
                    $"SA_PASSWORD={SqlSaPassword}"
                },
                HostConfig = new HostConfig
                {
                    PortBindings = new Dictionary <string, IList <PortBinding> >
                    {
                        {
                            "1433/tcp",
                            new[]
                            {
                                new PortBinding
                                {
                                    HostPort = SqlPort
                                }
                            }
                        }
                    }
                }
            });

            await dockerClient.Containers.StartContainerAsync(sqlContainer.ID, new ContainerStartParameters());

            await WaitUntilDatabaseAvailableAsync(SqlPort);
        }
示例#22
0
        public async Task <ContainerExecutionResult> RunAsync(Command command)
        {
            var createContainerParameters = new CreateContainerParameters
            {
                Image       = _configuration.ImageName,
                Tty         = true,
                AttachStdin = true,
                Cmd         = command.ProgramNameWithArguments,
                Env         = command.EnvironmentVariables,
                WorkingDir  = command.WorkingDirectory,
                HostConfig  = new HostConfig
                {
                    Memory = command.Limits.MemoryLimitInBytes
                }
            };

            if (!string.IsNullOrWhiteSpace(command.MountDirectory))
            {
                createContainerParameters.HostConfig.Mounts = new List <Mount>
                {
                    new Mount
                    {
                        Type   = "bind",
                        Source = command.MountDirectory,
                        Target = _configuration.DockerWorkingDir
                    }
                };
            }

            _createContainerResponse = await _client.Containers.CreateContainerAsync(
                createContainerParameters);

            await _client.Containers.StartContainerAsync(_createContainerResponse.ID, new ContainerStartParameters());


            if (await TryKillContainerAfterTimeout(command))
            {
                return(ContainerExecutionResult.KilledByTimeout);
            }

            var containerInspection = await _client.Containers.InspectContainerAsync(_createContainerResponse.ID);


            if (containerInspection.State.OOMKilled)
            {
                return(ContainerExecutionResult.KilledByMemoryLimit);
            }


            var errorOutputTask = GetContainerLogsAsync(new ContainerLogsParameters {
                ShowStderr = true
            });
            var standardOutputTask = GetContainerLogsAsync(new ContainerLogsParameters {
                ShowStdout = true
            });

            return(new ContainerExecutionResult
            {
                ExitCode = containerInspection.State.ExitCode,
                ErrorOutput = await errorOutputTask,
                StandardOutput = await standardOutputTask
            });
        }
示例#23
0
        private async Task <bool> StartService(DenService service)
        {
            string id      = string.Empty;
            bool   started = false;

            try
            {
                if (this.OnLog != null)
                {
                    this.OnLog($"{service.Name}");
                }
                await service.CreateImage();

                CreateContainerResponse ccr = await service.CreateContainer(service.ImageName);

                if (this.OnLog != null)
                {
                    this.OnLog($"{service.Name} created");
                }
                id = ccr.ID;

                if (this.OnLog != null)
                {
                    this.OnLog($"Starting {service.Name}");
                }

                started = id != string.Empty? await service.StartContainer(id): false;

                if (!started)
                {
                    if (this.OnError != null)
                    {
                        this.OnError(new Exception($"Error running {service.Name} container"));
                    }
                }
                else
                {
                    if (this.OnLog != null)
                    {
                        this.OnLog($"{service.Name} started");
                    }

                    if (service is DenHealthCheckService denHealthCheckService)
                    {
                        if (this.OnLog != null)
                        {
                            this.OnLog($"Waiting for {service.Name} health status");
                        }

                        started = await service.IsHealthy();

                        if (started)
                        {
                            if (this.OnLog != null)
                            {
                                this.OnLog($"{service.Name} is healthy");
                            }
                        }
                    }

                    this.RunningDenServices.Add(service);
                }
            }
            catch (DockerImageNotFoundException e)
            {
                this.OnError(e);
            }
            catch (DockerApiException e)
            {
                this.OnError(e);
            }

            return(started);
        }
示例#24
0
        /// <summary>
        ///     Execute a deployment.
        /// </summary>
        /// <param name="deploymentId">
        ///     A unique identifier for the deployment.
        /// </param>
        /// <param name="templateImageTag">
        ///     The tag of the Docker image that implements the deployment template.
        /// </param>
        /// <param name="templateParameters">
        ///     A dictionary containing global template parameters to be written to the state directory.
        /// </param>
        /// <returns>
        ///     <c>true</c>, if the deployment was started; otherwise, <c>false</c>.
        ///
        ///     TODO: Consider returning an enum instead.
        /// </returns>
        public async Task <bool> DeployAsync(string deploymentId, string templateImageTag, IDictionary <string, string> templateParameters)
        {
            if (String.IsNullOrWhiteSpace(templateImageTag))
            {
                throw new ArgumentException("Must supply a valid template image name.", nameof(templateImageTag));
            }

            if (templateParameters == null)
            {
                throw new ArgumentNullException(nameof(templateParameters));
            }

            try
            {
                Log.LogInformation("Starting deployment '{DeploymentId}' using image '{ImageTag}'...", deploymentId, templateImageTag);

                Log.LogInformation("Determining deployer's external IP address...");
                IPAddress deployerIPAddress = await GetDeployerIPAddressAsync();

                Log.LogInformation("Deployer's external IP address is '{DeployerIPAddress}'.", deployerIPAddress);
                templateParameters["deployment_ip"] = deployerIPAddress.ToString();

                DirectoryInfo deploymentLocalStateDirectory = GetLocalStateDirectory(deploymentId);
                DirectoryInfo deploymentHostStateDirectory  = GetHostStateDirectory(deploymentId);

                Log.LogInformation("Local state directory for deployment '{DeploymentId}' is '{LocalStateDirectory}'.", deploymentId, deploymentLocalStateDirectory.FullName);
                Log.LogInformation("Host state directory for deployment '{DeploymentId}' is '{LocalStateDirectory}'.", deploymentId, deploymentHostStateDirectory.FullName);

                WriteTemplateParameters(templateParameters, deploymentLocalStateDirectory);

                CreateContainerParameters createParameters = new CreateContainerParameters
                {
                    Name         = "deploy-" + deploymentId,
                    Image        = templateImageTag,
                    AttachStdout = true,
                    AttachStderr = true,
                    HostConfig   = new HostConfig
                    {
                        Binds = new List <string>
                        {
                            $"{deploymentHostStateDirectory.FullName}:/root/state"
                        },
                        LogConfig = new LogConfig
                        {
                            Type   = "json-file",
                            Config = new Dictionary <string, string>()
                        }
                    },
                    Env = new List <string>
                    {
                        "ANSIBLE_NOCOLOR=1" // Disable coloured output because escape sequences look weird in the log.
                    },
                    Labels = new Dictionary <string, string>
                    {
                        ["task.type"]                    = "deployment",
                        ["deployment.id"]                = deploymentId,
                        ["deployment.action"]            = "Deploy",
                        ["deployment.image.deploy.tag"]  = templateImageTag,
                        ["deployment.image.destroy.tag"] = GetDestroyerImageTag(templateImageTag)
                    }
                };

                CreateContainerResponse newContainer = await Client.Containers.CreateContainerAsync(createParameters);

                string containerId = newContainer.ID;
                Log.LogInformation("Created container '{ContainerId}'.", containerId);

                await Client.Containers.StartContainerAsync(containerId, new HostConfig());

                Log.LogInformation("Started container: '{ContainerId}'.", containerId);

                return(true);
            }
            catch (Exception unexpectedError)
            {
                Log.LogError("Unexpected error while executing deployment '{DeploymentId}': {Error}", deploymentId, unexpectedError);

                return(false);
            }
        }
示例#25
0
        public PlcOpcUaServer()
        {
            Uri dockerUri = null;

            try
            {
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    dockerUri = new Uri("tcp://localhost:2375");
                }
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                {
                    dockerUri = new Uri("unix:///var/run/docker.sock");
                }
                if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
                {
                    dockerUri = new Uri("not supported");
                }
                _dockerClient = new DockerClientConfiguration(dockerUri).CreateClient();
            }
            catch
            {
                throw new Exception($"Please adjust your docker deamon endpoint '{dockerUri}' for your configuration.");
            }

            // cleanup all PLC containers
            CleanupContainerAsync().Wait();

            // pull the latest image
            ImagesCreateParameters createParameters = new ImagesCreateParameters();

            createParameters.FromImage = _plcImage;
            createParameters.Tag       = "latest";
            try
            {
                _dockerClient.Images.CreateImageAsync(createParameters, new AuthConfig(), new Progress <JSONMessage>()).Wait();
            }
            catch (Exception)
            {
                throw new Exception($"Cannot pull image '{_plcImage}");
            }

            ImageInspectResponse imageInspectResponse = _dockerClient.Images.InspectImageAsync(_plcImage).Result;

            // create a new container
            CreateContainerParameters containerParams = new CreateContainerParameters();

            containerParams.Image    = _plcImage;
            containerParams.Hostname = "opcplc";
            containerParams.Name     = "opcplc";
            containerParams.Cmd      = new string[]
            {
                "--aa",
                "--pn", $"{_plcPort}"
            };
            // workaround .NET2.1 issue for private key access
            if (imageInspectResponse.Os.Equals("windows", StringComparison.InvariantCultureIgnoreCase))
            {
                containerParams.Cmd.Add("--at");
                containerParams.Cmd.Add("X509Store");
            }
            containerParams.ExposedPorts = new Dictionary <string, EmptyStruct>();
            containerParams.ExposedPorts.Add(new KeyValuePair <string, EmptyStruct>($"{_plcPort}/tcp", new EmptyStruct()));
            containerParams.HostConfig = new HostConfig();
            PortBinding portBinding = new PortBinding();

            portBinding.HostPort = _plcPort;
            portBinding.HostIP   = null;
            List <PortBinding> portBindings = new List <PortBinding>();

            portBindings.Add(portBinding);
            containerParams.HostConfig.PortBindings = new Dictionary <string, IList <PortBinding> >();
            containerParams.HostConfig.PortBindings.Add($"{_plcPort}/tcp", portBindings);
            CreateContainerResponse response = null;

            try
            {
                response        = _dockerClient.Containers.CreateContainerAsync(containerParams).Result;
                _plcContainerId = response.ID;
            }
            catch (Exception)
            {
                throw;
            }

            try
            {
                _dockerClient.Containers.StartContainerAsync(_plcContainerId, new ContainerStartParameters()).Wait();
            }
            catch (Exception)
            {
                throw;
            }
        }
 private async Task <bool> StartContainer(CreateContainerResponse containerResponse)
 {
     return(await _repository.StartContainer(containerResponse.ID));
 }
示例#27
0
        /// <summary>
        ///     Destroy a deployment.
        /// </summary>
        /// <param name="deploymentId">
        ///     The deployment Id.
        /// </param>
        /// <returns>
        ///     <c>true</c>, if the deployment was started; otherwise, <c>false</c>.
        ///
        ///     TODO: Consider returning an enum instead.
        /// </returns>
        public async Task <bool> DestroyAsync(string deploymentId)
        {
            if (String.IsNullOrWhiteSpace(deploymentId))
            {
                throw new ArgumentException("Must supply a valid deployment Id.", nameof(deploymentId));
            }

            Log.LogInformation("Destroy deployment '{DeploymentId}'.", deploymentId);

            try
            {
                IList <ContainerListResponse> matchingContainers = await Client.Containers.ListContainersAsync(new ContainersListParameters
                {
                    All     = true,
                    Filters = new FiltersDictionary
                    {
                        ["label"] = new FilterDictionary
                        {
                            ["deployment.id=" + deploymentId] = true
                        }
                    }
                });

                if (matchingContainers.Count == 0)
                {
                    Log.LogError("Deployment '{DeploymentId}' not found.");

                    return(false);
                }

                string destroyerImageTag = matchingContainers[0].Labels["deployment.image.destroy.tag"];

                Log.LogInformation("Starting destruction of deployment '{DeploymentId}' using image '{DestroyerImageTag}'...", deploymentId, destroyerImageTag);

                DirectoryInfo deploymentLocalStateDirectory = GetLocalStateDirectory(deploymentId);
                DirectoryInfo deploymentHostStateDirectory  = GetHostStateDirectory(deploymentId);

                Log.LogInformation("Local state directory for deployment '{DeploymentId}' is '{LocalStateDirectory}'.", deploymentId, deploymentLocalStateDirectory.FullName);
                Log.LogInformation("Host state directory for deployment '{DeploymentId}' is '{LocalStateDirectory}'.", deploymentId, deploymentHostStateDirectory.FullName);

                CreateContainerParameters createParameters = new CreateContainerParameters
                {
                    Name         = "destroy-" + deploymentId,
                    Image        = destroyerImageTag,
                    AttachStdout = true,
                    AttachStderr = true,
                    Tty          = false,
                    HostConfig   = new HostConfig
                    {
                        Binds = new List <string>
                        {
                            $"{deploymentHostStateDirectory.FullName}:/root/state"
                        },
                        LogConfig = new LogConfig
                        {
                            Type   = "json-file",
                            Config = new Dictionary <string, string>()
                        }
                    },
                    Env = new List <string>
                    {
                        "ANSIBLE_NOCOLOR=1" // Disable coloured output because escape sequences look weird in the log.
                    },
                    Labels = new Dictionary <string, string>
                    {
                        ["task.type"]                    = "deployment",
                        ["deployment.id"]                = deploymentId,
                        ["deployment.action"]            = "Destroy",
                        ["deployment.image.destroy.tag"] = destroyerImageTag
                    }
                };

                CreateContainerResponse newContainer = await Client.Containers.CreateContainerAsync(createParameters);

                string containerId = newContainer.ID;
                Log.LogInformation("Created container '{ContainerId}'.", containerId);

                await Client.Containers.StartContainerAsync(containerId, new HostConfig());

                Log.LogInformation("Started container: '{ContainerId}'.", containerId);

                return(true);
            }
            catch (Exception unexpectedError)
            {
                Log.LogError("Unexpected error while destroying deployment '{DeploymentId}': {Error}", deploymentId, unexpectedError);

                return(false);
            }
        }
示例#28
0
        /// <summary>
        ///     Called when the <see cref="Client"/> is ready to handle requests.
        /// </summary>
        void Ready()
        {
            // TODO: Handle termination of underlying Connection actor.

            Receive <ListImages>(listImages =>
            {
                var executeCommand = new Connection.ExecuteCommand(listImages, async(dockerClient, cancellationToken) =>
                {
                    var parameters = new ImagesListParameters
                    {
                        MatchName = listImages.MatchName,
                        All       = listImages.All,
                        Filters   = listImages.Filters.ToMutable()
                    };
                    IList <ImagesListResponse> images = await dockerClient.Images.ListImagesAsync(parameters);

                    return(new ImageList(listImages.CorrelationId, images));
                });

                _connection.Tell(executeCommand, Sender);
            });
            Receive <CreateContainer>(createContainer =>
            {
                var executeCommand = new Connection.ExecuteCommand(createContainer, async(dockerClient, cancellationToken) =>
                {
                    var parameters = new CreateContainerParameters
                    {
                        Image        = createContainer.Image,
                        Name         = createContainer.Name,
                        AttachStdout = createContainer.AttachStdOut,
                        AttachStderr = createContainer.AttachStdErr,
                        AttachStdin  = createContainer.AttachStdIn,
                        Tty          = createContainer.TTY,
                        HostConfig   = new HostConfig
                        {
                            // Hard-coded for now.
                            LogConfig = new LogConfig
                            {
                                Type = createContainer.LogType
                            }
                        }

                        // TODO: Add other parameters.
                    };
                    if (createContainer.EnvironmentVariables.Count > 0)
                    {
                        parameters.Env = createContainer.EnvironmentVariables
                                         .Select(
                            environmentVariable => $"{environmentVariable.Key}={environmentVariable.Value}"
                            )
                                         .ToList();
                    }
                    if (createContainer.Binds.Count > 0)
                    {
                        parameters.HostConfig.Binds = createContainer.Binds
                                                      .Select(
                            bind => $"{bind.Key}:{bind.Value}"
                            )
                                                      .ToList();
                    }
                    if (createContainer.Ports.Count > 0)
                    {
                        parameters.ExposedPorts = createContainer.Ports.ToDictionary(
                            port => port.Key,
                            port => (object)port.Value
                            );
                    }

                    CreateContainerResponse response = await dockerClient.Containers.CreateContainerAsync(parameters);

                    return(new ContainerCreated(createContainer.CorrelationId, response));
                });

                _connection.Tell(executeCommand, Sender);
            });
            Receive <StartContainer>(startContainer =>
            {
                var executeCommand = new Connection.ExecuteCommand(startContainer, async(dockerClient, cancellationToken) =>
                {
                    ContainerStartParameters parameters = new ContainerStartParameters
                    {
                        DetachKeys = startContainer.DetachKeys
                    };
                    bool containerWasStarted = await dockerClient.Containers.StartContainerAsync(startContainer.ContainerId, parameters);

                    return(new ContainerStarted(startContainer.CorrelationId, startContainer.ContainerId,
                                                alreadyStarted: !containerWasStarted
                                                ));
                });

                _connection.Tell(executeCommand, Sender);
            });
            Receive <StopContainer>(stopContainer =>
            {
                var executeCommand = new Connection.ExecuteCommand(stopContainer, async(dockerClient, cancellationToken) =>
                {
                    var parameters = new ContainerStopParameters
                    {
                        WaitBeforeKillSeconds = stopContainer.WaitBeforeKillSeconds
                    };
                    bool containerWasStopped = await dockerClient.Containers.StopContainerAsync(stopContainer.ContainerId, parameters, cancellationToken);

                    return(new ContainerStopped(stopContainer.CorrelationId, stopContainer.ContainerId,
                                                alreadyStopped: !containerWasStopped
                                                ));
                });

                _connection.Tell(executeCommand, Sender);
            });
            Receive <RemoveContainer>(removeContainer =>
            {
                var executeCommand = new Connection.ExecuteCommand(removeContainer, async(dockerClient, cancellationToken) =>
                {
                    await dockerClient.Containers.RemoveContainerAsync(removeContainer.ContainerId, removeContainer.Parameters);

                    return(new ContainerRemoved(removeContainer.CorrelationId,
                                                removeContainer.ContainerId
                                                ));
                });

                _connection.Tell(executeCommand, Sender);
            });
            Receive <GetContainerLogs>(getContainerLogs =>
            {
                Log.Debug("Received GetContainerLogs request '{0}' from '{1}'.", getContainerLogs.CorrelationId, Sender);

                var executeCommand = new Connection.ExecuteCommand(getContainerLogs, async(dockerClient, cancellationToken) =>
                {
                    Stream responseStream = await dockerClient.Containers.GetContainerLogsAsync(
                        getContainerLogs.ContainerId,
                        getContainerLogs.Parameters,
                        cancellationToken
                        );

                    return(new StreamedResponse(getContainerLogs.CorrelationId, responseStream, format: StreamedResponseFormat.Log));
                });

                _connection.Tell(executeCommand, Sender);
            });
            Receive <MonitorContainerEvents>(monitorContainerEvents =>
            {
                Log.Debug("Received MonitorContainerEvents request '{0}' from '{1}'.", monitorContainerEvents.CorrelationId, Sender);

                var executeCommand = new Connection.ExecuteCommand(monitorContainerEvents, async(dockerClient, cancellationToken) =>
                {
                    Stream responseStream = await dockerClient.Miscellaneous.MonitorEventsAsync(monitorContainerEvents.Parameters, cancellationToken);

                    return(new StreamedResponse(monitorContainerEvents.CorrelationId, responseStream, format: StreamedResponseFormat.Events));
                });

                _connection.Tell(executeCommand, Sender);
            });
            Receive <CancelRequest>(cancelRequest =>
            {
                _connection.Forward(cancelRequest);
            });
            Receive <EventBusActor.Subscribe>(subscribeToDockerEvents =>
            {
                if (_dockerEventBus == null)
                {
                    _dockerEventBus = Context.ActorOf(
                        DockerEventBus.Create(Self),
                        name: DockerEventBus.ActorName
                        );
                }

                _dockerEventBus.Forward(subscribeToDockerEvents);
            });
            Receive <EventBusActor.Unsubscribe>(unsubscribeFromDockerEvents =>
            {
                if (_dockerEventBus == null)
                {
                    return;
                }

                _dockerEventBus.Forward(unsubscribeFromDockerEvents);
            });
        }