{"action":"created","issue":{"url":"https://api.github.com/repos/docker/docker/issues/29048","repository_url":"https://api.github.com/repos/docker/docker","labels_url":"https://api.github.com/repos/docker/docker/issues/29048/labels{/name}","comments_url":"https://api.github.com/repos/docker/docker/issues/29048/comments","events_url":"https://api.github.com/repos/docker/docker/issues/29048/events","html_url":"https://github.com/docker/docker/pull/29048","id":193005114,"number":29048,"title":"Proposal - Incomplete POC - Builder GETENV","user":{"login":"jhowardmsft","id":10522484,"avatar_url":"https://avatars.githubusercontent.com/u/10522484?v=3","gravatar_id":"","url":"https://api.github.com/users/jhowardmsft","html_url":"https://github.com/jhowardmsft","followers_url":"https://api.github.com/users/jhowardmsft/followers","following_url":"https://api.github.com/users/jhowardmsft/following{/other_user}","gists_url":"https://api.github.com/users/jhowardmsft/gists{/gist_id}","starred_url":"https://api.github.com/users/jhowardmsft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jhowardmsft/subscriptions","organizations_url":"https://api.github.com/users/jhowardmsft/orgs","repos_url":"https://api.github.com/users/jhowardmsft/repos","events_url":"https://api.github.com/users/jhowardmsft/events{/privacy}","received_events_url":"https://api.github.com/users/jhowardmsft/received_events","type":"User","site_admin":false},"labels":[{"id":175374554,"url":"https://api.github.com/repos/docker/docker/labels/status/0-triage","name":"status/0-triage","color":"EEEEEE","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2016-12-02T00:54:20Z","updated_at":"2016-12-02T01:51:03Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/docker/docker/pulls/29048","html_url":"https://github.com/docker/docker/pull/29048","diff_url":"https://github.com/docker/docker/pull/29048.diff","patch_url":"https://github.com/docker/docker/pull/29048.patch"},"body":"Signed-off-by: John Howard <jhoward@microsoft.com>\r\n\r\n@duglin - defacto/actual builder maintainer :smile:\r\n\r\nThis is a very rough and incomplete prototype to throw the idea out. I'm trying to solve a very real problem with is more predominant in Windows, but also applicable to Linux. The current sample implementation is Windows only though at the moment.\r\n\r\nhttps://github.com/docker/docker/issues/22017 is one such example. And it's compounded when using nanoserver - see this workaround as a more extreme example: https://github.com/Microsoft/Virtualization-Documentation/blob/live/windows-container-samples/golang/Dockerfile#L24\r\n\r\nOn Linux, `$PATH` is defaulted, which for various reasons, on Windows cannot (and shouldn't) be done reliably. Hence in an image, `ENV` by default is blank in Windows, but has a couple of defaults on Linux. For variable substition in a Dockerfile, users expect to be able to do `ENV PATH c:\\myapp\\bin;$PATH` and it \"just works\". Unfortunately in the current docker engine design, the `$PATH` in that `ENV` statement is substituted from the configuration, not from the actual container itself. So on Windows, the PATH would end up as just `c:\\myapp\\bin`, which is clearly incorrect.\r\n\r\nSo what does this PR do (and what could/should it be extended to do)?\r\n\r\nIt introduces a new builder instruction `GETENV`. Currently all it does is get all the environment variables out of the container and print them to the console. The next step would be parsing them in key=value pairs and updating the configuration accordingly. \r\n\r\nIn reality, we probably want to be more restrictive, take into account `SHELL` and so on. So I (aspirationally, but very hard as I will comment on shortly) envisage something more like:\r\n\r\n`GETENV var1,var2,var3` which equates to (using default shell) `cmd /s /c set var1 var2 var3` or some equivalent Linux command. Unfortunately the cmd.exe shell in Windows if you say `set PATH` will actually return all variables starting PATH (including `PATHEXT`). Boo. From `set /?`:\r\n\r\n```\r\nSET command invoked with just a variable name, no equal sign or value\r\nwill display the value of all variables whose prefix matches the name\r\ngiven to the SET command.  For example:\r\n\r\n    SET P\r\n\r\nwould display all variables that begin with the letter 'P'\r\n```\r\n\r\nThat said, it doesn't look like sh and `export` is much better...  In PowerShell, it could be done though for example as:\r\n\r\n```\r\nPS E:\\go\\src\\github.com\\docker\\docker> Get-Childitem env:PATH | %{Write-Host \"$($_.Name)=$($_.Value)\"}\r\nPath=e:\\go;e:\\docker\\utils;e:\\go\\bin;C:\\Git\\usr\\bin;e:\\go\\src\\github.com\\docker\\docker\\bundles;c:\\gcc\\bin;c:\\pstools;c:\\Program Files\\Notepad++;c:\\CIUtilities;c:\\git\\cmd;c:\\git\\bin;c:\\git\\usr\\bin;c:\\gcc\\bin;c:\\go\\bin;c:\\liteide\\bin;C:\\Windows\\system32;C:\\Windows;C:\\Windows\\System32\\Wbem;C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C:\\Users\\Administrator\\AppData\\Local\\Microsoft\\WindowsApps;c:\\gopath\\bin;e:\\docker\\utils;C:\\Windows\\system32\\config\\systemprofile\\AppData\\Local\\Microsoft\\WindowsApps;C:\\git\\cmd;C:\\git\\mingw64\\bin;C:\\git\\usr\\bin;C:\\Users\\Administrator\\AppData\\Local\\Microsoft\\WindowsApps;;C:\\Program Files (x86)\\Microsoft VS Code\\bin\r\nPS E:\\go\\src\\github.com\\docker\\docker>\r\n```\r\n\r\nIn reality, it's more likely that only a very small subset of variables are wanted, so limiting it to a single variable isn't really that limiting. \r\n\r\nI can imagine (fairly simple extension) having a JSON form of the command as well. So\r\n\r\n`GETENV path` is equivalent to `current shell` `default getter-command` and\r\n`GETENV [\"cmd\", \"/s\", \"/c\", \"set\", \"path\"]` and\r\n`GETENV [\"sh\", \"-c\", \"export\", \"PATH\"]` and\r\n`GETENV [\"powershell\", \"-command\", \"Get-ChildItem env:PATH | ${Write-Host \"$($_.Name)=$($_.Value)\"]`\r\n\r\nare all functionally equivalent.\r\n\r\nRemember this proposal isn't exclusively about PATH. It could be applied to any variable, and I can imagine there are some images out there which do have environment variables configured which aren't explicitly in the configuration which may need to be appended to and be able to use environment variable substitution inside a dockerfile.\r\n\r\nSo anyway, taking the PATH example, rather than the current workaround necessary on Windowsservercore (simpler than nanoserver - see link at top), rather than (taken from Dockerfile.windows)\r\n\r\n```\r\nFROM microsoft/windowsservercore\r\nSHELL [\"powershell\", \"-command\"]\r\nRUN ...; `\r\n  setx /M PATH $('C:\\git\\bin;C:\\git\\usr\\bin;'+$Env:PATH+';C:\\gcc\\bin;C:\\go\\bin'); `\r\n  $env:PATH = 'C:\\gcc\\bin;$env:PATH'; `\r\n  `\r\n...\r\n```\r\n\r\nyou would be able to do the following which is (IMO) a lot cleaner, and would work on nanoserver without the additional Windows registry key workaround:\r\n\r\n```\r\nFROM microsoft/windowsservercore\r\nGETENV PATH\r\nENV PATH c:\\git\\bin;<other paths>;$PATH\r\nRUN ...\r\n```\r\n\r\n@friism @StefanScherer @thaJeztah @jstarks @tianon FYI"},"comment":{"url":"https://api.github.com/repos/docker/docker/issues/comments/264351655","html_url":"https://github.com/docker/docker/pull/29048#issuecomment-264351655","issue_url":"https://api.github.com/repos/docker/docker/issues/29048","id":264351655,"user":{"login":"jhowardmsft","id":10522484,"avatar_url":"https://avatars.githubusercontent.com/u/10522484?v=3","gravatar_id":"","url":"https://api.github.com/users/jhowardmsft","html_url":"https://github.com/jhowardmsft","followers_url":"https://api.github.com/users/jhowardmsft/followers","following_url":"https://api.github.com/users/jhowardmsft/following{/other_user}","gists_url":"https://api.github.com/users/jhowardmsft/gists{/gist_id}","starred_url":"https://api.github.com/users/jhowardmsft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jhowardmsft/subscriptions","organizations_url":"https://api.github.com/users/jhowardmsft/orgs","repos_url":"https://api.github.com/users/jhowardmsft/repos","events_url":"https://api.github.com/users/jhowardmsft/events{/privacy}","received_events_url":"https://api.github.com/users/jhowardmsft/received_events","type":"User","site_admin":false},"created_at":"2016-12-02T01:51:03Z","updated_at":"2016-12-02T01:51:03Z","body":"@duglin - we could, but that would slow down build for everyone. Hence why I'd rather not do that (although it did occur to me as an option)"}}
{"actor":{"display_login":"jhowardmsft"}}