mirror of https://github.com/docker/compose.git
Merge branch 'v2' into ENGDOCS-1373
This commit is contained in:
commit
44dd232e97
7
Makefile
7
Makefile
|
@ -17,9 +17,10 @@ VERSION ?= $(shell git describe --match 'v[0-9]*' --dirty='.m' --always --tags)
|
|||
|
||||
GO_LDFLAGS ?= -w -X ${PKG}/internal.Version=${VERSION}
|
||||
GO_BUILDTAGS ?= e2e
|
||||
|
||||
DRIVE_PREFIX?=
|
||||
ifeq ($(OS),Windows_NT)
|
||||
DETECTED_OS = Windows
|
||||
DRIVE_PREFIX=C:
|
||||
else
|
||||
DETECTED_OS = $(shell uname -s)
|
||||
endif
|
||||
|
@ -122,8 +123,8 @@ docs: ## generate documentation
|
|||
$(eval $@_TMP_OUT := $(shell mktemp -d -t compose-output.XXXXXXXXXX))
|
||||
$(BUILDX_CMD) bake --set "*.output=type=local,dest=$($@_TMP_OUT)" docs-update
|
||||
rm -rf ./docs/internal
|
||||
cp -R "$($@_TMP_OUT)"/out/* ./docs/
|
||||
rm -rf "$($@_TMP_OUT)"/*
|
||||
cp -R "$(DRIVE_PREFIX)$($@_TMP_OUT)"/out/* ./docs/
|
||||
rm -rf "$(DRIVE_PREFIX)$($@_TMP_OUT)"/*
|
||||
|
||||
.PHONY: validate-docs
|
||||
validate-docs: ## validate the doc does not change
|
||||
|
|
|
@ -44,7 +44,7 @@ func downCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
|
|||
ProjectOptions: p,
|
||||
}
|
||||
downCmd := &cobra.Command{
|
||||
Use: "down [OPTIONS]",
|
||||
Use: "down [OPTIONS] [SERVICES]",
|
||||
Short: "Stop and remove containers, networks",
|
||||
PreRunE: AdaptCmd(func(ctx context.Context, cmd *cobra.Command, args []string) error {
|
||||
opts.timeChanged = cmd.Flags().Changed("timeout")
|
||||
|
@ -56,16 +56,15 @@ func downCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
|
|||
return nil
|
||||
}),
|
||||
RunE: Adapt(func(ctx context.Context, args []string) error {
|
||||
return runDown(ctx, backend, opts)
|
||||
return runDown(ctx, backend, opts, args)
|
||||
}),
|
||||
Args: cobra.NoArgs,
|
||||
ValidArgsFunction: noCompletion(),
|
||||
}
|
||||
flags := downCmd.Flags()
|
||||
removeOrphans := utils.StringToBool(os.Getenv(ComposeRemoveOrphans))
|
||||
flags.BoolVar(&opts.removeOrphans, "remove-orphans", removeOrphans, "Remove containers for services not defined in the Compose file.")
|
||||
flags.IntVarP(&opts.timeout, "timeout", "t", 10, "Specify a shutdown timeout in seconds")
|
||||
flags.BoolVarP(&opts.volumes, "volumes", "v", false, "Remove named volumes declared in the `volumes` section of the Compose file and anonymous volumes attached to containers.")
|
||||
flags.BoolVarP(&opts.volumes, "volumes", "v", false, `Remove named volumes declared in the "volumes" section of the Compose file and anonymous volumes attached to containers.`)
|
||||
flags.StringVar(&opts.images, "rmi", "", `Remove images used by services. "local" remove only images that don't have a custom tag ("local"|"all")`)
|
||||
flags.SetNormalizeFunc(func(f *pflag.FlagSet, name string) pflag.NormalizedName {
|
||||
if name == "volume" {
|
||||
|
@ -77,7 +76,7 @@ func downCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
|
|||
return downCmd
|
||||
}
|
||||
|
||||
func runDown(ctx context.Context, backend api.Service, opts downOptions) error {
|
||||
func runDown(ctx context.Context, backend api.Service, opts downOptions, services []string) error {
|
||||
project, name, err := opts.projectOrName()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -94,5 +93,6 @@ func runDown(ctx context.Context, backend api.Service, opts downOptions) error {
|
|||
Timeout: timeout,
|
||||
Images: opts.images,
|
||||
Volumes: opts.volumes,
|
||||
Services: services,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ Stop and remove containers, networks
|
|||
| `--remove-orphans` | | | Remove containers for services not defined in the Compose file. |
|
||||
| `--rmi` | `string` | | Remove images used by services. "local" remove only images that don't have a custom tag ("local"\|"all") |
|
||||
| `-t`, `--timeout` | `int` | `10` | Specify a shutdown timeout in seconds |
|
||||
| `-v`, `--volumes` | | | Remove named volumes declared in the `volumes` section of the Compose file and anonymous volumes attached to containers. |
|
||||
| `-v`, `--volumes` | | | Remove named volumes declared in the "volumes" section of the Compose file and anonymous volumes attached to containers. |
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
|
|
|
@ -14,7 +14,7 @@ long: |-
|
|||
Anonymous volumes are not removed by default. However, as they don’t have a stable name, they will not be automatically
|
||||
mounted by a subsequent `up`. For data that needs to persist between updates, use explicit paths as bind mounts or
|
||||
named volumes.
|
||||
usage: docker compose down [OPTIONS]
|
||||
usage: docker compose down [OPTIONS] [SERVICES]
|
||||
pname: docker compose
|
||||
plink: docker_compose.yaml
|
||||
options:
|
||||
|
@ -54,7 +54,7 @@ options:
|
|||
value_type: bool
|
||||
default_value: "false"
|
||||
description: |
|
||||
Remove named volumes declared in the `volumes` section of the Compose file and anonymous volumes attached to containers.
|
||||
Remove named volumes declared in the "volumes" section of the Compose file and anonymous volumes attached to containers.
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
Feature: Report port conflicts
|
||||
|
||||
Background:
|
||||
Given a compose file
|
||||
"""
|
||||
services:
|
||||
web:
|
||||
image: nginx
|
||||
ports:
|
||||
- 31415:80
|
||||
"""
|
||||
And I run "docker rm -f nginx-pi-31415"
|
||||
|
||||
Scenario: Reports a port allocation conflict with another container
|
||||
Given I run "docker run -d -p 31415:80 --name nginx-pi-31415 nginx"
|
||||
When I run "compose up -d"
|
||||
Then the output contains "port is already allocated"
|
||||
And the exit code is 1
|
||||
|
||||
Scenario: Reports a port conflict with some other process
|
||||
Given a process listening on port 31415
|
||||
When I run "compose up -d"
|
||||
Then the output contains "address already in use"
|
||||
And the exit code is 1
|
||||
|
||||
Scenario: Cleanup
|
||||
Given I run "docker rm -f nginx-pi-31415"
|
||||
|
|
@ -16,6 +16,7 @@ Background:
|
|||
"""
|
||||
FROM golang:1.19-alpine
|
||||
"""
|
||||
And I run "docker rm -f external-test"
|
||||
|
||||
Scenario: external container from compose image exists
|
||||
When I run "compose build"
|
||||
|
@ -24,4 +25,5 @@ Scenario: external container from compose image exists
|
|||
Then the exit code is 0
|
||||
And I run "compose ps -a"
|
||||
Then the output does not contain "external-test"
|
||||
And I run "docker rm -f external-test"
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ package cucumber
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
|
@ -87,6 +88,7 @@ func setup(s *godog.ScenarioContext) {
|
|||
s.Step(`output contains "(.*)"$`, th.outputContains(true))
|
||||
s.Step(`output does not contain "(.*)"$`, th.outputContains(false))
|
||||
s.Step(`exit code is (\d+)$`, th.exitCodeIs)
|
||||
s.Step(`a process listening on port (\d+)$`, th.listenerOnPort)
|
||||
}
|
||||
|
||||
type testHelper struct {
|
||||
|
@ -174,3 +176,16 @@ func (th *testHelper) setDockerfile(dockerfileString string) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (th *testHelper) listenerOnPort(port int) error {
|
||||
l, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
th.T.Cleanup(func() {
|
||||
_ = l.Close()
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
11
go.mod
11
go.mod
|
@ -5,7 +5,7 @@ go 1.20
|
|||
require (
|
||||
github.com/AlecAivazis/survey/v2 v2.3.6
|
||||
github.com/buger/goterm v1.0.4
|
||||
github.com/compose-spec/compose-go v1.13.5
|
||||
github.com/compose-spec/compose-go v1.14.0
|
||||
github.com/containerd/console v1.0.3
|
||||
github.com/containerd/containerd v1.6.21
|
||||
github.com/cucumber/godog v0.0.0-00010101000000-000000000000 // replaced; see replace for the actual version used
|
||||
|
@ -30,7 +30,7 @@ require (
|
|||
github.com/sirupsen/logrus v1.9.2
|
||||
github.com/spf13/cobra v1.7.0
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/stretchr/testify v1.8.2
|
||||
github.com/stretchr/testify v1.8.4
|
||||
github.com/theupdateframework/notary v0.7.0
|
||||
github.com/tilt-dev/fsnotify v1.4.8-0.20220602155310-fff9c274a375
|
||||
go.opentelemetry.io/otel v1.15.1
|
||||
|
@ -58,7 +58,7 @@ require (
|
|||
github.com/bugsnag/bugsnag-go v1.5.0 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.1.2 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/cloudflare/cfssl v1.4.1
|
||||
github.com/cloudflare/cfssl v1.6.4 // indirect
|
||||
github.com/containerd/continuity v0.3.0 // indirect
|
||||
github.com/containerd/ttrpc v1.1.1 // indirect
|
||||
github.com/containerd/typeurl v1.0.2 // indirect
|
||||
|
@ -136,7 +136,6 @@ require (
|
|||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
||||
github.com/zmap/zcrypto v0.0.0-20220605182715-4dfcec6e9a8c // indirect
|
||||
github.com/zmap/zlint v1.1.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.29.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.29.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.29.0 // indirect
|
||||
|
@ -149,7 +148,7 @@ require (
|
|||
go.opentelemetry.io/otel/sdk v1.4.1 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.15.1 // indirect
|
||||
go.opentelemetry.io/proto/otlp v0.12.0 // indirect
|
||||
golang.org/x/crypto v0.2.0 // indirect
|
||||
golang.org/x/crypto v0.3.0 // indirect
|
||||
golang.org/x/net v0.7.0 // indirect
|
||||
golang.org/x/oauth2 v0.1.0 // indirect; replaced; see replace for the actual version used
|
||||
golang.org/x/sys v0.5.0 // indirect
|
||||
|
@ -166,7 +165,7 @@ require (
|
|||
k8s.io/api v0.24.1 // indirect; replaced; see replace for the actual version used
|
||||
k8s.io/apimachinery v0.24.1 // indirect; replaced; see replace for the actual version used
|
||||
k8s.io/client-go v0.24.1 // indirect; replaced; see replace for the actual version used
|
||||
k8s.io/klog/v2 v2.60.1 // indirect
|
||||
k8s.io/klog/v2 v2.80.1 // indirect
|
||||
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
|
||||
sigs.k8s.io/yaml v1.2.0 // indirect
|
||||
|
|
56
go.sum
56
go.sum
|
@ -1,4 +1,3 @@
|
|||
bitbucket.org/liamstask/goose v0.0.0-20150115234039-8488cc47d90c/go.mod h1:hSVuE3qU7grINVSwrmzHfpg9k87ALBk+XaualNyUzI4=
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
|
@ -74,8 +73,6 @@ github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZ
|
|||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0=
|
||||
github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0=
|
||||
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
|
||||
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||
github.com/Microsoft/hcsshim v0.9.8 h1:lf7xxK2+Ikbj9sVf2QZsouGjRjEp2STj1yDHgoVtU5k=
|
||||
|
@ -89,7 +86,6 @@ github.com/Shopify/logrus-bugsnag v0.0.0-20170309145241-6dbc35f2c30d/go.mod h1:H
|
|||
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
|
@ -139,7 +135,6 @@ github.com/bugsnag/panicwrap v1.2.0 h1:OzrKrRvXis8qEvOkfcxNcYbOd2O7xXS2nnKMEMABF
|
|||
github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuDPIFo=
|
||||
github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/certifi/gocertifi v0.0.0-20180118203423-deb3ae2ef261/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||
|
@ -150,12 +145,9 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P
|
|||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/backoff v0.0.0-20161212185259-647f3cdfc87a/go.mod h1:rzgs2ZOiguV6/NpiDgADjRLPNyZlApIWxKpkT+X8SdY=
|
||||
github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA=
|
||||
github.com/cloudflare/cfssl v1.4.1 h1:vScfU2DrIUI9VPHBVeeAQ0q5A+9yshO1Gz+3QoUQiKw=
|
||||
github.com/cloudflare/cfssl v1.4.1/go.mod h1:KManx/OJPb5QY+y0+o/898AMcM128sF0bURvoVUSjTo=
|
||||
github.com/cloudflare/go-metrics v0.0.0-20151117154305-6a9aea36fb41/go.mod h1:eaZPlJWD+G9wseg1BuRXlHnjntPMrywMsyxf+LTOdP4=
|
||||
github.com/cloudflare/redoctober v0.0.0-20171127175943-746a508df14c/go.mod h1:6Se34jNoqrd8bTxrmJB2Bg2aoZ2CdSXonils9NsiNgo=
|
||||
github.com/cloudflare/cfssl v1.6.4 h1:NMOvfrEjFfC63K3SGXgAnFdsgkmiq4kATme5BfcqrO8=
|
||||
github.com/cloudflare/cfssl v1.6.4/go.mod h1:8b3CQMxfWPAeom3zBnGJ6sd+G1NkL5TXqmDXacb+1J0=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
|
@ -165,8 +157,8 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH
|
|||
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/compose-spec/compose-go v1.13.5 h1:ogqJOGEbe3uRxMg0ZEufOoCQTpX61l8tUeyW4UQgEBk=
|
||||
github.com/compose-spec/compose-go v1.13.5/go.mod h1:m0o4G6MQDHjjz9rY7No9FpnNi+9sKic262rzrwuCqic=
|
||||
github.com/compose-spec/compose-go v1.14.0 h1:/+tQxBEPIrfsi87Qh7/VjMzcJN3BRNER/RO71ku+u6E=
|
||||
github.com/compose-spec/compose-go v1.14.0/go.mod h1:m0o4G6MQDHjjz9rY7No9FpnNi+9sKic262rzrwuCqic=
|
||||
github.com/containerd/cgroups v1.0.4 h1:jN/mbWBEaz+T1pi5OFtnkQ+8qnmEbAr1Oo1FRm5B0dA=
|
||||
github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw=
|
||||
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
|
||||
|
@ -195,7 +187,6 @@ github.com/cucumber/messages-go/v16 v16.0.0/go.mod h1:EJcyR5Mm5ZuDsKJnT2N9KRnBK3
|
|||
github.com/cucumber/messages-go/v16 v16.0.1 h1:fvkpwsLgnIm0qugftrw2YwNlio+ABe2Iu94Ap8GMYIY=
|
||||
github.com/cucumber/messages-go/v16 v16.0.1/go.mod h1:EJcyR5Mm5ZuDsKJnT2N9KRnBK30BGjtYotDKpwQ0v6g=
|
||||
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||
github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
@ -262,7 +253,6 @@ github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4
|
|||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||
github.com/fvbommel/sortorder v1.0.2 h1:mV4o8B2hKboCdkJm+a7uX/SIpZob4JzUpc5GGnM45eo=
|
||||
github.com/fvbommel/sortorder v1.0.2/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
|
||||
github.com/getsentry/raven-go v0.0.0-20180121060056-563b81fc02b7/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
|
@ -345,8 +335,7 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z
|
|||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
|
||||
github.com/google/certificate-transparency-go v1.0.10-0.20180222191210-5ab67e519c93/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg=
|
||||
github.com/google/certificate-transparency-go v1.0.21 h1:Yf1aXowfZ2nuboBsg7iYGLmwsOARdV86pfH3g95wXmE=
|
||||
github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg=
|
||||
github.com/google/certificate-transparency-go v1.1.4 h1:hCyXHDbtqlr/lMXU0D4WgbalXL0Zk4dSWWMbPV8VrqY=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
|
@ -453,7 +442,6 @@ github.com/in-toto/in-toto-golang v0.5.0 h1:hb8bgwr0M2hGdDsLjkJ3ZqJ8JFLL/tgYdAxF
|
|||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jinzhu/gorm v0.0.0-20170222002820-5409931a1bb8/go.mod h1:Vla75njaFJ8clLU1W44h34PjIkijhjHIYnZxMqCdxqo=
|
||||
github.com/jinzhu/gorm v1.9.11 h1:gaHGvE+UnWGlbWG4Y3FUwY1EcZ5n6S9WtqBA/uySMLE=
|
||||
github.com/jinzhu/gorm v1.9.11/go.mod h1:bu/pK8szGZ2puuErfU0RwyeNdsf3e6nCX/noXaVxkfw=
|
||||
|
@ -464,8 +452,7 @@ github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/
|
|||
github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
github.com/jmhodges/clock v0.0.0-20160418191101-880ee4c33548/go.mod h1:hGT6jSUVzF6no3QaDSMLGLEHtHSBSefs+MgcDWnmhmo=
|
||||
github.com/jmoiron/sqlx v0.0.0-20180124204410-05cef0741ade/go.mod h1:IiEW3SEiiErVyFdH8NTuWjSifiEQKUoyK3LNqr2kCHU=
|
||||
github.com/jmoiron/sqlx v1.3.3 h1:j82X0bf7oQ27XeqxicSZsTU5suPwKElg3oyxNn43iTk=
|
||||
github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
|
||||
github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
|
@ -487,8 +474,6 @@ github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNU
|
|||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kisielk/sqlstruct v0.0.0-20150923205031-648daed35d49/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE=
|
||||
github.com/kisom/goutils v1.1.0/go.mod h1:+UBTfd78habUYWFbNWTJNG+jNG/i/lGURakr4A/yNRw=
|
||||
github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM=
|
||||
github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
|
@ -504,11 +489,9 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
|||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/go-gypsy v0.0.0-20160905020020-08cad365cd28/go.mod h1:T/T7jsxVqf9k/zYOqbgNAsANsjxTd1Yq3htjDhQ1H0c=
|
||||
github.com/laurazard/godog v0.0.0-20220922095256-4c4b17abdae7 h1:R/J7xECY9oHrAg+4QjC38EoXaYysNLzhvXhH/SXcsVc=
|
||||
github.com/laurazard/godog v0.0.0-20220922095256-4c4b17abdae7/go.mod h1:Y02TTpimPXDb70PnG6M3zpODXm1+bjCsuZzcW76xAww=
|
||||
github.com/lib/pq v0.0.0-20150723085316-0dad96c0b94f/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v0.0.0-20180201184707-88edab080323/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/magiconair/properties v1.5.3/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=
|
||||
|
@ -527,7 +510,6 @@ github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh
|
|||
github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk=
|
||||
github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
|
||||
github.com/mattn/go-sqlite3 v1.6.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
||||
|
@ -576,7 +558,6 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
|
|||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
|
@ -710,7 +691,6 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
|||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
|
@ -719,8 +699,8 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
|||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs=
|
||||
github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
|
@ -735,13 +715,9 @@ github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea/go.mod h1:WPnis/6
|
|||
github.com/tonistiigi/vt100 v0.0.0-20210615222946-8066bb97264f h1:DLpt6B5oaaS8jyXHa9VA4rrZloBVPVXeCtrOsrFauxc=
|
||||
github.com/tonistiigi/vt100 v0.0.0-20210615222946-8066bb97264f/go.mod h1:ulncasL3N9uLrVann0m+CDlJKWsIAP34MPcOJF6VRvc=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||
github.com/vbatts/tar-split v0.11.2 h1:Via6XqJr0hceW4wff3QRzD5gAk/tatMw/4ZA7cTlIME=
|
||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
|
||||
github.com/weppos/publicsuffix-go v0.4.0/go.mod h1:z3LCPQ38eedDQSwmsSRW4Y7t2L8Ln16JPQ02lHAdn5k=
|
||||
github.com/weppos/publicsuffix-go v0.5.0/go.mod h1:z3LCPQ38eedDQSwmsSRW4Y7t2L8Ln16JPQ02lHAdn5k=
|
||||
github.com/weppos/publicsuffix-go v0.15.1-0.20220329081811-9a40b608a236 h1:vMJBP3PQViZsF6cOINtvyMC8ptpLsyJ4EwyFnzuWNxc=
|
||||
github.com/weppos/publicsuffix-go v0.15.1-0.20220329081811-9a40b608a236/go.mod h1:HYux0V0Zi04bHNwOHy4cXJVz/TQjYonnF6aoYhj+3QE=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
|
@ -757,16 +733,11 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
|||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
|
||||
github.com/zmap/rc2 v0.0.0-20131011165748-24b9757f5521/go.mod h1:3YZ9o3WnatTIZhuOtot4IcUfzoKVjUHqu6WALIyI0nE=
|
||||
github.com/zmap/zcertificate v0.0.0-20180516150559-0e3d58b1bac4/go.mod h1:5iU54tB79AMBcySS0R2XIyZBAVmeHranShAFELYx7is=
|
||||
github.com/zmap/zcrypto v0.0.0-20190729165852-9051775e6a2e/go.mod h1:w7kd3qXHh8FNaczNjslXqvFQiv5mMWRXlL9klTUAHc8=
|
||||
github.com/zmap/zcrypto v0.0.0-20191112190257-7f2fe6faf8cf/go.mod h1:w7kd3qXHh8FNaczNjslXqvFQiv5mMWRXlL9klTUAHc8=
|
||||
github.com/zmap/zcrypto v0.0.0-20220605182715-4dfcec6e9a8c h1:ufDm/IlBYZYLuiqvQuhpTKwrcAS2OlXEzWbDvTVGbSQ=
|
||||
github.com/zmap/zcrypto v0.0.0-20220605182715-4dfcec6e9a8c/go.mod h1:egdRkzUylATvPkWMpebZbXhv0FMEMJGX/ur0D3Csk2s=
|
||||
github.com/zmap/zlint v0.0.0-20190806154020-fd021b4cfbeb/go.mod h1:29UiAJNsiVdvTBFCJW8e3q6dcDbOoPkhMgttOSCIMMY=
|
||||
github.com/zmap/zlint v1.1.0 h1:Vyh2GmprXw5TLmKmkTa2BgFvvYAFBValBFesqkKsszM=
|
||||
github.com/zmap/zlint v1.1.0/go.mod h1:3MvSF/QhEftzpxKhh3jkBIOvugsSDYMCofl+UaIv0ww=
|
||||
github.com/zmap/zlint/v3 v3.1.0 h1:WjVytZo79m/L1+/Mlphl09WBob6YTGljN5IGWZFpAv0=
|
||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
|
@ -818,7 +789,6 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
|||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
|
@ -829,8 +799,8 @@ golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWP
|
|||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.2.0 h1:BRXPfhNivWL5Yq0BGQ39a2sW6t44aODpfxkWjYdzewE=
|
||||
golang.org/x/crypto v0.2.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A=
|
||||
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
|
@ -1358,8 +1328,8 @@ k8s.io/client-go v0.22.4/go.mod h1:Yzw4e5e7h1LNHA4uqnMVrpEpUs1hJOiuBsJKIlRCHDA=
|
|||
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||
k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
|
||||
k8s.io/klog/v2 v2.60.1 h1:VW25q3bZx9uE3vvdL6M8ezOX79vA2Aq1nEWLqNQclHc=
|
||||
k8s.io/klog/v2 v2.60.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||
k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4=
|
||||
k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||
k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
|
||||
k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 h1:HNSDgDCrr/6Ly3WEGKZftiE7IY19Vz2GdbOCyI4qqhc=
|
||||
|
|
|
@ -232,6 +232,8 @@ type DownOptions struct {
|
|||
Images string
|
||||
// Volumes remove volumes, both declared in the `volumes` section and anonymous ones
|
||||
Volumes bool
|
||||
// Services passed in the command line to be stopped
|
||||
Services []string
|
||||
}
|
||||
|
||||
// ConfigOptions group options of the Config API
|
||||
|
|
|
@ -19,6 +19,7 @@ package compose
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
@ -172,6 +173,9 @@ func (c *convergence) ensureService(ctx context.Context, project *types.Project,
|
|||
|
||||
eg, _ := errgroup.WithContext(ctx)
|
||||
|
||||
sort.Slice(containers, func(i, j int) bool {
|
||||
return containers[i].Created < containers[j].Created
|
||||
})
|
||||
for i, container := range containers {
|
||||
if i >= expected {
|
||||
// Scale Down
|
||||
|
|
|
@ -106,11 +106,6 @@ func (s *composeService) create(ctx context.Context, project *types.Project, opt
|
|||
}
|
||||
}
|
||||
|
||||
err = prepareServicesDependsOn(project)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return newConvergence(options.Services, observedState, s).apply(ctx, project, options)
|
||||
}
|
||||
|
||||
|
@ -147,72 +142,6 @@ func prepareNetworks(project *types.Project) {
|
|||
}
|
||||
}
|
||||
|
||||
func prepareServicesDependsOn(p *types.Project) error {
|
||||
allServices := types.Project{}
|
||||
allServices.Services = p.AllServices()
|
||||
|
||||
for i, service := range p.Services {
|
||||
var dependencies []string
|
||||
networkDependency := getDependentServiceFromMode(service.NetworkMode)
|
||||
if networkDependency != "" {
|
||||
dependencies = append(dependencies, networkDependency)
|
||||
}
|
||||
|
||||
ipcDependency := getDependentServiceFromMode(service.Ipc)
|
||||
if ipcDependency != "" {
|
||||
dependencies = append(dependencies, ipcDependency)
|
||||
}
|
||||
|
||||
pidDependency := getDependentServiceFromMode(service.Pid)
|
||||
if pidDependency != "" {
|
||||
dependencies = append(dependencies, pidDependency)
|
||||
}
|
||||
|
||||
for _, vol := range service.VolumesFrom {
|
||||
spec := strings.Split(vol, ":")
|
||||
if len(spec) == 0 {
|
||||
continue
|
||||
}
|
||||
if spec[0] == "container" {
|
||||
continue
|
||||
}
|
||||
dependencies = append(dependencies, spec[0])
|
||||
}
|
||||
|
||||
for _, link := range service.Links {
|
||||
dependencies = append(dependencies, strings.Split(link, ":")[0])
|
||||
}
|
||||
|
||||
for d := range service.DependsOn {
|
||||
dependencies = append(dependencies, d)
|
||||
}
|
||||
|
||||
if len(dependencies) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// Verify dependencies exist in the project, whether disabled or not
|
||||
deps, err := allServices.GetServices(dependencies...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if service.DependsOn == nil {
|
||||
service.DependsOn = make(types.DependsOnConfig)
|
||||
}
|
||||
|
||||
for _, d := range deps {
|
||||
if _, ok := service.DependsOn[d.Name]; !ok {
|
||||
service.DependsOn[d.Name] = types.ServiceDependency{
|
||||
Condition: types.ServiceConditionStarted,
|
||||
}
|
||||
}
|
||||
}
|
||||
p.Services[i] = service
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *composeService) ensureNetworks(ctx context.Context, networks types.Networks) error {
|
||||
for _, network := range networks {
|
||||
err := s.ensureNetwork(ctx, network)
|
||||
|
@ -640,8 +569,8 @@ func setLimits(limits *types.Resource, resources *container.Resources) {
|
|||
resources.NanoCPUs = int64(f * 1e9)
|
||||
}
|
||||
}
|
||||
if limits.PIds > 0 {
|
||||
resources.PidsLimit = &limits.PIds
|
||||
if limits.Pids > 0 {
|
||||
resources.PidsLimit = &limits.Pids
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -743,7 +672,10 @@ func getVolumesFrom(project *types.Project, volumesFrom []string) ([]string, []s
|
|||
}
|
||||
|
||||
func getDependentServiceFromMode(mode string) string {
|
||||
if strings.HasPrefix(mode, types.NetworkModeServicePrefix) {
|
||||
if strings.HasPrefix(
|
||||
mode,
|
||||
types.NetworkModeServicePrefix,
|
||||
) {
|
||||
return mode[len(types.NetworkModeServicePrefix):]
|
||||
}
|
||||
return ""
|
||||
|
|
|
@ -23,6 +23,8 @@ import (
|
|||
"sync"
|
||||
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
"github.com/docker/compose/v2/pkg/api"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"github.com/docker/compose/v2/pkg/utils"
|
||||
|
@ -38,8 +40,9 @@ const (
|
|||
)
|
||||
|
||||
type graphTraversal struct {
|
||||
mu sync.Mutex
|
||||
seen map[string]struct{}
|
||||
mu sync.Mutex
|
||||
seen map[string]struct{}
|
||||
ignored map[string]struct{}
|
||||
|
||||
extremityNodesFn func(*Graph) []*Vertex // leaves or roots
|
||||
adjacentNodesFn func(*Vertex) []*Vertex // getParents or getChildren
|
||||
|
@ -75,7 +78,7 @@ func downDirectionTraversal(visitorFn func(context.Context, string) error) *grap
|
|||
|
||||
// InDependencyOrder applies the function to the services of the project taking in account the dependency order
|
||||
func InDependencyOrder(ctx context.Context, project *types.Project, fn func(context.Context, string) error, options ...func(*graphTraversal)) error {
|
||||
graph, err := NewGraph(project.Services, ServiceStopped)
|
||||
graph, err := NewGraph(project, ServiceStopped)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -87,15 +90,46 @@ func InDependencyOrder(ctx context.Context, project *types.Project, fn func(cont
|
|||
}
|
||||
|
||||
// InReverseDependencyOrder applies the function to the services of the project in reverse order of dependencies
|
||||
func InReverseDependencyOrder(ctx context.Context, project *types.Project, fn func(context.Context, string) error) error {
|
||||
graph, err := NewGraph(project.Services, ServiceStarted)
|
||||
func InReverseDependencyOrder(ctx context.Context, project *types.Project, fn func(context.Context, string) error, options ...func(*graphTraversal)) error {
|
||||
graph, err := NewGraph(project, ServiceStarted)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t := downDirectionTraversal(fn)
|
||||
for _, option := range options {
|
||||
option(t)
|
||||
}
|
||||
return t.visit(ctx, graph)
|
||||
}
|
||||
|
||||
func WithRootNodesAndDown(nodes []string) func(*graphTraversal) {
|
||||
return func(t *graphTraversal) {
|
||||
if len(nodes) == 0 {
|
||||
return
|
||||
}
|
||||
originalFn := t.extremityNodesFn
|
||||
t.extremityNodesFn = func(graph *Graph) []*Vertex {
|
||||
var want []string
|
||||
for _, node := range nodes {
|
||||
vertex := graph.Vertices[node]
|
||||
want = append(want, vertex.Service)
|
||||
for _, v := range getAncestors(vertex) {
|
||||
want = append(want, v.Service)
|
||||
}
|
||||
}
|
||||
|
||||
t.ignored = map[string]struct{}{}
|
||||
for k := range graph.Vertices {
|
||||
if !utils.Contains(want, k) {
|
||||
t.ignored[k] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
return originalFn(graph)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (t *graphTraversal) visit(ctx context.Context, g *Graph) error {
|
||||
expect := len(g.Vertices)
|
||||
if expect == 0 {
|
||||
|
@ -142,7 +176,10 @@ func (t *graphTraversal) run(ctx context.Context, graph *Graph, eg *errgroup.Gro
|
|||
}
|
||||
|
||||
eg.Go(func() error {
|
||||
err := t.visitorFn(ctx, node.Service)
|
||||
var err error
|
||||
if _, ignore := t.ignored[node.Service]; !ignore {
|
||||
err = t.visitorFn(ctx, node.Service)
|
||||
}
|
||||
if err == nil {
|
||||
graph.UpdateStatus(node.Key, t.targetServiceStatus)
|
||||
}
|
||||
|
@ -197,6 +234,16 @@ func getChildren(v *Vertex) []*Vertex {
|
|||
return v.GetChildren()
|
||||
}
|
||||
|
||||
// getAncestors return all descendents for a vertex, might contain duplicates
|
||||
func getAncestors(v *Vertex) []*Vertex {
|
||||
var descendents []*Vertex
|
||||
for _, parent := range v.GetParents() {
|
||||
descendents = append(descendents, parent)
|
||||
descendents = append(descendents, getAncestors(parent)...)
|
||||
}
|
||||
return descendents
|
||||
}
|
||||
|
||||
// GetChildren returns a slice with the child vertices of the a Vertex
|
||||
func (v *Vertex) GetChildren() []*Vertex {
|
||||
var res []*Vertex
|
||||
|
@ -207,19 +254,28 @@ func (v *Vertex) GetChildren() []*Vertex {
|
|||
}
|
||||
|
||||
// NewGraph returns the dependency graph of the services
|
||||
func NewGraph(services types.Services, initialStatus ServiceStatus) (*Graph, error) {
|
||||
func NewGraph(project *types.Project, initialStatus ServiceStatus) (*Graph, error) {
|
||||
graph := &Graph{
|
||||
lock: sync.RWMutex{},
|
||||
Vertices: map[string]*Vertex{},
|
||||
}
|
||||
|
||||
for _, s := range services {
|
||||
for _, s := range project.Services {
|
||||
graph.AddVertex(s.Name, s.Name, initialStatus)
|
||||
}
|
||||
|
||||
for _, s := range services {
|
||||
for _, s := range project.Services {
|
||||
for _, name := range s.GetDependencies() {
|
||||
_ = graph.AddEdge(s.Name, name)
|
||||
err := graph.AddEdge(s.Name, name)
|
||||
if err != nil {
|
||||
if api.IsNotFoundError(err) {
|
||||
ds, err := project.GetDisabledService(name)
|
||||
if err == nil {
|
||||
return nil, fmt.Errorf("service %s is required by %s but is disabled. Can be enabled by profiles %s", name, s.Name, ds.Profiles)
|
||||
}
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -259,10 +315,10 @@ func (g *Graph) AddEdge(source string, destination string) error {
|
|||
destinationVertex := g.Vertices[destination]
|
||||
|
||||
if sourceVertex == nil {
|
||||
return fmt.Errorf("could not find %s", source)
|
||||
return errors.Wrapf(api.ErrNotFound, "could not find %s", source)
|
||||
}
|
||||
if destinationVertex == nil {
|
||||
return fmt.Errorf("could not find %s", destination)
|
||||
return errors.Wrapf(api.ErrNotFound, "could not find %s", destination)
|
||||
}
|
||||
|
||||
// If they are already connected
|
||||
|
|
|
@ -19,9 +19,12 @@ package compose
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
"github.com/docker/compose/v2/pkg/utils"
|
||||
testify "github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gotest.tools/v3/assert"
|
||||
|
@ -267,7 +270,7 @@ func TestBuildGraph(t *testing.T) {
|
|||
Services: tC.services,
|
||||
}
|
||||
|
||||
graph, err := NewGraph(project.Services, ServiceStopped)
|
||||
graph, err := NewGraph(&project, ServiceStopped)
|
||||
assert.NilError(t, err, fmt.Sprintf("failed to build graph for: %s", tC.desc))
|
||||
|
||||
for k, vertex := range graph.Vertices {
|
||||
|
@ -297,3 +300,88 @@ func isVertexEqual(a, b Vertex) bool {
|
|||
childrenEquality &&
|
||||
parentEquality
|
||||
}
|
||||
|
||||
func TestWith_RootNodesAndUp(t *testing.T) {
|
||||
graph := &Graph{
|
||||
lock: sync.RWMutex{},
|
||||
Vertices: map[string]*Vertex{},
|
||||
}
|
||||
|
||||
/** graph topology:
|
||||
A B
|
||||
/ \ / \
|
||||
G C E
|
||||
\ /
|
||||
D
|
||||
|
|
||||
F
|
||||
*/
|
||||
|
||||
graph.AddVertex("A", "A", 0)
|
||||
graph.AddVertex("B", "B", 0)
|
||||
graph.AddVertex("C", "C", 0)
|
||||
graph.AddVertex("D", "D", 0)
|
||||
graph.AddVertex("E", "E", 0)
|
||||
graph.AddVertex("F", "F", 0)
|
||||
graph.AddVertex("G", "G", 0)
|
||||
|
||||
_ = graph.AddEdge("C", "A")
|
||||
_ = graph.AddEdge("C", "B")
|
||||
_ = graph.AddEdge("E", "B")
|
||||
_ = graph.AddEdge("D", "C")
|
||||
_ = graph.AddEdge("D", "E")
|
||||
_ = graph.AddEdge("F", "D")
|
||||
_ = graph.AddEdge("G", "A")
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
nodes []string
|
||||
want []string
|
||||
}{
|
||||
{
|
||||
name: "whole graph",
|
||||
nodes: []string{"A", "B"},
|
||||
want: []string{"A", "B", "C", "D", "E", "F", "G"},
|
||||
},
|
||||
{
|
||||
name: "only leaves",
|
||||
nodes: []string{"F", "G"},
|
||||
want: []string{"F", "G"},
|
||||
},
|
||||
{
|
||||
name: "simple dependent",
|
||||
nodes: []string{"D"},
|
||||
want: []string{"D", "F"},
|
||||
},
|
||||
{
|
||||
name: "diamond dependents",
|
||||
nodes: []string{"B"},
|
||||
want: []string{"B", "C", "D", "E", "F"},
|
||||
},
|
||||
{
|
||||
name: "partial graph",
|
||||
nodes: []string{"A"},
|
||||
want: []string{"A", "C", "D", "F", "G"},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
mx := sync.Mutex{}
|
||||
expected := utils.Set[string]{}
|
||||
expected.AddAll("C", "G", "D", "F")
|
||||
var visited []string
|
||||
|
||||
gt := downDirectionTraversal(func(ctx context.Context, s string) error {
|
||||
mx.Lock()
|
||||
defer mx.Unlock()
|
||||
visited = append(visited, s)
|
||||
return nil
|
||||
})
|
||||
WithRootNodesAndDown(tt.nodes)(gt)
|
||||
err := gt.visit(context.TODO(), graph)
|
||||
assert.NilError(t, err)
|
||||
sort.Strings(visited)
|
||||
assert.DeepEqual(t, tt.want, visited)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ func (s *composeService) Down(ctx context.Context, projectName string, options a
|
|||
}, s.stdinfo())
|
||||
}
|
||||
|
||||
func (s *composeService) down(ctx context.Context, projectName string, options api.DownOptions) error {
|
||||
func (s *composeService) down(ctx context.Context, projectName string, options api.DownOptions) error { //nolint:gocyclo
|
||||
w := progress.ContextWriter(ctx)
|
||||
resourceToRemove := false
|
||||
|
||||
|
@ -65,6 +65,12 @@ func (s *composeService) down(ctx context.Context, projectName string, options a
|
|||
}
|
||||
}
|
||||
|
||||
// Check requested services exists in model
|
||||
options.Services, err = checkSelectedServices(options, project)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(containers) > 0 {
|
||||
resourceToRemove = true
|
||||
}
|
||||
|
@ -73,7 +79,7 @@ func (s *composeService) down(ctx context.Context, projectName string, options a
|
|||
serviceContainers := containers.filter(isService(service))
|
||||
err := s.removeContainers(ctx, w, serviceContainers, options.Timeout, options.Volumes)
|
||||
return err
|
||||
})
|
||||
}, WithRootNodesAndDown(options.Services))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -111,6 +117,23 @@ func (s *composeService) down(ctx context.Context, projectName string, options a
|
|||
return eg.Wait()
|
||||
}
|
||||
|
||||
func checkSelectedServices(options api.DownOptions, project *types.Project) ([]string, error) {
|
||||
var services []string
|
||||
for _, service := range options.Services {
|
||||
_, err := project.GetService(service)
|
||||
if err != nil {
|
||||
if options.Project != nil {
|
||||
// ran with an explicit compose.yaml file, so we should not ignore
|
||||
return nil, err
|
||||
}
|
||||
// ran without an explicit compose.yaml file, so can't distinguish typo vs container already removed
|
||||
} else {
|
||||
services = append(services, service)
|
||||
}
|
||||
}
|
||||
return services, nil
|
||||
}
|
||||
|
||||
func (s *composeService) ensureVolumesDown(ctx context.Context, project *types.Project, w progress.Writer) []downOp {
|
||||
var ops []downOp
|
||||
for _, vol := range project.Volumes {
|
||||
|
@ -229,6 +252,10 @@ func (s *composeService) removeImage(ctx context.Context, image string, w progre
|
|||
w.Event(progress.NewEvent(id, progress.Done, "Removed"))
|
||||
return nil
|
||||
}
|
||||
if errdefs.IsConflict(err) {
|
||||
w.Event(progress.NewEvent(id, progress.Warning, "Resource is still in use"))
|
||||
return nil
|
||||
}
|
||||
if errdefs.IsNotFound(err) {
|
||||
w.Event(progress.NewEvent(id, progress.Done, "Warning: No resource found to remove"))
|
||||
return nil
|
||||
|
@ -244,6 +271,10 @@ func (s *composeService) removeVolume(ctx context.Context, id string, w progress
|
|||
w.Event(progress.NewEvent(resource, progress.Done, "Removed"))
|
||||
return nil
|
||||
}
|
||||
if errdefs.IsConflict(err) {
|
||||
w.Event(progress.NewEvent(resource, progress.Warning, "Resource is still in use"))
|
||||
return nil
|
||||
}
|
||||
if errdefs.IsNotFound(err) {
|
||||
w.Event(progress.NewEvent(resource, progress.Done, "Warning: No resource found to remove"))
|
||||
return nil
|
||||
|
|
|
@ -28,11 +28,12 @@ func ServiceHash(o types.ServiceConfig) (string, error) {
|
|||
// remove the Build config when generating the service hash
|
||||
o.Build = nil
|
||||
o.PullPolicy = ""
|
||||
o.Scale = 1
|
||||
if o.Deploy != nil {
|
||||
var one uint64 = 1
|
||||
o.Deploy.Replicas = &one
|
||||
if o.Deploy == nil {
|
||||
o.Deploy = &types.DeployConfig{}
|
||||
}
|
||||
o.Scale = 1
|
||||
var one uint64 = 1
|
||||
o.Deploy.Replicas = &one
|
||||
bytes, err := json.Marshal(o)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
@ -45,7 +45,7 @@ func (s *composeService) injectSecrets(ctx context.Context, project *types.Proje
|
|||
}
|
||||
|
||||
err = s.apiClient().CopyToContainer(ctx, id, "/", &b, moby.CopyToContainerOptions{
|
||||
CopyUIDGID: true,
|
||||
CopyUIDGID: config.UID != "" || config.GID != "",
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -130,9 +130,7 @@ func (s *composeService) Watch(ctx context.Context, project *types.Project, serv
|
|||
}
|
||||
|
||||
name := service.Name
|
||||
bc := service.Build.Context
|
||||
|
||||
dockerIgnores, err := watch.LoadDockerIgnore(bc)
|
||||
dockerIgnores, err := watch.LoadDockerIgnore(service.Build.Context)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -150,12 +148,17 @@ func (s *composeService) Watch(ctx context.Context, project *types.Project, serv
|
|||
dotGitIgnore,
|
||||
)
|
||||
|
||||
watcher, err := watch.NewWatcher([]string{bc}, ignore)
|
||||
var paths []string
|
||||
for _, trigger := range config.Watch {
|
||||
paths = append(paths, trigger.Path)
|
||||
}
|
||||
|
||||
watcher, err := watch.NewWatcher(paths, ignore)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Fprintf(s.stdinfo(), "watching %s\n", bc)
|
||||
fmt.Fprintf(s.stdinfo(), "watching %s\n", paths)
|
||||
err = watcher.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -102,6 +102,14 @@ func TestLocalComposeUp(t *testing.T) {
|
|||
res.Assert(t, icmd.Expected{Out: `compose-e2e-demo-words-1 gtardif/sentences-api latest`})
|
||||
})
|
||||
|
||||
t.Run("down SERVICE", func(t *testing.T) {
|
||||
_ = c.RunDockerComposeCmd(t, "--project-name", projectName, "down", "web")
|
||||
|
||||
res := c.RunDockerComposeCmd(t, "--project-name", projectName, "ps")
|
||||
assert.Assert(t, !strings.Contains(res.Combined(), "compose-e2e-demo-web-1"), res.Combined())
|
||||
assert.Assert(t, strings.Contains(res.Combined(), "compose-e2e-demo-db-1"), res.Combined())
|
||||
})
|
||||
|
||||
t.Run("down", func(t *testing.T) {
|
||||
_ = c.RunDockerComposeCmd(t, "--project-name", projectName, "down")
|
||||
})
|
||||
|
|
|
@ -23,13 +23,14 @@ import (
|
|||
"context"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"syscall"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/compose/v2/pkg/utils"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gotest.tools/v3/assert"
|
||||
"gotest.tools/v3/icmd"
|
||||
)
|
||||
|
||||
|
@ -79,7 +80,7 @@ func TestUpDependenciesNotStopped(t *testing.T) {
|
|||
defer cancel()
|
||||
|
||||
cmd, err := StartWithNewGroupID(ctx, testCmd, upOut, nil)
|
||||
assert.NoError(t, err, "Failed to run compose up")
|
||||
assert.NilError(t, err, "Failed to run compose up")
|
||||
|
||||
t.Log("Waiting for containers to be in running state")
|
||||
upOut.RequireEventuallyContains(t, "hello app")
|
||||
|
@ -138,3 +139,17 @@ func TestUpWithDependencyExit(t *testing.T) {
|
|||
res.Assert(t, icmd.Expected{ExitCode: 1, Err: "dependency failed to start: container dependencies-db-1 exited (1)"})
|
||||
})
|
||||
}
|
||||
|
||||
func TestScaleDoesntRecreate(t *testing.T) {
|
||||
c := NewCLI(t)
|
||||
const projectName = "compose-e2e-scale"
|
||||
t.Cleanup(func() {
|
||||
c.RunDockerComposeCmd(t, "--project-name", projectName, "down")
|
||||
})
|
||||
|
||||
c.RunDockerComposeCmd(t, "-f", "fixtures/simple-composefile/compose.yaml", "--project-name", projectName, "up", "-d")
|
||||
|
||||
res := c.RunDockerComposeCmd(t, "-f", "fixtures/simple-composefile/compose.yaml", "--project-name", projectName, "up", "--scale", "simple=2", "-d")
|
||||
assert.Check(t, !strings.Contains(res.Combined(), "Recreated"))
|
||||
|
||||
}
|
||||
|
|
|
@ -153,6 +153,15 @@ func RemovedEvent(id string) Event {
|
|||
return NewEvent(id, Done, "Removed")
|
||||
}
|
||||
|
||||
// SkippedEvent creates a new Skipped Event
|
||||
func SkippedEvent(id string, reason string) Event {
|
||||
return Event{
|
||||
ID: id,
|
||||
Status: Warning,
|
||||
StatusText: "Skipped: " + reason,
|
||||
}
|
||||
}
|
||||
|
||||
// NewEvent new event
|
||||
func NewEvent(id string, status EventStatus, statusText string) Event {
|
||||
return Event{
|
||||
|
|
|
@ -21,12 +21,12 @@ import (
|
|||
"io"
|
||||
"sync"
|
||||
|
||||
"github.com/cloudflare/cfssl/log"
|
||||
"github.com/docker/compose/v2/pkg/api"
|
||||
|
||||
"github.com/containerd/console"
|
||||
"github.com/moby/term"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"github.com/docker/compose/v2/pkg/api"
|
||||
)
|
||||
|
||||
// Writer can write multiple progress events
|
||||
|
@ -125,7 +125,7 @@ func NewWriter(ctx context.Context, out io.Writer, progressTitle string) (Writer
|
|||
}
|
||||
if Mode == ModeTTY {
|
||||
if !isConsole {
|
||||
log.Warning("Terminal is not a POSIX console")
|
||||
logrus.Warn("Terminal is not a POSIX console")
|
||||
} else {
|
||||
return newTTYWriter(f, dryRun, progressTitle)
|
||||
}
|
||||
|
|
|
@ -20,8 +20,18 @@ func (s Set[T]) Add(v T) {
|
|||
s[v] = struct{}{}
|
||||
}
|
||||
|
||||
func (s Set[T]) Remove(v T) {
|
||||
delete(s, v)
|
||||
func (s Set[T]) AddAll(v ...T) {
|
||||
for _, e := range v {
|
||||
s[e] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
func (s Set[T]) Remove(v T) bool {
|
||||
_, ok := s[v]
|
||||
if ok {
|
||||
delete(s, v)
|
||||
}
|
||||
return ok
|
||||
}
|
||||
|
||||
func (s Set[T]) Clear() {
|
||||
|
|
Loading…
Reference in New Issue