Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
errordeveloper committed Jun 27, 2024
1 parent ae6b500 commit faa9e60
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 26 deletions.
4 changes: 2 additions & 2 deletions manifest/packager/packager.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (

type Packager interface {
//Pull(string) error
Push(context.Context, string) (string, error)
Push(context.Context, string) (*oci.PackageRefs, error)
}

type DefaultPackager struct {
Expand All @@ -32,7 +32,7 @@ func NewDefaultPackager(client *oci.Client, destinationRef string, sourceEpochTi
}
}

func (r *DefaultPackager) Push(ctx context.Context, dir string) (string, error) {
func (r *DefaultPackager) Push(ctx context.Context, dir string) (*oci.PackageRefs, error) {
return r.Client.PushArtefact(ctx, r.destinationRef, dir,
r.sourceEpochTimestamp, r.sourceAttestations...)
}
59 changes: 37 additions & 22 deletions oci/artefact.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ type ArtefactInfo struct {
Digest string
}

type PackageRefs struct {
Digest string
Primary string
Short string
SemVer []string
}

func (c *Client) Fetch(ctx context.Context, ref string, mediaTypes ...MediaType) ([]*ArtefactInfo, error) {
imageIndex, indexManifest, image, err := c.GetIndexOrImage(ctx, ref)
if err != nil {
Expand Down Expand Up @@ -220,18 +227,18 @@ func (c *Client) getImage(ctx context.Context, imageIndex ImageIndex, digest Has
}

// based on https://github.com/fluxcd/pkg/blob/2a323d771e17af02dee2ccbbb9b445b78ab048e5/oci/client/push.go
func (c *Client) PushArtefact(ctx context.Context, destinationRef, sourceDir string, timestamp *time.Time, sourceAttestations ...attestTypes.Statement) (string, error) {
func (c *Client) PushArtefact(ctx context.Context, destinationRef, sourceDir string, timestamp *time.Time, sourceAttestations ...attestTypes.Statement) (*PackageRefs, error) {
tmpDir, err := os.MkdirTemp("", "bpt-oci-artefact-*")
if err != nil {
return "", err
return nil, err
}
defer os.RemoveAll(tmpDir)

tmpFile := filepath.Join(tmpDir, "artefact.tgz")

outputFile, err := os.OpenFile(tmpFile, os.O_RDWR|os.O_CREATE|os.O_EXCL, regularFileMode)
if err != nil {
return "", err
return nil, err
}
defer outputFile.Close()

Expand All @@ -240,25 +247,22 @@ func (c *Client) PushArtefact(ctx context.Context, destinationRef, sourceDir str
output := io.MultiWriter(outputFile, c.hash)

if err := c.BuildArtefact(tmpFile, sourceDir, output); err != nil {
return "", err
return nil, err
}

attestLayer, err := c.BuildAttestations(sourceAttestations)
if err != nil {
return "", fmt.Errorf("failed to serialise attestations: %w", err)
return nil, fmt.Errorf("failed to serialise attestations: %w", err)
}

repo, err := name.NewRepository(destinationRef)
if err != nil {
return "", fmt.Errorf("invalid URL: %w", err)
return nil, fmt.Errorf("invalid URL: %w", err)
}
hash := hex.EncodeToString(c.hash.Sum(nil))
tag := repo.Tag(manifestTypes.ConfigImageTagPrefix + hash)

tagAliases := append(
SemVerTagsFromAttestations(ctx, tag, sourceAttestations...),
tag.Context().Tag(manifestTypes.ConfigImageTagPrefix+hash[:7]),
)
shortTag := tag.Context().Tag(manifestTypes.ConfigImageTagPrefix + hash[:7])
semVerTags := SemVerTagsFromAttestations(ctx, tag, sourceAttestations...)

if timestamp == nil {
timestamp = new(time.Time)
Expand Down Expand Up @@ -295,12 +299,12 @@ func (c *Client) PushArtefact(ctx context.Context, destinationRef, sourceDir str
tarball.WithCompressedCaching,
)
if err != nil {
return "", fmt.Errorf("creating artefact content layer failed: %w", err)
return nil, fmt.Errorf("creating artefact content layer failed: %w", err)
}

config, err = mutate.Append(config, mutate.Addendum{Layer: configLayer})
if err != nil {
return "", fmt.Errorf("appeding content to artifact failed: %w", err)
return nil, fmt.Errorf("appeding content to artifact failed: %w", err)
}

index = mutate.AppendManifests(index,
Expand All @@ -315,7 +319,7 @@ func (c *Client) PushArtefact(ctx context.Context, destinationRef, sourceDir str

summary, err := (attestTypes.Statements)(sourceAttestations).MarshalSummaryAnnotation()
if err != nil {
return "", err
return nil, err
}
attestAnnotations[AttestationsSummaryAnnotation] = summary

Expand All @@ -329,7 +333,7 @@ func (c *Client) PushArtefact(ctx context.Context, destinationRef, sourceDir str

attest, err = mutate.Append(attest, mutate.Addendum{Layer: attestLayer})
if err != nil {
return "", fmt.Errorf("appeding attestations to artifact failed: %w", err)
return nil, fmt.Errorf("appeding attestations to artifact failed: %w", err)
}

index = mutate.AppendManifests(index,
Expand All @@ -342,22 +346,33 @@ func (c *Client) PushArtefact(ctx context.Context, destinationRef, sourceDir str

digest, err := index.Digest()
if err != nil {
return "", fmt.Errorf("parsing index digest failed: %w", err)
return nil, fmt.Errorf("parsing index digest failed: %w", err)
}

if err := remote.WriteIndex(tag, index, c.remoteWithContext(ctx)...); err != nil {
return "", fmt.Errorf("pushing index failed: %w", err)
return nil, fmt.Errorf("pushing index failed: %w", err)
}

refs := &PackageRefs{
Digest: digest.String(),
Primary: tag.String(),
Short: shortTag.String(),
SemVer: make([]string, len(semVerTags)),
}

for i := range tagAliases {
if err := remote.Tag(tagAliases[i], index, c.remoteWithContext(ctx)...); err != nil {
return "", fmt.Errorf("adding alias tagging failed: %w", err)
for i, tagAlias := range append(semVerTags, shortTag) {
if err := remote.Tag(tagAlias, index, c.remoteWithContext(ctx)...); err != nil {
return nil, fmt.Errorf("adding alias tagging failed: %w", err)
}
if i < len(semVerTags) {
refs.SemVer[i] = tagAlias.String() + "@" + digest.String()
}
}
// TODO: reteurn tag and all of its aliases
return tagAliases[0].String() + "@" + digest.String(), err
return refs, nil
}

func (p *PackageRefs) String() string { return p.Short + "@" + p.Digest }

func SemVerTagsFromAttestations(ctx context.Context, tag name.Tag, sourceAttestations ...attestTypes.Statement) []name.Tag {
statements := attestTypes.FilterByPredicateType(manifest.ManifestDirPredicateType, sourceAttestations)
if len(statements) != 1 {
Expand Down
8 changes: 6 additions & 2 deletions tape/app/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,11 +182,15 @@ func (c *TapePackageCommand) Execute(args []string) error {
path, sourceEpochTimestamp := loader.MostRecentlyModified()
c.tape.log.Debugf("using source epoch timestamp %s from most recently modified manifest file %q", sourceEpochTimestamp, path)
packager := packager.NewDefaultPackager(client, c.OutputImage, &sourceEpochTimestamp, attreg.GetStatements()...)
packageRef, err := packager.Push(ctx, images.Dir())
packageRefs, err := packager.Push(ctx, images.Dir())
if err != nil {
return fmt.Errorf("failed to create package: %w", err)
}

c.tape.log.Infof("created package %q", packageRef)
c.tape.log.Infof("created package %q", packageRefs[1])

if len(packageRefs) > 2 {
c.tape.log.Infof("additional tags: %s", strings.Join(packageRefs[1:], ", "))
}
return nil
}

0 comments on commit faa9e60

Please sign in to comment.