Compare commits

..

34 Commits

Author SHA1 Message Date
Guillaume Lours
6b2ca93981 change dowstream ref
Signed-off-by: Guillaume Lours <guillaume.lours@docker.com>
2022-05-25 14:28:23 +02:00
Guillaume Lours
963e2e8757 update PAT token name
Signed-off-by: Guillaume Lours <guillaume.lours@docker.com>
2022-05-25 14:21:17 +02:00
Guillaume Lours
342ddc5ee5 Trigger dispatch manually for test purpose
Co-authored-by: CrazyMax <github@crazymax.dev>
2022-05-25 14:19:46 +02:00
Guillaume Lours
3b7f5ffc6b add a workflow to trigger a PR creation on Docker Documentation repo
Signed-off-by: Guillaume Lours <guillaume.lours@docker.com>
2022-05-25 14:12:02 +02:00
Guillaume Lours
5b6b674da9 Merge pull request #9495 from maxcleme/chore/bump_compose_go
bump compose-go to 1.2.6
2022-05-23 15:01:05 +02:00
Maxime CLEMENT
31d9490a0b bump compose-go to 1.2.6
Signed-off-by: Maxime CLEMENT <maxime.clement@docker.com>
2022-05-23 14:51:09 +02:00
Guillaume Lours
6b71073ae2 Merge pull request #9453 from glours/go-18
update golang version to 1.18
2022-05-23 10:41:03 +02:00
Guillaume Lours
e806acce88 Merge pull request #9481 from glours/add-tags-to-build
add tags property to build section
2022-05-23 10:23:40 +02:00
Guillaume Lours
71600a52bf update golang version to 1.18
Signed-off-by: Guillaume Lours <guillaume.lours@docker.com>
2022-05-20 22:13:55 +02:00
Guillaume Lours
285a9c94f7 Merge pull request #9476 from maxcleme/9469-fix-flickering-prompt
fix: prevent flickering prompt when pulling same image from N services
2022-05-20 22:09:02 +02:00
Guillaume Lours
22194f6ef7 Merge pull request #9493 from ulyssessouza/fix-local-e2e-compose-standalone
Fix local run of `make e2e-compose-standalone`
2022-05-20 21:41:42 +02:00
Ulysses Souza
e51fd0a844 Fix local run of make e2e-compose-standalone
Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com>
2022-05-20 21:31:16 +02:00
Ulysses Souza
b961d49859 Merge pull request #9033 from ulyssessouza/add-e2e-ddev
Add ddev's e2e test
2022-05-20 20:02:58 +02:00
Guillaume Lours
9cae9eb0fe Merge pull request #9488 from ndeloof/attach_profiles
attach _only_ to services declared by project applying profiles
2022-05-20 14:38:08 +02:00
Nicolas De Loof
8d03e29994 attach _only_ to services declared by project applying profiles
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2022-05-20 10:36:06 +02:00
Guillaume Lours
7ee7becd01 fix TestLocalComposeUp which fail locally
Signed-off-by: Guillaume Lours <guillaume.lours@docker.com>
2022-05-20 07:36:34 +02:00
Randy Fay
97d46a14ef Fix problems with ddev e2e test and minor cleanup, add tmate (#27)
* Add tmate for debugging
* Use -parallel=1 for standaone tests

Signed-off-by: Randy Fay <randy@randyfay.com>
2022-05-19 14:14:03 +02:00
Ulysses Souza
a5a1c5f2f1 Add ddev's e2e test
Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com>
2022-05-19 14:14:03 +02:00
Guillaume Lours
a2770b66ff add tags property to build section
Signed-off-by: Guillaume Lours <guillaume.lours@docker.com>
2022-05-18 14:43:54 +02:00
Maxime CLEMENT
48b150beff fix: prevent flickering prompt when pulling same image from N services
Signed-off-by: Maxime CLEMENT <maxime.clement@docker.com>
2022-05-18 08:58:06 +02:00
Guillaume Lours
7e3564b7ad Merge pull request #9475 from ndeloof/bump-compose-go
bump compose-go to 1.2.5
2022-05-17 17:21:00 +02:00
Nicolas De Loof
65b827d08f bump compose-go to 1.2.5
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2022-05-17 17:11:32 +02:00
Jan Vitturi
84f2168f80 Fix extra space printed with --no-log-prefix option
Signed-off-by: Jan Vitturi <vitturi.jan@gmail.com>
2022-05-17 15:20:21 +02:00
Guillaume Lours
a603e27117 cp command from service to host: use the first container found to copy source on the host
Signed-off-by: Guillaume Lours <guillaume.lours@docker.com>
2022-05-10 10:50:40 +02:00
Guillaume Lours
6d9d75406c update usage of the index flag of the cp command
Signed-off-by: Guillaume Lours <guillaume.lours@docker.com>
2022-05-10 10:50:40 +02:00
Guillaume Lours
a964d5587b align cp command index management with exec command
Signed-off-by: Guillaume Lours <guillaume.lours@docker.com>
2022-05-10 10:50:40 +02:00
Guillaume Lours
a983cf551d cp command: copy to all containers of a service as default behaviour
Signed-off-by: Guillaume Lours <guillaume.lours@docker.com>
2022-05-10 10:50:40 +02:00
Guillaume Lours
2f47e4582c Merge pull request #9440 from ndeloof/down_error
compose down exit=0 if nothing to remove
2022-05-06 10:42:26 +02:00
Nicolas De Loof
78b06764a1 compose down exit=0 if nothing to remove
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2022-05-04 13:51:21 +02:00
Guillaume Lours
4cebef1bf1 Merge pull request #9423 from quite/clarify-workdir
Clarify what default work dir is when multiple compose files
2022-05-03 14:02:03 +02:00
Daniel Lublin
d89c143c39 Clarify what default work dir is when multiple compose files
Signed-off-by: Daniel Lublin <daniel@lublin.se>
2022-05-03 13:14:34 +02:00
Guillaume Lours
028cb4dd89 Merge pull request #9158 from Jille/compose-down-noargs
down: Reject all arguments
2022-05-02 15:37:01 +02:00
Jille Timmermans
147c2d8fae down: Reject all arguments
The down command silently ignored all arguments, which might cause
confusion and/or outages if someone expects `docker-compose down
$service` to be the opposite of `docker-compose up $service`, rather
than turning down everything.

Signed-off-by: Jille Timmermans <jille@quis.cx>
2022-05-02 15:28:30 +02:00
Ulysses Souza
69e21d89f0 Fix relative paths on envfile label
Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com>
2022-04-30 10:14:39 +02:00
34 changed files with 371 additions and 135 deletions

View File

@@ -7,10 +7,10 @@ jobs:
if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '/generate-artifacts')
runs-on: ubuntu-latest
steps:
- name: Set up Go 1.17
- name: Set up Go 1.18
uses: actions/setup-go@v2
with:
go-version: 1.17
go-version: 1.18.2
id: go
- name: Checkout code into the Go module directory

View File

@@ -5,6 +5,12 @@ on:
branches:
- v2
pull_request:
workflow_dispatch:
inputs:
debug_enabled:
description: 'To run with tmate enter "debug_enabled"'
required: false
default: "false"
jobs:
lint:
@@ -13,10 +19,10 @@ jobs:
env:
GO111MODULE: "on"
steps:
- name: Set up Go 1.17
- name: Set up Go 1.18
uses: actions/setup-go@v2
with:
go-version: 1.17
go-version: 1.18.2
id: go
- name: Checkout code into the Go module directory
@@ -40,10 +46,10 @@ jobs:
env:
GO111MODULE: "on"
steps:
- name: Set up Go 1.17
- name: Set up Go 1.18
uses: actions/setup-go@v2
with:
go-version: 1.17
go-version: 1.18.2
id: go
- name: Checkout code into the Go module directory
@@ -65,10 +71,10 @@ jobs:
env:
GO111MODULE: "on"
steps:
- name: Set up Go 1.17
- name: Set up Go 1.18
uses: actions/setup-go@v2
with:
go-version: 1.17
go-version: 1.18.2
id: go
- name: Setup docker CLI
@@ -90,7 +96,7 @@ jobs:
- name: Build for local E2E
env:
BUILD_TAGS: e2e
run: make -f builder.Makefile compose-plugin
run: make GIT_TAG=e2e-PR-${{ github.event.pull_request.number }}-${{ github.event.pull_request.head.sha }} -f builder.Makefile compose-plugin
- name: E2E Test in plugin mode
run: make e2e-compose
@@ -101,10 +107,10 @@ jobs:
env:
GO111MODULE: "on"
steps:
- name: Set up Go 1.17
- name: Set up Go 1.18
uses: actions/setup-go@v2
with:
go-version: 1.17
go-version: 1.18.2
id: go
- name: Setup docker CLI
@@ -123,7 +129,17 @@ jobs:
- name: Build for local E2E
env:
BUILD_TAGS: e2e
run: make -f builder.Makefile compose-plugin
run: make GIT_TAG=e2e-PR-${{ github.event.pull_request.number }}-${{ github.event.pull_request.head.sha }} -f builder.Makefile compose-plugin
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
with:
limit-access-to-actor: true
github-token: ${{ secrets.GITHUB_TOKEN }}
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }}
- name: E2E Test in standalone mode
run: make e2e-compose-standalone
run: |
rm -f /usr/local/bin/docker-compose
cp bin/docker-compose /usr/local/bin
make e2e-compose-standalone

22
.github/workflows/dispatch-release.yml vendored Normal file
View File

@@ -0,0 +1,22 @@
name: dispatch release event to downstream repositories
on:
workflow_dispatch:
jobs:
dispatch_release_version:
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v6
with:
github-token: ${{ secrets.PAT_DOC_TOKEN }}
script: |
await github.rest.actions.createWorkflowDispatch({
owner: 'docker',
repo: 'docker.github.io',
workflow_id: 'compose_release',
ref: 'compose-api-upstream',
inputs: {
release: ${{ GITHUB_REF }},
},
})

View File

@@ -11,10 +11,10 @@ jobs:
upload-release:
runs-on: ubuntu-latest
steps:
- name: Set up Go 1.17
- name: Set up Go 1.18
uses: actions/setup-go@v2
with:
go-version: 1.17
go-version: 1.18.2
id: go
- name: Setup docker CLI

View File

@@ -15,7 +15,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
ARG GO_VERSION=1.17-alpine
ARG GO_VERSION=1.18.2-alpine
ARG GOLANGCI_LINT_VERSION=v1.40.1-alpine
ARG PROTOC_GEN_GO_VERSION=v1.4.3
@@ -88,7 +88,7 @@ RUN --mount=target=. \
make -f builder.Makefile test
FROM base AS check-license-headers
RUN go get -u github.com/kunalkushwaha/ltag
RUN go install github.com/kunalkushwaha/ltag@latest
RUN --mount=target=. \
make -f builder.Makefile check-license-headers

View File

@@ -43,11 +43,13 @@ compose-plugin: ## Compile the compose cli-plugin
.PHONY: e2e-compose
e2e-compose: ## Run end to end local tests in plugin mode. Set E2E_TEST=TestName to run a single test
docker compose version
go test $(TEST_FLAGS) -count=1 ./pkg/e2e
.PHONY: e2e-compose-standalone
e2e-compose-standalone: ## Run End to end local tests in standalone mode. Set E2E_TEST=TestName to run a single test
go test $(TEST_FLAGS) -count=1 --tags=standalone ./pkg/e2e
docker-compose version
go test $(TEST_FLAGS) -v -count=1 -parallel=1 --tags=standalone ./pkg/e2e
.PHONY: mocks
mocks:

View File

@@ -129,8 +129,8 @@ func (o *projectOptions) addProjectFlags(f *pflag.FlagSet) {
f.StringVarP(&o.ProjectName, "project-name", "p", "", "Project name")
f.StringArrayVarP(&o.ConfigPaths, "file", "f", []string{}, "Compose configuration files")
f.StringVar(&o.EnvFile, "env-file", "", "Specify an alternate environment file.")
f.StringVar(&o.ProjectDir, "project-directory", "", "Specify an alternate working directory\n(default: the path of the Compose file)")
f.StringVar(&o.WorkDir, "workdir", "", "DEPRECATED! USE --project-directory INSTEAD.\nSpecify an alternate working directory\n(default: the path of the Compose file)")
f.StringVar(&o.ProjectDir, "project-directory", "", "Specify an alternate working directory\n(default: the path of the, first specified, Compose file)")
f.StringVar(&o.WorkDir, "workdir", "", "DEPRECATED! USE --project-directory INSTEAD.\nSpecify an alternate working directory\n(default: the path of the, first specified, Compose file)")
f.BoolVar(&o.Compatibility, "compatibility", false, "Run compose in backward compatibility mode")
_ = f.MarkHidden("workdir")
}
@@ -169,7 +169,10 @@ func (o *projectOptions) toProject(services []string, po ...cli.ProjectOptionsFn
ef := o.EnvFile
if ef != "" && !filepath.IsAbs(ef) {
ef = filepath.Join(project.WorkingDir, o.EnvFile)
ef, err = filepath.Abs(ef)
if err != nil {
return nil, err
}
}
for i, s := range project.Services {
s.CustomLabels = map[string]string{
@@ -210,9 +213,9 @@ func (o *projectOptions) toProjectOptions(po ...cli.ProjectOptionsFn) (*cli.Proj
return cli.NewProjectOptions(o.ConfigPaths,
append(po,
cli.WithWorkingDirectory(o.ProjectDir),
cli.WithOsEnv,
cli.WithEnvFile(o.EnvFile),
cli.WithDotEnv,
cli.WithOsEnv,
cli.WithConfigFileEnv,
cli.WithDefaultConfigPath,
cli.WithName(o.ProjectName))...)

View File

@@ -55,7 +55,7 @@ func copyCommand(p *projectOptions, backend api.Service) *cobra.Command {
}
return nil
}),
RunE: Adapt(func(ctx context.Context, args []string) error {
RunE: AdaptCmd(func(ctx context.Context, cmd *cobra.Command, args []string) error {
opts.source = args[0]
opts.destination = args[1]
return runCopy(ctx, backend, opts)
@@ -64,8 +64,10 @@ func copyCommand(p *projectOptions, backend api.Service) *cobra.Command {
}
flags := copyCmd.Flags()
flags.IntVar(&opts.index, "index", 1, "Index of the container if there are multiple instances of a service [default: 1].")
flags.IntVar(&opts.index, "index", 0, "Index of the container if there are multiple instances of a service .")
flags.BoolVar(&opts.all, "all", false, "Copy to all the containers of the service.")
flags.MarkHidden("all") //nolint:errcheck
flags.MarkDeprecated("all", "By default all the containers of the service will get the source file/directory to be copied.") //nolint:errcheck
flags.BoolVarP(&opts.followLink, "follow-link", "L", false, "Always follow symbol link in SRC_PATH")
flags.BoolVarP(&opts.copyUIDGID, "archive", "a", false, "Archive mode (copy all uid/gid information)")

View File

@@ -59,6 +59,7 @@ func downCommand(p *projectOptions, backend api.Service) *cobra.Command {
RunE: Adapt(func(ctx context.Context, args []string) error {
return runDown(ctx, backend, opts)
}),
Args: cobra.NoArgs,
ValidArgsFunction: noCompletion(),
}
flags := downCmd.Flags()

View File

@@ -185,6 +185,9 @@ func runUp(ctx context.Context, backend api.Service, createOptions createOptions
if upOptions.attachDependencies {
attachTo = project.ServiceNames()
}
if len(attachTo) == 0 {
attachTo = project.ServiceNames()
}
create := api.CreateOptions{
Services: services,

View File

@@ -79,7 +79,7 @@ func (l *logConsumer) Log(container, service, message string) {
}
p := l.getPresenter(container)
for _, line := range strings.Split(message, "\n") {
fmt.Fprintf(l.writer, "%s %s\n", p.prefix, line) // nolint:errcheck
fmt.Fprintf(l.writer, "%s%s\n", p.prefix, line) // nolint:errcheck
}
}
@@ -118,5 +118,5 @@ type presenter struct {
}
func (p *presenter) setPrefix(width int) {
p.prefix = p.colors(fmt.Sprintf("%-"+strconv.Itoa(width)+"s |", p.name))
p.prefix = p.colors(fmt.Sprintf("%-"+strconv.Itoa(width)+"s | ", p.name))
}

View File

@@ -15,7 +15,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
ARG GO_VERSION=1.17
ARG GO_VERSION=1.18.2
ARG FORMATS=md,yaml
FROM --platform=${BUILDPLATFORM} golang:${GO_VERSION}-alpine AS docsgen

View File

@@ -44,7 +44,7 @@ Docker Compose
| `-f`, `--file` | `stringArray` | | Compose configuration files |
| `--profile` | `stringArray` | | Specify a profile to enable |
| `--project-directory` | `string` | | Specify an alternate working directory
(default: the path of the Compose file) |
(default: the path of the, first specified, Compose file) |
| `-p`, `--project-name` | `string` | | Project name |

View File

@@ -7,10 +7,9 @@ Copy files/folders between a service container and the local filesystem
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `--all` | | | Copy to all the containers of the service. |
| `-a`, `--archive` | | | Archive mode (copy all uid/gid information) |
| `-L`, `--follow-link` | | | Always follow symbol link in SRC_PATH |
| `--index` | `int` | `1` | Index of the container if there are multiple instances of a service [default: 1]. |
| `--index` | `int` | `0` | Index of the container if there are multiple instances of a service . |
<!---MARKER_GEN_END-->

View File

@@ -222,7 +222,7 @@ options:
value_type: string
description: |-
Specify an alternate working directory
(default: the path of the Compose file)
(default: the path of the, first specified, Compose file)
deprecated: false
hidden: false
experimental: false
@@ -265,7 +265,7 @@ options:
description: |-
DEPRECATED! USE --project-directory INSTEAD.
Specify an alternate working directory
(default: the path of the Compose file)
(default: the path of the, first specified, Compose file)
deprecated: false
hidden: true
experimental: false

View File

@@ -10,8 +10,8 @@ options:
value_type: bool
default_value: "false"
description: Copy to all the containers of the service.
deprecated: false
hidden: false
deprecated: true
hidden: true
experimental: false
experimentalcli: false
kubernetes: false
@@ -40,9 +40,9 @@ options:
swarm: false
- option: index
value_type: int
default_value: "1"
default_value: "0"
description: |
Index of the container if there are multiple instances of a service [default: 1].
Index of the container if there are multiple instances of a service .
deprecated: false
hidden: false
experimental: false

8
go.mod
View File

@@ -1,12 +1,12 @@
module github.com/docker/compose/v2
go 1.17
go 1.18
require (
github.com/AlecAivazis/survey/v2 v2.3.2
github.com/buger/goterm v1.0.4
github.com/cnabio/cnab-to-oci v0.3.1-beta1
github.com/compose-spec/compose-go v1.2.4
github.com/compose-spec/compose-go v1.2.6
github.com/containerd/console v1.0.3
github.com/containerd/containerd v1.6.2
github.com/distribution/distribution/v3 v3.0.0-20210316161203-a01c71e2477e
@@ -35,7 +35,7 @@ require (
github.com/theupdateframework/notary v0.6.1
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
gotest.tools v2.2.0+incompatible
gotest.tools/v3 v3.1.0
gotest.tools/v3 v3.2.0
)
require (
@@ -78,7 +78,7 @@ require (
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
github.com/miekg/pkcs11 v1.0.3 // indirect
github.com/mitchellh/mapstructure v1.4.3 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/moby/locker v1.0.1 // indirect
github.com/moby/sys/signal v0.6.0 // indirect
github.com/moby/sys/symlink v0.2.0 // indirect

17
go.sum
View File

@@ -259,7 +259,6 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA
github.com/certifi/gocertifi v0.0.0-20180118203423-deb3ae2ef261/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4=
github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.0/go.mod h1:dgIUBU3pDso/gPgZ1osOZ0iQf77oPR28Tjxl5dIMyVM=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
@@ -302,8 +301,8 @@ github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoC
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI=
github.com/codahale/hdrhistogram v0.0.0-20160425231609-f8ad88b59a58/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
github.com/compose-spec/compose-go v1.0.8/go.mod h1:REnCbBugoIdHB7S1sfkN/aJ7AJpNApGNjNiVjA9L8x4=
github.com/compose-spec/compose-go v1.2.4 h1:nzTFqM8+2J7Veao5Pq5U451thinv3U1wChIvcjX59/A=
github.com/compose-spec/compose-go v1.2.4/go.mod h1:pAy7Mikpeft4pxkFU565/DRHEbDfR84G6AQuiL+Hdg8=
github.com/compose-spec/compose-go v1.2.6 h1:9l2Y/yNn/OSngnkUBP8h8CchTmMcf1MW4BeUEaZXy8k=
github.com/compose-spec/compose-go v1.2.6/go.mod h1:cg8yTeI+7rfQsEW9XHOLx0sNVjGKEXr6XwVB4fxmG3A=
github.com/compose-spec/godotenv v1.1.1/go.mod h1:zF/3BOa18Z24tts5qnO/E9YURQanJTBUf7nlcCTNsyc=
github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE=
github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU=
@@ -1033,8 +1032,8 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh
github.com/mitchellh/mapstructure v1.3.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs=
github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
github.com/moby/buildkit v0.8.1/go.mod h1:/kyU1hKy/aYCuP39GZA9MaKioovHku57N6cqlKZIaiQ=
github.com/moby/buildkit v0.10.0-rc2.0.20220308185020-fdecd0ae108b h1:plbnJxjht8Z6D3c/ga79D1+VaA/IUfNVp08J3lcDgI8=
@@ -1475,7 +1474,6 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M=
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.opentelemetry.io/contrib v0.20.0 h1:ubFQUn0VCZ0gPwIoJfBJVpeBlyRMxu8Mm/huKWYd9p0=
go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.28.0/go.mod h1:vEhqr0m4eTc+DWxfsXoXue2GBgV2uUwVznkGIHW/e5w=
@@ -1492,7 +1490,6 @@ go.opentelemetry.io/otel v1.4.0/go.mod h1:jeAqMFKy2uLIxCtKxoFj0FAL5zAPKQagc3+GtB
go.opentelemetry.io/otel v1.4.1 h1:QbINgGDDcoQUoMJa2mMaWno49lja9sHwp6aoa2n3a4g=
go.opentelemetry.io/otel v1.4.1/go.mod h1:StM6F/0fSwpd8dKWDCdRr7uRvEPYdW0hBSlbdTiUde4=
go.opentelemetry.io/otel/exporters/jaeger v1.4.1/go.mod h1:ZW7vkOu9nC1CxsD8bHNHCia5JUbwP39vxgd1q4Z5rCI=
go.opentelemetry.io/otel/exporters/otlp v0.20.0 h1:PTNgq9MRmQqqJY0REVbZFvwkYOA85vbdQU/nVfxDyqg=
go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM=
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.3.0/go.mod h1:VpP4/RMn8bv8gNo9uK7/IMY4mtWLELsS+JIP0inH0h4=
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.4.1/go.mod h1:VpP4/RMn8bv8gNo9uK7/IMY4mtWLELsS+JIP0inH0h4=
@@ -2148,8 +2145,8 @@ gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
gotest.tools/v3 v3.1.0 h1:rVV8Tcg/8jHUkPUorwjaMTtemIMVXfIPKiOqnhEhakk=
gotest.tools/v3 v3.1.0/go.mod h1:fHy7eyTmJFO5bQbUsEGQ1v4m2J3Jz9eWL54TP2/ZuYQ=
gotest.tools/v3 v3.2.0 h1:I0DwBVMGAx26dttAj1BtJLAkVGncrkkUXfJLC4Flt/I=
gotest.tools/v3 v3.2.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A=
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20180920025451-e3ad64cb4ed3/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
@@ -2194,7 +2191,6 @@ k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8
k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
@@ -2233,7 +2229,6 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyz
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06 h1:zD2IemQ4LmOcAumeiyDWXKUI2SO0NYDe3H6QGvPOVgU=
sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18=
sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=

View File

@@ -275,6 +275,10 @@ func (s *composeService) toBuildOptions(project *types.Project, service types.Se
sessionConfig = append(sessionConfig, p)
}
if len(service.Build.Tags) > 0 {
tags = append(tags, service.Build.Tags...)
}
return build.Options{
Inputs: build.Inputs{
ContextPath: service.Build.Context,
@@ -291,7 +295,7 @@ func (s *composeService) toBuildOptions(project *types.Project, service types.Se
Platforms: plats,
Labels: service.Build.Labels,
NetworkMode: service.Build.Network,
ExtraHosts: service.Build.ExtraHosts,
ExtraHosts: service.Build.ExtraHosts.AsList(),
Session: sessionConfig,
}, nil
}

View File

@@ -18,14 +18,13 @@ package compose
import (
"context"
"fmt"
"sort"
"strconv"
moby "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/utils"
moby "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
)
// Containers is a set of moby Container
@@ -41,17 +40,7 @@ const (
func (s *composeService) getContainers(ctx context.Context, project string, oneOff oneOff, stopped bool, selectedServices ...string) (Containers, error) {
var containers Containers
f := []filters.KeyValuePair{projectFilter(project)}
if len(selectedServices) == 1 {
f = append(f, serviceFilter(selectedServices[0]))
}
switch oneOff {
case oneOffOnly:
f = append(f, oneOffFilter(true))
case oneOffExclude:
f = append(f, oneOffFilter(false))
case oneOffInclude:
}
f := getDefaultFilters(project, oneOff, selectedServices...)
containers, err := s.apiClient().ContainerList(ctx, moby.ContainerListOptions{
Filters: filters.NewArgs(f...),
All: stopped,
@@ -65,6 +54,40 @@ func (s *composeService) getContainers(ctx context.Context, project string, oneO
return containers, nil
}
func getDefaultFilters(projectName string, oneOff oneOff, selectedServices ...string) []filters.KeyValuePair {
f := []filters.KeyValuePair{projectFilter(projectName)}
if len(selectedServices) == 1 {
f = append(f, serviceFilter(selectedServices[0]))
}
switch oneOff {
case oneOffOnly:
f = append(f, oneOffFilter(true))
case oneOffExclude:
f = append(f, oneOffFilter(false))
case oneOffInclude:
}
return f
}
func (s *composeService) getSpecifiedContainer(ctx context.Context, projectName string, oneOff oneOff, stopped bool, serviceName string, containerIndex int) (moby.Container, error) {
defaultFilters := getDefaultFilters(projectName, oneOff, serviceName)
defaultFilters = append(defaultFilters, containerNumberFilter(containerIndex))
containers, err := s.apiClient().ContainerList(ctx, moby.ContainerListOptions{
Filters: filters.NewArgs(
defaultFilters...,
),
All: stopped,
})
if err != nil {
return moby.Container{}, err
}
if len(containers) < 1 {
return moby.Container{}, fmt.Errorf("service %q is not running container #%d", serviceName, containerIndex)
}
container := containers[0]
return container, nil
}
// containerPredicate define a predicate we want container to satisfy for filtering operations
type containerPredicate func(c moby.Container) bool
@@ -87,14 +110,6 @@ func isNotOneOff(c moby.Container) bool {
return !ok || v == "False"
}
func indexed(index int) containerPredicate {
return func(c moby.Container) bool {
number := c.Labels[api.ContainerNumberLabel]
idx, err := strconv.Atoi(number)
return err == nil && index == idx
}
}
// filter return Containers with elements to match predicate
func (containers Containers) filter(predicate containerPredicate) Containers {
var filtered Containers

View File

@@ -49,9 +49,11 @@ func (s *composeService) Copy(ctx context.Context, projectName string, options a
var direction copyDirection
var serviceName string
var copyFunc func(ctx context.Context, containerID string, srcPath string, dstPath string, opts api.CopyOptions) error
if srcService != "" {
direction |= fromService
serviceName = srcService
copyFunc = s.copyFromContainer
// copying from multiple containers of a services doesn't make sense.
if options.All {
@@ -61,41 +63,59 @@ func (s *composeService) Copy(ctx context.Context, projectName string, options a
if destService != "" {
direction |= toService
serviceName = destService
copyFunc = s.copyToContainer
}
if direction == acrossServices {
return errors.New("copying between services is not supported")
}
containers, err := s.getContainers(ctx, projectName, oneOffExclude, true, serviceName)
if direction == 0 {
return errors.New("unknown copy direction")
}
containers, err := s.listContainersTargetedForCopy(ctx, projectName, options.Index, direction, serviceName)
if err != nil {
return err
}
if len(containers) < 1 {
return fmt.Errorf("no container found for service %q", serviceName)
}
if !options.All {
containers = containers.filter(indexed(options.Index))
}
g := errgroup.Group{}
for _, container := range containers {
containerID := container.ID
g.Go(func() error {
switch direction {
case fromService:
return s.copyFromContainer(ctx, containerID, srcPath, dstPath, options)
case toService:
return s.copyToContainer(ctx, containerID, srcPath, dstPath, options)
case acrossServices:
return errors.New("copying between services is not supported")
default:
return errors.New("unknown copy direction")
}
return copyFunc(ctx, containerID, srcPath, dstPath, options)
})
}
return g.Wait()
}
func (s *composeService) listContainersTargetedForCopy(ctx context.Context, projectName string, index int, direction copyDirection, serviceName string) (Containers, error) {
var containers Containers
var err error
switch {
case index > 0:
container, err := s.getSpecifiedContainer(ctx, projectName, oneOffExclude, true, serviceName, index)
if err != nil {
return nil, err
}
return append(containers, container), nil
default:
containers, err = s.getContainers(ctx, projectName, oneOffExclude, true, serviceName)
if err != nil {
return nil, err
}
if len(containers) < 1 {
return nil, fmt.Errorf("no container found for service %q", serviceName)
}
if direction == fromService {
return containers[:1], err
}
return containers, err
}
}
func (s *composeService) copyToContainer(ctx context.Context, containerID string, srcPath string, dstPath string, opts api.CopyOptions) error {
var err error
if srcPath != "-" {

View File

@@ -375,7 +375,7 @@ func (s *composeService) getCreateOptions(ctx context.Context, p *types.Project,
DNS: service.DNS,
DNSSearch: service.DNSSearch,
DNSOptions: service.DNSOpts,
ExtraHosts: service.ExtraHosts,
ExtraHosts: service.ExtraHosts.AsList(),
SecurityOpt: securityOpts,
UsernsMode: container.UsernsMode(service.UserNSMode),
Privileged: service.Privileged,

View File

@@ -90,7 +90,7 @@ func (s *composeService) down(ctx context.Context, projectName string, options a
}
if !resourceToRemove && len(ops) == 0 {
w.Event(progress.NewEvent(projectName, progress.Done, "Warning: No resource found to remove"))
fmt.Fprintf(s.stderr(), "Warning: No resource found to remove for project %q.\n", projectName)
}
eg, _ := errgroup.WithContext(ctx)
@@ -239,7 +239,7 @@ func (s *composeService) removeContainers(ctx context.Context, w progress.Writer
func (s *composeService) getProjectWithResources(ctx context.Context, containers Containers, projectName string) (*types.Project, error) {
containers = containers.filter(isNotOneOff)
project, err := s.projectFromName(containers, projectName)
if err != nil {
if err != nil && !api.IsNotFoundError(err) {
return nil, err
}

View File

@@ -18,14 +18,12 @@ package compose
import (
"context"
"fmt"
"strings"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command/container"
"github.com/docker/compose/v2/pkg/api"
moby "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
)
func (s *composeService) Exec(ctx context.Context, projectName string, options api.RunOptions) (int, error) {
@@ -59,19 +57,5 @@ func (s *composeService) Exec(ctx context.Context, projectName string, options a
}
func (s *composeService) getExecTarget(ctx context.Context, projectName string, opts api.RunOptions) (moby.Container, error) {
containers, err := s.apiClient().ContainerList(ctx, moby.ContainerListOptions{
Filters: filters.NewArgs(
projectFilter(projectName),
serviceFilter(opts.Service),
containerNumberFilter(opts.Index),
),
})
if err != nil {
return moby.Container{}, err
}
if len(containers) < 1 {
return moby.Container{}, fmt.Errorf("service %q is not running container #%d", opts.Service, opts.Index)
}
container := containers[0]
return container, nil
return s.getSpecifiedContainer(ctx, projectName, oneOffInclude, false, opts.Service, opts.Index)
}

View File

@@ -61,12 +61,12 @@ func (s *composeService) Up(ctx context.Context, project *types.Project, options
go func() {
<-signalChan
s.Kill(ctx, project.Name, api.KillOptions{ // nolint:errcheck
Services: options.Create.Services,
Services: project.ServiceNames(),
})
}()
return s.Stop(ctx, project.Name, api.StopOptions{
Services: options.Create.Services,
Services: project.ServiceNames(),
})
})
}

View File

@@ -181,3 +181,24 @@ func TestBuildSecrets(t *testing.T) {
res.Assert(t, icmd.Success)
})
}
func TestBuildTags(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
t.Run("build with tags", func(t *testing.T) {
// ensure local test run does not reuse previously build image
c.RunDockerOrExitError("rmi", "build-test-tags")
c.RunDockerComposeCmd("--project-directory", "./fixtures/build-test/tags", "build", "--no-cache")
res := c.RunDockerCmd("image", "inspect", "build-test-tags")
expectedOutput := `"RepoTags": [
"docker/build-test-tags:1.0.0",
"build-test-tags:latest",
"other-image-name:v1.0.0"
],
`
res.Assert(t, icmd.Expected{Out: expectedOutput})
})
}

View File

@@ -0,0 +1,34 @@
/*
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 e2e
import (
"testing"
"gotest.tools/v3/icmd"
)
func TestDown(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
const projectName = "e2e-down"
t.Run("no resource to remove", func(t *testing.T) {
res := c.RunDockerOrExitError("compose", "--project-name", projectName, "down")
res.Assert(t, icmd.Expected{ExitCode: 0, Err: `No resource found to remove for project "e2e-down"`})
})
}

View File

@@ -95,7 +95,7 @@ func TestLocalComposeUp(t *testing.T) {
res := c.RunDockerComposeCmd("-p", projectName, "ps")
res.Assert(t, icmd.Expected{Out: `NAME COMMAND SERVICE STATUS PORTS`})
res.Assert(t, icmd.Expected{Out: `compose-e2e-demo-web-1 "/dispatcher" web running (healthy) 0.0.0.0:90->80/tcp, :::90->80/tcp`})
res.Assert(t, icmd.Expected{Out: `compose-e2e-demo-web-1 "/dispatcher" web running (healthy) 0.0.0.0:90->80/tcp`})
res.Assert(t, icmd.Expected{Out: `compose-e2e-demo-db-1 "docker-entrypoint.s…" db running 5432/tcp`})
})

View File

@@ -47,15 +47,18 @@ func TestCopy(t *testing.T) {
res.Assert(t, icmd.Expected{Out: `nginx running`})
})
t.Run("copy to container copies the file to the first container by default", func(t *testing.T) {
t.Run("copy to container copies the file to the all containers by default", func(t *testing.T) {
res := c.RunDockerComposeCmd("-f", "./fixtures/cp-test/compose.yaml", "-p", projectName, "cp", "./fixtures/cp-test/cp-me.txt", "nginx:/tmp/default.txt")
res.Assert(t, icmd.Expected{ExitCode: 0})
output := c.RunDockerCmd("exec", projectName+"-nginx-1", "cat", "/tmp/default.txt").Stdout()
assert.Assert(t, strings.Contains(output, `hello world`), output)
res = c.RunDockerOrExitError("exec", projectName+"_nginx_2", "cat", "/tmp/default.txt")
res.Assert(t, icmd.Expected{ExitCode: 1})
output = c.RunDockerCmd("exec", projectName+"-nginx-2", "cat", "/tmp/default.txt").Stdout()
assert.Assert(t, strings.Contains(output, `hello world`), output)
output = c.RunDockerCmd("exec", projectName+"-nginx-3", "cat", "/tmp/default.txt").Stdout()
assert.Assert(t, strings.Contains(output, `hello world`), output)
})
t.Run("copy to container with a given index copies the file to the given container", func(t *testing.T) {
@@ -69,20 +72,6 @@ func TestCopy(t *testing.T) {
res.Assert(t, icmd.Expected{ExitCode: 1})
})
t.Run("copy to container with the all flag copies the file to all containers", func(t *testing.T) {
res := c.RunDockerComposeCmd("-f", "./fixtures/cp-test/compose.yaml", "-p", projectName, "cp", "--all", "./fixtures/cp-test/cp-me.txt", "nginx:/tmp/all.txt")
res.Assert(t, icmd.Expected{ExitCode: 0})
output := c.RunDockerCmd("exec", projectName+"-nginx-1", "cat", "/tmp/all.txt").Stdout()
assert.Assert(t, strings.Contains(output, `hello world`), output)
output = c.RunDockerCmd("exec", projectName+"-nginx-2", "cat", "/tmp/all.txt").Stdout()
assert.Assert(t, strings.Contains(output, `hello world`), output)
output = c.RunDockerCmd("exec", projectName+"-nginx-3", "cat", "/tmp/all.txt").Stdout()
assert.Assert(t, strings.Contains(output, `hello world`), output)
})
t.Run("copy from a container copies the file to the host from the first container by default", func(t *testing.T) {
res := c.RunDockerComposeCmd("-f", "./fixtures/cp-test/compose.yaml", "-p", projectName, "cp", "nginx:/tmp/default.txt", "./fixtures/cp-test/from-default.txt")
res.Assert(t, icmd.Expected{ExitCode: 0})

86
pkg/e2e/ddev_test.go Normal file
View File

@@ -0,0 +1,86 @@
/*
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 e2e
import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
"testing"
"gotest.tools/v3/assert"
)
const ddevVersion = "v1.19.1"
func TestComposeRunDdev(t *testing.T) {
if !composeStandaloneMode {
t.Skip("Not running on standalone mode.")
}
if runtime.GOOS == "windows" {
t.Skip("Running on Windows. Skipping...")
}
_ = os.Setenv("DDEV_DEBUG", "true")
c := NewParallelE2eCLI(t, binDir)
dir, err := os.MkdirTemp("", t.Name()+"-")
assert.NilError(t, err)
// ddev needs to be able to find mkcert to figure out where certs are.
_ = os.Setenv("PATH", fmt.Sprintf("%s:%s", os.Getenv("PATH"), dir))
siteName := filepath.Base(dir)
t.Cleanup(func() {
_ = c.RunCmdInDir(dir, "./ddev", "delete", "-Oy")
_ = c.RunCmdInDir(dir, "./ddev", "poweroff")
_ = os.RemoveAll(dir)
})
osName := "linux"
if runtime.GOOS == "darwin" {
osName = "macos"
}
compressedFilename := fmt.Sprintf("ddev_%s-%s.%s.tar.gz", osName, runtime.GOARCH, ddevVersion)
c.RunCmdInDir(dir, "curl", "-LO",
fmt.Sprintf("https://github.com/drud/ddev/releases/download/%s/%s",
ddevVersion,
compressedFilename))
c.RunCmdInDir(dir, "tar", "-xzf", compressedFilename)
// Create a simple index.php we can test against.
c.RunCmdInDir(dir, "sh", "-c", "echo '<?php\nprint \"ddev is working\";' >index.php")
c.RunCmdInDir(dir, "./ddev", "config", "--auto")
c.RunCmdInDir(dir, "./ddev", "config", "global", "--use-docker-compose-from-path")
vRes := c.RunCmdInDir(dir, "./ddev", "version")
out := vRes.Stdout()
fmt.Printf("ddev version: %s\n", out)
c.RunCmdInDir(dir, "./ddev", "poweroff")
c.RunCmdInDir(dir, "./ddev", "start", "-y")
curlRes := c.RunCmdInDir(dir, "curl", "-sSL", fmt.Sprintf("http://%s.ddev.site", siteName))
out = curlRes.Stdout()
fmt.Println(out)
assert.Assert(c.test, strings.Contains(out, "ddev is working"), "Could not start project")
}

View File

@@ -0,0 +1,17 @@
# 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.
FROM nginx:alpine
RUN echo "SUCCESS"

View File

@@ -0,0 +1,9 @@
services:
nginx:
image: build-test-tags
build:
context: .
tags:
- docker.io/docker/build-test-tags:1.0.0
- other-image-name:v1.0.0

View File

@@ -192,6 +192,17 @@ func (c *E2eCLI) RunCmd(args ...string) *icmd.Result {
return res
}
// RunCmdInDir runs a command in a given dir, expects no error and returns a result
func (c *E2eCLI) RunCmdInDir(dir string, args ...string) *icmd.Result {
fmt.Printf("\t[%s] %s\n", c.test.Name(), strings.Join(args, " "))
assert.Assert(c.test, len(args) >= 1, "require at least one command in parameters")
cmd := c.NewCmd(args[0], args[1:]...)
cmd.Dir = dir
res := icmd.RunCmd(cmd)
res.Assert(c.test, icmd.Success)
return res
}
// RunDockerCmd runs a docker command, expects no error and returns a result
func (c *E2eCLI) RunDockerCmd(args ...string) *icmd.Result {
if len(args) > 0 && args[0] == compose.PluginName {

View File

@@ -83,7 +83,10 @@ func (w *ttyWriter) Event(e Event) {
last.Status = e.Status
last.Text = e.Text
last.StatusText = e.StatusText
last.ParentID = e.ParentID
// allow set/unset of parent, but not swapping otherwise prompt is flickering
if last.ParentID == "" || e.ParentID == "" {
last.ParentID = e.ParentID
}
w.events[e.ID] = last
} else {
e.startTime = time.Now()