buildkit/snapshot
Erik Sipsma 5c4dcb2741 cache: add support for Diff refs.
This allows you to create refs that are single layers representing the
diff between any two arbitrary refs. The primary use case for this is
to allows users to extract the changes created by ops like Exec and
rebase them elsewhere through MergeOp. However, there is no restriction
on the inputs to DiffOp and the resulting ref's layer is simply the
layer created by running the differ on the two inputs refs
(specifically, the same differ used during exports).

A Diff ref can be mounted by itself, in which case it is defined as the
result of applying the diff to Scratch. Most use cases though will use
Diff refs as the input to a MergeOp, in which case the diff is just
applied on top of the lower merge inputs, as was the case before.

In cases like Diff(A, A->B->C) (i.e. cases where the diff is between two
refs where the lower is an ancestor of upper), the diff will be defined
as the layers separating the two refs. In other cases, the diff is just
a single layer, not re-used from the inputs, representing the diff
between the two refs (which can be defined as the layer "Diff(A,B)" that
satisfies "Merge(A, Diff(A,B)) == B").

Note that there is technically a meaningful difference between the
"unmerge" behavior of extracting the layers separating diffs and the
"simple diff" of just running the differ on the two refs. Namely, in the
case where there are "intermediate deletes" (i.e. deletes that only
exist in layers between A and B but not between A and B by themselves),
then the simple diff and unmerge can create different results when
plugged into a MergeOp. This is due to the fact that intermediate
deletes will apply to the merge when using the unmerge behavior, but not
when using the simple diff. This is on top of the fact that the simple
diff inherently has a "flattening" behavior where multiple layers are
squashed into a single one.

So, in the case where lower is an ancestor of upper, we choose to follow
the unmerge behavior, but it's possible users may prefer the simple diff
behavior. As of right now, they won't be able to do so, but if needed we
can add the ability to choose which behavior is followed in the future.
This could be done through a flag provided to DiffOp or possibly by
adapting llb.Copy to support this type of behavior with the same
efficiency as DiffOp.

Signed-off-by: Erik Sipsma <erik@sipsma.dev>
2022-01-06 11:05:51 -08:00
..
containerd all: unify the specs-go package import alias to ocispecs 2021-08-11 08:29:09 +09:00
imagerefchecker all: unify the specs-go package import alias to ocispecs 2021-08-11 08:29:09 +09:00
diffapply_unix.go snapshot: cleanup diffApply and prepare for DiffOp 2021-12-09 21:21:35 -08:00
diffapply_windows.go snapshot: cleanup diffApply and prepare for DiffOp 2021-12-09 21:21:35 -08:00
localmounter.go snapshot: cleanup diffApply and prepare for DiffOp 2021-12-09 21:21:35 -08:00
localmounter_unix.go Add initial MergeOp implementation. 2021-11-18 11:10:48 -08:00
localmounter_windows.go Give a name to the only mount we care about 2020-07-24 20:40:46 +10:00
merge.go cache: add support for Diff refs. 2022-01-06 11:05:51 -08:00
snapshotter.go Disable redirect_dir for overlayfs snapshotter 2021-12-24 11:58:44 +09:00
snapshotter_test.go snapshot: cleanup diffApply and prepare for DiffOp 2021-12-09 21:21:35 -08:00
staticmountable.go Disable redirect_dir for overlayfs snapshotter 2021-12-24 11:58:44 +09:00