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
package computevm
import (
"cmp"
"context"
"fmt"
"sync"
"time"
kruntime "k8s.io/apimachinery/pkg/runtime"
"github.com/johnandersen777/socialweb-computer-kcp/api/v1alpha1"
"github.com/johnandersen777/socialweb-computer-kcp/internal/compute/firecracker"
"github.com/johnandersen777/socialweb-computer-kcp/internal/computevm"
"github.com/johnandersen777/socialweb-computer-kcp/internal/controllers/firecrackervm"
ctlruntime "github.com/johnandersen777/socialweb-computer-kcp/internal/controllers/runtime"
"github.com/johnandersen777/socialweb-computer-kcp/internal/controllers/runtime/manifests"
"github.com/johnandersen777/socialweb-computer-kcp/internal/hostprocess"
"github.com/johnandersen777/socialweb-computer-kcp/internal/hostsvc"
"github.com/johnandersen777/socialweb-computer-kcp/internal/kit/supervise"
)
const RestartMax = time.Minute
func Run(ctx context.Context, c computevm.Config) error {
log := c.Log
var wg sync.WaitGroup
defer wg.Wait()
wg.Go(func() { hostprocess.Supervise(ctx, computevm.Supervisor(c)) })
supervise.Restart(ctx, "computevm", supervise.Backoff{Min: computevm.RetryAfter, Max: RestartMax, OnError: func(err error, after time.Duration) {
if log != nil {
log.Error("the ComputeVM and FirecrackerVM controllers stopped; starting them again", "err", fmt.Sprint(err), "after", after.String())
}
}}, func(ctx context.Context) error { return run(ctx, c) })
return nil
}
func run(ctx context.Context, c computevm.Config) error {
host, err := computevm.Open(ctx, c)
if err != nil {
return err
}
workspace := cmp.Or(c.Workspace, hostprocess.DefaultWorkspace)
mgr, err := ctlruntime.NewManager(ctlruntime.Config{Rest: host.Rest, ExportWorkspace: manifests.Rebase(workspace, ctlruntime.DefaultExportWorkspace),
AddToScheme: []func(*kruntime.Scheme) error{v1alpha1.AddToScheme}, Log: c.Log})
if err != nil {
return err
}
if _, err := Register(mgr, host); err != nil {
return err
}
placement := firecrackervm.NewPlacement(host)
provider, err := firecracker.New(firecracker.Config{Handle: c.Handle, Log: c.Log},
firecracker.Deps{Runtime: c.Runtime, Units: c.Manager, UserData: host, Placement: placement, Processes: hostsvc.Processes{}})
if err != nil {
return err
}
defer provider.Close()
fc, err := firecrackervm.Register(ctx, mgr, provider, host, placement)
if err != nil {
return err
}
caps := c.Runtime.Capabilities()
host.Log().Info("the ComputeVM and FirecrackerVM controllers run in the core", "workspace", workspace, "backend", string(caps.Backend),
"hypervisor", caps.Hypervisor, "enforcesLimits", caps.EnforcesLimits, "gracefulStop", caps.GracefulStop)
ctx, cancel := context.WithCancel(ctx)
defer cancel()
var wg sync.WaitGroup
defer wg.Wait()
wg.Go(func() {
fc.Run(ctx)
cancel()
})
return mgr.Start(ctx)
}