Skip to content

Commit

Permalink
Allow specifying binary path in image
Browse files Browse the repository at this point in the history
Previously this was hard-coded to `/ko-app/<app-name>`.

go-releaser allows specifying the binary (including directory prefix);
we now support the same.
  • Loading branch information
justinsb committed Sep 8, 2023
1 parent daab1ac commit 0da27f1
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 18 deletions.
4 changes: 3 additions & 1 deletion pkg/build/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,16 @@ type Config struct {
// Env allows setting environment variables for `go build`
Env []string `yaml:",omitempty"`

// Binary allows overriding the output binary name (in the image)
Binary string `yaml:",omitempty"`

// Other GoReleaser fields that are not supported or do not make sense
// in the context of ko, for reference or for future use:
// Goos []string `yaml:",omitempty"`
// Goarch []string `yaml:",omitempty"`
// Goarm []string `yaml:",omitempty"`
// Gomips []string `yaml:",omitempty"`
// Targets []string `yaml:",omitempty"`
// Binary string `yaml:",omitempty"`
// Lang string `yaml:",omitempty"`
// Asmflags StringArray `yaml:",omitempty"`
// Gcflags StringArray `yaml:",omitempty"`
Expand Down
60 changes: 43 additions & 17 deletions pkg/build/gobuild.go
Original file line number Diff line number Diff line change
Expand Up @@ -496,25 +496,39 @@ func tarBinary(name, binary string, platform *v1.Platform) (*bytes.Buffer, error
// 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"}
appDir := filepath.Dir(name)
dirs := []string{appDir}
if platform.OS == "windows" {
dirs = []string{
"Hives",
"Files",
"Files/ko-app",
"Files/" + appDir,
}
name = "Files" + name
}
for _, dir := range dirs {
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 nil, fmt.Errorf("writing dir %q to tar: %w", dir, err)
// Create all parent directories also
var parents []string
current := dir
for {
parents = append(parents, current)
current = filepath.Dir(current)
if current == "/" {
break
}
}

for i := len(parents) - 1; i >= 0; i-- {
parent := parents[i]
if err := tw.WriteHeader(&tar.Header{
Name: parent,
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 nil, fmt.Errorf("writing dir %q to tar: %w", parent, err)
}
}
}

Expand Down Expand Up @@ -789,6 +803,14 @@ func (g *gobuild) configForImportPath(ip string) Config {
return config
}

// pathToWindows converts a unix-style path to a windows-style path.
// For example, /apps/foo => C:\apps\foo
func pathToWindows(s string) string {
pathComponents := []string{"C:"}
pathComponents = append(pathComponents, strings.Split(s, "/")...)
return strings.Join(pathComponents, `\`)
}

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 @@ -859,9 +881,13 @@ func (g *gobuild) buildOne(ctx context.Context, refStr string, base v1.Image, pl
},
})

appDir := "/ko-app"
appFileName := appFilename(ref.Path())
appPath := path.Join(appDir, appFileName)
config := g.configForImportPath(ref.Path())
appPath := config.Binary
if appPath == "" {
appPath = path.Join("/ko-app", appFilename(ref.Path()))
}
appDir := path.Dir(appPath)
appFileName := path.Base(appPath)

miss := func() (v1.Layer, error) {
return buildLayer(appPath, file, platform, layerMediaType)
Expand Down Expand Up @@ -900,8 +926,8 @@ 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" {
cfg.Config.Entrypoint = []string{`C:\ko-app\` + appFileName}
updatePath(cfg, `C:\ko-app`)
cfg.Config.Entrypoint = []string{pathToWindows(appPath)}
updatePath(cfg, pathToWindows(filepath.Dir(appPath)))
cfg.Config.Env = append(cfg.Config.Env, `KO_DATA_PATH=C:\var\run\ko`)
} else {
updatePath(cfg, appDir)
Expand Down

0 comments on commit 0da27f1

Please sign in to comment.