Revert "Remove flat (0.1.0) => nested (0.2.0) migration code"

This reverts commit 2f831887c6.

Signed-off-by: Nathan LeClaire <nathan.leclaire@gmail.com>
This commit is contained in:
Nathan LeClaire 2015-07-17 16:48:11 -07:00
parent ad6d8d49a8
commit 79b9450fef
4 changed files with 257 additions and 2 deletions

View File

@ -35,7 +35,8 @@ func (s Filestore) loadHost(name string) (*Host, error) {
return nil, err
}
return host, nil
h := FillNestedHost(host)
return h, nil
}
func (s Filestore) GetPath() string {

View File

@ -33,6 +33,17 @@ type Host struct {
Driver drivers.Driver
StorePath string
HostOptions *HostOptions
// deprecated options; these are left to assist in config migrations
SwarmHost string
SwarmMaster bool
SwarmDiscovery string
CaCertPath string
PrivateKeyPath string
ServerCertPath string
ServerKeyPath string
ClientCertPath string
ClientKeyPath string
}
type HostOptions struct {
@ -282,7 +293,9 @@ func (h *Host) LoadConfig() error {
return err
}
authOptions := hostMetadata.HostOptions.AuthOptions
meta := FillNestedHostMetadata(&hostMetadata)
authOptions := meta.HostOptions.AuthOptions
driver, err := drivers.NewDriver(hostMetadata.DriverName, h.Name, h.StorePath, authOptions.CaCertPath, authOptions.PrivateKeyPath)
if err != nil {

122
libmachine/migrate.go Normal file
View File

@ -0,0 +1,122 @@
package libmachine
import (
"path/filepath"
"github.com/docker/machine/libmachine/auth"
"github.com/docker/machine/libmachine/engine"
"github.com/docker/machine/libmachine/swarm"
"github.com/docker/machine/utils"
)
// In the 0.0.1 => 0.0.2 transition, the JSON representation of
// machines changed from a "flat" to a more "nested" structure
// for various options and configuration settings. To preserve
// compatibility with existing machines, these migration functions
// have been introduced. They preserve backwards compat at the expense
// of some duplicated information.
// validates host config and modifies if needed
// this is used for configuration updates
func FillNestedHost(host *Host) *Host {
certInfo := getCertInfoFromHost(host)
if host.HostOptions == nil {
host.HostOptions = &HostOptions{}
}
if host.HostOptions.EngineOptions == nil {
host.HostOptions.EngineOptions = &engine.EngineOptions{}
}
if host.HostOptions.SwarmOptions == nil {
host.HostOptions.SwarmOptions = &swarm.SwarmOptions{
Address: "",
Discovery: host.SwarmDiscovery,
Host: host.SwarmHost,
Master: host.SwarmMaster,
}
}
host.HostOptions.AuthOptions = &auth.AuthOptions{
StorePath: host.StorePath,
CaCertPath: certInfo.CaCertPath,
CaCertRemotePath: "",
ServerCertPath: certInfo.ServerCertPath,
ServerKeyPath: certInfo.ServerKeyPath,
ClientKeyPath: certInfo.ClientKeyPath,
ServerCertRemotePath: "",
ServerKeyRemotePath: "",
PrivateKeyPath: certInfo.CaKeyPath,
ClientCertPath: certInfo.ClientCertPath,
}
return host
}
// fills nested host metadata and modifies if needed
// this is used for configuration updates
func FillNestedHostMetadata(m *HostMetadata) *HostMetadata {
if m.HostOptions.EngineOptions == nil {
m.HostOptions.EngineOptions = &engine.EngineOptions{}
}
if m.HostOptions.AuthOptions == nil {
m.HostOptions.AuthOptions = &auth.AuthOptions{
StorePath: m.StorePath,
CaCertPath: m.CaCertPath,
CaCertRemotePath: "",
ServerCertPath: m.ServerCertPath,
ServerKeyPath: m.ServerKeyPath,
ClientKeyPath: "",
ServerCertRemotePath: "",
ServerKeyRemotePath: "",
PrivateKeyPath: m.PrivateKeyPath,
ClientCertPath: m.ClientCertPath,
}
}
return m
}
func getCertInfoFromHost(h *Host) CertPathInfo {
// setup cert paths
caCertPath := h.CaCertPath
caKeyPath := h.PrivateKeyPath
clientCertPath := h.ClientCertPath
clientKeyPath := h.ClientKeyPath
serverCertPath := h.ServerCertPath
serverKeyPath := h.ServerKeyPath
if caCertPath == "" {
caCertPath = filepath.Join(utils.GetMachineCertDir(), "ca.pem")
}
if caKeyPath == "" {
caKeyPath = filepath.Join(utils.GetMachineCertDir(), "ca-key.pem")
}
if clientCertPath == "" {
clientCertPath = filepath.Join(utils.GetMachineCertDir(), "cert.pem")
}
if clientKeyPath == "" {
clientKeyPath = filepath.Join(utils.GetMachineCertDir(), "key.pem")
}
if serverCertPath == "" {
serverCertPath = filepath.Join(utils.GetMachineCertDir(), "server.pem")
}
if serverKeyPath == "" {
serverKeyPath = filepath.Join(utils.GetMachineCertDir(), "server-key.pem")
}
return CertPathInfo{
CaCertPath: caCertPath,
CaKeyPath: caKeyPath,
ClientCertPath: clientCertPath,
ClientKeyPath: clientKeyPath,
ServerCertPath: serverCertPath,
ServerKeyPath: serverKeyPath,
}
}

119
libmachine/migrate_test.go Normal file
View File

@ -0,0 +1,119 @@
package libmachine
import (
"os"
"reflect"
"testing"
"github.com/docker/machine/libmachine/auth"
"github.com/docker/machine/libmachine/engine"
"github.com/docker/machine/libmachine/swarm"
)
func TestFillNestedHost(t *testing.T) {
os.Setenv("MACHINE_STORAGE_PATH", "/tmp/migration")
originalHost := &Host{
HostOptions: nil,
SwarmDiscovery: "token://foobar",
SwarmHost: "1.2.3.4:2376",
SwarmMaster: true,
CaCertPath: "",
PrivateKeyPath: "",
ClientCertPath: "",
ClientKeyPath: "",
ServerCertPath: "",
ServerKeyPath: "",
}
hostOptions := &HostOptions{
SwarmOptions: &swarm.SwarmOptions{
Master: true,
Discovery: "token://foobar",
Host: "1.2.3.4:2376",
},
AuthOptions: &auth.AuthOptions{
CaCertPath: "/tmp/migration/certs/ca.pem",
PrivateKeyPath: "/tmp/migration/certs/ca-key.pem",
ClientCertPath: "/tmp/migration/certs/cert.pem",
ClientKeyPath: "/tmp/migration/certs/key.pem",
ServerCertPath: "/tmp/migration/certs/server.pem",
ServerKeyPath: "/tmp/migration/certs/server-key.pem",
},
EngineOptions: &engine.EngineOptions{},
}
expectedHost := &Host{
SwarmHost: "1.2.3.4:2376",
SwarmDiscovery: "token://foobar",
SwarmMaster: true,
HostOptions: hostOptions,
}
host := FillNestedHost(originalHost)
if !reflect.DeepEqual(host, expectedHost) {
t.Logf("\n%+v\n%+v", host, expectedHost)
t.Logf("\n%+v\n%+v", host.HostOptions, expectedHost.HostOptions)
t.Fatal("Expected these structs to be equal, they were different")
}
}
func TestFillNestedHostMetadata(t *testing.T) {
metadata := &HostMetadata{
HostOptions: HostOptions{
EngineOptions: nil,
AuthOptions: nil,
},
StorePath: "/tmp/store",
CaCertPath: "/tmp/store/certs/ca.pem",
ServerCertPath: "/tmp/store/certs/server.pem",
}
expectedAuthOptions := &auth.AuthOptions{
StorePath: "/tmp/store",
CaCertPath: "/tmp/store/certs/ca.pem",
ServerCertPath: "/tmp/store/certs/server.pem",
}
expectedMetadata := &HostMetadata{
HostOptions: HostOptions{
EngineOptions: &engine.EngineOptions{},
AuthOptions: expectedAuthOptions,
},
StorePath: "/tmp/store",
CaCertPath: "/tmp/store/certs/ca.pem",
ServerCertPath: "/tmp/store/certs/server.pem",
}
m := FillNestedHostMetadata(metadata)
if !reflect.DeepEqual(m, expectedMetadata) {
t.Logf("\n%+v\n%+v", m, expectedMetadata)
t.Fatal("Expected these structs to be equal, they were different")
}
}
// Tests a function which "prefills" certificate information for a host
// due to a schema migration from "flat" to a "nested" structure.
func TestGetCertInfoFromHost(t *testing.T) {
os.Setenv("MACHINE_STORAGE_PATH", "/tmp/migration")
host := &Host{
CaCertPath: "",
PrivateKeyPath: "",
ClientCertPath: "",
ClientKeyPath: "",
ServerCertPath: "",
ServerKeyPath: "",
}
expectedCertInfo := CertPathInfo{
CaCertPath: "/tmp/migration/certs/ca.pem",
CaKeyPath: "/tmp/migration/certs/ca-key.pem",
ClientCertPath: "/tmp/migration/certs/cert.pem",
ClientKeyPath: "/tmp/migration/certs/key.pem",
ServerCertPath: "/tmp/migration/certs/server.pem",
ServerKeyPath: "/tmp/migration/certs/server-key.pem",
}
certInfo := getCertInfoFromHost(host)
if !reflect.DeepEqual(expectedCertInfo, certInfo) {
t.Log("\n\n\n", expectedCertInfo, "\n\n\n", certInfo)
t.Fatal("Expected these structs to be equal, they were different")
}
}