dnephin / dobi

A build automation tool for Docker applications
https://dnephin.github.io/dobi/
Apache License 2.0
309 stars 36 forks source link

Parent image change does not trigger child rebuild #141

Closed Enteee closed 6 years ago

Enteee commented 6 years ago

dobi version 0.11.1 (build: ee9138c, date: Sun Jun 24 19:40:44 UTC 2018)

When building an image on top of another one, dobi does not rebuild the child once the parent changes. with parent: all the images listed as dependencies.

.
├── A
│   ├── a
│   └── Dockerfile
├── B
│   └── Dockerfile
└── dobi.yaml

2 directories, 4 files

dobi.yaml:

image=image/A:
  image: "a"
  context: "A"
  tags: [
    "latest",
  ]

image=image/B:
  depends: [
    "image/A",
  ]
  image: "b"
  context: "B"
  tags: [
    "latest",
  ]

A/Dockerfile:

FROM alpine
COPY a a

A/a:

1

B/Dockerfile:

FROM a

When I run dobi image/B, this first builds image/A then image/B on top of the just built a.

$ dobi image/B
[WARN] meta.project is not set. Using default "dobi-bug".
Step 1/2 : FROM alpine
 ---> 3fd9065eaf02
Step 2/2 : COPY a a
 ---> 3b9f36f12977
Successfully built 3b9f36f12977
Successfully tagged a:latest
[image:build image/A] a Created
Step 1/1 : FROM a
 ---> 3b9f36f12977
Successfully built 3b9f36f12977
Successfully tagged b:latest
[image:build image/B] b Created

If then something in A changes, I get the folliwng unexpected behaviour:

$ touch A/a # same for echo $RANDOM > A/a with the exception that docker won't re-use the cache
$ dobi image/B
[WARN] meta.project is not set. Using default "dobi-bug".
Step 1/2 : FROM alpine
 ---> 3fd9065eaf02
Step 2/2 : COPY a a
 ---> Using cache
 ---> c44138ce777e
Successfully built c44138ce777e
Successfully tagged a:latest
[image:build image/A] a Created
[image:build image/B] b is fresh

Instead of [image:build image/B] b is fresh I would expect dobi to re build image/B.

Enteee commented 6 years ago

I was looking at the code lase week end and from my understandning this should work. Therefore I do assume this is a bug? Maybe related to how a image with with a default task is registered in the context.

digging deeper.. :pick:

dnephin commented 6 years ago

I think I've identified the problem. It seems to be an issue with tracking which dependencies were modified in the context. Debugging why that is failing now.

Ah, the problem is that the dependency name taht is saved is a full task name (image/A:build), but the check for modified deps is using the short name image/A.

dnephin commented 6 years ago

A workaround (using the excellent example you provided) would be to set the depends to image/A:build, which then properly rebuilds things. I'll look into a proper fix, which I think would be to make sure it's always using fully expanded task names.

Enteee commented 6 years ago

Yay, awesome!

While thinking about this I discovered a possible loophole:

what happens if you have three images, A, B, C with B and C both depend on A.

if you now:

  1. build B && build C
  2. change something in A
  3. rebuild B (this should now build A then B)
  4. rebuild C

I think 4 won't do anything, wherease it maybe should. But I'll test your changes and maybe come back with a new feature request. This seems to be a bigger task, since dobi probably has to persist information about dependencies to get this solved.

dnephin commented 6 years ago

Ah yes, that is probably true. I think that could be fixed by comparing the imageID of the parent image at build time against the current imageID of the tag in the first FROM. The parent imageID at build time may need to be stored in he image record as well.

At some point I'd like to try and use buildkit directly, which I hope would provide more information about the image directly.