Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: new git flags #1322

Merged
merged 7 commits into from
Aug 13, 2020
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
7 changes: 6 additions & 1 deletion cmd/executor/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ func addKanikoOptionsFlags() {
RootCmd.PersistentFlags().VarP(&opts.Labels, "label", "", "Set metadata for an image. Set it repeatedly for multiple labels.")
RootCmd.PersistentFlags().BoolVarP(&opts.SkipUnusedStages, "skip-unused-stages", "", false, "Build only used stages if defined to true. Otherwise it builds by default all stages, even the unnecessaries ones until it reaches the target stage / end of Dockerfile")
RootCmd.PersistentFlags().BoolVarP(&opts.RunV2, "use-new-run", "", false, "Experimental run command to detect file system changes. This new run command does no rely on snapshotting to detect changes.")
RootCmd.PersistentFlags().Var(&opts.Git, "git", "Branch to clone if build context is a git repository")
}

// addHiddenFlags marks certain flags as hidden from the executor help text
Expand Down Expand Up @@ -266,7 +267,11 @@ func resolveSourceContext() error {
opts.SrcContext = opts.Bucket
}
}
contextExecutor, err := buildcontext.GetBuildContext(opts.SrcContext)
contextExecutor, err := buildcontext.GetBuildContext(opts.SrcContext, buildcontext.BuildOptions{
GitBranch: opts.Git.Branch,
GitSingleBranch: opts.Git.SingleBranch,
GitRecurseSubmodules: opts.Git.RecurseSubmodules,
})
if err != nil {
return err
}
Expand Down
18 changes: 2 additions & 16 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,20 @@ require (
cloud.google.com/go v0.38.0
github.com/Azure/azure-pipeline-go v0.2.2 // indirect
github.com/Azure/azure-storage-blob-go v0.8.0
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 // indirect
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 // indirect
github.com/aws/aws-sdk-go v1.27.1
github.com/docker/docker v1.14.0-0.20190319215453-e7b5f7dbe98c
github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916 // indirect
github.com/docker/swarmkit v1.12.1-0.20180726190244-7567d47988d8 // indirect
github.com/emirpasic/gods v1.9.0 // indirect
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect
github.com/genuinetools/amicontained v0.4.3
github.com/gliderlabs/ssh v0.2.2 // indirect
github.com/go-git/go-git/v5 v5.1.0
github.com/golang/mock v1.3.1
github.com/google/go-cmp v0.3.0
github.com/google/go-containerregistry v0.0.0-20200313165449-955bf358a3d8
github.com/google/go-github v17.0.0+incompatible
github.com/google/go-querystring v1.0.0 // indirect
github.com/hashicorp/go-memdb v0.0.0-20180223233045-1289e7fffe71 // indirect
github.com/hashicorp/go-uuid v1.0.1 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/karrick/godirwalk v1.7.7
github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e // indirect
github.com/mattn/go-ieproxy v0.0.0-20190805055040-f9202b1cfdeb // indirect
github.com/mattn/go-shellwords v1.0.3 // indirect
github.com/minio/highwayhash v1.0.0
Expand All @@ -41,22 +35,14 @@ require (
github.com/opencontainers/selinux v1.0.0-rc1 // indirect
github.com/opentracing/opentracing-go v1.0.2 // indirect
github.com/otiai10/copy v1.0.2
github.com/pelletier/go-buffruneio v0.2.0 // indirect
github.com/pkg/errors v0.9.1
github.com/sergi/go-diff v1.0.0 // indirect
github.com/sirupsen/logrus v1.4.2
github.com/spf13/afero v1.2.2
github.com/spf13/cobra v0.0.5
github.com/spf13/pflag v1.0.5
github.com/src-d/gcfg v1.3.0 // indirect
github.com/tonistiigi/fsutil v0.0.0-20191018213012-0f039a052ca1 // indirect
github.com/vbatts/tar-split v0.10.2 // indirect
github.com/xanzy/ssh-agent v0.2.0 // indirect
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b
golang.org/x/net v0.0.0-20200301022130-244492dfa37a
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e
gopkg.in/src-d/go-billy.v4 v4.2.0 // indirect
gopkg.in/src-d/go-git-fixtures.v3 v3.5.0 // indirect
gopkg.in/src-d/go-git.v4 v4.6.0
gopkg.in/warnings.v0 v0.1.2 // indirect
)
57 changes: 37 additions & 20 deletions go.sum

Large diffs are not rendered by default.

10 changes: 8 additions & 2 deletions pkg/buildcontext/buildcontext.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ const (
TarBuildContextPrefix = "tar://"
)

type BuildOptions struct {
GitBranch string
GitSingleBranch bool
GitRecurseSubmodules bool
}

// BuildContext unifies calls to download and unpack the build context.
type BuildContext interface {
// Unpacks a build context and returns the directory where it resides
Expand All @@ -36,7 +42,7 @@ type BuildContext interface {

// GetBuildContext parses srcContext for the prefix and returns related buildcontext
// parser
func GetBuildContext(srcContext string) (BuildContext, error) {
func GetBuildContext(srcContext string, opts BuildOptions) (BuildContext, error) {
split := strings.SplitAfter(srcContext, "://")
if len(split) > 1 {
prefix := split[0]
Expand All @@ -50,7 +56,7 @@ func GetBuildContext(srcContext string) (BuildContext, error) {
case constants.LocalDirBuildContextPrefix:
return &Dir{context: context}, nil
case constants.GitBuildContextPrefix:
return &Git{context: context}, nil
return &Git{context: context, opts: opts}, nil
case constants.HTTPSBuildContextPrefix:
if util.ValidAzureBlobStorageHost(srcContext) {
return &AzureBlob{context: srcContext}, nil
Expand Down
76 changes: 70 additions & 6 deletions pkg/buildcontext/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,20 @@ limitations under the License.
package buildcontext

import (
"fmt"
"os"
"strings"

"github.com/GoogleContainerTools/kaniko/pkg/constants"
git "gopkg.in/src-d/go-git.v4"
"gopkg.in/src-d/go-git.v4/plumbing"
"gopkg.in/src-d/go-git.v4/plumbing/transport"
"gopkg.in/src-d/go-git.v4/plumbing/transport/http"
"github.com/go-git/go-billy/v5/osfs"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/config"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/cache"
"github.com/go-git/go-git/v5/plumbing/transport"
"github.com/go-git/go-git/v5/plumbing/transport/http"
"github.com/go-git/go-git/v5/storage/filesystem"
"github.com/sirupsen/logrus"
)

const (
Expand All @@ -43,25 +49,83 @@ var (
// Git unifies calls to download and unpack the build context.
type Git struct {
context string
opts BuildOptions
}

// UnpackTarFromBuildContext will provide the directory where Git Repository is Cloned
func (g *Git) UnpackTarFromBuildContext() (string, error) {
directory := constants.BuildContextDir
parts := strings.Split(g.context, "#")
url := getGitPullMethod() + "://" + parts[0]
options := git.CloneOptions{
URL: getGitPullMethod() + "://" + parts[0],
URL: url,
Auth: getGitAuth(),
Progress: os.Stdout,
RecurseSubmodules: git.DefaultSubmoduleRecursionDepth,
SingleBranch: g.opts.GitSingleBranch,
RecurseSubmodules: getRecurseSubmodules(g.opts.GitRecurseSubmodules),
}
if len(parts) > 1 {
options.ReferenceName = plumbing.ReferenceName(parts[1])
}

if branch := g.opts.GitBranch; branch != "" {
ref, err := getGitReferenceName(directory, url, branch)
if err != nil {
return directory, err
}
options.ReferenceName = ref
}

logrus.Debugf("Getting source from reference %s", options.ReferenceName)
_, err := git.PlainClone(directory, false, &options)
return directory, err
}

func getGitReferenceName(directory string, url string, branch string) (plumbing.ReferenceName, error) {
var remote = git.NewRemote(
filesystem.NewStorage(
osfs.New(directory),
cache.NewObjectLRUDefault(),
),
&config.RemoteConfig{
URLs: []string{url},
},
)

refs, err := remote.List(&git.ListOptions{
Auth: getGitAuth(),
})
if err != nil {
return plumbing.HEAD, err
}

if ref := plumbing.NewBranchReferenceName(branch); gitRefExists(ref, refs) {
return ref, nil
}

if ref := plumbing.NewTagReferenceName(branch); gitRefExists(ref, refs) {
return ref, nil
}

return plumbing.HEAD, fmt.Errorf("invalid branch: %s", branch)
}

func gitRefExists(ref plumbing.ReferenceName, refs []*plumbing.Reference) bool {
for _, ref2 := range refs {
if ref.String() == ref2.Name().String() {
return true
}
}
return false
}

func getRecurseSubmodules(v bool) git.SubmoduleRescursivity {
if v {
return git.DefaultSubmoduleRecursionDepth
}
return git.NoRecurseSubmodules
}

func getGitAuth() transport.AuthMethod {
username := os.Getenv(gitAuthUsernameEnvKey)
password := os.Getenv(gitAuthPasswordEnvKey)
Expand Down
4 changes: 2 additions & 2 deletions pkg/buildcontext/git_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ import (
"testing"

"github.com/GoogleContainerTools/kaniko/testutil"
"gopkg.in/src-d/go-git.v4/plumbing/transport"
"gopkg.in/src-d/go-git.v4/plumbing/transport/http"
"github.com/go-git/go-git/v5/plumbing/transport"
"github.com/go-git/go-git/v5/plumbing/transport/http"
)

func TestGetGitPullMethod(t *testing.T) {
Expand Down
45 changes: 45 additions & 0 deletions pkg/config/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ limitations under the License.
package config

import (
"errors"
"fmt"
"strconv"
"strings"
"time"
)

Expand Down Expand Up @@ -58,6 +62,47 @@ type KanikoOptions struct {
IgnoreVarRun bool
SkipUnusedStages bool
RunV2 bool
Git KanikoGitOptions
}

type KanikoGitOptions struct {
Branch string
SingleBranch bool
RecurseSubmodules bool
}

var ErrInvalidGitFlag = errors.New("invalid git flag, must be in the key=value format")

func (k *KanikoGitOptions) Type() string {
return "gitoptions"
}

func (k *KanikoGitOptions) String() string {
return fmt.Sprintf("branch=%s,single-branch=%t,recurse-submodules=%t", k.Branch, k.SingleBranch, k.RecurseSubmodules)
}

func (k *KanikoGitOptions) Set(s string) error {
var parts = strings.SplitN(s, "=", 2)
if len(parts) != 2 {
return fmt.Errorf("%w: %s", ErrInvalidGitFlag, s)
}
switch parts[0] {
case "branch":
k.Branch = parts[1]
case "single-branch":
v, err := strconv.ParseBool(parts[1])
if err != nil {
return err
}
k.SingleBranch = v
case "recurse-submodules":
v, err := strconv.ParseBool(parts[1])
if err != nil {
return err
}
k.RecurseSubmodules = v
}
return nil
}

// WarmerOptions are options that are set by command line arguments to the cache warmer.
Expand Down
37 changes: 37 additions & 0 deletions pkg/config/options_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package config

import (
"testing"

"github.com/GoogleContainerTools/kaniko/testutil"
)

func TestKanikoGitOptions(t *testing.T) {
t.Run("invalid pair", func(t *testing.T) {
var g = &KanikoGitOptions{}
testutil.CheckError(t, true, g.Set("branch"))
})

t.Run("sets values", func(t *testing.T) {
var g = &KanikoGitOptions{}
testutil.CheckNoError(t, g.Set("branch=foo"))
testutil.CheckNoError(t, g.Set("recurse-submodules=true"))
testutil.CheckNoError(t, g.Set("single-branch=true"))
testutil.CheckDeepEqual(t, KanikoGitOptions{
Branch: "foo",
SingleBranch: true,
RecurseSubmodules: true,
}, *g)
})

t.Run("sets bools other than true", func(t *testing.T) {
var g = KanikoGitOptions{}
testutil.CheckError(t, true, g.Set("recurse-submodules="))
testutil.CheckError(t, true, g.Set("single-branch=zaza"))
testutil.CheckNoError(t, g.Set("recurse-submodules=false"))
testutil.CheckDeepEqual(t, KanikoGitOptions{
SingleBranch: false,
RecurseSubmodules: false,
}, g)
})
}
2 changes: 1 addition & 1 deletion vendor/github.com/emirpasic/gods/containers/enumerable.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading