Skip to content
This repository has been archived by the owner on Mar 23, 2023. It is now read-only.

Adds support for docker-machine #77

Merged
merged 9 commits into from
Aug 10, 2015
Merged

Conversation

labianchin
Copy link
Contributor

Related to issue #50.
Although it is already working I'd still consider this as a preview.
It seems to be missing to update Readme, add tests and improve the install (e.g. add_environment_variables is not important for docker-machine).
Can you please provide some feedback? And also what would you expect to get this merged?

@brikis98
Copy link
Owner

Thanks for the pull request. I apologize for the delay, but I'm currently on the road with limited Internet access, so I'll take a look once I'm back (should be early August).

@ilkka
Copy link
Contributor

ilkka commented Jul 28, 2015

Since probably in almost all cases docker-osx-dev would be run against the active machine, I think you could drop the requirement to set the machine name environment variable on every invocation, and instead just use $(docker-machine active) to get it. Thoughts?

@labianchin
Copy link
Contributor Author

@brikis98, no problem, I still have to add some tests.

@ilkka, sorry getting ahead of you, but I needed it this week.
Correct, but there is the case where you can have multiple active docker-machines. What about passing the machine name as first argument?

docker-osx-dev machine-name

Also, I am trying to maintain compatibility with boot2docker. Later if needed we can drop support for it.

################################################################################

function get_json_val () {
python -c "import json,sys;sys.stdout.write(json.dumps(json.load(sys.stdin)$1))" | sed -e 's/^"//' -e 's/"$//'
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit concerned about adding a dependency on python. Any alternative way to do this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed! That is a hard one and I will have to think better on this. I saw it is possible to do with sed, grep and awk.
Some examples that I saw using grep actually use GNU grep, which is not always available on OSX. I am open to any suggestion.

@brikis98
Copy link
Owner

Thank you for the PR. This is a pretty massive change that forks the code in quite a few places. Do we know for sure that using boot2docker directly via the CLI is deprecated? Is docker-machine definitely the way to interact with Docker on the desktop in the future? If so, it's worth thinking about supporting only docker-machine. This project is hard to test (see #7), so I worry about any complications that fork the code too much.

@bgentry
Copy link

bgentry commented Jul 30, 2015

The boot2docker-cli deprecation notice is here: https://github.com/boot2docker/boot2docker-cli#pending-deprecation

I have used docker-machine locally on OS X and it seems to work just fine, not sure if there's any reason to keep supporting the boot2docker-cli instead. Maybe somebody from Docker or somebody that has more knowledge around that can chime in.

@brikis98
Copy link
Owner

Hmm, the Docker Docs still point to boot2docker and using it as a command line tool.

@labianchin
Copy link
Contributor Author

Thanks @brikis98 for the feedback!

I made some changes but, for me, there are at least two things outstanding:

  • Find an alternative to using python to parse docker-machine inspect json.
  • Add some automated tests

Regarding the boot2docker deprecation, my understanding is that it is slowly being deprecated. I'd suggest for now keeping support for both boot2docker and docker-machine. But in the near future, boot2docker support should be dropped.

@brikis98
Copy link
Owner

OK, let's keep the boot2docker support a bit longer. Let me know if you have ideas on the JSON & automated test front.

@ilkka
Copy link
Contributor

ilkka commented Aug 5, 2015

Correct, but there is the case where you can have multiple active docker-machines.

@labianchin, multiple active? I thought the active machine was determined by DOCKER_HOST in the env, meaning there can only be one?

@ilkka
Copy link
Contributor

ilkka commented Aug 5, 2015

just tried this branch again and noticed a weird thing: my freshly generated virtualbox docker machine has a config like this:

{
    "DriverName": "virtualbox",
    "Driver": {
        "IPAddress": "192.168.99.100",
        ...
        "SSHPort": 55045,
        ...
    }
   ...
}

which makes docker-osx-dev sync try to connect to port 55045, which fails. docker-machine ssh <machine> works just fine though, as does manually ssh'ing to port 22. I have no idea why that value is there or what it's significance is, but set up like this, the sync doesn't work.

@ilkka
Copy link
Contributor

ilkka commented Aug 5, 2015

Ah, now I understand what is happening with SSHPort: that's the port on localhost that the vbox SSH port is forwarded to. So if you're gonna use SSHPort for rsync, you should connect to localhost, not the docker machine itself.

@labianchin
Copy link
Contributor Author

@labianchin, multiple active? I thought the active machine was determined by DOCKER_HOST in the env, meaning there can only be one?

@ilkka, Yes. That makes more sense when you use a driver like EC2, OpenStack or GCE. This way you can have multiple docker-machine active (and running) in the cloud. You might want to have a docker-machine per each project you have.

So in one terminal tab you can run:

cd project-foo && docker-osx-dev --machine-name machine-for-project-foo

And in the other:

cd project-bar && docker-osx-dev --machine-name machine-for-project-bar

@labianchin
Copy link
Contributor Author

which makes docker-osx-dev sync try to connect to port 55045, which fails. docker-machine ssh works just fine though, as does manually ssh'ing to port 22. I have no idea why that value is there or what it's significance is, but set up like this, the sync doesn't work.

@ilkka Thanks for catching that! I was testing more with the openstack driver. There the SSHPort was 22. I will take a look on that. I guess I will have to understand better which params docker-machine ssh use.

@labianchin
Copy link
Contributor Author

@ilkka

So I was looking into what is the arguments docker-machine scp use, with the virtualbox driver it is this:

/usr/bin/scp [/usr/bin/scp -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=quiet -3 -i /Users/me/.docker/machine/machines/local/id_rsa foo.txt docker@192.168.99.100:/]

So, I just removed the -p argument for the rsync --rsh. Now should be fine.

But, one problem I am getting is that even after install_rsync_on_docker_host, and with rsync on /usr/local/bin it keeps getting -sh: rsync: not found.

It seems rsync 64bits is now available for tce-load: boot2docker/boot2docker#936 (comment). @brikis98, should we use it?

@ilkka
Copy link
Contributor

ilkka commented Aug 5, 2015

You might want to have a docker-machine per each project you have.

@labianchin ah yes, but since active is stored in the env, it is per terminal session, so you can run multiple machines that way too, just in separate terminals. Essentially it's the same. I don't mind having the parameter, I just think that defaulting to whatever docker-machine active outputs saves typing and is in no way surprising behaviour :)

But, one problem I am getting is that even after install_rsync_on_docker_host, and with rsync on /usr/local/bin it keeps getting -sh: rsync: not found.

I found that I had to docker-osx-dev install before it found rsync after restarting (but not recreating) my docker machine, although I might have been hallucinating from all the coffee 😅 Don't know if it's related at all.

@brikis98
Copy link
Owner

brikis98 commented Aug 5, 2015

@labianchin: Yes, if the 64 bit rsync is now working, we should go back to using tce-load to install it. I think the original code is still in the comments. I've been meaning to do this, but haven't had a chance to get to it, so PRs are welcome :)

@labianchin
Copy link
Contributor Author

@ilkka, that make sense. I agree that would be a good default. But if, for now, we are keeping the support for boot2docker, then it would be better to keep the default (no --machine-name arg) as using boot2docker.

Also, I just run docker-machine active and I get this:

dev

But when I run docker-machine ls:

NAME         ACTIVE   DRIVER       STATE     URL                         SWARM
dev                   virtualbox   Stopped
dev1                  virtualbox   Stopped
dokku-test            openstack    Running   tcp://10.254.132.163:2376
lbianchin2            openstack    Running   tcp://10.254.132.14:2376
local                 virtualbox   Running   tcp://192.168.99.102:2376

That is weird.

Fix port parameter in do_rsync
Install will add to host based on docker-machine name and ip
Install does not set the environment when using docker-machine
- pass --machine-name as argument, instead of env var
- ssh command working also for boot2docker ssh
- add_docker_environment_variables function that adds env vars only for
boot2docker
- add doc and rename get_json_value
}

#
# Configures variables based on a the docker-machine inspect from $DOCKER_MACHINE_NAME
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor typo: "a the"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@brikis98
Copy link
Owner

brikis98 commented Aug 6, 2015

@labianchin: Thanks! I just left a bunch more comments. Almost there.

@ilkka
Copy link
Contributor

ilkka commented Aug 6, 2015

@labianchin that docker-machine active behaviour is due to the slightly different ways active and ls determine the active host. active only looks at the value of DOCKER_HOST, but ls also checks that the host is running.

docker-machine start "$DOCKER_MACHINE_NAME"
eval $(docker-machine env "$DOCKER_MACHINE_NAME")
configure_docker_machine
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, here, this eval will run something like this:

export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.103:2376"
export DOCKER_CERT_PATH="/Users/someone/.docker/machine/machines/local"
export DOCKER_MACHINE_NAME="local"

We can see that DOCKER_MACHINE_NAME will be redefined.

Also, as in the docker-machine documentation, if the user runs eval "$(docker-machine env <machine-name>)", it will define the DOCKER_MACHINE_NAME to the env. Then if he runs docker-osx-dev, he would not need to pass the --machine-name argument.

I guess this is fine, I can add to the Readme.md about this behavior.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@labianchin
Copy link
Contributor Author

@brikis98 thanks for the feedback, I will be making the fixes.

@ilkka Please see this: #77 (comment)

So running eval "$(docker-machine env <machine-name>)" would mean the user does not need use the --machine-name argument.

@nathanleclaire
Copy link

One idea I've tinkered with is some kind of --delta flag to docker-machine scp which would shell out to rsync if available instead of scp. Would that be of interest to you / help your workload on this project?

@labianchin
Copy link
Contributor Author

Yes @nathanleclaire, I would be interested! Can you provide some details on what you have in mind? Probably via e-mail. Thanks!

@labianchin
Copy link
Contributor Author

@brikis98 I think I got all the suggested fixes in this last commit. Can you take a look?


#
# Read a json string from stdin and return the value of the key provided as first argument
# Uses head -n 1 to avoid duplicates
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an implementation detail. Instead, you should probably say something along the lines of "Does a simple string search and returns the first string value that matches the given key".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@brikis98
Copy link
Owner

brikis98 commented Aug 7, 2015

@labianchin: A few more questions/comments above :)

@labianchin
Copy link
Contributor Author

Hey @brikis98, I've made some fixes. Please also see my previous comments.

```
> docker-machine create --driver virtualbox <machine-name>
> eval "$(docker-machine env <machine-name>)"
> docker-osx-dev install
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, just realized I have one more question on this: do you have to run the install command every time you run docker-machine create? Or only the eval part?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, I am little confused on what should be the role of the install for docker-machine.

   install_dependencies # Should actually run before docker-machine create. Once for osx user.
   init_docker_host # Per machine, should run after docker-machine create. This seems only important for the next command
   install_rsync_on_docker_host # Is this really important? the sync will also install rsync.
   add_docker_host # Per machine, should run after docker-machine create. Also, is it important?
   add_environment_variables # Not used for docker-machine

I would avoid making the install create the docker-machine, as in the creation the user needs to supply the driver he wants and all the driver's configuration. It is also seems misleading that a install command would create a machine.

I'd suggest the following flow:

docker-osx-dev install_dependencies # once per osx user
docker-machine create --driver virtualbox <machine-name>
eval "$(docker-machine env <machine-name>)"
cd /foo/bar
docker-osx-dev

In this way there is no need to run install after docker-machine create. The install would only make sense for boot2docker.

@brikis98
Copy link
Owner

brikis98 commented Aug 9, 2015

I expect developers to run the docker-osx-dev script very frequently, so we should keep its startup time well under one second in the normal case. Therefore, the install command should take care of anything that:

  1. Takes a long time (more than ~1 second)
  2. Anything that needs to happen only once per computer
  3. Anything that needs to be run before you can use docker (i.e., install docker itself)

This is why it includes install_dependencies, init_docker_host, install_rsync_on_docker_host, add_docker_host, and add_environment_variables. The actual docker-osx-dev script, in theory, should run just the watch_and_sync command. However, it runs a few other steps (e.g., install_rsync_no_docker_host) that:

  1. Might go out of sync as the user tweaks their docker environment
  2. Are very fast to run in the normal case (e.g., checking if rsync is installed is very quick)

The question I asked earlier, though I guess not very clearly, was whether the install command should automate the eval "$(docker-machine env <machine-name>)" command you have listed in the README, or any other manual steps necessary for using docker-machine?

@labianchin
Copy link
Contributor Author

Yes. That really make sense. Thanks for clarifying.

Answering your question: I believe it shouldn't, as users might want to switch between different docker-machine instances (machines). So every time they run docker-osx-dev (watch_and_sync), they supply which machine name they want to run with.

So, clarifying, this steps, should run just after creating a new machine instance:

eval "$(docker-machine env <machine-name>)"
docker-osx-dev install

Which is equivalent of:

docker-osx-dev --machine-name <machine-name> install

After the instance is created and docker-osx-dev installed, users only need to run:

eval "$(docker-machine env <machine-name>)"
docker-osx-dev

Or the equivalent:

docker-osx-dev --machine-name <machine-name>

brikis98 added a commit that referenced this pull request Aug 10, 2015
Adds support for docker-machine
@brikis98 brikis98 merged commit 0a9c919 into brikis98:master Aug 10, 2015
@brikis98
Copy link
Owner

Awesome, thanks for the PR. It's now merged.

@labianchin
Copy link
Contributor Author

Thanks for all the feedback! That has been a great experience contributing to this project.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants