mirror of
https://github.com/bpg/terraform-provider-proxmox.git
synced 2025-06-29 18:21:10 +00:00
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>
This commit is contained in:
parent
a76cc6256d
commit
2d9e0b585e
@ -71,7 +71,7 @@ The following assumptions are made about the test environment:
|
|||||||
|
|
||||||
- It has one node named `pve`
|
- It has one node named `pve`
|
||||||
- The node has local storages named `local` and `local-lvm`
|
- 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)
|
- Default Linux Bridge "vmbr0" is VLAN aware (datacenter -> pve -> network -> edit & apply)
|
||||||
|
|
||||||
Create `example/terraform.tfvars` with the following variables:
|
Create `example/terraform.tfvars` with the following variables:
|
||||||
|
@ -92,4 +92,4 @@ Goal is to have a proxmox node in VM using <https://virt-manager.org/> for a job
|
|||||||
|
|
||||||
10. Now you can run `make example`.
|
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 <https://registry.terraform.io/providers/bpg/proxmox/latest/docs/resources/virtual_environment_file#snippets>.
|
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 <https://registry.terraform.io/providers/bpg/proxmox/latest/docs/resources/virtual_environment_file#snippets>.
|
||||||
|
@ -4,12 +4,12 @@ title: proxmox_virtual_environment_download_file
|
|||||||
parent: Resources
|
parent: Resources
|
||||||
subcategory: Virtual Environment
|
subcategory: Virtual Environment
|
||||||
description: |-
|
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
|
# 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.<br><br>
|
~> Besides the `Datastore.AllocateTemplate` privilege, this resource requires both the `Sys.Audit` and `Sys.Modify` privileges.<br><br>
|
||||||
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.
|
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"
|
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" {
|
resource "proxmox_virtual_environment_download_file" "latest_debian_12_bookworm_qcow2_img" {
|
||||||
content_type = "iso"
|
content_type = "iso"
|
||||||
datastore_id = "local"
|
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"
|
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" {
|
resource "proxmox_virtual_environment_download_file" "latest_ubuntu_22_jammy_qcow2_img" {
|
||||||
content_type = "iso"
|
content_type = "iso"
|
||||||
datastore_id = "local"
|
datastore_id = "local"
|
||||||
@ -73,7 +91,7 @@ resource "proxmox_virtual_environment_download_file" "latest_ubuntu_22_jammy_lxc
|
|||||||
|
|
||||||
### Required
|
### 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.
|
- `datastore_id` (String) The identifier for the target datastore.
|
||||||
- `node_name` (String) The node name.
|
- `node_name` (String) The node name.
|
||||||
- `url` (String) The URL to download the file from. Must match regex: `https?://.*`.
|
- `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` (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`.
|
- `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`.
|
- `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` (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.
|
- `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).
|
- `upload_timeout` (Number) The file download timeout seconds. Default is 600 (10min).
|
||||||
|
@ -7,7 +7,7 @@ subcategory: Virtual Environment
|
|||||||
|
|
||||||
# Resource: proxmox_virtual_environment_file
|
# 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
|
## 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.
|
-> 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
|
```hcl
|
||||||
resource "proxmox_virtual_environment_file" "ubuntu_container_template" {
|
resource "proxmox_virtual_environment_file" "ubuntu_container_template" {
|
||||||
content_type = "iso"
|
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
|
||||||
|
|
||||||
-> 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.
|
-> 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`)
|
- `backup` (allowed extensions: `.vzdump`, `.tar.gz`, `.tar.xz`, `tar.zst`)
|
||||||
- `iso` (allowed extensions: `.iso`, `.img`)
|
- `iso` (allowed extensions: `.iso`, `.img`)
|
||||||
- `snippets` (allowed extensions: any)
|
- `snippets` (allowed extensions: any)
|
||||||
|
- `import` (allowed extensions: `.raw`, `.qcow2`, `.vmdk`)
|
||||||
- `vztmpl` (allowed extensions: `.tar.gz`, `.tar.xz`, `tar.zst`)
|
- `vztmpl` (allowed extensions: `.tar.gz`, `.tar.xz`, `tar.zst`)
|
||||||
- `datastore_id` - (Required) The datastore id.
|
- `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.
|
- `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.
|
||||||
|
@ -20,3 +20,13 @@ resource "proxmox_virtual_environment_download_file" "latest_debian_12_bookworm_
|
|||||||
overwrite = true
|
overwrite = true
|
||||||
overwrite_unmanaged = 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
|
||||||
|
}
|
||||||
|
@ -8,6 +8,16 @@ resource "proxmox_virtual_environment_download_file" "release_20231228_debian_12
|
|||||||
checksum_algorithm = "sha512"
|
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" {
|
resource "proxmox_virtual_environment_download_file" "latest_debian_12_bookworm_qcow2_img" {
|
||||||
content_type = "iso"
|
content_type = "iso"
|
||||||
datastore_id = "local"
|
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"
|
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" {
|
resource "proxmox_virtual_environment_download_file" "latest_ubuntu_22_jammy_qcow2_img" {
|
||||||
content_type = "iso"
|
content_type = "iso"
|
||||||
datastore_id = "local"
|
datastore_id = "local"
|
||||||
|
@ -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"
|
||||||
|
}
|
||||||
|
}
|
@ -115,7 +115,7 @@ func (d *versionDatasource) Read(ctx context.Context, _ datasource.ReadRequest,
|
|||||||
|
|
||||||
state.Release = types.StringValue(version.Release)
|
state.Release = types.StringValue(version.Release)
|
||||||
state.RepositoryID = types.StringValue(version.RepositoryID)
|
state.RepositoryID = types.StringValue(version.RepositoryID)
|
||||||
state.Version = types.StringValue(version.Version)
|
state.Version = types.StringValue(version.Version.String())
|
||||||
|
|
||||||
state.ID = types.StringValue("version")
|
state.ID = types.StringValue("version")
|
||||||
|
|
||||||
|
@ -153,15 +153,16 @@ func (r *downloadFileResource) Schema(
|
|||||||
Description: "Manages files upload using PVE download-url API. ",
|
Description: "Manages files upload using PVE download-url API. ",
|
||||||
MarkdownDescription: "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 " +
|
"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{
|
Attributes: map[string]schema.Attribute{
|
||||||
"id": attribute.ResourceID(),
|
"id": attribute.ResourceID(),
|
||||||
"content_type": schema.StringAttribute{
|
"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,
|
Required: true,
|
||||||
Validators: []validator.String{stringvalidator.OneOf([]string{
|
Validators: []validator.String{stringvalidator.OneOf([]string{
|
||||||
"iso",
|
"iso",
|
||||||
"vztmpl",
|
"vztmpl",
|
||||||
|
"import",
|
||||||
}...)},
|
}...)},
|
||||||
PlanModifiers: []planmodifier.String{
|
PlanModifiers: []planmodifier.String{
|
||||||
stringplanmodifier.RequiresReplace(),
|
stringplanmodifier.RequiresReplace(),
|
||||||
@ -170,7 +171,8 @@ func (r *downloadFileResource) Schema(
|
|||||||
"file_name": schema.StringAttribute{
|
"file_name": schema.StringAttribute{
|
||||||
Description: "The file name. If not provided, it is calculated " +
|
Description: "The file name. If not provided, it is calculated " +
|
||||||
"using `url`. PVE will raise 'wrong file extension' error for some popular " +
|
"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,
|
Computed: true,
|
||||||
Required: false,
|
Required: false,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
|
@ -60,7 +60,7 @@ func TestAccResourceDownloadFile(t *testing.T) {
|
|||||||
}`),
|
}`),
|
||||||
ExpectError: regexp.MustCompile(`Attribute url must match HTTP URL regex`),
|
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(`
|
Config: te.RenderConfig(`
|
||||||
resource "proxmox_virtual_environment_download_file" "qcow2_image" {
|
resource "proxmox_virtual_environment_download_file" "qcow2_image" {
|
||||||
content_type = "iso"
|
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{
|
{"download & update iso file", []resource.TestStep{
|
||||||
{
|
{
|
||||||
Config: te.RenderConfig(`
|
Config: te.RenderConfig(`
|
||||||
|
20
proxmox/version/capabilities.go
Normal file
20
proxmox/version/capabilities.go
Normal file
@ -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")))
|
||||||
|
}
|
@ -6,6 +6,12 @@
|
|||||||
|
|
||||||
package version
|
package version
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/hashicorp/go-version"
|
||||||
|
)
|
||||||
|
|
||||||
// ResponseBody contains the body from a version response.
|
// ResponseBody contains the body from a version response.
|
||||||
type ResponseBody struct {
|
type ResponseBody struct {
|
||||||
Data *ResponseData `json:"data,omitempty"`
|
Data *ResponseData `json:"data,omitempty"`
|
||||||
@ -13,8 +19,24 @@ type ResponseBody struct {
|
|||||||
|
|
||||||
// ResponseData contains the data from a version response.
|
// ResponseData contains the data from a version response.
|
||||||
type ResponseData struct {
|
type ResponseData struct {
|
||||||
Console string `json:"console"`
|
Console string `json:"console"`
|
||||||
Release string `json:"release"`
|
Release string `json:"release"`
|
||||||
RepositoryID string `json:"repoid"`
|
RepositoryID string `json:"repoid"`
|
||||||
Version string `json:"version"`
|
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
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,9 @@ import (
|
|||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
"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/api"
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/proxmox/version"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmoxtf"
|
"github.com/bpg/terraform-provider-proxmox/proxmoxtf"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmoxtf/resource/validators"
|
"github.com/bpg/terraform-provider-proxmox/proxmoxtf/resource/validators"
|
||||||
"github.com/bpg/terraform-provider-proxmox/utils"
|
"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
|
var diags diag.Diagnostics
|
||||||
|
|
||||||
contentType, dg := fileGetContentType(d)
|
|
||||||
diags = append(diags, dg...)
|
|
||||||
|
|
||||||
fileName, err := fileGetSourceFileName(d)
|
fileName, err := fileGetSourceFileName(d)
|
||||||
diags = append(diags, diag.FromErr(err)...)
|
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)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
contentType, dg := fileGetContentType(ctx, d, capi)
|
||||||
|
diags = append(diags, dg...)
|
||||||
|
|
||||||
list, err := capi.Node(nodeName).Storage(datastoreID).ListDatastoreFiles(ctx)
|
list, err := capi.Node(nodeName).Storage(datastoreID).ListDatastoreFiles(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
@ -406,7 +408,7 @@ func fileCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag
|
|||||||
"url": sourceFilePath,
|
"url": sourceFilePath,
|
||||||
})
|
})
|
||||||
|
|
||||||
version, e := api.GetMinTLSVersion(sourceFileMinTLS)
|
minTLSVersion, e := api.GetMinTLSVersion(sourceFileMinTLS)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
return diag.FromErr(e)
|
return diag.FromErr(e)
|
||||||
}
|
}
|
||||||
@ -414,7 +416,7 @@ func fileCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag
|
|||||||
httpClient := http.Client{
|
httpClient := http.Client{
|
||||||
Transport: &http.Transport{
|
Transport: &http.Transport{
|
||||||
TLSClientConfig: &tls.Config{
|
TLSClientConfig: &tls.Config{
|
||||||
MinVersion: version,
|
MinVersion: minTLSVersion,
|
||||||
InsecureSkipVerify: sourceFileInsecure,
|
InsecureSkipVerify: sourceFileInsecure,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -553,7 +555,7 @@ func fileCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch *contentType {
|
switch *contentType {
|
||||||
case "iso", "vztmpl":
|
case "iso", "vztmpl", "import":
|
||||||
_, err = capi.Node(nodeName).Storage(datastoreID).APIUpload(
|
_, err = capi.Node(nodeName).Storage(datastoreID).APIUpload(
|
||||||
ctx, request, config.TempDir(),
|
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...)
|
diags = append(diags, di...)
|
||||||
if diags.HasError() {
|
if diags.HasError() {
|
||||||
return diags
|
return diags
|
||||||
@ -617,11 +619,20 @@ func fileCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag
|
|||||||
return diags
|
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)
|
contentType := d.Get(mkResourceVirtualEnvironmentFileContentType).(string)
|
||||||
sourceFile := d.Get(mkResourceVirtualEnvironmentFileSourceFile).([]interface{})
|
sourceFile := d.Get(mkResourceVirtualEnvironmentFileSourceFile).([]interface{})
|
||||||
sourceRaw := d.Get(mkResourceVirtualEnvironmentFileSourceRaw).([]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 := ""
|
sourceFilePath := ""
|
||||||
|
|
||||||
if len(sourceFile) > 0 {
|
if len(sourceFile) > 0 {
|
||||||
@ -638,11 +649,15 @@ func fileGetContentType(d *schema.ResourceData) (*string, diag.Diagnostics) {
|
|||||||
mkResourceVirtualEnvironmentFileSourceRaw,
|
mkResourceVirtualEnvironmentFileSourceRaw,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if contentType == "" {
|
if contentType == "" {
|
||||||
if strings.HasSuffix(sourceFilePath, ".tar.gz") ||
|
if strings.HasSuffix(sourceFilePath, ".tar.gz") ||
|
||||||
strings.HasSuffix(sourceFilePath, ".tar.xz") {
|
strings.HasSuffix(sourceFilePath, ".tar.xz") {
|
||||||
contentType = "vztmpl"
|
contentType = "vztmpl"
|
||||||
|
} else if ver.SupportImportContentType() &&
|
||||||
|
(strings.HasSuffix(sourceFilePath, ".qcow2") ||
|
||||||
|
strings.HasSuffix(sourceFilePath, ".raw") ||
|
||||||
|
strings.HasSuffix(sourceFilePath, ".vmdk")) {
|
||||||
|
contentType = "import"
|
||||||
} else {
|
} else {
|
||||||
ext := strings.TrimLeft(strings.ToLower(filepath.Ext(sourceFilePath)), ".")
|
ext := strings.TrimLeft(strings.ToLower(filepath.Ext(sourceFilePath)), ".")
|
||||||
|
|
||||||
@ -715,14 +730,14 @@ func fileGetSourceFileName(d *schema.ResourceData) (*string, error) {
|
|||||||
return &sourceFileFileName, nil
|
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)
|
fileName, err := fileGetSourceFileName(d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fileVolumeID{}, diag.FromErr(err)
|
return fileVolumeID{}, diag.FromErr(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
datastoreID := d.Get(mkResourceVirtualEnvironmentFileDatastoreID).(string)
|
datastoreID := d.Get(mkResourceVirtualEnvironmentFileDatastoreID).(string)
|
||||||
contentType, diags := fileGetContentType(d)
|
contentType, diags := fileGetContentType(ctx, d, c)
|
||||||
|
|
||||||
return fileVolumeID{
|
return fileVolumeID{
|
||||||
datastoreID: datastoreID,
|
datastoreID: datastoreID,
|
||||||
|
@ -118,11 +118,16 @@ func Test_fileParseVolumeID(t *testing.T) {
|
|||||||
{"missing type", "local:/file.ido", fileVolumeID{}, true},
|
{"missing type", "local:/file.ido", fileVolumeID{}, true},
|
||||||
{"missing file", "local:iso", fileVolumeID{}, true},
|
{"missing file", "local:iso", 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",
|
datastoreID: "local",
|
||||||
contentType: "iso",
|
contentType: "iso",
|
||||||
fileName: "file.iso",
|
fileName: "file.iso",
|
||||||
}, false},
|
}, false},
|
||||||
|
{"valid import", "local:import/file.qcow2", fileVolumeID{
|
||||||
|
datastoreID: "local",
|
||||||
|
contentType: "import",
|
||||||
|
fileName: "file.qcow2",
|
||||||
|
}, false},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
@ -24,6 +24,7 @@ func ContentType() schema.SchemaValidateDiagFunc {
|
|||||||
"iso",
|
"iso",
|
||||||
"snippets",
|
"snippets",
|
||||||
"vztmpl",
|
"vztmpl",
|
||||||
|
"import",
|
||||||
}, false))
|
}, false))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,4 +92,4 @@ Goal is to have a proxmox node in VM using <https://virt-manager.org/> for a job
|
|||||||
|
|
||||||
10. Now you can run `make example`.
|
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 <https://registry.terraform.io/providers/bpg/proxmox/latest/docs/resources/virtual_environment_file#snippets>.
|
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 <https://registry.terraform.io/providers/bpg/proxmox/latest/docs/resources/virtual_environment_file#snippets>.
|
||||||
|
Loading…
Reference in New Issue
Block a user