From 991bfd27940fffd50a89853d7336db0faa729766 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Fri, 20 Oct 2017 17:07:08 +0100 Subject: [PATCH] linuxkit pkg: handle packages which are not in git Detect if this is the case by checking if the given path is not in git and conditionalising anything which would touch git. Images built from outside git will, in the absence of options to force otherwise, get tagged "latest". Fixes: #2613 Signed-off-by: Ian Campbell --- src/cmd/linuxkit/pkglib/build.go | 6 +++--- src/cmd/linuxkit/pkglib/git.go | 34 +++++++++++++++++++++++++++++-- src/cmd/linuxkit/pkglib/pkglib.go | 29 +++++++++++++++++--------- 3 files changed, 54 insertions(+), 15 deletions(-) diff --git a/src/cmd/linuxkit/pkglib/build.go b/src/cmd/linuxkit/pkglib/build.go index f32c723be..a52a92997 100644 --- a/src/cmd/linuxkit/pkglib/build.go +++ b/src/cmd/linuxkit/pkglib/build.go @@ -70,7 +70,7 @@ func (p Pkg) Build(bos ...BuildOpt) error { return fmt.Errorf("Unknown arch %q", arch) } - if bo.release == "" { + if p.git != nil && bo.release == "" { r, err := p.git.commitTag("HEAD") if err != nil { return err @@ -97,10 +97,10 @@ func (p Pkg) Build(bos ...BuildOpt) error { var args []string - if p.gitRepo != "" { + if p.git != nil && p.gitRepo != "" { args = append(args, "--label", "org.opencontainers.image.source="+p.gitRepo) } - if !p.dirty { + if p.git != nil && !p.dirty { commit, err := p.git.commitHash("HEAD") if err != nil { return err diff --git a/src/cmd/linuxkit/pkglib/git.go b/src/cmd/linuxkit/pkglib/git.go index ee7498b3f..41a8c990d 100644 --- a/src/cmd/linuxkit/pkglib/git.go +++ b/src/cmd/linuxkit/pkglib/git.go @@ -24,8 +24,19 @@ type git struct { dir string } -func newGit(dir string) *git { - return &git{dir} +// Returns git==nil and no error if the path is not within a git repository +func newGit(dir string) (*git, error) { + g := &git{dir} + + // Check if dir really is within a git directory + ok, err := g.isWorkTree(dir) + if err != nil { + return nil, err + } + if !ok { + return nil, nil + } + return g, nil } func (g git) mkCmd(args ...string) *exec.Cmd { @@ -56,6 +67,25 @@ func (g git) command(args ...string) error { return cmd.Run() } +func (g git) isWorkTree(pkg string) (bool, error) { + tf, err := g.commandStdout(nil, "rev-parse", "--is-inside-work-tree") + if err != nil { + // If we executed git ok but it errored then that's because this isn't a git repo + if _, ok := err.(*exec.ExitError); ok { + return false, nil + } + return false, err + } + + tf = strings.TrimSpace(tf) + + if tf == "true" { + return true, nil + } + + return false, fmt.Errorf("unexpected output from git rev-parse --is-inside-work-tree: %s", tf) +} + func (g git) treeHash(pkg, commit string) (string, error) { out, err := g.commandStdout(os.Stderr, "ls-tree", "--full-tree", commit, "--", pkg) if err != nil { diff --git a/src/cmd/linuxkit/pkglib/pkglib.go b/src/cmd/linuxkit/pkglib/pkglib.go index 1b44f003a..aab1e05c9 100644 --- a/src/cmd/linuxkit/pkglib/pkglib.go +++ b/src/cmd/linuxkit/pkglib/pkglib.go @@ -139,22 +139,27 @@ func NewFromCLI(fs *flag.FlagSet, args ...string) (Pkg, error) { } }) - git := newGit(pkgPath) - - gitDirty, err := git.isDirty(hashPath, hashCommit) + git, err := newGit(pkgPath) if err != nil { return Pkg{}, err } - dirty = dirty || gitDirty - - if hash == "" { - if hash, err = git.treeHash(hashPath, hashCommit); err != nil { + if git != nil { + gitDirty, err := git.isDirty(hashPath, hashCommit) + if err != nil { return Pkg{}, err } - if dirty { - hash += "-dirty" + dirty = dirty || gitDirty + + if hash == "" { + if hash, err = git.treeHash(hashPath, hashCommit); err != nil { + return Pkg{}, err + } + + if dirty { + hash += "-dirty" + } } } @@ -193,7 +198,11 @@ func (p Pkg) ReleaseTag(release string) (string, error) { // Tag returns the tag to use for the package func (p Pkg) Tag() string { - return p.org + "/" + p.image + ":" + p.hash + r := p.org + "/" + p.image + if p.hash != "" { + r += ":" + p.hash + } + return r } // TrustEnabled returns true if trust is enabled