Skip to content

Commit 4a177f7

Browse files
committed
edit: rename package from template to virtualmachine
Renamed package and corrected documentation accordingly.
1 parent 9adc728 commit 4a177f7

File tree

14 files changed

+212
-158
lines changed

14 files changed

+212
-158
lines changed

.web-docs/README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ Packer is able to target both ISO and existing Cloud-Init images.
3737

3838
#### Data Sources
3939

40-
- [data source](/packer/integrations/hashicorp/proxmox/latest/components/datasource/template) - The proxmox template
41-
datasource is able to get info about existing guests from Proxmox cluster and return VM ID of a single guest that
42-
matches all specified filters. This ID can later be used in the 'clone' builder to select template.
40+
- [virtualmachine](/packer/integrations/hashicorp/proxmox/latest/components/datasource/virtualmachine) - The proxmox
41+
virtual machine datasource retrieves information about existing virtual machines
42+
from Proxmox cluster and returns VM ID of one virtual machine that matches all
43+
specified filters. This ID can be used in the clone builder to select a template.

.web-docs/components/data-source/template/README.md renamed to .web-docs/components/data-source/virtualmachine/README.md

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,26 @@
1-
Type: `proxmox-template`
2-
Artifact BuilderId: `proxmox.template`
1+
Type: `proxmox-virtualmachine`
2+
Artifact BuilderId: `proxmox.virtualmachine`
33

4-
The `proxmox-template` datasource is able to get info about existing guests
5-
from [Proxmox](https://www.proxmox.com/en/proxmox-ve) cluster and return VM
6-
ID of a single guest that matches all specified filters. This ID can later
7-
be used in the `proxmox-clone` builder to select template.
4+
The `proxmox-virtualmachine` datasource retrieves information about existing virtual machines
5+
from [Proxmox](https://www.proxmox.com/en/proxmox-ve) cluster and returns VM ID of one virtual machine
6+
that matches all specified filters. This ID can be used in the `proxmox-clone` builder to select a template.
87

98
## Configuration Reference
109

11-
<!-- Code generated from the comments of the Config struct in datasource/proxmox/data.go; DO NOT EDIT MANUALLY -->
10+
<!-- Code generated from the comments of the Config struct in datasource/virtualmachine/data.go; DO NOT EDIT MANUALLY -->
1211

1312
Datasource has a bunch of filters which you can use, for example, to find the latest available
1413
template in the cluster that matches defined filters.
1514

1615
You can combine any number of filters but all of them will be conjuncted with AND.
1716
When datasource cannot return only one (zero or >1) guest identifiers it will return error.
1817

19-
<!-- End of code generated from the comments of the Config struct in datasource/proxmox/data.go; -->
18+
<!-- End of code generated from the comments of the Config struct in datasource/virtualmachine/data.go; -->
2019

2120

2221
## Optional:
2322

24-
<!-- Code generated from the comments of the Config struct in datasource/proxmox/data.go; DO NOT EDIT MANUALLY -->
23+
<!-- Code generated from the comments of the Config struct in datasource/virtualmachine/data.go; DO NOT EDIT MANUALLY -->
2524

2625
- `proxmox_url` (string) - URL to the Proxmox API, including the full path,
2726
so `https://<server>:<port>/api2/json` for example.
@@ -50,60 +49,70 @@ When datasource cannot return only one (zero or >1) guest identifiers it will re
5049
- `task_timeout` (duration string | ex: "1h5m2s") - `task_timeout` (duration string | ex: "10m") - The timeout for
5150
Promox API operations, e.g. clones. Defaults to 1 minute.
5251

53-
- `name` (string) - Filter that returns `vm_id` for guest which name exactly matches this value.
52+
- `name` (string) - Filter that returns `vm_id` for virtual machine which name exactly matches this value.
5453
Options `name` and `name_regex` are mutually exclusive.
5554

56-
- `name_regex` (string) - Filter that returns `vm_id` for guest which name matches the regular expression.
55+
- `name_regex` (string) - Filter that returns `vm_id` for virtual machine which name matches the regular expression.
5756
Expression must use [Go Regex Syntax](https://pkg.go.dev/regexp/syntax).
5857
Options `name` and `name_regex` are mutually exclusive.
5958

60-
- `template` (bool) - Filter that returns guest `vm_id` only when guest is template.
59+
- `template` (bool) - Filter that returns virtual machine `vm_id` only when virtual machine is template.
6160

62-
- `node` (string) - Filter that returns `vm_id` only when guest is located on the specified PVE node.
61+
- `node` (string) - Filter that returns `vm_id` only when virtual machine is located on the specified PVE node.
6362

64-
- `vm_tags` (string) - Filter that returns `vm_id` for guest which has all these tags. When you need to
63+
- `vm_tags` (string) - Filter that returns `vm_id` for virtual machine which has all these tags. When you need to
6564
specify more than one tag, use semicolon as separator (`"tag1;tag2"`).
66-
Every specified tag must exist in guest.
65+
Every specified tag must exist in virtual machine.
6766

68-
- `latest` (bool) - This filter determines how to handle multiple guests that were matched with all
69-
previous filters. Guest creation time is being used to find latest.
70-
By default, multiple matching guests results in an error.
67+
- `latest` (bool) - This filter determines how to handle multiple virtual machines that were matched with all
68+
previous filters. Virtual machine creation time is being used to find latest.
69+
By default, multiple matching virtual machines results in an error.
7170

72-
<!-- End of code generated from the comments of the Config struct in datasource/proxmox/data.go; -->
71+
<!-- End of code generated from the comments of the Config struct in datasource/virtualmachine/data.go; -->
7372

7473

7574
## Output:
7675

77-
<!-- Code generated from the comments of the DatasourceOutput struct in datasource/proxmox/data.go; DO NOT EDIT MANUALLY -->
76+
<!-- Code generated from the comments of the DatasourceOutput struct in datasource/virtualmachine/data.go; DO NOT EDIT MANUALLY -->
7877

79-
- `vm_id` (uint) - Identifier of the found guest.
78+
- `vm_id` (uint) - Identifier of the found virtual machine.
8079

81-
- `vm_name` (string) - Name of the found guest.
80+
- `vm_name` (string) - Name of the found virtual machine.
8281

83-
- `vm_tags` (string) - Tags of the found guest separated with semicolon.
82+
- `vm_tags` (string) - Tags of the found virtual machine separated with semicolon.
8483

85-
<!-- End of code generated from the comments of the DatasourceOutput struct in datasource/proxmox/data.go; -->
84+
<!-- End of code generated from the comments of the DatasourceOutput struct in datasource/virtualmachine/data.go; -->
8685

8786

8887
## Example Usage
8988

9089
This is a very basic example which connects to local PVE host, finds the latest
9190
guest which name matches the regex `image-.*` and which type is `template`. The
92-
ID is then printed to console as output variable.
91+
ID of the virtual machine is printed to console as output variable.
9392

9493
```hcl
95-
data "proxmox-template" "default" {
96-
proxmox_url = "https://localhost:8006/api2/json"
94+
variable "password" {
95+
type = string
96+
default = "supersecret"
97+
}
98+
99+
variable "username" {
100+
type = string
101+
default = "apiuser@pve"
102+
}
103+
104+
data "proxmox-virtualmachine" "default" {
105+
proxmox_url = "https://my-proxmox.my-domain:8006/api2/json"
97106
insecure_skip_tls_verify = true
98-
username = "root@pam"
99-
password = "password"
107+
username = "${var.username}"
108+
password = "${var.password}"
100109
name_regex = "image-.*"
101110
template = true
102111
latest = true
103112
}
104113
105114
locals {
106-
vm_id = data.proxmox-template.default.vm_id
115+
vm_id = data.proxmox-virtualmachine.default.vm_id
107116
}
108117
109118
source "null" "basic-example" {

.web-docs/metadata.hcl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ integration {
1919
}
2020
component {
2121
type = "data-source"
22-
name = "Proxmox Template"
23-
slug = "template"
22+
name = "Proxmox Virtual Machine"
23+
slug = "virtualmachine"
2424
}
2525
}

datasource/proxmox/data.go renamed to datasource/virtualmachine/data.go

Lines changed: 51 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//go:generate packer-sdc struct-markdown
55
//go:generate packer-sdc mapstructure-to-hcl2 -type Config,DatasourceOutput
66

7-
package proxmoxtemplate
7+
package virtualmachine
88

99
import (
1010
"crypto/tls"
@@ -63,24 +63,24 @@ type Config struct {
6363
// `task_timeout` (duration string | ex: "10m") - The timeout for
6464
// Promox API operations, e.g. clones. Defaults to 1 minute.
6565
TaskTimeout time.Duration `mapstructure:"task_timeout"`
66-
// Filter that returns `vm_id` for guest which name exactly matches this value.
66+
// Filter that returns `vm_id` for virtual machine which name exactly matches this value.
6767
// Options `name` and `name_regex` are mutually exclusive.
6868
Name string `mapstructure:"name"`
69-
// Filter that returns `vm_id` for guest which name matches the regular expression.
69+
// Filter that returns `vm_id` for virtual machine which name matches the regular expression.
7070
// Expression must use [Go Regex Syntax](https://pkg.go.dev/regexp/syntax).
7171
// Options `name` and `name_regex` are mutually exclusive.
7272
NameRegex string `mapstructure:"name_regex"`
73-
// Filter that returns guest `vm_id` only when guest is template.
73+
// Filter that returns virtual machine `vm_id` only when virtual machine is template.
7474
Template bool `mapstructure:"template"`
75-
// Filter that returns `vm_id` only when guest is located on the specified PVE node.
75+
// Filter that returns `vm_id` only when virtual machine is located on the specified PVE node.
7676
Node string `mapstructure:"node"`
77-
// Filter that returns `vm_id` for guest which has all these tags. When you need to
77+
// Filter that returns `vm_id` for virtual machine which has all these tags. When you need to
7878
// specify more than one tag, use semicolon as separator (`"tag1;tag2"`).
79-
// Every specified tag must exist in guest.
79+
// Every specified tag must exist in virtual machine.
8080
VmTags string `mapstructure:"vm_tags"`
81-
// This filter determines how to handle multiple guests that were matched with all
82-
// previous filters. Guest creation time is being used to find latest.
83-
// By default, multiple matching guests results in an error.
81+
// This filter determines how to handle multiple virtual machines that were matched with all
82+
// previous filters. Virtual machine creation time is being used to find latest.
83+
// By default, multiple matching virtual machines results in an error.
8484
Latest bool `mapstructure:"latest"`
8585
}
8686

@@ -89,11 +89,11 @@ type Datasource struct {
8989
}
9090

9191
type DatasourceOutput struct {
92-
// Identifier of the found guest.
92+
// Identifier of the found virtual machine.
9393
VmId uint `mapstructure:"vm_id"`
94-
// Name of the found guest.
94+
// Name of the found virtual machine.
9595
VmName string `mapstructure:"vm_name"`
96-
// Tags of the found guest separated with semicolon.
96+
// Tags of the found virtual machine separated with semicolon.
9797
VmTags string `mapstructure:"vm_tags"`
9898
}
9999

@@ -180,7 +180,7 @@ func (d *Datasource) Execute() (cty.Value, error) {
180180

181181
filteredVms := filterGuests(d.config, vmList)
182182
if len(filteredVms) == 0 {
183-
return cty.NullVal(cty.EmptyObject), errors.New("not a single vm matches the configured filters")
183+
return cty.NullVal(cty.EmptyObject), errors.New("no virtual machine matches the filters")
184184
}
185185

186186
if d.config.Latest {
@@ -195,11 +195,11 @@ func (d *Datasource) Execute() (cty.Value, error) {
195195
}
196196

197197
vmId = latestConfig["vmid"].(uint)
198-
vmName = latestConfig["name"].(string)
199-
vmTags = latestConfig["tags"].(string)
198+
vmName = configValueOrEmpty(&latestConfig, "name")
199+
vmTags = configValueOrEmpty(&latestConfig, "tags")
200200
} else {
201201
if len(filteredVms) > 1 {
202-
return cty.NullVal(cty.EmptyObject), errors.New("more than one guest passed filters, cannot return vm_id")
202+
return cty.NullVal(cty.EmptyObject), errors.New("more than one virtual machine matched the filters")
203203
}
204204
vmId = filteredVms[0].Id
205205
vmName = filteredVms[0].Name
@@ -230,13 +230,13 @@ func findLatestConfig(configs []vmConfig) (vmConfig, error) {
230230
result = configs[i]
231231
}
232232
} else {
233-
return nil, errors.New("no meta field in the guest config")
233+
return nil, errors.New("no meta field in the virtual machine config")
234234
}
235235
}
236236
return result, nil
237237
}
238238

239-
// Get configs from PVE in 'map[string]interface{}' format for all VMs in the list.
239+
// getVmConfigs retrieves configs from PVE in 'map[string]interface{}' format for all VMs in the list.
240240
// Also add value of VM ID to every config (useful for further steps).
241241
func getVmConfigs(client *proxmox.Client, vmList []proxmox.GuestResource) ([]vmConfig, error) {
242242
var result []vmConfig
@@ -253,7 +253,7 @@ func getVmConfigs(client *proxmox.Client, vmList []proxmox.GuestResource) ([]vmC
253253
return result, nil
254254
}
255255

256-
// filterGuests removes guests from the `guests` list that do not match some filters in the datasource config.
256+
// filterGuests removes virtual machines from the `guests` list that do not match some filters in the datasource config.
257257
func filterGuests(config Config, guests []proxmox.GuestResource) []proxmox.GuestResource {
258258
filterFuncs := make([]func(proxmox.GuestResource) bool, 0)
259259

@@ -292,6 +292,9 @@ func filterGuests(config Config, guests []proxmox.GuestResource) []proxmox.Guest
292292
result := make([]proxmox.GuestResource, 0)
293293
for _, guest := range guests {
294294
var ok bool
295+
if len(filterFuncs) == 0 {
296+
ok = true
297+
}
295298
for _, guestPassedFilter := range filterFuncs {
296299
if ok = guestPassedFilter(guest); !ok {
297300
break
@@ -305,6 +308,8 @@ func filterGuests(config Config, guests []proxmox.GuestResource) []proxmox.Guest
305308
return result
306309
}
307310

311+
// configTagsMatchNodeTags compares two lists of strings and returns true only when all
312+
// elements from the first list are present in the second list.
308313
func configTagsMatchNodeTags(configTags []string, nodeTags []proxmox.Tag) bool {
309314
var countOfMatchedTags int
310315
for _, configTag := range configTags {
@@ -325,14 +330,15 @@ func configTagsMatchNodeTags(configTags []string, nodeTags []proxmox.Tag) bool {
325330
return true
326331
}
327332

333+
// newProxmoxClient creates new client and tries to connect and log in to Proxmox instance.
328334
func newProxmoxClient(config Config) (*proxmox.Client, error) {
329335
tlsConfig := &tls.Config{
330336
InsecureSkipVerify: config.SkipCertValidation,
331337
}
332338

333339
client, err := proxmox.NewClient(strings.TrimSuffix(config.proxmoxURL.String(), "/"), nil, "", tlsConfig, "", int(config.TaskTimeout.Seconds()))
334340
if err != nil {
335-
return nil, err
341+
return nil, fmt.Errorf("could not connect to Proxmox: %w", err)
336342
}
337343

338344
*proxmox.Debug = config.PackerDebug
@@ -346,17 +352,19 @@ func newProxmoxClient(config Config) (*proxmox.Client, error) {
346352
log.Print("using password auth")
347353
err = client.Login(config.Username, config.Password, "")
348354
if err != nil {
349-
return nil, err
355+
return nil, fmt.Errorf("could not log in to Proxmox: %w", err)
350356
}
351357
}
352358

353359
return client, nil
354360
}
355361

362+
// parseMetaField parses the string from the `meta` field and returns integer value
363+
// representing the creation date of the virtual machine in epoch seconds format.
356364
func parseMetaField(field string) (int, error) {
357365
re, err := regexp.Compile(`.*ctime=(?P<ctime>[0-9]+).*`)
358366
if err != nil {
359-
return 0, err
367+
return 0, fmt.Errorf("could not compile regex to parse meta field: %w", err)
360368
}
361369

362370
matched := re.MatchString(field)
@@ -366,15 +374,34 @@ func parseMetaField(field string) (int, error) {
366374
valueStr := re.ReplaceAllString(field, "${ctime}")
367375
value, err := strconv.Atoi(valueStr)
368376
if err != nil {
369-
return 0, err
377+
return 0, fmt.Errorf("could not convert date field to int: %w", err)
370378
}
371379
return value, nil
372380
}
373381

382+
// joinTags used to combine list of strings into one string with defined separator.
374383
func joinTags(tags []proxmox.Tag, separator string) string {
375384
tagsAsStrings := make([]string, len(tags))
376385
for i, tag := range tags {
377386
tagsAsStrings[i] = string(tag)
378387
}
379388
return strings.Join(tagsAsStrings, separator)
380389
}
390+
391+
// configValueOrEmpty tries to retrieve string by key from dynamic map of interfaces.
392+
// In case when key not found or there was an error, this function returns empty string.
393+
func configValueOrEmpty(values *vmConfig, key string) string {
394+
result := ""
395+
if values != nil {
396+
value, exists := (*values)[key]
397+
if !exists {
398+
return result
399+
}
400+
strValue, ok := value.(string)
401+
if !ok {
402+
return result
403+
}
404+
result = strValue
405+
}
406+
return result
407+
}

datasource/proxmox/data.hcl2spec.go renamed to datasource/virtualmachine/data.hcl2spec.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

datasource/proxmox/data_test.go renamed to datasource/virtualmachine/data_test.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package proxmoxtemplate
1+
package virtualmachine
22

33
import (
44
"fmt"
@@ -126,6 +126,14 @@ func TestExecute(t *testing.T) {
126126
Latest: true,
127127
},
128128
},
129+
{
130+
name: "found latest guest at cluster, no error",
131+
expectFailure: false,
132+
expectedVmId: 102,
133+
configDiff: Config{
134+
Latest: true,
135+
},
136+
},
129137
{
130138
name: "proxmox host not found, error",
131139
expectFailure: true,

docs-partials/datasource/proxmox/DatasourceOutput.mdx

Lines changed: 0 additions & 9 deletions
This file was deleted.

0 commit comments

Comments
 (0)