Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

plugins: set OTEL_RESOURCE_ATTRIBUTES when invoking a plugin #4875

Merged
merged 2 commits into from
Feb 28, 2024

Conversation

jsternberg
Copy link
Contributor

@jsternberg jsternberg commented Feb 13, 2024

- What I did

When a plugin is invoked, the docker cli will now set
OTEL_RESOURCE_ATTRIBUTES to pass OTEL resource attribute names to the
plugin as additional resource attributes. At the moment, the only
resource attribute passed is cobra.command_path.

All resource attributes passed by the CLI are prepended with the
namespace docker.cli to avoid clashing with existing ones the plugin
uses or ones defined by the user.

For aliased commands like the various builder commands, the command path
is overwritten to match with the original name (such as docker builder) instead of the forwarded name (such as docker buildx build).

- How I did it

This sets the OTEL_RESOURCE_ATTRIBUTES environment variable when invoking plugins and provides an option for the CLI to override this name through an annotation.

- How to verify it

See docker/buildx#2225.

- Description for the changelog

Set OTEL_RESOURCE_ATTRIBUTES when invoking plugins.

- A picture of a cute animal (not mandatory but encouraged)

@codecov-commenter
Copy link

codecov-commenter commented Feb 13, 2024

Codecov Report

Merging #4875 (5786f20) into master (eb306df) will decrease coverage by 0.08%.
The diff coverage is 13.79%.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #4875      +/-   ##
==========================================
- Coverage   61.31%   61.24%   -0.08%     
==========================================
  Files         287      287              
  Lines       20065    20090      +25     
==========================================
+ Hits        12303    12304       +1     
- Misses       6869     6893      +24     
  Partials      893      893              

@laurazard
Copy link
Member

I'm wondering:

  1. Is setting an env var the best way to do this? Could the CLI pass this is some other way?
  2. Whatever mechanism we do use for this, do we want to only have this special case handling code for docker build/build aliases or is this something that could be useful for other plugins/an interface that we should cement

/cc @thaJeztah @krissetto @Benehiko @neersighted

@Benehiko
Copy link
Member

I agree with @laurazard, to me this feels a bit hacky. I don't have an alternative solution for this right now, but we should think about this a bit.

@thaJeztah
Copy link
Member

Oh! Forgot to comment; yes agree as well. If we want to fix this, we should at least not make this specific to "build", as there's other plugins that may have the same / similar issues.

@thaJeztah
Copy link
Member

Very quick blurb / thought;

I think we currently alias all of these to the same command in buildx / docker-buildx, correct? i.e.,

  • docker build -> executes docker-buildx build
  • docker buildx build -> executes docker-buildx build
  • docker builder build -> executes docker-buildx build
  • docker image build -> executes docker-buildx build

Would it make sense to have the plugin (docker-buildx in this case) define (hidden) aliases for each, so;

  • docker build -> executes docker-buildx build
  • docker buildx build -> executes docker-buildx build <-- ❓ not sure what to do for this one if we want to distinguish this from the same "without buildx as subcommand"
  • docker builder build -> executes docker-buildx builder build (and other builder subcommands, like ls)
  • docker image build -> executes docker-buildx image build

Having such aliases also allows the plugin to apply specific behavior as well for each. In most cases this may only be to "adjust --help / usage output", but perhaps there's subtle differences between some (I recall some changes between docker buildx build and docker build w.r.t. which builder to user and whether --load should be used, but not sure). Other changes could be for (e.g.) the builder subcommand to only have the subcommands that we want to show there; which (for example) could hide imagetools (not sure we want that to be a builder subcommand!).

Perhaps the above would also need / could also need the plugin to advertise commands and aliases it wants to register as part of its metadata, e.g. something like;

~/.docker/cli-plugins/docker-buildx docker-cli-plugin-metadata
{
     "SchemaVersion": "0.1.0",
     "Vendor": "Docker Inc.",
     "Version": "v0.12.1-desktop.4",
     "ShortDescription": "Docker Buildx",
     "aliases": {
        "docker build": "build",
        "docker builder": "builder",
        "docker image build": "image build"
     }
}

@krissetto
Copy link
Contributor

I have two main thoughts regarding this:

  • Why does buildx need to be aware of the precise command initially used to invoke it? It almost feels like the plugin shouldn't have that info, as it strictly depends on the CLI implementation of aliases. If we need metrics/telemetry for which alias is used, I'd think that should be the CLI's responsibility, not the plugins'.

  • If we do decide we need the CLI to pass extra info to plugins, I think we should standardize some parameter format (or whatever other strategy) to be able to pass that info in the same way to all plugins. As a quick example, we could be sending a json string as some key-value parameter that gets passed down to the cli plugins (docker-buildx --context-info "{'key': 'value'}" build)

@thaJeztah

Would it make sense to have the plugin (docker-buildx in this case) define (hidden) aliases for each

Maybe i'm missing something, but I really wouldn't make buildx (or any other plugin) aware of the cli specific implementation details of aliases unless there's a really good reason to do so. I feel like having hidden aliases in the buildx plugin itself would be too tight of a coupling with the alias logic of the cli itself. Also, having slightly different buildx behavior based on the CLI alias used seems to be a bit of a headache, aside from a potential future footgun

@thaJeztah
Copy link
Member

If we do decide we need the CLI to pass extra info to plugins, I think we should standardize some parameter format (or whatever other strategy) to be able to pass that info in the same way to all plugins.

Yes, that was another approach I was considering. Only part there would be that it would (currently) be breaking backward-compatibility with existing plugins, so we'd need some way for the plugin to advertise that it supports that (to prevent it failng with unknown flag: --context-info).

A potentially nicer approach would be to start using the socket we now provide as a communication channel (i.e. the plugin could request this information from the CLI when needed).

Why does buildx need to be aware of the precise command initially used to invoke it?

One thing could be to print the correct "usage" output, for example, any of the below show the same usage output, but none of thm used buildx as subcommand;

docker build --help

Usage:  docker buildx build [OPTIONS] PATH | URL | -
...


docker image build --help

Usage:  docker buildx build [OPTIONS] PATH | URL | -
...


docker builder build --help

Usage:  docker buildx build [OPTIONS] PATH | URL | -
...
  

Possibly, there would bee other things to modify there, for example, it doesn't show available aliases (docker image build, docker build), but buildx also added a one-letter b alias for build;

docker build --help

Usage:  docker buildx build [OPTIONS] PATH | URL | -

Start a build

Aliases:
  docker buildx build, docker buildx b

I think that may have been added by maintainers who didn't like typing much. Perhaps that's ok when using buildx as a standalone binary, but it doesn't fit in the docker CLI UX, and it currently doesn't work (i.e., docker b, docker image b won't work), which makes it confusing

Maybe i'm missing something, but I really wouldn't make buildx (or any other plugin) aware of the cli specific implementation details of aliases unless there's a really good reason to do so

Definitely would need discussion. My thinking here is also for a plugin to be able to register aliases under existing "management" subcommands. Currently plugins can only add a top-level command (which usually would be a group of commands), i.e. the docker-compose CLI plugin adds a docker compose subcommand, and "owns" everything under that. But for buildx, special code was added to allow it to be adding (actually replacing) docker image build and docker build commands.

For some plugins we may consider them to be able to register additional functionality in parts of the CLI, e.g., think of a docker image debug subcommand that's backed by the "docker debug" extension, or docker image analyze (or whatever term to use) for Docker Scout to analyse an image.

Also, having slightly different buildx behavior based on the CLI alias used seems to be a bit of a headache, aside from a potential future footgun

Yeah, I agree in general; there's been a ton of discussion about that. Not sure from the top of my head now what the exact behavior is right now; but read the discussion on #3676 for more details.

Still there could be cases where things may be different depending on how they're invoked; possibly the same "plugin" command could back multiple things, but needs to adapt behavior (perhaps not a good example, but a bit similar to #3265 - all of which could theoretically be backed by a docker events plugin, but when calling docker container events it to automatically apply a --filter type=container filter).

I think the docker builder case may be interesting in that respect, as I'm not sure if that's necessarily meant to be a full alias of docker buildx, or only show a subset of commands; `d

@krissetto
Copy link
Contributor

Just throwing some ideas out there, I don't want to block anything


Perhaps that's ok when using buildx as a standalone binary, but it doesn't fit in the docker CLI UX, and it currently doesn't work (i.e., docker b, docker image b won't work), which makes it confusing

Confusing for who? I might be wrong, but IIRC most users should not really be aware that the CLI itself has plugins which should mostly behave like the standalone binaries, so I think the confusion is mostly for those people who already know the inner workings of the code a bit.

One thing could be to print the correct "usage" output

Thinking of one of our goals (making the CLI UX more consistent and generally better), are we sure each individual plugin should handle these sorts of messages for the user in its own way? It seems to me that if we could have a communication channel between plugins and the CLI (like the aforementioned socket), then the plugins could delegate some of those user-facing behaviors to the CLI itself (so we could for example unify error/warning messages and their styling, the plugins wouldn't need to know about aliases, we could have better control of the general UX, etc).

This could clearly also be achieved if "everyone is on the same page" and implements user-facing behavior in the same agreed-upon way.

perhaps not a good example, but a bit similar to #3265 - all of which could theoretically be backed by a docker events plugin, but when calling docker container events it to automatically apply a --filter type=container filter

Now this example is getting me thinking..I guess it could make sense for the plugins to register their own aliases when used by the CLI, and it shouldn't even be too much work once we decide on how we'd like to persist some data for the CLI (eg. in a sqlite db we could also use for the metadata caching).

Maybe something along the lines of:

  • Find the plugins in the plugin directories;
  • Get metadata and store it;
  • After getting the metadata and validating the plugin, we could call a specific hidden command on the binary (like the metadata one) to register aliases against the CLI, saving that info together with the metadata, or showing an error if the aliases would be overwriting other commands etc. Thinking about it, even the metadata itself could contain the desired aliases to register;
  • CLI creates all the commands required for plugins and their aliases (and on the next run it'd have the data cached for better perf) and proceeds with evaluating the user-typed args etc.

@jsternberg
Copy link
Contributor Author

Why does buildx need to be aware of the precise command initially used to invoke it? It almost feels like the plugin shouldn't have that info, as it strictly depends on the CLI implementation of aliases. If we need metrics/telemetry for which alias is used, I'd think that should be the CLI's responsibility, not the plugins'.

The primary reason is because we are able to collect much more detailed metrics inside of the plugin, but we still want to know how it was invoked.

If there's maybe a more acceptable way, OTEL itself has a way of overriding the service name used for a resource with an environment variable. Would doing something like setting OTEL_SERVICE_NAME (which defaults to buildx) to the alias that was used be acceptable? This would allow us to know which alias invoked the plugin for the purposes of metrics but mostly wouldn't affect anything else.

I don't know if we would need anything else beyond that. I don't think it's a good idea to allow plugins to register aliases with their metadata and I also don't think it's necessarily a good idea for the plugin to be able to meaningfully change it's behavior based on the alias that was used to invoke it.

@thaJeztah
Copy link
Member

Confusing for who? I might be wrong, but IIRC most users should not really be aware that the CLI itself has plugins which should mostly behave like the standalone binaries, so I think the confusion is mostly for those people who already know the inner workings of the code a bit.

Yes, so that part is where things currently break, because the --help output shows the same, and not output for the command you executed (i.e., it shows docker buildx build, not docker build).

Thinking of one of our goals (making the CLI UX more consistent and generally better), are we sure each individual plugin should handle these sorts of messages for the user in its own way?

Currently, at least they do, because the CLI itself doesn't know what the plugin provides, and the plugin may have output to produce as part of its invocation (including --help output).

I don't think it's a good idea to allow plugins to register aliases with their metadata and I also don't think it's necessarily a good idea for the plugin to be able to

This would need to be looked into. I also want to avoid having to hard-code every alias for each plugin in the CLI, because that would defeat the whole purpose of plugins to allow them to be developed separate from the docker CLI.

I also don't think it's necessarily a good idea for the plugin to be able to meaningfully change it's behavior based on the alias that was used to invoke it.

Yeah, so they already do (which was the whole discussion about that I linked to). That is, unless you ran docker buildx install, docker buildx build and docker build are ... different.

i.e. docker build uses the built-in builder, even if you created a builder and specified it to be the one to use;

docker builder create --use
eloquent_bell

echo -e "FROM busybox\nRUN echo foo > bar\n" | docker build -
[+] Building 0.1s (6/6) FINISHED                                                                                                         docker:default
 => [internal] load build definition from Dockerfile                                                                                               0.0s
 => => transferring dockerfile: 70B                                                                                                                0.0s
...

But docker buildx build uses the selected builder, but produces no image by default;

echo -e "FROM busybox\nRUN echo foo > bar\n" | docker buildx build -
[+] Building 3.4s (7/7) FINISHED                                                                                         docker-container:eloquent_bell
=> [internal] booting buildkit                                                                                                                    1.5s
=> => pulling image moby/buildkit:buildx-stable-1                                                                                                 1.0s
=> => creating container buildx_buildkit_eloquent_bell0                                                                                           0.5s
...
WARNING: No output specified with docker-container driver. Build result will only remain in the build cache. To push result image into registry use --push or to load image into docker use --load

The primary reason is because we are able to collect much more detailed metrics inside of the plugin, but we still want to know how it was invoked.

I'm curious where OTEL should be produced for the invocation. I wonder if we'd end up with things being double (i.e. docker CLI is invoked with docker build or docker buildx build, and creates a span for that invocation, and the docker-buildx plugin that's invoked also does this?)

@jsternberg
Copy link
Contributor Author

I'm curious where OTEL should be produced for the invocation. I wonder if we'd end up with things being double (i.e. docker CLI is invoked with docker build or docker buildx build, and creates a span for that invocation, and the docker-buildx plugin that's invoked also does this?)

At least for this implementation, we're not utilizing spans so there isn't really a concern of measuring two spans. We're using the metrics side of OTEL so that we can constrain a bit more easily the data we collect and prevent sending too much to the docker backend which is a black box to people outside of docker.

For the double span thing, I'll likely want to take a look at it to understand it, but if we were using the spans, we'd be looking for one specific span which would be the one that buildx produces. In order to have an issue with a double span, we'd need to invoke the same code twice and produce the same span.

At the moment, we're mimicking what compose does for its implementation. The compose plugin (not compose-cli) initializes the OTEL client itself using some configuration data inside of the context and then sends the OTEL traces to a GRPC socket that's been specified if metrics collection is enabled. We're planning to use the same socket, but the metrics side rather than the traces side of that same socket.

For the OTEL_SERVICE_NAME thing, it makes sense to me that the docker cli might have an interest in normalizing the naming of the plugin it's invoking rather than letting the user decide what the name should be. We could pass docker.cli (or something else) as the service.namespace to signify that the invocation was produced by the docker cli and then set the OTEL_SERVICE_NAME to the component that invoked the plugin. For everything except build, this would just match the plugin name. For build, we could have it be the aliased subcommand.

Doing it in this way scopes the change to only OTEL and seems a bit less hacky than just a random environment variable name. It might also help OTEL traces to be a bit more fully fledged since these names will show up in the traces so a person looking at the trace will be able to see them the same way the metrics endpoint sees them.

@jsternberg
Copy link
Contributor Author

Updated the PR to use the service name method I was referring to since I think that method would be desirable for us and provide some more uniformity within the CLI.

@milas just want to check that doing this doesn't cause any conflict with compose since this uses a similar path. I believe this should just ensure that the service name is properly set to compose. One potential downside to this method is if we want to allow a user to set the OTEL_SERVICE_NAME to their own custom value, we'll prevent them from doing that. At the same time, I think that environment variable is a bit more useful on the server-side and isn't particularly useful on the client side.

@jsternberg
Copy link
Contributor Author

Also, if we don't want to overload service name, we can choose our own attribute names such as docker.plugin.name and add them as part of OTEL_RESOURCE_ATTRIBUTES.

@laurazard
Copy link
Member

Late to the discussion (or early, but I missed the follow ups from everyone 😅

A few points, top down, as I'm reading through the discussion that happened in the meantime:

Why does buildx need to be aware of the precise command initially used to invoke it? It almost feels like the plugin shouldn't have that info, as it strictly depends on the CLI implementation of aliases. If we need metrics/telemetry for which alias is used, I'd think that should be the CLI's responsibility, not the plugins'.

Metrics, to provide correct usage information ("I ran docker build, why is this telling me that docker buildx doesn't have this flag?!"), etc.

It's very important to remember that most (all?) CLI plugins currently, explicitly, support both being executed as a CLI plugin or as a standalone binary, and as such in general do care about how they are invoked, and should behave properly in both cases.

Confusing for who? I might be wrong, but IIRC most users should not really be aware that the CLI itself has plugins which should mostly behave like the standalone binaries, so I think the confusion is mostly for those people who already know the inner workings of the code a bit.

Same point as above. Actually, for historical reasons, some users expect that plugins such as Compose are a standalone thing, and are still executing docker-compose to run it. Also, the standalone usecase is explicitly supported, and much desired/used in the case of buildx in CI, for one example. We shouldn't try to hide this imo, but we should make sure plugins have all the things they need to to function properly in both cases (as long as the standalone case is something we want to continue supporting, which I understand is the case).

Thinking of one of our goals (making the CLI UX more consistent and generally better), are we sure each individual plugin should handle these sorts of messages for the user in its own way?

It's complicated. On one hand, there is a lot of stuff that we could (and indeed, that was the idea) use the socket for! Even more, if you look at the hooks PR #4376, the idea was literally to take a structure logging approach to things (we discussed internally later using go templates, or something else, this was just a PoC) and let the CLI handle the actual printing of messages. However, we also probably want the plugins to have the same output whether connected to the CLI or not, so we can't abstract all of that away from the CLI. What we could do is build libraries for printing these kinds of messages/a bunch of other things into the CLI that the plugins can use, whether running as a CLI plugin or not, to print messages, which would achieve the UX consistency goal.

Maybe something along the lines of:
[...]

Yeah! The system you describe here is the same system as we discussed when we talked about carrying @neersighted's work with on-disk plugin metadata caching. In reality, you're mixing two concerns here – performance, and plugin aliases/etc – that is, on-disk caching is entirely orthogonal (but is recommended and we should follow up on it) for us to let plugin configure their own aliases, which could all be done at runtime.

I'll leave the OTEL discussion to those in the know, but from what I could see before, I don't think we should have double-span issues between the CLI invocation and the plugin's own.

@Benehiko
Copy link
Member

From my uninformed perspective, I would think that the CLI-plugin architecture would follow a client-server design, with the socket (as @laurazard and @thaJeztah mentioned) being the communication channel. There are of course other methods of IPC, but sockets are easy for plugins to adopt.

My thoughts on this are similar to @krissetto that you would have some sort of common interface of communication between the CLI and each plugin. I suppose to get something that is language agnostic, one could go with something like protobuf and have the CLI create the spec which plugins can consume in a defined way.

The CLI could then provide certain functionality to plugins (such as logging message etc.). Of course as @thaJeztah and I discussed this could be difficult since some plugins wouldn't want to be fully dependent upon the CLI for certain features, such as logging :).

Maintaining the CLI would also become more difficult as the features the CLI exposes to plugins increase. The question of some plugins wanting to be independent from the CLI as well as dependent makes it tricky. I suppose there are ways around this by having a wrapper around the standalone to make it plugin compatible or as @thaJeztah mentioned to me - compiling with flags to set the binary in a plugin mode could also work.

TL;DR plugins are hard and making everything work would take some thought. I agree to use the socket for IPC.

@jsternberg
Copy link
Contributor Author

jsternberg commented Feb 15, 2024

For the purposes required for what we need, I think a bidirectional socket communication might be too complicated. We don't really need to have a code path that asks the CLI for any information. We just mostly need it to tell us the command the plugin was originally invoked with.

I'm not sure what's the best way, but I do think likely using OTEL_RESOURCE_ATTRIBUTES is a good way for the CLI to interface with the plugin and give some additional information. Mostly because it's extensible and can be ignored if not needed, but also offers additional information for tracing that might be helpful. If this is a way that's acceptable, then there's a few different ways that we can pass this information.

  1. Define a new resource attribute with docker.cli.plugin as the attribute prefix. Define docker.cli.plugin.name or some other suitable attributes to pass how it was invoked.
  2. Use an existing namespace like the process attributes defined here. Have the CLI process discover the original command line and pass these attributes to the plugin.
  3. Combine these two approaches. Use the same structure as an existing attribute (such as process), but put it under the docker.cli namespace somewhere. Maybe something like docker.cli.process.command.

The advantage of using OTEL_RESOURCE_ATTRIBUTES is these attributes will automatically show up for any plugin using the default OTEL libraries and using the resource.WithFromEnv or resource.Default. It avoids any complexity of an IPC socket and it can't really reliably be used for the plugins to make any decisions based on the variables so we don't encourage plugins to do things they shouldn't be doing.

The advantage of option 1 is that we are using our own namespace and it won't conflict with any existing patterns. It's also straightforward and gives the exact information I need for my use case without becoming too much code. The advantage of 2 is it gives more information in an already standardized way, but I'm afraid that it could potentially conflict with the plugin itself since the values will be for the CLI process and not the plugin. The 3rd option has the advantage of being standardized for naming, but also scoped so the CLI process and plugins don't compete with each other and gives more information than option 1 in a bit more of a generic way.

Copy link
Collaborator

@cpuguy83 cpuguy83 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks ok to me.
I haven't tested it but I like the idea here.

@jsternberg
Copy link
Contributor Author

I've made some modifications from the original and wanted to go over them along with the ideas I considered but didn't like for one reason or another.

I tried using the existing process metrics from here: https://opentelemetry.io/docs/specs/semconv/resource/process/

I figured that using those and recording the resource at the start of the program (before any of the aliases has changed the command args) and then passing them to the plugin would work. It did, but it also came with the side effect that every plugin received the command line arguments in plaintext as part of the resource attributes in an environment variable. This included any sensitive information such as passwords from the command line and that would mean that the resource on traces and metrics would all have potentially sensitive command line arguments. This seemed too much. There wasn't another already existing OTEL attribute that would only give the subcommands and I figured adding one wouldn't make sense because there was too large of a possibility there would be a future conflict and, from my understanding, the process set of metrics seems to be things you could discover from /proc. Subcommands are something that's part of cobra so it didn't make sense.

My next attempt was to use CommandPath from Cobra. In the most recent version of Cobra (not the one we're using), you can use an annotation to override the root command's output for the purposes of help messages. This functionality might be useful for some of the issues discussed in this issue regarding help messages. I ultimately decided against it for a few reasons.

  1. Plugins don't have a proper subcommand so CommandPath() was docker always.
  2. If you did CommandPath() + plugin.Name as the annotation it required additional logic.
  3. Overwriting CommandPath() to be docker builder with the above pattern would result in docker builder buildx being the command path which is not a valid command.

Still, this annotation name cobra.command_path made sense to me and, while not an OTEL official name, felt like something that could be reasonably part of a contrib package.

For the implementation, I opted to create a new docker-specific annotation. If this annotation is set, it uses it without any additional processing. If it is not set, it defaults to CommandPath() + plugin.Name.

@jsternberg jsternberg changed the title build: set environment variable with the build alias used plugins: set OTEL_RESORUCE_ATTRIBUTES when invoking a plugin Feb 20, 2024
@jsternberg jsternberg changed the title plugins: set OTEL_RESORUCE_ATTRIBUTES when invoking a plugin plugins: set OTEL_RESOURCE_ATTRIBUTES when invoking a plugin Feb 20, 2024
@jsternberg jsternberg force-pushed the build-alias-env-var branch 3 times, most recently from df76528 to 99eb502 Compare February 20, 2024 17:19
@tonistiigi tonistiigi added this to the 26.0.0 milestone Feb 20, 2024
jsternberg and others added 2 commits February 28, 2024 12:43
When a plugin is invoked, the docker cli will now set
`OTEL_RESOURCE_ATTRIBUTES` to pass OTEL resource attribute names to the
plugin as additional resource attributes. At the moment, the only
resource attribute passed is `cobra.command_path`.

All resource attributes passed by the CLI are prepended with the
namespace `docker.cli` to avoid clashing with existing ones the plugin
uses or ones defined by the user.

For aliased commands like the various builder commands, the command path
is overwritten to match with the original name (such as `docker
builder`) instead of the forwarded name (such as `docker buildx build`).

Signed-off-by: Jonathan A. Sternberg <jonathan.sternberg@docker.com>
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
Copy link
Contributor

@krissetto krissetto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"LGTM"; looks like many have this a review, and we agreed on this, so bringing this in.

@thaJeztah thaJeztah merged commit 9015b71 into docker:master Feb 28, 2024
88 checks passed
@jsternberg jsternberg deleted the build-alias-env-var branch March 4, 2024 15:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants