GCP: Fix panic while parsing a specific build job log

The `cloudbuildResourcesFromBuildLog()` function from the internal GCP
package could cause panic while parsing Build job log which failed early
and didn't create any Compute Engine resources. The function relied on
the `Regexp.FindStringSubmatch()` method to always return a match
while being used on the build log. Accessing a member of a nil slice
would cause a panic in `osbuild-worker`, such as:

Stack trace of thread 185316:
 #0  0x0000564e5393b5e1 runtime.raise (osbuild-worker)
 #1  0x0000564e5391fa1e runtime.sigfwdgo (osbuild-worker)
 #2  0x0000564e5391e354 runtime.sigtrampgo (osbuild-worker)
 #3  0x0000564e5393b953 runtime.sigtramp (osbuild-worker)
 #4  0x00007f37e98e3b20 __restore_rt (libpthread.so.0)
 #5  0x0000564e5393b5e1 runtime.raise (osbuild-worker)
 #6  0x0000564e5391f5ea runtime.crash (osbuild-worker)
 #7  0x0000564e53909306 runtime.fatalpanic (osbuild-worker)
 #8  0x0000564e53908ca1 runtime.gopanic (osbuild-worker)
 #9  0x0000564e53906b65 runtime.goPanicIndex (osbuild-worker)
 #10 0x0000564e5420b36e github.com/osbuild/osbuild-composer/internal/cloud/gcp.cloudbuildResourcesFromBuildLog (osbuild-worker)
 #11 0x0000564e54209ebb github.com/osbuild/osbuild-composer/internal/cloud/gcp.(*GCP).CloudbuildBuildCleanup (osbuild-worker)
 #12 0x0000564e54b05a9b main.(*OSBuildJobImpl).Run (osbuild-worker)
 #13 0x0000564e54b08854 main.main (osbuild-worker)
 #14 0x0000564e5390b722 runtime.main (osbuild-worker)
 #15 0x0000564e53939a11 runtime.goexit (osbuild-worker)

Add a unit test testing this scenario.

Make the `cloudbuildResourcesFromBuildLog()` function more robust and
not blindly expect to find matches in the build log. As a result the
`cloudbuildBuildResources` struct instance returned from the function
may be empty. Subsequently make sure that the `CloudbuildBuildCleanup()`
method handles an empty `cloudbuildBuildResources` instance correctly.
Specifically the `storageCacheDir.bucket` may be an empty string and
thus won't exist. Ensure that this does not result in infinite loop by
checking for `storage.ErrBucketNotExist` while iterating the bucket
objects.

Signed-off-by: Tomas Hozza <thozza@redhat.com>
This commit is contained in:
Tomas Hozza 2021-04-27 21:08:29 +02:00 committed by Tomas Hozza
parent 27c5aafeca
commit 5e591ccc3d
2 changed files with 65 additions and 4 deletions

View file

@ -148,7 +148,7 @@ func (g *GCP) CloudbuildBuildCleanup(ctx context.Context, buildID string) ([]str
objects := bucket.Objects(ctx, &storage.Query{Prefix: resources.storageCacheDir.dir})
for {
objAttrs, err := objects.Next()
if err == iterator.Done {
if err == iterator.Done || err == storage.ErrBucketNotExist {
break
}
if err != nil {
@ -178,7 +178,9 @@ func cloudbuildResourcesFromBuildLog(buildLog string) (*cloudbuildBuildResources
return &resources, err
}
zoneMatch := zoneRe.FindStringSubmatch(buildLog)
resources.zone = zoneMatch[1]
if zoneMatch != nil {
resources.zone = zoneMatch[1]
}
// extract Storage cache directory
// [inflate]: 2021-03-12T13:13:10Z Workflow GCSPath: gs://ascendant-braid-303513-daisy-bkt-us-central1/gce-image-import-2021-03-12T13:13:08Z-btgtd
@ -187,8 +189,10 @@ func cloudbuildResourcesFromBuildLog(buildLog string) (*cloudbuildBuildResources
return &resources, err
}
cacheDirMatch := cacheDirRe.FindStringSubmatch(buildLog)
resources.storageCacheDir.bucket = cacheDirMatch[1]
resources.storageCacheDir.dir = cacheDirMatch[2]
if cacheDirMatch != nil {
resources.storageCacheDir.bucket = cacheDirMatch[1]
resources.storageCacheDir.dir = cacheDirMatch[2]
}
// extract Compute disks
// [inflate.setup-disks]: 2021-03-12T13:13:11Z CreateDisks: Creating disk "disk-importer-inflate-7366y".