Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .web-docs/components/builder/upcloud/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ The upcloud builder is used to generate storage templates on UpCloud.

- `token` (string) - The API token to use when interfacing with the UpCloud API. This is mutually exclusive with username and password.

- `server_plan` (string) - Server plan to use for the builder server. Defaults to `1xCPU-2GB`.

- `storage_name` (string) - The name of the storage that will be used to find the first matching storage in the list of existing templates.

Note that `storage_uuid` parameter has higher priority. You should use either `storage_uuid` or `storage_name` for not strict matching (e.g "ubuntu server 24.04").
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ See updating [Changelog example here](https://keepachangelog.com/en/1.0.0/)

## [Unreleased]

### Added

- `server_plan` parameter to builder configuration for selecting server plan to use during build.

## [1.9.2] - 2025-10-16

### Changed
Expand Down
2 changes: 1 addition & 1 deletion builder/upcloud/artifact.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func (a *Artifact) Files() []string {
}

func (a *Artifact) Id() string { //nolint:revive // method is required by packer-plugin-sdk
result := []string{}
result := make([]string, 0, len(a.Templates))
for _, t := range a.Templates {
result = append(result, t.UUID)
}
Expand Down
6 changes: 3 additions & 3 deletions builder/upcloud/artifact_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func TestArtifact_Id(t *testing.T) {
uuid2 := "some-uuid-2"
expected := fmt.Sprintf("%s,%s", uuid1, uuid2)

templates := []*upcloud.Storage{}
templates := make([]*upcloud.Storage, 0, 2)
templates = append(templates, &upcloud.Storage{UUID: uuid1}, &upcloud.Storage{UUID: uuid2})

a := &Artifact{Templates: templates}
Expand All @@ -39,7 +39,7 @@ func TestArtifact_String(t *testing.T) {
t.Parallel()
expected := `Storage template created, UUID: some-uuid`

templates := []*upcloud.Storage{}
templates := make([]*upcloud.Storage, 0, 1)
templates = append(templates, &upcloud.Storage{UUID: "some-uuid"})

a := &Artifact{Templates: templates}
Expand All @@ -52,7 +52,7 @@ func TestArtifact_String(t *testing.T) {

func TestArtifact_Metadata(t *testing.T) {
t.Parallel()
templates := []*upcloud.Storage{}
templates := make([]*upcloud.Storage, 0, 2)
templates = append(templates,
&upcloud.Storage{
UUID: "some-uuid",
Expand Down
25 changes: 20 additions & 5 deletions builder/upcloud/builder_acc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ var testBuilderStorageName string
//go:embed test-fixtures/json/networking.json
var testBuilderNetworking string

//go:embed test-fixtures/json/basic_standard_tier.json
var testBuilderBasicStandardTier string
//go:embed test-fixtures/json/plan_and_tier.json
var testBuilderPlanAndTier string

func TestBuilderAcc_default(t *testing.T) {
t.Parallel()
Expand Down Expand Up @@ -78,12 +78,12 @@ func TestBuilderAcc_storageName(t *testing.T) {
acctest.TestPlugin(t, testCase)
}

func TestBuilderAcc_standardTier(t *testing.T) {
func TestBuilderAcc_planAndTier(t *testing.T) {
t.Parallel()
testAccPreCheck(t)
testCase := &acctest.PluginTestCase{
Name: t.Name(),
Template: testBuilderBasicStandardTier,
Template: testBuilderPlanAndTier,
Check: checkTestResult(t),
Teardown: teardown(t, t.Name()),
}
Expand All @@ -107,6 +107,9 @@ func TestBuilderAcc_networking(t *testing.T) {
//go:embed test-fixtures/hcl2/basic.pkr.hcl
var testBuildBasicHcl string

//go:embed test-fixtures/hcl2/plan_and_tier.pkr.hcl
var testBuilderPlanAndTierHcl string

//go:embed test-fixtures/hcl2/storage-uuid.pkr.hcl
var testBuilderStorageUUIDHcl string

Expand All @@ -128,6 +131,18 @@ func TestBuilderAcc_default_hcl(t *testing.T) {
acctest.TestPlugin(t, testCase)
}

func TestBuilderAcc_planAndTier_hcl(t *testing.T) {
t.Parallel()
testAccPreCheck(t)
testCase := &acctest.PluginTestCase{
Name: t.Name(),
Template: testBuilderPlanAndTierHcl,
Check: checkTestResult(t),
Teardown: teardown(t, t.Name()),
}
acctest.TestPlugin(t, testCase)
}

func TestBuilderAcc_storageUuid_hcl(t *testing.T) {
t.Parallel()
testAccPreCheck(t)
Expand All @@ -152,7 +167,7 @@ func TestBuilderAcc_storageName_hcl(t *testing.T) {
acctest.TestPlugin(t, testCase)
}

func TestBuilderAcc_network_interfaces(t *testing.T) {
func TestBuilderAcc_network_interfaces_hcl(t *testing.T) {
t.Parallel()
testAccPreCheck(t)
testCase := &acctest.PluginTestCase{
Expand Down
3 changes: 3 additions & 0 deletions builder/upcloud/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ type Config struct {
// The zone in which the server and template should be created (e.g. nl-ams1).
Zone string `mapstructure:"zone" required:"true"`

// Server plan to use for the builder server. Defaults to `1xCPU-2GB`.
ServerPlan string `mapstructure:"server_plan"`

// The UUID of the storage you want to use as a template when creating the server.
//
// Optionally use `storage_name` parameter to find matching storage
Expand Down
2 changes: 2 additions & 0 deletions builder/upcloud/config.hcl2spec.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions builder/upcloud/step_create_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ func (s *StepCreateServer) createServer(ctx context.Context, ui packer.Ui, drv d
}

response, err := drv.CreateServer(ctx, &driver.ServerOpts{
ServerPlan: s.Config.ServerPlan,
StorageUUID: storage.UUID,
StorageSize: s.Config.StorageSize,
Zone: s.Config.Zone,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
source "upcloud" "standard-tier" {
server_plan = "2xCPU-4GB"
storage_uuid = "01000000-0000-4000-8000-000150020100" # Rocky Linux 9
zone = "pl-waw1"
storage_tier = "standard"
zone = "pl-waw1"
}

build {
sources = ["source.upcloud.standard-tier"]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"builders": [{
"type": "upcloud",
"zone": "nl-ams1",
"server_plan": "2xCPU-4GB",
"storage_uuid": "01000000-0000-4000-8000-000150020100",
"storage_tier": "standard"
}]
Expand Down
4 changes: 2 additions & 2 deletions builder/upcloud/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ func sshHostCallback(state multistep.StateBag) (string, error) {
}

func convertNetworkTypes(rawNetworking []NetworkInterface) []request.CreateServerInterface {
networking := []request.CreateServerInterface{}
networking := make([]request.CreateServerInterface, 0, len(rawNetworking))
for _, iface := range rawNetworking {
ips := []request.CreateServerIPAddress{}
ips := make([]request.CreateServerIPAddress, 0, len(iface.IPAddresses))
for _, ip := range iface.IPAddresses {
ips = append(ips, request.CreateServerIPAddress{Family: ip.Family, Address: ip.Address})
}
Expand Down
2 changes: 2 additions & 0 deletions docs-partials/builder/upcloud/Config-not-required.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

- `token` (string) - The API token to use when interfacing with the UpCloud API. This is mutually exclusive with username and password.

- `server_plan` (string) - Server plan to use for the builder server. Defaults to `1xCPU-2GB`.

- `storage_name` (string) - The name of the storage that will be used to find the first matching storage in the list of existing templates.

Note that `storage_uuid` parameter has higher priority. You should use either `storage_uuid` or `storage_name` for not strict matching (e.g "ubuntu server 24.04").
Expand Down
7 changes: 6 additions & 1 deletion internal/driver/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ type (
}

ServerOpts struct {
ServerPlan string
StorageUUID string
StorageSize int
Zone string
Expand Down Expand Up @@ -409,13 +410,17 @@ func (d *driver) GetServerStorage(ctx context.Context, serverUUID string) (*upcl
func (d *driver) prepareCreateRequest(opts *ServerOpts) *request.CreateServerRequest {
title := fmt.Sprintf("packer-%s-%s", DefaultHostname, getNowString())
titleDisk := fmt.Sprintf("%s-disk1", DefaultHostname)
plan := opts.ServerPlan
if plan == "" {
plan = DefaultPlan
}

request := request.CreateServerRequest{
Title: title,
Hostname: DefaultHostname,
Zone: opts.Zone,
PasswordDelivery: request.PasswordDeliveryNone,
Plan: DefaultPlan,
Plan: plan,
StorageDevices: []request.CreateServerStorageDevice{
{
Action: request.CreateServerStorageDeviceActionClone,
Expand Down
4 changes: 2 additions & 2 deletions post-processor/upcloud-import/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ func TestNewConfig_BothAuthMethods(t *testing.T) {

assert.NoError(t, err)
assert.Equal(t, "test-api-token", c.Token)
assert.Equal(t, "", c.Username)
assert.Equal(t, "", c.Password)
assert.Empty(t, c.Username)
assert.Empty(t, c.Password)
}

func TestNewConfig_NoAuthMethods(t *testing.T) {
Expand Down
Loading