nut
nut copied to clipboard
Add support for Windows
Their is one short platform dependent file to implement in module github.com/fgrehm/go-dockerpty
: term_PLATFORM.go
Probably some other modifications, especially when filepath.Join
is called: since it will be compiled for Windows, but targets container path (linux) half the time, errors are to be expected.
I forked and updated github.com/fgrehm/go-dockerpty
in github.com/matthieudelaro/go-dockerpty
(see PR).
Nut branch supportwindows now uses the fork, so it compiles for Windows properly. Does anyone have a Windows 10 + Docker for Windows running to give it a try?
I also added https transport so that it can be tested against Docker Toolbox on Windows, but I doubt it will work since attach fails with Docker Toolbox on OSX.
Here is how to test Nut with Docker for Windows, on Windows 10:
Move to branch supportwindows
# Build Nut for Windows, in a container
docker run -i -t --rm -v $PWD:/go/src/github.com/matthieudelaro/nut -w /go/src/github.com/matthieudelaro/nut golang:1.6 env GOOS=windows GOARCH=amd64 go build -o nut
Expected bugs:
- Nut uses filepath packages to build paths of volumes to mount in the container, and to set up the working directory. On Windows, those path should look like C:\some\path, whereas those should be given to the container as /some/path.
- so far, Docker for Windows does not support volumes, so Nut can't mount volumes for the project
Here is how to test Nut with Docker Toolbox, on Windows:
Move to branch supportwindows
# Build Nut for Windows, in a container
docker run -i -t --rm -v $PWD:/go/src/github.com/matthieudelaro/nut -w /go/src/github.com/matthieudelaro/nut golang:1.6 env GOOS=windows GOARCH=amd64 go build -o nut
Nut should be able to connect to Docker daemon using Docker Machine variables, pull images automatically, and start container. But: Expected bug:
- as with Docker for Windows, there should be the bug of filepath
- as with Docker Toolbox on OSX, there should be a bug to attach to the container (see Add support for Docker Toolbox #5)
- there should also be the bug of GUI, maybe for the same reason
Fix filepath
I think that a fix is to create some containerFilePath
package, which behaves as provides same features as path/filepath
package (filepath.Abs(), filepath.Join(), filepath.Base(), filepath.Dir()), but always with proper paths for linux, even when compiled on Windows.
Fix attach
First make sure where the issues comes from. I think it comes from fsouza/go-dockerclient#126 (Nut uses this library to connect to Docker Daemon). If so, then good fix is to help fix go-dockerclient.
The source code of path/filepath
is available here : https://golang.org/src/path/filepath/
I think we can copy/paste the code dedicated to linux into a subpackage of nut, called nut/filepathLinux
. Then, in the source of Nut, use nut/filepathLinux
instead of path/filepath
when it comes to paths for the container, and keep using path/filepath
when it comes to paths for the host.
Nut compiles and partially runs on Windows! Since Nut supports Docker Toolbox on OSX, it also got closer to supporting Docker Toolbox on Windows.
What works
- parse configuration
- init project
- load configuration from Github
- pull docker image
What fails
- start and attach to container fails: “the parameter is incorrect”, even when there isn't any directory to mount in the container, and no working directory is specified.
(tested on Docker Toolbox, Windows 7)
Branch supportwindows
has been merged into master
, to leverage the support of connection over HTTPS on all platforms. So testing on Windows doesn't require to checkout anymore:
git clone https://github.com/matthieudelaro/nut.git —recursive
cd nut
docker run -i -t --rm -v $PWD:/go/src/github.com/matthieudelaro/nut -w /go/src/github.com/matthieudelaro/nut golang:1.6 env GOOS=windows GOARCH=amd64 go build -o nut
./nut --exec="echo hello world"
I'm able to compile it on Windows using the master branch. Using PowerShell, I adjusted the above command by using ${PWD}
and setting the output to nut.exe
.
docker run -i -t --rm -v ${PWD}:/go/src/github.com/matthieudelaro/nut -w /go/src/github.com/matthieudelaro/nut golang:1.6 env GOOS=windows GOARCH=amd64 go build -o nut.exe
PS C:\Users\cameron\go\src\github.com\matthieudelaro\nut> .\nut.exe
NAME:
nut - the development environment, containerized
USAGE:
C:\Users\cameron\go\src\github.com\matthieudelaro\nut\nut.exe [global options] command [command options] [arguments...]
VERSION:
0.1.2 dev
COMMANDS:
build macro: build the project
build-all, ba macro: build the project for linux, OSX, and for Windows
build-linux, bl macro: build the project for Linux
build-osx, bo macro: build the project for OSX
build-windows, bw macro: build the project for Windows
code macro: open this project in vscode
run macro: run the project in the container
test macro: test the project
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--clean clean all data stored in .nut
--init initialize a nut project
--github Use with --init: provide a GitHub repository to initialize Nut.
--logs Use with --exec: display log messages. Useful for contributors and to report an issue
--exec execute a command in a container.
--help, -h show help
--version, -v print the version
That looks good. However, trying out this throws an error:
PS C:\Users\cameron\go\src\github.com\matthieudelaro\nut> .\nut.exe --exec="echo hello world"
Could not inspect image golang:1.6 : Get http://unix.sock/images/golang:1.6/json: dial unix /var/run/docker.sock: socket: An a
ddress incompatible with the requested protocol was used.
Pulling image...
time="2016-05-17T11:58:43-07:00" level=error msg="Could not pull image golang:1.6: dial unix /var/run/docker.sock: socket: An
address incompatible with the requested protocol was used."
I have the latest Docker for Windows 1.11.1-beta11 installed.
Thanks for the test with Docker for Windows!
I assume that you don't get this issue with Docker Toolbox, right? It looks like it comes from here : https://github.com/matthieudelaro/nut/blob/master/network.go#L44
In case $DOCKER_HOST
environment variable is not defined, Nut assumes that you are not using Toolbox/Docker Machine, so it contacts docker host via docker socket. Which seems not to be addressable with unix:///var/run/docker.sock
on Windows.
However, according to this post, on Windows we can mount docker socket, just like on linux, with docker run -v /var/run/docker.sock:/var/run/docker.sock
, so there must be a way to use this file as host socket.
On OSX, when Docker for Mac is off, I get this error message:
Could not inspect image golang:1.6 : cannot connect to Docker endpoint
# which differs from your error on Windows:
Could not inspect image golang:1.6 : Get http://unix.sock/images/golang:1.6/json: dial unix /var/run/docker.sock: socket: An address incompatible with the requested protocol was used.
"incompatible with the requested protocol"... Maybe removing unix:///
would be worth a try? Also, I don't know what kind of socket is used in Docker for Windows, but probably not a pure unix socket. So maybe there is something to change here...
anyone with windows and node installed willing to try this command to see if it works?
npm install -g nut-bin
haven't tested it on windows yet
it should automatically put a pre-build binary of nut
in the path without needing to run docker commands and compile locally. But I'm not sure if I need to modify it by adding .exe
- or if that happens automatically. Based on @ctaggart 's fix I might need to include that file extension for windows
@RnbWd : I tried npm on Windows 10, which encounters issues in the installation process:
I also tried to compile and run nut on Windows 10, with Docker Toolbox:
- pulled with git on windows
- build on windows
- run in Git Bash, and in Command Prompt:
With Git Bash
The first issue in Git Bash on my installation is that docker run
yields the following bug: https://github.com/docker/toolbox/issues/136. As a result, I'm not sure I can expect Nut to work either. So I tested in Command Prompt:
With Command Prompt
docker run
works properly in this environment. The error message for Nut changes: it is not the handle which is incorrect, but the parameter.
I can't explain why the error log doesn't format \n
properly. I know there can be issues with new line characters in files when transferred from Unix world to Windows, but I think Git is has got a feature to do the translation. And anyway it is not really a new line, so... Could this weird behavior also affect the formatting of http request? Because there are only minimal parameters here.
oh, there's ways to normalize the paths between linux / windows, and I always see windows files ending in .exe
- right now it's like this:
module.exports = new BinWrapper()
.src(BASE + 'osx/nut', 'darwin')
.src(BASE + 'linux/nut', 'linux', 'x64')
.src(BASE + 'windows/nut', 'win32', 'x64')
.dest(path.join(__dirname, '../vendor'))
.use('nut')
It's using the default path
module, so that might need be normalized with windows (it's easy just requires a special fs package). And I probably need to add this line at the end:
.use(process.platform === 'win32' ? 'vault.exe' : 'vault');
so I can rename the file? or maybe it's a global npm permission thing? I assume it needs .exe
, but I don't know windows that well.
I don't know either :(
I'll assume yes... - but i'll start up a windows vm (or maybe window IOT for raspi) - or just try building it instead of linking a binary. I'm certain this is possible
Ok. It's not trivial to get a VM which can do emulation, so I created a Windows 10 VM in Virtual Box, which connects to the docker VM (both VM are running on the same host). Here is the recipe to connect them:
prepare VMs
- go to VM of docker (default) -> Settings -> Network -> Adapter 2 -> Promiscuous Mode : set to Allow VMs
- go to Windows VM -> Settings -> Network. Set Attached to = Host-Only Adapter, Name = vboxnet0, promiscuous mode: Allow All
- verify that Windows VM can ping docker VM
copy-paste certificates from osx to windows
- from /Users/matthieudelaro/.docker/machine/machines/default
- you may have to add read permissions to the files
- don't copy neither id_rsa nor id_rsa.pub
- to C:\Users\matthieudelaro.docker\machine\machines\vbox
set docker machine environment variables
# open cmd (not git terminal. See Note)
# for CMD
set DOCKER_HOST=tcp://192.168.99.100:2376
set DOCKER_TLS_VERIFY=1
set DOCKER_TOOLBOX_INSTALL_PATH=C:\Program Files\Docker Toolbox
set DOCKER_CERT_PATH=C:\Users\matthieudelaro\.docker\machine\machines\vbox
# for Git Bash
export DOCKER_HOST=tcp://192.168.99.100:2376
export DOCKER_TLS_VERIFY=1
export DOCKER_TOOLBOX_INSTALL_PATH="/C/Program Files/Docker Toolbox"
export DOCKER_CERT_PATH=/C/Users/matthieudelaro/.docker/machine/machines/vbox
test docker
docker run -it --rm golang /bin/bash # you are in !
Note
In case of error "cannot enable tty mode on non tty input", see https://github.com/docker/toolbox/issues/136
If you need to troubleshoot the connection: Windows 10 VM won't answer ping from Docker VM, but Docker VM answers ping from Windows 10 VM.
If this works properly for you as well, I may write a blog post for this, or add it to the wiki for contributors.
Okay I'll try this out - and my roommate has a windows machine too.. not sure if I can use the same code to get docker native but if virtual machine doesn't work I'll try his computer. (at my last job, we had to use windows for a printer driver, and our VM's were faster than the 'cheap windows laptop' we tried using initially. - the bindings for docker could be weird? But I know that the npm binary installation works (I relied on that heavily in the past)
edit: formatted with .exe
- not the exact code up right now but one line different.
not sure if I can use the same code to get docker native
Not sure it answers your question, but my recipe doesn't make use of Docker for Windows. It uses Docker Toolbox.
TL;DR: Nut v0.1.3 supports Windows :tada:
Here is a call to top
with Nut:
Details
So far Nut used to call docker api directly, without using docker cli at all. Now there is a flag --dockercli
to force Nut to use docker cli instead of using docker api itself. On Windows, this flag is ON by default.
I tested this in CMD on Windows 10, in a VM reaching another VM running boot2docker. I had issues in Git Bash (due to an issue of docker toolbox in this environment, under some circumstances: https://github.com/docker/toolbox/issues/136)
@RnbWd : I updated the manual build. For Windows, there are both nut
and nut.exe
, in case it's useful for npm.
sorry i was out of town I'll update it and test it on my roommates windows machine as well
Are GUI applications not supported on Windows yet? There's a workflow for running containerized GUI apps on Windows 10 that goes like this:
-
Start X Server (XMingW or Cygwin/X), with access control disabled and TCP transport. E.g. for Cygwin/X, you'd use:
XWin :0 -multiwindow -clipboard -wgl -ac -listen tcp
-
Start some container with the
DISPLAY
env var set to<docker NAT IP address>:0
. E.g. if you're in PowerShell, you can add the following to yourdocker run
invocation:-e DISPLAY=$(Get-NetIPAddress | ? { $_.InterfaceAlias -like '*docker*' -and $_.AddressFamily -eq 'IPv4' } | % { $_.IPAddress }):0
I have a bunch of scripts for this in my profile, but I was hoping there's some nice tool that encapsulates this stuff.
Hello @masaeedu ,
You're right, it's not implemented yet. This feature is implemented for OSX and for other unix systems in platform depend files.
The OSX version implements a workflow similar to the one you describe, in just a few lines. As for windows version, I never had the chance to dev Nut on a proper Windows installation, but I'm pretty sure that you could implement it quickly, using the other versions as an example. I think that this section of the wiki will help you. Hoping to see your PR soon :)
@matthieudelaro Alright then. What should be the strategy for installing X? Do you just expect it to be on the machine or install it yourself?
Great :)
For OSX, I assumed that it was already installed. But I didn't make any assumption about the configuration of X, so that it should work with any install.
So you could do the same, and simply provide instructions to install X on Windows. I don't feel confortable about forcing users to use a specific implementation of X. (However it may be required for you method, and in this case it should be explained in the instructions to use the feature on Windows.)