From 6f5f3bc2f3aea1bf5e5772533be80c3bfbb4e3a9 Mon Sep 17 00:00:00 2001 From: Felipe Lalanne Date: Sun, 1 Aug 2021 23:02:44 -0400 Subject: [PATCH] Fix regression with local mode push PR #1749 introduced a bug when pushing local target state. An update to the [image name normalization](https://github.com/balena-os/balena-supervisor/blob/f1bd4b8d9bcef29e326cbf97eaddd837c2704d19/src/lib/docker-utils.ts#L81) failed to consider the local image name format. This results in mangling of image names in the database, i.e. the image `ubuntu:latest` is stored as `/ubuntu:latest`. This causes an exception to be returned by the dockerode `getImage('/ubuntu:latest').inspect()` call. This sends the supervisor into a crash loop and is shown on the supervisor journal logs as ``` getaddrinfo ENOTFOUND images at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:64:26) ``` Unfortunately if this happens on a user device, since the mangled image name is already on the database, the easiest way to fix is to remove the supervisor database and let the supervisor recreate it. Deleting the database should be side effect free. Change-type: patch --- src/compose/application-manager.ts | 4 +++- src/lib/docker-utils.ts | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/compose/application-manager.ts b/src/compose/application-manager.ts index 4b46ab8c..c6de2885 100644 --- a/src/compose/application-manager.ts +++ b/src/compose/application-manager.ts @@ -674,7 +674,9 @@ function saveAndRemoveImages( (svc) => _.find(availableImages, { dockerImageId: svc.config.image, - name: svc.imageName, + // There is no 1-1 mapping between services and images + // on disk, so the only way to compare is by imageId + imageId: svc.imageId, }) ?? _.find(availableImages, { dockerImageId: svc.config.image }), ), ) as imageManager.Image[]; diff --git a/src/lib/docker-utils.ts b/src/lib/docker-utils.ts index ee907466..5fd79175 100644 --- a/src/lib/docker-utils.ts +++ b/src/lib/docker-utils.ts @@ -80,7 +80,7 @@ export function getRegistryAndName(uri: string): ImageNameParts { // Normalise an image name to always have a tag, with :latest being the default export function normaliseImageName(image: string) { const { registry, imageName, tagName, digest } = getRegistryAndName(image); - const repository = [registry, imageName].join('/'); + const repository = [registry, imageName].filter((s) => !!s).join('/'); if (!digest) { return [repository, tagName || 'latest'].join(':');