Потоковая передача файла tar в библиотеку Docker.DotNet? - PullRequest
0 голосов
/ 26 апреля 2019

У меня есть строка 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 без записи на диск?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...