Skip to content

Commit 68dc77e

Browse files
committed
pkg/store: refactor YAML loader
Signed-off-by: Akihiro Suda <[email protected]>
1 parent 06dd452 commit 68dc77e

File tree

6 files changed

+68
-78
lines changed

6 files changed

+68
-78
lines changed

cmd/limactl/shell.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ func shellAction(clicontext *cli.Context) error {
5757
if inst.Status == store.StatusStopped {
5858
return errors.Errorf("instance %q is stopped, run `limactl start %s` to start the instance", instName, instName)
5959
}
60-
y, _, err := store.LoadYAMLByInstanceName(instName)
60+
y, err := inst.LoadYAML()
6161
if err != nil {
6262
return err
6363
}

cmd/limactl/start.go

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -34,86 +34,88 @@ var startCommand = &cli.Command{
3434
BashComplete: startBashComplete,
3535
}
3636

37-
func loadOrCreateYAML(clicontext *cli.Context) (y *limayaml.LimaYAML, instDir string, err error) {
37+
func loadOrCreateInstance(clicontext *cli.Context) (*store.Instance, error) {
3838
if clicontext.NArg() > 1 {
39-
return nil, "", errors.Errorf("too many arguments")
39+
return nil, errors.Errorf("too many arguments")
4040
}
4141

4242
arg := clicontext.Args().First()
4343
if arg == "" {
4444
arg = DefaultInstanceName
4545
}
4646

47-
yBytes := limayaml.DefaultTemplate
48-
var instName string
47+
var (
48+
instName string
49+
yBytes = limayaml.DefaultTemplate
50+
err error
51+
)
4952

5053
if argSeemsYAMLPath(arg) {
5154
instName = instNameFromYAMLPath(arg)
5255
logrus.Debugf("interpreting argument %q as a file path for instance %q", arg, instName)
5356
yBytes, err = os.ReadFile(arg)
5457
if err != nil {
55-
return nil, "", err
58+
return nil, err
5659
}
5760
} else {
5861
instName = arg
5962
logrus.Debugf("interpreting argument %q as an instance name %q", arg, instName)
60-
if err = identifiers.Validate(instName); err != nil {
61-
return nil, "", errors.Wrapf(err, "argument must be either an instance name or a YAML file path, got %q", instName)
63+
if err := identifiers.Validate(instName); err != nil {
64+
return nil, errors.Wrapf(err, "argument must be either an instance name or a YAML file path, got %q", instName)
6265
}
63-
y, instDir, err = store.LoadYAMLByInstanceName(instName)
64-
if err == nil {
66+
if inst, err := store.Inspect(instName); err == nil {
6567
logrus.Infof("Using the existing instance %q", instName)
66-
return y, instDir, nil
68+
return inst, nil
6769
} else {
6870
if !errors.Is(err, os.ErrNotExist) {
69-
return nil, "", err
71+
return nil, err
7072
}
7173
}
7274
}
7375
// create a new instance from the template
74-
instDir, err = store.InstanceDir(instName)
76+
instDir, err := store.InstanceDir(instName)
7577
if err != nil {
76-
return nil, "", err
78+
return nil, err
7779
}
7880

7981
if _, err := os.Stat(instDir); !errors.Is(err, os.ErrNotExist) {
80-
return nil, "", errors.Errorf("instance %q already exists (%q)", instName, instDir)
82+
return nil, errors.Errorf("instance %q already exists (%q)", instName, instDir)
8183
}
8284

8385
if clicontext.Bool("tty") {
8486
yBytes, err = openEditor(clicontext, instName, yBytes)
8587
if err != nil {
86-
return nil, "", err
88+
return nil, err
8789
}
8890
if len(yBytes) == 0 {
8991
logrus.Info("Aborting, as requested by saving the file with empty content")
9092
os.Exit(0)
91-
return nil, "", errors.New("should not reach here")
93+
return nil, errors.New("should not reach here")
9294
}
9395
} else {
9496
logrus.Info("Terminal is not available, proceeding without opening an editor")
9597
}
96-
y, err = limayaml.Load(yBytes)
98+
y, err := limayaml.Load(yBytes)
9799
if err != nil {
98-
return nil, "", err
100+
return nil, err
99101
}
100102
if err := limayaml.Validate(*y); err != nil {
101103
if !clicontext.Bool("tty") {
102-
return nil, "", err
104+
return nil, err
103105
}
104106
rejectedYAML := "lima.REJECTED.yaml"
105107
if writeErr := os.WriteFile(rejectedYAML, yBytes, 0644); writeErr != nil {
106-
return nil, "", errors.Wrapf(err, "the YAML is invalid, attempted to save the buffer as %q but failed: %v", rejectedYAML, writeErr)
108+
return nil, errors.Wrapf(err, "the YAML is invalid, attempted to save the buffer as %q but failed: %v", rejectedYAML, writeErr)
107109
}
108-
return nil, "", errors.Wrapf(err, "the YAML is invalid, saved the buffer as %q", rejectedYAML)
110+
return nil, errors.Wrapf(err, "the YAML is invalid, saved the buffer as %q", rejectedYAML)
109111
}
110112
if err := os.MkdirAll(instDir, 0700); err != nil {
111-
return nil, "", err
113+
return nil, err
112114
}
113115
if err := os.WriteFile(filepath.Join(instDir, store.YAMLFileName), yBytes, 0644); err != nil {
114-
return nil, "", err
116+
return nil, err
115117
}
116-
return y, instDir, nil
118+
return store.Inspect(instName)
117119
}
118120

119121
// openEditor opens an editor, and returns the content (not path) of the modified yaml.
@@ -164,16 +166,12 @@ func openEditor(clicontext *cli.Context, name string, initialContent []byte) ([]
164166
}
165167

166168
func startAction(clicontext *cli.Context) error {
167-
y, instDir, err := loadOrCreateYAML(clicontext)
168-
if err != nil {
169-
return err
170-
}
171-
instName, err := store.InstanceNameFromInstanceDir(instDir)
169+
inst, err := loadOrCreateInstance(clicontext)
172170
if err != nil {
173171
return err
174172
}
175173
ctx := clicontext.Context
176-
return start.Start(ctx, instName, instDir, y)
174+
return start.Start(ctx, inst)
177175
}
178176

179177
func argSeemsYAMLPath(arg string) bool {

pkg/hostagent/hostagent.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,22 +56,27 @@ func New(instName string, stdout, stderr io.Writer, sigintCh chan os.Signal) (*H
5656
Level: logrus.DebugLevel,
5757
}
5858

59-
y, instDir, err := store.LoadYAMLByInstanceName(instName)
59+
inst, err := store.Inspect(instName)
60+
if err != nil {
61+
return nil, err
62+
}
63+
64+
y, err := inst.LoadYAML()
6065
if err != nil {
6166
return nil, err
6267
}
6368

6469
qCfg := qemu.Config{
6570
Name: instName,
66-
InstanceDir: instDir,
71+
InstanceDir: inst.Dir,
6772
LimaYAML: y,
6873
}
6974
qExe, qArgs, err := qemu.Cmdline(qCfg)
7075
if err != nil {
7176
return nil, err
7277
}
7378

74-
sshArgs, err := sshutil.SSHArgs(instDir)
79+
sshArgs, err := sshutil.SSHArgs(inst.Dir)
7580
if err != nil {
7681
return nil, err
7782
}
@@ -82,7 +87,7 @@ func New(instName string, stdout, stderr io.Writer, sigintCh chan os.Signal) (*H
8287
a := &HostAgent{
8388
l: l,
8489
y: y,
85-
instDir: instDir,
90+
instDir: inst.Dir,
8691
sshConfig: sshConfig,
8792
portForwarder: newPortForwarder(l, sshConfig, y.SSH.LocalPort),
8893
qExe: qExe,

pkg/start/start.go

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
hostagentapi "github.com/AkihiroSuda/lima/pkg/hostagent/api"
1313
"github.com/AkihiroSuda/lima/pkg/limayaml"
1414
"github.com/AkihiroSuda/lima/pkg/qemu"
15+
"github.com/AkihiroSuda/lima/pkg/store"
1516
"github.com/pkg/errors"
1617
"github.com/sirupsen/logrus"
1718
)
@@ -33,22 +34,27 @@ func ensureDisk(ctx context.Context, instName, instDir string, y *limayaml.LimaY
3334
return nil
3435
}
3536

36-
func Start(ctx context.Context, instName, instDir string, y *limayaml.LimaYAML) error {
37-
haPIDPath := filepath.Join(instDir, "ha.pid")
37+
func Start(ctx context.Context, inst *store.Instance) error {
38+
haPIDPath := filepath.Join(inst.Dir, "ha.pid")
3839
if _, err := os.Stat(haPIDPath); !errors.Is(err, os.ErrNotExist) {
39-
return errors.Errorf("instance %q seems running (hint: remove %q if the instance is not actually running)", instName, haPIDPath)
40+
return errors.Errorf("instance %q seems running (hint: remove %q if the instance is not actually running)", inst.Name, haPIDPath)
4041
}
4142

42-
if err := ensureDisk(ctx, instName, instDir, y); err != nil {
43+
y, err := inst.LoadYAML()
44+
if err != nil {
45+
return err
46+
}
47+
48+
if err := ensureDisk(ctx, inst.Name, inst.Dir, y); err != nil {
4349
return err
4450
}
4551

4652
self, err := os.Executable()
4753
if err != nil {
4854
return err
4955
}
50-
haStdoutPath := filepath.Join(instDir, "ha.stdout.log")
51-
haStderrPath := filepath.Join(instDir, "ha.stderr.log")
56+
haStdoutPath := filepath.Join(inst.Dir, "ha.stdout.log")
57+
haStderrPath := filepath.Join(inst.Dir, "ha.stderr.log")
5258
if err := os.RemoveAll(haStdoutPath); err != nil {
5359
return err
5460
}
@@ -69,7 +75,7 @@ func Start(ctx context.Context, instName, instDir string, y *limayaml.LimaYAML)
6975
haCmd := exec.CommandContext(ctx, self,
7076
"hostagent",
7177
"--pidfile", haPIDPath,
72-
instName)
78+
inst.Name)
7379
haCmd.Stdout = haStdoutW
7480
haCmd.Stderr = haStderrW
7581

@@ -81,7 +87,7 @@ func Start(ctx context.Context, instName, instDir string, y *limayaml.LimaYAML)
8187
return err
8288
}
8389

84-
return watchHostAgentEvents(ctx, instName, haStdoutPath, haStderrPath)
90+
return watchHostAgentEvents(ctx, inst.Name, haStdoutPath, haStderrPath)
8591
// leave the hostagent process running
8692
}
8793

pkg/store/instance.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,28 @@ type Instance struct {
3030
Errors []error `json:"errors,omitempty"`
3131
}
3232

33-
// Inspect returns err only when the instance does not exist.
33+
func (inst *Instance) LoadYAML() (*limayaml.LimaYAML, error) {
34+
if inst.Dir == "" {
35+
return nil, errors.New("inst.Dir is empty")
36+
}
37+
yamlPath := filepath.Join(inst.Dir, YAMLFileName)
38+
return LoadYAMLByFilePath(yamlPath)
39+
}
40+
41+
// Inspect returns err only when the instance does not exist (os.ErrNotExist).
3442
// Other errors are returned as *Instance.Errors
3543
func Inspect(instName string) (*Instance, error) {
3644
inst := &Instance{
3745
Name: instName,
3846
Status: StatusUnknown,
3947
}
40-
y, instDir, err := LoadYAMLByInstanceName(instName)
48+
// InstanceDir validates the instName but does not check whether the instance exists
49+
instDir, err := InstanceDir(instName)
50+
if err != nil {
51+
return nil, err
52+
}
53+
yamlPath := filepath.Join(instDir, YAMLFileName)
54+
y, err := LoadYAMLByFilePath(yamlPath)
4155
if err != nil {
4256
if errors.Is(err, os.ErrNotExist) {
4357
return nil, err

pkg/store/store.go

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,6 @@ func InstanceDir(name string) (string, error) {
6464
return dir, nil
6565
}
6666

67-
// InstanceNameFromInstanceDir extracts the instance name
68-
// from the path of the instance directory.
69-
// e.g. "foo" for "/Users/somebody/.lima/foo".
70-
func InstanceNameFromInstanceDir(s string) (string, error) {
71-
base := filepath.Base(s)
72-
return base, identifiers.Validate(base)
73-
}
74-
7567
// LoadYAMLByFilePath loads and validates the yaml.
7668
func LoadYAMLByFilePath(filePath string) (*limayaml.LimaYAML, error) {
7769
if _, err := os.Stat(filePath); err != nil {
@@ -90,28 +82,3 @@ func LoadYAMLByFilePath(filePath string) (*limayaml.LimaYAML, error) {
9082
}
9183
return y, nil
9284
}
93-
94-
// YAMLFilePathByInstanceName returns the yaml file path but does not
95-
// check whether it exists.
96-
func YAMLFilePathByInstanceName(instName string) (string, string, error) {
97-
instDir, err := InstanceDir(instName)
98-
if err != nil {
99-
return "", instDir, err
100-
}
101-
instYAMLPath := filepath.Join(instDir, YAMLFileName)
102-
return instYAMLPath, instDir, nil
103-
}
104-
105-
// LoadYAMLByInstanceName loads and validates the yaml.
106-
// LoadYAMLByInstanceName may return os.ErrNotExist
107-
func LoadYAMLByInstanceName(instName string) (*limayaml.LimaYAML, string, error) {
108-
instYAMLPath, instDir, err := YAMLFilePathByInstanceName(instName)
109-
if err != nil {
110-
return nil, "", err
111-
}
112-
y, err := LoadYAMLByFilePath(instYAMLPath)
113-
if err != nil {
114-
return nil, "", err
115-
}
116-
return y, instDir, nil
117-
}

0 commit comments

Comments
 (0)