mirror of
https://github.com/bpg/terraform-provider-proxmox.git
synced 2025-06-30 02:31:10 +00:00
feat: add support for 'import' content type in Proxmox file resources
Signed-off-by: Marco Attia <54147992+Vaneixus@users.noreply.github.com>
This commit is contained in:
parent
b6bcfe75aa
commit
d88f0efd75
@ -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`.
|
||||
|
||||
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>.
|
||||
|
@ -126,6 +126,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.
|
||||
|
@ -205,23 +205,22 @@ func (r *downloadFileResource) Schema(
|
||||
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(),
|
||||
},
|
||||
},
|
||||
"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.",
|
||||
Computed: true,
|
||||
Required: false,
|
||||
Optional: true,
|
||||
Description: "The file name. If not provided, it is calculated using `url`.",
|
||||
Computed: true,
|
||||
Required: false,
|
||||
Optional: true,
|
||||
PlanModifiers: []planmodifier.String{
|
||||
stringplanmodifier.RequiresReplace(),
|
||||
stringplanmodifier.UseStateForUnknown(),
|
||||
|
@ -20,6 +20,7 @@ import (
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -325,9 +326,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 +343,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)
|
||||
@ -553,7 +554,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 +601,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 +618,33 @@ 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 proxmoxtf.ProviderConfiguration) (*string, diag.Diagnostics) {
|
||||
contentType := d.Get(mkResourceVirtualEnvironmentFileContentType).(string)
|
||||
sourceFile := d.Get(mkResourceVirtualEnvironmentFileSourceFile).([]interface{})
|
||||
sourceRaw := d.Get(mkResourceVirtualEnvironmentFileSourceRaw).([]interface{})
|
||||
|
||||
release := 0.0
|
||||
pc, err := c.GetClient()
|
||||
if err != nil {
|
||||
tflog.Warn(ctx, "failed to determine Proxmox Client API version", map[string]interface{}{
|
||||
"error": err,
|
||||
})
|
||||
} else {
|
||||
version, err := pc.Version().Version(context.Background())
|
||||
if err != nil {
|
||||
tflog.Warn(ctx, "failed to determine Proxmox VE version", map[string]interface{}{
|
||||
"error": err,
|
||||
})
|
||||
} else {
|
||||
release, err = strconv.ParseFloat(version.Release, 32)
|
||||
if err != nil {
|
||||
tflog.Warn(ctx, "failed to parse Proxmox VE version", map[string]interface{}{
|
||||
"error": err,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sourceFilePath := ""
|
||||
|
||||
if len(sourceFile) > 0 {
|
||||
@ -638,22 +661,26 @@ 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 release > 8.4 && (strings.HasSuffix(sourceFilePath, ".qcow2") ||
|
||||
strings.HasSuffix(sourceFilePath, ".raw") ||
|
||||
strings.HasSuffix(sourceFilePath, ".vmdk")) {
|
||||
contentType = "import"
|
||||
} else {
|
||||
ext := strings.TrimLeft(strings.ToLower(filepath.Ext(sourceFilePath)), ".")
|
||||
|
||||
switch ext {
|
||||
case "img", "iso":
|
||||
case "iso":
|
||||
contentType = "iso"
|
||||
case "yaml", "yml":
|
||||
contentType = "snippets"
|
||||
}
|
||||
}
|
||||
|
||||
// We cannot determine, for example, the content type of an .img file, so we require the user to specify it.
|
||||
if contentType == "" {
|
||||
return nil, diag.Errorf(
|
||||
"cannot determine the content type of source \"%s\" - Please manually define the \"%s\" argument",
|
||||
@ -715,14 +742,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 proxmoxtf.ProviderConfiguration) (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,
|
||||
|
@ -24,6 +24,7 @@ func ContentType() schema.SchemaValidateDiagFunc {
|
||||
"iso",
|
||||
"snippets",
|
||||
"vztmpl",
|
||||
"import",
|
||||
}, false))
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user