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/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 163abb4d..0de2b4c5 100644 --- a/proxmoxtf/resource/file.go +++ b/proxmoxtf/resource/file.go @@ -20,7 +20,6 @@ import ( "path/filepath" "slices" "sort" - "strconv" "strings" "time" @@ -31,6 +30,7 @@ import ( "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" @@ -408,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) } @@ -416,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, }, }, @@ -624,28 +624,13 @@ func fileGetContentType(ctx context.Context, d *schema.ResourceData, c proxmox.C sourceFile := d.Get(mkResourceVirtualEnvironmentFileSourceFile).([]interface{}) sourceRaw := d.Get(mkResourceVirtualEnvironmentFileSourceRaw).([]interface{}) - releaseMajor := 0 - releaseMinor := 0 - - version, err := c.Version().Version(ctx) - if err != nil { - tflog.Warn(ctx, "failed to determine Proxmox VE version", map[string]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, }) - } else { - release := strings.Split(version.Release, ".") - releaseMajor, err = strconv.Atoi(release[0]) - if err != nil { - tflog.Warn(ctx, "failed to parse Proxmox VE version Major", map[string]interface{}{ - "error": err, - }) - } - releaseMinor, err = strconv.Atoi(release[1]) - if err != nil { - tflog.Warn(ctx, "failed to parse Proxmox VE version Minor", map[string]interface{}{ - "error": err, - }) - } } sourceFilePath := "" @@ -668,10 +653,10 @@ func fileGetContentType(ctx context.Context, d *schema.ResourceData, c proxmox.C if strings.HasSuffix(sourceFilePath, ".tar.gz") || strings.HasSuffix(sourceFilePath, ".tar.xz") { contentType = "vztmpl" - // For Proxmox VE 8.4 and later, we can import VM images to the "import" content type. - } else if releaseMajor >= 8 && releaseMinor > 4 && (strings.HasSuffix(sourceFilePath, ".qcow2") || - strings.HasSuffix(sourceFilePath, ".raw") || - strings.HasSuffix(sourceFilePath, ".vmdk")) { + } 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)), ".")