Skip to content

Commit f5a91ff

Browse files
committed
layer: revamp for readability
When adding verbiage for restriction on duplicate entries in the tar archive, it was not immediately clear where this information would be organized. This revamp seeks to make the document on the whole more suitable for implementors and be interpretable for compliance. Signed-off-by: Vincent Batts <[email protected]>
1 parent 364b09a commit f5a91ff

File tree

1 file changed

+145
-37
lines changed

1 file changed

+145
-37
lines changed

layer.md

Lines changed: 145 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,200 @@
1-
# OpenContainers Image Layers Specification
1+
# Image Layer Filesystem Changeset
22

3-
This specification describes how to serialize a filesystem and filesystem changes like removed files into a blob called a layer.
4-
To create a complete filesystem one or more layers are ordered on top of each other.
3+
This document describes how to serialize a filesystem and filesystem changes like removed files into a blob called a layer.
4+
One or more layers are ordered on top of each other to create a complete filesystem.
55
This document will use a concrete example to illustrate how to create and consume these filesystem layers.
66

7-
## Creating an Image Layers Based on Filesystem Changes
7+
## Distributable Format
88

9-
An example of creating image filesystem layers follows.
9+
Layer Changesets for the [mediatype](./media-types.md) `application/vnd.oci.image.layer.tar+gzip` MUST be packaged in [tar archive][tar-archive].
10+
Layer Changesets for the [mediatype](./media-types.md) `application/vnd.oci.image.layer.tar+gzip` MUST NOT include duplicate entries for file paths in the resulting [tar archive][tar-archive].
1011

11-
An image root filesystem is first created as an empty directory.
12-
Here is the initial empty directory structure for a changeset using the randomly-generated directory name `c3167915dc9d` ([actual layer DiffIDs are generated based on the content](#id_desc)).
12+
## Change Types
13+
14+
Types of changes that can occur in a changeset are:
15+
16+
* Additions
17+
* Modifications
18+
* Removals
19+
20+
Additions and Modifications are represented the same in the changeset tar archive.
21+
22+
Removals are represented using "[whiteout](#whiteouts)" file entries (See [Representing Changes](#representing-changes)).
23+
24+
### File Types
25+
26+
Throughout this document section, the use of word "files" includes:
27+
28+
* regular files
29+
* directories
30+
* sockets
31+
* symbolic links
32+
* block devices
33+
* character devices
34+
* FIFOs
35+
36+
### File Attributes
37+
38+
Where supported, MUST include file attributes for Additions and Modifications include:
39+
40+
* Modification Time (`mtime`)
41+
* User ID (`uid`)
42+
* User Name (`uname`) *secondary to `uid`*
43+
* Group ID (`gid `)
44+
* Group Name (`gname`) *secondary to `gid`*
45+
* Mode (`mode`)
46+
* Extended Attributes (`xattrs`)
47+
* Symlink reference (`linkname`)
48+
49+
[Sparse files](https://en.wikipedia.org/wiki/Sparse_file) SHOULD NOT be used because they lack consistent support across tar implementations.
50+
51+
## Creating
52+
53+
### Initial Root Filesystem
54+
55+
The initial root filesystem is the base or parent layer.
56+
57+
For this example, an image root filesystem has an initial state as an empty directory.
58+
The name of the directory is not relevant to the layer itself, only for the purpose of producing comparisons.
59+
60+
Here is an initial empty directory structure for a changeset, with a unique directory name `rootfs-c9d-v1`.
1361

1462
```
15-
c3167915dc9d/
63+
rootfs-c9d-v1/
1664
```
1765

66+
### Populate Initial Filesystem
67+
1868
Files and directories are then created:
1969

2070
```
21-
c3167915dc9d/
71+
rootfs-c9d-v1/
2272
etc/
2373
my-app-config
2474
bin/
2575
my-app-binary
2676
my-app-tools
2777
```
2878

29-
The `c3167915dc9d` directory is then committed as a plain Tar archive with entries for the following files:
79+
The `rootfs-c9d-v1` directory is then created as a plain [tar archive][tar-archive] with relative path to `rootfs-c9d-v1`.
80+
Entries for the following files:
3081

3182
```
32-
etc/my-app-config
33-
bin/my-app-binary
34-
bin/my-app-tools
83+
./
84+
./etc/
85+
./etc/my-app-config
86+
./bin/
87+
./bin/my-app-binary
88+
./bin/my-app-tools
3589
```
3690

37-
To make changes to the filesystem of this image, create a new directory, such as `f60c56784b83`, and initialize it with a snapshot of the parent image's root filesystem, so that the directory is identical to that of `c3167915dc9d`.
91+
### Populate a Comparison Filesystem
92+
93+
Create a new directory and initialize it with an copy or snapshot of the prior root filesystem.
94+
Example commands that can preserve [file attributes](#file-attributes) to make this copy are:
95+
* [cp(1)](http://linux.die.net/man/1/cp): `cp -a rootfs-c9d-v1/ rootfs-c9d-v1.s1/`
96+
* [rsync(1)](http://linux.die.net/man/1/rsync): `rsync -aHAX rootfs-c9d-v1/ rootfs-c9d-v1.s1/`
97+
* [tar(1)](http://linux.die.net/man/1/tar): `mkdir rootfs-c9d-v1.s1 && tar --acls --xattrs -C rootfs-c9d-v1/ -c . | tar -C rootfs-c9d-v1.s1/ --acls --xattrs -x` (including `--selinux` where supported)
3898

39-
**Implementor's Note:** a copy-on-write or union filesystem can make this very efficient.
99+
Any [changes](#change-types) to the snapshot MUST NOT change or affect the directory it was copied from.
100+
101+
For example `rootfs-c9d-v1.s1` is an identical snapshot of `rootfs-c9d-v1`.
102+
In this way `rootfs-c9d-v1.s1` is prepared for updates and alterations.
103+
104+
**Implementor's Note**: *a copy-on-write or union filesystem can efficiently make directory snapshots*
105+
106+
Initial layout of the snapshot:
40107

41108
```
42-
f60c56784b83/
109+
rootfs-c9d-v1.s1/
43110
etc/
44111
my-app-config
45112
bin/
46113
my-app-binary
47114
my-app-tools
48115
```
49116

50-
This example change is going to add a configuration directory at `/etc/my-app.d` which contains a default config file.
51-
There's also a change to the `my-app-tools` binary to handle the config layout change.
52-
The `f60c56784b83` directory then looks like this:
117+
See [Change Types](#change-types) for more details on changes.
118+
119+
For example, add a directory at `/etc/my-app.d` containing a default config file, removing the existing config file.
120+
Also a change (in attribute or file content) to `./bin/my-app-tools` binary to handle the config layout change.
121+
122+
Following these changes, the representation of the `rootfs-c9d-v1.s1` directory:
53123

54124
```
55-
f60c56784b83/
125+
rootfs-c9d-v1.s1/
56126
etc/
57-
.wh.my-app-config
58127
my-app.d/
59128
default.cfg
60129
bin/
61130
my-app-binary
62131
my-app-tools
63132
```
64133

65-
This reflects the removal of `/etc/my-app-config` and creation of a file and directory at `/etc/my-app.d/default.cfg`.
66-
`/bin/my-app-tools` has also been replaced with an updated version.
67-
Before committing this directory to a changeset, because it has a parent image, it is first compared with the directory tree of the parent snapshot, `f60c56784b83`, looking for files and directories that have been added, modified, or removed.
134+
### Determining Changes
135+
136+
When two directories are compared, the relative root is the top-level directory.
137+
The directories are compared, looking for files that have been [added, modified, or removed](#change-types).
138+
139+
For this example, `rootfs-c9d-v1/` and `rootfs-c9d-v1.s1/` are recursively compared, each as relative root path.
140+
68141
The following changeset is found:
69142

70143
```
144+
Added: /etc/my-app.d/
71145
Added: /etc/my-app.d/default.cfg
72146
Modified: /bin/my-app-tools
73147
Deleted: /etc/my-app-config
74148
```
75149

76-
A Tar Archive is then created which contains *only* this changeset:
150+
This reflects the removal of `/etc/my-app-config` and creation of a file and directory at `/etc/my-app.d/default.cfg`.
151+
`/bin/my-app-tools` has also been replaced with an updated version.
77152

78-
- Added and modified files and directories in their entirety
79-
- Deleted files or directory marked with a whiteout file
153+
### Representing Changes
80154

81-
A whiteout file is an empty file that prefixes the deleted paths basename `.wh.`.
82-
When a whiteout is found in the upper changeset of a filesystem, any matching name in the lower changeset is ignored, and the whiteout itself is also hidden.
83-
As files prefixed with `.wh.` are special whiteout tombstones it is not possible to create a filesystem which has a file or directory with a name beginning with `.wh.`.
155+
A [tar archive][tar-archive] is then created which contains *only* this changeset:
84156

85-
The resulting Tar archive for `f60c56784b83` has the following entries:
157+
- Added and modified files and directories in their entirety
158+
- Deleted files or directories marked with a [whiteout file](#whiteouts)
159+
160+
The resulting tar archive for `rootfs-c9d-v1.s1` has the following entries:
86161

87162
```
88-
/etc/my-app.d/default.cfg
89-
/bin/my-app-tools
90-
/etc/.wh.my-app-config
163+
./etc/my-app.d/
164+
./etc/my-app.d/default.cfg
165+
./bin/my-app-tools
166+
./etc/.wh.my-app-config
91167
```
92168

93-
Whiteout files MUST only apply to resources in lower layers.
169+
Where the basename name of `./etc/my-app-config` is now prefixed with `.wh.`, and will therefore be removed when the changeset is applied.
170+
171+
## Applying
172+
173+
Layer Changesets of [mediatype](./media-types.md) `application/vnd.oci.image.layer.tar+gzip` are applied rather than strictly extracted in normal fashion for tar archives.
174+
175+
Applying a layer changeset requires consideration for the [whiteout](#whiteouts) files.
176+
In the absence of any [whiteout](#whiteouts) files in a layer changeset, the archive is extracted like a regular tar archive.
177+
178+
179+
### Changeset over existing files
180+
181+
This section covers applying an entry in a layer changeset, if the file path already exists.
182+
183+
If the file path is a directory, then the existing path just has it's attribute set from the layer changeset for that filepath.
184+
If the file path is any other file type (regular file, FIFO, etc), then the:
185+
* file path is unlinked (See [`unlink(2)`](http://linux.die.net/man/2/unlink))
186+
* create the file
187+
* If a regular file then content written.
188+
* set attributes on the filepath
189+
190+
## Whiteouts
191+
192+
A whiteout file is an empty file with a special filename that signifies a path should be deleted.
193+
A whiteout filename consists of the prefix .wh. plus the basename of the path to be deleted.
194+
As files prefixed with `.wh.` are special whiteout markers, it is not possible to create a filesystem which has a file or directory with a name beginning with `.wh.`.
195+
196+
Once a whiteout is applied, the whiteout itself MUST also be hidden.
197+
Whiteout files MUST only apply to resources in lower/parent layers.
94198
Files that are present in the same layer as a whiteout file can only be hidden by whiteout files in subsequent layers.
95199
The following is a base layer with several resources:
96200

@@ -124,6 +228,8 @@ a/.wh..wh..opq
124228

125229
Implementations SHOULD generate layers such that the whiteout files appear before sibling directory entries.
126230

231+
### Opaque Whiteout
232+
127233
In addition to expressing that a single entry should be removed from a lower layer, layers may remove all of the children using an opaque whiteout entry.
128234
An opaque whiteout entry is a file with the name `.wh..wh..opq` indicating that all siblings are hidden in the lower layer.
129235
Let's take the following base layer as an example:
@@ -146,7 +252,7 @@ bin/
146252
```
147253

148254
This is called _opaque whiteout_ format.
149-
An _opaque whiteout_ file hides _all_ children of the `bin/` including sub-directories and all descendents.
255+
An _opaque whiteout_ file hides _all_ children of the `bin/` including sub-directories and all descendants.
150256
Using _explicit whiteout_ files, this would be equivalent to the following:
151257

152258
```
@@ -158,8 +264,10 @@ bin/
158264

159265
In this case, a unique whiteout file is generated for each entry.
160266
If there were more children of `bin/` in the base layer, there would be an entry for each.
161-
Note that this opaque file will apply to _all_ children, including sub-directories, other resources and all descendents.
267+
Note that this opaque file will apply to _all_ children, including sub-directories, other resources and all descendants.
162268

163269
Implementations SHOULD generate layers using _explicit whiteout_ files, but MUST accept both.
164270

165271
Any given image is likely to be composed of several of these Image Filesystem Changeset tar archives.
272+
273+
[tar-archive]: https://en.wikipedia.org/wiki/Tar_(computing)

0 commit comments

Comments
 (0)