У меня есть строка Dockerfile, _dockerfile
, которую я использую в качестве шаблона для генерации других файлов Dockerfile. Я пытаюсь взять сгенерированную строку шаблона _dockerfile
и упаковать ее в память в виде потока для Docker API. Демон Docker требует, чтобы поток был потоком tar из их документации на конечной точке /build
:
Входной поток должен быть архивом tar, сжатым с помощью одного из следующих алгоритмов: identity (без сжатия), gzip, bzip2, xz
В настоящее время я создаю его так с помощью библиотеки SharpZipLib:
public async Task BuildAsync() {
using (var inputMs = new MemoryStream(Encoding.ASCII.GetBytes(_dockerfile))) {
var outputMs = new MemoryStream() as Stream;
// Docker.DotNet.DockerClient.BuildImageFromDockerfileAsync requires a Stream in order to send it to the Docker daemon.
var builderStream = await _client.Images.BuildImageFromDockerfileAsync(CreateContext(inputMs, outputMs), new ImageBuildParameters() { Dockerfile = ".", Tags = new string[] { "test/test:latest" } });
using (var sr = new StreamReader(builderStream)) {
while (sr.Peek() > -1) {
var output = await sr.ReadLineAsync();
Console.WriteLine(output);
}
}
}
}
private Stream CreateContext(Stream input, Stream output) {
var tarOutputStream = new TarOutputStream(output);
var entry = TarEntry.CreateTarEntry("Dockerfile");
entry.Size = input.Length;
tarOutputStream.PutNextEntry(entry);
// read from the input stream, write to the local buffer,
// then write to the file.
var buffer = new byte[32 * 1024];
while (true) {
int numRead = input.Read(buffer, 0, buffer.Length);
if (numRead <= 0)
break;
tarOutputStream.Write(buffer, 0, numRead);
}
tarOutputStream.CloseEntry();
return tarOutputStream;
}
Когда я запускаю его, я получаю эту ошибку:
Docker.DotNet.DockerApiException: Docker API responded with status code=InternalServerError, response={"message":"unexpected error reading Dockerfile: read /var/lib/docker/tmp/docker-builder534485209: is a directory"}
Я думаю, что происходит, потому что я не закрыл поток архивов tar, он пытается читать из внутренней памяти демона? В любом случае, я знаю, что должен лучше обрабатывать потоковый конвейер.
Как я могу превратить строку в памяти в поток tar без записи на диск?