Skip to content

Commit

Permalink
Removes assumption that Hypervisors only have one struct property (#79)
Browse files Browse the repository at this point in the history
* Better document hypervisor interface

* Removes assumption that Hypervisors only have one struct property
  • Loading branch information
Eagerod authored Feb 23, 2025
1 parent 70eb713 commit dd52112
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 14 deletions.
4 changes: 4 additions & 0 deletions cmd/hope/utils/nodes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ type MockHypervisor struct {
node hope.Node
}

func (m *MockHypervisor) Initialize(node hope.Node) error {
return nil
}

func (m *MockHypervisor) ListNodes() ([]string, error) {
nodes := []string{}
for _, n := range testNodes {
Expand Down
7 changes: 6 additions & 1 deletion pkg/hope/hypervisors/exsi_hypervisor.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@ type EsxiHypervisor struct {
node hope.Node
}

func (hyp EsxiHypervisor) ListNodes() ([]string, error) {
func (hyp *EsxiHypervisor) Initialize(node hope.Node) error {
hyp.node = node
return nil
}

func (hyp *EsxiHypervisor) ListNodes() ([]string, error) {
v, e := esxi.ListVms(hyp.node.ConnectionString())
if e == nil {
return *v, nil
Expand Down
32 changes: 21 additions & 11 deletions pkg/hope/hypervisors/hypervisor.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,39 @@ import (

// Hypervisor acts as a catch-all for "an entity that exposes access to manage
// a virtual machine".
//
// ListNodes returns a list of identifiers for the nodes present on the
// hypervisor.
//
// ResolveNode will use the contents of the provided &hope.Node, and will
// return a new &hope.Node that can be used as though it were a physical
// machine on the network.
//
// UnderlyingNode returns the base object used to create the hypervisor.
type Hypervisor interface {
// Initialize using the provided Node.
Initialize(hope.Node) error

// Return a list of identifiers for the nodes present on the hypervisor.
ListNodes() ([]string, error)

// Ask the hypervisor for the host of the node, and return a new node with
// reachable IP in its host field.
ResolveNode(node hope.Node) (hope.Node, error)

// Returns the base object used to create the hypervisor.
UnderlyingNode() (hope.Node, error)

// Copy an image from the packer cache to all hypervisors it should exist
// on.
CopyImage(packer.JsonSpec, hope.VMs, hope.VMImageSpec) error

// Create an image using the given image spec.
CreateImage(hope.VMs, hope.VMImageSpec, []string, bool) (*packer.JsonSpec, error)

// Create a node from the given image spec.
CreateNode(hope.Node, hope.VMs, hope.VMImageSpec) error

// Start the VM identified by the given value.
StartVM(string) error

// Start the VM identified by the given value.
StopVM(string) error

// Should these interfaces also take a hope.Node, just for consistency's
// sake?
// Delete the VM identified by the given value.
DeleteVM(string) error

// Get the IP address of the VM identified by the given value.
VMIPAddress(string) (string, error)
}
10 changes: 8 additions & 2 deletions pkg/hope/hypervisors/hypervisor_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,16 @@ func ToHypervisor(node hope.Node) (Hypervisor, error) {
return nil, fmt.Errorf("node named %s is not a hypervisor", node.Name)
}

var rv Hypervisor = nil
switch node.Engine {
case "esxi":
return &EsxiHypervisor{node}, nil
rv = &EsxiHypervisor{}
default:
return nil, fmt.Errorf("failed to resolve hypervisor engine: %s", node.Engine)
}

return nil, fmt.Errorf("failed to resolve hypervisor engine: %s", node.Engine)
if err := rv.Initialize(node); err != nil {
return nil, err
}
return rv, nil
}

0 comments on commit dd52112

Please sign in to comment.