-
Notifications
You must be signed in to change notification settings - Fork 123
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
Windows Container support #96
Conversation
…onnection/docker.py
…/connection/docker.py
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.
Thanks for this contribution!
I can't review this fully since I don't have or use Windows; I'll mainly make sure that the code looks good and that it won't break the non-Windows side :-)
Two things:
- This needs a changelog fragment;
- Please remove the
display.debug
statements that dump stdout/stderr. This could accidentally dump secrets into logs where they do not belong.
* Added changelog fragment
@felixfontein Thank for the quick reply on my PR! |
Co-authored-by: Felix Fontein <felix@fontein.de>
…ins/connection/docker.py
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.
The non-Windows part of this PR looks good (i.e. it should not break anything ;) ).
@felixfontein Why are the RHEL 8.2 tasks in the CI pipeline are failing. Is this relevant to my PR? |
Co-authored-by: Brian Scholer <1260690+briantist@users.noreply.github.com>
@tmeckel the RHEL issues are unrelated to this PR, there seems to be something wrong with the setup of the VMs. I've pinged someone to investigate. |
The RHEL will be fixed by #97. |
Tests should now pass. Let's see :) |
recheck |
@briantist @jborean93 I plan to create a new release of community.docker on Monday or Tuesday next week (so it can get included in Ansible 3.1.0). If you don't manage to review the PR until then, I can also create another release once this is merged, so no pressure ;) |
I'm not sure I'll be able to actually run this to try it out unfortunately, certainly not before your next release. I'll see if I get a chance to try it out at some point |
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.
Some nice edge case stuff in the review but what you have here is pretty good.
I will highly recommend that tests be added as soon as possible, there are a few private functions and edge cases with Windows that are hard to keep track off without tests actually testing those scenarios.
local_cmd = self._build_exec_cmd([self._play_context.executable, '-c', cmd]) | ||
if getattr(self._shell, "_IS_WINDOWS", False): | ||
sudoable = False | ||
local_cmd = self._build_exec_cmd(["cmd", "/c", cmd]) |
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 might be wrong but I believe using cmd /c
here will mean any raw
task with the connection plugin will be using cmd
as the shell rather than PowerShell. You may want to change this based on whether the ansible_shell_type
is either cmd
or powershell
to allow a user to change this as they desire.
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.
@jborean93 yes this is true. Bit when I change the code as follows I receive a file not found
. So the interpreter (Powershell) cannot be found. So I suspect I didn't grasp what you meant by saying I should utilize the ansible_shell_type
. Any guidance?
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.
Do you know what the default shell is for a Windows container, i.e. what runs when you do docker exec ...
. Is it cmd or is it powershell.exe, or maybe no shell at all?
Basically right now if someone was to do the following
- raw: echo "hi"
Is that going to be running under cmd or powershell? With the current changes here that will be running as cmd
which might not be ideal if someone has set ansible_shell_type=powershell
. Maybe the desire is to have raw
with this connection plugin independent to the shell plugin used, if that's the case then the PR as it is makes sense. If you wish for this to be dependent on the shell plugin then you will have to hardcode cmd.exe /c
when using the cmd shell and powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command
for the powershell shell.
This might be something that @felixfontein may want to comment on.
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 don't think I can say something here. I've never used Docker with Windows containers, so I have zero experience what these contain.
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 mostly mean more in general, do you expect that raw
should match the ansible_shell_type
(powershell or cmd) or should it just be the same thing on the connection plugin?
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.
Matching ansible_shell_type
would be nice I guess, though I'm not even sure whether Linux containers fully support that (I've never really looked at shell plugins). I also have no idea how complicated it would be to 'properly' implement this.
@@ -308,11 +330,32 @@ def put_file(self, in_path, out_path): | |||
count = ' count=0' | |||
else: | |||
count = '' | |||
args = self._build_exec_cmd([self._play_context.executable, "-c", "dd of=%s bs=%s%s" % (out_path, BUFSIZE, count)]) | |||
if getattr(self._shell, "_IS_WINDOWS", False): | |||
cmd = '''& { $strm = [Console]::OpenStandardInput(1024) |
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 you use _encode_script
as per below you can skip the & { ... }
entirely and just run the command as is.
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.
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'm not sure what is happening here, the error you've shared is something that is thrown by the bootstrap_wrapper.ps1 which is used when executing a module. The code you have here is for copying a file to the docker container and shouldn't be calling the bootstrap_wrapper code.
if getattr(self._shell, "_IS_WINDOWS", False): | ||
cmd = '''& { $strm = [Console]::OpenStandardInput(1024) | ||
$data = [System.Array]::CreateInstance([byte],1024) | ||
$fstrm = [IO.File]::OpenWrite(%s) |
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.
You still need to have more logic to handle here. Right now at a quote glance I could have a path like:
’+ (&[ScriptBlock]::Create([[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String("my code to inject")) +’
Note the use of unicode smart quotes
PowerShell (un)helpfully treats a bunch of smart quotes as the same as single quotes so even if you ran shlex_quote
on your path it won't escape what is needed. As soon as you can escape outside of a quote you can embed whatever command you want to run here.
There are 2 choices I can see you moving to:
- Use a the same (or similar regex) to the ansible.windows quote filter for powershell to escape the smart quotes and give you a literal value
- Base64 encode the path and decode that in your script - base64 means you no longer have to deal with quotes or unicode characters
cmd = '''
...
$outPath = [Text.Encoding]::UTF8.GetString([Convert]::FromBase64String('%s'))
...
''' % (to_text(base64.b64encode(to_bytes(out_path, encoding='utf-8'))))
Both options remove the need for `shlex_quote` but I still recommend you normalize the path as you have done today.
There's one big problem with Windows container tests: someone has to create and maintain them. Since Windows containers cannot run on Linux, this requires the tests to run on Windows. Our CI (AZP) theoretically does support that, but we've never run tests on Windows for any of the docker plugins and modules yet. So this is far from simple to set up. |
Totally understand that problem, at a quick glance you could do what we did for testing SSH against Windows hosts. Still spin up an AWS EC2 instance for Windows Server 2019 and install the Containers feature and a running container. I'm not sure if it's possible to even expose the Docker port over the internet like that so that might be a no go. Ultimately it's up to you as the maintainers what you would like to have. I just know this is going to be painful to support going forwards without some kind of tests around it. |
If this were to be accepted, I have a CI pipeline for my organisation which would make use of these utilities for docker swarm creation and more. We use WinRM and Windows Server 2019 predominantly but resources to work with others since idempotent IasC is in it's infancy here. I was actually on my way to find out the views of me PRing the Therefore, watching this and stand ready to assist. |
@jimbo8098 I'm happy to merge this (once all review comments are addressed) also without Windows tests. We (or in particularly I :-) ) don't mind Windows-specific PRs - as long as they don't break other platforms. It would be great to have Windows tests in this repository as well; as long as we don't have them, Windows support in the modules is "use on your own risk, we try not to break it, but we won't notice in case we do". If your CI pipeline uses say the |
Just to add to my previous point, Our infrastructure is Windows Server 2019 hardware, not containers. I suspect the two should be the same in a CI environment if you are just building towards testing infra for this though some mechanisms of course might be a bit different. Will look to PR on |
@tmeckel do you have time to incorporate the latest review comments? It would be great if we could get this merged. |
@felixfontein sorry for the delay. Found some time to work on the comments of @jborean93 |
@tmeckel ping |
@felixfontein added comments. Awaiting answers from @jborean93 |
Docs Build 📝This PR is closed and any previously published docsite has been unpublished. |
SUMMARY
This PR contains changes to
docker.py
to support Windows Containers.ISSUE TYPE