1
0
mirror of https://github.com/moby/buildkit.git synced 2025-11-28 16:03:59 +03:00
Files
buildkit/source/git/identifier.go
Justin Chadwell 9a51bb0ff1 git: use custom giturl type to preserve original remote
This resolves a regression introduced in
50e75e3565. In this previous patch, I'd
incorrectly assumed that scp-like URLs can express a subset of
"standard"-URLs and so we can always safely convert them for
consistency. This isn't true - the URL "git@example.com:foo" should be
resolved to the home directory of the host, however, the converted URL
"ssh://git@example.com/foo" will be resolved to the root of the host.

To resolve this, we need to not perform this conversion. However, we
also need preserve the behaviour of firm distinction between SCP and
normal URL types (so as to keep proper port parsing).

To do this, we add a new GitURL type to the gitutil package. This new
type contains all useful fields shared in common between the standard
libraries url package and our custom scp-style url parsing package. This
keeps the previous property of a single clean interface to all GitURLs,
while also ensuring that we preserve the original URL to pass to the Git
CLI (making sure we strip fragments out, which are used as
buildkit-level metadata).

As a side-effect of this, the client-side calling code for parsing
git urls is simplified (so we don't have to do fragment wrangling at
every call point).

Signed-off-by: Justin Chadwell <me@jedevc.com>
2023-10-12 19:17:11 +01:00

86 lines
2.0 KiB
Go

package git
import (
"path"
"strings"
"github.com/moby/buildkit/solver/llbsolver/provenance"
"github.com/moby/buildkit/source"
srctypes "github.com/moby/buildkit/source/types"
"github.com/moby/buildkit/util/gitutil"
"github.com/moby/buildkit/util/sshutil"
)
type GitIdentifier struct {
Remote string
Ref string
Subdir string
KeepGitDir bool
AuthTokenSecret string
AuthHeaderSecret string
MountSSHSock string
KnownSSHHosts string
}
func NewGitIdentifier(remoteURL string) (*GitIdentifier, error) {
if !isGitTransport(remoteURL) {
remoteURL = "https://" + remoteURL
}
u, err := gitutil.ParseURL(remoteURL)
if err != nil {
return nil, err
}
repo := GitIdentifier{Remote: u.Remote}
if u.Fragment != nil {
repo.Ref = u.Fragment.Ref
repo.Subdir = u.Fragment.Subdir
}
if sd := path.Clean(repo.Subdir); sd == "/" || sd == "." {
repo.Subdir = ""
}
return &repo, nil
}
func (GitIdentifier) Scheme() string {
return srctypes.GitScheme
}
var _ source.Identifier = (*GitIdentifier)(nil)
func (id *GitIdentifier) Capture(c *provenance.Capture, pin string) error {
url := id.Remote
if id.Ref != "" {
url += "#" + id.Ref
}
c.AddGit(provenance.GitSource{
URL: url,
Commit: pin,
})
if id.AuthTokenSecret != "" {
c.AddSecret(provenance.Secret{
ID: id.AuthTokenSecret,
Optional: true,
})
}
if id.AuthHeaderSecret != "" {
c.AddSecret(provenance.Secret{
ID: id.AuthHeaderSecret,
Optional: true,
})
}
if id.MountSSHSock != "" {
c.AddSSH(provenance.SSH{
ID: id.MountSSHSock,
Optional: true,
})
}
return nil
}
// isGitTransport returns true if the provided str is a git transport by inspecting
// the prefix of the string for known protocols used in git.
func isGitTransport(str string) bool {
return strings.HasPrefix(str, "http://") || strings.HasPrefix(str, "https://") || strings.HasPrefix(str, "git://") || strings.HasPrefix(str, "ssh://") || sshutil.IsImplicitSSHTransport(str)
}