Initial commit of Warewulf v4 POC
This commit is contained in:
29
Makefile
Normal file
29
Makefile
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
|
||||||
|
|
||||||
|
files:
|
||||||
|
sudo install -d -m 0755 /var/warewulf/provision
|
||||||
|
sudo install -d -m 0755 /var/warewulf/provision/kernels
|
||||||
|
sudo install -d -m 0755 /var/warewulf/provision/overlays
|
||||||
|
sudo install -d -m 0755 /var/warewulf/provision/bases
|
||||||
|
sudo install -d -m 0755 /etc/warewulf/
|
||||||
|
sudo install -m 0644 dhcpd.conf /etc/dhcp/dhcpd.conf
|
||||||
|
sudo install -m 0644 nodes.yaml /etc/warewulf/nodes.yaml
|
||||||
|
sudo cp -r tftpboot/* /var/lib/tftpboot/warewulf/ipxe/
|
||||||
|
sudo cp -r overlays /etc/warewulf/
|
||||||
|
|
||||||
|
services: files
|
||||||
|
sudo systemctl enable tftp
|
||||||
|
sudo systemctl restart tftp
|
||||||
|
sudo systemctl enable dhcpd
|
||||||
|
sudo systemctl restart dhcpd
|
||||||
|
|
||||||
|
build:
|
||||||
|
go build cmd/warewulfd/warewulfd.go
|
||||||
|
go build cmd/wwbuild/wwbuild.go
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f warewulfd
|
||||||
|
rm -f wwbuild
|
||||||
|
|
||||||
|
install: build files services
|
||||||
|
|
||||||
18
README.md
18
README.md
@@ -1 +1,17 @@
|
|||||||
# warewulf
|
# warewulf
|
||||||
|
|
||||||
|
This is built on CentOS-7. More needs to be done to make it work on other
|
||||||
|
distributions and versions specifically with the system service
|
||||||
|
compoenents.
|
||||||
|
|
||||||
|
In a nutshell, to use:
|
||||||
|
|
||||||
|
1. make install
|
||||||
|
2. build VNFS `sudo singularity build --sandbox /var/chroots/centos-7 centos-7.def`
|
||||||
|
3. Edit `/etc/warewulf/nodes.yaml`
|
||||||
|
4. Run the following commands:
|
||||||
|
a. `./wwbuild vnfs`
|
||||||
|
b. `./wwbuild kernel`
|
||||||
|
c. `./wwbuild overlay`
|
||||||
|
c. `./warewulfd`
|
||||||
|
5. Boot your node and watch the console and the output of the Warewulfd process
|
||||||
|
|||||||
17
centos-7.def
Normal file
17
centos-7.def
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
BootStrap: yum
|
||||||
|
OSVersion: 7
|
||||||
|
MirrorURL: http://mirror.centos.org/centos-%{OSVERSION}/%{OSVERSION}/os/x86_64/
|
||||||
|
Include: yum
|
||||||
|
|
||||||
|
|
||||||
|
%post
|
||||||
|
|
||||||
|
sed -i 's/^root:\*:/root::/g' /etc/passwd
|
||||||
|
|
||||||
|
yum install -y basesystem bash chkconfig coreutils e2fsprogs \
|
||||||
|
ethtool filesystem findutils gawk grep initscripts iproute \
|
||||||
|
iputils net-tools nfs-utils pam psmisc rdate rsync sed setup \
|
||||||
|
shadow-utils rsyslog tcp_wrappers tzdata util-linux words \
|
||||||
|
zlib tar less gzip which util-linux openssh-clients \
|
||||||
|
openssh-server dhclient pciutils vim-minimal shadow-utils \
|
||||||
|
strace cronie crontabs cpio wget centos-release
|
||||||
117
cmd/warewulfd/warewulfd.go
Normal file
117
cmd/warewulfd/warewulfd.go
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"io"
|
||||||
|
"path"
|
||||||
|
|
||||||
|
"net/http"
|
||||||
|
"github.com/hpcng/warewulf/internal/pkg/assets"
|
||||||
|
)
|
||||||
|
|
||||||
|
const LocalStateDir = "/var/warewulf"
|
||||||
|
const SysConfDir = "/etc/warewulf"
|
||||||
|
|
||||||
|
|
||||||
|
func ipxe(w http.ResponseWriter, req *http.Request) {
|
||||||
|
url := strings.Split(req.URL.Path, "/");
|
||||||
|
|
||||||
|
if url[2] == "" {
|
||||||
|
fmt.Printf("ERROR: Bad iPXE request from %s\n", req.RemoteAddr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
node := assets.FindByHwaddr(url[2])
|
||||||
|
|
||||||
|
if node.HostName != "" {
|
||||||
|
fmt.Printf("IPXE: %15s: hwaddr=%s\n", node.Fqdn, url[2]);
|
||||||
|
|
||||||
|
fmt.Fprintf(w, "#!ipxe\n");
|
||||||
|
|
||||||
|
fmt.Fprintf(w, "echo Now booting Warewulf - v4 Proof of Concept\n");
|
||||||
|
fmt.Fprintf(w, "set base http://192.168.1.1:9873/\n")
|
||||||
|
fmt.Fprintf(w, "kernel ${base}/files/kernel/%s crashkernel=no quiet\n", url[2])
|
||||||
|
fmt.Fprintf(w, "initrd ${base}/files/vnfs/%s\n", url[2])
|
||||||
|
fmt.Fprintf(w, "initrd ${base}/files/kmods/%s\n", url[2])
|
||||||
|
fmt.Fprintf(w, "initrd ${base}/files/overlay/%s\n", url[2])
|
||||||
|
fmt.Fprintf(w, "boot\n");
|
||||||
|
} else {
|
||||||
|
fmt.Printf("ERROR: iPXE request from unknown Node (hwaddr=%s)\n", url[2])
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func files(w http.ResponseWriter, req *http.Request) {
|
||||||
|
url := strings.Split(req.URL.Path, "/")
|
||||||
|
|
||||||
|
node := assets.FindByHwaddr(url[3])
|
||||||
|
|
||||||
|
fmt.Printf("GET: %15s: %s\n", node.Fqdn, req.URL.Path)
|
||||||
|
|
||||||
|
if url[2] == "kernel" {
|
||||||
|
if node.KernelVersion != "" {
|
||||||
|
kernelFile := fmt.Sprintf("%s/provision/kernels/vmlinuz-%s", LocalStateDir, node.KernelVersion);
|
||||||
|
|
||||||
|
sendFile(w, kernelFile, node.Fqdn);
|
||||||
|
}
|
||||||
|
} else if url[2] == "kmods" {
|
||||||
|
if node.KernelVersion != "" {
|
||||||
|
kmodsFile := fmt.Sprintf("%s/provision/kernels/kmods-%s.img", LocalStateDir, node.KernelVersion);
|
||||||
|
|
||||||
|
sendFile(w, kmodsFile, node.Fqdn);
|
||||||
|
}
|
||||||
|
} else if url[2] == "vnfs" {
|
||||||
|
if node.Vnfs != "" {
|
||||||
|
vnfsFile := fmt.Sprintf("%s/provision/bases/%s.img.gz", LocalStateDir, path.Base(node.Vnfs))
|
||||||
|
|
||||||
|
sendFile(w, vnfsFile, node.Fqdn);
|
||||||
|
}
|
||||||
|
} else if url[2] == "overlay" {
|
||||||
|
if node.Overlay!= "" {
|
||||||
|
overlayFile := fmt.Sprintf("%s/provision/overlays/%s.img", LocalStateDir, node.Fqdn);
|
||||||
|
|
||||||
|
sendFile(w, overlayFile, node.Fqdn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func sendFile(w http.ResponseWriter, filename string, sendto string) {
|
||||||
|
|
||||||
|
fmt.Printf("SEND: %15s: %s\n", sendto, filename);
|
||||||
|
|
||||||
|
fd, err := os.Open(filename)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("ERROR: %s\n", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileHeader := make([]byte, 512)
|
||||||
|
fd.Read(FileHeader)
|
||||||
|
FileContentType := http.DetectContentType(FileHeader)
|
||||||
|
FileStat, _ := fd.Stat()
|
||||||
|
FileSize := strconv.FormatInt(FileStat.Size(), 10)
|
||||||
|
|
||||||
|
w.Header().Set("Content-Disposition", "attachment; filename=kernel")
|
||||||
|
w.Header().Set("Content-Type", FileContentType)
|
||||||
|
w.Header().Set("Content-Length", FileSize)
|
||||||
|
|
||||||
|
fd.Seek(0, 0)
|
||||||
|
io.Copy(w, fd)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
http.HandleFunc("/ipxe/", ipxe)
|
||||||
|
http.HandleFunc("/files/", files)
|
||||||
|
|
||||||
|
http.ListenAndServe(":9873", nil)
|
||||||
|
}
|
||||||
86
cmd/wwbuild/wwbuild.go
Normal file
86
cmd/wwbuild/wwbuild.go
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
|
||||||
|
import(
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"fmt"
|
||||||
|
"path"
|
||||||
|
|
||||||
|
"github.com/hpcng/warewulf/internal/pkg/assets"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
const LocalStateDir = "/var/warewulf"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func main(){
|
||||||
|
|
||||||
|
if len(os.Args) < 2 {
|
||||||
|
fmt.Printf("USAGE: %s [vnfs/kernel/overlays/all]\n", os.Args[0]);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if os.Args[1] == "vnfs" {
|
||||||
|
for _, vnfs := range assets.FindAllVnfs() {
|
||||||
|
if _, err := os.Stat(vnfs); err == nil {
|
||||||
|
cmd := fmt.Sprintf("cd %s; find . | cpio --quiet -o -H newc | gzip -c > \"%s/provision/bases/%s.img.gz\"", vnfs, LocalStateDir, path.Base(vnfs));
|
||||||
|
fmt.Printf("BUILDING VNFS: %s\n", vnfs);
|
||||||
|
out, err := exec.Command("/bin/sh", "-c", cmd).Output();
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
output := string(out[:])
|
||||||
|
fmt.Println(output)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("SKIPPING VNFS: (bad path) %s\n", vnfs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if os.Args[1] == "kernel" {
|
||||||
|
for _, kernelVers := range assets.FindAllKernels() {
|
||||||
|
kernelSource := fmt.Sprintf("/boot/vmlinuz-%s", kernelVers)
|
||||||
|
if _, err := os.Stat(kernelSource); err == nil {
|
||||||
|
kernelDestination := fmt.Sprintf("%s/provision/kernels/vmlinuz-%s", LocalStateDir, kernelVers);
|
||||||
|
fmt.Printf("SETUP KERNEL: %s (%s)\n", kernelSource, kernelDestination);
|
||||||
|
err := exec.Command("cp", kernelSource, kernelDestination).Run()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
kernelMods := fmt.Sprintf("/lib/modules/%s", kernelVers)
|
||||||
|
if _, err := os.Stat(kernelMods); err == nil {
|
||||||
|
fmt.Printf("BUILDING MODS: %s\n", kernelMods);
|
||||||
|
cmd := fmt.Sprintf("find %s | cpio --quiet -o -H newc -F \"%s/provision/kernels/kmods-%s.img\"", kernelMods, LocalStateDir, kernelVers);
|
||||||
|
err := exec.Command("/bin/sh", "-c", cmd).Run();
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("OUTPUT: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if os.Args[1] == "overlay" {
|
||||||
|
fmt.Printf("note: This needs to create an overlay for each node with macro expansions\n");
|
||||||
|
|
||||||
|
|
||||||
|
for _, node := range assets.FindAllNodes() {
|
||||||
|
overlayDir := fmt.Sprintf("/etc/warewulf/overlays/%s", node.Overlay);
|
||||||
|
if _, err := os.Stat(overlayDir); err == nil {
|
||||||
|
cmd := fmt.Sprintf("cd %s; find . | cpio --quiet -o -H newc | gzip -c > \"%s/provision/overlays/%s.img\"", overlayDir, LocalStateDir, node.Fqdn);
|
||||||
|
fmt.Printf("BUILDING OVERLAY: %s\n", node.Fqdn);
|
||||||
|
err := exec.Command("/bin/sh", "-c", cmd).Run();
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%s", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Printf("SKIPPING OVERLAY: (bad path) %s\n", overlayDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
54
dhcpd.conf
Normal file
54
dhcpd.conf
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
|
||||||
|
allow booting;
|
||||||
|
allow bootp;
|
||||||
|
ddns-update-style interim;
|
||||||
|
authoritative;
|
||||||
|
|
||||||
|
option space ipxe;
|
||||||
|
|
||||||
|
# Tell iPXE to not wait for ProxyDHCP requests to speed up boot.
|
||||||
|
option ipxe.no-pxedhcp code 176 = unsigned integer 8;
|
||||||
|
option ipxe.no-pxedhcp 1;
|
||||||
|
|
||||||
|
option architecture-type code 93 = unsigned integer 16;
|
||||||
|
|
||||||
|
if exists user-class and option user-class = "iPXE" {
|
||||||
|
#filename "http://192.168.1.1/WW4/ipxe/${mac:hexhyp}";
|
||||||
|
#filename "http://192.168.1.1:9873/ipxe?hwaddr=${mac:hexhyp}";
|
||||||
|
filename "http://192.168.1.1:9873/ipxe/${mac:hexhyp}";
|
||||||
|
} else {
|
||||||
|
if option architecture-type = 00:0B {
|
||||||
|
filename "/warewulf/ipxe/bin-arm64-efi/snp.efi";
|
||||||
|
} elsif option architecture-type = 00:0A {
|
||||||
|
filename "/warewulf/ipxe/bin-arm32-efi/placeholder.efi";
|
||||||
|
} elsif option architecture-type = 00:09 {
|
||||||
|
filename "/warewulf/ipxe/bin-x86_64-efi/snp.efi";
|
||||||
|
} elsif option architecture-type = 00:07 {
|
||||||
|
filename "/warewulf/ipxe/bin-x86_64-efi/snp.efi";
|
||||||
|
} elsif option architecture-type = 00:06 {
|
||||||
|
filename "/warewulf/ipxe/bin-i386-efi/snp.efi";
|
||||||
|
} elsif option architecture-type = 00:00 {
|
||||||
|
filename "/warewulf/ipxe/bin-i386-pcbios/undionly.kpxe";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
subnet 192.168.1.0 netmask 255.255.255.0 {
|
||||||
|
range 192.168.1.10 192.168.1.99;
|
||||||
|
next-server 192.168.1.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#subnet 192.168.1.0 netmask 255.255.255.0 {
|
||||||
|
# not authoritative;
|
||||||
|
# option subnet-mask 255.255.255.0;
|
||||||
|
#}
|
||||||
|
|
||||||
|
#group {
|
||||||
|
# host n0000_localdomain-eth0 {
|
||||||
|
# option host-name n0000;
|
||||||
|
# option domain-name "localdomain";
|
||||||
|
# hardware ethernet 00:0c:29:c3:bf:42;
|
||||||
|
# fixed-address 192.168.1.100;
|
||||||
|
# next-server 192.168.1.1;
|
||||||
|
# }
|
||||||
|
#}
|
||||||
5
go.mod
Normal file
5
go.mod
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
module github.com/hpcng/warewulf
|
||||||
|
|
||||||
|
go 1.15
|
||||||
|
|
||||||
|
require gopkg.in/yaml.v2 v2.3.0
|
||||||
3
go.sum
Normal file
3
go.sum
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||||
|
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
182
internal/pkg/assets/assets.go
Normal file
182
internal/pkg/assets/assets.go
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
|
||||||
|
package assets
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
|
||||||
|
"gopkg.in/yaml.v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
const ConfigFile = "/etc/warewulf/nodes.yaml"
|
||||||
|
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
type nodeYaml struct {
|
||||||
|
NodeGroups map[string]nodeGroup //`yaml:"nodegroups"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type nodeGroup struct {
|
||||||
|
Comment string
|
||||||
|
Vnfs string
|
||||||
|
Overlay string
|
||||||
|
DomainSuffix string `yaml:"domain suffix"`
|
||||||
|
KernelVersion string `yaml:"kernel version"`
|
||||||
|
Nodes map[string]nodeEntry
|
||||||
|
}
|
||||||
|
|
||||||
|
type nodeEntry struct {
|
||||||
|
Hostname string
|
||||||
|
Vnfs string
|
||||||
|
Overlay string
|
||||||
|
DomainSuffix string `yaml:"domain suffix"`
|
||||||
|
KernelVersion string `yaml:"kernel version"`
|
||||||
|
IpmiIpaddr string `yaml:"ipmi ipaddr"`
|
||||||
|
NetDevs map[string]netDevs
|
||||||
|
}
|
||||||
|
|
||||||
|
type netDevs struct {
|
||||||
|
Type string
|
||||||
|
Hwaddr string
|
||||||
|
Ipaddr string
|
||||||
|
Netmask string
|
||||||
|
Gateway string
|
||||||
|
}
|
||||||
|
|
||||||
|
type NodeInfo struct {
|
||||||
|
GroupName string
|
||||||
|
HostName string
|
||||||
|
Fqdn string
|
||||||
|
Vnfs string
|
||||||
|
Overlay string
|
||||||
|
KernelVersion string
|
||||||
|
NetDevs map[string]netDevs
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func FindAllNodes() []NodeInfo {
|
||||||
|
var c nodeYaml
|
||||||
|
var ret []NodeInfo
|
||||||
|
|
||||||
|
fd, err := ioutil.ReadFile(ConfigFile)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = yaml.Unmarshal(fd, &c)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for groupname, group := range c.NodeGroups {
|
||||||
|
for _, node := range group.Nodes {
|
||||||
|
var n NodeInfo
|
||||||
|
|
||||||
|
n.GroupName = groupname
|
||||||
|
n.HostName = node.Hostname
|
||||||
|
|
||||||
|
n.Vnfs = group.Vnfs
|
||||||
|
n.Overlay = group.Overlay
|
||||||
|
n.KernelVersion = group.KernelVersion
|
||||||
|
n.NetDevs = node.NetDevs
|
||||||
|
|
||||||
|
if ( group.DomainSuffix != "" ) {
|
||||||
|
n.Fqdn = node.Hostname + "." + group.DomainSuffix
|
||||||
|
} else {
|
||||||
|
n.Fqdn = node.Hostname
|
||||||
|
}
|
||||||
|
if node.KernelVersion != "" {
|
||||||
|
n.KernelVersion = node.KernelVersion
|
||||||
|
}
|
||||||
|
if node.Vnfs != "" {
|
||||||
|
n.Vnfs = node.Vnfs
|
||||||
|
}
|
||||||
|
if node.Overlay != "" {
|
||||||
|
n.Overlay = node.Overlay
|
||||||
|
}
|
||||||
|
ret = append(ret, n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func FindByHwaddr(hwa string) NodeInfo{
|
||||||
|
var ret NodeInfo
|
||||||
|
|
||||||
|
for _, node := range FindAllNodes() {
|
||||||
|
for _, dev := range node.NetDevs {
|
||||||
|
if dev.Hwaddr == hwa {
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func FindAllVnfs() []string {
|
||||||
|
var ret []string
|
||||||
|
set := make(map[string]bool)
|
||||||
|
|
||||||
|
for _, node := range FindAllNodes() {
|
||||||
|
if node.Vnfs != "" {
|
||||||
|
set[node.Vnfs] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for entry, _ := range set {
|
||||||
|
ret = append(ret, entry)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func FindAllKernels() []string {
|
||||||
|
var ret []string
|
||||||
|
set := make(map[string]bool)
|
||||||
|
|
||||||
|
for _, node := range FindAllNodes() {
|
||||||
|
if node.KernelVersion != "" {
|
||||||
|
set[node.KernelVersion] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for entry, _ := range set {
|
||||||
|
ret = append(ret, entry)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func FindAllOverlays() []string {
|
||||||
|
var ret []string
|
||||||
|
set := make(map[string]bool)
|
||||||
|
|
||||||
|
for _, node := range FindAllNodes() {
|
||||||
|
if node.Overlay != "" {
|
||||||
|
set[node.Overlay] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for entry, _ := range set {
|
||||||
|
ret = append(ret, entry)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
16
internal/pkg/util/util.go
Normal file
16
internal/pkg/util/util.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
package util
|
||||||
|
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"crypto/sha1"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func Sha1Sum(input string) []byte{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
52
nodes.yaml
Normal file
52
nodes.yaml
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
nodegroups:
|
||||||
|
group_1:
|
||||||
|
comment: This is the group 1
|
||||||
|
vnfs: /var/chroots/test
|
||||||
|
overlay: generic
|
||||||
|
domain suffix: group1
|
||||||
|
nodes:
|
||||||
|
n0000:
|
||||||
|
hostname: n0000
|
||||||
|
kernel version: 3.10.0-1127.el7.x86_64
|
||||||
|
netdevs:
|
||||||
|
eth0:
|
||||||
|
hwaddr: xx:xx:xx:xx:aa
|
||||||
|
ipaddr: x.x.x.x
|
||||||
|
netmask: x.x.x.x
|
||||||
|
gateway: x.x.x.x
|
||||||
|
group_2:
|
||||||
|
comment: This is the group 2
|
||||||
|
vnfs: /var/chroots/test
|
||||||
|
overlay: generic
|
||||||
|
domain suffix: group2
|
||||||
|
kernel version: 3.10.0-1127.el7.x86_64
|
||||||
|
nodes:
|
||||||
|
n0000:
|
||||||
|
hostname: n0000
|
||||||
|
ipmi ipaddr: x.x.x.x
|
||||||
|
netdevs:
|
||||||
|
eth0:
|
||||||
|
hwaddr: 00-0c-29-c3-bf-42
|
||||||
|
ipaddr: x.x.x.x
|
||||||
|
netmask: x.x.x.x
|
||||||
|
gateway: x.x.x.x
|
||||||
|
type: ethernet
|
||||||
|
ib0:
|
||||||
|
hwaddr: xx:xx:xx:xx:xx
|
||||||
|
ipaddr: x.x.x.x
|
||||||
|
netmask: x.x.x.x
|
||||||
|
gateway: x.x.x.x
|
||||||
|
type: infiniband
|
||||||
|
n0001:
|
||||||
|
hostname: n0001
|
||||||
|
ipmi ipaddr: x.x.x.x
|
||||||
|
netdevs:
|
||||||
|
eth0:
|
||||||
|
hwaddr: xx:xx:xx:xx:xx
|
||||||
|
ipaddr: x.x.x.x
|
||||||
|
netmask: x.x.x.x
|
||||||
|
gateway: x.x.x.x
|
||||||
|
ib0:
|
||||||
|
hwaddr: xx:xx:xx:xx:xx
|
||||||
|
ipaddr: x.x.x.x
|
||||||
|
netmask: x.x.x.x
|
||||||
14
overlays/generic/init
Executable file
14
overlays/generic/init
Executable file
@@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
clear
|
||||||
|
|
||||||
|
mount -t proc none /proc
|
||||||
|
mount -t sysfs none /sys
|
||||||
|
mount -t devtmpfs devtmpfs /dev
|
||||||
|
|
||||||
|
/sbin/ip link set dev lo up
|
||||||
|
|
||||||
|
echo "Calling /sbin/init..."
|
||||||
|
echo
|
||||||
|
|
||||||
|
exec /sbin/init
|
||||||
BIN
tftpboot/bin-i386-efi/snp.efi
Normal file
BIN
tftpboot/bin-i386-efi/snp.efi
Normal file
Binary file not shown.
BIN
tftpboot/bin-i386-pcbios/undionly.kpxe
Normal file
BIN
tftpboot/bin-i386-pcbios/undionly.kpxe
Normal file
Binary file not shown.
BIN
tftpboot/bin-x86_64-efi/snp.efi
Normal file
BIN
tftpboot/bin-x86_64-efi/snp.efi
Normal file
Binary file not shown.
Reference in New Issue
Block a user