0
0
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:
dandaolrian 2023-08-10 17:01:14 +02:00 committed by GitHub
parent 8a5a53301b
commit f901e711dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 28 additions and 2 deletions

View File

@ -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 \

View File

@ -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

View File

@ -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
} }

View File

@ -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.

View File

@ -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)