Internals Docker - Glow-Lang/glow GitHub Wiki

Here is the painful manual process by which I currently update our docker image for CI. It needs to be further automated, or replaced by something else entirely, possibly based on Guix, assuming we have a good enough Linux container story for Guix on Mac (maybe via snapcraft?).

Checkout your code as per the expectations of update-gerbil-nix-recipe

I wrote a script update-gerbil-nix-recipe.ss that automates a lot of the update, but far from all of it.

update-gerbil-nix-recipe.ss expects all your packages to have git checkouts at expected paths under the same directory. You can override these expectations, but it's a pain.

You should be good if you follow the instructions from glow/HACKING.md.

Have a shell function for update-gerbil-nix-recipe

I use the following shell function. Obviously, your paths may vary, and you may have to include any override you depend on as above.

mysrc=/home/fare/src/fare
gerbsup () {
        local gu=$mysrc/gerbil-utils
        GERBIL_LOADPATH=$gu $gu/scripts/update-gerbil-nix-recipe.ss $@
}

Before you use this function, you may have to recompile gerbil-utils with ./build.ss.

Updating Gambit and/or Gerbil

If you need to update Gambit and/or Gerbil, use the above script to update the recipes, then install via nix:

nixpkgs=$mysrc/nixpkgs
gerbsup
nix-env -f $nixpkgs -iA gambit-unstable gerbil-unstable

After gerbil is successfully upgraded, you may have to rm -rf ~/.gerbil/lib and manually recompile all your dependencies, because gxpkg's handling of dependencies is somewhat broken.

Get all your Gerbil packages working locally

Build all gerbil packages working locally, with the gerbil-unstable from Nix, but otherwise using ./build.ss outside of a nix-shell.

Push all your changes upstream

You may have to use branches for some of the packages if you don't have upstream committer access, or don't want to push to master without further testing.

Use gerbsup to update everything

Simple case:

gerbsup

More complex case may have a lot of git branch overrides:

gerbsup --gerbil-libp2p-repo github.com/AlexKnauth/gerbil-libp2p@logger --ftw-repo github.com/fare-patches/ftw -w github/Glow-lang/glow@timeout2 -o

The optional -o avoids an expensive polling for a new gambit that if modified will trigger an even more expensive rebuild of everything.

Optional: build everything with nix

You can test your nix build now, though the make-docker-image script will automatically do it for you later if you don't:

nix-env -f $nixpkgs -iA gambit-unstable gerbil-unstable gerbilPackages-unstable

Commit your changes to nixpkgs

Let's assume you have in $mysrc/nixpkgs a checkout of the devel branch of our fork of nixpkgs at https://github.com/MuKnIO/nixpkgs I actually do a git clone of https://github.com/NixOS/nixpkgs in another directory, configure our fork as the remote mukn with git remote add mukn https://github.com/MuKnIO/nixpkgs, then use git worktree add $mysrc/nixpkgs then make sure that worktree is on a devel branch based on that of mukn, so that, if and when included in a docker image, said checkout doesn't include the entire git history. (But I don't think our scripts are currently including it in a docker image, though they once did and might do it again.)

Anyway, now you can use git add -u and git diff --cached to see the changes (I have a shell function gad that does the above two). Then you can create one git commit per nix package, so they can be merged upstream later.

Usually, I work on a stack of existing commits since the last upstream merge to nixpkgs, that I will rebase. In the future, we may use a nix flake instead.

On top of my stack of commits is currently a change to glow, so first I will amend said change if needed with:

git commit --amend pkgs/development/compilers/gerbil/glow-lang.nix

Then, I will look at the top entry from git diff --cached and while that command returns a non-empty set of changes, I will create my commits with commands such as:

git commit -m 'gerbilPackages-unstable.gerbil-ethereum: 2020-10-18 -> 2021-11-30' pkgs/development/compilers/gerbil/gerbil-ethereum.nix

I actually, I first use a message more like -m 'eth 11-30', then use C-r ' e t h for zsh to search the last similar command in my history. Similarly I search ' g a m for gambit changes, ' p o o for gerbil-poo changes, etc.

Finally, I rebase interactively with

git rebase -i new-globase

Where the new-globase was recently updated from the nixpkgs master or nixpkgs-unstable, and its commit will also become that current-globase after successful update.

In that interactive rebase, I will first replace the pick prefixes of updates with s of f depending on whether or not (respectively) the date for the package has changed, then move each line after the according package change.

When it's all rebased, time to push:

git push --force mukn devel

Building the Docker image

Now you can run the function defined as below (modulo using your own paths):

nixglow () {
   b=$mysrc/gerbil-utils/build.ss
   time $b nixpkgs -f "$nixpkgs" && time $b publish -f "$nixpkgs" && time $b docker ${1:-all}
}

Assuming all is in order, and dockerd is running, etc., it do all the work.

Troubleshooting

Old versions of packages being installed by nix inside docker

Sometimes, I find that nix uses an old cached version of https://github.com/MuKnIO/nixpkgs/archive/devel.tar.gz I'm not sure where some bad cache fails to be invalidated (nix? docker? github servers? TODO: find out next time that happens), but a kluge that worked so far was to tweak the URL at the top of $mysrc/gerbil-utils/scripts/make-docker-image.ss to another non-canonical variant of said URL to avoid the old cached version. I suspect I may be failing to include some hash in some docker command, causing an old cache to be reused. Maybe then docker image prune -a can also help flush that cache.