From 2d9e0b585e307196b97a680716db75c9cc010bac Mon Sep 17 00:00:00 2001
From: Marco Attia <54147992+Vaneixus@users.noreply.github.com>
Date: Sat, 28 Jun 2025 01:23:22 +0000
Subject: [PATCH] feat: add support for 'import' content type in Proxmox file
resources (#1983)
Signed-off-by: Marco Attia <54147992+Vaneixus@users.noreply.github.com>
Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
Co-authored-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
---
README.md | 2 +-
docs/guides/setup-proxmox-for-tests.md | 2 +-
.../virtual_environment_download_file.md | 26 +++++++++++--
docs/resources/virtual_environment_file.md | 17 ++++++++-
...ource_virtual_environment_download_file.tf | 10 +++++
.../resource.tf | 18 +++++++++
.../resource.tf | 19 ++++++++++
fwprovider/datasource_version.go | 2 +-
fwprovider/nodes/resource_download_file.go | 8 ++--
.../nodes/resource_download_file_test.go | 17 ++++++++-
proxmox/version/capabilities.go | 20 ++++++++++
proxmox/version/version_types.go | 30 +++++++++++++--
proxmoxtf/resource/file.go | 37 +++++++++++++------
proxmoxtf/resource/file_test.go | 7 +++-
proxmoxtf/resource/validators/file.go | 1 +
.../guides/setup-proxmox-for-tests.md.tmpl | 2 +-
16 files changed, 189 insertions(+), 29 deletions(-)
create mode 100644 examples/resources/proxmox_virtual_environment_file/resource.tf
create mode 100644 proxmox/version/capabilities.go
diff --git a/README.md b/README.md
index a780e8e7..da27fdfd 100644
--- a/README.md
+++ b/README.md
@@ -71,7 +71,7 @@ The following assumptions are made about the test environment:
- It has one node named `pve`
- The node has local storages named `local` and `local-lvm`
-- The "Snippets" content type is enabled in the `local` storage
+- The "Snippets" and "Import" content types are enabled in the `local` storage
- Default Linux Bridge "vmbr0" is VLAN aware (datacenter -> pve -> network -> edit & apply)
Create `example/terraform.tfvars` with the following variables:
diff --git a/docs/guides/setup-proxmox-for-tests.md b/docs/guides/setup-proxmox-for-tests.md
index 2d2f9f72..71ea146f 100644
--- a/docs/guides/setup-proxmox-for-tests.md
+++ b/docs/guides/setup-proxmox-for-tests.md
@@ -92,4 +92,4 @@ Goal is to have a proxmox node in VM using for a job
10. Now you can run `make example`.
-11. If you see error with proxmox_virtual_environment_file: the datastore "local" does not support content type "snippets"; supported content types are: `[backup, iso, vztmpl]`, you need to enable them, see .
+11. If you see error with proxmox_virtual_environment_file: the datastore "local" does not support content type "snippets"; supported content types are: `[backup, iso, vztmpl, import]`, you need to enable them, see .
diff --git a/docs/resources/virtual_environment_download_file.md b/docs/resources/virtual_environment_download_file.md
index 74609db3..42ed5a49 100644
--- a/docs/resources/virtual_environment_download_file.md
+++ b/docs/resources/virtual_environment_download_file.md
@@ -4,12 +4,12 @@ title: proxmox_virtual_environment_download_file
parent: Resources
subcategory: Virtual Environment
description: |-
- Manages files upload using PVE download-url API. It can be fully compatible and faster replacement for image files created using proxmox_virtual_environment_file. Supports images for VMs (ISO images) and LXC (CT Templates).
+ Manages files upload using PVE download-url API. It can be fully compatible and faster replacement for image files created using proxmox_virtual_environment_file. Supports images for VMs (ISO and disk images) and LXC (CT Templates).
---
# Resource: proxmox_virtual_environment_download_file
-Manages files upload using PVE download-url API. It can be fully compatible and faster replacement for image files created using `proxmox_virtual_environment_file`. Supports images for VMs (ISO images) and LXC (CT Templates).
+Manages files upload using PVE download-url API. It can be fully compatible and faster replacement for image files created using `proxmox_virtual_environment_file`. Supports images for VMs (ISO and disk images) and LXC (CT Templates).
~> Besides the `Datastore.AllocateTemplate` privilege, this resource requires both the `Sys.Audit` and `Sys.Modify` privileges.
For more details, see the [`download-url`](https://pve.proxmox.com/pve-docs/api-viewer/index.html#/nodes/{node}/storage/{storage}/download-url) API documentation under the "Required permissions" section.
@@ -27,6 +27,16 @@ resource "proxmox_virtual_environment_download_file" "release_20231228_debian_12
checksum_algorithm = "sha512"
}
+resource "proxmox_virtual_environment_download_file" "release_20231228_debian_12_bookworm_qcow2" {
+ content_type = "import"
+ datastore_id = "local"
+ file_name = "debian-12-generic-amd64-20231228-1609.qcow2"
+ node_name = "pve"
+ url = "https://cloud.debian.org/images/cloud/bookworm/20231228-1609/debian-12-generic-amd64-20231228-1609.qcow2"
+ checksum = "d2fbcf11fb28795842e91364d8c7b69f1870db09ff299eb94e4fbbfa510eb78d141e74c1f4bf6dfa0b7e33d0c3b66e6751886feadb4e9916f778bab1776bdf1b"
+ checksum_algorithm = "sha512"
+}
+
resource "proxmox_virtual_environment_download_file" "latest_debian_12_bookworm_qcow2_img" {
content_type = "iso"
datastore_id = "local"
@@ -35,6 +45,14 @@ resource "proxmox_virtual_environment_download_file" "latest_debian_12_bookworm_
url = "https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2"
}
+resource "proxmox_virtual_environment_download_file" "latest_debian_12_bookworm_qcow2" {
+ content_type = "import"
+ datastore_id = "local"
+ file_name = "debian-12-generic-amd64.qcow2"
+ node_name = "pve"
+ url = "https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2"
+}
+
resource "proxmox_virtual_environment_download_file" "latest_ubuntu_22_jammy_qcow2_img" {
content_type = "iso"
datastore_id = "local"
@@ -73,7 +91,7 @@ resource "proxmox_virtual_environment_download_file" "latest_ubuntu_22_jammy_lxc
### Required
-- `content_type` (String) The file content type. Must be `iso` for VM images or `vztmpl` for LXC images.
+- `content_type` (String) The file content type. Must be `iso` or `import` for VM images or `vztmpl` for LXC images.
- `datastore_id` (String) The identifier for the target datastore.
- `node_name` (String) The node name.
- `url` (String) The URL to download the file from. Must match regex: `https?://.*`.
@@ -83,7 +101,7 @@ resource "proxmox_virtual_environment_download_file" "latest_ubuntu_22_jammy_lxc
- `checksum` (String) The expected checksum of the file.
- `checksum_algorithm` (String) The algorithm to calculate the checksum of the file. Must be `md5` | `sha1` | `sha224` | `sha256` | `sha384` | `sha512`.
- `decompression_algorithm` (String) Decompress the downloaded file using the specified compression algorithm. Must be one of `gz` | `lzo` | `zst` | `bz2`.
-- `file_name` (String) The file name. If not provided, it is calculated using `url`. PVE will raise 'wrong file extension' error for some popular extensions file `.raw` or `.qcow2`. Workaround is to use e.g. `.img` instead.
+- `file_name` (String) The file name. If not provided, it is calculated using `url`. PVE will raise 'wrong file extension' error for some popular extensions file `.raw` or `.qcow2` on PVE versions prior to 8.4. Workaround is to use e.g. `.img` instead.
- `overwrite` (Boolean) By default `true`. If `true` and file size has changed in the datastore, it will be replaced. If `false`, there will be no check.
- `overwrite_unmanaged` (Boolean) If `true` and a file with the same name already exists in the datastore, it will be deleted and the new file will be downloaded. If `false` and the file already exists, an error will be returned.
- `upload_timeout` (Number) The file download timeout seconds. Default is 600 (10min).
diff --git a/docs/resources/virtual_environment_file.md b/docs/resources/virtual_environment_file.md
index 90c36275..4c3dfaf6 100644
--- a/docs/resources/virtual_environment_file.md
+++ b/docs/resources/virtual_environment_file.md
@@ -7,7 +7,7 @@ subcategory: Virtual Environment
# Resource: proxmox_virtual_environment_file
-Use this resource to upload files to a Proxmox VE node. The file can be a backup, an ISO image, a snippet, or a container template depending on the `content_type` attribute.
+Use this resource to upload files to a Proxmox VE node. The file can be a backup, an ISO image, a Disk Image, a snippet, or a container template depending on the `content_type` attribute.
## Example Usage
@@ -33,6 +33,8 @@ resource "proxmox_virtual_environment_file" "backup" {
-> Consider using `proxmox_virtual_environment_download_file` resource instead. Using this resource for images is less efficient (requires to transfer uploaded image to node) though still supported.
+-> Importing Disks is not enabled by default in new Proxmox installations. You need to enable them in the 'Datacenter>Storage' section of the proxmox interface before first using this resource with `content_type = "import"`.
+
```hcl
resource "proxmox_virtual_environment_file" "ubuntu_container_template" {
content_type = "iso"
@@ -45,6 +47,18 @@ resource "proxmox_virtual_environment_file" "ubuntu_container_template" {
}
```
+```hcl
+resource "proxmox_virtual_environment_file" "ubuntu_container_template" {
+ content_type = "import"
+ datastore_id = "local"
+ node_name = "pve"
+
+ source_file {
+ path = "https://cloud-images.ubuntu.com/jammy/20230929/jammy-server-cloudimg-amd64-disk-kvm.img"
+ }
+}
+```
+
### Snippets
-> Snippets are not enabled by default in new Proxmox installations. You need to enable them in the 'Datacenter>Storage' section of the proxmox interface before first using this resource.
@@ -126,6 +140,7 @@ resource "proxmox_virtual_environment_file" "ubuntu_container_template" {
- `backup` (allowed extensions: `.vzdump`, `.tar.gz`, `.tar.xz`, `tar.zst`)
- `iso` (allowed extensions: `.iso`, `.img`)
- `snippets` (allowed extensions: any)
+ - `import` (allowed extensions: `.raw`, `.qcow2`, `.vmdk`)
- `vztmpl` (allowed extensions: `.tar.gz`, `.tar.xz`, `tar.zst`)
- `datastore_id` - (Required) The datastore id.
- `file_mode` - The file mode in octal format, e.g. `0700` or `600`. Note that the prefixes `0o` and `0x` is not supported! Setting this attribute is also only allowed for `root@pam` authenticated user.
diff --git a/example/resource_virtual_environment_download_file.tf b/example/resource_virtual_environment_download_file.tf
index 8532d95a..895fcb52 100644
--- a/example/resource_virtual_environment_download_file.tf
+++ b/example/resource_virtual_environment_download_file.tf
@@ -20,3 +20,13 @@ resource "proxmox_virtual_environment_download_file" "latest_debian_12_bookworm_
overwrite = true
overwrite_unmanaged = true
}
+
+resource "proxmox_virtual_environment_download_file" "latest_debian_12_bookworm_qcow2" {
+ content_type = "import"
+ datastore_id = "local"
+ file_name = "debian-12-generic-amd64.qcow2"
+ node_name = "pve"
+ url = var.latest_debian_12_bookworm_qcow2_img_url
+ overwrite = true
+ overwrite_unmanaged = true
+}
diff --git a/examples/resources/proxmox_virtual_environment_download_file/resource.tf b/examples/resources/proxmox_virtual_environment_download_file/resource.tf
index 655f64e2..adc83315 100644
--- a/examples/resources/proxmox_virtual_environment_download_file/resource.tf
+++ b/examples/resources/proxmox_virtual_environment_download_file/resource.tf
@@ -8,6 +8,16 @@ resource "proxmox_virtual_environment_download_file" "release_20231228_debian_12
checksum_algorithm = "sha512"
}
+resource "proxmox_virtual_environment_download_file" "release_20231228_debian_12_bookworm_qcow2" {
+ content_type = "import"
+ datastore_id = "local"
+ file_name = "debian-12-generic-amd64-20231228-1609.qcow2"
+ node_name = "pve"
+ url = "https://cloud.debian.org/images/cloud/bookworm/20231228-1609/debian-12-generic-amd64-20231228-1609.qcow2"
+ checksum = "d2fbcf11fb28795842e91364d8c7b69f1870db09ff299eb94e4fbbfa510eb78d141e74c1f4bf6dfa0b7e33d0c3b66e6751886feadb4e9916f778bab1776bdf1b"
+ checksum_algorithm = "sha512"
+}
+
resource "proxmox_virtual_environment_download_file" "latest_debian_12_bookworm_qcow2_img" {
content_type = "iso"
datastore_id = "local"
@@ -16,6 +26,14 @@ resource "proxmox_virtual_environment_download_file" "latest_debian_12_bookworm_
url = "https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2"
}
+resource "proxmox_virtual_environment_download_file" "latest_debian_12_bookworm_qcow2" {
+ content_type = "import"
+ datastore_id = "local"
+ file_name = "debian-12-generic-amd64.qcow2"
+ node_name = "pve"
+ url = "https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2"
+}
+
resource "proxmox_virtual_environment_download_file" "latest_ubuntu_22_jammy_qcow2_img" {
content_type = "iso"
datastore_id = "local"
diff --git a/examples/resources/proxmox_virtual_environment_file/resource.tf b/examples/resources/proxmox_virtual_environment_file/resource.tf
new file mode 100644
index 00000000..67977b54
--- /dev/null
+++ b/examples/resources/proxmox_virtual_environment_file/resource.tf
@@ -0,0 +1,19 @@
+resource "proxmox_virtual_environment_file" "latest_debian_12_bookworm_qcow2" {
+ content_type = "import"
+ datastore_id = "local"
+ node_name = "pve"
+
+ source_file {
+ path = "https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2"
+ }
+}
+
+resource "proxmox_virtual_environment_file" "release_20231228_debian_12_bookworm_qcow2" {
+ content_type = "import"
+ datastore_id = "local"
+ node_name = "pve"
+
+ source_file {
+ path = "https://cloud.debian.org/images/cloud/bookworm/20231228-1609/debian-12-generic-amd64-20231228-1609.qcow2"
+ }
+}
diff --git a/fwprovider/datasource_version.go b/fwprovider/datasource_version.go
index eb7d3283..76afc5c8 100644
--- a/fwprovider/datasource_version.go
+++ b/fwprovider/datasource_version.go
@@ -115,7 +115,7 @@ func (d *versionDatasource) Read(ctx context.Context, _ datasource.ReadRequest,
state.Release = types.StringValue(version.Release)
state.RepositoryID = types.StringValue(version.RepositoryID)
- state.Version = types.StringValue(version.Version)
+ state.Version = types.StringValue(version.Version.String())
state.ID = types.StringValue("version")
diff --git a/fwprovider/nodes/resource_download_file.go b/fwprovider/nodes/resource_download_file.go
index abee921d..c121d1dc 100644
--- a/fwprovider/nodes/resource_download_file.go
+++ b/fwprovider/nodes/resource_download_file.go
@@ -153,15 +153,16 @@ func (r *downloadFileResource) Schema(
Description: "Manages files upload using PVE download-url API. ",
MarkdownDescription: "Manages files upload using PVE download-url API. " +
"It can be fully compatible and faster replacement for image files created using " +
- "`proxmox_virtual_environment_file`. Supports images for VMs (ISO images) and LXC (CT Templates).",
+ "`proxmox_virtual_environment_file`. Supports images for VMs (ISO and disk images) and LXC (CT Templates).",
Attributes: map[string]schema.Attribute{
"id": attribute.ResourceID(),
"content_type": schema.StringAttribute{
- Description: "The file content type. Must be `iso` for VM images or `vztmpl` for LXC images.",
+ Description: "The file content type. Must be `iso` or `import` for VM images or `vztmpl` for LXC images.",
Required: true,
Validators: []validator.String{stringvalidator.OneOf([]string{
"iso",
"vztmpl",
+ "import",
}...)},
PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplace(),
@@ -170,7 +171,8 @@ func (r *downloadFileResource) Schema(
"file_name": schema.StringAttribute{
Description: "The file name. If not provided, it is calculated " +
"using `url`. PVE will raise 'wrong file extension' error for some popular " +
- "extensions file `.raw` or `.qcow2`. Workaround is to use e.g. `.img` instead.",
+ "extensions file `.raw` or `.qcow2` on PVE versions prior to 8.4. " +
+ "Workaround is to use e.g. `.img` instead.",
Computed: true,
Required: false,
Optional: true,
diff --git a/fwprovider/nodes/resource_download_file_test.go b/fwprovider/nodes/resource_download_file_test.go
index aad1a6c6..add33cf9 100644
--- a/fwprovider/nodes/resource_download_file_test.go
+++ b/fwprovider/nodes/resource_download_file_test.go
@@ -60,7 +60,7 @@ func TestAccResourceDownloadFile(t *testing.T) {
}`),
ExpectError: regexp.MustCompile(`Attribute url must match HTTP URL regex`),
}}},
- {"download qcow2 file", []resource.TestStep{{
+ {"download qcow2 file to iso storage", []resource.TestStep{{
Config: te.RenderConfig(`
resource "proxmox_virtual_environment_download_file" "qcow2_image" {
content_type = "iso"
@@ -91,6 +91,21 @@ func TestAccResourceDownloadFile(t *testing.T) {
}),
),
}}},
+ {"download qcow2 file to import storage", []resource.TestStep{{
+ Config: te.RenderConfig(`
+ resource "proxmox_virtual_environment_download_file" "qcow2_image" {
+ content_type = "import"
+ node_name = "{{.NodeName}}"
+ datastore_id = "{{.DatastoreID}}"
+ file_name = "fake_qcow2_file.qcow2"
+ url = "{{.FakeFileQCOW2}}"
+ checksum = "688787d8ff144c502c7f5cffaafe2cc588d86079f9de88304c26b0cb99ce91c6"
+ checksum_algorithm = "sha256"
+ overwrite_unmanaged = true
+ }`),
+ // the details sais "Image is not in qcow2 format", but we can't assert that
+ ExpectError: regexp.MustCompile(`Error downloading file from url`),
+ }}},
{"download & update iso file", []resource.TestStep{
{
Config: te.RenderConfig(`
diff --git a/proxmox/version/capabilities.go b/proxmox/version/capabilities.go
new file mode 100644
index 00000000..5608f9ce
--- /dev/null
+++ b/proxmox/version/capabilities.go
@@ -0,0 +1,20 @@
+/*
+ * 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 version
+
+import "github.com/hashicorp/go-version"
+
+// MinimumProxmoxVersion is the minimum supported Proxmox version by the provider.
+//
+//nolint:gochecknoglobals
+var MinimumProxmoxVersion = ProxmoxVersion{*version.Must(version.NewVersion("8.0.0"))}
+
+// SupportImportContentType checks if the Proxmox version supports the `import` content type when uploading disk images.
+// See https://bugzilla.proxmox.com/show_bug.cgi?id=2424
+func (v *ProxmoxVersion) SupportImportContentType() bool {
+ return v.GreaterThanOrEqual(version.Must(version.NewVersion("8.4.0")))
+}
diff --git a/proxmox/version/version_types.go b/proxmox/version/version_types.go
index f4221e6d..022d5b93 100644
--- a/proxmox/version/version_types.go
+++ b/proxmox/version/version_types.go
@@ -6,6 +6,12 @@
package version
+import (
+ "fmt"
+
+ "github.com/hashicorp/go-version"
+)
+
// ResponseBody contains the body from a version response.
type ResponseBody struct {
Data *ResponseData `json:"data,omitempty"`
@@ -13,8 +19,24 @@ type ResponseBody struct {
// ResponseData contains the data from a version response.
type ResponseData struct {
- Console string `json:"console"`
- Release string `json:"release"`
- RepositoryID string `json:"repoid"`
- Version string `json:"version"`
+ Console string `json:"console"`
+ Release string `json:"release"`
+ RepositoryID string `json:"repoid"`
+ Version ProxmoxVersion `json:"version"`
+}
+
+type ProxmoxVersion struct {
+ version.Version
+}
+
+func (v *ProxmoxVersion) UnmarshalJSON(data []byte) error {
+ // Unmarshal the version string into a go-version Version object
+ ver, err := version.NewVersion(string(data))
+ if err != nil {
+ return fmt.Errorf("failed to parse version %q: %w", string(data), err)
+ }
+
+ v.Version = *ver
+
+ return nil
}
diff --git a/proxmoxtf/resource/file.go b/proxmoxtf/resource/file.go
index ed6d9f60..617482b8 100644
--- a/proxmoxtf/resource/file.go
+++ b/proxmoxtf/resource/file.go
@@ -28,7 +28,9 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+ "github.com/bpg/terraform-provider-proxmox/proxmox"
"github.com/bpg/terraform-provider-proxmox/proxmox/api"
+ "github.com/bpg/terraform-provider-proxmox/proxmox/version"
"github.com/bpg/terraform-provider-proxmox/proxmoxtf"
"github.com/bpg/terraform-provider-proxmox/proxmoxtf/resource/validators"
"github.com/bpg/terraform-provider-proxmox/utils"
@@ -325,9 +327,6 @@ func fileCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag
var diags diag.Diagnostics
- contentType, dg := fileGetContentType(d)
- diags = append(diags, dg...)
-
fileName, err := fileGetSourceFileName(d)
diags = append(diags, diag.FromErr(err)...)
@@ -345,6 +344,9 @@ func fileCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag
return diag.FromErr(err)
}
+ contentType, dg := fileGetContentType(ctx, d, capi)
+ diags = append(diags, dg...)
+
list, err := capi.Node(nodeName).Storage(datastoreID).ListDatastoreFiles(ctx)
if err != nil {
return diag.FromErr(err)
@@ -406,7 +408,7 @@ func fileCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag
"url": sourceFilePath,
})
- version, e := api.GetMinTLSVersion(sourceFileMinTLS)
+ minTLSVersion, e := api.GetMinTLSVersion(sourceFileMinTLS)
if e != nil {
return diag.FromErr(e)
}
@@ -414,7 +416,7 @@ func fileCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag
httpClient := http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
- MinVersion: version,
+ MinVersion: minTLSVersion,
InsecureSkipVerify: sourceFileInsecure,
},
},
@@ -553,7 +555,7 @@ func fileCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag
}
switch *contentType {
- case "iso", "vztmpl":
+ case "iso", "vztmpl", "import":
_, err = capi.Node(nodeName).Storage(datastoreID).APIUpload(
ctx, request, config.TempDir(),
)
@@ -600,7 +602,7 @@ func fileCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag
}
- volID, di := fileGetVolumeID(d)
+ volID, di := fileGetVolumeID(ctx, d, capi)
diags = append(diags, di...)
if diags.HasError() {
return diags
@@ -617,11 +619,20 @@ func fileCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag
return diags
}
-func fileGetContentType(d *schema.ResourceData) (*string, diag.Diagnostics) {
+func fileGetContentType(ctx context.Context, d *schema.ResourceData, c proxmox.Client) (*string, diag.Diagnostics) {
contentType := d.Get(mkResourceVirtualEnvironmentFileContentType).(string)
sourceFile := d.Get(mkResourceVirtualEnvironmentFileSourceFile).([]interface{})
sourceRaw := d.Get(mkResourceVirtualEnvironmentFileSourceRaw).([]interface{})
+ ver := version.MinimumProxmoxVersion
+ if versionResp, err := c.Version().Version(ctx); err == nil {
+ ver = versionResp.Version
+ } else {
+ tflog.Warn(ctx, fmt.Sprintf("failed to determine Proxmox VE version, assume %v", ver), map[string]interface{}{
+ "error": err,
+ })
+ }
+
sourceFilePath := ""
if len(sourceFile) > 0 {
@@ -638,11 +649,15 @@ func fileGetContentType(d *schema.ResourceData) (*string, diag.Diagnostics) {
mkResourceVirtualEnvironmentFileSourceRaw,
)
}
-
if contentType == "" {
if strings.HasSuffix(sourceFilePath, ".tar.gz") ||
strings.HasSuffix(sourceFilePath, ".tar.xz") {
contentType = "vztmpl"
+ } else if ver.SupportImportContentType() &&
+ (strings.HasSuffix(sourceFilePath, ".qcow2") ||
+ strings.HasSuffix(sourceFilePath, ".raw") ||
+ strings.HasSuffix(sourceFilePath, ".vmdk")) {
+ contentType = "import"
} else {
ext := strings.TrimLeft(strings.ToLower(filepath.Ext(sourceFilePath)), ".")
@@ -715,14 +730,14 @@ func fileGetSourceFileName(d *schema.ResourceData) (*string, error) {
return &sourceFileFileName, nil
}
-func fileGetVolumeID(d *schema.ResourceData) (fileVolumeID, diag.Diagnostics) {
+func fileGetVolumeID(ctx context.Context, d *schema.ResourceData, c proxmox.Client) (fileVolumeID, diag.Diagnostics) {
fileName, err := fileGetSourceFileName(d)
if err != nil {
return fileVolumeID{}, diag.FromErr(err)
}
datastoreID := d.Get(mkResourceVirtualEnvironmentFileDatastoreID).(string)
- contentType, diags := fileGetContentType(d)
+ contentType, diags := fileGetContentType(ctx, d, c)
return fileVolumeID{
datastoreID: datastoreID,
diff --git a/proxmoxtf/resource/file_test.go b/proxmoxtf/resource/file_test.go
index 8299de07..b73a38f4 100644
--- a/proxmoxtf/resource/file_test.go
+++ b/proxmoxtf/resource/file_test.go
@@ -118,11 +118,16 @@ func Test_fileParseVolumeID(t *testing.T) {
{"missing type", "local:/file.ido", fileVolumeID{}, true},
{"missing file", "local:iso", fileVolumeID{}, true},
{"missing file", "local:iso/", fileVolumeID{}, true},
- {"valid", "local:iso/file.iso", fileVolumeID{
+ {"valid iso", "local:iso/file.iso", fileVolumeID{
datastoreID: "local",
contentType: "iso",
fileName: "file.iso",
}, false},
+ {"valid import", "local:import/file.qcow2", fileVolumeID{
+ datastoreID: "local",
+ contentType: "import",
+ fileName: "file.qcow2",
+ }, false},
}
for _, tt := range tests {
diff --git a/proxmoxtf/resource/validators/file.go b/proxmoxtf/resource/validators/file.go
index 8cd2e57e..0c8e5908 100644
--- a/proxmoxtf/resource/validators/file.go
+++ b/proxmoxtf/resource/validators/file.go
@@ -24,6 +24,7 @@ func ContentType() schema.SchemaValidateDiagFunc {
"iso",
"snippets",
"vztmpl",
+ "import",
}, false))
}
diff --git a/templates/guides/setup-proxmox-for-tests.md.tmpl b/templates/guides/setup-proxmox-for-tests.md.tmpl
index 2d2f9f72..71ea146f 100644
--- a/templates/guides/setup-proxmox-for-tests.md.tmpl
+++ b/templates/guides/setup-proxmox-for-tests.md.tmpl
@@ -92,4 +92,4 @@ Goal is to have a proxmox node in VM using for a job
10. Now you can run `make example`.
-11. If you see error with proxmox_virtual_environment_file: the datastore "local" does not support content type "snippets"; supported content types are: `[backup, iso, vztmpl]`, you need to enable them, see .
+11. If you see error with proxmox_virtual_environment_file: the datastore "local" does not support content type "snippets"; supported content types are: `[backup, iso, vztmpl, import]`, you need to enable them, see .