6

I'm building a Yocto image for a project but it's a long process. On my powerful dev machine it takes around 3 hours and can consume up to 100 GB of space.

The thing is that the final image is not "necessarily" the end goal; it's my application that runs on top of it that is important. As such, the yocto recipes don't change much, but my application does.

I would like to run continuous integration (CI) for my app and even continuous delivery (CD). But both are quite hard for now because of the size of the yocto build.

Since the build does not change much, I though of "caching" it in some way and use it for my application's CI/CD and I though of Docker. That would be quite interesting as I could maintain that image and share it with colleagues who need to work on the project and use it in CI/CD.

  1. Could a custom Docker image be built for that kind of use?
  2. Would it be possible to build such an image completely offline? I don't want to have to upload the 100GB and have to re-download it on build machines...

Thanks!

Stephano
  • 5,716
  • 7
  • 41
  • 57
big_gie
  • 2,829
  • 3
  • 31
  • 45

1 Answers1

7

1. Yes.

I've used docker to build Yocto images for many different reasons, always with positive results.

2. Yes, with some work.

You want to take advantage of the fact that Yocto caches all the stuff you need to do your build in what it calls "Shared State Cache". This is normally located in your build directory under ${BUILDDIR}/sstate-cache, and it contains exactly what you are looking for in this case. There are a couple of options for how to get these files to your build machines.

Option 1 is using sstate mirrors:

This isn't completely offline, but lets you download a much smaller cache and build from that cache, rather than from source.

Here's what's in my local.conf file:

SSTATE_MIRRORS ?= "\
file://.* http://my.shared-computer.com/some-folder/PATH"

Don't forget the PATH at the end. That is required. The build system substitutes the correct path within the directory structure.

Option 2 lets you keep a local copy of your sstate-cache and build from that locally.

In your dockerfile, create the sstate-cache directory (location isn't important here, I like /opt for my purposes):

RUN mkdir -p /opt/yocto/sstate-cache

Then be sure to bindmount these directories when you run your build in order to preserve the contents, like this:

docker run ... -v /place/to/save/cache:/opt/yocto/sstate-cache

Edit the local.conf in your build directory so that it points at these folders:

SSTATE_DIR ?= "/opt/yocto/sstate-cache"

In this way, you can get your cache onto your build machines in whatever way is best for you (scp, nfs, sneakernet).

Hope this helps!

Stephano
  • 5,716
  • 7
  • 41
  • 57
  • I've done something similar in the end. I'm using gitlab-ci-multi-runner with docker executor. As such, I don't have (yet) a `Dockerfile`: my CI config tels Docker to use `ubuntu:16.04` as the image. In my CI config, I created a symlink to `/cache` named `build`. Then, in the runner config I set the `/cache` to be a `rw` volume so I can keep the whole `build` directory between runs, including `sstate`, downloads, etc. My question was slightly different though; Can I create a new image with the `build` content already in it? But then it might not make sense as what I want is simply a cache. – big_gie Aug 11 '16 at 01:32
  • @big_gie I agree, cache is probably what you want. You could certainly tell docker to pull in a full build directory from somewhere, but that would waste a lot of space / time, and not take advantage of the caching features of Yocto. Glad you worked something out! – Stephano Aug 15 '16 at 18:43
  • For Option2 you are restricting the runner to one job in parallel only? I guess otherwise this can't work, since multiples jobs would be writing to the sstate-cache in parallel. – Étienne Jul 14 '20 at 12:23