Skip to content

Commit

Permalink
Make relative paths in a VM config relative to the run_dir, split out…
Browse files Browse the repository at this point in the history
… setting defaults
  • Loading branch information
bensallen committed Aug 19, 2019
1 parent 520ca5e commit 6a1f8ce
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 24 deletions.
2 changes: 1 addition & 1 deletion TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ Configuring Network: "net0"
cmd: ifconfig bridge1 192.168.99.1 netmask 0xffffff00
cmd: ifconfig bridge1 192.168.99.1 netmask 0xffffff00

- Make relative paths in a VM config relative to the run_dir
- Add dependency graph ordering
- Debug logging
- Remove all fmt.Printf and use log or similar
Expand Down Expand Up @@ -57,3 +56,4 @@ cmd: ifconfig bridge1 192.168.99.1 netmask 0xffffff00
- Check that kernel and vmlinux exist in Up() of boot.kexec
- If one of the tap interfaces doesn't come up, still add the ones that do come up to the bridge
- Make relative paths be relative to the config file.
- Make relative paths in a VM config relative to the run_dir
18 changes: 17 additions & 1 deletion internal/config/config.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package config

import (
"path/filepath"
)

// Config represents a hkmgr.toml config file
type Config struct {
Network Network `toml:"network"`
VM VM `toml:"vm"`
Expand All @@ -9,7 +14,18 @@ type Config struct {
// UpdateRelativePaths finds relative paths in the config and turns them into
// fully qualified paths based on the config file path.
func (c *Config) UpdateRelativePaths() {
configDir := filepath.Dir(c.Path)

for name := range c.VM {
c.VM[name].updateRelativePaths(configDir, name)
}
}

// Defaults sets default values for unset variables in the config.
func (c *Config) Defaults() {
configDir := filepath.Dir(c.Path)

for name := range c.VM {
c.VM[name].updateRelativePaths(c.Path, name)
c.VM[name].defaults(configDir, name)
}
}
106 changes: 84 additions & 22 deletions internal/config/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,20 @@ var hyperkitPath = "hyperkit"
type VM map[string]*VMConfig

type VMConfig struct {
Memory string `toml:"memory"`
Cores int `toml:"cores"`
UUID string `toml:"uuid"`
SSHKey string `toml:"ssh_key"`
ProvisionPre string `toml:"provision_pre"`
ProvisionPost string `toml:"provision_post"`
Before []string `toml:"before"`
After []string `toml:"after"`
Requires []string `toml:"requires"`
RunDir string `toml:"run_dir"`
Network []NetConf `toml:"network"`
Boot Boot `toml:"boot"`
HDD []HDD `toml:"hdd"`
CDROM []CDROM `toml:"cdrom"`
Memory string `toml:"memory"`
Cores int `toml:"cores"`
UUID string `toml:"uuid"`
SSHKey string `toml:"ssh_key"`
ProvisionPre string `toml:"provision_pre"`
ProvisionPost string `toml:"provision_post"`
Before []string `toml:"before"`
After []string `toml:"after"`
Requires []string `toml:"requires"`
RunDir string `toml:"run_dir"`
Network []*NetConf `toml:"network"`
Boot Boot `toml:"boot"`
HDD []*HDD `toml:"hdd"`
CDROM []*CDROM `toml:"cdrom"`
}

// Status is the status of a VM process
Expand Down Expand Up @@ -242,7 +242,7 @@ func (v *VMConfig) Validate() error {
return errors.New("RunDir not specified")
}

if err := v.Boot.Validate(); err != nil {
if err := v.Boot.validate(); err != nil {
return err
}

Expand All @@ -260,13 +260,24 @@ func (v *VMConfig) Validate() error {
return nil
}

func (v *VMConfig) updateRelativePaths(configPath string, name string) {
configDir := filepath.Dir(configPath)
func (v *VMConfig) defaults(configDir string, name string) {
if v.RunDir == "" {
v.RunDir = filepath.Join(configDir, ".run/vm/", name)
} else if v.RunDir[:0] != "/" {
}
}

func (v *VMConfig) updateRelativePaths(configDir string, name string) {
if v.RunDir[:1] != "/" {
v.RunDir = filepath.Join(configDir, v.RunDir)
}

v.Boot.updateRelativePaths(configDir)
for i := range v.HDD {
v.HDD[i].updateRelativePaths(v.RunDir)
}
for i := range v.CDROM {
v.CDROM[i].updateRelativePaths(v.RunDir)
}
}

// Boot config
Expand All @@ -292,7 +303,7 @@ func (b *Boot) Cli() []string {
return []string{}
}

func (b *Boot) Validate() error {
func (b *Boot) validate() error {
if (Kexec{}) != b.Kexec {
return b.Kexec.Validate()
}
Expand All @@ -308,6 +319,20 @@ func (b *Boot) Validate() error {
return nil
}

func (b *Boot) updateRelativePaths(configDir string) {
if (Kexec{}) != b.Kexec {
b.Kexec.updateRelativePaths(configDir)
}

if (Firmware{}) != b.Firmware {
b.Firmware.updateRelativePaths(configDir)
}

if (FBSD{}) != b.FBSD {
b.FBSD.updateRelativePaths(configDir)
}
}

type Kexec struct {
Kernel string `toml:"kernel"`
Initrd string `toml:"initrd"`
Expand All @@ -319,7 +344,6 @@ func (k *Kexec) Cli() []string {
}

func (k *Kexec) Validate() error {

if !fileExists(k.Kernel) {
return fmt.Errorf("kernel not found: %s", k.Kernel)
}
Expand All @@ -331,6 +355,16 @@ func (k *Kexec) Validate() error {
return nil
}

func (k *Kexec) updateRelativePaths(configDir string) {
if k.Kernel[:1] != "/" {
k.Kernel = filepath.Join(configDir, k.Kernel)
}

if k.Initrd[:1] != "/" {
k.Initrd = filepath.Join(configDir, k.Initrd)
}
}

type Firmware struct {
Path string `toml:"path"`
}
Expand All @@ -344,6 +378,12 @@ func (f *Firmware) Validate() error {
return nil
}

func (f *Firmware) updateRelativePaths(configDir string) {
if f.Path[:1] != "/" {
f.Path = filepath.Join(configDir, f.Path)
}
}

type FBSD struct {
Userboot string `toml:"userboot"`
BootVolume string `toml:"userboot"`
Expand All @@ -359,7 +399,17 @@ func (f *FBSD) Validate() error {
return nil
}

// VM Network Config
func (f *FBSD) updateRelativePaths(configDir string) {
if f.Userboot[:1] != "/" {
f.Userboot = filepath.Join(configDir, f.Userboot)
}

if f.Userboot[:1] != "/" {
f.BootVolume = filepath.Join(configDir, f.BootVolume)
}
}

// NetConf is a VM network configuration
type NetConf struct {
IP string `toml:"ip"`
MAC string `toml:"mac"`
Expand Down Expand Up @@ -401,7 +451,7 @@ func (n *NetConf) validate() error {
}

func (n *NetConf) devicePath() string {
if n.Device[0] == '/' {
if n.Device[:1] == "/" {
return n.Device
}
return "/dev/" + n.Device
Expand All @@ -419,12 +469,24 @@ func (h *HDD) create() error {
return nil
}

func (h *HDD) updateRelativePaths(runDir string) {
if h.Path[:1] != "/" {
h.Path = filepath.Join(runDir, h.Path)
}
}

type CDROM struct {
Path string
Driver string
Extract bool
}

func (c *CDROM) updateRelativePaths(runDir string) {
if c.Path[:1] != "/" {
c.Path = filepath.Join(runDir, c.Path)
}
}

// Check if a file exists and isn't a directory
func fileExists(filename string) bool {
info, err := os.Stat(filename)
Expand Down
2 changes: 2 additions & 0 deletions internal/root/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,9 @@ func Run() error {
return err
}

config.Defaults()
config.UpdateRelativePaths()

if debug {
fmt.Printf("Parsed config:\n\n%# v\n", pretty.Formatter(config))
}
Expand Down

0 comments on commit 6a1f8ce

Please sign in to comment.