Skip to content
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

What about Windows? #38

Closed
2 tasks
emk opened this issue Oct 21, 2016 · 18 comments · Fixed by #41
Closed
2 tasks

What about Windows? #38

emk opened this issue Oct 21, 2016 · 18 comments · Fixed by #41
Labels

Comments

@emk
Copy link
Contributor

emk commented Oct 21, 2016

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:

  • cage uses Rust's std::path type represent paths both outside and inside containers. This works fine as long as the host OS and the container OS use similar file naming conventions. But if we want to support Linux containers on a Windows system, then we'll need to figure out how to handle path names for two different OSes in a single Rust application, and convert between them as needed.

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

@emk emk added the RFC label Oct 21, 2016
@dudymas
Copy link
Contributor

dudymas commented Oct 21, 2016

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:

  • keeping it manual,
  • removing backtrace, or
  • (really scary) try to get cygwin working on travis (so far no evidence this is possible)

Thoughts?

@emk
Copy link
Contributor Author

emk commented Oct 21, 2016

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
Copy link
Contributor Author

emk commented Oct 21, 2016

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: rust-lang-deprecated/error-chain#45

@emk
Copy link
Contributor Author

emk commented Oct 21, 2016

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:

  • The test suites pass.
  • The tutorial in README.md works.

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

  • You submit a PR containing a WINDOWS.md file explaining how to build on Windows, and make sure the tutorial works.
  • I try to cross compile with MinGW and see what's up with backtrace.
  • I make it possible to disable OpenSSL using feature flags, which will work fine for 95% of users and greatly simplify porting.

Any thoughts? Do these seem like good first steps?

@dudymas
Copy link
Contributor

dudymas commented Oct 22, 2016

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
Copy link
Contributor

dudymas commented Oct 22, 2016

so after a large run around... I find that actually, legit... openssl libraries for windows are utterly borky mccorgi... see sfackler/rust-openssl#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
Copy link
Contributor

dudymas commented Oct 22, 2016

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

image

@dudymas
Copy link
Contributor

dudymas commented Oct 22, 2016

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
Copy link
Contributor

dudymas commented Oct 22, 2016

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
Copy link
Contributor

dudymas commented Oct 22, 2016

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 docker/compose#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 added a commit that referenced this issue Oct 22, 2016
@dudymas is trying to port `cage` to run under Windows, and he _might_
have found a way to finess the pathname issues by building using either
Cygwin or MinGW, which use Unix-style paths.  But getting OpenSSL to
build is a continual nuissance.

On top of that, OpenSSL is broken in our official Mac binary builds, and
must be re-enabled by building from source.

So this patch allows turning off our Vault support at compile time,
which in turn gets rid of our OpenSSL dependency.  Which in turn makes a
Windows port less stressful, and will allow us to build Mac binaries
that actually disable features that won't work.
@emk
Copy link
Contributor Author

emk commented Oct 22, 2016

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
Copy link
Contributor Author

emk commented Oct 22, 2016

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 rust-lang/rust#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
Copy link
Contributor

dudymas commented Oct 22, 2016

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
Copy link
Contributor Author

emk commented Oct 22, 2016

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
Copy link
Contributor Author

emk commented Oct 22, 2016

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 emk closed this as completed in #41 Oct 22, 2016
emk added a commit that referenced this issue Oct 22, 2016
windows support docs: Address #38
@emk
Copy link
Contributor Author

emk commented Oct 23, 2016

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

@emk emk reopened this Oct 23, 2016
emk added a commit that referenced this issue Oct 23, 2016
If we use `"/"` in `join` calls, it tends to break unit tests on
Windows.  This won't fix all the related test failures, but should get
us in the ballpark.
@emk
Copy link
Contributor Author

emk commented Oct 25, 2016 via email

@emk
Copy link
Contributor Author

emk commented Nov 14, 2016

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!

@emk emk closed this as completed Nov 14, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants