Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

`docker context export` writes a truncated tar archive

未关闭 适合新手
#7,332 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
92/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
docker, go
领域
cli

调研方向

从 cli/context/store/store.go 中的 Export() 开始,检查 tar writer 和 output writer 是如何关闭的。运行 cli/context/store 中现有的测试,然后验证包含 TLS 文件的导出 context 是一个可被 Python tarfile 和 macOS tar 接受的完整 tar 归档。

由索引模型根据 Issue 内容生成。

描述

Description

docker context export writes a truncated tar file. The two zero blocks that end a tar archive are never written, and when the context has TLS files, the padding after the last file is missing too.

docker context import still reads these files, because Go's archive/tar stops quietly at EOF. Other readers are stricter: with TLS files in the context, Python's tarfile rejects the export, and so does the macOS tar when reading it from a pipe (output below).

The cause is the order of these deferred calls in Export() in cli/context/store/store.go:

tw := tar.NewWriter(writer)
defer tw.Close()
defer writer.Close()

Deferred calls run last-in, first-out. So the pipe is closed first, and when tw.Close() then tries to write the padding and the trailer, it gets io.ErrClosedPipe. That error is ignored. The code hasn't changed since the context store was added in b34f340346f (2018).

Reproduce
$ openssl req -x509 -newkey rsa:2048 -nodes -keyout /dev/null -out ca.pem -days 1 -subj "/CN=example"
$ docker context create example --docker "host=tcp://127.0.0.1:2376,ca=$PWD/ca.pem"
example
Successfully created context "example"
$ docker context export example example.tar
Written file "example.tar"
$ wc -c < example.tar
3667

A tar file is always a multiple of 512 bytes, and 3667 isn't (the exact size depends on the certificate). The file stops 83 bytes into a block, right after the contents of tls/docker/ca.pem:

$ python3 -m tarfile -l example.tar
Traceback (most recent call last):
  ...
ReadError: unexpected end of data

$ docker context export example - | tar -tf - > /dev/null
tar: Truncated input file (needed 1536 bytes, only 1107 available)
tar: Error exit delayed from previous errors.
Expected behavior

A complete tar file: each file padded to a 512-byte boundary, then the end-of-archive marker. Other tar tools should be able to read the export too.

docker version
Client:
 Version:           29.8.0
 API version:       1.56
 Go version:        go1.26.8
 Git commit:        88096ef
 Built:             Thu Sep  3 21:49:43 2026
 OS/Arch:           darwin/amd64
 Context:           default

Server: Docker Desktop 4.91.0 (239619)
 Engine:
  Version:          29.8.0
  API version:      1.56 (minimum version 1.40)
  Go version:       go1.26.8
  Git commit:       3ce5872
  Built:            Thu Sep  3 21:51:20 2026
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          v2.3.4
  GitCommit:        db8809540e1a7a9da5d518876894933ff55692ab
 runc:
  Version:          1.4.3
  GitCommit:        v1.4.3-0-gbb14dabe
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
docker info
N/A, the daemon isn't involved. This happens in the CLI's context store (cli/context/store).
Additional Info

Same result with the CLI built from master (7fc2dff9bc).

Without TLS files the archive happens to end on a block boundary, and the readers above accept it. The end-of-archive marker is still missing, though.

Closing the tar writer before the pipe fixes it. With this change, the export from the steps above is a complete archive that both readers accept, and the existing tests in cli/context/store still pass:

tw := tar.NewWriter(writer)
defer func() {
	// Close the tar writer first, so that the padding and the
	// end-of-archive marker are written before the pipe is closed.
	writer.CloseWithError(tw.Close())
}()

Happy to open a PR for this.

主要语言
Go
星标
6.1k
派生
2.2k
平均合并
1 天 11 小时
30 天内合并 PR
45

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

docker/cli 的其他 Issue

查看 docker/cli 的全部 Issue

相似的 Issue

更多 Go Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。