faradayio / cage

Develop and deploy complex Docker applications
http://cage.faraday.io
Apache License 2.0
307 stars 26 forks source link

What about Windows? #38

Closed emk closed 7 years ago

emk commented 7 years ago

Windows supports Docker! There are two potential use cases here:

  1. Linux containers. You can run Linux containers using Docker for Windows. This has some pretty seriously limitations, mostly related to working with container source code. In particular, two problems come up frequently: (1) git for Windows will check out text files using Windows line endings by default, which breaks container builds. (2) Windows can't represent the +x bit marking files as executable, which means that scripts built into the container will generally not be runnable.
  2. Windows containers. Windows now supports Windows guests! I've never used this but it sounds interesting. But to support this, we'd need contributions from somebody who actually uses Windows containers for real projects, and we'd need to verify that docker-compose works for this scenario. If you have experience with this, please feel to chime in!

In addition to the limitations mentioned above, cage itself has one limitation that affects use case (1) significantly:

If there's demand for cage on Windows, we'd love to see it happen. But this would almost certainly require contributions from somebody who uses Docker under Windows.

Initial Windows port

dudymas commented 7 years ago

sorry for the stream of consciousness comment earlier... here's a better synopsis:

I can build cage on windows with cygwin and some help from openssl binaries online.

At this point, it's easiest to start with just putting documentation down for how to manually build on windows. Building on travis won't be easy until rust's backtrace stuff works on mingw. As such I would either recommend:

Thoughts?

emk commented 7 years ago

Wow! I'm impressed you got it to run on Windows so quickly! This is great.

Based on what I remember, MinGW is a lot better for building "normal" standalone binaries than Cygwin, so if it comes down to a choice between the two, I have a slight bias towards MinGW. But if Cygwin is much easier to get building, I'm OK with with looking at that and at least having written instructions.

If disabling backtrace makes things simpler, than I'm heavily in favor of disabling backtrace. We mostly only use backtrace to figure out why certain error messages are missing useful context, so it's not essential. I'm OK with adding Cargo "features" to cage to control backtrace support, or with submitting PRs upstream to error-chain. We can also add a flag to disable vault support, which will remove the dependency on OpenSSL.

As for automated builds, I'd prefer Travis if we can make it work using MinGW and no backtrace. I can help mess around with this some, too.

Anyway, these are just my quick scattered reactions, and I'm definitely very much open to suggestions about how to make this easier. I'll have some more time this weekend to think more about this, and maybe help out if I can. Thank you very much for taking an interest in Windows!

emk commented 7 years ago

This looks like the upstream pull request that we would need to convince the error chain maintainers to merge if we wanted to support MinGW without backtrace: https://github.com/brson/error-chain/pull/45

emk commented 7 years ago

OK. I've had a few more minutes to think about this, and I'd like to propose a plan. Your feedback is very welcome! 😀

First of all, here's what I'd like to propose for minimum QA requirements for a Windows port:

If that's the goal, here's one way we could approach it:

Any thoughts? Do these seem like good first steps?

dudymas commented 7 years ago

The plan sounds good. In case you're wondering, I spent the last 6 hours trying to get the cygwin stuff to work on other windows setups... no good. I just started on a lucky machine. 64bit is wrecking havoc... I'm not sure why, but no matter how hard I try, the rust openssl stuff demands 32bit. I can fudge it by renaming dll's to have 32 in their names, but I'm pretty confident the code will end up blowing up and somehow I just have a new bug I discovered in the linker (who would have thought).

So... my early confidence seems remiss. I'm going to work on seeing if I can get a pure 32bit build working now... (hilariously enough, miniz-sys is fighting THAT and only wants 64bit no matter how hard I try to tell it not to. I guess the rust compiler and cargo just assume a competent toolset and don't pass along my env-vars?). If I get that up and going, most of this should be golden.

Let me know if you need any of my artifacts, as otherwise I hate to trouble you with a pile of bash/powershell scripts that are choked with distant references to anime and robot chicken (they really are awful, and my setup for getting the 64bit build to work 30% of the time is now closer to 5%. And I was pretty much just copying my bash history from docker containers for the ubuntu stuff and passing it through sed 's/f-bomb/hooray/g' ). I'm pretty sure I'll need to set up a sed script or something else to mess with the cargo lock file if we want an automated build that drops backtrace... The error that backtrace gave me was that it could not find the 'cc' command... which seemed to mean it was trying to use the standard linux tooling rather than the mingw tools.

All in all, this sounds fun! I'll see how far I get with the first three checkboxes/tasks.

dudymas commented 7 years ago

so after a large run around... I find that actually, legit... openssl libraries for windows are utterly borky mccorgi... see https://github.com/sfackler/rust-openssl/issues/442

I'm currently working on a proper write-up, because after following these steps it seems like the machines are rather happy... shrug a minor miracle at this point

dudymas commented 7 years ago

Yep... following their advice is working out dandy. I'll feed back in my own two cents. hooray:

image

dudymas commented 7 years ago

because the library names actually change on windows between binary distributions... wow... I guess it makes sense to literally tell people to rename the lib files. Time for some 🍶

dudymas commented 7 years ago

cargo test got interesting:

failures:
    cmd::compose::runs_docker_compose_on_all_pods
    cmd::compose::runs_docker_compose_on_named_pods_and_services
    cmd::exec::invokes_docker_exec
    cmd::exec::runs_shells
    cmd::logs::runs_docker_compose_logs
    cmd::pull::runs_docker_compose_pull_on_all_pods
    cmd::run::runs_a_single_service_pod
    cmd::run::runs_tests
    cmd::run::runs_tests_with_custom_command
    cmd::up::runs_docker_compose_up_honors_enable_in_targets
    command_runner::os_command_runner_runs_commands
    command_runner::test_command_runner_logs_commands
    hook::runs_requested_hook_scripts
    plugins::transform::abs_path::converts_relative_paths_to_absolute
    project::new_from_example_uses_example_and_target
    project::output_applies_expected_transforms
    project::output_mounts_cloned_libraries
    sources::can_be_cloned

test result: FAILED. 41 passed; 18 failed; 0 ignored; 0 measured

error: test failed

C:\Users\jwhite\Code\cage>docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
dudymas commented 7 years ago

Okay more on this, apparently docker-compose still does not support interactive mode on windows.

BUT! Someone got a PR in that fixes this about a month ago https://github.com/docker/compose/pull/3980 So now when the next docker-compose release comes out, there should be a chance for us to retest this and get the fellow working fully. And hopefully by then we should see rustc-openssl stabilize (or at least be a little less brittle)

emk commented 7 years ago

OK, let's make your life a bit easier! I've added support for building without OpenSSL. Just run:

cargo build --no-default-features --features default_minimal

This will disable the Vault plugin, but it will remove the dependency on OpenSSL. Next I'm going to try to set up a MinGW cross compiler and see how far I make it.

As for the unit tests, the plugins::transform::abs_path::converts_relative_paths_to_absolute is a dead giveaway: It looks like we have some sort of pathname representation issues. This might mean that we're seeing / replaced by \, making test suites fail. If this is case, I can fix that relatively easily, so don't worry about it.

As for the rest of the test suites, let's leave that aside for now. It's too much to bite off at once. Let's start with a simpler question: Can you go through the tutorial in README.md? What works? What breaks?

emk commented 7 years ago

OK, we have some cross-compilation progress targetting MinGW from a Linux host! Here are the basic steps.

This will get you almost there:

sudo apt install gcc-mingw-w64-x86-64
rustup target add x86_64-pc-windows-gnu
cargo build --target x86_64-pc-windows-gnu --no-default-features --features default_minimal

But you'll get an error message as seen in https://github.com/rust-lang/rust/issues/33465. You can work around this with:

cargo rustc --bin cage --target x86_64-pc-windows-gnu --no-default-features --features default_minimal -- -C linker=x86_64-w64-mingw32-gcc

There's probably some way to set this up correctly in Cargo.toml, but I don't know it yet.

When run, this will produce a target/x86_64-pc-windows-gnu/debug/cage.exe file that I haven't tried in any way, shape or form. But it compiles (including libbacktrace), and it's pretty easy to reproduce with just a few shell commands.

I'm going to see if I can get it to use the correct linker automatically.

dudymas commented 7 years ago

Thanks for the new build features. I'll try them out in a bit... and very cool that you got the windows-gnu build to work on ubuntu/debian. Sounds like travis builds will be a shoe in.

The tutorial won't work until the interactive docker-compose fix hits in their next version. I'm trying to get more details on that. Otherwise, I guess I'll do a quick writeup on how to get where I got last night, and start a new PR.

emk commented 7 years ago

Ah, this works without errors, at least:

sudo apt install gcc-mingw-w64-x86-64
rustup target add x86_64-pc-windows-gnu
cargo build --lib --target x86_64-pc-windows-gnu --no-default-features --features default_minimal
cargo rustc --bin cage --target x86_64-pc-windows-gnu --no-default-features --features default_minimal -- -C linker=x86_64-w64-mingw32-gcc

Now, if you're compiling on Windows with a native MinGW Rust toolchain, you can probably just try:

cargo build --no-default-features --features default_minimal

...and you shouldn't need to set up cross-compilation and mess with the linker. At the very least, it's a good starting point.

By the way, we also gitter chat room. Depending on the time of day, you may be able find me online there and ask questions in real time.

The tutorial won't work until the interactive docker-compose fix hits in their next version.

How does the tutorial fail? Is it just the shell command? Or is it other stuff which breaks? If most stuff mostly works except for that bug, then we're in pretty good shape.

What I'm really curious about is cage source mount rails_hello; cage up, creating src/rails_hello/public/index.html, and reloading the page. If that works, then the essentials are there and we can deal with the other stuff later.

emk commented 7 years ago

OK, it should now be possible to build optimized MinGW binaries using Ubuntu 16.04 as follows:

sudo apt-get install gcc-mingw-w64-x86-64
curl https://sh.rustup.rs -sSf | sh
rustup target add x86_64-pc-windows-gnu
cargo build --release --target x86_64-pc-windows-gnu --no-default-features --features default-minimal

...without any errors. I have no idea how well these binaries work.

I believe that @dudymas is trying to figure out how to get a native build under Windows using MinGW and msys.

emk commented 7 years ago

This got closed automatically by merging the initial Windows support, but we're still not done. Re-opening!

emk commented 7 years ago

I'm going to give you a way to build cage without OpenSSL. That means no vault integration on Windows, but that's a pretty specialized feature anyway.

emk commented 7 years ago

OK, all the tests are passing on Windows! I'm going to close this tracking issue and we can file bugs if we find any specific limitations.

Many thanks to @dudymas for all his aid getting this working!