-
Notifications
You must be signed in to change notification settings - Fork 94
/
config_darwin.go
114 lines (92 loc) · 3.38 KB
/
config_darwin.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//go:build darwin
package config
import (
"fmt"
"strconv"
"strings"
"github.com/spf13/afero"
"gopkg.in/yaml.v3"
"github.com/runfinch/finch/pkg/command"
"github.com/runfinch/finch/pkg/flog"
"github.com/runfinch/finch/pkg/fmemory"
"github.com/runfinch/finch/pkg/system"
)
// SystemSettings represents the system configuration specifc to macOS.
type SystemSettings struct {
CPUs *int `yaml:"cpus,omitempty"`
Memory *string `yaml:"memory,omitempty"`
AdditionalDirectories []AdditionalDirectory `yaml:"additional_directories,omitempty"`
Rosetta *bool `yaml:"rosetta,omitempty"`
SharedSystemSettings `yaml:",inline"`
}
// Finch represents the configuration file for Finch CLI.
type Finch struct {
SystemSettings `yaml:",inline"`
SharedSettings `yaml:",inline"`
}
// SupportsVirtualizationFramework checks if the user's system supports Virtualization.framework.
func SupportsVirtualizationFramework(cmdCreator command.Creator) (bool, error) {
cmd := cmdCreator.Create("sw_vers", "-productVersion")
out, err := cmd.Output()
if err != nil {
return false, fmt.Errorf("failed to run sw_vers command: %w", err)
}
splitVer := strings.Split(string(out), ".")
if len(splitVer) == 0 {
return false, fmt.Errorf("unexpected result from string split: %v", splitVer)
}
majorVersionInt, err := strconv.ParseInt(splitVer[0], 10, 64)
if err != nil {
return false, fmt.Errorf("failed to parse split sw_vers output (%s) into int: %w", splitVer[0], err)
}
if majorVersionInt >= 13 {
return true, nil
}
return false, nil
}
// ModifyFinchConfig Modify Finch's configuration from user inputs.
func ModifyFinchConfig(fs afero.Fs, logger flog.Logger, finchConfigPath string, opts VMConfigOpts) (bool, error) {
var isConfigUpdated bool
systemDeps := system.NewStdLib()
mem := fmemory.NewMemory()
finchCfg, err := loadFinchConfig(fs, finchConfigPath, logger, systemDeps, mem)
if err != nil {
return isConfigUpdated, err
}
cpus, memory := opts.CPUs, opts.Memory
if cpus != DefaultCPUs && cpus != *finchCfg.CPUs {
*finchCfg.CPUs = cpus
isConfigUpdated = true
}
if memory != DefaultMemory && memory != *finchCfg.Memory {
*finchCfg.Memory = memory
isConfigUpdated = true
}
if !isConfigUpdated {
return isConfigUpdated, fmt.Errorf("the number of CPUs or the amount of memory should be at least one valid value")
}
if err := validate(finchCfg, logger, systemDeps, mem); err != nil {
return false, fmt.Errorf("failed to validate config file: %w", err)
}
if err := writeConfig(finchCfg, fs, finchConfigPath); err != nil {
return false, err
}
return isConfigUpdated, nil
}
// loadFinchConfig Load Finch's configuration from a YAML file.
func loadFinchConfig(fs afero.Fs, finchConfigPath string, logger flog.Logger, systemDeps LoadSystemDeps, mem fmemory.Memory) (*Finch, error) {
b, err := afero.ReadFile(fs, finchConfigPath)
if err != nil {
return nil, fmt.Errorf("failed to read config file: %w", err)
}
var cfg Finch
if err := yaml.Unmarshal(b, &cfg); err != nil {
return nil, fmt.Errorf("failed to unmarshal config file: %w", err)
}
if err := validate(&cfg, logger, systemDeps, mem); err != nil {
return nil, fmt.Errorf("failed to validate config file: %w", err)
}
return &cfg, nil
}