forked from ns1/waitron
/
machine.go
130 lines (118 loc) · 3.6 KB
/
machine.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
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
package main
import (
"errors"
"fmt"
"github.com/flosch/pongo2"
"github.com/satori/go.uuid"
"gopkg.in/yaml.v2"
"io/ioutil"
"log"
"os"
"path"
"strings"
)
// Machine configuration
type Machine struct {
Hostname string
OperatingSystem string
Finish string
Preseed string
ShortName string
Domain string
Token string // This is set by the service
Network []Interface
Params map[string]string
ImageURL string `yaml:"image_url"`
Kernel string
Initrd string
Cmdline string
}
// Interface Configuration
type Interface struct {
Name string
IPAddress string
MacAddress string
Gateway string
Netmask string
}
// PixieConfig boot configuration
type PixieConfig struct {
Kernel string `json:"kernel" description:"The kernel file"`
Initrd []string `json:"initrd"`
Cmdline string `json:"cmdline"`
}
func machineDefinition(hostname string, machinePath string) (Machine, error) {
var m Machine
data, err := ioutil.ReadFile(path.Join(machinePath, hostname+".yaml"))
if err != nil {
return Machine{}, err
}
err = yaml.Unmarshal(data, &m)
if err != nil {
return Machine{}, err
}
hostSlice := strings.Split(m.Hostname, ".")
m.ShortName = hostSlice[0]
m.Domain = strings.Join(hostSlice[1:], ".")
return m, nil
}
// Render template among with machine and config struct
func (m Machine) renderTemplate(template string, config Config) (string, error) {
template = path.Join(config.TemplatePath, template)
if _, err := os.Stat(template); err != nil {
return "", errors.New("Template does not exist")
}
var tpl = pongo2.Must(pongo2.FromFile(template))
result, err := tpl.Execute(pongo2.Context{"machine": m, "config": config})
if err != nil {
return "", err
}
return result, err
}
// Posts machine macaddress to the forman proxy among with pxe configuration
func (m Machine) setBuildMode(config Config) error {
// Generate a random token used to authenticate requests
config.Tokens[m.Hostname] = uuid.NewV4().String()
log.Println(fmt.Sprintf("%s installation token: %s", m.Hostname, config.Tokens[m.Hostname]))
// Add token to machine struct
m.Token = config.Tokens[m.Hostname]
//Add to the MachineBuild table
config.MachineBuild[fmt.Sprintf("%s", m.Network[0].MacAddress)] = m.Hostname
//Change machine state
config.MachineState[m.Hostname] = "Installing"
return nil
}
/*
cancelBuild remove the machines mac address from the MachineBuild map
which stops waitron from serving the PixieConfig used by pixiecore
*/
func (m Machine) cancelBuildMode(config Config) error {
//Delete mac from the building map
delete(config.MachineBuild, fmt.Sprintf("%s", m.Network[0].MacAddress))
//Change machine state
config.MachineState[m.Hostname] = "Installed"
return nil
}
// Return string2 if string1 is empty
func defaultString(string1 string, string2 string) string {
if string1 == "" {
return string2
}
return string1
}
// Builds pxe config to be sent to pixiecore
func (m Machine) pixieInit(config Config) (PixieConfig, error) {
pixieConfig := PixieConfig{}
tpl, err := pongo2.FromString(defaultString(m.Cmdline, config.DefaultCmdline))
if err != nil {
return pixieConfig, err
}
cmdline, err := tpl.Execute(pongo2.Context{"BaseURL": config.BaseURL, "Hostname": m.Hostname, "Token": m.Token})
if err != nil {
return pixieConfig, err
}
pixieConfig.Kernel = defaultString(m.ImageURL+m.Kernel, config.DefaultImageURL+config.DefaultKernel)
pixieConfig.Initrd = []string{defaultString(m.ImageURL+m.Initrd, config.DefaultImageURL+config.DefaultInitrd)}
pixieConfig.Cmdline = cmdline
return pixieConfig, nil
}