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

Allow configuring app directory/path binaries are placed into #1403

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,18 @@ influence the build process.
| `KO_CONFIG_PATH` | `./.ko.yaml` | Path to `ko` configuration file (optional) |
| `KOCACHE` | (not set) | This tells `ko` to store a local mapping between the `go build` inputs to the image layer that they produce, so `go build` can be skipped entirely if the layer is already present in the image registry (optional). |

## Overwriting which directory binaries are placed in

By default `ko` places executable binaries of your application into `/ko-app`.

As it is sometimes desirable to place an executable into a specific folder inside
the container, or into a default executable path like `/bin` or `/usr/local/bin`,
this directory can be overwritten.

This custom path can be defined either
- via the `--app-dir` command line flag
- or a `defaultAppDirectory` entry in the `.ko.yaml` file.

## Naming Images

`ko` provides a few different strategies for naming the image it pushes, to
Expand Down
1 change: 1 addition & 0 deletions docs/reference/ko_apply.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ ko apply -f FILENAME [flags]
### Options

```
--app-dir string Directory the application binaries should be placed inside the container instead of default /ko-app.
--bare Whether to just use KO_DOCKER_REPO without additional context (may not work properly with --tags).
-B, --base-import-paths Whether to use the base path without MD5 hash after KO_DOCKER_REPO (may not work properly with --tags).
--debug Include Delve debugger into image and wrap around ko-app. This debugger will listen to port 40000.
Expand Down
1 change: 1 addition & 0 deletions docs/reference/ko_build.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ ko build IMPORTPATH... [flags]
### Options

```
--app-dir string Directory the application binaries should be placed inside the container instead of default /ko-app.
--bare Whether to just use KO_DOCKER_REPO without additional context (may not work properly with --tags).
-B, --base-import-paths Whether to use the base path without MD5 hash after KO_DOCKER_REPO (may not work properly with --tags).
--debug Include Delve debugger into image and wrap around ko-app. This debugger will listen to port 40000.
Expand Down
1 change: 1 addition & 0 deletions docs/reference/ko_create.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ ko create -f FILENAME [flags]
### Options

```
--app-dir string Directory the application binaries should be placed inside the container instead of default /ko-app.
--bare Whether to just use KO_DOCKER_REPO without additional context (may not work properly with --tags).
-B, --base-import-paths Whether to use the base path without MD5 hash after KO_DOCKER_REPO (may not work properly with --tags).
--debug Include Delve debugger into image and wrap around ko-app. This debugger will listen to port 40000.
Expand Down
1 change: 1 addition & 0 deletions docs/reference/ko_resolve.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ ko resolve -f FILENAME [flags]
### Options

```
--app-dir string Directory the application binaries should be placed inside the container instead of default /ko-app.
--bare Whether to just use KO_DOCKER_REPO without additional context (may not work properly with --tags).
-B, --base-import-paths Whether to use the base path without MD5 hash after KO_DOCKER_REPO (may not work properly with --tags).
--debug Include Delve debugger into image and wrap around ko-app. This debugger will listen to port 40000.
Expand Down
1 change: 1 addition & 0 deletions docs/reference/ko_run.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ ko run IMPORTPATH [flags]
### Options

```
--app-dir string Directory the application binaries should be placed inside the container instead of default /ko-app.
--bare Whether to just use KO_DOCKER_REPO without additional context (may not work properly with --tags).
-B, --base-import-paths Whether to use the base path without MD5 hash after KO_DOCKER_REPO (may not work properly with --tags).
--debug Include Delve debugger into image and wrap around ko-app. This debugger will listen to port 40000.
Expand Down
34 changes: 23 additions & 11 deletions pkg/build/gobuild.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import (

const (
defaultAppFilename = "ko-app"
defaultAppDir = "/ko-app"

defaultGoBin = "go" // defaults to first go binary found in PATH
goBinPathEnv = "KO_GO_PATH" // env lookup for optional relative or full go binary path
Expand Down Expand Up @@ -100,6 +101,7 @@ type gobuild struct {
defaultLdflags []string
platformMatcher *platformMatcher
dir string
appDir string
labels map[string]string
debug bool
semaphore *semaphore.Weighted
Expand Down Expand Up @@ -127,6 +129,7 @@ type gobuildOpener struct {
platforms []string
labels map[string]string
dir string
appDir string
jobs int
debug bool
}
Expand Down Expand Up @@ -158,6 +161,7 @@ func (gbo *gobuildOpener) Open() (Interface, error) {
defaultLdflags: gbo.defaultLdflags,
labels: gbo.labels,
dir: gbo.dir,
appDir: gbo.appDir,
debug: gbo.debug,
platformMatcher: matcher,
cache: &layerCache{
Expand Down Expand Up @@ -578,7 +582,7 @@ func appFilename(importpath string) string {
// owner: BUILTIN/Users group: BUILTIN/Users ($sddlValue="O:BUG:BU")
const userOwnerAndGroupSID = "AQAAgBQAAAAkAAAAAAAAAAAAAAABAgAAAAAABSAAAAAhAgAAAQIAAAAAAAUgAAAAIQIAAA=="

func tarBinary(name, binary string, platform *v1.Platform, opts *layerOptions) (*bytes.Buffer, error) {
func tarBinary(name, binary, binaryDir string, platform *v1.Platform, opts *layerOptions) (*bytes.Buffer, error) {
buf := bytes.NewBuffer(nil)
tw := tar.NewWriter(buf)
defer tw.Close()
Expand All @@ -587,12 +591,12 @@ func tarBinary(name, binary string, platform *v1.Platform, opts *layerOptions) (
// For Windows, the layer must contain a Hives/ directory, and the root
// of the actual filesystem goes in a Files/ directory.
// For Linux, the binary goes into /ko-app/
dirs := []string{"ko-app"}
dirs := []string{binaryDir}
if platform.OS == "windows" {
dirs = []string{
"Hives",
"Files",
"Files/ko-app",
path.Join("Files", binaryDir),
}
name = "Files" + name
}
Expand Down Expand Up @@ -927,6 +931,13 @@ func (g gobuild) useDebugging(platform v1.Platform) bool {
return g.debug && doesPlatformSupportDebugging(platform)
}

func (g gobuild) getAppDir() string {
if g.appDir != "" {
return g.appDir
}
return defaultAppDir
}

func (g *gobuild) buildOne(ctx context.Context, refStr string, base v1.Image, platform *v1.Platform) (oci.SignedImage, error) {
if err := g.semaphore.Acquire(ctx, 1); err != nil {
return nil, err
Expand Down Expand Up @@ -1043,7 +1054,7 @@ func (g *gobuild) buildOne(ctx context.Context, refStr string, base v1.Image, pl
},
})

appDir := "/ko-app"
appDir := g.getAppDir()
appFileName := appFilename(ref.Path())
appPath := path.Join(appDir, appFileName)

Expand All @@ -1054,7 +1065,7 @@ func (g *gobuild) buildOne(ctx context.Context, refStr string, base v1.Image, pl
}

miss := func() (v1.Layer, error) {
return buildLayer(appPath, file, platform, layerMediaType, &lo)
return buildLayer(g.getAppDir(), appPath, file, platform, layerMediaType, &lo)
}

var binaryLayer v1.Layer
Expand Down Expand Up @@ -1089,11 +1100,11 @@ func (g *gobuild) buildOne(ctx context.Context, refStr string, base v1.Image, pl
}
defer os.RemoveAll(filepath.Dir(delveBinary))

delvePath = path.Join("/ko-app", filepath.Base(delveBinary))
delvePath = path.Join(g.getAppDir(), filepath.Base(delveBinary))

// add layer with delve binary
delveLayer, err := g.cache.get(ctx, delveBinary, func() (v1.Layer, error) {
return buildLayer(delvePath, delveBinary, platform, layerMediaType, &lo)
return buildLayer(appDir, delvePath, delveBinary, platform, layerMediaType, &lo)
})
if err != nil {
return nil, fmt.Errorf("cache.get(%q): %w", delveBinary, err)
Expand Down Expand Up @@ -1136,15 +1147,16 @@ func (g *gobuild) buildOne(ctx context.Context, refStr string, base v1.Image, pl
cfg.Config.Entrypoint = []string{appPath}
cfg.Config.Cmd = nil
if platform.OS == "windows" {
appPath := `C:\ko-app\` + appFileName
appPath := strings.Replace(path.Join("C:", g.getAppDir(), appFileName), "/", `\`, -1)
if g.debug {
cfg.Config.Entrypoint = append([]string{"C:\\" + delvePath}, delveArgs...)
cfg.Config.Entrypoint = append(cfg.Config.Entrypoint, appPath)
} else {
cfg.Config.Entrypoint = []string{appPath}
}

updatePath(cfg, `C:\ko-app`)
addDirPath := strings.Replace(path.Join("C:", g.getAppDir()), "/", `\`, -1)
updatePath(cfg, addDirPath)
cfg.Config.Env = append(cfg.Config.Env, `KO_DATA_PATH=C:\var\run\ko`)
} else {
if g.useDebugging(*platform) {
Expand Down Expand Up @@ -1200,9 +1212,9 @@ type layerOptions struct {
linuxCapabilities *caps.FileCaps
}

func buildLayer(appPath, file string, platform *v1.Platform, layerMediaType types.MediaType, opts *layerOptions) (v1.Layer, error) {
func buildLayer(appDir, appPath, file string, platform *v1.Platform, layerMediaType types.MediaType, opts *layerOptions) (v1.Layer, error) {
// Construct a tarball with the binary and produce a layer.
binaryLayerBuf, err := tarBinary(appPath, file, platform, opts)
binaryLayerBuf, err := tarBinary(appPath, file, appDir, platform, opts)
if err != nil {
return nil, fmt.Errorf("tarring binary: %w", err)
}
Expand Down
Loading