{"action":"created","issue":{"url":"https://api.github.com/repos/docker/docker/issues/26936","repository_url":"https://api.github.com/repos/docker/docker","labels_url":"https://api.github.com/repos/docker/docker/issues/26936/labels{/name}","comments_url":"https://api.github.com/repos/docker/docker/issues/26936/comments","events_url":"https://api.github.com/repos/docker/docker/issues/26936/events","html_url":"https://github.com/docker/docker/pull/26936","id":179389454,"number":26936,"title":"Add --user-agent daemon flag","user":{"login":"jonjohnsonjr","id":17863526,"avatar_url":"https://avatars.githubusercontent.com/u/17863526?v=3","gravatar_id":"","url":"https://api.github.com/users/jonjohnsonjr","html_url":"https://github.com/jonjohnsonjr","followers_url":"https://api.github.com/users/jonjohnsonjr/followers","following_url":"https://api.github.com/users/jonjohnsonjr/following{/other_user}","gists_url":"https://api.github.com/users/jonjohnsonjr/gists{/gist_id}","starred_url":"https://api.github.com/users/jonjohnsonjr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jonjohnsonjr/subscriptions","organizations_url":"https://api.github.com/users/jonjohnsonjr/orgs","repos_url":"https://api.github.com/users/jonjohnsonjr/repos","events_url":"https://api.github.com/users/jonjohnsonjr/events{/privacy}","received_events_url":"https://api.github.com/users/jonjohnsonjr/received_events","type":"User","site_admin":false},"labels":[{"id":175375318,"url":"https://api.github.com/repos/docker/docker/labels/status/1-design-review","name":"status/1-design-review","color":"fef2c0","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":6,"created_at":"2016-09-27T03:30:42Z","updated_at":"2016-11-03T23:32:25Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/docker/docker/pulls/26936","html_url":"https://github.com/docker/docker/pull/26936","diff_url":"https://github.com/docker/docker/pull/26936.diff","patch_url":"https://github.com/docker/docker/pull/26936.patch"},"body":"**\\- What I did**\n\nAdded `--user-agent` flag to daemon that adds an annotation to the User-Agent header.\n\nFor example, the flag `--user-agent \"my-annotation\"` yields this user-agent:\n\n`docker/1.13.0-dev go/go1.7.1 git-commit/c2a6ba7 kernel/3.13.0-95-generic os/linux arch/amd64 custom/my-annotation UpstreamClient(Docker-Client/1.13.0-dev \\\\(linux\\\\))`\n\nNote the new \"custom/my-annotation\". I'm open to suggestions on a better name than \"custom\" or a nice method for specifying the [product](https://tools.ietf.org/html/rfc7231#section-5.5.3). :)\n\nWhy is this useful?\n\nWe have multiple runtime environments using docker, but no simple way to distinguish between these environments and normal docker users (for analytics and debugging purposes). This flag solves that.\n\nAre you aware of the [HttpHeaders](https://docs.docker.com/engine/reference/commandline/cli/#/configuration-files) config property?\n\nYes. This isn't a great solution for us, since it requires modifying the client configuration file. AFAICT, there's no programmatic way to manipulate the client config file, so this isn't a particularly robust option. It's also much simpler to add this to the daemon than try to plumb it through clients, since we have more control over the daemon configuration.\n\n**\\- How I did it**\n\nTo make this a simpler change, I broke it into four commits.\n\nThe first two move context handling for the user-agent and docker version from `httputils` to `pkg/useragent` and `dockerversion`. I also renamed the functions to `NewContext` and `FromContext`, which [I believe is more idiomatic](https://blog.golang.org/context):\n- `getUserAgentFromContext` becomes `useragent.FromContext`\n- `httputils.VersionFromContext` becomes `dockerversion.FromContext`\n\nThe third commit re-centralizes the user-agent logic to effectively undo parts of #19057. That PR pulled the user-agent logic out of the `registry` package and added the user-agent as a parameter to a bunch of functions. In #21373, a context parameter was added back to most of those functions (or their callers), and an implicit dependency on the user_agent middleware (`api/server/middleware/user_agent.go`) was introduced; i.e. calls to `dockerversion.DockerUserAgent` expect the user_agent middleware to have previously populated ctx with the upstream client's user-agent.\n\nI think it's cleaner to have the user_agent middleware just construct the user-agent and add it to the context instead. This makes `dockerversion.DockerUserAgent`'s dependency on the user_agent middleware explicit and IMO makes it much simpler to reason about how the user-agent is constructed, since it all happens in one place. As a happy side effect, we can remove the user-agent parameter from any functions that take a context.\n\nThe final commit actually adds the flag. I'm happy to squash these into one commit or break them apart into multiple PRs -- not sure what the protocol is.\n\n**\\- How to verify it**\n\nRun the integration test:\n\n```\nTESTFLAGS='-check.f DockerRegistrySuite.TestUserAgentPassThrough' make test-integration-cli\n```\n\nOr start dockerd with the flag:\n\n```\ndockerd --user-agent \"my-annotation\" &\n```\n\nand check the logs of a push against a local registry:\n\n```\ndocker run -d -p 5000:5000 registry:2 && \\\n docker pull busybox && \\\n docker tag busybox localhost:5000/busybox && \\\n docker push localhost:5000/busybox && \\\n docker logs `docker ps -q` # assuming no other running containers\n```\n\nYou should see \"custom/my-annotation\". \n\n**\\- Description for the changelog**\n\nAdd `--user-agent` daemon flag to annotate the user-agent with additional info (for debugging, analytics).\n\n**\\- A picture of a cute animal (not mandatory but encouraged)**\n\nSay hi to Toxic!\n\n![803730612_64614](https://cloud.githubusercontent.com/assets/17863526/18856877/d2507e3e-8413-11e6-9344-00b38e007125.jpg)\n"},"comment":{"url":"https://api.github.com/repos/docker/docker/issues/comments/258305212","html_url":"https://github.com/docker/docker/pull/26936#issuecomment-258305212","issue_url":"https://api.github.com/repos/docker/docker/issues/26936","id":258305212,"user":{"login":"LK4D4","id":101445,"avatar_url":"https://avatars.githubusercontent.com/u/101445?v=3","gravatar_id":"","url":"https://api.github.com/users/LK4D4","html_url":"https://github.com/LK4D4","followers_url":"https://api.github.com/users/LK4D4/followers","following_url":"https://api.github.com/users/LK4D4/following{/other_user}","gists_url":"https://api.github.com/users/LK4D4/gists{/gist_id}","starred_url":"https://api.github.com/users/LK4D4/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/LK4D4/subscriptions","organizations_url":"https://api.github.com/users/LK4D4/orgs","repos_url":"https://api.github.com/users/LK4D4/repos","events_url":"https://api.github.com/users/LK4D4/events{/privacy}","received_events_url":"https://api.github.com/users/LK4D4/received_events","type":"User","site_admin":false},"created_at":"2016-11-03T23:32:25Z","updated_at":"2016-11-03T23:32:25Z","body":"@runcom @mattmoor @j0hnst0n so, what do you think about additional headers?"}}
{"actor":{"display_login":"LK4D4"}}