mirror of
https://github.com/ko-build/ko.git
synced 2025-09-16 08:56:23 +02:00
Add --disable-optimizations flag to make debugging easier. (#24)
* Ignore GoLand files. * Add --disable-optimizations flag to make debugging easier. * Fix unit test (by ignoring the new functionality).
This commit is contained in:
committed by
jonjohnsonjr
parent
3584e2d4d3
commit
b0a1702132
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# Ignore GoLand (IntelliJ) files.
|
||||
.idea/
|
||||
|
@@ -70,6 +70,7 @@ func addKubeCommands(topLevel *cobra.Command) {
|
||||
no := &NameOptions{}
|
||||
fo := &FilenameOptions{}
|
||||
ta := &TagsOptions{}
|
||||
do := &DebugOptions{}
|
||||
apply := &cobra.Command{
|
||||
Use: "apply -f FILENAME",
|
||||
Short: "Apply the input files with image references resolved to built/pushed image digests.",
|
||||
@@ -144,7 +145,7 @@ func addKubeCommands(topLevel *cobra.Command) {
|
||||
stdin.Write([]byte("---\n"))
|
||||
}
|
||||
// Once primed kick things off.
|
||||
resolveFilesToWriter(fo, no, lo, ta, stdin)
|
||||
resolveFilesToWriter(fo, no, lo, ta, do, stdin)
|
||||
}()
|
||||
|
||||
// Run it.
|
||||
@@ -157,6 +158,7 @@ func addKubeCommands(topLevel *cobra.Command) {
|
||||
addNamingArgs(apply, no)
|
||||
addFileArg(apply, fo)
|
||||
addTagsArg(apply, ta)
|
||||
addDebugArg(apply, do)
|
||||
|
||||
// Collect the ko-specific apply flags before registering the kubectl global
|
||||
// flags so that we can ignore them when passing kubectl global flags through
|
||||
@@ -197,13 +199,14 @@ func addKubeCommands(topLevel *cobra.Command) {
|
||||
ko resolve --local -f config/`,
|
||||
Args: cobra.NoArgs,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
resolveFilesToWriter(fo, no, lo, ta, os.Stdout)
|
||||
resolveFilesToWriter(fo, no, lo, ta, do, os.Stdout)
|
||||
},
|
||||
}
|
||||
addLocalArg(resolve, lo)
|
||||
addNamingArgs(resolve, no)
|
||||
addFileArg(resolve, fo)
|
||||
addTagsArg(resolve, ta)
|
||||
addDebugArg(resolve, do)
|
||||
topLevel.AddCommand(resolve)
|
||||
|
||||
publish := &cobra.Command{
|
||||
@@ -237,12 +240,13 @@ func addKubeCommands(topLevel *cobra.Command) {
|
||||
ko publish --local github.com/foo/bar/cmd/baz github.com/foo/bar/cmd/blah`,
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
Run: func(_ *cobra.Command, args []string) {
|
||||
publishImages(args, no, lo, ta)
|
||||
publishImages(args, no, lo, ta, do)
|
||||
},
|
||||
}
|
||||
addLocalArg(publish, lo)
|
||||
addNamingArgs(publish, no)
|
||||
addTagsArg(publish, ta)
|
||||
addDebugArg(publish, do)
|
||||
topLevel.AddCommand(publish)
|
||||
|
||||
run := &cobra.Command{
|
||||
@@ -259,7 +263,7 @@ func addKubeCommands(topLevel *cobra.Command) {
|
||||
# This supports relative import paths as well.
|
||||
ko run foo --image=./cmd/baz`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
imgs := publishImages([]string{bo.Path}, no, lo, ta)
|
||||
imgs := publishImages([]string{bo.Path}, no, lo, ta, do)
|
||||
|
||||
// There's only one, but this is the simple way to access the
|
||||
// reference since the import path may have been qualified.
|
||||
@@ -293,6 +297,7 @@ func addKubeCommands(topLevel *cobra.Command) {
|
||||
addNamingArgs(run, no)
|
||||
addImageArg(run, bo)
|
||||
addTagsArg(run, ta)
|
||||
addDebugArg(run, do)
|
||||
|
||||
topLevel.AddCommand(run)
|
||||
}
|
||||
|
29
cmd/ko/debug.go
Normal file
29
cmd/ko/debug.go
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright 2019 Google LLC All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// DebugOptions holds options to improve debugging containers.
|
||||
type DebugOptions struct {
|
||||
DisableOptimizations bool
|
||||
}
|
||||
|
||||
func addDebugArg(cmd *cobra.Command, do *DebugOptions) {
|
||||
cmd.Flags().BoolVar(&do.DisableOptimizations, "disable-optimizations", do.DisableOptimizations,
|
||||
"Disable optimizations when building Go code. Useful when you want to interactively debug the created container.")
|
||||
}
|
@@ -38,8 +38,8 @@ func qualifyLocalImport(importpath, gopathsrc, pwd string) (string, error) {
|
||||
return filepath.Join(strings.TrimPrefix(pwd, gopathsrc+string(filepath.Separator)), importpath), nil
|
||||
}
|
||||
|
||||
func publishImages(importpaths []string, no *NameOptions, lo *LocalOptions, ta *TagsOptions) map[string]name.Reference {
|
||||
opt, err := gobuildOptions()
|
||||
func publishImages(importpaths []string, no *NameOptions, lo *LocalOptions, ta *TagsOptions, do *DebugOptions) map[string]name.Reference {
|
||||
opt, err := gobuildOptions(do)
|
||||
if err != nil {
|
||||
log.Fatalf("error setting up builder options: %v", err)
|
||||
}
|
||||
|
@@ -30,7 +30,7 @@ import (
|
||||
"github.com/mattmoor/dep-notify/pkg/graph"
|
||||
)
|
||||
|
||||
func gobuildOptions() ([]build.Option, error) {
|
||||
func gobuildOptions(do *DebugOptions) ([]build.Option, error) {
|
||||
creationTime, err := getCreationTime()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -41,11 +41,14 @@ func gobuildOptions() ([]build.Option, error) {
|
||||
if creationTime != nil {
|
||||
opts = append(opts, build.WithCreationTime(*creationTime))
|
||||
}
|
||||
if do.DisableOptimizations {
|
||||
opts = append(opts, build.WithDisabledOptimizations())
|
||||
}
|
||||
return opts, nil
|
||||
}
|
||||
|
||||
func makeBuilder() (*build.Caching, error) {
|
||||
opt, err := gobuildOptions()
|
||||
func makeBuilder(do *DebugOptions) (*build.Caching, error) {
|
||||
opt, err := gobuildOptions(do)
|
||||
if err != nil {
|
||||
log.Fatalf("error setting up builder options: %v", err)
|
||||
}
|
||||
@@ -104,9 +107,9 @@ func makePublisher(no *NameOptions, lo *LocalOptions, ta *TagsOptions) (publish.
|
||||
// resolvedFuture represents a "future" for the bytes of a resolved file.
|
||||
type resolvedFuture chan []byte
|
||||
|
||||
func resolveFilesToWriter(fo *FilenameOptions, no *NameOptions, lo *LocalOptions, ta *TagsOptions, out io.WriteCloser) {
|
||||
func resolveFilesToWriter(fo *FilenameOptions, no *NameOptions, lo *LocalOptions, ta *TagsOptions, do *DebugOptions, out io.WriteCloser) {
|
||||
defer out.Close()
|
||||
builder, err := makeBuilder()
|
||||
builder, err := makeBuilder(do)
|
||||
if err != nil {
|
||||
log.Fatalf("error creating builder: %v", err)
|
||||
}
|
||||
|
@@ -38,12 +38,13 @@ const (
|
||||
|
||||
// GetBase takes an importpath and returns a base v1.Image.
|
||||
type GetBase func(string) (v1.Image, error)
|
||||
type builder func(string) (string, error)
|
||||
type builder func(string, bool) (string, error)
|
||||
|
||||
type gobuild struct {
|
||||
getBase GetBase
|
||||
creationTime v1.Time
|
||||
build builder
|
||||
disableOptimizations bool
|
||||
}
|
||||
|
||||
// Option is a functional option for NewGo.
|
||||
@@ -53,6 +54,7 @@ type gobuildOpener struct {
|
||||
getBase GetBase
|
||||
creationTime v1.Time
|
||||
build builder
|
||||
disableOptimizations bool
|
||||
}
|
||||
|
||||
func (gbo *gobuildOpener) Open() (Interface, error) {
|
||||
@@ -63,6 +65,7 @@ func (gbo *gobuildOpener) Open() (Interface, error) {
|
||||
getBase: gbo.getBase,
|
||||
creationTime: gbo.creationTime,
|
||||
build: gbo.build,
|
||||
disableOptimizations: gbo.disableOptimizations,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -94,14 +97,22 @@ func (*gobuild) IsSupportedReference(s string) bool {
|
||||
return p.IsCommand()
|
||||
}
|
||||
|
||||
func build(ip string) (string, error) {
|
||||
func build(ip string, disableOptimizations bool) (string, error) {
|
||||
tmpDir, err := ioutil.TempDir("", "ko")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
file := filepath.Join(tmpDir, "out")
|
||||
|
||||
cmd := exec.Command("go", "build", "-o", file, ip)
|
||||
args := make([]string, 0, 6)
|
||||
args = append(args, "build")
|
||||
if disableOptimizations {
|
||||
// Disable optimizations (-N) and inlining (-l).
|
||||
args = append(args, "-gcflags", "all=-N -l")
|
||||
}
|
||||
args = append(args, "-o", file)
|
||||
args = append(args, ip)
|
||||
cmd := exec.Command("go", args...)
|
||||
|
||||
// Last one wins
|
||||
// TODO(mattmoor): GOARCH=amd64
|
||||
@@ -273,7 +284,7 @@ func tarKoData(importpath string) (*bytes.Buffer, error) {
|
||||
// Build implements build.Interface
|
||||
func (gb *gobuild) Build(s string) (v1.Image, error) {
|
||||
// Do the build into a temporary file.
|
||||
file, err := gb.build(s)
|
||||
file, err := gb.build(s, gb.disableOptimizations)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -62,7 +62,7 @@ func TestGoBuildIsSupportedRef(t *testing.T) {
|
||||
}
|
||||
|
||||
// A helper method we use to substitute for the default "build" method.
|
||||
func writeTempFile(s string) (string, error) {
|
||||
func writeTempFile(s string, _ bool) (string, error) {
|
||||
tmpDir, err := ioutil.TempDir("", "ko")
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
@@ -36,6 +36,15 @@ func WithCreationTime(t v1.Time) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// WithDisabledOptimizations is a functional option for disabling optimizations
|
||||
// when compiling.
|
||||
func WithDisabledOptimizations() Option {
|
||||
return func(gbo *gobuildOpener) error {
|
||||
gbo.disableOptimizations = true
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// withBuilder is a functional option for overriding the way go binaries
|
||||
// are built. This is exposed for testing.
|
||||
func withBuilder(b builder) Option {
|
||||
|
Reference in New Issue
Block a user