-
Notifications
You must be signed in to change notification settings - Fork 1
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
Implement binary exec / RPC based plugins for Machine #3
Conversation
e49cd4a
to
e2695a4
Compare
a88e3c2
to
666d6d4
Compare
e2695a4
to
e72c538
Compare
Good to see progress 👍 ; lots of todo's as well I see 😄 |
Added some details. |
Example plugin here: https://github.com/nathanleclaire/docker-machine-xhyve @zchee @timfallmk Check it out! I can help you to compile if you need. I have gotten a create to run about halfway through with the driver but looks like the driver has an issue getting the DHCP lease on my computer. |
You can see what I changed in that example driver in this commit: nathanleclaire/docker-machine-xhyve@dfb0d8b Some of it as well is just revisions to the driver such as fixing an issue with VBox version checking, updating it to use |
I've discovered an issue with leaking goroutines / processes after the main process exits, so that will need to be debugged before this is ready for prime time as well. |
- Clear out some cruft tightly coupling libmachine to filestore - Comment out drivers other than virtualbox for now - Change way too many things - Mostly, break out the code to be more modular. - Destroy all traces of "provider" in its current form. It will be brought back as something more sensible, instead of something which overlaps in function with both Host and Store. - Fix mis-managed config passthru - Remove a few instances of state stored in env vars - This should be explicitly communicated in Go-land, not through the shell. - Rename "store" module to "persist" - This is done mostly to avoid confusion about the fact that a concrete instance of a "Store" interface is oftentimes referred to as "store" in the code. - Rip out repetitive antipattern for getting store - This replaces the previous repetive idiom for getting the cert info, and consequently the store, with a much less repetitive idiom. - Also, some redundant methods in commands.go for accessing hosts have either been simplified or removed entirely. - First steps towards fixing up tests - Test progress continues - Replace unit tests with integration tests - MAKE ALL UNIT TESTS PASS YAY - Add helper test files - Don't write to disk in libmachine/host - Heh.. coverage check strikes again - Fix remove code - Move cert code around - Continued progress: simplify Driver - Fixups and make creation work with new model - Move drivers module inside of libmachine - Move ssh module inside of libmachine - Move state module to libmachine - Move utils module to libmachine - Move version module to libmachine - Move log module to libmachine - Modify some constructor methods around - Change Travis build dep structure - Boring gofmt fix - Add version module - Move NewHost to store - Update some boring cert path infos to make API easier to use - Fix up some issues around the new model - Clean up some cert path stuff - Don't use shady functions to get store path :D - Continue artifact work - Fix silly machines dir bug - Continue fixing silly path issues - Change up output of vbm a bit - Continue work to make example go - Change output a little more - Last changes needed to make create finish properly - Fix config.go to use libmachine - Cut down code duplication and make both methods work with libmachine - Add pluggable logging implementation - Return error when machine already in desired state - Update example to show log method - Fix file:// bug - Fix Swarm defaults - Remove unused TLS settings from Engine and Swarm options - Remove spurious error - Correct bug detecting if migration was performed - Fix compilation errors from tests - Fix most of remaining test issues - Fix final silly bug in tests - Remove extraneous debug code - Add -race to test command - Appease the gofmt - Appease the generate coverage - Making executive decision to remove Travis coverage check In the early days I thought this would be a good idea because it would encourage people to write tests in case they added a new module. Well, in fact it has just turned into a giant nuisance and made refactoring work like this even more difficult. - Move Get to Load - Move HostListItem code to CLI Signed-off-by: Nathan LeClaire <nathan.leclaire@gmail.com>
Signed-off-by: Nathan LeClaire <nathan.leclaire@gmail.com>
Signed-off-by: Nathan LeClaire <nathan.leclaire@gmail.com>
@nathanleclaire Yes! I start with the debug, and the refactoring...
This problem caused by I will wait @nathanleclaire reply. |
e72c538
to
1eaa772
Compare
666d6d4
to
7e92a5a
Compare
hi |
Also, a few various cleanups are bundled: 1. Only call GetDriver() once to get the object in provision/utils.go 2. SSH command wrapper will return the error and let the consumer decide what to do with it instead of bailing automatically on non-255 Signed-off-by: Nathan LeClaire <nathan.leclaire@gmail.com>
- Clear out some cruft tightly coupling libmachine to filestore - Comment out drivers other than virtualbox for now - Change way too many things - Mostly, break out the code to be more modular. - Destroy all traces of "provider" in its current form. It will be brought back as something more sensible, instead of something which overlaps in function with both Host and Store. - Fix mis-managed config passthru - Remove a few instances of state stored in env vars - This should be explicitly communicated in Go-land, not through the shell. - Rename "store" module to "persist" - This is done mostly to avoid confusion about the fact that a concrete instance of a "Store" interface is oftentimes referred to as "store" in the code. - Rip out repetitive antipattern for getting store - This replaces the previous repetive idiom for getting the cert info, and consequently the store, with a much less repetitive idiom. - Also, some redundant methods in commands.go for accessing hosts have either been simplified or removed entirely. - First steps towards fixing up tests - Test progress continues - Replace unit tests with integration tests - MAKE ALL UNIT TESTS PASS YAY - Add helper test files - Don't write to disk in libmachine/host - Heh.. coverage check strikes again - Fix remove code - Move cert code around - Continued progress: simplify Driver - Fixups and make creation work with new model - Move drivers module inside of libmachine - Move ssh module inside of libmachine - Move state module to libmachine - Move utils module to libmachine - Move version module to libmachine - Move log module to libmachine - Modify some constructor methods around - Change Travis build dep structure - Boring gofmt fix - Add version module - Move NewHost to store - Update some boring cert path infos to make API easier to use - Fix up some issues around the new model - Clean up some cert path stuff - Don't use shady functions to get store path :D - Continue artifact work - Fix silly machines dir bug - Continue fixing silly path issues - Change up output of vbm a bit - Continue work to make example go - Change output a little more - Last changes needed to make create finish properly - Fix config.go to use libmachine - Cut down code duplication and make both methods work with libmachine - Add pluggable logging implementation - Return error when machine already in desired state - Update example to show log method - Fix file:// bug - Fix Swarm defaults - Remove unused TLS settings from Engine and Swarm options - Remove spurious error - Correct bug detecting if migration was performed - Fix compilation errors from tests - Fix most of remaining test issues - Fix final silly bug in tests - Remove extraneous debug code - Add -race to test command - Appease the gofmt - Appease the generate coverage - Making executive decision to remove Travis coverage check In the early days I thought this would be a good idea because it would encourage people to write tests in case they added a new module. Well, in fact it has just turned into a giant nuisance and made refactoring work like this even more difficult. - Move Get to Load - Move HostListItem code to CLI Signed-off-by: Nathan LeClaire <nathan.leclaire@gmail.com>
- First RPC steps - Work on some flaws in RPC model - Remove unused TLS settings from Engine and Swarm options - Add code to correctly encode data over the network - Add client driver for RPC - Rename server driver file - Start to make marshal make sense - Fix silly RPC method args and add client - Fix some issues with RPC calls, and marshaling - Simplify plugin main.go - Move towards 100% plugin in CLI - Ensure that plugin servers are cleaned up properly - Make flag parsing for driver flags work properly
Signed-off-by: Nathan LeClaire <nathan.leclaire@gmail.com>
d7b25d8
to
0b4755f
Compare
Should note that this also includes docker#1685: I needed it to make a |
7e92a5a
to
c66779f
Compare
@nlamirault Check it out. |
@zchee thanks |
65255f1
to
51f40dd
Compare
79da42f
to
4095f02
Compare
@zchee any particular reason why you are building the driver binary with |
@janeczku Hi,
|
6a50dd1
to
c84605e
Compare
|
fe0ae54
to
b5927f1
Compare
Please move discussion to: docker#1902 |
Docker Machine Driver Plugins
Motivation
Many folks have expressed interest in writing or maintaining a driver for Machine but @ehazlett and I are incapable of reviewing and maintaining all of them ourselves. Additionally, we are a bottleneck for when people want to add features and release new versions of existing drivers. Therefore, we are moving to a plugin-based architecture.
Usage
From the end user's perspective, the Machine CLI will be pretty similar to how it always has, with the additional caveat that binaries for the desired plugins must be installed as well as the core
docker-machine
binary.For the plugin developer and/or distributor, there are some considerations to keep in mind. All plugins must be Go binaries located in the end user's
PATH
with the name ofdocker-machine-drivername
. Once present, they will be usable.To implement a plugin, the driver developer must make a new repository with the plugin code, which:
virtualbox
) which contains astruct
that fulfills theDriver
interface fromgitpro.ttaallkk.top/docker/machine/libmachine/drivers
main
module (I've chosen to make this in a directory calledbin
in thevirtualbox
example presented here for this) which callsplugin.RegisterPlugin()
with an instantiated instance of the struct.Example from VirtualBox:
Migrating an Existing Driver to a Plugin
This is for the time of writing and is likely to change, but I think through documenting things we can hopefully the most mundane details of this process through a script.
The most important / likely to trip up migrators details are:
libmachine
. Some examples:github.com/docker/machine/log
=>github.com/docker/machine/libmachine/log
github.com/docker/machine/utils
=>github.com/docker/machine/libmachine/mcnutils
github.com/docker/machine/drivers
=>github.com/docker/machine/libmachine/drivers
StorePath
expected by many drivers has been replaced byGlobalArtifactPath
andLocalArtifactPath
methods (formerlyResolveStorePath
), but in the light of day I'm not really sold on this decision of mine, and may well change it back to the way it was before).cli.Flag
in the drivers has changed to a Machine-specific model which is more RPC-friendly. Essentially:GetCreateFlags
is now a required method on theDriver
itself, not a module-level function, which returns[]mcnflag.Flag
(a custom type encompassing all types of flags). All instances ofcli.Flag
and/or concrete types that implement it should be replaced bymcnflag.Flag
.init
block callingRegister
in the driver moduleNewDriver
"factory" method in the driver module, but not actually required.Under The Hood
The way that plugins work is heavily inspired by Hashicorp's Terraform.
When a Machine command is invoked, the following happens:
Host
struct(s) is loaded up from disk, and instead of loading the literal driver struct like in the past, aRpcClientDriver
is loaded into theDriver
field. This struct fulfills the Driver interface but is agnostic about the provider, it simply proxies methods to the RPC Driver server listening in the plugin binary.localhost
, and the created RPC client connects to it.RawDriver
is set as[]byte
to ensure that the configuration can be set over the network again on subsequent invocations.Tooling
We don't have any tooling / default Machine plugin repository yet, but there are several things I'd like to see:
22
,2376
,3376
in the case of Swarm master, etc.Caveat Emptor
Some of the underlying API / mechanics are likely to change, such as
libmachine
details. Ultimately, however, it is our goal to make migrating existing work that has been done on drivers to the plugin-based model as smooth as possible. To that end, we really want to get people playing with this ASAP, so feel free to reach out, comment, and attempt some implementations.