mirror of
https://github.com/bpg/terraform-provider-proxmox.git
synced 2025-08-22 19:38:35 +00:00
feat(file): ensure upload of ISO/VSTMPL is completed upon resource creation (#471)
* feat(provider): ensure upload of ISO/VSTMPL completes before starting VM and add timeout to config for this * remove `ForceNew: true` for the timeout attribute * minor docs update --------- Co-authored-by: dandaolrian <dandaolrian@users.noreply.github.com> Co-authored-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
This commit is contained in:
parent
8a5a53301b
commit
f901e711dd
1
Makefile
1
Makefile
@ -33,6 +33,7 @@ example: example-build example-init example-apply example-destroy
|
|||||||
|
|
||||||
example-apply:
|
example-apply:
|
||||||
export TF_CLI_CONFIG_FILE="$(shell pwd -P)/example.tfrc" \
|
export TF_CLI_CONFIG_FILE="$(shell pwd -P)/example.tfrc" \
|
||||||
|
&& export TF_REATTACH_PROVIDERS='{"registry.terraform.io/bpg/proxmox":{"Protocol":"grpc","ProtocolVersion":6,"Pid":82711,"Test":true,"Addr":{"Network":"unix","String":"/var/folders/xx/4plpx_3133lbctp7b7v1yfch0000gn/T/plugin3121225613"}}}' \
|
||||||
&& export TF_DISABLE_CHECKPOINT="true" \
|
&& export TF_DISABLE_CHECKPOINT="true" \
|
||||||
&& export TF_PLUGIN_CACHE_DIR="$(TERRAFORM_PLUGIN_CACHE_DIRECTORY)" \
|
&& export TF_PLUGIN_CACHE_DIR="$(TERRAFORM_PLUGIN_CACHE_DIRECTORY)" \
|
||||||
&& cd ./example \
|
&& cd ./example \
|
||||||
|
@ -76,6 +76,8 @@ EOF
|
|||||||
- `data` - (Required) The raw data.
|
- `data` - (Required) The raw data.
|
||||||
- `file_name` - (Required) The file name.
|
- `file_name` - (Required) The file name.
|
||||||
- `resize` - (Optional) The number of bytes to resize the file to.
|
- `resize` - (Optional) The number of bytes to resize the file to.
|
||||||
|
- `timeout_upload` - (Optional) Timeout for uploading ISO/VSTMPL files in
|
||||||
|
seconds (defaults to 1800).
|
||||||
|
|
||||||
## Attribute Reference
|
## Attribute Reference
|
||||||
|
|
||||||
@ -96,7 +98,8 @@ created as another temporary file).
|
|||||||
|
|
||||||
## Import
|
## Import
|
||||||
|
|
||||||
Instances can be imported using the `node_name`, `datastore_id`, `content_type` and the `file_name`, e.g.,
|
Instances can be imported using the `node_name`, `datastore_id`, `content_type`
|
||||||
|
and the `file_name`, e.g.,
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ terraform import proxmox_virtual_environment_file.cloud_config pve/local/snippets/example.cloud-config.yaml
|
$ terraform import proxmox_virtual_environment_file.cloud_config pve/local/snippets/example.cloud-config.yaml
|
||||||
|
@ -144,6 +144,7 @@ func (c *Client) APIUpload(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
datastoreID string,
|
datastoreID string,
|
||||||
d *api.FileUploadRequest,
|
d *api.FileUploadRequest,
|
||||||
|
uploadTimeout int,
|
||||||
) (*DatastoreUploadResponseBody, error) {
|
) (*DatastoreUploadResponseBody, error) {
|
||||||
tflog.Debug(ctx, "uploading file to datastore using PVE API", map[string]interface{}{
|
tflog.Debug(ctx, "uploading file to datastore using PVE API", map[string]interface{}{
|
||||||
"file_name": d.FileName,
|
"file_name": d.FileName,
|
||||||
@ -276,5 +277,15 @@ func (c *Client) APIUpload(
|
|||||||
return nil, fmt.Errorf("error uploading file to datastore %s: %w", datastoreID, err)
|
return nil, fmt.Errorf("error uploading file to datastore %s: %w", datastoreID, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if resBody.UploadID == nil {
|
||||||
|
return nil, fmt.Errorf("error uploading file to datastore %s: no uploadID", datastoreID)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.Tasks().WaitForTask(ctx, *resBody.UploadID, uploadTimeout, 5)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error uploading file to datastore %s: failed waiting for upload - %w", datastoreID, err)
|
||||||
|
}
|
||||||
|
|
||||||
return resBody, nil
|
return resBody, nil
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,7 @@ const (
|
|||||||
dvResourceVirtualEnvironmentFileSourceFileFileName = ""
|
dvResourceVirtualEnvironmentFileSourceFileFileName = ""
|
||||||
dvResourceVirtualEnvironmentFileSourceFileInsecure = false
|
dvResourceVirtualEnvironmentFileSourceFileInsecure = false
|
||||||
dvResourceVirtualEnvironmentFileSourceRawResize = 0
|
dvResourceVirtualEnvironmentFileSourceRawResize = 0
|
||||||
|
dvResourceVirtualEnvironmentFileTimeoutUpload = 1800
|
||||||
|
|
||||||
mkResourceVirtualEnvironmentFileContentType = "content_type"
|
mkResourceVirtualEnvironmentFileContentType = "content_type"
|
||||||
mkResourceVirtualEnvironmentFileDatastoreID = "datastore_id"
|
mkResourceVirtualEnvironmentFileDatastoreID = "datastore_id"
|
||||||
@ -58,6 +59,7 @@ const (
|
|||||||
mkResourceVirtualEnvironmentFileSourceRawData = "data"
|
mkResourceVirtualEnvironmentFileSourceRawData = "data"
|
||||||
mkResourceVirtualEnvironmentFileSourceRawFileName = "file_name"
|
mkResourceVirtualEnvironmentFileSourceRawFileName = "file_name"
|
||||||
mkResourceVirtualEnvironmentFileSourceRawResize = "resize"
|
mkResourceVirtualEnvironmentFileSourceRawResize = "resize"
|
||||||
|
mkResourceVirtualEnvironmentFileTimeoutUpload = "timeout_upload"
|
||||||
)
|
)
|
||||||
|
|
||||||
// File returns a resource that manages files on a node.
|
// File returns a resource that manages files on a node.
|
||||||
@ -190,6 +192,12 @@ func File() *schema.Resource {
|
|||||||
MaxItems: 1,
|
MaxItems: 1,
|
||||||
MinItems: 0,
|
MinItems: 0,
|
||||||
},
|
},
|
||||||
|
mkResourceVirtualEnvironmentFileTimeoutUpload: {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Description: "Timeout for uploading ISO/VSTMPL files in seconds",
|
||||||
|
Optional: true,
|
||||||
|
Default: dvResourceVirtualEnvironmentFileTimeoutUpload,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
CreateContext: fileCreate,
|
CreateContext: fileCreate,
|
||||||
ReadContext: fileRead,
|
ReadContext: fileRead,
|
||||||
@ -425,7 +433,8 @@ func fileCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag
|
|||||||
|
|
||||||
switch *contentType {
|
switch *contentType {
|
||||||
case "iso", "vztmpl":
|
case "iso", "vztmpl":
|
||||||
_, err = capi.Node(nodeName).APIUpload(ctx, datastoreID, request)
|
uploadTimeout := d.Get(mkResourceVirtualEnvironmentFileTimeoutUpload).(int)
|
||||||
|
_, err = capi.Node(nodeName).APIUpload(ctx, datastoreID, request, uploadTimeout)
|
||||||
default:
|
default:
|
||||||
// For all other content types, we need to upload the file to the node's
|
// For all other content types, we need to upload the file to the node's
|
||||||
// datastore using SFTP.
|
// datastore using SFTP.
|
||||||
|
@ -40,6 +40,7 @@ func TestFileSchema(t *testing.T) {
|
|||||||
mkResourceVirtualEnvironmentFileContentType,
|
mkResourceVirtualEnvironmentFileContentType,
|
||||||
mkResourceVirtualEnvironmentFileSourceFile,
|
mkResourceVirtualEnvironmentFileSourceFile,
|
||||||
mkResourceVirtualEnvironmentFileSourceRaw,
|
mkResourceVirtualEnvironmentFileSourceRaw,
|
||||||
|
mkResourceVirtualEnvironmentFileTimeoutUpload,
|
||||||
})
|
})
|
||||||
|
|
||||||
test.AssertComputedAttributes(t, s, []string{
|
test.AssertComputedAttributes(t, s, []string{
|
||||||
@ -59,6 +60,7 @@ func TestFileSchema(t *testing.T) {
|
|||||||
mkResourceVirtualEnvironmentFileNodeName: schema.TypeString,
|
mkResourceVirtualEnvironmentFileNodeName: schema.TypeString,
|
||||||
mkResourceVirtualEnvironmentFileSourceFile: schema.TypeList,
|
mkResourceVirtualEnvironmentFileSourceFile: schema.TypeList,
|
||||||
mkResourceVirtualEnvironmentFileSourceRaw: schema.TypeList,
|
mkResourceVirtualEnvironmentFileSourceRaw: schema.TypeList,
|
||||||
|
mkResourceVirtualEnvironmentFileTimeoutUpload: schema.TypeInt,
|
||||||
})
|
})
|
||||||
|
|
||||||
sourceFileSchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentFileSourceFile)
|
sourceFileSchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentFileSourceFile)
|
||||||
|
Loading…
Reference in New Issue
Block a user