Commit Graph

4363 Commits

Author SHA1 Message Date
Milas Bowman 1fdbcb6255 build: pass BuildOptions around explicitly & fix multi-platform issues
The big change here is to pass around an explicit `*BuildOptions` object
as part of Compose operations like `up` & `run` that may or may not do
builds. If the options object is `nil`, no builds whatsoever will be
attempted.

Motivation is to allow for partial rebuilds in the context of an `up`
for watch. This was broken and tricky to accomplish because various parts
of the Compose APIs mutate the `*Project` for convenience in ways that
make it unusable afterwards. (For example, it might set `service.Build = nil`
because it's not going to build that service right _then_. But we might
still want to build it later!)

NOTE: This commit does not actually touch the watch logic. This is all
      in preparation to make it possible.

As part of this, a bunch of code moved around and I eliminated a bunch
of partially redundant logic, mostly around multi-platform. Several
edge cases have been addressed as part of this:
 * `DOCKER_DEFAULT_PLATFORM` was _overriding_ explicitly set platforms
   in some cases, this is no longer true, and it behaves like the Docker
   CLI now
 * It was possible for Compose to build an image for one platform and
   then try to run it for a different platform (and fail)
 * Errors are no longer returned if a local image exists but for the
   wrong platform - the correct platform will be fetched/built (if
   possible).

Because there's a LOT of subtlety and tricky logic here, I've also tried
to add an excessive amount of explanatory comments.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-09-01 08:32:56 +02:00
Milas Bowman 407a0d5b53
up: fix various race/deadlock conditions on exit (#10934)
If running `up` in foreground mode (i.e. not `-d`),
when exiting via `Ctrl-C`, Compose stops all the
services it launched directly as part of that `up`
command.

In one of the E2E tests (`TestUpDependenciesNotStopped`),
this was occasionally flaking because the stop
behavior was racy: the return might not block on
the stop operation because it gets added to the
error group in a goroutine. As a result, it was
possible for no services to get terminated on exit.

There were a few other related pieces here that
I uncovered and tried to fix while stressing this.
For example, the printer could cause a deadlock if
an event was sent to it after it stopped.

Also, an error group wasn't really appropriate here;
each goroutine is a different operation for printing,
signal-handling, etc. If one part fails, we don't
actually want printing to stop, for example. This has
been switched to a `multierror.Group`, which has the
same API but coalesces errors instead of canceling a
context the moment the first one fails and returning
that single error.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-31 10:47:14 -04:00
Milas Bowman d0dfb848df
Merge pull request #10953 from thaJeztah/drop_uuid
pkg/api: replace uuid for basic random id
2023-08-31 10:43:34 -04:00
Sebastiaan van Stijn 8caa6f1f3e
pkg/api: replace uuid for basic random id
The uuid package in distribution was created as a utility for the distribution
project itself, to cut down external dependencies (see [1][1]).

For compose, this has the reverse effect, as it now brings all the dependencies
of the distribution module with it.

This patch switches to the uuid generation to crypto/rand to produce a random
id. I was considering using a different uuid implementation, or docker's
"stringid.GenerateRandomID", but all of those are doing more than needed,
so keep it simple.

Currently, this change has little effect, because compose also uses the
distribution module for other purposes, but the distribution project is
in the process of moving the "reference" package to a separate module,
in which case we don't want to depend on the distribution module only for
the uuid package.

[1]: 36e34a55ad

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-31 10:13:32 +02:00
Milas Bowman d6f842b042
test: e2e test reliability improvements (#10950)
* Use unique project name prefixes (some of these tests assert
  on output using the project name as a magic string, so could
  be impacted by other tests with the same project name prefix)
* Tear down port range project before starting to try and avoid
  race conditions with the engine and port assignment

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-30 16:01:15 -04:00
Milas Bowman 4fbbf201cd
build(deps): upgrade to compose-go v1.18.3 (#10947)
https://github.com/compose-spec/compose-go/releases/tag/v1.18.3

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-30 09:17:57 -04:00
Bilal Khan 935d72f46f added the dot at the end of the sentence
Signed-off-by: Bilal Khan <bilalkhanrecovered@gmail.com>
2023-08-28 09:19:26 +02:00
Nicolas De Loof 41682acc77 add support for attributes exposed by `docker ps`
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-08-25 16:36:45 +02:00
Nicolas De Loof 1054792b47 align docker compose ps with docker CLI to support --format
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-08-25 16:36:45 +02:00
Milas Bowman 19f66918cc watch: only allow a single instance per-project
This is a good place to start introducing (local) exclusivity
to Compose. Now, when `alpha watch` launches, it will check for
the existence of a PID file in the user XDG runtime directory,
and create one if the existing one is stale or does not exist.
If the PID file exists and is valid, an error is returned and
Compose exits.

A slight tweak to the experimental remote Git loader has been
made to use the XDG package for consistency.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-25 15:49:28 +02:00
Milas Bowman 186744e034 ci: bump golangci-lint to v1.54.2
Also improve incremental lint caching.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-24 08:57:47 +02:00
Milas Bowman bc9d696fa0
Merge pull request #10922 from thaJeztah/replace_dockerignore
replace dockerfile/dockerignore with patternmatcher/ignorefile
2023-08-23 16:04:19 -04:00
Nicolas De loof 6204fb1c94
logs: fix for missing output on container exit (#10925)
We can't assume we receive container logs line by line. Some framework won't buffer output and will send char by char, and we also can receive looong lines which get buffered to 32kb and then cut into multiple logs.

This assumes we will catch container streams being closed before we receive a die event for container, which could be subject to race condition, but at least the impact here is minimal and the fix works for reproduction examples provided in linked issues.

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-08-23 08:57:18 -04:00
Sebastiaan van Stijn 5d732010a7
replace dockerfile/dockerignore with patternmatcher/ignorefile
The BuildKit dockerignore package was integrated in the patternmatcher
repository / module. This patch updates our uses of the BuildKit package
with its new location.

A small local change was made to keep the format of the existing error message,
because the "ignorefile" package is slightly more agnostic in that respect
and doesn't include ".dockerignore" in the error message.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-23 00:43:17 +02:00
Sebastiaan van Stijn 2006f3fe7d
go.mod: github.com/moby/patternmatcher v0.6.0
- integrate frontend/dockerfile/dockerignore from buildkit

full diff: https://github.com/moby/patternmatcher/compare/v0.5.0...v0.6.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-23 00:40:12 +02:00
Sebastiaan van Stijn 192718c001
go.mod: remove some outdated comments
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-23 00:39:35 +02:00
Milas Bowman c79f67fead otel: add `include` to project up span
Flatten the list of included files and add as a slice attribute.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-22 16:10:18 +02:00
dependabot[bot] 3b294bfdda
build(deps): bump github.com/compose-spec/compose-go from 1.18.1 to 1.18.2 (#10915)
build(deps): bump github.com/compose-spec/compose-go

Bumps [github.com/compose-spec/compose-go](https://github.com/compose-spec/compose-go) from 1.18.1 to 1.18.2.
- [Release notes](https://github.com/compose-spec/compose-go/releases)
- [Commits](https://github.com/compose-spec/compose-go/compare/v1.18.1...v1.18.2)

---
updated-dependencies:
- dependency-name: github.com/compose-spec/compose-go
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-21 14:02:03 -04:00
Nicolas De loof dd34f7a22b
include: add experimental support for Git resources (#10811)
Requires setting `COMPOSE_EXPERIMENTAL_GIT_REMOTE=1`.

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-08-18 09:16:45 -04:00
Milas Bowman caad72713b up: handle various attach use cases better
By default, `compose up` attaches to all services (i.e.
shows log output from every associated container). If
a service is specified, e.g. `compose up foo`, then
only `foo`'s logs are tailed. The `--attach-dependencies`
flag can also be used, so that if `foo` depended upon
`bar`, then `bar`'s logs would also be followed. It's
also possible to use `--no-attach` to filter out one
or more services explicitly, e.g. `compose up --no-attach=noisy`
would launch all services, including `noisy`, and would
show log output from every service _except_ `noisy`.
Lastly, it's possible to use `up --attach` to explicitly
restrict to a subset of services (or their dependencies).

How these flags interact with each other is also worth
thinking through.

There were a few different connected issues here, but
the primary issue was that running `compose up foo` was
always attaching dependencies regardless of `--attach-dependencies`.

The filtering logic here has been updated so that it
behaves predictably both when launching all services
(`compose up`) or a subset (`compose up foo`) as well
as various flag combinations on top of those.

Notably, this required making some changes to how it
watches containers. The logic here between attaching
for logs and monitoring for lifecycle changes is
tightly coupled, so some changes were needed to ensure
that the full set of services being `up`'d are _watched_
and the subset that should have logs shown are _attached_.
(This does mean faking the attach with an event but not
actually doing it.)

While handling that, I adjusted the context lifetimes
here, which improves error handling that gets shown to
the user and should help avoid potential leaks by getting
rid of a `context.Background()`.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-18 12:38:38 +02:00
Nicolas De loof 792afb8d13
build: use correct values for proxy variables (#10908)
clone variable before we capture a pointer

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-08-17 14:25:28 -04:00
Nicolas De Loof 150449bbd2 warn user secret uid/gid/mode is not supported
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-08-16 19:17:28 +02:00
Guillaume Lours 8d0df18762
Merge pull request #10867 from docker/dependabot/go_modules/github.com/moby/buildkit-0.12.1
build(deps): bump github.com/moby/buildkit from 0.12.1-0.20230717122532-faa0cc7da353 to 0.12.1
2023-08-11 10:45:05 +02:00
dependabot[bot] 5b53f8e47f
build(deps): bump github.com/moby/buildkit
Bumps [github.com/moby/buildkit](https://github.com/moby/buildkit) from 0.12.1-0.20230717122532-faa0cc7da353 to 0.12.1.
- [Release notes](https://github.com/moby/buildkit/releases)
- [Commits](https://github.com/moby/buildkit/commits/v0.12.1)

---
updated-dependencies:
- dependency-name: github.com/moby/buildkit
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-11 08:28:23 +00:00
Guillaume Lours c5fef61383
Merge pull request #10893 from glours/bump-compose-go-v1.18.1
bump compose-go to version v1.18.1
2023-08-10 21:08:07 +02:00
Guillaume Lours ce3cb2b00c
bump compose-go to version v1.18.1
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-08-10 20:51:22 +02:00
Guillaume Lours d9e73db8e6
Merge pull request #10891 from glours/bump-compose-go-v1.18.0
bump compose-go to version v1.18.0
2023-08-10 17:13:53 +02:00
Guillaume Lours d6b4d1c755
bump compose-go to version v1.18.0
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-08-10 17:00:32 +02:00
Guillaume Lours 0baf24a269
Merge pull request #10890 from glours/bump-golang-1.21
upgrade Golang to 1.21
2023-08-10 15:22:50 +02:00
Guillaume Lours 0511b0c2b8
Merge pull request #10878 from relrelb/profiles_completion
Add shell completion for `--profile`
2023-08-10 15:16:24 +02:00
Guillaume Lours 5bbdf3d84a
Merge pull request #10879 from relrelb/project_directory_completion
Improve shell completion for `--project-directory`
2023-08-10 15:15:58 +02:00
Guillaume Lours 52103cce74 update README and CI workflows to match main branch
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-08-10 15:11:27 +02:00
Guillaume Lours 020b57ca31
upgrade Golang to 1.21
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-08-10 15:07:09 +02:00
Milas Bowman bfa54081d4
build: fix missing proxy build args for classic builder (#10887)
Refactor to use a consistent code path for determining the build
args for a service image regardless of whether BuildKit or the
classic builder is being used.

After recent changes, these code paths had diverged, so the classic
builder was missing the proxy variables from the Docker client
config.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-10 08:57:28 -04:00
Milas Bowman 0be8e4a676
trace: do not block connecting to OTLP endpoint (#10882)
This was left over from debugging, but we should not block.
OTel will handle the connection in the background.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-08 15:47:18 -04:00
Milas Bowman fd8ab2f7ac
watch: enable tar-based syncer by default (#10877)
Swap the default implementation now that batching is merged.
Keeping the `docker cp` based implementation around for the
moment, but it needs to be _explicitly_ disabled now by setting
`COMPOSE_EXPERIMENTAL_WATCH_TAR=0`.

After the next release, we should remove the `docker cp`
implementation entirely.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-04 16:58:01 -04:00
Guillaume Lours b406b393bf
Merge pull request #10881 from silvin-lubecki/display-builder-name
Display builder's name on the first build line.
2023-08-04 17:36:18 +02:00
Silvin Lubecki 0a9d1277c5 Display builder's name on the first build line.
Code borrowed from buildx commands/build.go.

Signed-off-by: Silvin Lubecki <silvin.lubecki@docker.com>
2023-08-04 17:11:44 +02:00
Milas Bowman c350f80d4b
up: do not warn on successful optional dependency complete (#10870)
If an optional dependency exits successfully (exit code of 0),
with a service condition of `service_completed_successfully`,
don't log a warning.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-03 21:00:49 +00:00
relrelb 8a4095b507 Improve shell completion for `--project-directory`
Signed-off-by: Ariel Bachar <relrelb@users.noreply.github.com>
Signed-off-by: relrelb <relrelb@users.noreply.github.com>
2023-08-03 23:40:56 +03:00
relrelb 0345461412 Add shell completion for `--profile`
Signed-off-by: Ariel Bachar <relrelb@users.noreply.github.com>
Signed-off-by: relrelb <relrelb@users.noreply.github.com>
2023-08-03 23:09:13 +03:00
Milas Bowman 80856eacaf
progress: minor correctness fixes (#10871)
* When waiting for dependencies, `select` on the context as well
  as the ticker
* Write multiple progress events "transactionally" (i.e. hold the
  lock for the duration to avoid other events being interleaved)
* Do not change "finished" steps back to "in progress" to prevent
  flickering

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-03 15:14:17 -04:00
Praful Gupta d7b1972d5e
doc: update Config() comment in API Service interface (#10840)
Update Config comment in Service interface

Signed-off-by: Praful Gupta <prafulgupta6@gmail.com>
2023-08-03 15:13:26 -04:00
Silvin Lubecki 7c42776770
Improve buildkit node creation (#10843)
Move builder and nodes initialization code up, avoiding to recreate/load them for every service build.

Signed-off-by: Silvin Lubecki <silvin.lubecki@docker.com>
2023-08-03 15:11:16 -04:00
Milas Bowman 3b0742fd57
watch: batch & de-duplicate file events (#10865)
Adjust the debouncing logic so that it applies to all inbound file
events, regardless of whether they match a sync or rebuild rule.

When the batch is flushed out, if any event for the service is a
rebuild event, then the service is rebuilt and all sync events for
the batch are ignored. If _all_ events in the batch are sync events,
then a sync is triggered, passing the entire batch at once. This
provides a substantial performance win for the new `tar`-based
implementation, as it can efficiently transfer the changes in bulk.

Additionally, this helps with jitter, e.g. it's not uncommon for
there to be double-writes in quick succession to a file, so even if
there's not many files being modified at once, it can still prevent
some unnecessary transfers.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-03 14:53:02 -04:00
Milas Bowman efd44de1b7
watch: support multiple containers for tar implementation (#10860)
Support services with scale > 1 for the tar watch sync.

Add a "lossy" multi-writer specific to pipes that writes the
tar data to each `io.PipeWriter`, which is connected to `stdin`
for the `tar` process being exec'd in the container.

The data is written serially to each writer. This could be
adjusted to do concurrent writes but that will rapidly increase
the I/O load, so is not done here - in general, 99% of the
time you'll be developing (and thus using watch/sync) with a
single replica of a service.

If a write fails, the corresponding `io.PipeWriter` is removed
from the active set and closed with an error.

This means that a single container copy failing won't stop
writes to the others that are succeeding. Of course, they will
be in an inconsistent state afterwards still, but that's a
different problem.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-03 14:52:39 -04:00
Milas Bowman bdb3f91eb4
test: temporarily disable an exit-code-from Cucumber test case (#10875)
Something is wrong here, disabling while we investigate.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-03 14:49:59 -04:00
Milas Bowman f94cb49062
test: fix e2e test for privileged builds (#10873)
We cannot guarantee the exact value of `CapEff` across
environments, and this test has started failing some places,
e.g. Docker Desktop, and now GitHub Actions (likely due to
a kernel upgrade on the runners or similar).

By setting `privileged: true` on the build, we're asking for
the `security.insecure` entitlement on the build. A safe
assumption is that will include `CAP_SYS_ADMIN`, which won't
be present otherwise, so mask the `CapEff` value and check
for that.

It's worth noting that realistically, the build won't even
be able to complete without the correct entitlement, since the
`Dockerfile` uses `RUN --security=insecure`, so this is really
an additional sanity check.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-03 12:23:24 -04:00
Milas Bowman e7ed070690
Merge pull request #10861 from thaJeztah/update_go1.20.7
update to go1.20.7
2023-08-02 10:08:37 -04:00
Sebastiaan van Stijn 8a1bf5d28b
update to go1.20.7
Includes a fix for CVE-2023-29409

go1.20.7 (released 2023-08-01) includes a security fix to the crypto/tls
package, as well as bug fixes to the assembler and the compiler. See the
Go 1.20.7 milestone on our issue tracker for details:

- https://github.com/golang/go/issues?q=milestone%3AGo1.20.7+label%3ACherryPickApproved
- full diff: https://github.com/golang/go/compare/go1.20.6...go1.20.7

From the mailing list announcement:

[security] Go 1.20.7 and Go 1.19.12 are released

Hello gophers,

We have just released Go versions 1.20.7 and 1.19.12, minor point releases.

These minor releases include 1 security fixes following the security policy:

- crypto/tls: restrict RSA keys in certificates to <= 8192 bits

  Extremely large RSA keys in certificate chains can cause a client/server
  to expend significant CPU time verifying signatures. Limit this by
  restricting the size of RSA keys transmitted during handshakes to <=
  8192 bits.

  Based on a survey of publicly trusted RSA keys, there are currently only
  three certificates in circulation with keys larger than this, and all
  three appear to be test certificates that are not actively deployed. It
  is possible there are larger keys in use in private PKIs, but we target
  the web PKI, so causing breakage here in the interests of increasing the
  default safety of users of crypto/tls seems reasonable.

  Thanks to Mateusz Poliwczak for reporting this issue.

View the release notes for more information:
https://go.dev/doc/devel/release#go1.20.7

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-02 00:22:13 +02:00