Skip to content

Commit c375847

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 55691e3 commit c375847

1 file changed

Lines changed: 93 additions & 33 deletions

File tree

layer.md

Lines changed: 93 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,109 @@
1-
# Creating an Image Filesystem Changeset
1+
# Filesystem Layer Changeset
22

3-
An example of creating an Image Filesystem Changeset follows.
3+
A layer changeset is the distributable difference between filesystems.
4+
A layer changeset is not directly extracted, but applied to a filesystem.
45

5-
An image root filesystem is first created as an empty directory.
6-
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)).
6+
## Distributable Format
7+
8+
Layer Changesets for the [mediatype](./media-types.md) `application/vnd.oci.image.layer.tar+gzip` MUST be packaged in [tar archive][tar-archive].
9+
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].
10+
11+
## Change Types
12+
13+
Types of changes that can occur in a changeset are:
14+
15+
* Additions
16+
* Modifications
17+
* Removals
18+
19+
Additions and Modifications are reflected the same in the changeset tar archive.
20+
21+
Removals are reflected using "[whiteout](#whiteouts)" file entries (See [Representing Changes](#representing-changes)).
22+
23+
## Creating
24+
25+
### Initial Root Filesystem
26+
27+
An image root filesystem has an initial state as an empty directory.
28+
The name of the directory is not relevant to the layer itself, only for the purpose of producing comparisons.
29+
30+
Here is an initial empty directory structure for a changeset, with a unique directory name `rootfs-c9d-v1`.
731

832
```
9-
c3167915dc9d/
33+
rootfs-c9d-v1/
1034
```
1135

36+
### Populate Initial Filesystem
37+
1238
Files and directories are then created:
1339

1440
```
15-
c3167915dc9d/
41+
rootfs-c9d-v1/
1642
etc/
1743
my-app-config
1844
bin/
1945
my-app-binary
2046
my-app-tools
2147
```
2248

23-
The `c3167915dc9d` directory is then committed as a plain Tar archive with entries for the following files:
49+
The `rootfs-c9d-v1` directory is then committed as a plain [Tar archive][tar-archive] with relative path to `rootfs-c9d-v1`.
50+
Entries for the following files:
2451

2552
```
26-
etc/my-app-config
27-
bin/my-app-binary
28-
bin/my-app-tools
53+
./
54+
./etc/
55+
./etc/my-app-config
56+
./bin/
57+
./bin/my-app-binary
58+
./bin/my-app-tools
2959
```
3060

31-
To make changes to the filesystem of this container 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`.
32-
NOTE: a copy-on-write or union filesystem can make this very efficient:
61+
### Populate a Comparison Filesystem
62+
63+
Create a new directory and initialize it with an identical copy or snapshot of the prior root filesystem.
64+
Any changes to the snapshot MUST not change or affect the directory it was copied from.
65+
66+
For example `rootfs-c9d-v1.s1` is an identical snapshot of `rootfs-c9d-v1`.
67+
In this way `rootfs-c9d-v1.s1` is prepared for updates and alterations.
68+
69+
**NOTE**: *a copy-on-write or union filesystem can efficiently make directory snapshots*
70+
71+
Initial layout of the snapshot:
3372

3473
```
35-
f60c56784b83/
74+
rootfs-c9d-v1.s1/
3675
etc/
3776
my-app-config
3877
bin/
3978
my-app-binary
4079
my-app-tools
4180
```
4281

43-
This example change is going to add a configuration directory at `/etc/my-app.d` which contains a default config file.
44-
There's also a change to the `my-app-tools` binary to handle the config layout change.
45-
The `f60c56784b83` directory then looks like this:
82+
Changes include new files, file and path removals, and updates to file attributes (mtime, uid, gid, mode, xattrs, etc.).
83+
84+
For example, add a directory at `/etc/my-app.d` containing a default config file, removing the existing config file.
85+
Also a change to the `./bin/my-app-tools` binary to handle the config layout change.
86+
87+
Following these changes, the representation of the `rootfs-c9d-v1.s1` directory:
4688

4789
```
48-
f60c56784b83/
90+
rootfs-c9d-v1.s1/
4991
etc/
50-
.wh.my-app-config
5192
my-app.d/
5293
default.cfg
5394
bin/
5495
my-app-binary
5596
my-app-tools
5697
```
5798

58-
This reflects the removal of `/etc/my-app-config` and creation of a file and directory at `/etc/my-app.d/default.cfg`.
59-
`/bin/my-app-tools` has also been replaced with an updated version.
60-
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.
99+
### Determining Changes
100+
101+
When two directories are compared, the relative root is the top-level directory.
102+
The directories are compared, looking for files that have been added, modified, or removed.
103+
Where "files" includes regular files, directories, sockets, symbolic links, block devices, character devices and FIFOs.
104+
105+
For this example, `rootfs-c9d-v1/` and `rootfs-c9d-v1.s1/` are recursively compared, each as relative root path.
106+
61107
The following changeset is found:
62108

63109
```
@@ -66,23 +112,33 @@ Modified: /bin/my-app-tools
66112
Deleted: /etc/my-app-config
67113
```
68114

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

71-
- Added and modified files and directories in their entirety
72-
- Deleted files or directory marked with a whiteout file
118+
### Representing Changes
73119

74-
A whiteout file is an empty file that prefixes the deleted paths basename `.wh.`.
75-
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.
76-
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.`.
120+
A [tar archive][tar-archive] is then created which contains *only* this changeset:
77121

78-
The resulting Tar archive for `f60c56784b83` has the following entries:
122+
- Added and modified files and directories in their entirety
123+
- Deleted files or directory marked with a [whiteout file](#whiteouts)
124+
125+
The resulting Tar archive for `rootfs-c9d-v1.s1` has the following entries:
79126

80127
```
81-
/etc/my-app.d/default.cfg
82-
/bin/my-app-tools
83-
/etc/.wh.my-app-config
128+
./etc/my-app.d/
129+
./etc/my-app.d/default.cfg
130+
./bin/my-app-tools
131+
./etc/.wh.my-app-config
84132
```
85133

134+
## Applying
135+
136+
## Whiteouts
137+
138+
A whiteout file is an empty file that prefixes the deleted paths basename with `.wh.`.
139+
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.`.
140+
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.
141+
86142
Whiteout files MUST only apply to resources in lower layers.
87143
Files that are present in the same layer as a whiteout file can only be hidden by whiteout files in subsequent layers.
88144
The following is a base layer with several resources:
@@ -117,6 +173,8 @@ a/.wh..wh..opq
117173

118174
Implementations SHOULD generate layers such that the whiteout files appear before sibling directory entries.
119175

176+
### Opaque Whiteout
177+
120178
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.
121179
An opaque whiteout entry is a file with the name `.wh..wh..opq` indicating that all siblings are hidden in the lower layer.
122180
Let's take the following base layer as an example:
@@ -139,7 +197,7 @@ bin/
139197
```
140198

141199
This is called _opaque whiteout_ format.
142-
An _opaque whiteout_ file hides _all_ children of the `bin/` including sub-directories and all descendents.
200+
An _opaque whiteout_ file hides _all_ children of the `bin/` including sub-directories and all descendants.
143201
Using _explicit whiteout_ files, this would be equivalent to the following:
144202

145203
```
@@ -151,8 +209,10 @@ bin/
151209

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

156214
Implementations SHOULD generate layers using _explicit whiteout_ files, but MUST accept both.
157215

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

0 commit comments

Comments
 (0)