mirror of https://github.com/docker/compose.git
Merge pull request #1474 from docker/build_windows
This commit is contained in:
commit
d67e8b9c51
|
@ -62,35 +62,8 @@ func mustDelegateToMoby(ctxType string) bool {
|
||||||
|
|
||||||
// Exec delegates to com.docker.cli if on moby context
|
// Exec delegates to com.docker.cli if on moby context
|
||||||
func Exec(root *cobra.Command) {
|
func Exec(root *cobra.Command) {
|
||||||
execBinary, err := resolvepath.LookPath(ComDockerCli)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
cmd := exec.Command(execBinary, os.Args[1:]...)
|
|
||||||
cmd.Stdin = os.Stdin
|
|
||||||
cmd.Stdout = os.Stdout
|
|
||||||
cmd.Stderr = os.Stderr
|
|
||||||
|
|
||||||
signals := make(chan os.Signal, 1)
|
|
||||||
childExit := make(chan bool)
|
childExit := make(chan bool)
|
||||||
signal.Notify(signals) // catch all signals
|
err := RunDocker(childExit, os.Args[1:]...)
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case sig := <-signals:
|
|
||||||
if cmd.Process == nil {
|
|
||||||
continue // can happen if receiving signal before the process is actually started
|
|
||||||
}
|
|
||||||
// nolint errcheck
|
|
||||||
cmd.Process.Signal(sig)
|
|
||||||
case <-childExit:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
err = cmd.Run()
|
|
||||||
childExit <- true
|
childExit <- true
|
||||||
if err != nil {
|
if err != nil {
|
||||||
metrics.Track(store.DefaultContextType, os.Args[1:], metrics.FailureStatus)
|
metrics.Track(store.DefaultContextType, os.Args[1:], metrics.FailureStatus)
|
||||||
|
@ -110,6 +83,38 @@ func Exec(root *cobra.Command) {
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RunDocker runs a docker command, and forward signals to the shellout command (stops listening to signals when an event is sent to childExit)
|
||||||
|
func RunDocker(childExit chan bool, args ...string) error {
|
||||||
|
execBinary, err := resolvepath.LookPath(ComDockerCli)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
cmd := exec.Command(execBinary, args...)
|
||||||
|
cmd.Stdin = os.Stdin
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
|
signals := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(signals) // catch all signals
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case sig := <-signals:
|
||||||
|
if cmd.Process == nil {
|
||||||
|
continue // can happen if receiving signal before the process is actually started
|
||||||
|
}
|
||||||
|
// nolint errcheck
|
||||||
|
cmd.Process.Signal(sig)
|
||||||
|
case <-childExit:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return cmd.Run()
|
||||||
|
}
|
||||||
|
|
||||||
// IsDefaultContextCommand checks if the command exists in the classic cli (issues a shellout --help)
|
// IsDefaultContextCommand checks if the command exists in the classic cli (issues a shellout --help)
|
||||||
func IsDefaultContextCommand(dockerCommand string) bool {
|
func IsDefaultContextCommand(dockerCommand string) bool {
|
||||||
cmd := exec.Command(ComDockerCli, dockerCommand, "--help")
|
cmd := exec.Command(ComDockerCli, dockerCommand, "--help")
|
||||||
|
|
|
@ -41,6 +41,18 @@ import (
|
||||||
func (s *composeService) Build(ctx context.Context, project *types.Project, options compose.BuildOptions) error {
|
func (s *composeService) Build(ctx context.Context, project *types.Project, options compose.BuildOptions) error {
|
||||||
opts := map[string]build.Options{}
|
opts := map[string]build.Options{}
|
||||||
imagesToBuild := []string{}
|
imagesToBuild := []string{}
|
||||||
|
|
||||||
|
// retrieve OS type
|
||||||
|
info, err := s.apiClient.Info(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if info.OSType == "windows" {
|
||||||
|
// no support yet for Windows container builds in Buildkit
|
||||||
|
// https://docs.docker.com/develop/develop-images/build_enhancements/#limitations
|
||||||
|
return s.windowsBuild(project, options)
|
||||||
|
}
|
||||||
|
|
||||||
for _, service := range project.Services {
|
for _, service := range project.Services {
|
||||||
if service.Build != nil {
|
if service.Build != nil {
|
||||||
imageName := getImageName(service, project.Name)
|
imageName := getImageName(service, project.Name)
|
||||||
|
@ -66,7 +78,7 @@ func (s *composeService) Build(ctx context.Context, project *types.Project, opti
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err := s.build(ctx, project, opts, options.Progress)
|
err = s.build(ctx, project, opts, options.Progress)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if len(imagesToBuild) > 0 {
|
if len(imagesToBuild) > 0 {
|
||||||
utils.DisplayScanSuggestMsg()
|
utils.DisplayScanSuggestMsg()
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
/*
|
||||||
|
Copyright 2020 Docker Compose CLI authors
|
||||||
|
|
||||||
|
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 compose
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/docker/compose-cli/api/compose"
|
||||||
|
"github.com/docker/compose-cli/cli/mobycli"
|
||||||
|
|
||||||
|
"github.com/compose-spec/compose-go/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *composeService) windowsBuild(project *types.Project, options compose.BuildOptions) error {
|
||||||
|
projectDir := project.WorkingDir
|
||||||
|
for _, service := range project.Services {
|
||||||
|
if service.Build != nil {
|
||||||
|
imageName := getImageName(service, project.Name)
|
||||||
|
dockerfile := service.Build.Dockerfile
|
||||||
|
if dockerfile != "" {
|
||||||
|
if stat, err := os.Stat(projectDir); err == nil && stat.IsDir() {
|
||||||
|
|
||||||
|
dockerfile = filepath.Join(projectDir, dockerfile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// build args
|
||||||
|
cmd := &commandBuilder{
|
||||||
|
Path: filepath.Join(projectDir, service.Build.Context),
|
||||||
|
}
|
||||||
|
cmd.addParams("--build-arg", options.Args)
|
||||||
|
cmd.addFlag("--pull", options.Pull)
|
||||||
|
cmd.addArg("--progress", options.Progress)
|
||||||
|
|
||||||
|
cmd.addList("--cache-from", service.Build.CacheFrom)
|
||||||
|
cmd.addArg("--file", dockerfile)
|
||||||
|
cmd.addParams("--label", service.Build.Labels)
|
||||||
|
cmd.addArg("--network", service.Build.Network)
|
||||||
|
cmd.addArg("--target", service.Build.Target)
|
||||||
|
cmd.addArg("--platform", service.Platform)
|
||||||
|
cmd.addArg("--isolation", service.Build.Isolation)
|
||||||
|
cmd.addList("--add-host", service.Build.ExtraHosts)
|
||||||
|
|
||||||
|
cmd.addArg("--tag", imageName)
|
||||||
|
|
||||||
|
args := cmd.getArguments()
|
||||||
|
// shell out to moby cli
|
||||||
|
childExit := make(chan bool)
|
||||||
|
err := mobycli.RunDocker(childExit, args...)
|
||||||
|
childExit <- true
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type commandBuilder struct {
|
||||||
|
Args []string
|
||||||
|
Path string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *commandBuilder) addArg(name, value string) {
|
||||||
|
if value != "" {
|
||||||
|
c.Args = append(c.Args, name, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *commandBuilder) addFlag(name string, flag bool) {
|
||||||
|
if flag {
|
||||||
|
c.Args = append(c.Args, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *commandBuilder) addParams(name string, params map[string]string) {
|
||||||
|
if len(params) > 0 {
|
||||||
|
for k, v := range params {
|
||||||
|
c.Args = append(c.Args, name, fmt.Sprintf("%s=%s", k, v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *commandBuilder) addList(name string, values []string) {
|
||||||
|
if len(values) > 0 {
|
||||||
|
for _, v := range values {
|
||||||
|
c.Args = append(c.Args, name, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *commandBuilder) getArguments() []string {
|
||||||
|
cmd := []string{"build"}
|
||||||
|
cmd = append(cmd, c.Args...)
|
||||||
|
cmd = append(cmd, c.Path)
|
||||||
|
return cmd
|
||||||
|
}
|
Loading…
Reference in New Issue