Skip to content

Commit

Permalink
feat: allow ignoring remote cache-export error if failing
Browse files Browse the repository at this point in the history
Signed-off-by: JordanGoasdoue <jordan.goasdoue@dailymotion.com>
  • Loading branch information
JordanGoasdoue committed Dec 21, 2022
1 parent c0e38e1 commit e0b2ea1
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 4 deletions.
5 changes: 5 additions & 0 deletions README.md
Expand Up @@ -390,6 +390,7 @@ buildctl build ... \
* `compression=<uncompressed|gzip|estargz|zstd>`: choose compression type for layers newly created and cached, gzip is default value. estargz and zstd should be used with `oci-mediatypes=true`
* `compression-level=<value>`: choose compression level for gzip, estargz (0-9) and zstd (0-22)
* `force-compression=true`: forcibly apply `compression` option to all layers
* `ignore_error=<false|true>`: specify if error is ignored in case cache export fails (default: `false`)

`--import-cache` options:
* `type=registry`
Expand All @@ -415,6 +416,7 @@ The directory layout conforms to OCI Image Spec v1.0.
* `compression=<uncompressed|gzip|estargz|zstd>`: choose compression type for layers newly created and cached, gzip is default value. estargz and zstd should be used with `oci-mediatypes=true`.
* `compression-level=<value>`: compression level for gzip, estargz (0-9) and zstd (0-22)
* `force-compression=true`: forcibly apply `compression` option to all layers
* `ignore_error=<false|true>`: specify if error is ignored in case cache export fails (default: `false`)

`--import-cache` options:
* `type=local`
Expand Down Expand Up @@ -449,6 +451,7 @@ in your workflow to expose the runtime.
* `min`: only export layers for the resulting image
* `max`: export all the layers of all intermediate steps
* `scope=<scope>`: which scope cache object belongs to (default `buildkit`)
* `ignore_error=<false|true>`: specify if error is ignored in case cache export fails (default: `false`)

`--import-cache` options:
* `type=gha`
Expand Down Expand Up @@ -496,6 +499,7 @@ Others options are:
* `prefix=<prefix>`: set global prefix to store / read files on s3 (default: empty)
* `name=<manifest>`: specify name of the manifest to use (default `buildkit`)
* Multiple manifest names can be specified at the same time, separated by `;`. The standard use case is to use the git sha1 as name, and the branch name as duplicate, and load both with 2 `import-cache` commands.
* `ignore_error=<false|true>`: specify if error is ignored in case cache export fails (default: `false`)

`--import-cache` options:
* `type=s3`
Expand Down Expand Up @@ -540,6 +544,7 @@ There are 2 options supported for Azure Blob Storage authentication:
* `prefix=<prefix>`: set global prefix to store / read files on the Azure Blob Storage container (`<container>`) (default: empty)
* `name=<manifest>`: specify name of the manifest to use (default: `buildkit`)
* Multiple manifest names can be specified at the same time, separated by `;`. The standard use case is to use the git sha1 as name, and the branch name as duplicate, and load both with 2 `import-cache` commands.
* `ignore_error=<false|true>`: specify if error is ignored in case cache export fails (default: `false`)

`--import-cache` options:
* `type=azblob`
Expand Down
9 changes: 9 additions & 0 deletions control/control.go
Expand Up @@ -3,6 +3,7 @@ package control
import (
"context"
"fmt"
"strconv"
"sync"
"sync/atomic"
"time"
Expand Down Expand Up @@ -368,6 +369,14 @@ func (c *Controller) Solve(ctx context.Context, req *controlapi.SolveRequest) (*
} else {
exp.CacheExportMode = exportMode
}
if ignoreErrorStr, ok := e.Attrs["ignore_error"]; ok {
ignoreError, err := strconv.ParseBool(ignoreErrorStr)
if err != nil {
bklog.G(ctx).Debugf("skipping invalid cache export ignore_error: %s", e.Attrs["ignore_error"])
} else {
exp.IgnoreError = ignoreError
}
}
cacheExporters = append(cacheExporters, exp)
}

Expand Down
12 changes: 11 additions & 1 deletion hack/s3_test/test.sh
Expand Up @@ -20,7 +20,17 @@ done

export default_options="type=s3,bucket=my-bucket,region=us-east-1,endpoint_url=http://127.0.0.1:9000,access_key_id=minioadmin,secret_access_key=minioadmin,use_path_style=true"

rm -rf /tmp/destdir1 /tmp/destdir2
rm -rf /tmp/destdir0 /tmp/destdir1 /tmp/destdir2

# Check --export-cache with ignore_error=true and fake non reachable endpoint_url
# Should ignore error and skip the remote cache export
buildctl build \
--progress plain \
--frontend dockerfile.v0 \
--local context=/test/test1 \
--local dockerfile=/test/test1 \
--export-cache "$default_options,endpoint_url=http://fake-url:9000,ignore_error=true" \
--output type=local,dest=/tmp/destdir0

# First build: no cache on s3
# 4 files should be exported (2 blobs + 2 manifests)
Expand Down
18 changes: 15 additions & 3 deletions solver/llbsolver/solver.go
Expand Up @@ -58,6 +58,7 @@ type ExporterRequest struct {
type RemoteCacheExporter struct {
remotecache.Exporter
solver.CacheExportMode
IgnoreError bool
}

// ResolveWorkerFunc returns default worker for the temporary default non-distributed use cases
Expand Down Expand Up @@ -564,14 +565,17 @@ func (s *Solver) Solve(ctx context.Context, id string, sessionID string, req fro
func runCacheExporters(ctx context.Context, exporters []RemoteCacheExporter, j *solver.Job, cached *result.Result[solver.CachedResult], inp *result.Result[cache.ImmutableRef]) (map[string]string, error) {
eg, ctx := errgroup.WithContext(ctx)
g := session.NewGroup(j.SessionID)
preparingStr := "preparing build cache for export"
finalizingStr := "finalizing build cache for export"
ignoreErrStr := "skipping error because ignore_error enabled"
var cacheExporterResponse map[string]string
resps := make([]map[string]string, len(exporters))
for i, exp := range exporters {
func(exp RemoteCacheExporter, i int) {
eg.Go(func() (err error) {
id := fmt.Sprint(j.SessionID, "-cache-", i)
return inBuilderContext(ctx, j, exp.Exporter.Name(), id, func(ctx context.Context, _ session.Group) error {
prepareDone := progress.OneOff(ctx, "preparing build cache for export")
prepareDone := progress.OneOff(ctx, preparingStr)
if err := result.EachRef(cached, inp, func(res solver.CachedResult, ref cache.ImmutableRef) error {
ctx = withDescHandlerCacheOpts(ctx, ref)

Expand All @@ -587,12 +591,20 @@ func runCacheExporters(ctx context.Context, exporters []RemoteCacheExporter, j *
})
return err
}); err != nil {
return prepareDone(err)
if !exp.IgnoreError {
return prepareDone(err)
}
ignoreErrorDone := progress.OneOff(ctx, fmt.Sprintf("failed %s - %s: %v", preparingStr, ignoreErrStr, err.Error()))
return ignoreErrorDone(nil)
}
prepareDone(nil)
resps[i], err = exp.Finalize(ctx)
if err != nil {
return err
if !exp.IgnoreError {
return err
}
ignoreErrorDone := progress.OneOff(ctx, fmt.Sprintf("failed %s - %s: %v", finalizingStr, ignoreErrStr, err.Error()))
return ignoreErrorDone(nil)
}
return nil
})
Expand Down

0 comments on commit e0b2ea1

Please sign in to comment.