{"action":"created","issue":{"url":"https://api.github.com/repos/docker/machine/issues/2516","repository_url":"https://api.github.com/repos/docker/machine","labels_url":"https://api.github.com/repos/docker/machine/issues/2516/labels{/name}","comments_url":"https://api.github.com/repos/docker/machine/issues/2516/comments","events_url":"https://api.github.com/repos/docker/machine/issues/2516/events","html_url":"https://github.com/docker/machine/issues/2516","id":120855053,"number":2516,"title":"Implement more shareable serialization logic for config.json","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},"labels":[{"id":153847762,"url":"https://api.github.com/repos/docker/machine/labels/kind/enhancement","name":"kind/enhancement","color":"84b6eb","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":11,"created_at":"2015-12-07T20:00:13Z","updated_at":"2016-12-10T07:02:55Z","closed_at":null,"body":"This is a proposal to deal with a variety of problems around sharing configurations from computer to computer.\n## Problem\n\nCurrently if one creates a server using Docker Machine, a new folder is created on their computer containing `config.json` (description of the machine) and secrets associated with that machine.  To use this same configuration on another computer is not straightforward, largely because moving the folder to the same path on another machine does not guarantee that the OS paths will be translated correctly.\n\nFor instance, a user might have their `CaCertPath` at `/Users/nathanleclaire/.docker/machine/certs/ca.pem`, but on another computer the `StorePath` might be `C:\\Users\\nathan\\.docker`.\n## Proposal\n\nThis could potentially be mitigated by implementing a custom type with custom JSON marshal and unmarshal logic using Golang's `JSONMarshaler` and `JSONUnmarshaler` interfaces.\n\nThis would allow us to have a \"universal translation layer\" for pathing.  Likewise, \n\nCode speaks louder than words, so here's an example:\n\n``` go\npackage main\n\nimport (\n    \"encoding/json\"\n    \"fmt\"\n    \"log\"\n    \"strings\"\n)\n\ntype FSPath string\n\nvar machineDir = \"/Users/nathanleclaire/.docker/machine\"\n\nfunc (fspath FSPath) MarshalJSON() ([]byte, error) {\n    stringForm := string(fspath)\n    stringForm = strings.Replace(stringForm, machineDir, \"{{.MachineDir}}\", -1)\n    return []byte(fmt.Sprintf(`\"%s\"`, stringForm)), nil\n}\n\nfunc (fspath *FSPath) UnmarshalJSON(data []byte) error {\n    stringForm := string(data)\n    *fspath = FSPath(strings.Replace(stringForm, \"{{.MachineDir}}\", machineDir, -1))\n    return nil\n\n}\n\nfunc main() {\n    var caCertPath FSPath\n    caCertPath = \"/Users/nathanleclaire/.docker/machine/certs/ca-cert.pem\"\n    caCertJSON, err := json.Marshal(caCertPath)\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    fmt.Println(\"Persisted form: \", string(caCertJSON))\n\n    var loadedCaCertPath FSPath\n    if err := json.Unmarshal(caCertJSON, &loadedCaCertPath); err != nil {\n        log.Fatal(err)\n    }\n\n    fmt.Println(\"Loaded form: \", loadedCaCertPath)\n}\n```\n\nOutput:\n\n``` console\nPersisted form:  \"{{.MachineDir}}/certs/ca-cert.pem\"\nLoaded form:  \"/Users/nathanleclaire/.docker/machine/certs/ca-cert.pem\"\n```\n\nLink to playground version: http://play.golang.org/p/fbR-k8nItm\n\nFor instance, we could use this to normalize the paths to always have the same type of slashes like mentioned in https://github.com/docker/machine/issues/2509\n\nIf this is implemented properly, we can ensure that the user's `StorePath` will always be set correctly when loaded, no matter where the store they happened to move their machine folder to is.\n## Potential issues\n\nSeems like this isn't a particularly risky move, but the most annoying bit would be to update all of our code to use `FSPath` instead of vanilla `string`, which is certainly a decent chunk of overhead and decently risky given some issues around serialization and migration that we've had in the past.\n## Future\n\nOne of the reasons I think this could be nice to implement is that it could set a precedent for doing this in other areas as well.  For instance, to keep API credentials encrypted when they are on disk and prompt for a password before decrypting them in the `Unmarshal` step (as just one suggestion of many possibilities).\n\nRelated issues / PRs:\n- https://github.com/docker/machine/issues/2509\n- https://github.com/docker/machine/issues/1328\n\ncc @docker/machine-maintainers What do you think about this solution?\n"},"comment":{"url":"https://api.github.com/repos/docker/machine/issues/comments/266184030","html_url":"https://github.com/docker/machine/issues/2516#issuecomment-266184030","issue_url":"https://api.github.com/repos/docker/machine/issues/2516","id":266184030,"user":{"login":"monodeep12","id":640191,"avatar_url":"https://avatars.githubusercontent.com/u/640191?v=3","gravatar_id":"","url":"https://api.github.com/users/monodeep12","html_url":"https://github.com/monodeep12","followers_url":"https://api.github.com/users/monodeep12/followers","following_url":"https://api.github.com/users/monodeep12/following{/other_user}","gists_url":"https://api.github.com/users/monodeep12/gists{/gist_id}","starred_url":"https://api.github.com/users/monodeep12/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/monodeep12/subscriptions","organizations_url":"https://api.github.com/users/monodeep12/orgs","repos_url":"https://api.github.com/users/monodeep12/repos","events_url":"https://api.github.com/users/monodeep12/events{/privacy}","received_events_url":"https://api.github.com/users/monodeep12/received_events","type":"User","site_admin":false},"created_at":"2016-12-10T07:02:55Z","updated_at":"2016-12-10T07:02:55Z","body":"Any update on this feature?"}}
{"actor":{"display_login":"monodeep12"}}