mirror of
https://github.com/docker/compose.git
synced 2026-02-14 12:39:23 +08:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d474515d45 | ||
|
|
2b21c5df93 | ||
|
|
1f3c10eb4b | ||
|
|
68ad165a59 | ||
|
|
3060ed2795 | ||
|
|
be09b2e8ce | ||
|
|
571a1af013 | ||
|
|
8f644eea73 | ||
|
|
56e92e34b6 | ||
|
|
a42a04dfe8 | ||
|
|
34bcd03a76 | ||
|
|
ed61e42f93 | ||
|
|
65696bb1cb | ||
|
|
446e00520c | ||
|
|
c01c9c29f4 | ||
|
|
038c81f34e |
22
.github/workflows/ci.yml
vendored
22
.github/workflows/ci.yml
vendored
@@ -56,7 +56,7 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
uses: docker/setup-buildx-action@v3
|
||||
-
|
||||
name: Run
|
||||
run: |
|
||||
@@ -81,13 +81,13 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
uses: docker/setup-qemu-action@v3
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
uses: docker/setup-buildx-action@v3
|
||||
-
|
||||
name: Build
|
||||
uses: docker/bake-action@v2
|
||||
uses: docker/bake-action@v5
|
||||
with:
|
||||
targets: release
|
||||
set: |
|
||||
@@ -110,10 +110,10 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
uses: docker/setup-buildx-action@v3
|
||||
-
|
||||
name: Test
|
||||
uses: docker/bake-action@v2
|
||||
uses: docker/bake-action@v5
|
||||
with:
|
||||
targets: test
|
||||
set: |
|
||||
@@ -141,10 +141,8 @@ jobs:
|
||||
- plugin
|
||||
- standalone
|
||||
engine:
|
||||
- 24.0.9
|
||||
- 25.0.5
|
||||
- 26.1.4
|
||||
- 27.4.0-rc.4
|
||||
- 26
|
||||
- 27
|
||||
steps:
|
||||
- name: Prepare
|
||||
run: |
|
||||
@@ -165,7 +163,7 @@ jobs:
|
||||
run: docker --version
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
uses: docker/setup-buildx-action@v3
|
||||
-
|
||||
name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
@@ -175,7 +173,7 @@ jobs:
|
||||
cache: true
|
||||
-
|
||||
name: Build
|
||||
uses: docker/bake-action@v2
|
||||
uses: docker/bake-action@v5
|
||||
with:
|
||||
targets: binary-with-coverage
|
||||
set: |
|
||||
|
||||
22
.github/workflows/merge.yml
vendored
22
.github/workflows/merge.yml
vendored
@@ -84,14 +84,14 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
uses: docker/setup-qemu-action@v3
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
uses: docker/setup-buildx-action@v3
|
||||
-
|
||||
name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: |
|
||||
${{ env.REPO_SLUG }}
|
||||
@@ -102,13 +102,13 @@ jobs:
|
||||
-
|
||||
name: Login to DockerHub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v2
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERPUBLICBOT_USERNAME }}
|
||||
password: ${{ secrets.DOCKERPUBLICBOT_WRITE_PAT }}
|
||||
-
|
||||
name: Build and push image
|
||||
uses: docker/bake-action@v2
|
||||
uses: docker/bake-action@v5
|
||||
id: bake
|
||||
with:
|
||||
files: |
|
||||
@@ -129,14 +129,16 @@ jobs:
|
||||
-
|
||||
name: Generate Token
|
||||
id: generate_token
|
||||
uses: tibdex/github-app-token@v1
|
||||
uses: actions/create-github-app-token@v1
|
||||
with:
|
||||
app_id: ${{ vars.DOCKERDESKTOP_APP_ID }}
|
||||
private_key: ${{ secrets.DOCKERDESKTOP_APP_PRIVATEKEY }}
|
||||
repository: docker/${{ secrets.DOCKERDESKTOP_REPO }}
|
||||
app-id: ${{ vars.DOCKERDESKTOP_APP_ID }}
|
||||
private-key: ${{ secrets.DOCKERDESKTOP_APP_PRIVATEKEY }}
|
||||
owner: docker
|
||||
repositories: |
|
||||
${{ secrets.DOCKERDESKTOP_REPO }}
|
||||
-
|
||||
name: Trigger Docker Desktop e2e with edge version
|
||||
uses: actions/github-script@v6
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
github-token: ${{ steps.generate_token.outputs.token }}
|
||||
script: |
|
||||
|
||||
8
.github/workflows/scorecards.yml
vendored
8
.github/workflows/scorecards.yml
vendored
@@ -22,12 +22,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: "Checkout code"
|
||||
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846 # tag=v3.0.0
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.4.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: "Run analysis"
|
||||
uses: ossf/scorecard-action@99c53751e09b9529366343771cc321ec74e9bd3d # tag=v2.0.6
|
||||
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # tag=v2.4.0
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
@@ -41,7 +41,7 @@ jobs:
|
||||
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
||||
# format to the repository Actions tab.
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 # tag=v3.0.0
|
||||
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # tag=v4.5.0
|
||||
with:
|
||||
name: SARIF file
|
||||
path: results.sarif
|
||||
@@ -49,6 +49,6 @@ jobs:
|
||||
|
||||
# Upload the results to GitHub's code scanning dashboard.
|
||||
- name: "Upload to code-scanning"
|
||||
uses: github/codeql-action/upload-sarif@5f532563584d71fdef14ee64d17bafb34f751ce5 # tag=v1.0.26
|
||||
uses: github/codeql-action/upload-sarif@3096afedf9873361b2b2f65e1445b13272c83eb8 # tag=v2.20.00
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
||||
@@ -10,7 +10,7 @@ linters:
|
||||
- errorlint
|
||||
- gocritic
|
||||
- gocyclo
|
||||
- gofmt
|
||||
- gofumpt
|
||||
- goimports
|
||||
- gomodguard
|
||||
- revive
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
ARG GO_VERSION=1.22.8
|
||||
ARG GO_VERSION=1.22.10
|
||||
ARG XX_VERSION=1.6.1
|
||||
ARG GOLANGCI_LINT_VERSION=v1.60.2
|
||||
ARG ADDLICENSE_VERSION=v1.0.0
|
||||
|
||||
5
Makefile
5
Makefile
@@ -116,6 +116,11 @@ cache-clear: ## Clear the builder cache
|
||||
lint: ## run linter(s)
|
||||
$(BUILDX_CMD) bake lint
|
||||
|
||||
.PHONY: fmt
|
||||
fmt:
|
||||
gofumpt --version >/dev/null 2>&1 || go install mvdan.cc/gofumpt@latest
|
||||
gofumpt -w .
|
||||
|
||||
.PHONY: docs
|
||||
docs: ## generate documentation
|
||||
$(eval $@_TMP_OUT := $(shell mktemp -d -t compose-output.XXXXXXXXXX))
|
||||
|
||||
@@ -60,5 +60,4 @@ func TestGetFlags(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -348,7 +348,6 @@ func runHash(ctx context.Context, dockerCli command.Cli, opts configOptions) err
|
||||
}
|
||||
|
||||
hash, err := compose.ServiceHash(s)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -198,7 +198,9 @@ func applyScaleOpts(project *types.Project, opts []string) error {
|
||||
}
|
||||
|
||||
func (opts createOptions) isPullPolicyValid() bool {
|
||||
pullPolicies := []string{types.PullPolicyAlways, types.PullPolicyNever, types.PullPolicyBuild,
|
||||
types.PullPolicyMissing, types.PullPolicyIfNotPresent}
|
||||
pullPolicies := []string{
|
||||
types.PullPolicyAlways, types.PullPolicyNever, types.PullPolicyBuild,
|
||||
types.PullPolicyMissing, types.PullPolicyIfNotPresent,
|
||||
}
|
||||
return slices.Contains(pullPolicies, opts.Pull)
|
||||
}
|
||||
|
||||
@@ -154,6 +154,7 @@ func runCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *
|
||||
options.noTty = !options.tty
|
||||
}
|
||||
}
|
||||
createOpts.pullChanged = cmd.Flags().Changed("pull")
|
||||
return nil
|
||||
}),
|
||||
RunE: Adapt(func(ctx context.Context, args []string) error {
|
||||
@@ -188,6 +189,7 @@ func runCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *
|
||||
flags.StringArrayVarP(&options.publish, "publish", "p", []string{}, "Publish a container's port(s) to the host")
|
||||
flags.BoolVar(&options.useAliases, "use-aliases", false, "Use the service's network useAliases in the network(s) the container connects to")
|
||||
flags.BoolVarP(&options.servicePorts, "service-ports", "P", false, "Run command with all service's ports enabled and mapped to the host")
|
||||
flags.StringVar(&createOpts.Pull, "pull", "policy", `Pull image before running ("always"|"missing"|"never")`)
|
||||
flags.BoolVar(&options.quietPull, "quiet-pull", false, "Pull without printing progress information")
|
||||
flags.BoolVar(&createOpts.Build, "build", false, "Build image before starting container")
|
||||
flags.BoolVar(&options.removeOrphans, "remove-orphans", false, "Remove containers for services not defined in the Compose file")
|
||||
|
||||
@@ -92,7 +92,6 @@ func parseServicesReplicasArgs(args []string) (map[string]int, error) {
|
||||
return nil, fmt.Errorf("invalid scale specifier: %s", arg)
|
||||
}
|
||||
intValue, err := strconv.Atoi(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid scale specifier: can't parse replica value as int: %v", arg)
|
||||
}
|
||||
|
||||
@@ -47,5 +47,4 @@ func TestApplyScaleOpt(t *testing.T) {
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, *bar.Scale, 3)
|
||||
assert.Equal(t, *bar.Deploy.Replicas, 3)
|
||||
|
||||
}
|
||||
|
||||
@@ -27,42 +27,49 @@ var disableAnsi bool
|
||||
func ansi(code string) string {
|
||||
return fmt.Sprintf("\033%s", code)
|
||||
}
|
||||
|
||||
func SaveCursor() {
|
||||
if disableAnsi {
|
||||
return
|
||||
}
|
||||
fmt.Print(ansi("7"))
|
||||
}
|
||||
|
||||
func RestoreCursor() {
|
||||
if disableAnsi {
|
||||
return
|
||||
}
|
||||
fmt.Print(ansi("8"))
|
||||
}
|
||||
|
||||
func HideCursor() {
|
||||
if disableAnsi {
|
||||
return
|
||||
}
|
||||
fmt.Print(ansi("[?25l"))
|
||||
}
|
||||
|
||||
func ShowCursor() {
|
||||
if disableAnsi {
|
||||
return
|
||||
}
|
||||
fmt.Print(ansi("[?25h"))
|
||||
}
|
||||
|
||||
func MoveCursor(y, x int) {
|
||||
if disableAnsi {
|
||||
return
|
||||
}
|
||||
fmt.Print(ansi(fmt.Sprintf("[%d;%dH", y, x)))
|
||||
}
|
||||
|
||||
func MoveCursorX(pos int) {
|
||||
if disableAnsi {
|
||||
return
|
||||
}
|
||||
fmt.Print(ansi(fmt.Sprintf("[%dG", pos)))
|
||||
}
|
||||
|
||||
func ClearLine() {
|
||||
if disableAnsi {
|
||||
return
|
||||
@@ -70,6 +77,7 @@ func ClearLine() {
|
||||
// Does not move cursor from its current position
|
||||
fmt.Print(ansi("[2K"))
|
||||
}
|
||||
|
||||
func MoveCursorUp(lines int) {
|
||||
if disableAnsi {
|
||||
return
|
||||
@@ -77,6 +85,7 @@ func MoveCursorUp(lines int) {
|
||||
// Does not add new lines
|
||||
fmt.Print(ansi(fmt.Sprintf("[%dA", lines)))
|
||||
}
|
||||
|
||||
func MoveCursorDown(lines int) {
|
||||
if disableAnsi {
|
||||
return
|
||||
@@ -84,10 +93,12 @@ func MoveCursorDown(lines int) {
|
||||
// Does not add new lines
|
||||
fmt.Print(ansi(fmt.Sprintf("[%dB", lines)))
|
||||
}
|
||||
|
||||
func NewLine() {
|
||||
// Like \n
|
||||
fmt.Print("\012")
|
||||
}
|
||||
|
||||
func lenAnsi(s string) int {
|
||||
// len has into consideration ansi codes, if we want
|
||||
// the len of the actual len(string) we need to strip
|
||||
|
||||
@@ -104,10 +104,12 @@ func makeColorFunc(code string) colorFunc {
|
||||
}
|
||||
}
|
||||
|
||||
var nextColor = rainbowColor
|
||||
var rainbow []colorFunc
|
||||
var currentIndex = 0
|
||||
var mutex sync.Mutex
|
||||
var (
|
||||
nextColor = rainbowColor
|
||||
rainbow []colorFunc
|
||||
currentIndex = 0
|
||||
mutex sync.Mutex
|
||||
)
|
||||
|
||||
func rainbowColor() colorFunc {
|
||||
mutex.Lock()
|
||||
|
||||
@@ -110,8 +110,10 @@ type LogKeyboard struct {
|
||||
signalChannel chan<- os.Signal
|
||||
}
|
||||
|
||||
var KeyboardManager *LogKeyboard
|
||||
var eg multierror.Group
|
||||
var (
|
||||
KeyboardManager *LogKeyboard
|
||||
eg multierror.Group
|
||||
)
|
||||
|
||||
func NewKeyboardManager(ctx context.Context, isDockerDesktopActive, isWatchConfigured bool,
|
||||
sc chan<- os.Signal,
|
||||
@@ -206,7 +208,7 @@ func (lk *LogKeyboard) navigationMenu() string {
|
||||
if openDDInfo != "" || openDDUI != "" {
|
||||
watchInfo = navColor(" ")
|
||||
}
|
||||
var isEnabled = " Enable"
|
||||
isEnabled := " Enable"
|
||||
if lk.Watch.Watching {
|
||||
isEnabled = " Disable"
|
||||
}
|
||||
@@ -260,6 +262,7 @@ func (lk *LogKeyboard) openDDComposeUI(ctx context.Context, project *types.Proje
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
func (lk *LogKeyboard) openDDWatchDocs(ctx context.Context, project *types.Project) {
|
||||
eg.Go(tracing.EventWrapFuncForErrGroup(ctx, "menu/gui/watch", tracing.SpanOptions{},
|
||||
func(ctx context.Context) error {
|
||||
|
||||
@@ -57,29 +57,30 @@ specified in the service configuration.
|
||||
|
||||
### Options
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:------------------------|:--------------|:--------|:---------------------------------------------------------------------------------|
|
||||
| `--build` | `bool` | | Build image before starting container |
|
||||
| `--cap-add` | `list` | | Add Linux capabilities |
|
||||
| `--cap-drop` | `list` | | Drop Linux capabilities |
|
||||
| `-d`, `--detach` | `bool` | | Run container in background and print container ID |
|
||||
| `--dry-run` | `bool` | | Execute command in dry run mode |
|
||||
| `--entrypoint` | `string` | | Override the entrypoint of the image |
|
||||
| `-e`, `--env` | `stringArray` | | Set environment variables |
|
||||
| `-i`, `--interactive` | `bool` | `true` | Keep STDIN open even if not attached |
|
||||
| `-l`, `--label` | `stringArray` | | Add or override a label |
|
||||
| `--name` | `string` | | Assign a name to the container |
|
||||
| `-T`, `--no-TTY` | `bool` | `true` | Disable pseudo-TTY allocation (default: auto-detected) |
|
||||
| `--no-deps` | `bool` | | Don't start linked services |
|
||||
| `-p`, `--publish` | `stringArray` | | Publish a container's port(s) to the host |
|
||||
| `--quiet-pull` | `bool` | | Pull without printing progress information |
|
||||
| `--remove-orphans` | `bool` | | Remove containers for services not defined in the Compose file |
|
||||
| `--rm` | `bool` | | Automatically remove the container when it exits |
|
||||
| `-P`, `--service-ports` | `bool` | | Run command with all service's ports enabled and mapped to the host |
|
||||
| `--use-aliases` | `bool` | | Use the service's network useAliases in the network(s) the container connects to |
|
||||
| `-u`, `--user` | `string` | | Run as specified username or uid |
|
||||
| `-v`, `--volume` | `stringArray` | | Bind mount a volume |
|
||||
| `-w`, `--workdir` | `string` | | Working directory inside the container |
|
||||
| Name | Type | Default | Description |
|
||||
|:------------------------|:--------------|:---------|:---------------------------------------------------------------------------------|
|
||||
| `--build` | `bool` | | Build image before starting container |
|
||||
| `--cap-add` | `list` | | Add Linux capabilities |
|
||||
| `--cap-drop` | `list` | | Drop Linux capabilities |
|
||||
| `-d`, `--detach` | `bool` | | Run container in background and print container ID |
|
||||
| `--dry-run` | `bool` | | Execute command in dry run mode |
|
||||
| `--entrypoint` | `string` | | Override the entrypoint of the image |
|
||||
| `-e`, `--env` | `stringArray` | | Set environment variables |
|
||||
| `-i`, `--interactive` | `bool` | `true` | Keep STDIN open even if not attached |
|
||||
| `-l`, `--label` | `stringArray` | | Add or override a label |
|
||||
| `--name` | `string` | | Assign a name to the container |
|
||||
| `-T`, `--no-TTY` | `bool` | `true` | Disable pseudo-TTY allocation (default: auto-detected) |
|
||||
| `--no-deps` | `bool` | | Don't start linked services |
|
||||
| `-p`, `--publish` | `stringArray` | | Publish a container's port(s) to the host |
|
||||
| `--pull` | `string` | `policy` | Pull image before running ("always"\|"missing"\|"never") |
|
||||
| `--quiet-pull` | `bool` | | Pull without printing progress information |
|
||||
| `--remove-orphans` | `bool` | | Remove containers for services not defined in the Compose file |
|
||||
| `--rm` | `bool` | | Automatically remove the container when it exits |
|
||||
| `-P`, `--service-ports` | `bool` | | Run command with all service's ports enabled and mapped to the host |
|
||||
| `--use-aliases` | `bool` | | Use the service's network useAliases in the network(s) the container connects to |
|
||||
| `-u`, `--user` | `string` | | Run as specified username or uid |
|
||||
| `-v`, `--volume` | `stringArray` | | Bind mount a volume |
|
||||
| `-w`, `--workdir` | `string` | | Working directory inside the container |
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
|
||||
@@ -180,6 +180,16 @@ options:
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: pull
|
||||
value_type: string
|
||||
default_value: policy
|
||||
description: Pull image before running ("always"|"missing"|"never")
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: quiet-pull
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
|
||||
8
go.mod
8
go.mod
@@ -1,15 +1,15 @@
|
||||
module github.com/docker/compose/v2
|
||||
|
||||
go 1.22.7
|
||||
go 1.22.10
|
||||
|
||||
toolchain go1.23.3
|
||||
toolchain go1.23.4
|
||||
|
||||
require (
|
||||
github.com/AlecAivazis/survey/v2 v2.3.7
|
||||
github.com/Microsoft/go-winio v0.6.2
|
||||
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
|
||||
github.com/buger/goterm v1.0.4
|
||||
github.com/compose-spec/compose-go/v2 v2.4.6
|
||||
github.com/compose-spec/compose-go/v2 v2.4.7
|
||||
github.com/containerd/containerd v1.7.24
|
||||
github.com/containerd/platforms v0.2.1
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
@@ -173,7 +173,7 @@ require (
|
||||
go.opentelemetry.io/otel/sdk/metric v1.28.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
|
||||
golang.org/x/crypto v0.31.0 // indirect
|
||||
golang.org/x/net v0.29.0 // indirect
|
||||
golang.org/x/net v0.33.0 // indirect
|
||||
golang.org/x/oauth2 v0.23.0 // indirect
|
||||
golang.org/x/term v0.27.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
|
||||
8
go.sum
8
go.sum
@@ -79,8 +79,8 @@ github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004 h1:lkAMpLVBDaj17e
|
||||
github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA=
|
||||
github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUoc7Ik9EfrFqcylYqgPZ9ANSbTAntnE=
|
||||
github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4=
|
||||
github.com/compose-spec/compose-go/v2 v2.4.6 h1:QiqXQ2L/f0OCbAl41bPpeiGAWVRIQ+GEDrYxO+dRPhQ=
|
||||
github.com/compose-spec/compose-go/v2 v2.4.6/go.mod h1:lFN0DrMxIncJGYAXTfWuajfwj5haBJqrBkarHcnjJKc=
|
||||
github.com/compose-spec/compose-go/v2 v2.4.7 h1:WNpz5bIbKG+G+w9pfu72B1ZXr+Og9jez8TMEo8ecXPk=
|
||||
github.com/compose-spec/compose-go/v2 v2.4.7/go.mod h1:lFN0DrMxIncJGYAXTfWuajfwj5haBJqrBkarHcnjJKc=
|
||||
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
|
||||
github.com/containerd/cgroups/v3 v3.0.3 h1:S5ByHZ/h9PMe5IOQoN7E+nMc2UcLEM/V48DGDJ9kip0=
|
||||
github.com/containerd/cgroups/v3 v3.0.3/go.mod h1:8HBe7V3aWGLFPd/k03swSIsGjZhHI2WzJmticMgVuz0=
|
||||
@@ -545,8 +545,8 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
|
||||
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
|
||||
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
|
||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
|
||||
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
||||
@@ -16,7 +16,5 @@
|
||||
|
||||
package internal
|
||||
|
||||
var (
|
||||
// Version is the version of the CLI injected in compilation time
|
||||
Version = "dev"
|
||||
)
|
||||
// Version is the version of the CLI injected in compilation time
|
||||
var Version = "dev"
|
||||
|
||||
@@ -431,7 +431,6 @@ func (e Event) String() string {
|
||||
attr = append(attr, fmt.Sprintf("%s=%s", k, v))
|
||||
}
|
||||
return fmt.Sprintf("%s container %s %s (%s)\n", t, e.Status, e.Container, strings.Join(attr, ", "))
|
||||
|
||||
}
|
||||
|
||||
// ListOptions group options of the ls API
|
||||
|
||||
@@ -101,7 +101,8 @@ func (d *DryRunClient) ContainerAttach(ctx context.Context, container string, op
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ContainerCreate(ctx context.Context, config *containerType.Config, hostConfig *containerType.HostConfig,
|
||||
networkingConfig *network.NetworkingConfig, platform *specs.Platform, containerName string) (containerType.CreateResponse, error) {
|
||||
networkingConfig *network.NetworkingConfig, platform *specs.Platform, containerName string,
|
||||
) (containerType.CreateResponse, error) {
|
||||
d.containers = append(d.containers, moby.Container{
|
||||
ID: containerName,
|
||||
Names: []string{containerName},
|
||||
@@ -229,7 +230,6 @@ func (d *DryRunClient) ImageInspectWithRaw(ctx context.Context, imageName string
|
||||
default:
|
||||
return d.apiClient.ImageInspectWithRaw(ctx, imageName)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ImagePull(ctx context.Context, ref string, options image.PullOptions) (io.ReadCloser, error) {
|
||||
|
||||
@@ -134,7 +134,6 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
|
||||
fmt.Sprintf("building with %q instance using %s driver", b.Name, b.Driver),
|
||||
fmt.Sprintf("%s:%s", b.Driver, b.Name),
|
||||
))
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -187,7 +187,6 @@ func (s *composeService) projectFromName(containers Containers, projectName stri
|
||||
Image: c.Image,
|
||||
Labels: c.Labels,
|
||||
}
|
||||
|
||||
}
|
||||
service.Scale = increment(service.Scale)
|
||||
set[serviceLabel] = service
|
||||
@@ -321,7 +320,6 @@ func (s *composeService) RuntimeVersion(ctx context.Context) (string, error) {
|
||||
runtimeVersion.val = version.APIVersion
|
||||
})
|
||||
return runtimeVersion.val, runtimeVersion.err
|
||||
|
||||
}
|
||||
|
||||
func (s *composeService) isDesktopIntegrationActive() bool {
|
||||
|
||||
@@ -384,6 +384,12 @@ func checkExpectedNetworks(expected types.ServiceConfig, actual moby.Container,
|
||||
func checkExpectedVolumes(expected types.ServiceConfig, actual moby.Container, volumes map[string]string) bool {
|
||||
// check container's volume mounts and search for the expected ones
|
||||
for _, vol := range expected.Volumes {
|
||||
if vol.Type != string(mmount.TypeVolume) {
|
||||
continue
|
||||
}
|
||||
if vol.Source == "" {
|
||||
continue
|
||||
}
|
||||
id := volumes[vol.Source]
|
||||
found := false
|
||||
for _, mount := range actual.Mounts {
|
||||
@@ -578,11 +584,11 @@ func nextContainerNumber(containers []moby.Container) int {
|
||||
}
|
||||
}
|
||||
return maxNumber + 1
|
||||
|
||||
}
|
||||
|
||||
func (s *composeService) createContainer(ctx context.Context, project *types.Project, service types.ServiceConfig,
|
||||
name string, number int, opts createOptions) (container moby.Container, err error) {
|
||||
name string, number int, opts createOptions,
|
||||
) (container moby.Container, err error) {
|
||||
w := progress.ContextWriter(ctx)
|
||||
eventName := "Container " + name
|
||||
w.Event(progress.CreatingEvent(eventName))
|
||||
@@ -595,7 +601,8 @@ func (s *composeService) createContainer(ctx context.Context, project *types.Pro
|
||||
}
|
||||
|
||||
func (s *composeService) recreateContainer(ctx context.Context, project *types.Project, service types.ServiceConfig,
|
||||
replaced moby.Container, inherit bool, timeout *time.Duration) (moby.Container, error) {
|
||||
replaced moby.Container, inherit bool, timeout *time.Duration,
|
||||
) (moby.Container, error) {
|
||||
var created moby.Container
|
||||
w := progress.ContextWriter(ctx)
|
||||
w.Event(progress.NewEvent(getContainerProgressName(replaced), progress.Working, "Recreate"))
|
||||
@@ -664,7 +671,6 @@ func (s *composeService) createMobyContainer(ctx context.Context,
|
||||
) (moby.Container, error) {
|
||||
var created moby.Container
|
||||
cfgs, err := s.getCreateConfigs(ctx, project, service, number, inherit, opts)
|
||||
|
||||
if err != nil {
|
||||
return created, err
|
||||
}
|
||||
@@ -847,7 +853,8 @@ func (s *composeService) isServiceCompleted(ctx context.Context, containers Cont
|
||||
func (s *composeService) startService(ctx context.Context,
|
||||
project *types.Project, service types.ServiceConfig,
|
||||
containers Containers, listener api.ContainerEventListener,
|
||||
timeout time.Duration) error {
|
||||
timeout time.Duration,
|
||||
) error {
|
||||
if service.Deploy != nil && service.Deploy.Replicas != nil && *service.Deploy.Replicas == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -432,5 +432,4 @@ func TestCreateMobyContainer(t *testing.T) {
|
||||
}, progress.ContextWriter(context.TODO()))
|
||||
assert.NilError(t, err)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
@@ -139,7 +139,6 @@ func (s *composeService) listContainersTargetedForCopy(ctx context.Context, proj
|
||||
}
|
||||
if direction == fromService {
|
||||
return containers[:1], err
|
||||
|
||||
}
|
||||
return containers, err
|
||||
}
|
||||
|
||||
@@ -205,7 +205,6 @@ func (s *composeService) ensureProjectVolumes(ctx context.Context, project *type
|
||||
}
|
||||
return nil
|
||||
}()
|
||||
|
||||
if err != nil {
|
||||
progress.ContextWriter(ctx).TailMsgf("Failed to prepare Synchronized file shares: %v", err)
|
||||
}
|
||||
@@ -259,7 +258,7 @@ func (s *composeService) getCreateConfigs(ctx context.Context,
|
||||
if err != nil {
|
||||
return createConfigs{}, err
|
||||
}
|
||||
var containerConfig = container.Config{
|
||||
containerConfig := container.Config{
|
||||
Hostname: service.Hostname,
|
||||
Domainname: service.DomainName,
|
||||
User: service.User,
|
||||
@@ -892,7 +891,7 @@ func requireMountAPI(bind *types.ServiceVolumeBind) bool {
|
||||
}
|
||||
|
||||
func buildContainerMountOptions(p types.Project, s types.ServiceConfig, img moby.ImageInspect, inherit *moby.Container) ([]mount.Mount, error) {
|
||||
var mounts = map[string]mount.Mount{}
|
||||
mounts := map[string]mount.Mount{}
|
||||
if inherit != nil {
|
||||
for _, m := range inherit.Mounts {
|
||||
if m.Type == "tmpfs" {
|
||||
@@ -978,7 +977,7 @@ func fillBindMounts(p types.Project, s types.ServiceConfig, m map[string]mount.M
|
||||
}
|
||||
|
||||
func buildContainerConfigMounts(p types.Project, s types.ServiceConfig) ([]mount.Mount, error) {
|
||||
var mounts = map[string]mount.Mount{}
|
||||
mounts := map[string]mount.Mount{}
|
||||
|
||||
configsBaseDir := "/"
|
||||
for _, config := range s.Configs {
|
||||
@@ -1028,7 +1027,7 @@ func buildContainerConfigMounts(p types.Project, s types.ServiceConfig) ([]mount
|
||||
}
|
||||
|
||||
func buildContainerSecretMounts(p types.Project, s types.ServiceConfig) ([]mount.Mount, error) {
|
||||
var mounts = map[string]mount.Mount{}
|
||||
mounts := map[string]mount.Mount{}
|
||||
|
||||
secretsDir := "/run/secrets/"
|
||||
for _, secret := range s.Secrets {
|
||||
@@ -1221,7 +1220,7 @@ func (s *composeService) ensureNetwork(ctx context.Context, project *types.Proje
|
||||
if errdefs.IsConflict(err) {
|
||||
// Maybe another execution of `docker compose up|run` created same network
|
||||
// let's retry once
|
||||
return s.resolveOrCreateNetwork(ctx, project, "", n)
|
||||
return s.resolveOrCreateNetwork(ctx, project, name, n)
|
||||
}
|
||||
return id, err
|
||||
}
|
||||
@@ -1392,7 +1391,6 @@ func (s *composeService) resolveExternalNetwork(ctx context.Context, n *types.Ne
|
||||
networks, err := s.apiClient().NetworkList(ctx, network.ListOptions{
|
||||
Filters: filters.NewArgs(filters.Arg("name", n.Name)),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -1467,7 +1465,7 @@ func (s *composeService) ensureVolume(ctx context.Context, name string, volume t
|
||||
}
|
||||
actual, ok := inspected.Labels[api.ConfigHashLabel]
|
||||
if ok && actual != expected {
|
||||
var confirm = assumeYes
|
||||
confirm := assumeYes
|
||||
if !assumeYes {
|
||||
msg := fmt.Sprintf("Volume %q exists but doesn't match configuration in compose file. Recreate (data will be lost)?", volume.Name)
|
||||
confirm, err = prompt.NewPrompt(s.stdin(), s.stdout()).Confirm(msg, false)
|
||||
|
||||
@@ -438,7 +438,6 @@ func (g *Graph) HasCycles() (bool, error) {
|
||||
if !utils.StringContains(discovered, vertex.Key) && !utils.StringContains(finished, vertex.Key) {
|
||||
var err error
|
||||
discovered, finished, err = g.visit(vertex.Key, path, discovered, finished)
|
||||
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
|
||||
@@ -211,7 +211,8 @@ func TestDownRemoveOrphans(t *testing.T) {
|
||||
{
|
||||
Name: "myProject_default",
|
||||
Labels: map[string]string{compose.NetworkLabel: "default"},
|
||||
}}, nil)
|
||||
},
|
||||
}, nil)
|
||||
|
||||
stopOptions := containerType.StopOptions{}
|
||||
api.EXPECT().ContainerStop(gomock.Any(), "123", stopOptions).Return(nil)
|
||||
|
||||
@@ -21,10 +21,8 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
// isCaseInsensitiveEnvVars is true on platforms where environment variable names are treated case-insensitively.
|
||||
isCaseInsensitiveEnvVars = (runtime.GOOS == "windows")
|
||||
)
|
||||
// isCaseInsensitiveEnvVars is true on platforms where environment variable names are treated case-insensitively.
|
||||
var isCaseInsensitiveEnvVars = (runtime.GOOS == "windows")
|
||||
|
||||
// envResolver returns resolver for environment variables suitable for the current platform.
|
||||
// Expected to be used with `MappingWithEquals.Resolve`.
|
||||
|
||||
@@ -92,7 +92,6 @@ func (s *composeService) createProjectFromContainers(containers []moby.Container
|
||||
Image: c.Image,
|
||||
Labels: c.Labels,
|
||||
}
|
||||
|
||||
}
|
||||
service.Scale = increment(service.Scale)
|
||||
|
||||
@@ -172,7 +171,8 @@ func (s *composeService) toComposeHealthCheck(healthConfig *containerType.Health
|
||||
}
|
||||
|
||||
func (s *composeService) toComposeVolumes(volumes []moby.MountPoint) (map[string]types.VolumeConfig,
|
||||
[]types.ServiceVolumeConfig, map[string]types.SecretConfig, []types.ServiceSecretConfig) {
|
||||
[]types.ServiceVolumeConfig, map[string]types.SecretConfig, []types.ServiceSecretConfig,
|
||||
) {
|
||||
volumeConfigs := make(map[string]types.VolumeConfig)
|
||||
secretConfigs := make(map[string]types.SecretConfig)
|
||||
var serviceVolumeConfigs []types.ServiceVolumeConfig
|
||||
@@ -227,7 +227,6 @@ func (s *composeService) toComposeNetwork(networks map[string]*network.EndpointS
|
||||
networkConfigs[name] = types.NetworkConfig{
|
||||
Internal: inspect.Internal,
|
||||
}
|
||||
|
||||
}
|
||||
serviceNetworkConfigs[name] = &types.ServiceNetworkConfig{
|
||||
Aliases: net.Aliases,
|
||||
|
||||
@@ -48,7 +48,6 @@ func (s *composeService) Images(ctx context.Context, projectName string, options
|
||||
for _, c := range allContainers {
|
||||
if utils.StringContains(options.Services, c.Labels[api.ServiceLabel]) {
|
||||
containers = append(containers, c)
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -123,7 +123,8 @@ func containerLabels(service string, oneOff bool) map[string]string {
|
||||
compose.ServiceLabel: service,
|
||||
compose.ConfigFilesLabel: composefile,
|
||||
compose.WorkingDirLabel: workingdir,
|
||||
compose.ProjectLabel: strings.ToLower(testProject)}
|
||||
compose.ProjectLabel: strings.ToLower(testProject),
|
||||
}
|
||||
if oneOff {
|
||||
labels[compose.OneoffLabel] = "True"
|
||||
}
|
||||
|
||||
@@ -39,7 +39,6 @@ func (s *composeService) Logs(
|
||||
consumer api.LogConsumer,
|
||||
options api.LogOptions,
|
||||
) error {
|
||||
|
||||
var containers Containers
|
||||
var err error
|
||||
|
||||
|
||||
@@ -54,7 +54,6 @@ func (s *composeService) pause(ctx context.Context, projectName string, options
|
||||
}
|
||||
return err
|
||||
})
|
||||
|
||||
})
|
||||
return eg.Wait()
|
||||
}
|
||||
@@ -86,7 +85,6 @@ func (s *composeService) unPause(ctx context.Context, projectName string, option
|
||||
}
|
||||
return err
|
||||
})
|
||||
|
||||
})
|
||||
return eg.Wait()
|
||||
}
|
||||
|
||||
@@ -55,7 +55,8 @@ func TestPs(t *testing.T) {
|
||||
containers, err := tested.Ps(ctx, strings.ToLower(testProject), compose.PsOptions{})
|
||||
|
||||
expected := []compose.ContainerSummary{
|
||||
{ID: "123", Name: "123", Names: []string{"/123"}, Image: "foo", Project: strings.ToLower(testProject), Service: "service1",
|
||||
{
|
||||
ID: "123", Name: "123", Names: []string{"/123"}, Image: "foo", Project: strings.ToLower(testProject), Service: "service1",
|
||||
State: "running", Health: "healthy", Publishers: []compose.PortPublisher{},
|
||||
Labels: map[string]string{
|
||||
compose.ProjectLabel: strings.ToLower(testProject),
|
||||
@@ -64,7 +65,8 @@ func TestPs(t *testing.T) {
|
||||
compose.ServiceLabel: "service1",
|
||||
},
|
||||
},
|
||||
{ID: "456", Name: "456", Names: []string{"/456"}, Image: "foo", Project: strings.ToLower(testProject), Service: "service1",
|
||||
{
|
||||
ID: "456", Name: "456", Names: []string{"/456"}, Image: "foo", Project: strings.ToLower(testProject), Service: "service1",
|
||||
State: "running", Health: "",
|
||||
Publishers: []compose.PortPublisher{{URL: "localhost", TargetPort: 90, PublishedPort: 80}},
|
||||
Labels: map[string]string{
|
||||
@@ -74,7 +76,8 @@ func TestPs(t *testing.T) {
|
||||
compose.ServiceLabel: "service1",
|
||||
},
|
||||
},
|
||||
{ID: "789", Name: "789", Names: []string{"/789"}, Image: "foo", Project: strings.ToLower(testProject), Service: "service2",
|
||||
{
|
||||
ID: "789", Name: "789", Names: []string{"/789"}, Image: "foo", Project: strings.ToLower(testProject), Service: "service2",
|
||||
State: "exited", Health: "", ExitCode: 130, Publishers: []compose.PortPublisher{},
|
||||
Labels: map[string]string{
|
||||
compose.ProjectLabel: strings.ToLower(testProject),
|
||||
|
||||
@@ -175,7 +175,8 @@ func getUnwrappedErrorMessage(err error) string {
|
||||
}
|
||||
|
||||
func (s *composeService) pullServiceImage(ctx context.Context, service types.ServiceConfig,
|
||||
configFile driver.Auth, w progress.Writer, quietPull bool, defaultPlatform string) (string, error) {
|
||||
configFile driver.Auth, w progress.Writer, quietPull bool, defaultPlatform string,
|
||||
) (string, error) {
|
||||
w.Event(progress.Event{
|
||||
ID: service.Name,
|
||||
Status: progress.Working,
|
||||
|
||||
@@ -31,6 +31,5 @@ func (s *composeService) Scale(ctx context.Context, project *types.Project, opti
|
||||
return err
|
||||
}
|
||||
return s.start(ctx, project.Name, api.StartOptions{Project: project, Services: options.Services}, nil)
|
||||
|
||||
}), s.stdinfo())
|
||||
}
|
||||
|
||||
@@ -180,7 +180,8 @@ type containerWatchFn func(container moby.Container, t time.Time) error
|
||||
// watchContainers uses engine events to capture container start/die and notify ContainerEventListener
|
||||
func (s *composeService) watchContainers(ctx context.Context, //nolint:gocyclo
|
||||
projectName string, services, required []string,
|
||||
listener api.ContainerEventListener, containers Containers, onStart, onRecreate containerWatchFn) error {
|
||||
listener api.ContainerEventListener, containers Containers, onStart, onRecreate containerWatchFn,
|
||||
) error {
|
||||
if len(containers) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -69,6 +69,7 @@ func (s *composeService) getSyncImplementation(project *types.Project) (sync.Syn
|
||||
|
||||
return sync.NewTar(project.Name, tarDockerClient{s: s}), nil
|
||||
}
|
||||
|
||||
func (s *composeService) shouldWatch(project *types.Project) bool {
|
||||
var shouldWatch bool
|
||||
for i := range project.Services {
|
||||
@@ -84,6 +85,7 @@ func (s *composeService) shouldWatch(project *types.Project) bool {
|
||||
func (s *composeService) Watch(ctx context.Context, project *types.Project, services []string, options api.WatchOptions) error {
|
||||
return s.watch(ctx, nil, project, services, options)
|
||||
}
|
||||
|
||||
func (s *composeService) watch(ctx context.Context, syncChannel chan bool, project *types.Project, services []string, options api.WatchOptions) error { //nolint: gocyclo
|
||||
var err error
|
||||
if project, err = project.WithSelectedServices(services); err != nil {
|
||||
@@ -145,13 +147,13 @@ func (s *composeService) watch(ctx context.Context, syncChannel chan bool, proje
|
||||
|
||||
var paths, pathLogs []string
|
||||
for _, trigger := range config.Watch {
|
||||
if trigger.Action != types.WatchActionRebuild && checkIfPathAlreadyBindMounted(trigger.Path, service.Volumes) {
|
||||
if isSync(trigger) && checkIfPathAlreadyBindMounted(trigger.Path, service.Volumes) {
|
||||
logrus.Warnf("path '%s' also declared by a bind mount volume, this path won't be monitored!\n", trigger.Path)
|
||||
continue
|
||||
} else {
|
||||
var initialSync bool
|
||||
success, err := trigger.Extensions.Get("x-initialSync", &initialSync)
|
||||
if err == nil && success && initialSync && (trigger.Action == types.WatchActionSync || trigger.Action == types.WatchActionSyncRestart) {
|
||||
if err == nil && success && initialSync && isSync(trigger) {
|
||||
// Need to check initial files are in container that are meant to be synched from watch action
|
||||
err := s.initialSync(ctx, project, service, trigger, ignore, syncer)
|
||||
if err != nil {
|
||||
@@ -202,6 +204,10 @@ func (s *composeService) watch(ctx context.Context, syncChannel chan bool, proje
|
||||
}
|
||||
}
|
||||
|
||||
func isSync(trigger types.Trigger) bool {
|
||||
return trigger.Action == types.WatchActionSync || trigger.Action == types.WatchActionSyncRestart
|
||||
}
|
||||
|
||||
func (s *composeService) watchEvents(ctx context.Context, project *types.Project, name string, options api.WatchOptions, watcher watch.Notify, syncer sync.Syncer, triggers []types.Trigger) error {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
@@ -553,7 +559,6 @@ func (s *composeService) rebuild(ctx context.Context, project *types.Project, se
|
||||
// restrict the build to ONLY this service, not any of its dependencies
|
||||
options.Build.Services = []string{serviceName}
|
||||
imageNameToIdMap, err := s.build(ctx, project, *options.Build, nil)
|
||||
|
||||
if err != nil {
|
||||
options.LogTo.Log(api.WatchLogger, fmt.Sprintf("Build failed. Error: %v", err))
|
||||
return err
|
||||
@@ -626,7 +631,6 @@ func (s *composeService) pruneDanglingImagesOnRebuild(ctx context.Context, proje
|
||||
filters.Arg("label", api.ProjectLabel+"="+projectName),
|
||||
),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
logrus.Debugf("Failed to list images: %v", err)
|
||||
return
|
||||
|
||||
@@ -50,7 +50,7 @@ func TestDebounceBatching(t *testing.T) {
|
||||
matcher := watch.EmptyMatcher{}
|
||||
eventBatchCh := batchDebounceEvents(ctx, clock, quietPeriod, ch)
|
||||
for i := 0; i < 100; i++ {
|
||||
var path = "/a"
|
||||
path := "/a"
|
||||
if i%2 == 0 {
|
||||
path = "/b"
|
||||
}
|
||||
@@ -121,7 +121,6 @@ func (s stdLogger) Status(container, msg string) {
|
||||
}
|
||||
|
||||
func (s stdLogger) Register(container string) {
|
||||
|
||||
}
|
||||
|
||||
func TestWatch_Sync(t *testing.T) {
|
||||
|
||||
@@ -32,7 +32,6 @@ import (
|
||||
)
|
||||
|
||||
func TestLocalComposeBuild(t *testing.T) {
|
||||
|
||||
for _, env := range []string{"DOCKER_BUILDKIT=0", "DOCKER_BUILDKIT=1", "DOCKER_BUILDKIT=1,COMPOSE-BAKE=1"} {
|
||||
c := NewCLI(t, WithEnv(strings.Split(env, ",")...))
|
||||
|
||||
@@ -135,7 +134,6 @@ func TestLocalComposeBuild(t *testing.T) {
|
||||
c.RunDockerOrExitError(t, "rmi", "-f", "custom-nginx")
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestBuildSSH(t *testing.T) {
|
||||
@@ -150,7 +148,6 @@ func TestBuildSSH(t *testing.T) {
|
||||
ExitCode: 1,
|
||||
Err: "invalid empty ssh agent socket: make sure SSH_AUTH_SOCK is set",
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
t.Run("build succeed with ssh from Compose file", func(t *testing.T) {
|
||||
@@ -218,7 +215,6 @@ func TestBuildTags(t *testing.T) {
|
||||
c := NewParallelCLI(t)
|
||||
|
||||
t.Run("build with tags", func(t *testing.T) {
|
||||
|
||||
// ensure local test run does not reuse previously build image
|
||||
c.RunDockerOrExitError(t, "rmi", "build-test-tags")
|
||||
|
||||
@@ -318,7 +314,6 @@ func TestBuildPlatformsWithCorrectBuildxConfig(t *testing.T) {
|
||||
assert.NilError(t, res.Error, res.Stderr())
|
||||
res.Assert(t, icmd.Expected{Out: "I am building for linux/arm64"})
|
||||
res.Assert(t, icmd.Expected{Out: "I am building for linux/amd64"})
|
||||
|
||||
})
|
||||
|
||||
t.Run("multi-arch multi service builds ok", func(t *testing.T) {
|
||||
@@ -355,7 +350,6 @@ func TestBuildPlatformsWithCorrectBuildxConfig(t *testing.T) {
|
||||
assert.NilError(t, res.Error, res.Stderr())
|
||||
res.Assert(t, icmd.Expected{Out: "I am building for linux/386"})
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func TestBuildPrivileged(t *testing.T) {
|
||||
@@ -445,7 +439,6 @@ Switch to a different driver, or turn on the containerd image store, and try aga
|
||||
Err: "the classic builder doesn't support privileged mode, set DOCKER_BUILDKIT=1 to use BuildKit",
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func TestBuildBuilder(t *testing.T) {
|
||||
@@ -472,7 +465,6 @@ func TestBuildBuilder(t *testing.T) {
|
||||
Err: fmt.Sprintf(`no builder %q found`, "unknown-builder"),
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func TestBuildEntitlements(t *testing.T) {
|
||||
|
||||
@@ -169,4 +169,14 @@ func TestLocalComposeRun(t *testing.T) {
|
||||
assert.Assert(t, !strings.Contains(res.Combined(), "Pull complete"), res.Combined())
|
||||
assert.Assert(t, strings.Contains(res.Combined(), "Pulled"), res.Combined())
|
||||
})
|
||||
|
||||
t.Run("--pull", func(t *testing.T) {
|
||||
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/run-test/pull.yaml", "down", "--rmi", "all")
|
||||
res.Assert(t, icmd.Success)
|
||||
|
||||
res = c.RunDockerComposeCmd(t, "-f", "./fixtures/run-test/pull.yaml", "run", "--pull", "always", "backend")
|
||||
assert.Assert(t, strings.Contains(res.Combined(), "backend Pulling"), res.Combined())
|
||||
assert.Assert(t, strings.Contains(res.Combined(), "Download complete"), res.Combined())
|
||||
assert.Assert(t, strings.Contains(res.Combined(), "backend Pulled"), res.Combined())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -83,7 +83,6 @@ func TestLocalComposeUp(t *testing.T) {
|
||||
t.Run("check user labels", func(t *testing.T) {
|
||||
res := c.RunDockerCmd(t, "inspect", projectName+"-web-1")
|
||||
res.Assert(t, icmd.Expected{Out: `"my-label": "test"`})
|
||||
|
||||
})
|
||||
|
||||
t.Run("check healthcheck output", func(t *testing.T) {
|
||||
@@ -391,7 +390,6 @@ func TestNestedDotEnv(t *testing.T) {
|
||||
ExitCode: 0,
|
||||
Out: "root sub win=sub",
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func TestUnnecessaryResources(t *testing.T) {
|
||||
|
||||
@@ -4,4 +4,4 @@ services:
|
||||
build:
|
||||
context: .
|
||||
ssh:
|
||||
- fake-ssh=./fixtures/build-test/ssh/fake_rsa
|
||||
- fake-ssh=./fake_rsa
|
||||
|
||||
5
pkg/e2e/fixtures/recreate-volumes/bind.yaml
Normal file
5
pkg/e2e/fixtures/recreate-volumes/bind.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
services:
|
||||
app:
|
||||
image: alpine
|
||||
volumes:
|
||||
- .:/my_vol
|
||||
4
pkg/e2e/fixtures/run-test/pull.yaml
Normal file
4
pkg/e2e/fixtures/run-test/pull.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
services:
|
||||
backend:
|
||||
image: nginx
|
||||
command: nginx -t
|
||||
@@ -133,7 +133,6 @@ func copyLocalConfig(t testing.TB, configDir string) {
|
||||
// initializePlugins copies the necessary plugin files to the temporary config
|
||||
// directory for the test.
|
||||
func initializePlugins(t testing.TB, configDir string) {
|
||||
|
||||
t.Cleanup(func() {
|
||||
if t.Failed() {
|
||||
if conf, err := os.ReadFile(filepath.Join(configDir, "config.json")); err == nil {
|
||||
|
||||
@@ -128,6 +128,5 @@ func expectOutput(res *icmd.Result, expected string) func(t poll.LogT) poll.Resu
|
||||
return poll.Success()
|
||||
}
|
||||
return poll.Continue("condition not met")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,9 +142,7 @@ func TestNetworkModes(t *testing.T) {
|
||||
t.Run("run with service mode dependency", func(t *testing.T) {
|
||||
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/network-test/compose.yaml", "--project-name", projectName, "run", "-T", "mydb", "echo", "success")
|
||||
res.Assert(t, icmd.Expected{Out: "success"})
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func TestNetworkConfigChanged(t *testing.T) {
|
||||
@@ -182,5 +180,4 @@ func TestMacAddress(t *testing.T) {
|
||||
})
|
||||
res := c.RunDockerCmd(t, "inspect", fmt.Sprintf("%s-test-1", projectName), "-f", "{{ (index .NetworkSettings.Networks \"network_mac_address_default\" ).MacAddress }}")
|
||||
res.Assert(t, icmd.Expected{Out: "00:e0:84:35:d0:e8"})
|
||||
|
||||
}
|
||||
|
||||
@@ -89,5 +89,4 @@ func TestComposePull(t *testing.T) {
|
||||
res := c.RunDockerComposeCmd(t, "--project-directory", "fixtures/compose-pull/unknown-image", "pull", "--ignore-pull-failures")
|
||||
res.Assert(t, icmd.Expected{Err: "Some service image(s) must be built from source by running:"})
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
@@ -152,7 +152,6 @@ func TestScaleDoesntRecreate(t *testing.T) {
|
||||
|
||||
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"))
|
||||
|
||||
}
|
||||
|
||||
func TestUpWithDependencyNotRequired(t *testing.T) {
|
||||
|
||||
@@ -161,3 +161,16 @@ func TestUpRecreateVolumes(t *testing.T) {
|
||||
res = c.RunDockerCmd(t, "volume", "inspect", fmt.Sprintf("%s_my_vol", projectName), "-f", "{{ index .Labels \"foo\" }}")
|
||||
res.Assert(t, icmd.Expected{Out: "zot"})
|
||||
}
|
||||
|
||||
func TestUpRecreateVolumes_IgnoreBinds(t *testing.T) {
|
||||
c := NewCLI(t)
|
||||
const projectName = "compose-e2e-recreate-volumes"
|
||||
t.Cleanup(func() {
|
||||
c.cleanupWithDown(t, projectName)
|
||||
})
|
||||
|
||||
c.RunDockerComposeCmd(t, "-f", "./fixtures/recreate-volumes/bind.yaml", "--project-name", projectName, "up", "-d")
|
||||
|
||||
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/recreate-volumes/bind.yaml", "--project-name", projectName, "up", "-d")
|
||||
assert.Check(t, !strings.Contains(res.Combined(), "Recreated"))
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@ import (
|
||||
)
|
||||
|
||||
func TestWatch(t *testing.T) {
|
||||
|
||||
services := []string{"alpine", "busybox", "debian"}
|
||||
for _, svcName := range services {
|
||||
t.Run(svcName, func(t *testing.T) {
|
||||
@@ -133,7 +132,6 @@ func TestRebuildOnDotEnvWithExternalNetwork(t *testing.T) {
|
||||
}
|
||||
})
|
||||
testComplete.Store(true)
|
||||
|
||||
}
|
||||
|
||||
// NOTE: these tests all share a single Compose file but are safe to run
|
||||
|
||||
@@ -51,7 +51,7 @@ func (p *jsonWriter) Start(ctx context.Context) error {
|
||||
}
|
||||
|
||||
func (p *jsonWriter) Event(e Event) {
|
||||
var message = &jsonMessage{
|
||||
message := &jsonMessage{
|
||||
DryRun: p.dryRun,
|
||||
Tail: false,
|
||||
ID: e.ID,
|
||||
@@ -75,7 +75,7 @@ func (p *jsonWriter) Events(events []Event) {
|
||||
}
|
||||
|
||||
func (p *jsonWriter) TailMsgf(msg string, args ...interface{}) {
|
||||
var message = &jsonMessage{
|
||||
message := &jsonMessage{
|
||||
DryRun: p.dryRun,
|
||||
Tail: true,
|
||||
ID: "",
|
||||
|
||||
@@ -20,8 +20,7 @@ import (
|
||||
"context"
|
||||
)
|
||||
|
||||
type noopWriter struct {
|
||||
}
|
||||
type noopWriter struct{}
|
||||
|
||||
func (p *noopWriter) Start(ctx context.Context) error {
|
||||
return nil
|
||||
|
||||
@@ -345,6 +345,4 @@ func lenAnsi(s string) int {
|
||||
return length
|
||||
}
|
||||
|
||||
var (
|
||||
percentChars = strings.Split("⠀⡀⣀⣄⣤⣦⣶⣷⣿", "")
|
||||
)
|
||||
var percentChars = strings.Split("⠀⡀⣀⣄⣤⣦⣶⣷⣿", "")
|
||||
|
||||
@@ -36,5 +36,4 @@ func TestSplitWriter(t *testing.T) {
|
||||
w.Write([]byte("\n"))
|
||||
w.Write([]byte("world!\n"))
|
||||
assert.DeepEqual(t, lines, []string{"hello", "world!"})
|
||||
|
||||
}
|
||||
|
||||
@@ -28,9 +28,7 @@ import (
|
||||
"github.com/tilt-dev/fsnotify"
|
||||
)
|
||||
|
||||
var (
|
||||
numberOfWatches = expvar.NewInt("watch.naive.numberOfWatches")
|
||||
)
|
||||
var numberOfWatches = expvar.NewInt("watch.naive.numberOfWatches")
|
||||
|
||||
type FileEvent struct {
|
||||
path string
|
||||
@@ -76,8 +74,7 @@ type PathMatcher interface {
|
||||
MatchesEntireDir(file string) (bool, error)
|
||||
}
|
||||
|
||||
type EmptyMatcher struct {
|
||||
}
|
||||
type EmptyMatcher struct{}
|
||||
|
||||
func (EmptyMatcher) Matches(f string) (bool, error) { return false, nil }
|
||||
func (EmptyMatcher) MatchesEntireDir(f string) (bool, error) { return false, nil }
|
||||
|
||||
Reference in New Issue
Block a user