mirror of
https://github.com/bpg/terraform-provider-proxmox.git
synced 2025-08-22 19:38:35 +00:00
Merge pull request #16 from danitso/bugfix-vm-id-uniqueness
Bugfix vm id uniqueness
This commit is contained in:
commit
bbdc197609
@ -3,6 +3,8 @@
|
||||
BUG FIXES:
|
||||
|
||||
* library/virtual_environment_nodes: Fix node IP address format
|
||||
* resource/virtual_environment_container: Fix VM ID collision when `vm_id` is not specified
|
||||
* resource/virtual_environment_vm: Fix VM ID collision when `vm_id` is not specified
|
||||
|
||||
WORKAROUNDS:
|
||||
|
||||
|
1
go.sum
1
go.sum
@ -78,6 +78,7 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
|
||||
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
|
||||
|
@ -18,6 +18,9 @@ type CustomBool bool
|
||||
// CustomCommaSeparatedList allows a JSON string to also be a string array.
|
||||
type CustomCommaSeparatedList []string
|
||||
|
||||
// CustomInt allows a JSON integer value to also be a string.
|
||||
type CustomInt int
|
||||
|
||||
// CustomLineBreakSeparatedList allows a multiline JSON string to also be a string array.
|
||||
type CustomLineBreakSeparatedList []string
|
||||
|
||||
@ -70,6 +73,25 @@ func (r *CustomCommaSeparatedList) UnmarshalJSON(b []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON converts a JSON value to an integer.
|
||||
func (r *CustomInt) UnmarshalJSON(b []byte) error {
|
||||
s := string(b)
|
||||
|
||||
if strings.HasPrefix(s, "\"") && strings.HasSuffix(s, "\"") {
|
||||
s = s[1 : len(s)-1]
|
||||
}
|
||||
|
||||
i, err := strconv.ParseInt(s, 10, 32)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*r = CustomInt(i)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON converts a boolean to a JSON value.
|
||||
func (r *CustomLineBreakSeparatedList) MarshalJSON() ([]byte, error) {
|
||||
s := strings.Join(*r, "\n")
|
||||
|
29
proxmox/virtual_environment_cluster.go
Normal file
29
proxmox/virtual_environment_cluster.go
Normal file
@ -0,0 +1,29 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package proxmox
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
// GetClusterNextID retrieves the next free VM identifier for the cluster.
|
||||
func (c *VirtualEnvironmentClient) GetClusterNextID(vmID *int) (*int, error) {
|
||||
reqBody := &VirtualEnvironmentClusterNextIDRequestBody{
|
||||
VMID: vmID,
|
||||
}
|
||||
|
||||
resBody := &VirtualEnvironmentClusterNextIDResponseBody{}
|
||||
err := c.DoRequest(hmGET, "cluster/nextid", reqBody, resBody)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resBody.Data == nil {
|
||||
return nil, errors.New("The server did not include a data object in the response")
|
||||
}
|
||||
|
||||
return (*int)(resBody.Data), nil
|
||||
}
|
15
proxmox/virtual_environment_cluster_types.go
Normal file
15
proxmox/virtual_environment_cluster_types.go
Normal file
@ -0,0 +1,15 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package proxmox
|
||||
|
||||
// VirtualEnvironmentClusterNextIDRequestBody contains the data for a cluster next id request.
|
||||
type VirtualEnvironmentClusterNextIDRequestBody struct {
|
||||
VMID *int `json:"vmid,omitempty" url:"vmid,omitempty"`
|
||||
}
|
||||
|
||||
// VirtualEnvironmentClusterNextIDResponseBody contains the body from a cluster next id response.
|
||||
type VirtualEnvironmentClusterNextIDResponseBody struct {
|
||||
Data *CustomInt `json:"data,omitempty"`
|
||||
}
|
@ -7,11 +7,22 @@ package proxmox
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
getVMIDStep = 1
|
||||
)
|
||||
|
||||
var (
|
||||
getVMIDCounter = -1
|
||||
getVMIDCounterMutex = &sync.Mutex{}
|
||||
)
|
||||
|
||||
// CloneVM clones a virtual machine.
|
||||
func (c *VirtualEnvironmentClient) CloneVM(nodeName string, vmID int, d *VirtualEnvironmentVMCloneRequestBody) error {
|
||||
return c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/qemu/%d/clone", url.PathEscape(nodeName), vmID), d, nil)
|
||||
@ -45,30 +56,46 @@ func (c *VirtualEnvironmentClient) GetVM(nodeName string, vmID int) (*VirtualEnv
|
||||
|
||||
// GetVMID retrieves the next available VM identifier.
|
||||
func (c *VirtualEnvironmentClient) GetVMID() (*int, error) {
|
||||
nodes, err := c.ListNodes()
|
||||
getVMIDCounterMutex.Lock()
|
||||
defer getVMIDCounterMutex.Unlock()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if getVMIDCounter < 0 {
|
||||
nextVMID, err := c.GetClusterNextID(nil)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if nextVMID == nil {
|
||||
return nil, errors.New("Unable to retrieve the next available VM identifier")
|
||||
}
|
||||
|
||||
getVMIDCounter = *nextVMID + getVMIDStep
|
||||
|
||||
log.Printf("[DEBUG] Determined next available VM identifier to be %d", *nextVMID)
|
||||
|
||||
return nextVMID, nil
|
||||
}
|
||||
|
||||
vmID := 100
|
||||
vmID := getVMIDCounter
|
||||
|
||||
VMID:
|
||||
for vmID <= 2147483637 {
|
||||
for _, n := range nodes {
|
||||
err := c.DoRequest(hmGET, fmt.Sprintf("nodes/%s/qemu/%d/status/current", url.PathEscape(n.Name), vmID), nil, nil)
|
||||
_, err := c.GetClusterNextID(&vmID)
|
||||
|
||||
if err == nil {
|
||||
vmID += 5
|
||||
if err != nil {
|
||||
vmID += getVMIDStep
|
||||
|
||||
continue VMID
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
getVMIDCounter = vmID + getVMIDStep
|
||||
|
||||
log.Printf("[DEBUG] Determined next available VM identifier to be %d", vmID)
|
||||
|
||||
return &vmID, nil
|
||||
}
|
||||
|
||||
return nil, errors.New("Unable to retrieve the next available VM identifier")
|
||||
return nil, errors.New("Unable to determine the next available VM identifier")
|
||||
}
|
||||
|
||||
// GetVMNetworkInterfacesFromAgent retrieves the network interfaces reported by the QEMU agent.
|
||||
|
@ -349,7 +349,7 @@ func getVLANIDsValidator() schema.SchemaValidateFunc {
|
||||
|
||||
func getVMIDValidator() schema.SchemaValidateFunc {
|
||||
return func(i interface{}, k string) (ws []string, es []error) {
|
||||
min := 1
|
||||
min := 100
|
||||
max := 2147483647
|
||||
|
||||
v, ok := i.(int)
|
||||
|
Loading…
Reference in New Issue
Block a user