-
Notifications
You must be signed in to change notification settings - Fork 79
/
Copy pathipxe.go
95 lines (81 loc) · 2.21 KB
/
ipxe.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
package job
import (
"net/http"
"github.com/pkg/errors"
"github.com/tinkerbell/boots/conf"
"github.com/tinkerbell/boots/ipxe"
)
var (
byDistro = make(map[string]BootScript)
bySlug = make(map[string]BootScript)
defaultInstaller BootScript
scripts = map[string]BootScript{
"auto": auto,
"shell": shell,
}
)
type BootScript func(Job, *ipxe.Script)
func RegisterDefaultInstaller(bootScript BootScript) {
if defaultInstaller != nil {
err := errors.New("default installer already registered!")
joblog.Fatal(err)
}
defaultInstaller = bootScript
}
func RegisterDistro(name string, builder BootScript) {
if _, ok := byDistro[name]; ok {
err := errors.Errorf("distro %q already registered!", name)
joblog.Fatal(err, "distro", name)
}
byDistro[name] = builder
}
func RegisterSlug(name string, builder BootScript) {
if _, ok := bySlug[name]; ok {
err := errors.Errorf("slug %q already registered!", name)
joblog.Fatal(err, "slug", name)
}
bySlug[name] = builder
}
func (j Job) serveBootScript(w http.ResponseWriter, req *http.Request, name string) {
fn, ok := scripts[name]
if !ok {
w.WriteHeader(http.StatusNotFound)
j.With("script", name).Error(errors.New("boot script not found"))
return
}
s := ipxe.NewScript()
s.Set("iface", j.InterfaceName(0)).Or("shell")
s.Set("tinkerbell", "http://"+conf.PublicFQDN)
s.Set("syslog_host", conf.PublicSyslogFQDN)
s.Set("ipxe_cloud_config", "packet")
s.Echo("Packet.net Baremetal - iPXE boot")
fn(j, s)
if _, err := w.Write(s.Bytes()); err != nil {
j.With("script", name).Error(errors.Wrap(err, "unable to write boot script"))
return
}
}
func auto(j Job, s *ipxe.Script) {
if j.instance == nil {
j.Info(errors.New("no device to boot, providing an iPXE shell"))
shell(j, s)
return
}
if f, ok := bySlug[j.hardware.OperatingSystem().Slug]; ok {
f(j, s)
return
}
if f, ok := byDistro[j.hardware.OperatingSystem().Distro]; ok {
f(j, s)
return
}
if defaultInstaller != nil {
defaultInstaller(j, s)
return
}
j.With("slug", j.hardware.OperatingSystem().Slug, "distro", j.hardware.OperatingSystem().Distro).Error(errors.New("unsupported slug/distro"))
shell(j, s)
}
func shell(j Job, s *ipxe.Script) {
s.Shell()
}