Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
lima-vm
GitHub Repository: lima-vm/lima
Path: blob/master/pkg/instance/create.go
2611 views
1
// SPDX-FileCopyrightText: Copyright The Lima Authors
2
// SPDX-License-Identifier: Apache-2.0
3
4
package instance
5
6
import (
7
"context"
8
"errors"
9
"fmt"
10
"os"
11
"path/filepath"
12
13
"github.com/lima-vm/lima/v2/pkg/cidata"
14
"github.com/lima-vm/lima/v2/pkg/driverutil"
15
"github.com/lima-vm/lima/v2/pkg/limatype"
16
"github.com/lima-vm/lima/v2/pkg/limatype/dirnames"
17
"github.com/lima-vm/lima/v2/pkg/limatype/filenames"
18
"github.com/lima-vm/lima/v2/pkg/limayaml"
19
"github.com/lima-vm/lima/v2/pkg/osutil"
20
"github.com/lima-vm/lima/v2/pkg/store"
21
"github.com/lima-vm/lima/v2/pkg/version"
22
)
23
24
func Create(ctx context.Context, instName string, instConfig []byte, saveBrokenYAML bool) (*limatype.Instance, error) {
25
if instName == "" {
26
return nil, errors.New("got empty instName")
27
}
28
if len(instConfig) == 0 {
29
return nil, errors.New("got empty instConfig")
30
}
31
32
instDir, err := dirnames.InstanceDir(instName)
33
if err != nil {
34
return nil, err
35
}
36
37
// the full path of the socket name must be less than UNIX_PATH_MAX chars.
38
maxSockName := filepath.Join(instDir, filenames.LongestSock)
39
if len(maxSockName) >= osutil.UnixPathMax {
40
return nil, fmt.Errorf("instance name %q too long: %q must be less than UNIX_PATH_MAX=%d characters, but is %d",
41
instName, maxSockName, osutil.UnixPathMax, len(maxSockName))
42
}
43
if _, err := os.Stat(instDir); !errors.Is(err, os.ErrNotExist) {
44
return nil, fmt.Errorf("instance %q already exists (%q)", instName, instDir)
45
}
46
// limayaml.Load() needs to pass the store file path to limayaml.FillDefault() to calculate default MAC addresses
47
filePath := filepath.Join(instDir, filenames.LimaYAML)
48
loadedInstConfig, err := limayaml.LoadWithWarnings(ctx, instConfig, filePath)
49
if err != nil {
50
return nil, err
51
}
52
if err := driverutil.ResolveVMType(ctx, loadedInstConfig, filePath); err != nil {
53
return nil, fmt.Errorf("failed to resolve vm for %q: %w", filePath, err)
54
}
55
if err := limayaml.Validate(loadedInstConfig, true); err != nil {
56
if !saveBrokenYAML {
57
return nil, err
58
}
59
rejectedYAML := "lima.REJECTED.yaml"
60
if writeErr := os.WriteFile(rejectedYAML, instConfig, 0o644); writeErr != nil {
61
return nil, fmt.Errorf("the YAML is invalid, attempted to save the buffer as %q but failed: %w: %w", rejectedYAML, writeErr, err)
62
}
63
return nil, fmt.Errorf("the YAML is invalid, saved the buffer as %q: %w", rejectedYAML, err)
64
}
65
if err := os.MkdirAll(instDir, 0o700); err != nil {
66
return nil, err
67
}
68
if err := os.WriteFile(filePath, instConfig, 0o644); err != nil {
69
return nil, err
70
}
71
if err := cidata.GenerateCloudConfig(ctx, instDir, instName, loadedInstConfig); err != nil {
72
return nil, err
73
}
74
if err := os.WriteFile(filepath.Join(instDir, filenames.LimaVersion), []byte(version.Version), 0o444); err != nil {
75
return nil, err
76
}
77
78
inst, err := store.Inspect(ctx, instName)
79
if err != nil {
80
return nil, err
81
}
82
83
limaDriver, err := driverutil.CreateConfiguredDriver(inst, 0)
84
if err != nil {
85
return nil, fmt.Errorf("failed to create driver instance: %w", err)
86
}
87
88
if err := limaDriver.Create(ctx); err != nil {
89
return nil, err
90
}
91
92
return inst, nil
93
}
94
95