Skip to content

Commit

Permalink
cluster: update docker-desktop client for new docker protocol. Fixes …
Browse files Browse the repository at this point in the history
…issue #105 (#106)
  • Loading branch information
nicks authored Apr 12, 2021
1 parent b6f808a commit 80c2784
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 26 deletions.
67 changes: 42 additions & 25 deletions pkg/cluster/docker_desktop.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,19 +127,51 @@ func (c DockerDesktopClient) SetSettingValue(ctx context.Context, key, newValue
return c.writeSettings(ctx, settings)
}

// Returns true if the value changed, false if the value is unchanged.
// Returns an error if not able to set.
func (c DockerDesktopClient) applySet(settings map[string]interface{}, key, newValue string) (bool, error) {
spec, err := c.lookupMapAt(settings, key)
parts := strings.Split(key, ".")
if len(parts) <= 1 {
return false, fmt.Errorf("key cannot be set: %s", key)
}

parentKey := strings.Join(parts[:len(parts)-1], ".")
childKey := parts[len(parts)-1]
parentSpec, err := c.lookupMapAt(settings, parentKey)
if err != nil {
return false, err
}

switch v := spec["value"].(type) {
// In Docker Desktop, a boolean setting can be stored in one of two formats:
//
// {"kubernetes": {"enabled": true}}
// {"kubernetes": {"enabled": {"value": true}}}
//
// To resolve this problem, we create some intermediate variables:
// v - the value that we're replacing
// vParent - the map owning the value we're replacing
// vParentKey - the key where v lives in vParent
v, ok := parentSpec[childKey]
if !ok {
return false, fmt.Errorf("nothing found at DockerDesktop setting %q", key)
}

vParent := parentSpec
vParentKey := childKey
childMap, isMap := v.(map[string]interface{})
if isMap {
v = childMap["value"]
vParent = childMap
vParentKey = "value"
}

switch v := v.(type) {
case bool:
if newValue == "true" {
spec["value"] = true
vParent[vParentKey] = true
return !v, nil
} else if newValue == "false" {
spec["value"] = false
vParent[vParentKey] = false
return v, nil
}

Expand All @@ -151,23 +183,23 @@ func (c DockerDesktopClient) applySet(settings map[string]interface{}, key, newV
return false, fmt.Errorf("expected number for setting %q, got: %s. Error: %v", key, newValue, err)
}

max, ok := spec["max"].(float64)
max, ok := vParent["max"].(float64)
if ok && newValFloat > max {
return false, fmt.Errorf("setting value %q: %s greater than max allowed (%f)", key, newValue, max)
}
min, ok := spec["min"].(float64)
min, ok := vParent["min"].(float64)
if ok && newValFloat < min {
return false, fmt.Errorf("setting value %q: %s less than min allowed (%f)", key, newValue, min)
}

if newValFloat != v {
spec["value"] = newValFloat
vParent[vParentKey] = newValFloat
return true, nil
}
return false, nil
case string:
if newValue != v {
spec["value"] = newValue
vParent[vParentKey] = newValue
return true, nil
}
return false, nil
Expand All @@ -179,7 +211,7 @@ func (c DockerDesktopClient) applySet(settings map[string]interface{}, key, newV
pathSpec = append(pathSpec, map[string]interface{}{"path": path, "cached": false})
}

spec["value"] = pathSpec
vParent[vParentKey] = pathSpec

// Don't bother trying to optimize this.
return true, nil
Expand Down Expand Up @@ -262,22 +294,7 @@ func (c DockerDesktopClient) lookupMapAt(settings map[string]interface{}, key st
}

func (c DockerDesktopClient) setK8sEnabled(settings map[string]interface{}, newVal bool) (changed bool, err error) {
enabledSetting, err := c.lookupMapAt(settings, "vm.kubernetes.enabled")
if err != nil {
return false, err
}

isEnabled, ok := enabledSetting["value"].(bool)
if !ok {
return false, fmt.Errorf("expected bool at DockerDesktop setting vm.kubernetes.enabled.value, got: %T",
enabledSetting["value"])
}

if isEnabled == newVal {
return false, nil
}
enabledSetting["value"] = newVal
return true, nil
return c.applySet(settings, "vm.kubernetes.enabled", fmt.Sprintf("%v", newVal))
}

func (c DockerDesktopClient) ensureMinCPU(settings map[string]interface{}, desired int) (changed bool, err error) {
Expand Down
29 changes: 28 additions & 1 deletion pkg/cluster/docker_desktop_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,31 @@ func TestEnableKubernetes(t *testing.T) {
f := newD4MFixture(t)
defer f.TearDown()

f.settings = getSettingsOldJSON

ctx := context.Background()
settings, err := f.d4m.settings(ctx)
require.NoError(t, err)

changed, err := f.d4m.setK8sEnabled(settings, true)
assert.True(t, changed)
require.NoError(t, err)

err = f.d4m.writeSettings(ctx, settings)
require.NoError(t, err)

expected := strings.Replace(postSettingsJSON,
`"kubernetes":{"enabled":false,`,
`"kubernetes":{"enabled":true,`, 1)
assert.Equal(t,
f.postSettings,
f.readerToMap(strings.NewReader(expected)))
}

func TestEnableKubernetesOldFormat(t *testing.T) {
f := newD4MFixture(t)
defer f.TearDown()

ctx := context.Background()
settings, err := f.d4m.settings(ctx)
require.NoError(t, err)
Expand Down Expand Up @@ -199,7 +224,9 @@ func TestSetSettingValueFileSharing(t *testing.T) {

}

var getSettingsJSON = `{"vm":{"proxy":{"exclude":{"value":"","locked":false},"http":{"value":"","locked":false},"https":{"value":"","locked":false},"mode":{"value":"system","locked":false}},"daemon":{"locks":[],"json":"{\"debug\":true,\"experimental\":false}"},"resources":{"cpus":{"value":2,"min":1,"locked":false,"max":8},"memoryMiB":{"value":8192,"min":1024,"locked":false,"max":16384},"diskSizeMiB":{"value":61035,"used":18486,"locked":false},"dataFolder":{"value":"\/Users\/nick\/Library\/Containers\/com.docker.docker\/Data\/vms\/0\/data","locked":false},"swapMiB":{"value":1024,"min":512,"locked":false,"max":4096}},"fileSharing":{"value":[{"path":"\/Users","cached":false},{"path":"\/Volumes","cached":false},{"path":"\/private","cached":false},{"path":"\/tmp","cached":false}],"locked":false},"kubernetes":{"enabled":{"value":false,"locked":false},"stackOrchestrator":{"value":false,"locked":false},"showSystemContainers":{"value":false,"locked":false}},"network":{"dns":{"locked":false},"vpnkitCIDR":{"value":"192.168.65.0\/24","locked":false},"automaticDNS":{"value":true,"locked":false}}},"desktop":{"exportInsecureDaemon":{"value":false,"locked":false},"useGrpcfuse":{"value":true,"locked":false},"backupData":{"value":false,"locked":false},"checkForUpdates":{"value":true,"locked":false},"useCredentialHelper":{"value":true,"locked":false},"autoStart":{"value":false,"locked":false},"analyticsEnabled":{"value":true,"locked":false}},"wslIntegration":{"distros":{"value":[],"locked":false},"enableIntegrationWithDefaultWslDistro":{"value":false,"locked":false}},"cli":{"useCloudCli":{"value":true,"locked":false},"experimental":{"value":true,"locked":false}}}`
var getSettingsOldJSON = `{"vm":{"proxy":{"exclude":{"value":"","locked":false},"http":{"value":"","locked":false},"https":{"value":"","locked":false},"mode":{"value":"system","locked":false}},"daemon":{"locks":[],"json":"{\"debug\":true,\"experimental\":false}"},"resources":{"cpus":{"value":2,"min":1,"locked":false,"max":8},"memoryMiB":{"value":8192,"min":1024,"locked":false,"max":16384},"diskSizeMiB":{"value":61035,"used":18486,"locked":false},"dataFolder":{"value":"\/Users\/nick\/Library\/Containers\/com.docker.docker\/Data\/vms\/0\/data","locked":false},"swapMiB":{"value":1024,"min":512,"locked":false,"max":4096}},"fileSharing":{"value":[{"path":"\/Users","cached":false},{"path":"\/Volumes","cached":false},{"path":"\/private","cached":false},{"path":"\/tmp","cached":false}],"locked":false},"kubernetes":{"enabled":{"value":false,"locked":false},"stackOrchestrator":{"value":false,"locked":false},"showSystemContainers":{"value":false,"locked":false}},"network":{"dns":{"locked":false},"vpnkitCIDR":{"value":"192.168.65.0\/24","locked":false},"automaticDNS":{"value":true,"locked":false}}},"desktop":{"exportInsecureDaemon":{"value":false,"locked":false},"useGrpcfuse":{"value":true,"locked":false},"backupData":{"value":false,"locked":false},"checkForUpdates":{"value":true,"locked":false},"useCredentialHelper":{"value":true,"locked":false},"autoStart":{"value":false,"locked":false},"analyticsEnabled":{"value":true,"locked":false}},"wslIntegration":{"distros":{"value":[],"locked":false},"enableIntegrationWithDefaultWslDistro":{"value":false,"locked":false}},"cli":{"useCloudCli":{"value":true,"locked":false},"experimental":{"value":true,"locked":false}}}`

var getSettingsJSON = `{"vm":{"proxy":{"exclude":"","http":"","https":"","mode":"system"},"daemon":{"locks":[],"json":"{\"debug\":true,\"experimental\":false}"},"resources":{"cpus":{"value":2,"min":1,"locked":false,"max":8},"memoryMiB":{"value":8192,"min":1024,"locked":false,"max":16384},"diskSizeMiB":{"value":61035,"used":18486,"locked":false},"dataFolder":"\/Users\/nick\/Library\/Containers\/com.docker.docker\/Data\/vms\/0\/data","swapMiB":{"value":1024,"min":512,"locked":false,"max":4096}},"fileSharing":{"value":[{"path":"\/Users","cached":false},{"path":"\/Volumes","cached":false},{"path":"\/private","cached":false},{"path":"\/tmp","cached":false}],"locked":false},"kubernetes":{"enabled":false,"stackOrchestrator":false,"showSystemContainers":false},"network":{"dns":{"locked":false},"vpnkitCIDR":"192.168.65.0\/24","automaticDNS":true}},"desktop":{"exportInsecureDaemon":false,"useGrpcfuse":true,"backupData":false,"checkForUpdates":true,"useCredentialHelper":true,"autoStart":false,"analyticsEnabled":true},"wslIntegration":{"distros":[],"enableIntegrationWithDefaultWslDistro":false},"cli":{"useCloudCli":true,"experimental":true}}`

var postSettingsJSON = `{"desktop":{"exportInsecureDaemon":false,"useGrpcfuse":true,"backupData":false,"checkForUpdates":true,"useCredentialHelper":true,"autoStart":false,"analyticsEnabled":true},"cli":{"useCloudCli":true,"experimental":true},"vm":{"daemon":"{\"debug\":true,\"experimental\":false}","fileSharing":[{"path":"/Users","cached":false},{"path":"/Volumes","cached":false},{"path":"/private","cached":false},{"path":"/tmp","cached":false}],"kubernetes":{"enabled":false,"stackOrchestrator":false,"showSystemContainers":false},"network":{"vpnkitCIDR":"192.168.65.0/24","automaticDNS":true},"proxy":{"exclude":"","http":"","https":"","mode":"system"},"resources":{"cpus":2,"memoryMiB":8192,"diskSizeMiB":61035,"dataFolder":"/Users/nick/Library/Containers/com.docker.docker/Data/vms/0/data","swapMiB":1024}},"wslIntegration":{"distros":[],"enableIntegrationWithDefaultWslDistro":false}}`

Expand Down

0 comments on commit 80c2784

Please sign in to comment.