Skip to content

Commit 67e9c94

Browse files
committed
storage: add VerifyArtifact method
Signed-off-by: Hidde Beydals <[email protected]>
1 parent 62fd433 commit 67e9c94

File tree

2 files changed

+89
-0
lines changed

2 files changed

+89
-0
lines changed

internal/controller/storage.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"compress/gzip"
2222
"context"
2323
"fmt"
24+
"github.com/opencontainers/go-digest"
2425
"io"
2526
"io/fs"
2627
"net/url"
@@ -325,6 +326,35 @@ func (s *Storage) ArtifactExist(artifact v1.Artifact) bool {
325326
return fi.Mode().IsRegular()
326327
}
327328

329+
// VerifyArtifact verifies if the Digest of the v1.Artifact matches the digest
330+
// of the file in Storage. It returns an error if the digests don't match, or
331+
// if it can't be verified.
332+
func (s *Storage) VerifyArtifact(artifact v1.Artifact) error {
333+
if artifact.Digest == "" {
334+
return fmt.Errorf("artifact has no digest")
335+
}
336+
337+
d, err := digest.Parse(artifact.Digest)
338+
if err != nil {
339+
return fmt.Errorf("failed to parse artifact digest '%s': %w", artifact.Digest, err)
340+
}
341+
342+
f, err := os.Open(s.LocalPath(artifact))
343+
if err != nil {
344+
return err
345+
}
346+
defer f.Close()
347+
348+
verifier := d.Verifier()
349+
if _, err = io.Copy(verifier, f); err != nil {
350+
return err
351+
}
352+
if !verifier.Verified() {
353+
return fmt.Errorf("computed digest doesn't match '%s'", d.String())
354+
}
355+
return nil
356+
}
357+
328358
// ArchiveFileFilter must return true if a file should not be included in the archive after inspecting the given path
329359
// and/or os.FileInfo.
330360
type ArchiveFileFilter func(p string, fi os.FileInfo) bool

internal/controller/storage_test.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"archive/tar"
2121
"compress/gzip"
2222
"context"
23+
"errors"
2324
"fmt"
2425
"io"
2526
"os"
@@ -718,3 +719,61 @@ func TestStorage_GarbageCollect(t *testing.T) {
718719
})
719720
}
720721
}
722+
723+
func TestStorage_VerifyArtifact(t *testing.T) {
724+
g := NewWithT(t)
725+
726+
dir := t.TempDir()
727+
s, err := NewStorage(dir, "", 0, 0)
728+
g.Expect(err).ToNot(HaveOccurred(), "failed to create new storage")
729+
730+
g.Expect(os.WriteFile(filepath.Join(dir, "artifact"), []byte("test"), 0o600)).To(Succeed())
731+
732+
t.Run("artifact without digest", func(t *testing.T) {
733+
g := NewWithT(t)
734+
735+
err := s.VerifyArtifact(sourcev1.Artifact{})
736+
g.Expect(err).To(HaveOccurred())
737+
g.Expect(err).To(MatchError("artifact has no digest"))
738+
})
739+
740+
t.Run("artifact with invalid digest", func(t *testing.T) {
741+
g := NewWithT(t)
742+
743+
err := s.VerifyArtifact(sourcev1.Artifact{Digest: "invalid"})
744+
g.Expect(err).To(HaveOccurred())
745+
g.Expect(err).To(MatchError("failed to parse artifact digest 'invalid': invalid checksum digest format"))
746+
})
747+
748+
t.Run("artifact with invalid path", func(t *testing.T) {
749+
g := NewWithT(t)
750+
751+
err := s.VerifyArtifact(sourcev1.Artifact{
752+
Digest: "sha256:9ba7a35ce8acd3557fe30680ef193ca7a36bb5dc62788f30de7122a0a5beab69",
753+
Path: "invalid",
754+
})
755+
g.Expect(err).To(HaveOccurred())
756+
g.Expect(errors.Is(err, os.ErrNotExist)).To(BeTrue())
757+
})
758+
759+
t.Run("artifact with digest mismatch", func(t *testing.T) {
760+
g := NewWithT(t)
761+
762+
err := s.VerifyArtifact(sourcev1.Artifact{
763+
Digest: "sha256:9ba7a35ce8acd3557fe30680ef193ca7a36bb5dc62788f30de7122a0a5beab69",
764+
Path: "artifact",
765+
})
766+
g.Expect(err).To(HaveOccurred())
767+
g.Expect(err).To(MatchError("computed digest doesn't match 'sha256:9ba7a35ce8acd3557fe30680ef193ca7a36bb5dc62788f30de7122a0a5beab69'"))
768+
})
769+
770+
t.Run("artifact with digest match", func(t *testing.T) {
771+
g := NewWithT(t)
772+
773+
err := s.VerifyArtifact(sourcev1.Artifact{
774+
Digest: "sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
775+
Path: "artifact",
776+
})
777+
g.Expect(err).ToNot(HaveOccurred())
778+
})
779+
}

0 commit comments

Comments
 (0)