From 3fd3b77b32a20a7b5758bc23432017d16a7abec8 Mon Sep 17 00:00:00 2001 From: Brad Hoekstra Date: Wed, 20 Feb 2019 14:40:43 -0500 Subject: [PATCH 1/2] Name the app using the base of the importpath --- pkg/ko/build/gobuild.go | 10 ++++++---- pkg/ko/build/gobuild_test.go | 8 ++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/pkg/ko/build/gobuild.go b/pkg/ko/build/gobuild.go index 6a378cebf..98394a1a5 100644 --- a/pkg/ko/build/gobuild.go +++ b/pkg/ko/build/gobuild.go @@ -31,7 +31,7 @@ import ( "github.com/google/go-containerregistry/pkg/v1/tarball" ) -const appPath = "/ko-app" +const appDir = "/ko-app" // GetBase takes an importpath and returns a base v1.Image. type GetBase func(string) (v1.Image, error) @@ -117,7 +117,7 @@ func build(ip string) (string, error) { return file, nil } -func tarBinary(binary string) (*bytes.Buffer, error) { +func tarBinary(name, binary string) (*bytes.Buffer, error) { buf := bytes.NewBuffer(nil) tw := tar.NewWriter(buf) defer tw.Close() @@ -132,7 +132,7 @@ func tarBinary(binary string) (*bytes.Buffer, error) { return nil, err } header := &tar.Header{ - Name: appPath, + Name: name, Size: stat.Size(), Typeflag: tar.TypeReg, // Use a fixed Mode, so that this isn't sensitive to the directory and umask @@ -249,8 +249,10 @@ func (gb *gobuild) Build(s string) (v1.Image, error) { } layers = append(layers, dataLayer) + appPath := filepath.Join(appDir, filepath.Base(s)) + // Construct a tarball with the binary and produce a layer. - binaryLayerBuf, err := tarBinary(file) + binaryLayerBuf, err := tarBinary(appPath, file) if err != nil { return nil, err } diff --git a/pkg/ko/build/gobuild_test.go b/pkg/ko/build/gobuild_test.go index 80cc2a95a..1cf472b3b 100644 --- a/pkg/ko/build/gobuild_test.go +++ b/pkg/ko/build/gobuild_test.go @@ -119,7 +119,7 @@ func TestGoBuildNoKoData(t *testing.T) { t.Run("check determinism", func(t *testing.T) { expectedHash := v1.Hash{ Algorithm: "sha256", - Hex: "a688c9bc444d0a34cbc24abd62aa2fa263f61f2060963bb7a4fc3fa92075a2bf", + Hex: "4b0bcce3acbfba36dbdb76d3c5d0dc43e268cf2666fcf58584fc714ccbb28bd7", } appLayer := ls[baseLayers+1] @@ -141,7 +141,7 @@ func TestGoBuildNoKoData(t *testing.T) { t.Errorf("len(entrypoint) = %v, want %v", got, want) } - if got, want := entrypoint[0], appPath; got != want { + if got, want := entrypoint[0], "/ko-app/crane"; got != want { t.Errorf("entrypoint = %v, want %v", got, want) } }) @@ -196,7 +196,7 @@ func TestGoBuild(t *testing.T) { t.Run("check determinism", func(t *testing.T) { expectedHash := v1.Hash{ Algorithm: "sha256", - Hex: "71912d718600c5a2b8db3a127a14073bba61dded0dac8e1a6ebdeb4a37f2ce8d", + Hex: "c7502053d5bcf34f0b720cdea2d53ff0e38e803756108396e09f92ad36cc375e", } appLayer := ls[baseLayers+1] @@ -277,7 +277,7 @@ func TestGoBuild(t *testing.T) { t.Errorf("len(entrypoint) = %v, want %v", got, want) } - if got, want := entrypoint[0], appPath; got != want { + if got, want := entrypoint[0], "/ko-app/test"; got != want { t.Errorf("entrypoint = %v, want %v", got, want) } }) From f66e69133df0adeb7183da1722b60cab50255694 Mon Sep 17 00:00:00 2001 From: Brad Hoekstra Date: Thu, 21 Feb 2019 10:07:30 -0500 Subject: [PATCH 2/2] Create parent directory, handle invalid base name --- pkg/ko/build/gobuild.go | 49 ++++++++++++++++++++++++++++++++++-- pkg/ko/build/gobuild_test.go | 4 +-- 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/pkg/ko/build/gobuild.go b/pkg/ko/build/gobuild.go index 98394a1a5..7300f5e22 100644 --- a/pkg/ko/build/gobuild.go +++ b/pkg/ko/build/gobuild.go @@ -31,7 +31,10 @@ import ( "github.com/google/go-containerregistry/pkg/v1/tarball" ) -const appDir = "/ko-app" +const ( + appDir = "/ko-app" + defaultAppFilename = "ko-app" +) // GetBase takes an importpath and returns a base v1.Image. type GetBase func(string) (v1.Image, error) @@ -117,11 +120,53 @@ func build(ip string) (string, error) { return file, nil } +func appFilename(importpath string) string { + base := filepath.Base(importpath) + + // If we fail to determine a good name from the importpath then use a + // safe default. + if base == "." || base == string(filepath.Separator) { + return defaultAppFilename + } + + return base +} + +func tarAddDirectories(tw *tar.Writer, dir string) error { + if dir == "." || dir == string(filepath.Separator) { + return nil + } + + // Write parent directories first + if err := tarAddDirectories(tw, filepath.Dir(dir)); err != nil { + return err + } + + // write the directory header to the tarball archive + if err := tw.WriteHeader(&tar.Header{ + Name: dir, + Typeflag: tar.TypeDir, + // Use a fixed Mode, so that this isn't sensitive to the directory and umask + // under which it was created. Additionally, windows can only set 0222, + // 0444, or 0666, none of which are executable. + Mode: 0555, + }); err != nil { + return err + } + + return nil +} + func tarBinary(name, binary string) (*bytes.Buffer, error) { buf := bytes.NewBuffer(nil) tw := tar.NewWriter(buf) defer tw.Close() + // write the parent directories to the tarball archive + if err := tarAddDirectories(tw, filepath.Dir(name)); err != nil { + return nil, err + } + file, err := os.Open(binary) if err != nil { return nil, err @@ -249,7 +294,7 @@ func (gb *gobuild) Build(s string) (v1.Image, error) { } layers = append(layers, dataLayer) - appPath := filepath.Join(appDir, filepath.Base(s)) + appPath := filepath.Join(appDir, appFilename(s)) // Construct a tarball with the binary and produce a layer. binaryLayerBuf, err := tarBinary(appPath, file) diff --git a/pkg/ko/build/gobuild_test.go b/pkg/ko/build/gobuild_test.go index 1cf472b3b..4ed9f77f5 100644 --- a/pkg/ko/build/gobuild_test.go +++ b/pkg/ko/build/gobuild_test.go @@ -119,7 +119,7 @@ func TestGoBuildNoKoData(t *testing.T) { t.Run("check determinism", func(t *testing.T) { expectedHash := v1.Hash{ Algorithm: "sha256", - Hex: "4b0bcce3acbfba36dbdb76d3c5d0dc43e268cf2666fcf58584fc714ccbb28bd7", + Hex: "f9a8bbe82883cf49161202d6697d906319c5b418725d4256778e6958c786801f", } appLayer := ls[baseLayers+1] @@ -196,7 +196,7 @@ func TestGoBuild(t *testing.T) { t.Run("check determinism", func(t *testing.T) { expectedHash := v1.Hash{ Algorithm: "sha256", - Hex: "c7502053d5bcf34f0b720cdea2d53ff0e38e803756108396e09f92ad36cc375e", + Hex: "d6538378e47da0d6780d9a7caa6bdeffa6428bc6d35b95e1802958d1eefb671c", } appLayer := ls[baseLayers+1]