Docker工具包分析-archive-v1.12.3
本次分析介绍Docker的archive工具包。之前说到”docker cp”命令用到了TarResourceRebase(),CopyTo(),TarResource()和Unpack()
。我们先来看压缩的代码。
压缩
TarResource()
TarResource()定义在/pkg/archive/copy.go中:
|
|
可以看出,TarResource()调用的是TarResourceRebase()。
TarResourceRebase()
TarResourceRebase()也定义在/pkg/archive/copy.go中:
|
|
可以看到,TarResourceRebase()调用的是TarWithOptions()。
Tar()
在介绍TarWithOptions()之前,先来介绍Tar(),定义在/pkg/archive/archive.go中:
|
|
可以看到,Tar()调用的也是TarWithOptions()。
TarWithOptions()
TarWithOptions()定义在/pkg/archive/archive.go中:
|
|
TarWithOptions()的流程如下:
- 调用io.Pipe()生成pipeReader, pipeWriter;
- 调用CompressStream()封装pipeWriter成compressWriter;
- 生成tarAppender;
- 遍历文件,调用tarAppender的addTarFile()把文件写入数据流;
- 返回pipeReader。
先来看CompressStream():
|
|
DecompressStream()的流程如下:
- 生成sync.Pool的封装BufioReader32KPool(加速垃圾回收),并从BufioReader32KPool获取一个buf;
- 依据压缩类型封装成不同的writerCloser,NewWriteCloserWrapper()允许自己定义Close()方法;
- 目前只支持Uncompressed和Gzip两种压缩形式。
再来看tarAppender的addTarFile():
|
|
addTarFile()的流程如下:
- 写入头文件信息;
- 读取文件内容;
- 把文件内容写入到TarWriter中。
现在写入的数据会自动经压缩包打包成数据流了。
解压
CopyTo()
先来看CopyTo(),定义在/pkg/archive/copy.go中:
|
|
可以看到,CopyTo()调用了Untar()。
Untar()
Untar()定义在/pkg/archive/archive.go中:
|
|
这里Untar()和UntarUncompressed()都会调用untarHandler()。
untarHandler()是如果需要解压,那么调用DecompressStream(),然后调用Unpack()。
DecompressStream()
DecompressStream()定义在/pkg/archive/archive.go中:
|
|
DecompressStream()会在Reader的基础上加一层解压操作。
Unpack()
Unpack()定义在/pkg/archive/archive.go中:
|
|
Unpack()的流程如下:
- 通过tar.NewReader()把Reader封装成tarReader;
- 然后调用Next()获取数据流中的数据包;
- 调用createTarFile()创建文件。
createTarFile()
|
|
createTarFile()目前还没吃透。
Demo
下面以Tar()和Untar()两个入口演示如何使用Docker的archive工具。
|
|