Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
errordeveloper committed Oct 6, 2023
1 parent ef2cb99 commit 0731442
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 23 deletions.
11 changes: 10 additions & 1 deletion attest/manifest/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import (
"cmp"

"github.com/docker/labs-brown-tape/attest/types"
attestTypes "github.com/docker/labs-brown-tape/attest/types"
)

const (
ManifestDirPredicateType = "docker.com/tape/ManifestDir/v0.1"
ManifestDirPredicateType = "docker.com/tape/ManifestDir/v0.2"
)

var (
Expand Down Expand Up @@ -41,6 +42,14 @@ func MakeDirContentsStatement(dir string, entries *types.PathCheckSummaryCollect
}
}

func MakeDirContentsStatementFrom(statement types.Statement) DirContents {
dirContents := DirContents{
GenericStatement: attestTypes.GenericStatement[SourceDirectory]{},
}
dirContents.ConvertFrom(statement)
return dirContents
}

func (a SourceDirectory) Compare(b SourceDirectory) types.Cmp {
if cmp := cmp.Compare(a.Path, b.Path); cmp != 0 {
return &cmp
Expand Down
24 changes: 24 additions & 0 deletions attest/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,30 @@ func Export(s ExportableStatement) toto.Statement {
}
}

func FilterByPredicateType(t string, s Statements) Statements {
results := Statements{}
for i := range s {
if s[i].GetType() == t {
results = append(results, s[i])
}
}
return results
}

type StamentConverter[T any] struct {
Statement
}

func (s *GenericStatement[T]) ConvertFrom(statement Statement) error {
predicate, ok := s.GetPredicate().(ComparablePredicate[T])
if !ok {
return fmt.Errorf("cannot convert statement with predicte of type %T into %T", s.GetPredicate(), GenericStatement[T]{})
}

*s = MakeStatement[T](s.GetType(), predicate, s.GetSubject()...)
return nil
}

func (s Statements) Export() []toto.Statement {
statements := make([]toto.Statement, len(s))
for i := range s {
Expand Down
126 changes: 104 additions & 22 deletions attest/vcs/git/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,23 @@ type (
}

GitSummary struct {
ObjectHash *string `json:"objectHash,omitempty"`
Remotes map[string][]string `json:"remotes,omitempty"`
Reference GitReference `json:"reference,omitempty"`
Object GitObject `json:"object,omitempty"`
Remotes map[string][]string `json:"remotes,omitempty"`
Reference GitReference `json:"reference,omitempty"`
}

GitObject struct {
TreeHash string `json:"treeHash,omitempty"`
CommitHash string `json:"commitHash,omitempty"`
Tags []string `json:"tags,omitempty"`
}

GitReference struct {
Name string `json:"name,omitempty"`
Hash string `json:"hash,omitempty"`
Type string `json:"type,omitempty"`
Target string `json:"target,omitempty"`
Name string `json:"name,omitempty"`
Hash string `json:"hash,omitempty"`
Type string `json:"type,omitempty"`
Target string `json:"target,omitempty"`
Tags []string `json:"tags,omitempty"`
}
)

Expand Down Expand Up @@ -148,13 +155,97 @@ func (c *PathChecker) MakeSummary() (types.PathCheckSummary, error) {
// TODO: also check if local tag in sync wirth remote tag
// TODO: provide info on singed tags/commits

head, err := c.cache.repo.Head()
if err != nil {
return nil, err
}

ref := GitReference{
Name: head.Name().String(),
Hash: head.Hash().String(),
Type: head.Type().String(),
Target: head.Target().String(),
}

obj := &GitObject{}
if summary.Unmodified {
git.ObjectHash = new(string)
*git.ObjectHash = c.cache.obj.ID().String()
obj.TreeHash = c.cache.obj.ID().String()
} else if c.IsBlob() {
// there is currently no easy way to obtain a hash for a subtree
git.ObjectHash = new(string)
*git.ObjectHash = c.cache.blobHash
obj.TreeHash = c.cache.blobHash
}

headCommit, err := c.cache.repo.CommitObject(head.Hash())
if err != nil {
return nil, err
}

if summary.Unmodified {
commitIter := object.NewCommitPathIterFromIter(
func(path string) bool {
switch {
case c.IsTree():
return strings.HasPrefix(c.cache.repoPath, path)
case c.IsBlob():
return c.cache.repoPath == path
default:
return false
}
},
object.NewCommitIterCTime(headCommit, nil, nil),
true,
)

if err := commitIter.ForEach(func(commit *object.Commit) error {
if obj.CommitHash != "" {
return nil
}
obj.CommitHash = commit.Hash.String()
return nil

// //fmt.Println(commit.Hash, commit.TreeHash, obj.TreeHash)
// switch {
// case obj.Hash != "":
// return nil
// case c.IsTree():
// obj.Hash = commit.Hash.String()
// return nil
// case c.IsBlob():
// if commit.TreeHash.String() == obj.TreeHash {
// obj.Hash = commit.Hash.String()
// }
// return nil
// default:
// return nil
// }
}); err != nil {
return nil, err
}

defer commitIter.Close()
}

tags, err := c.cache.repo.Tags()
if err != nil {
return nil, err
}

if err := tags.ForEach(func(tag *plumbing.Reference) error {
hash, err := c.cache.repo.ResolveRevision(plumbing.Revision(tag.Name()))
if err != nil {
return err
}
h := hash.String()
t := tag.Name().Short()
if h == ref.Hash {
ref.Tags = append(ref.Tags, t)
}
if h == obj.CommitHash {
obj.Tags = append(obj.Tags, t)
}
return nil
}); err != nil {
return nil, err
}

remotes, err := c.cache.repo.Remotes()
Expand Down Expand Up @@ -189,17 +280,8 @@ func (c *PathChecker) MakeSummary() (types.PathCheckSummary, error) {
git.Remotes[remoteConfig.Name] = remoteConfig.URLs
}

head, err := c.cache.repo.Head()
if err != nil {
return nil, err
}

git.Reference = GitReference{
Name: head.Name().String(),
Hash: head.Hash().String(),
Type: head.Type().String(),
Target: head.Target().String(),
}
git.Reference = ref
git.Object = *obj

return summary, nil
}
Expand Down
19 changes: 19 additions & 0 deletions oci/artefact.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/google/go-containerregistry/pkg/v1/tarball"
typesv1 "github.com/google/go-containerregistry/pkg/v1/types"

"github.com/docker/labs-brown-tape/attest/manifest"
attestTypes "github.com/docker/labs-brown-tape/attest/types"
manifestTypes "github.com/docker/labs-brown-tape/manifest/types"
)
Expand Down Expand Up @@ -223,6 +224,10 @@ func (c *Client) PushArtefact(ctx context.Context, destinationRef, sourceDir str
}
defer os.RemoveAll(tmpDir)

_, err = SemVerFromAttestations(ctx, sourceAttestations...)
if err != nil {
return "", err
}
tmpFile := filepath.Join(tmpDir, "artefact.tgz")

outputFile, err := os.OpenFile(tmpFile, os.O_RDWR|os.O_CREATE|os.O_EXCL, regularFileMode)
Expand Down Expand Up @@ -348,6 +353,20 @@ func (c *Client) PushArtefact(ctx context.Context, destinationRef, sourceDir str
return tagAlias.String() + "@" + digest.String(), err
}

func SemVerFromAttestations(ctx context.Context, sourceAttestations ...attestTypes.Statement) (string, error) {
statements := attestTypes.FilterByPredicateType(manifest.ManifestDirPredicateType, sourceAttestations)
if len(statements) == 0 {
return "", fmt.Errorf("VCS provinance attestion (%q) not found", manifest.ManifestDirPredicateType)
}
if len(statements) > 1 {
return "", fmt.Errorf("too many attestations of type %q found, expected 1", manifest.ManifestDirPredicateType)
}

_ = manifest.MakeDirContentsStatementFrom(statements[0])

return "", nil
}

func makeDescriptorWithPlatform() Descriptor {
return Descriptor{
Platform: &Platform{
Expand Down

0 comments on commit 0731442

Please sign in to comment.