droplet create makes the network and disks
This commit is contained in:
parent
bf01596f30
commit
65563eb8e2
129
doDroplet.go
129
doDroplet.go
|
@ -7,11 +7,15 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"go.wit.com/lib/gui/shell"
|
||||
"go.wit.com/lib/protobuf/virtpb"
|
||||
"go.wit.com/log"
|
||||
)
|
||||
|
@ -132,13 +136,13 @@ func doEvent(e *virtpb.Event) *virtpb.Event {
|
|||
}
|
||||
result.DropletName = e.Droplet.Hostname
|
||||
result.Error = e.Droplet.FormatTEXT() // feedback to the other side for debugging
|
||||
if e.Droplet != nil {
|
||||
|
||||
// attempt to create the new droplet
|
||||
if err := createDroplet(e.Droplet, result); err != nil {
|
||||
result.Error += fmt.Sprintf("createDroplet() err: %v", err)
|
||||
result.State = virtpb.Event_FAIL
|
||||
return result
|
||||
}
|
||||
}
|
||||
log.Println("create droplet worked", e.Droplet.FormatTEXT())
|
||||
result.State = virtpb.Event_DONE
|
||||
return result
|
||||
|
@ -224,23 +228,134 @@ func createDroplet(newd *virtpb.Droplet, result *virtpb.Event) error {
|
|||
return fmt.Errorf("hostname already defined")
|
||||
}
|
||||
|
||||
// by default, on locally imported domains, set the preferred hypervisor!
|
||||
newd.LocalOnly = "yes on: " + "farm03"
|
||||
|
||||
// by default, on locally imported domains, set the preferred hypervisor!
|
||||
newd.PreferredHypervisor = "farm03"
|
||||
newd.StartState = virtpb.DropletState_OFF
|
||||
|
||||
newd.Current = new(virtpb.Current)
|
||||
newd.Current.Hypervisor = "farm03"
|
||||
newd.StartState = virtpb.DropletState_OFF
|
||||
newd.Current.State = virtpb.DropletState_OFF
|
||||
|
||||
me.cluster.AddDroplet(newd)
|
||||
// create the network
|
||||
if err := createNetwork(newd); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// create the disks
|
||||
if err := createDisks(newd); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// append the protobuf and save it
|
||||
me.cluster.AddDroplet(newd)
|
||||
if err := me.cluster.ConfigSave(); err != nil {
|
||||
log.Info("configsave error", err)
|
||||
return fmt.Errorf("ConfigSave() error: %v", err)
|
||||
}
|
||||
|
||||
result.State = virtpb.Event_DONE
|
||||
return nil
|
||||
}
|
||||
|
||||
func findDisks(d *virtpb.Droplet) error {
|
||||
log.Info("need to do this")
|
||||
return nil
|
||||
}
|
||||
|
||||
func createDisks(d *virtpb.Droplet) error {
|
||||
if d.Disks != nil {
|
||||
return findDisks(d)
|
||||
}
|
||||
|
||||
newdisk := new(virtpb.Disk)
|
||||
newdisk.Filename = d.Hostname + ".qcow2"
|
||||
newdisk.Filepath = "/home/nfs2"
|
||||
d.Disks = append(d.Disks, newdisk)
|
||||
|
||||
basefile := "/home/nfs2/base2025.wit-5.qcow2"
|
||||
newfile := filepath.Join(newdisk.Filepath, newdisk.Filename)
|
||||
|
||||
if !shell.Exists(newdisk.Filepath) {
|
||||
return fmt.Errorf("disk image path missing: %s", newdisk.Filepath)
|
||||
}
|
||||
|
||||
if !shell.Exists(basefile) {
|
||||
return fmt.Errorf("basefile %s missing", basefile)
|
||||
}
|
||||
|
||||
if shell.Exists(newfile) {
|
||||
return fmt.Errorf("disk image already exists: %s", newfile)
|
||||
}
|
||||
|
||||
cmd := []string{"dd", "bs=100M", "status=progress", "oflag=dsync", "if=" + basefile, "of=" + newfile}
|
||||
result := shell.RunRealtime(cmd)
|
||||
if result.Exit != 0 {
|
||||
return fmt.Errorf("dd to %s failed %d\n%s\n%s", newfile, result.Exit, strings.Join(result.Stdout, "\n"), strings.Join(result.Stderr, "\n"))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func createNetwork(d *virtpb.Droplet) error {
|
||||
if d.Networks != nil {
|
||||
// network already done
|
||||
return nil
|
||||
}
|
||||
if len(d.Networks) > 0 {
|
||||
// network already done
|
||||
return nil
|
||||
}
|
||||
|
||||
n := new(virtpb.Network)
|
||||
n.Mac = getNewMac()
|
||||
n.Name = "worldbr"
|
||||
d.Networks = append(d.Networks, n)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getNewMac() string {
|
||||
// mac address map to check for duplicates
|
||||
var macs map[string]string
|
||||
macs = make(map[string]string)
|
||||
|
||||
loop := me.cluster.DropletsAll() // get the list of droplets
|
||||
for loop.Scan() {
|
||||
d := loop.Next()
|
||||
for _, n := range d.Networks {
|
||||
// log.Println("network:", n.Mac, d.Uuid, d.Hostname)
|
||||
if _, ok := macs[n.Mac]; ok {
|
||||
// UUID already exists
|
||||
log.Info("duplicate MAC", n.Mac, macs[n.Mac])
|
||||
log.Info("duplicate MAC", n.Mac, d.Hostname)
|
||||
return ""
|
||||
}
|
||||
macs[n.Mac] = d.Hostname
|
||||
}
|
||||
}
|
||||
|
||||
return generateMAC(macs)
|
||||
}
|
||||
|
||||
func generateMAC(macs map[string]string) string {
|
||||
prefix := []byte{0x22, 0x22, 0x22}
|
||||
for {
|
||||
// Generate last 3 bytes randomly
|
||||
suffix := make([]byte, 3)
|
||||
if _, err := rand.Read(suffix); err != nil {
|
||||
log.Fatalf("Failed to generate random bytes: %v", err)
|
||||
}
|
||||
|
||||
// Format full MAC address
|
||||
mac := fmt.Sprintf("%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
prefix[0], prefix[1], prefix[2],
|
||||
suffix[0], suffix[1], suffix[2])
|
||||
|
||||
// Check if MAC is already used
|
||||
if _, exists := macs[mac]; !exists {
|
||||
log.Println("Using new MAC:", mac)
|
||||
return mac
|
||||
}
|
||||
log.Println("MAC already defined:", mac)
|
||||
}
|
||||
}
|
||||
|
|
5
start.go
5
start.go
|
@ -52,15 +52,14 @@ func Start(id string) (string, error) {
|
|||
}
|
||||
|
||||
if d.Current == nil {
|
||||
// result = d.Hostname + " d.Current == nil"
|
||||
// return result, errors.New(result)
|
||||
d.Current = new(virtpb.Current)
|
||||
}
|
||||
|
||||
// is the droplet already on?
|
||||
if d.Current.State == virtpb.DropletState_ON {
|
||||
result = "EVENT start droplet " + d.Hostname + " is already ON"
|
||||
return result, errors.New(result)
|
||||
}
|
||||
}
|
||||
|
||||
// make the list of hypervisors that are active and can start new droplets
|
||||
var pool []*HyperT
|
||||
|
|
35
validate.go
35
validate.go
|
@ -15,7 +15,6 @@ package main
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
@ -163,40 +162,6 @@ func ValidateDiskFilenames() ([]*virtpb.Event, error) {
|
|||
return alle, nil
|
||||
}
|
||||
|
||||
func getNewMac() string {
|
||||
// mac address map to check for duplicates
|
||||
var macs map[string]string
|
||||
macs = make(map[string]string)
|
||||
|
||||
loop := me.cluster.DropletsAll() // get the list of droplets
|
||||
for loop.Scan() {
|
||||
d := loop.Next()
|
||||
for _, n := range d.Networks {
|
||||
// log.Println("network:", n.Mac, d.Uuid, d.Hostname)
|
||||
if _, ok := macs[n.Mac]; ok {
|
||||
// UUID already exists
|
||||
log.Info("duplicate MAC", n.Mac, macs[n.Mac])
|
||||
log.Info("duplicate MAC", n.Mac, d.Hostname)
|
||||
return ""
|
||||
}
|
||||
macs[n.Mac] = d.Hostname
|
||||
}
|
||||
}
|
||||
|
||||
var i int = 9
|
||||
var mac string
|
||||
for {
|
||||
mac = fmt.Sprintf("22:22:22:22:22:%02d", i)
|
||||
if _, ok := macs[mac]; ok {
|
||||
log.Info("MAC already defined", mac, macs[mac])
|
||||
i += 1
|
||||
continue
|
||||
}
|
||||
log.Info("using new MAC:", mac)
|
||||
return mac
|
||||
}
|
||||
}
|
||||
|
||||
// consistancy check. run on a regular basis
|
||||
//
|
||||
// runs on startup. dies if there are duplicates
|
||||
|
|
Loading…
Reference in New Issue