Skip to content

Commit

Permalink
Add generation of MAC addresses when not specified in the configurati…
Browse files Browse the repository at this point in the history
…on file for a TAP net type. Move pidFile() and uuidFile() to a new file internal/config/file.go along with a new hwaddrFile() function
  • Loading branch information
bensallen committed Dec 26, 2019
1 parent c19ca61 commit d6f89c3
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 38 deletions.
5 changes: 2 additions & 3 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

- Reorganize internal/config to move VM action logic outside of config, eg. vm/vm.go
- Generate HDD if it doesn't already exist
- Generate MAC for tap interfaces if not specified, store in .run/vm/\<name\>/\<net\>_mac
- Check write privs on run_dir, pid, and tty in Validate()
- Check write privs on hdd, read privs on cdrom
- Add template support for kexec cmdline for IP, ssh public
Expand Down Expand Up @@ -62,7 +61,6 @@ Configuring Network: "net0"
cmd: ifconfig bridge1 192.168.99.1 netmask 0xffffff00
cmd: ifconfig bridge1 192.168.99.1 netmask 0xffffff00


## Completed

- Add arg to each relevant command to work on specific VM
Expand All @@ -77,4 +75,5 @@ cmd: ifconfig bridge1 192.168.99.1 netmask 0xffffff00
- Make relative paths in a VM config relative to the run_dir
- Add pid in status output
- Add CI, CircleCI, clean code, etc.
- Generate UUID if not specified, store in .run/vm/\<name\>/uuid
- Generate UUID if not specified, store in .run/vm/\<name\>/uuid
- Generate MAC for tap interfaces if not specified, store in .run/vm/\<name\>/\<net\>_mac
62 changes: 62 additions & 0 deletions internal/config/file.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package config

import (
"fmt"
"io/ioutil"
"net"
"os"
"strconv"

"github.com/google/uuid"
)

func pidFile(path string) (int, error) {
if _, err := os.Stat(path); os.IsNotExist(err) {
return 0, fmt.Errorf("pid file not found")
}
pidTxt, err := ioutil.ReadFile(path)
if err != nil {
return 0, fmt.Errorf("pid file cannot be read")
}

pid, err := strconv.Atoi(string(pidTxt))
if err != nil {
return 0, fmt.Errorf("pid file does not contain an integer")
}

return pid, nil
}

func uuidFile(path string) (uuid.UUID, error) {
if _, err := os.Stat(path); os.IsNotExist(err) {
return [16]byte{}, fmt.Errorf("uuid file not found")
}
uuidTxt, err := ioutil.ReadFile(path)
if err != nil {
return [16]byte{}, fmt.Errorf("uuid file cannot be read")
}

uuid, err := uuid.Parse(string(uuidTxt))
if err != nil {
return [16]byte{}, fmt.Errorf("uuid file does not contain an UUID")
}

return uuid, nil
}

func hwaddrFile(path string) (net.HardwareAddr, error) {
if _, err := os.Stat(path); os.IsNotExist(err) {
return nil, fmt.Errorf("mac addr file not found")
}
hwaddrTxt, err := ioutil.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("mac addr file cannot be read")
}

hwaddr, err := net.ParseMAC(string(hwaddrTxt))
if err != nil {
return nil, fmt.Errorf("mac addr file does not contain a hardware address")
}

return hwaddr, nil
}
17 changes: 17 additions & 0 deletions internal/config/network.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package config

import (
"crypto/rand"
"fmt"
"net"
"strings"
Expand Down Expand Up @@ -129,3 +130,19 @@ func (v *VPNKit) Up() error {
func (v *VPNKit) Destroy() error {
return nil
}

// genMAC creates a random 6 byte hardware address, eg. MAC address.
// The address generated has the locally administered bit set and
// is a unicast address.
func genMAC() (net.HardwareAddr, error) {
buf := make([]byte, 6)
_, err := rand.Read(buf)
if err != nil {
return nil, err
}

// Set local bit, ensure unicast address
buf[0] = (buf[0] | 2) & 0xfe

return buf, nil
}
72 changes: 37 additions & 35 deletions internal/config/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package config
import (
"errors"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
Expand Down Expand Up @@ -172,40 +171,6 @@ func sigLookup(s string) (syscall.Signal, error) {
return sig, nil
}

func pidFile(path string) (int, error) {
if _, err := os.Stat(path); os.IsNotExist(err) {
return 0, fmt.Errorf("pid file not found")
}
pidTxt, err := ioutil.ReadFile(path)
if err != nil {
return 0, fmt.Errorf("pid file cannot be read")
}

pid, err := strconv.Atoi(string(pidTxt))
if err != nil {
return 0, fmt.Errorf("pid file does not contain an integer")
}

return pid, nil
}

func uuidFile(path string) (uuid.UUID, error) {
if _, err := os.Stat(path); os.IsNotExist(err) {
return [16]byte{}, fmt.Errorf("uuid file not found")
}
uuidTxt, err := ioutil.ReadFile(path)
if err != nil {
return [16]byte{}, fmt.Errorf("uuid file cannot be read")
}

uuid, err := uuid.Parse(string(uuidTxt))
if err != nil {
return [16]byte{}, fmt.Errorf("uuid file does not contain an UUID")
}

return uuid, nil
}

func (v *VMConfig) Cli() []string {

var args []string
Expand Down Expand Up @@ -307,6 +272,13 @@ func (v *VMConfig) defaults(configDir string, name string) error {
}
v.UUID = UUID.String()
}

for _, net := range v.Network {
if err := net.defaults(v.RunDir); err != nil {
return err
}
}

return nil
}

Expand Down Expand Up @@ -494,6 +466,36 @@ func (n *NetConf) validate() error {
return nil
}

func (n *NetConf) defaults(runDir string) error {
switch n.Driver {

case "virtio-tap":
if n.MAC == "" {
MAC, err := hwaddrFile(runDir + "/" + n.MemberOf + "_mac")

if err != nil {
MAC, err = genMAC()
if err != nil {
return err
}

w, err := os.Create(runDir + "/" + n.MemberOf + "_mac")
if err != nil {
return err
}

defer w.Close()

if _, err := w.WriteString(MAC.String()); err != nil {
return err
}
}
n.MAC = MAC.String()
}
}
return nil
}

func (n *NetConf) devicePath() string {
if n.Device[:1] == "/" {
return n.Device
Expand Down

0 comments on commit d6f89c3

Please sign in to comment.