mirror of
https://github.com/moby/buildkit.git
synced 2025-11-28 16:03:59 +03:00
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>
86 lines
2.0 KiB
Go
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)
|
|
}
|