This commit is contained in:
2026-06-15 13:23:15 +03:00
parent 6b82f23445
commit e459fcb4c4
19 changed files with 268 additions and 104 deletions

View File

@@ -71,13 +71,15 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
return diag.Errorf("resourceComputeCreate: can't create Compute because rgID %d is not allowed or does not exist", d.Get("rg_id").(int))
}
hasImage, err := existImageId(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
if !d.Get("create_blank").(bool) {
hasImage, err := existImageId(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
if !hasImage {
return diag.Errorf("resourceComputeCreate: can't create Compute because imageID %d is not allowed or does not exist", d.Get("image_id").(int))
if !hasImage {
return diag.Errorf("resourceComputeCreate: can't create Compute because imageID %d is not allowed or does not exist", d.Get("image_id").(int))
}
}
if zoneID, ok := d.GetOk("zone_id"); ok {
@@ -288,7 +290,31 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
}
log.Debugf("resourceComputeCreate: creating Compute of type KVM VM x86")
apiResp, err := c.CloudAPI().KVMX86().Create(ctx, createReqX86)
var apiResp uint64
if d.Get("create_blank").(bool) {
log.Debugf("resourceComputeCreate: using createBlank endpoint")
createBlankReq := kvmx86.CreateBlankRequest{
RGID: createReqX86.RGID,
Name: createReqX86.Name,
CPU: createReqX86.CPU,
RAM: createReqX86.RAM,
StoragePolicyID: createReqX86.StoragePolicyID,
WithoutBootDisk: createReqX86.WithoutBootDisk,
BootDisk: createReqX86.BootDisk,
SEPID: createReqX86.SepID,
Pool: createReqX86.Pool,
DataDisks: createReqX86.DataDisks,
Interfaces: createReqX86.Interfaces,
Description: createReqX86.Description,
Chipset: createReqX86.Chipset,
PreferredCPU: createReqX86.PreferredCPU,
ZoneID: createReqX86.ZoneID,
OSVersion: createReqX86.OSVersion,
}
apiResp, err = c.CloudAPI().KVMX86().CreateBlank(ctx, createBlankReq)
} else {
apiResp, err = c.CloudAPI().KVMX86().Create(ctx, createReqX86)
}
if err != nil {
return diag.FromErr(err)
}
@@ -452,6 +478,9 @@ func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interf
if start, ok := d.GetOk("started"); ok {
if start.(bool) {
req := compute.StartRequest{ComputeID: computeId}
if altBootID, ok := d.Get("alt_boot_id").(int); ok {
req.AltBootID = uint64(altBootID)
}
log.Debugf("resourceComputeCreate: starting Compute ID %d after completing its resource configuration", computeId)
if _, err := c.CloudAPI().Compute().Start(ctx, req); err != nil {
warnings.Add(err)
@@ -763,13 +792,15 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
return diag.Errorf("resourceComputeUpdate: can't update Compute because rgID %d not allowed or does not exist", d.Get("rg_id").(int))
}
hasImage, err := existImageId(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
if !d.Get("create_blank").(bool) {
hasImage, err := existImageId(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
if !hasImage {
return diag.Errorf("resourceComputeUpdate: can't update Compute because imageID %d not allowed or does not exist", d.Get("image_id").(int))
if !hasImage {
return diag.Errorf("resourceComputeUpdate: can't update Compute because imageID %d not allowed or does not exist", d.Get("image_id").(int))
}
}
if d.HasChange("zone_id") {
@@ -857,6 +888,9 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
if start, ok := d.GetOk("started"); ok {
if start.(bool) {
req := compute.StartRequest{ComputeID: computeRec.ID}
if altBootID, ok := d.Get("alt_boot_id").(int); ok {
req.AltBootID = uint64(altBootID)
}
if _, err := c.CloudAPI().Compute().Start(ctx, req); err != nil {
return diag.FromErr(err)
@@ -1099,7 +1133,11 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
// If used to be STARTED, we need to start it after update
if isStopRequired {
if _, err := c.CloudAPI().Compute().Start(ctx, compute.StartRequest{ComputeID: computeRec.ID}); err != nil {
req := compute.StartRequest{ComputeID: computeRec.ID}
if altBootID, ok := d.Get("alt_boot_id").(int); ok {
req.AltBootID = uint64(altBootID)
}
if _, err := c.CloudAPI().Compute().Start(ctx, req); err != nil {
return diag.FromErr(err)
}
}
@@ -1208,9 +1246,6 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
if diskConv["sep_id"].(int) != 0 {
req.SepID = uint64(diskConv["sep_id"].(int))
}
if diskConv["disk_type"].(string) != "" {
req.DiskType = diskConv["disk_type"].(string)
}
if diskConv["pool"].(string) != "" {
req.Pool = diskConv["pool"].(string)
}
@@ -1856,6 +1891,9 @@ func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interf
req := compute.StartRequest{
ComputeID: computeRec.ID,
}
if altBootID, ok := d.Get("alt_boot_id").(int); ok {
req.AltBootID = uint64(altBootID)
}
if !isStopRequired {
if _, err := c.CloudAPI().Compute().Start(ctx, req); err != nil {
return diag.FromErr(err)
@@ -2051,11 +2089,9 @@ func disksSubresourceSchemaMake() map[string]*schema.Schema {
Description: "Storage endpoint provider ID; by default the same with boot disk",
},
"disk_type": {
Type: schema.TypeString,
Computed: true,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{"B", "D"}, false),
Description: "The type of disk in terms of its role in compute: 'B=Boot, D=Data'",
Type: schema.TypeString,
Computed: true,
Description: "The type of disk in terms of its role in compute: 'B=Boot, D=Data'",
},
"pool": {
Type: schema.TypeString,
@@ -2353,6 +2389,12 @@ func ResourceComputeSchemaMake() map[string]*schema.Schema {
Default: false,
Description: "If True, the imageId, bootDisk, sepId, pool parameters are ignored and the compute is created without a boot disk in the stopped state.",
},
"create_blank": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "If True, the compute is created via kvmx86/createBlank endpoint (without OS image). The image_id field is not required in this case.",
},
"boot_disk_size": {
Type: schema.TypeInt,
Optional: true,
@@ -2607,6 +2649,11 @@ func ResourceComputeSchemaMake() map[string]*schema.Schema {
Default: false,
Description: "Flag for resize compute",
},
"alt_boot_id": {
Type: schema.TypeInt,
Optional: true,
Description: "ID of CD-ROM live image to boot",
},
"started": {
Type: schema.TypeBool,
Optional: true,

View File

@@ -293,7 +293,13 @@ func utilityComputeNetworksConfigure(ctx context.Context, d *schema.ResourceData
if needStart {
computeId, _ := strconv.ParseUint(d.Id(), 10, 64)
if numErr, err := utilityComputeStart(ctx, computeId, m); err != nil {
var altBootID uint64
if altBootIDRaw, ok := d.Get("alt_boot_id").(int); ok {
altBootID = uint64(altBootIDRaw)
} else {
altBootID = 0
}
if numErr, err := utilityComputeStart(ctx, computeId, altBootID, m); err != nil {
apiErrCount += numErr
lastSavedError = err
}
@@ -456,10 +462,14 @@ func utilityComputeStop(ctx context.Context, computeID uint64, m interface{}) er
return nil
}
func utilityComputeStart(ctx context.Context, computeID uint64, m interface{}) (int, error) {
func utilityComputeStart(ctx context.Context, computeID uint64, altBootID uint64, m interface{}) (int, error) {
c := m.(*controller.ControllerCfg)
startReq := compute.StartRequest{ComputeID: computeID}
if altBootID > 0 {
startReq.AltBootID = altBootID
}
log.Debugf("utilityComputeNetworksConfigure: starting compute %d", computeID)
_, err := c.CloudAPI().Compute().Start(ctx, startReq)
if err != nil {