-
Notifications
You must be signed in to change notification settings - Fork 260
Expand file tree
/
Copy pathlibmachine.go
More file actions
131 lines (109 loc) · 3.5 KB
/
Copy pathlibmachine.go
File metadata and controls
131 lines (109 loc) · 3.5 KB
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package libmachine
import (
"context"
"encoding/json"
"fmt"
"io"
"time"
crcerrors "github.com/code-ready/crc/pkg/crc/errors"
log "github.com/code-ready/crc/pkg/crc/logging"
"github.com/code-ready/crc/pkg/drivers/hyperv"
"github.com/code-ready/crc/pkg/libmachine/host"
"github.com/code-ready/crc/pkg/libmachine/persist"
"github.com/code-ready/machine/libmachine/drivers"
rpcdriver "github.com/code-ready/machine/libmachine/drivers/rpc"
"github.com/code-ready/machine/libmachine/state"
"github.com/pkg/errors"
)
type API interface {
io.Closer
NewHost(driverName string, driverPath string, rawDriver []byte) (*host.Host, error)
Create(ctx context.Context, h *host.Host) error
persist.Store
}
type Client struct {
*persist.Filestore
clientDriverFactory rpcdriver.RPCClientDriverFactory
}
func NewClient(storePath string) *Client {
return &Client{
Filestore: persist.NewFilestore(storePath),
clientDriverFactory: rpcdriver.NewRPCClientDriverFactory(),
}
}
func (api *Client) NewHost(driverName string, driverPath string, rawDriver []byte) (*host.Host, error) {
var driver drivers.Driver
if driverName == "hyperv" {
driver = hyperv.NewDriver("", "")
if err := json.Unmarshal(rawDriver, &driver); err != nil {
return nil, err
}
} else {
var err error
driver, err = api.clientDriverFactory.NewRPCClientDriver(driverName, driverPath, rawDriver)
if err != nil {
return nil, err
}
}
return &host.Host{
ConfigVersion: host.Version,
Name: driver.GetMachineName(),
Driver: driver,
DriverName: driver.DriverName(),
DriverPath: driverPath,
RawDriver: rawDriver,
}, nil
}
func (api *Client) Load(name string) (*host.Host, error) {
h, err := api.Filestore.Load(name)
if err != nil {
return nil, err
}
if h.DriverName == "hyperv" {
driver := hyperv.NewDriver("", "")
if err := json.Unmarshal(h.RawDriver, &driver); err != nil {
return nil, err
}
h.Driver = driver
return h, nil
}
d, err := api.clientDriverFactory.NewRPCClientDriver(h.DriverName, h.DriverPath, h.RawDriver)
if err != nil {
return nil, err
}
h.Driver = d
return h, nil
}
// Create is the wrapper method which covers all of the boilerplate around
// actually creating, provisioning, and persisting an instance in the store.
func (api *Client) Create(ctx context.Context, h *host.Host) error {
log.Debug("Running pre-create checks...")
if err := h.Driver.PreCreateCheck(); err != nil {
return errors.Wrap(err, "error with pre-create check")
}
if err := api.Save(h); err != nil {
return fmt.Errorf("Error saving host to store before attempting creation: %s", err)
}
log.Debug("Creating machine...")
if err := h.Driver.Create(); err != nil {
return fmt.Errorf("Error in driver during machine creation: %s", err)
}
if err := h.Driver.Start(); err != nil {
return fmt.Errorf("Error in driver during machine start: %s", err)
}
if err := api.Save(h); err != nil {
return fmt.Errorf("Error saving host to store after attempting creation: %s", err)
}
log.Debug("Waiting for machine to be running, this may take a few minutes...")
if err := crcerrors.RetryAfterWithContext(ctx, 3*time.Minute, host.MachineInState(h.Driver, state.Running), 3*time.Second); err != nil {
return fmt.Errorf("Error waiting for machine to be running: %s", err)
}
log.Debug("Machine is up and running!")
if err := api.SetExists(h.Name); err != nil {
log.Debug("Failed to record VM existence")
}
return nil
}
func (api *Client) Close() error {
return api.clientDriverFactory.Close()
}