mirror of
https://github.com/open-policy-agent/opa.git
synced 2026-08-12 19:32:48 -06:00
download: Fix saving OCI bundles on disk
This commit fixes an issue related to zero-sized bundles being saved to disk, which can cause OPA to fail to start if a remote OCI repository is unavailable. Fixes: #6939 Signed-off-by: Sergey-Kizimov <serget.kizimov@hiya.com>
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
package download
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
@@ -210,13 +211,14 @@ func (d *OCIDownloader) oneShot(ctx context.Context) error {
|
||||
d.SetCache(resp.etag) // set the current etag sha to the cache
|
||||
|
||||
if d.f != nil {
|
||||
d.f(ctx, Update{ETag: resp.etag, Bundle: resp.b, Error: nil, Metrics: m, Raw: resp.raw})
|
||||
d.f(ctx, Update{ETag: resp.etag, Bundle: resp.b, Error: nil, Metrics: m, Raw: resp.raw, Size: resp.size})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *OCIDownloader) download(ctx context.Context, m metrics.Metrics) (*downloaderResponse, error) {
|
||||
d.logger.Debug("OCI - Download starting.")
|
||||
var buf bytes.Buffer
|
||||
|
||||
preferences := []string{fmt.Sprintf("modes=%v,%v", defaultBundleMode, deltaBundleMode)}
|
||||
|
||||
@@ -256,10 +258,15 @@ func (d *OCIDownloader) download(ctx context.Context, m metrics.Metrics) (*downl
|
||||
}, nil
|
||||
}
|
||||
fileReader, err := os.Open(bundleFilePath)
|
||||
|
||||
cnt := &count{}
|
||||
r := io.TeeReader(fileReader, cnt)
|
||||
tee := io.TeeReader(r, &buf)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
loader := bundle.NewTarballLoaderWithBaseURL(fileReader, d.localStorePath)
|
||||
loader := bundle.NewTarballLoaderWithBaseURL(tee, d.localStorePath)
|
||||
reader := bundle.NewCustomReader(loader).
|
||||
WithMetrics(m).
|
||||
WithBundleVerificationConfig(d.bvc).
|
||||
@@ -274,9 +281,10 @@ func (d *OCIDownloader) download(ctx context.Context, m metrics.Metrics) (*downl
|
||||
|
||||
return &downloaderResponse{
|
||||
b: &bundleInfo,
|
||||
raw: fileReader,
|
||||
raw: &buf,
|
||||
etag: etag,
|
||||
longPoll: false,
|
||||
size: cnt.Bytes(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -382,6 +383,55 @@ func TestOCICustomAuthPlugin(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestOCIValidateAndInjectDefaults(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
fixture := newTestFixture(t)
|
||||
fixture.server.expEtag = "sha256:c5834dbce332cabe6ae68a364de171a50bf5b08024c27d7c08cc72878b4df7ff"
|
||||
|
||||
updates := make(chan *Update)
|
||||
|
||||
config := Config{}
|
||||
if err := config.ValidateAndInjectDefaults(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
d := NewOCI(config, fixture.client, "ghcr.io/org/repo:latest", t.TempDir()).WithCallback(func(_ context.Context, u Update) {
|
||||
updates <- &u
|
||||
}).WithBundlePersistence(true)
|
||||
|
||||
d.Start(ctx)
|
||||
|
||||
// Give time for some download events to occur
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
u1 := <-updates
|
||||
|
||||
if u1.Size == 0 {
|
||||
t.Fatal("expected non-0 size")
|
||||
}
|
||||
|
||||
if u1.Raw == nil {
|
||||
t.Fatal("expected bundle reader to be non-nil")
|
||||
}
|
||||
|
||||
r := bundle.NewReader(u1.Raw)
|
||||
|
||||
b, err := r.Read()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(b.Data, u1.Bundle.Data) {
|
||||
t.Fatal("expected the bundle object and reader to have the same data")
|
||||
}
|
||||
|
||||
if len(b.Modules) != len(u1.Bundle.Modules) {
|
||||
t.Fatal("expected the bundle object and reader to have the same number of bundle modules")
|
||||
}
|
||||
|
||||
d.Stop(ctx)
|
||||
}
|
||||
|
||||
func mockAuthPluginLookup(string) rest.HTTPAuthPlugin {
|
||||
return &mockAuthPlugin{}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user