Skip to content

Conversation

@ueokande
Copy link

@ueokande ueokande commented Dec 4, 2018

I propose that the user can configure HTTP client to access internet by it.

In our case, the http proxy settings is required when the client accesses to Internet.
The HTTP proxy is currently set via environment variable.

Proxy: http.ProxyFromEnvironment,

This patch adds filed HTTPClient *http.Client to SystemContext to use on pulling image or fetching informations from the Internet. The docker client use HTTPClient field if set, and ignores cert configs in SystemContext fields, otherwise it use default http client from cert configs in SystemContext.

Add `HTTPClient` field into `types.SystemContext` to configure
http client by caller.  If the `HTTPClient` filed is set,
cert configurations are ignored in `types.SystemContext` on fetching
images.
@rhatdan
Copy link
Member

rhatdan commented Dec 11, 2018

@vrothberg PTAL

@vrothberg
Copy link
Member

Thanks for the PR. It's an interesting idea to move that into the API!

We have a highly related discussion over at containers/buildah. I think we can extend the ideas over there to fit your needs in the API as well. However, we need to be careful to not introduce too many ways of configuring proxies.

@ueokande could you have a look at the linked issue and share your thoughts there?

@ueokande
Copy link
Author

@vrothberg
We don't use buildah, and import containers/image library instead.

In our scenario, updater tools deployed in the data-center fetches newer container image via HTTP proxy.
I think setting HTTP client is practical requirement. Some API client such as GitHub client has attribute of the configurable *http.Client. That is usable not only setting HTTP proxy but also setting throttle, compression, and so on.

We currently use os.Setenv() hacks to set HTTP proxy in the updater tool (see here).

Copy link
Member

@vrothberg vrothberg left a comment

Choose a reason for hiding this comment

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

@ueokande, sorry for the late response, I lost this PR from my radar.

LGTM, just a minor nitpick, also you need to sign the commits (git commit -s).

@mtrmac WDYT?


// newHTTPClient returns new http client for docker client. It returns HTTPClient in SystemContext if set,
// otherwise returns default client.
func newHTTPClient(sys *types.SystemContext, registry, hostName, reference string) (*http.Client, error) {
Copy link
Member

Choose a reason for hiding this comment

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

Could we document the arguments as for newDockerClient?

@mtrmac
Copy link
Collaborator

mtrmac commented Jan 14, 2019

I don’t really like this… in the sense that the vast majority of clients should not need to care at this low level (notably we definitely don’t want Buildah/podman to have its own code to deal with proxies; that should be handled for them transparently in c/image).

If a typical client of c/image needed to set its own http.Client, that would clearly be a sign that c/image is not doing what it should do.

Of course, that does not automatically mean that there can’t be exceptional clients that would benefit from this capability — but once we add this option, we will lose the feedback channel because callers who find c/image insufficient can just use its own http.Client without telling us.

In this case, wouldn’t it be enough to add a HTTPProxy func(*Request) (*url.URL, error) option, to be set by c/image in the created http.Transport? OTOH…

That is usable not only setting HTTP proxy but also setting throttle, compression, and so on.

is true as well.

I’m honestly unsure.

Copy link
Collaborator

@mtrmac mtrmac left a comment

Choose a reason for hiding this comment

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

(Just noting smaller issues I have noticed, this does not automatically mean that overall I think this should be merged.)

var httpClient *http.Client
if url.Scheme != "unix" {
if url.Scheme == "http" {
if sys.HTTPClient != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

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

sys == nil is always valid, and must be treated the same as &types.SystemContext{}.

DirForceCompress bool

// HTTPClient is the HTTP client to use. If the HTTPClient field is not nil,
// the docker client is created with HTTPClient, and the below cert
Copy link
Collaborator

Choose a reason for hiding this comment

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

This does not apply only to “docker”, and it should be in the “Global configuration overrides” section.


// HTTPClient is the HTTP client to use. If the HTTPClient field is not nil,
// the docker client is created with HTTPClient, and the below cert
// config are ignored.
Copy link
Collaborator

Choose a reason for hiding this comment

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

There are no options “below” — and while this makes sense in a way, it can lead to surprising behavior changes.

@mtrmac
Copy link
Collaborator

mtrmac commented Jan 14, 2019

After reading the code in more detail: the way HTTPClient overrides so many other SystemContext options — although it does make sense, if the client is overridable at all, it must be overridable completely — this can lead to very surprising results where important security-related options can be silently ignored.

That’s another point in favor of a more localized HTTPProxy option. Or, maybe, instead of having a straight override which just replaces the http.Client, there could be an “edit hook” (vaguely similar to httpWrapper in #254), which would still leave all of the options supported and used by default, but allow callers to make specific localized edits to the http.Client without affecting the other options — but callers still could replace the implementation wholesale if they really wanted to.

(Still unsure, but leaning much more towards a more targeted option. I’d love to head what others think as well.)

@vrothberg
Copy link
Member

I think @mtrmac makes some good points, especially regarding the subtleties regarding security. A more targetted/dedicated option to support proxies via the API might be easier to handle than a complete http client. @runcom @rhatdan PTAL.

@rhatdan
Copy link
Member

rhatdan commented Jan 14, 2019

I agree this should be done in containers/image not in any of the packages that use containers/image.

@rhatdan
Copy link
Member

rhatdan commented Mar 8, 2019

What is the state of this PR?

@jamescassell
Copy link

I'd argue that the primary method of configuring the system to use a HTTP Proxy should be to use the http_proxy, https_proxy, and no_proxy environment variables. A competent sysadmin should set these system-wide so that they are automatically set for all users and services in the case that they are needed. As long as c/image honors those settings, I'm indifferent whether any other method is supported for setting a proxy.

@rhatdan
Copy link
Member

rhatdan commented Apr 25, 2019

@ueokande Are you still interested in this PR?

@ueokande
Copy link
Author

Sorry for replying so late.

I noticed that the design is not so good. Adding HTTPClient parameter brings duplicated TLS configurations in SystemContext. They are confusing for users.

Additionally, some methods create an HTTP client by &http.Client{}. If HTTPClient is added, we fix all of them and it makes huge changes on the behavior.

Thanks for the duscuttion, but I am inclined to close this PR once.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants