Skip to content

Commit

Permalink
fix vm status / task
Browse files Browse the repository at this point in the history
  • Loading branch information
sp-yduck committed Jul 29, 2023
1 parent 9009960 commit bf81716
Show file tree
Hide file tree
Showing 7 changed files with 173 additions and 9 deletions.
37 changes: 37 additions & 0 deletions api/qemu_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,3 +242,40 @@ type VirtualMachineConfig struct {
// Cloud-init interfaces
// IPConfig
}

type VirtualMachineRebootOption struct {
TimeOut int `json:"timeout,omitempty"`
}

type VirtualMachineResumeOption struct {
NoCheck bool `json:"nocheck,omitempty"`
SkipLock bool `json:"skiplock,omitempty"`
}

type VirtualMachineStartOption struct {
// override qemu's -cpu argument with the given string
ForceCPU string `json:"force-cpu,omitempty"`
// specifies the qemu machine type
Machine string `json:"machine,omitempty"`
// cluster node name
MigratedFroom string `json:"migratedfrom,omitempty"`
// cidr of (sub) network that is used for migration
MigrationNetwork string `json:"migration_network,omitempty"`
// migration traffic is ecrypted using an SSH tunnel by default.
// On secure, completely private networks this can be disabled to increase performance.
MigrationType string `json:"migration_type,omitempty"`
SkipLock bool `json:"skiplock,omitempty"`
// some command save/restore state from this location
StateURI string `json:"stateuri,omitempty"`
// Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage.
// Providing the special value '1' will map each source storage to itself.
TargetStoraage string `json:"targetstorage,omitempty"`
TimeOut int `json:"timeout,omitempty"`
}

type VirtualMachineStopOption struct {
KeepActive bool `json:"keepActive,omitempty"`
MigratedFrom string `json:"migratedfrom,omitempty"`
SkipLock bool `json:"skiplock,omitempty"`
TimeOut int `json:"timeout,omitempty"`
}
12 changes: 6 additions & 6 deletions proxmox/qemu.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,28 +152,28 @@ func (c *VirtualMachine) ResizeVolume(ctx context.Context, disk, size string) er
return nil
}

func (c *VirtualMachine) Start(ctx context.Context) error {
func (c *VirtualMachine) Start(ctx context.Context, option api.VirtualMachineStartOption) error {
path := fmt.Sprintf("/nodes/%s/qemu/%d/status/start", c.Node, c.VM.VMID)
var upid string
if err := c.restclient.Post(ctx, path, nil, &upid); err != nil {
if err := c.restclient.Post(ctx, path, option, &upid); err != nil {
return err
}
return c.service.EnsureTaskDone(ctx, c.Node, upid)
}

func (c *VirtualMachine) Stop(ctx context.Context) error {
func (c *VirtualMachine) Stop(ctx context.Context, option api.VirtualMachineStopOption) error {
path := fmt.Sprintf("/nodes/%s/qemu/%d/status/stop", c.Node, c.VM.VMID)
var upid string
if err := c.restclient.Post(ctx, path, nil, &upid); err != nil {
if err := c.restclient.Post(ctx, path, option, &upid); err != nil {
return err
}
return c.service.EnsureTaskDone(ctx, c.Node, upid)
}

func (c *VirtualMachine) Resume(ctx context.Context) error {
func (c *VirtualMachine) Resume(ctx context.Context, option api.VirtualMachineResumeOption) error {
path := fmt.Sprintf("/nodes/%s/qemu/%d/status/resume", c.Node, c.VM.VMID)
var upid string
if err := c.restclient.Post(ctx, path, nil, &upid); err != nil {
if err := c.restclient.Post(ctx, path, option, &upid); err != nil {
return err
}
return c.service.EnsureTaskDone(ctx, c.Node, upid)
Expand Down
44 changes: 44 additions & 0 deletions proxmox/qemu_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package proxmox

import (
"context"

"github.com/sp-yduck/proxmox-go/api"
)

func (s *TestSuite) TestVirtualMachine() {
_, testVM := s.getTestVirtualMachine()
vm, err := s.service.VirtualMachine(context.TODO(), testVM.VM.VMID)
if err != nil {
s.T().Fatalf("failed to get vm(vmid=%d): %v", testVM.VM.VMID, err)
}
s.Assert().Equal(*vm, *testVM)
}

func (s *TestSuite) TestStop() {
_, testVM := s.getTestVirtualMachine()
if err := testVM.Stop(context.TODO(), api.VirtualMachineStopOption{}); err != nil {
s.T().Fatalf("failed to stop vm: %v", err)
}
}

func (s *TestSuite) getTestNode() *api.Node {
nodes, err := s.service.restclient.GetNodes(context.TODO())
if err != nil {
s.T().Fatalf("failed to get nodes: %v", err)
}
return nodes[0]
}

func (s *TestSuite) getTestVirtualMachine() (*api.Node, *VirtualMachine) {
node := s.getTestNode()
vms, err := s.service.restclient.GetVirtualMachines(context.TODO(), node.Node)
if err != nil {
s.T().Fatalf("failed to get vms: %v", err)
}
vm, err := s.service.VirtualMachine(context.TODO(), vms[0].VMID)
if err != nil {
s.T().Fatalf("failed to get vm: %v", err)
}
return node, vm
}
41 changes: 41 additions & 0 deletions proxmox/suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package proxmox

import (
"os"
"testing"

"github.com/stretchr/testify/suite"
)

type TestSuite struct {
suite.Suite
service Service
}

func (s *TestSuite) SetupSuite() {
url := os.Getenv("PROXMOX_URL")
user := os.Getenv("PROXMOX_USERNAME")
password := os.Getenv("PROXMOX_PASSWORD")
tokeid := os.Getenv("PROXMOX_TOKENID")
secret := os.Getenv("PROXMOX_SECRET")
if url == "" {
s.T().Fatal("url must not be empty")
}

authConfig := AuthConfig{
Username: user,
Password: password,
TokenID: tokeid,
Secret: secret,
}

service, err := NewService(url, authConfig, true)
if err != nil {
s.T().Fatalf("failed to create new service: %v", err)
}
s.service = *service
}

func TestSuiteIntegration(t *testing.T) {
suite.Run(t, new(TestSuite))
}
9 changes: 6 additions & 3 deletions proxmox/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@ const (
func (s *Service) MustGetTask(ctx context.Context, node string, upid string) (*api.Task, error) {
for i := 0; i < 10; i++ {
task, err := s.restclient.GetTask(ctx, node, upid)
if rest.IsNotFound(err) {
time.Sleep(time.Second * 1)
continue
if err != nil {
if rest.IsNotFound(err) {
time.Sleep(time.Second * 1)
continue
}
return nil, err
}
return task, nil
}
Expand Down
33 changes: 33 additions & 0 deletions proxmox/task_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package proxmox

import (
"context"

"github.com/sp-yduck/proxmox-go/api"
)

func (s *TestSuite) TestMustGetTask() {
testNode, testTask := s.getTestTask()
task, err := s.service.MustGetTask(context.TODO(), testNode.Node, testTask.UPID)
if err != nil {
s.T().Fatalf("failed to get task: %v", err)
}
s.Assert().Equal(*task, *testTask)
}

func (s *TestSuite) TestEnsureTaskDone() {
testNode, testTask := s.getTestTask()
err := s.service.EnsureTaskDone(context.TODO(), testNode.Node, testTask.UPID)
if err != nil {
s.T().Fatalf("failed to get task: %v", err)
}
}

func (s *TestSuite) getTestTask() (*api.Node, *api.Task) {
node := s.getTestNode()
tasks, err := s.service.restclient.GetTasks(context.TODO(), node.Node)
if err != nil {
s.T().Fatalf("failed to get tasks: %v", err)
}
return node, tasks[0]
}
6 changes: 6 additions & 0 deletions rest/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,15 @@ func (e *Error) Error() string {
}

func IsNotFound(err error) bool {
if err == nil {
return false
}
return err.Error() == NotFound
}

func IsNotAuthorized(err error) bool {
if err == nil {
return false
}
return err.Error() == NotAuthorized
}

0 comments on commit bf81716

Please sign in to comment.