{"action":"created","comment":{"url":"https://api.github.com/repos/docker/machine/pulls/comments/37712142","id":37712142,"diff_hunk":"@@ -1,104 +0,0 @@\n-package commands","path":"commands/config_test.go","position":1,"original_position":1,"commit_id":"ca4909fc4ac45090696dc78f5f5ad1066b3674f8","original_commit_id":"258428069e9b1a3c4dae8b39fbd19dbfd1c37903","user":{"login":"nathanleclaire","id":1476820,"avatar_url":"https://avatars.githubusercontent.com/u/1476820?v=3","gravatar_id":"","url":"https://api.github.com/users/nathanleclaire","html_url":"https://github.com/nathanleclaire","followers_url":"https://api.github.com/users/nathanleclaire/followers","following_url":"https://api.github.com/users/nathanleclaire/following{/other_user}","gists_url":"https://api.github.com/users/nathanleclaire/gists{/gist_id}","starred_url":"https://api.github.com/users/nathanleclaire/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nathanleclaire/subscriptions","organizations_url":"https://api.github.com/users/nathanleclaire/orgs","repos_url":"https://api.github.com/users/nathanleclaire/repos","events_url":"https://api.github.com/users/nathanleclaire/events{/privacy}","received_events_url":"https://api.github.com/users/nathanleclaire/received_events","type":"User","site_admin":false},"body":"I felt that way before, but now I actually think the opposite is true.  It's very hard to tell just from looking at the filesystem which parts of the code have tests and which need them.  We haven't had any \"Hey, noticed there was an empty test file so I submitted a patch\" type contributions, so I think we just have to be stricter in code review.","created_at":"2015-08-23T23:37:26Z","updated_at":"2015-08-23T23:37:26Z","html_url":"https://github.com/docker/machine/pull/1729#discussion_r37712142","pull_request_url":"https://api.github.com/repos/docker/machine/pulls/1729","_links":{"self":{"href":"https://api.github.com/repos/docker/machine/pulls/comments/37712142"},"html":{"href":"https://github.com/docker/machine/pull/1729#discussion_r37712142"},"pull_request":{"href":"https://api.github.com/repos/docker/machine/pulls/1729"}}},"pull_request":{"url":"https://api.github.com/repos/docker/machine/pulls/1729","id":42778507,"html_url":"https://github.com/docker/machine/pull/1729","diff_url":"https://github.com/docker/machine/pull/1729.diff","patch_url":"https://github.com/docker/machine/pull/1729.patch","issue_url":"https://api.github.com/repos/docker/machine/issues/1729","number":1729,"state":"open","locked":false,"title":"Make libmachine consumable by outside world","user":{"login":"nathanleclaire","id":1476820,"avatar_url":"https://avatars.githubusercontent.com/u/1476820?v=3","gravatar_id":"","url":"https://api.github.com/users/nathanleclaire","html_url":"https://github.com/nathanleclaire","followers_url":"https://api.github.com/users/nathanleclaire/followers","following_url":"https://api.github.com/users/nathanleclaire/following{/other_user}","gists_url":"https://api.github.com/users/nathanleclaire/gists{/gist_id}","starred_url":"https://api.github.com/users/nathanleclaire/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nathanleclaire/subscriptions","organizations_url":"https://api.github.com/users/nathanleclaire/orgs","repos_url":"https://api.github.com/users/nathanleclaire/repos","events_url":"https://api.github.com/users/nathanleclaire/events{/privacy}","received_events_url":"https://api.github.com/users/nathanleclaire/received_events","type":"User","site_admin":false},"body":"Alright, I'm hesitant to turn this in incomplete (which it is so far-- probably about 60-70% done), but better early than never, and I'd prefer to iterate on something crude and incomplete rather than toil away and learn that others have some fundamental disagreements on my approach.\r\n\r\nSorry for the size of the patch, but you'll notice (in the current state at least) there are about 2x as many deletions as additions, and a chunk of it is now-or-never cleanup work to make the API more sane.\r\n\r\nI'll annotate the code a little to guide since the patch is so large.\r\n\r\n## Design Principles:\r\n\r\n- [x] Never, ever write to disk inside the `host` module.  That's the `persist` module's job.  To that end, it would be good to get another `Store` implementation to prove viability outside of `Filestore`, and automatically test it.  To that extent, ideally `Store` needs some more re-working so it can keep track of artifacts (secrets such as certs and mundane artifacts like ISOs) instead of having everybody write them to the filesystem willy-nilly.\r\n- [x] `Provider` in its current form is completely gone as its role conflicted heavily with `host.Host`.  Later, I want to bring back `Provider` as a notion of something which \"provides\" host creation and management and provides the things needed to bootstrap control of them, such as API tokens.\r\n\r\n\r\nSomething like the following code is my rough roadmap for where I'm working towards with the `libmachine` module.  I'm not really sure how to best handle the awkward `DriverOptions` bit.  `interface{}` seems wrong, but we don't have strongly typed `Provider`s to give us `Host`s (like alluded to above).\r\n\r\n```Go\r\npackage main\r\n\r\n// Sample Virtualbox create independent of Machine CLI.\r\n\r\nimport (\r\n    \"fmt\"\r\n\r\n    \"github.com/docker/machine/libmachine\"\r\n    \"github.com/docker/machine/libmachine/engine\"\r\n    \"github.com/docker/machine/libmachine/host\"\r\n    \"github.com/docker/machine/drivers/virtualbox\"\r\n)\r\n\r\nfunc main() {\r\n    // returns the familiar store at $HOME/.docker/machine\r\n    store, _ := libmachine.GetDefaultStore()\r\n\r\n    h := &host.Host{\r\n        Name: \"mycoolhost\",\r\n        HostOptions: &host.HostOptions{\r\n                EngineOptions: &engine.EngineOptions{\r\n                    StorageDriver: \"overlay\",\r\n                },\r\n        },\r\n        Driver: &virtualbox.Driver{\r\n            CPU: 2,\r\n            Memory: 2048,\r\n        },\r\n    }\r\n    \r\n    // This method is a very high-level method which includes host creation,\r\n    // saving the newly created host in the store, and provisioning.\r\n    h, _ = libmachine.Create(store, h)\r\n\r\n    out, _ := h.RunSSHCommand(\"df -h\")\r\n\r\n    fmt.Printf(\"Results of your disk space query:\\n%s\\n\", out)\r\n\r\n    fmt.Println(\"Powering down machine now...\")\r\n    _ := h.Stop()\r\n}\r\n```\r\n\r\nThoughts:\r\n\r\n- I'd like to rename `host` module to something a bit less confusing, to avoid collision with the instantiated `Host` struct.  To that extent, I really am wondering if we should just move `Host` to be `Machine`, as it _is_ `libmachine` after all.\r\n- You'll notice that `store` is now in its own module, as are most of the `libmachine`-related functions.  The core `libmachine` namespace will be reserved for very high-level functions meant for calling from the outside world, and/or `commands`.\r\n- `libmachine` depends on other things such as `github.com/docker/machine/log`, do those go in `libmachine` as well?  How does that all work?  Logging etc. since I'm sure consumers of the API won't want us logging to terminal all over the place implicitly.  Guess we should pass in an `io.Writer` as a \"config\" property of... something?\r\n- The API should probably be versioned, how do we do so?  Sounds like another case for a `libmachine` client struct that you should be instantiating before doing anything.\r\n\r\ncc @ehazlett @ibuildthecloud @hairyhenderson @SvenDowideit @tianon @bfirsh  :musical_note:  MACHINE PARTY :tada: :balloon: :confetti_ball: ","created_at":"2015-08-19T05:38:29Z","updated_at":"2015-08-23T23:37:26Z","closed_at":null,"merged_at":null,"merge_commit_sha":"ed48ffed31b702358ca4954a188fd65f19cd57ce","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/docker/machine/pulls/1729/commits","review_comments_url":"https://api.github.com/repos/docker/machine/pulls/1729/comments","review_comment_url":"https://api.github.com/repos/docker/machine/pulls/comments{/number}","comments_url":"https://api.github.com/repos/docker/machine/issues/1729/comments","statuses_url":"https://api.github.com/repos/docker/machine/statuses/ca4909fc4ac45090696dc78f5f5ad1066b3674f8","head":{"label":"nathanleclaire:git_r_done_libmachine","ref":"git_r_done_libmachine","sha":"ca4909fc4ac45090696dc78f5f5ad1066b3674f8","user":{"login":"nathanleclaire","id":1476820,"avatar_url":"https://avatars.githubusercontent.com/u/1476820?v=3","gravatar_id":"","url":"https://api.github.com/users/nathanleclaire","html_url":"https://github.com/nathanleclaire","followers_url":"https://api.github.com/users/nathanleclaire/followers","following_url":"https://api.github.com/users/nathanleclaire/following{/other_user}","gists_url":"https://api.github.com/users/nathanleclaire/gists{/gist_id}","starred_url":"https://api.github.com/users/nathanleclaire/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nathanleclaire/subscriptions","organizations_url":"https://api.github.com/users/nathanleclaire/orgs","repos_url":"https://api.github.com/users/nathanleclaire/repos","events_url":"https://api.github.com/users/nathanleclaire/events{/privacy}","received_events_url":"https://api.github.com/users/nathanleclaire/received_events","type":"User","site_admin":false},"repo":{"id":27627407,"name":"machine","full_name":"nathanleclaire/machine","owner":{"login":"nathanleclaire","id":1476820,"avatar_url":"https://avatars.githubusercontent.com/u/1476820?v=3","gravatar_id":"","url":"https://api.github.com/users/nathanleclaire","html_url":"https://github.com/nathanleclaire","followers_url":"https://api.github.com/users/nathanleclaire/followers","following_url":"https://api.github.com/users/nathanleclaire/following{/other_user}","gists_url":"https://api.github.com/users/nathanleclaire/gists{/gist_id}","starred_url":"https://api.github.com/users/nathanleclaire/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nathanleclaire/subscriptions","organizations_url":"https://api.github.com/users/nathanleclaire/orgs","repos_url":"https://api.github.com/users/nathanleclaire/repos","events_url":"https://api.github.com/users/nathanleclaire/events{/privacy}","received_events_url":"https://api.github.com/users/nathanleclaire/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/nathanleclaire/machine","description":"Machine management for a container-centric world","fork":true,"url":"https://api.github.com/repos/nathanleclaire/machine","forks_url":"https://api.github.com/repos/nathanleclaire/machine/forks","keys_url":"https://api.github.com/repos/nathanleclaire/machine/keys{/key_id}","collaborators_url":"https://api.github.com/repos/nathanleclaire/machine/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/nathanleclaire/machine/teams","hooks_url":"https://api.github.com/repos/nathanleclaire/machine/hooks","issue_events_url":"https://api.github.com/repos/nathanleclaire/machine/issues/events{/number}","events_url":"https://api.github.com/repos/nathanleclaire/machine/events","assignees_url":"https://api.github.com/repos/nathanleclaire/machine/assignees{/user}","branches_url":"https://api.github.com/repos/nathanleclaire/machine/branches{/branch}","tags_url":"https://api.github.com/repos/nathanleclaire/machine/tags","blobs_url":"https://api.github.com/repos/nathanleclaire/machine/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/nathanleclaire/machine/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/nathanleclaire/machine/git/refs{/sha}","trees_url":"https://api.github.com/repos/nathanleclaire/machine/git/trees{/sha}","statuses_url":"https://api.github.com/repos/nathanleclaire/machine/statuses/{sha}","languages_url":"https://api.github.com/repos/nathanleclaire/machine/languages","stargazers_url":"https://api.github.com/repos/nathanleclaire/machine/stargazers","contributors_url":"https://api.github.com/repos/nathanleclaire/machine/contributors","subscribers_url":"https://api.github.com/repos/nathanleclaire/machine/subscribers","subscription_url":"https://api.github.com/repos/nathanleclaire/machine/subscription","commits_url":"https://api.github.com/repos/nathanleclaire/machine/commits{/sha}","git_commits_url":"https://api.github.com/repos/nathanleclaire/machine/git/commits{/sha}","comments_url":"https://api.github.com/repos/nathanleclaire/machine/comments{/number}","issue_comment_url":"https://api.github.com/repos/nathanleclaire/machine/issues/comments{/number}","contents_url":"https://api.github.com/repos/nathanleclaire/machine/contents/{+path}","compare_url":"https://api.github.com/repos/nathanleclaire/machine/compare/{base}...{head}","merges_url":"https://api.github.com/repos/nathanleclaire/machine/merges","archive_url":"https://api.github.com/repos/nathanleclaire/machine/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/nathanleclaire/machine/downloads","issues_url":"https://api.github.com/repos/nathanleclaire/machine/issues{/number}","pulls_url":"https://api.github.com/repos/nathanleclaire/machine/pulls{/number}","milestones_url":"https://api.github.com/repos/nathanleclaire/machine/milestones{/number}","notifications_url":"https://api.github.com/repos/nathanleclaire/machine/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/nathanleclaire/machine/labels{/name}","releases_url":"https://api.github.com/repos/nathanleclaire/machine/releases{/id}","created_at":"2014-12-06T08:16:23Z","updated_at":"2015-05-01T18:48:35Z","pushed_at":"2015-08-23T13:23:40Z","git_url":"git://github.com/nathanleclaire/machine.git","ssh_url":"git@github.com:nathanleclaire/machine.git","clone_url":"https://github.com/nathanleclaire/machine.git","svn_url":"https://github.com/nathanleclaire/machine","homepage":null,"size":9706,"stargazers_count":1,"watchers_count":1,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":1,"default_branch":"master"}},"base":{"label":"docker:master","ref":"master","sha":"816d60203a0e10b0d78d451e36c3e5e2f2ddb65b","user":{"login":"docker","id":5429470,"avatar_url":"https://avatars.githubusercontent.com/u/5429470?v=3","gravatar_id":"","url":"https://api.github.com/users/docker","html_url":"https://github.com/docker","followers_url":"https://api.github.com/users/docker/followers","following_url":"https://api.github.com/users/docker/following{/other_user}","gists_url":"https://api.github.com/users/docker/gists{/gist_id}","starred_url":"https://api.github.com/users/docker/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/docker/subscriptions","organizations_url":"https://api.github.com/users/docker/orgs","repos_url":"https://api.github.com/users/docker/repos","events_url":"https://api.github.com/users/docker/events{/privacy}","received_events_url":"https://api.github.com/users/docker/received_events","type":"Organization","site_admin":false},"repo":{"id":27494663,"name":"machine","full_name":"docker/machine","owner":{"login":"docker","id":5429470,"avatar_url":"https://avatars.githubusercontent.com/u/5429470?v=3","gravatar_id":"","url":"https://api.github.com/users/docker","html_url":"https://github.com/docker","followers_url":"https://api.github.com/users/docker/followers","following_url":"https://api.github.com/users/docker/following{/other_user}","gists_url":"https://api.github.com/users/docker/gists{/gist_id}","starred_url":"https://api.github.com/users/docker/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/docker/subscriptions","organizations_url":"https://api.github.com/users/docker/orgs","repos_url":"https://api.github.com/users/docker/repos","events_url":"https://api.github.com/users/docker/events{/privacy}","received_events_url":"https://api.github.com/users/docker/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/docker/machine","description":"Machine management for a container-centric world","fork":false,"url":"https://api.github.com/repos/docker/machine","forks_url":"https://api.github.com/repos/docker/machine/forks","keys_url":"https://api.github.com/repos/docker/machine/keys{/key_id}","collaborators_url":"https://api.github.com/repos/docker/machine/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/docker/machine/teams","hooks_url":"https://api.github.com/repos/docker/machine/hooks","issue_events_url":"https://api.github.com/repos/docker/machine/issues/events{/number}","events_url":"https://api.github.com/repos/docker/machine/events","assignees_url":"https://api.github.com/repos/docker/machine/assignees{/user}","branches_url":"https://api.github.com/repos/docker/machine/branches{/branch}","tags_url":"https://api.github.com/repos/docker/machine/tags","blobs_url":"https://api.github.com/repos/docker/machine/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/docker/machine/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/docker/machine/git/refs{/sha}","trees_url":"https://api.github.com/repos/docker/machine/git/trees{/sha}","statuses_url":"https://api.github.com/repos/docker/machine/statuses/{sha}","languages_url":"https://api.github.com/repos/docker/machine/languages","stargazers_url":"https://api.github.com/repos/docker/machine/stargazers","contributors_url":"https://api.github.com/repos/docker/machine/contributors","subscribers_url":"https://api.github.com/repos/docker/machine/subscribers","subscription_url":"https://api.github.com/repos/docker/machine/subscription","commits_url":"https://api.github.com/repos/docker/machine/commits{/sha}","git_commits_url":"https://api.github.com/repos/docker/machine/git/commits{/sha}","comments_url":"https://api.github.com/repos/docker/machine/comments{/number}","issue_comment_url":"https://api.github.com/repos/docker/machine/issues/comments{/number}","contents_url":"https://api.github.com/repos/docker/machine/contents/{+path}","compare_url":"https://api.github.com/repos/docker/machine/compare/{base}...{head}","merges_url":"https://api.github.com/repos/docker/machine/merges","archive_url":"https://api.github.com/repos/docker/machine/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/docker/machine/downloads","issues_url":"https://api.github.com/repos/docker/machine/issues{/number}","pulls_url":"https://api.github.com/repos/docker/machine/pulls{/number}","milestones_url":"https://api.github.com/repos/docker/machine/milestones{/number}","notifications_url":"https://api.github.com/repos/docker/machine/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/docker/machine/labels{/name}","releases_url":"https://api.github.com/repos/docker/machine/releases{/id}","created_at":"2014-12-03T15:52:06Z","updated_at":"2015-08-23T22:24:36Z","pushed_at":"2015-08-23T19:36:32Z","git_url":"git://github.com/docker/machine.git","ssh_url":"git@github.com:docker/machine.git","clone_url":"https://github.com/docker/machine.git","svn_url":"https://github.com/docker/machine","homepage":"https://docs.docker.com/machine/","size":33397,"stargazers_count":2360,"watchers_count":2360,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":478,"mirror_url":null,"open_issues_count":368,"forks":478,"open_issues":368,"watchers":2360,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/docker/machine/pulls/1729"},"html":{"href":"https://github.com/docker/machine/pull/1729"},"issue":{"href":"https://api.github.com/repos/docker/machine/issues/1729"},"comments":{"href":"https://api.github.com/repos/docker/machine/issues/1729/comments"},"review_comments":{"href":"https://api.github.com/repos/docker/machine/pulls/1729/comments"},"review_comment":{"href":"https://api.github.com/repos/docker/machine/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/docker/machine/pulls/1729/commits"},"statuses":{"href":"https://api.github.com/repos/docker/machine/statuses/ca4909fc4ac45090696dc78f5f5ad1066b3674f8"}}}}