-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
feat: add option --container-host to commands local start-api, local start-lambda and local invoke #2700
Conversation
I have a hard time coming up with a reasonable cli option name for this. I wonder if this is the approach we should go. What are the possible values customers might specify using Or even further, we can detect whether |
As far as I know, |
All communication with the Docker daemon happens through socket, and technically the listening end (hence the containers started by the daemon) could be anywhere, so the address the containers are listening on could also be anywhere. |
This is exactly my problem. I have the daemon on a different machine and need to specify that as the host |
click.option( | ||
"--container-host", | ||
default="localhost", | ||
help="Host of locally emulated Lambda container", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This help text should be more verbose and explain what are potential options, and when it needs to be specified. Looking at this from the user perspective, we want this to be clear/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure! I'm thinking Host of locally emulated Lambda container. This option can be used for running SAM CLI in containers e.g. If you want to run SAM CLI in a Docker container, use this option with host.docker.internal. For SAM CLI running on your local machine, this option is not needed.
This should be clear for customers who want to use this option. Let me know your thought.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
host.docker.internal
works in some situations such as for macOS, but doesn't unconditionally resolve to the actual machine running Docker out of the box. See docker/for-linux#264
Even if SAM CLI is running locally (not inside a container), the Docker daemon could be running remotely (see e.g. #2700 (comment)), requiring this argument.
Mentioning host.docker.internal
is probably fine, but the main point is that this option is useful when the container ports aren't exposed on SAM CLI's localhost
, regardless of where SAM CLI may run.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes you're right. The above message could be a little misleading for some use cases. I will try to make the help text more general with a detailed example like host.docker.internal
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Host of locally emulated Lambda container. This option can be used when the container ports aren't exposed on SAM CLI's localhost. e.g. If you want to run SAM CLI in a Docker container on Mac OS, use this option with host.docker.internal.
How is this help text?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like it! I'd maybe amend a little bit to something like this:
Host of locally emulated Lambda container. This option is useful when the container ports aren't exposed on the same host SAM CLI runs on. For example, if you want to run SAM CLI in a Docker container on macOS, use this option with
host.docker.internal
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Talked to Chris and we feel this looks better for customers to understand and it's pretty clear too:
Host of locally emulated Lambda container. This option is useful when the containers run on a different host than SAM CLI. For example, if you want to run SAM CLI in a Docker container on macOS, use this option with
host.docker.internal
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems container_host
can never be None
because it has a default value in click. Therefore, the Optional
for this might be misleading.
@@ -71,6 +72,7 @@ def __init__( | |||
:param docker_client: Optional, a docker client to replace the default one loaded from env | |||
:param container_opts: Optional, a dictionary containing the container options | |||
:param additional_volumes: Optional list of additional volumes | |||
:param string container_host: Optional. Host of locally emulated Lambda container |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this cannot be optional anymore, because if customers do not specify a value, click will use the default value localhost
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same reason as my another comment below.
samcli/local/docker/container.py
Outdated
@@ -55,6 +55,7 @@ def __init__( | |||
docker_client=None, | |||
container_opts=None, | |||
additional_volumes=None, | |||
container_host=None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here, this is not optional
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_init_
here is also used in another its child class LambdaBuildContainer
. The new option is not used in that class so I make it as optional.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if this is used by other classes (i'm assuming those other classes are instantiated outside of sam local suite, is it sam build?) , should we set a default value? this can get overridden when the actual option is used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I know, container_host
is only used in SAM LOCAL suite when one of its child class is instantiated. So whether or not setting the default value here makes no difference. If we could potentially expand the use of new option outside of sam local suite, then yes we should set default to localhost
here. Considering there is no negative impact setting the default value, I will add the default value to the option here.
samcli/local/docker/container.py
Outdated
@@ -55,6 +55,7 @@ def __init__( | |||
docker_client=None, | |||
container_opts=None, | |||
additional_volumes=None, | |||
container_host=None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if this is used by other classes (i'm assuming those other classes are instantiated outside of sam local suite, is it sam build?) , should we set a default value? this can get overridden when the actual option is used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although we store localhost
(the default value) in two different places, it is acceptable to me due to it is very unlikely to change. Thanks for addressing the comments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great feature, thanks for the implementation 🎉
Can we also add some integration test cases to validate this new parameter as well?
@@ -43,6 +43,7 @@ def __init__( | |||
aws_region: Optional[str] = None, | |||
env_vars_values: Optional[Dict[Any, Any]] = None, | |||
debug_context: Optional[DebugContext] = None, | |||
container_host: Optional[str] = None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since there is a default value for the parameter, would this param be None
anytime?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This param won't be None
in the current use case. The reasons I set it to None
:
- I'd like to have minimum impact on the current use case. If this class is initialized somewhere else, we shouldn't assume it's
localhost
unless it's passed from cli. - Match to the overall style.
) | ||
), | ||
click.option( | ||
"--container-host", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For any security reasons, do we need to validate if this option valid?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good point. Let me check on this and get back to you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For security reasons, there is nothing we can validate. There is a use case that docker daemon is running on a different host and the customer wants to use that host. We won't be able to understand if it's a good host provided by customer or just a bad actor.
For the integration test, please see my explanation in the summary.
|
…start-lambda and local invoke (aws#2700)
…, local start-lambda and local invoke (#2700)" (#2794) This reverts commit e653fe2. Co-authored-by: Xia Zhao <[email protected]>
Why did this get reverted in master? |
@hanneswidrig We found a bug when using |
…, local start-lambda and local invoke (aws#2700)" (aws#2794) This reverts commit e653fe2. Co-authored-by: Xia Zhao <[email protected]>
Add an option
--container-host
to commandslocal start-api
,local start-lambda
andlocal invoke
. Customers will be able to specify the host of local emulated containers to support more use cases.Which issue(s) does this change fix?
#2492 #2436
Why is this change necessary?
Some customers are having issues to run sam local commands within containers.
How does it address the issue?
After some investigation, this line is the root cause that SAM CLI can not be run within containers. The
localhost
can not be recognized by the system when running in a container. With the new option--container-host
, customers will be able to specify host of the local emulated container (e.g. host.docker.internal in Docker).If the new option is not set,
localhost
will be used as default so it won't have impact on current use cases.What side effects does this change have?
Checklist
I didn't write integration tests for this feature. Basically the new option only make a small change to the URL of the container and unit tests show the correct URL is being called. It's very complicated to write integration test to simulate real use case since the feature will only be used when running in a container. Therefore I believe unit tests are sufficient for this change.
make pr
passesmake update-reproducible-reqs
if dependencies were changedBy submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.