Skip to content

Commit

Permalink
Merge pull request #89 from infosiftr/context-checksum
Browse files Browse the repository at this point in the history
Add `ArchGitChecksum` template command in `bashbrew cat`
  • Loading branch information
tianon authored Jan 12, 2024
2 parents 4e0ea8d + 795ff4b commit 1a2b388
Show file tree
Hide file tree
Showing 12 changed files with 699 additions and 99 deletions.
30 changes: 30 additions & 0 deletions cmd/bashbrew/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"path/filepath"
"regexp"
"strings"
"time"

"github.com/urfave/cli"

Expand Down Expand Up @@ -96,6 +97,35 @@ func getGitCommit(commit string) (string, error) {
return h.String(), nil
}

func (r Repo) archGitFS(arch string, entry *manifest.Manifest2822Entry) (fs.FS, error) {
commit, err := r.fetchGitRepo(arch, entry)
if err != nil {
return nil, fmt.Errorf("failed fetching %q: %w", r.EntryIdentifier(entry), err)
}

gitFS, err := gitCommitFS(commit)
if err != nil {
return nil, err
}

return fs.Sub(gitFS, entry.ArchDirectory(arch))
}

// returns the timestamp of the ArchGitCommit -- useful for SOURCE_DATE_EPOCH
func (r Repo) ArchGitTime(arch string, entry *manifest.Manifest2822Entry) (time.Time, error) {
f, err := r.archGitFS(arch, entry)
if err != nil {
return time.Time{}, err
}

fi, err := fs.Stat(f, ".")
if err != nil {
return time.Time{}, err
}

return fi.ModTime(), nil
}

func gitCommitFS(commit string) (fs.FS, error) {
if err := ensureGitInit(); err != nil {
return nil, err
Expand Down
57 changes: 57 additions & 0 deletions cmd/bashbrew/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package main
import (
"fmt"
"os"
"path"
"path/filepath"
"strings"

"github.com/sirupsen/logrus" // this is used by containerd libraries, so we need to set the default log level for it
"github.com/urfave/cli"
xTerm "golang.org/x/term"

"github.com/docker-library/bashbrew/architecture"
"github.com/docker-library/bashbrew/manifest"
Expand Down Expand Up @@ -421,6 +423,61 @@ func main() {

Category: "plumbing",
},
{
Name: "context",
Usage: "(eventually Dockerfile-filtered) git archive",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "sha256",
Usage: `print sha256 instead of raw tar`,
},
// TODO "unfiltered" or something for not applying Dockerfile filtering (once that's implemented)
},
Before: subcommandBeforeFactory("context"),
Action: func(c *cli.Context) error {
repos, err := repos(false, c.Args()...)
if err != nil {
return err
}
if len(repos) != 1 {
return fmt.Errorf("'context' expects to act on exactly one architecture of one entry of one repo (got %d repos)", len(repos))
}

r, err := fetch(repos[0])
if err != nil {
return err
}

// TODO technically something like "hello-world:latest" *could* be relaxed a little if it resolves via architecture to one and only one entry 🤔 (but that's a little hard to implement with the existing internal data structures -- see TODO at the top of "sort.go")

if r.TagEntry == nil {
return fmt.Errorf("'context' expects to act on exactly one architecture of one entry of one repo (no specific entry of %q selected)", r.RepoName)
}
if len(r.TagEntries) != 1 {
return fmt.Errorf("'context' expects to act on exactly one architecture of one entry of one repo (got %d entires)", len(r.TagEntries))
}

if !r.TagEntry.HasArchitecture(arch) {
return fmt.Errorf("%q does not include architecture %q", path.Join(namespace, r.RepoName)+":"+r.TagEntry.Tags[0], arch)
}

if c.Bool("sha256") {
sum, err := r.ArchGitChecksum(arch, r.TagEntry)
if err != nil {
return err
}
fmt.Println(sum)
return nil
} else {
if xTerm.IsTerminal(int(os.Stdout.Fd())) {
return fmt.Errorf("cowardly refusing to output a tar to a terminal")
}
return r.archContextTar(arch, r.TagEntry, os.Stdout)
}
},

Category: "plumbing",
},
{
Name: "remote",
Usage: "query registries for bashbrew-related data",
Expand Down
1 change: 1 addition & 0 deletions cmd/bashbrew/oci-builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ func importOCIBlob(ctx context.Context, cs content.Store, fs iofs.FS, descriptor

// this is "docker build" but for "Builder: oci-import"
func ociImportBuild(tags []string, commit, dir, file string) (*imagespec.Descriptor, error) {
// TODO use r.archGitFS (we have no r or arch or entry here 😅)
fs, err := gitCommitFS(commit)
if err != nil {
return nil, err
Expand Down
10 changes: 6 additions & 4 deletions cmd/bashbrew/sort.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"pault.ag/go/topsort"
)

// TODO unify archFilter and applyConstraints handling by pre-filtering the full list of Repo objects such that all that remains are things we should process (thus removing all "if" statements throughout the various loops); re-doing the Architectures and Entries lists to only include ones we should process, etc

func sortRepos(repos []string, applyConstraints bool) ([]string, error) {
rs := []*Repo{}
rsMap := map[*Repo]string{}
Expand Down Expand Up @@ -103,10 +105,10 @@ func sortRepoObjects(rs []*Repo, applyConstraints bool) ([]*Repo, error) {
continue
}
/*
// TODO need archFilter here :(
if archFilter && !entry.HasArchitecture(arch) {
continue
}
// TODO need archFilter here :(
if archFilter && !entry.HasArchitecture(arch) {
continue
}
*/

entryArches := []string{arch}
Expand Down
28 changes: 28 additions & 0 deletions cmd/bashbrew/tar.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package main

import (
"crypto/sha256"
"fmt"
"io"

"github.com/docker-library/bashbrew/manifest"
"github.com/docker-library/bashbrew/pkg/tarscrub"
)

func (r Repo) archContextTar(arch string, entry *manifest.Manifest2822Entry, w io.Writer) error {
f, err := r.archGitFS(arch, entry)
if err != nil {
return err
}

return tarscrub.WriteTar(f, w)
}

func (r Repo) ArchGitChecksum(arch string, entry *manifest.Manifest2822Entry) (string, error) {
h := sha256.New()
err := r.archContextTar(arch, entry, h)
if err != nil {
return "", err
}
return fmt.Sprintf("%x", h.Sum(nil)), nil
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
github.com/sirupsen/logrus v1.9.0
github.com/urfave/cli v1.22.10
go.etcd.io/bbolt v1.3.7
golang.org/x/term v0.5.0
pault.ag/go/debian v0.12.0
pault.ag/go/topsort v0.1.1
)
Expand Down
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -940,6 +940,7 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand Down
Loading

0 comments on commit 1a2b388

Please sign in to comment.