Skip to content

Commit 79b9450

Browse files
Revert "Remove flat (0.1.0) => nested (0.2.0) migration code"
This reverts commit 2f83188. Signed-off-by: Nathan LeClaire <nathan.leclaire@gmail.com>
1 parent ad6d8d4 commit 79b9450

File tree

4 files changed

+257
-2
lines changed

4 files changed

+257
-2
lines changed

libmachine/filestore.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ func (s Filestore) loadHost(name string) (*Host, error) {
3535
return nil, err
3636
}
3737

38-
return host, nil
38+
h := FillNestedHost(host)
39+
return h, nil
3940
}
4041

4142
func (s Filestore) GetPath() string {

libmachine/host.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,17 @@ type Host struct {
3333
Driver drivers.Driver
3434
StorePath string
3535
HostOptions *HostOptions
36+
37+
// deprecated options; these are left to assist in config migrations
38+
SwarmHost string
39+
SwarmMaster bool
40+
SwarmDiscovery string
41+
CaCertPath string
42+
PrivateKeyPath string
43+
ServerCertPath string
44+
ServerKeyPath string
45+
ClientCertPath string
46+
ClientKeyPath string
3647
}
3748

3849
type HostOptions struct {
@@ -282,7 +293,9 @@ func (h *Host) LoadConfig() error {
282293
return err
283294
}
284295

285-
authOptions := hostMetadata.HostOptions.AuthOptions
296+
meta := FillNestedHostMetadata(&hostMetadata)
297+
298+
authOptions := meta.HostOptions.AuthOptions
286299

287300
driver, err := drivers.NewDriver(hostMetadata.DriverName, h.Name, h.StorePath, authOptions.CaCertPath, authOptions.PrivateKeyPath)
288301
if err != nil {

libmachine/migrate.go

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
package libmachine
2+
3+
import (
4+
"path/filepath"
5+
6+
"github.com/docker/machine/libmachine/auth"
7+
"github.com/docker/machine/libmachine/engine"
8+
"github.com/docker/machine/libmachine/swarm"
9+
"github.com/docker/machine/utils"
10+
)
11+
12+
// In the 0.0.1 => 0.0.2 transition, the JSON representation of
13+
// machines changed from a "flat" to a more "nested" structure
14+
// for various options and configuration settings. To preserve
15+
// compatibility with existing machines, these migration functions
16+
// have been introduced. They preserve backwards compat at the expense
17+
// of some duplicated information.
18+
19+
// validates host config and modifies if needed
20+
// this is used for configuration updates
21+
func FillNestedHost(host *Host) *Host {
22+
certInfo := getCertInfoFromHost(host)
23+
24+
if host.HostOptions == nil {
25+
host.HostOptions = &HostOptions{}
26+
}
27+
if host.HostOptions.EngineOptions == nil {
28+
host.HostOptions.EngineOptions = &engine.EngineOptions{}
29+
}
30+
31+
if host.HostOptions.SwarmOptions == nil {
32+
host.HostOptions.SwarmOptions = &swarm.SwarmOptions{
33+
Address: "",
34+
Discovery: host.SwarmDiscovery,
35+
Host: host.SwarmHost,
36+
Master: host.SwarmMaster,
37+
}
38+
}
39+
40+
host.HostOptions.AuthOptions = &auth.AuthOptions{
41+
StorePath: host.StorePath,
42+
CaCertPath: certInfo.CaCertPath,
43+
CaCertRemotePath: "",
44+
ServerCertPath: certInfo.ServerCertPath,
45+
ServerKeyPath: certInfo.ServerKeyPath,
46+
ClientKeyPath: certInfo.ClientKeyPath,
47+
ServerCertRemotePath: "",
48+
ServerKeyRemotePath: "",
49+
PrivateKeyPath: certInfo.CaKeyPath,
50+
ClientCertPath: certInfo.ClientCertPath,
51+
}
52+
53+
return host
54+
}
55+
56+
// fills nested host metadata and modifies if needed
57+
// this is used for configuration updates
58+
func FillNestedHostMetadata(m *HostMetadata) *HostMetadata {
59+
if m.HostOptions.EngineOptions == nil {
60+
m.HostOptions.EngineOptions = &engine.EngineOptions{}
61+
}
62+
63+
if m.HostOptions.AuthOptions == nil {
64+
m.HostOptions.AuthOptions = &auth.AuthOptions{
65+
StorePath: m.StorePath,
66+
CaCertPath: m.CaCertPath,
67+
CaCertRemotePath: "",
68+
ServerCertPath: m.ServerCertPath,
69+
ServerKeyPath: m.ServerKeyPath,
70+
ClientKeyPath: "",
71+
ServerCertRemotePath: "",
72+
ServerKeyRemotePath: "",
73+
PrivateKeyPath: m.PrivateKeyPath,
74+
ClientCertPath: m.ClientCertPath,
75+
}
76+
}
77+
78+
return m
79+
}
80+
81+
func getCertInfoFromHost(h *Host) CertPathInfo {
82+
// setup cert paths
83+
caCertPath := h.CaCertPath
84+
caKeyPath := h.PrivateKeyPath
85+
clientCertPath := h.ClientCertPath
86+
clientKeyPath := h.ClientKeyPath
87+
serverCertPath := h.ServerCertPath
88+
serverKeyPath := h.ServerKeyPath
89+
90+
if caCertPath == "" {
91+
caCertPath = filepath.Join(utils.GetMachineCertDir(), "ca.pem")
92+
}
93+
94+
if caKeyPath == "" {
95+
caKeyPath = filepath.Join(utils.GetMachineCertDir(), "ca-key.pem")
96+
}
97+
98+
if clientCertPath == "" {
99+
clientCertPath = filepath.Join(utils.GetMachineCertDir(), "cert.pem")
100+
}
101+
102+
if clientKeyPath == "" {
103+
clientKeyPath = filepath.Join(utils.GetMachineCertDir(), "key.pem")
104+
}
105+
106+
if serverCertPath == "" {
107+
serverCertPath = filepath.Join(utils.GetMachineCertDir(), "server.pem")
108+
}
109+
110+
if serverKeyPath == "" {
111+
serverKeyPath = filepath.Join(utils.GetMachineCertDir(), "server-key.pem")
112+
}
113+
114+
return CertPathInfo{
115+
CaCertPath: caCertPath,
116+
CaKeyPath: caKeyPath,
117+
ClientCertPath: clientCertPath,
118+
ClientKeyPath: clientKeyPath,
119+
ServerCertPath: serverCertPath,
120+
ServerKeyPath: serverKeyPath,
121+
}
122+
}

libmachine/migrate_test.go

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
package libmachine
2+
3+
import (
4+
"os"
5+
"reflect"
6+
"testing"
7+
8+
"github.com/docker/machine/libmachine/auth"
9+
"github.com/docker/machine/libmachine/engine"
10+
"github.com/docker/machine/libmachine/swarm"
11+
)
12+
13+
func TestFillNestedHost(t *testing.T) {
14+
os.Setenv("MACHINE_STORAGE_PATH", "/tmp/migration")
15+
originalHost := &Host{
16+
HostOptions: nil,
17+
SwarmDiscovery: "token://foobar",
18+
SwarmHost: "1.2.3.4:2376",
19+
SwarmMaster: true,
20+
CaCertPath: "",
21+
PrivateKeyPath: "",
22+
ClientCertPath: "",
23+
ClientKeyPath: "",
24+
ServerCertPath: "",
25+
ServerKeyPath: "",
26+
}
27+
hostOptions := &HostOptions{
28+
SwarmOptions: &swarm.SwarmOptions{
29+
Master: true,
30+
Discovery: "token://foobar",
31+
Host: "1.2.3.4:2376",
32+
},
33+
AuthOptions: &auth.AuthOptions{
34+
CaCertPath: "/tmp/migration/certs/ca.pem",
35+
PrivateKeyPath: "/tmp/migration/certs/ca-key.pem",
36+
ClientCertPath: "/tmp/migration/certs/cert.pem",
37+
ClientKeyPath: "/tmp/migration/certs/key.pem",
38+
ServerCertPath: "/tmp/migration/certs/server.pem",
39+
ServerKeyPath: "/tmp/migration/certs/server-key.pem",
40+
},
41+
EngineOptions: &engine.EngineOptions{},
42+
}
43+
44+
expectedHost := &Host{
45+
SwarmHost: "1.2.3.4:2376",
46+
SwarmDiscovery: "token://foobar",
47+
SwarmMaster: true,
48+
HostOptions: hostOptions,
49+
}
50+
51+
host := FillNestedHost(originalHost)
52+
53+
if !reflect.DeepEqual(host, expectedHost) {
54+
t.Logf("\n%+v\n%+v", host, expectedHost)
55+
t.Logf("\n%+v\n%+v", host.HostOptions, expectedHost.HostOptions)
56+
t.Fatal("Expected these structs to be equal, they were different")
57+
}
58+
}
59+
60+
func TestFillNestedHostMetadata(t *testing.T) {
61+
metadata := &HostMetadata{
62+
HostOptions: HostOptions{
63+
EngineOptions: nil,
64+
AuthOptions: nil,
65+
},
66+
StorePath: "/tmp/store",
67+
CaCertPath: "/tmp/store/certs/ca.pem",
68+
ServerCertPath: "/tmp/store/certs/server.pem",
69+
}
70+
expectedAuthOptions := &auth.AuthOptions{
71+
StorePath: "/tmp/store",
72+
CaCertPath: "/tmp/store/certs/ca.pem",
73+
ServerCertPath: "/tmp/store/certs/server.pem",
74+
}
75+
76+
expectedMetadata := &HostMetadata{
77+
HostOptions: HostOptions{
78+
EngineOptions: &engine.EngineOptions{},
79+
AuthOptions: expectedAuthOptions,
80+
},
81+
StorePath: "/tmp/store",
82+
CaCertPath: "/tmp/store/certs/ca.pem",
83+
ServerCertPath: "/tmp/store/certs/server.pem",
84+
}
85+
86+
m := FillNestedHostMetadata(metadata)
87+
88+
if !reflect.DeepEqual(m, expectedMetadata) {
89+
t.Logf("\n%+v\n%+v", m, expectedMetadata)
90+
t.Fatal("Expected these structs to be equal, they were different")
91+
}
92+
}
93+
94+
// Tests a function which "prefills" certificate information for a host
95+
// due to a schema migration from "flat" to a "nested" structure.
96+
func TestGetCertInfoFromHost(t *testing.T) {
97+
os.Setenv("MACHINE_STORAGE_PATH", "/tmp/migration")
98+
host := &Host{
99+
CaCertPath: "",
100+
PrivateKeyPath: "",
101+
ClientCertPath: "",
102+
ClientKeyPath: "",
103+
ServerCertPath: "",
104+
ServerKeyPath: "",
105+
}
106+
expectedCertInfo := CertPathInfo{
107+
CaCertPath: "/tmp/migration/certs/ca.pem",
108+
CaKeyPath: "/tmp/migration/certs/ca-key.pem",
109+
ClientCertPath: "/tmp/migration/certs/cert.pem",
110+
ClientKeyPath: "/tmp/migration/certs/key.pem",
111+
ServerCertPath: "/tmp/migration/certs/server.pem",
112+
ServerKeyPath: "/tmp/migration/certs/server-key.pem",
113+
}
114+
certInfo := getCertInfoFromHost(host)
115+
if !reflect.DeepEqual(expectedCertInfo, certInfo) {
116+
t.Log("\n\n\n", expectedCertInfo, "\n\n\n", certInfo)
117+
t.Fatal("Expected these structs to be equal, they were different")
118+
}
119+
}

0 commit comments

Comments
 (0)