From 07d2d70d2df9059bfd2c19301c8c44c18a01e95e Mon Sep 17 00:00:00 2001 From: Eric Le Lay Date: Wed, 26 Aug 2026 09:01:47 +0200 Subject: [PATCH] Use gophercloud/v2 to support OpenStack 2026.1. Fixes #162 --- builder/openstack/access_config.go | 27 +++++----- builder/openstack/artifact.go | 7 +-- builder/openstack/builder.go | 7 +++ builder/openstack/builder.hcl2spec.go | 2 +- builder/openstack/image_config.go | 2 +- builder/openstack/networks.go | 39 ++++++++------- builder/openstack/run_config.go | 2 +- builder/openstack/run_config_test.go | 2 +- builder/openstack/server.go | 22 +++++---- builder/openstack/ssh.go | 10 ++-- builder/openstack/step_add_image_members.go | 6 +-- builder/openstack/step_allocate_ip.go | 19 +++---- builder/openstack/step_create_image.go | 16 +++--- builder/openstack/step_create_volume.go | 14 +++--- builder/openstack/step_delete_server.go | 2 +- builder/openstack/step_discover_network.go | 4 +- builder/openstack/step_get_password.go | 4 +- builder/openstack/step_key_pair.go | 9 ++-- builder/openstack/step_load_flavor.go | 8 +-- builder/openstack/step_run_source_server.go | 36 +++++++------- builder/openstack/step_source_image_info.go | 17 ++++--- builder/openstack/step_stop_server.go | 12 ++--- .../openstack/step_update_image_mindisk.go | 5 +- builder/openstack/step_update_image_tags.go | 3 +- .../openstack/step_update_image_visibility.go | 3 +- .../openstack/step_wait_for_rackconnect.go | 4 +- builder/openstack/volume.go | 19 +++---- go.mod | 22 +++++---- go.sum | 49 +++++++++---------- 29 files changed, 198 insertions(+), 174 deletions(-) diff --git a/builder/openstack/access_config.go b/builder/openstack/access_config.go index 334cd312..d7df5a67 100644 --- a/builder/openstack/access_config.go +++ b/builder/openstack/access_config.go @@ -7,6 +7,7 @@ package openstack import ( "bytes" + "context" "crypto/tls" "crypto/x509" "fmt" @@ -14,9 +15,9 @@ import ( "net/http" "os" - "github.com/gophercloud/gophercloud" - "github.com/gophercloud/gophercloud/openstack" - "github.com/gophercloud/utils/openstack/clientconfig" + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/openstack" + "github.com/gophercloud/utils/v2/openstack/clientconfig" "github.com/hashicorp/go-cleanhttp" packersdk "github.com/hashicorp/packer-plugin-sdk/packer" "github.com/hashicorp/packer-plugin-sdk/template/interpolate" @@ -135,6 +136,10 @@ func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error { c.ClientKeyFile = os.Getenv("OS_KEY") } + return nil +} + +func (c *AccessConfig) Authenticate(ctx context.Context) error { clientOpts := new(clientconfig.ClientOpts) // If a cloud entry was given, base AuthOptions on a clouds.yaml file. @@ -143,7 +148,7 @@ func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error { cloud, err := clientconfig.GetCloudFromYAML(clientOpts) if err != nil { - return []error{err} + return err } if c.Region == "" && cloud.RegionName != "" { @@ -166,7 +171,7 @@ func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error { ao, err := clientconfig.AuthOptions(clientOpts) if err != nil { - return []error{err} + return err } // Make sure we reauth as needed @@ -198,7 +203,7 @@ func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error { // Build the client itself client, err := openstack.NewClient(ao.IdentityEndpoint) if err != nil { - return []error{err} + return err } tls_config := &tls.Config{} @@ -206,7 +211,7 @@ func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error { if c.CACertFile != "" { caCert, err := os.ReadFile(c.CACertFile) if err != nil { - return []error{err} + return err } caCertPool := x509.NewCertPool() caCertPool.AppendCertsFromPEM(caCert) @@ -222,7 +227,7 @@ func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error { if c.ClientCertFile != "" && c.ClientKeyFile != "" { cert, err := tls.LoadX509KeyPair(c.ClientCertFile, c.ClientKeyFile) if err != nil { - return []error{err} + return err } tls_config.Certificates = []tls.Certificate{cert} @@ -233,9 +238,9 @@ func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error { client.HTTPClient.Transport = transport // Auth - err = openstack.Authenticate(client, *ao) + err = openstack.Authenticate(ctx, client, *ao) if err != nil { - return []error{err} + return err } c.osClient = client @@ -259,7 +264,7 @@ func (c *AccessConfig) computeV2Client() (*gophercloud.ServiceClient, error) { } func (c *AccessConfig) imageV2Client() (*gophercloud.ServiceClient, error) { - return openstack.NewImageServiceV2(c.osClient, gophercloud.EndpointOpts{ + return openstack.NewImageV2(c.osClient, gophercloud.EndpointOpts{ Region: c.Region, Availability: c.getEndpointType(), }) diff --git a/builder/openstack/artifact.go b/builder/openstack/artifact.go index 2940f847..5f09f774 100644 --- a/builder/openstack/artifact.go +++ b/builder/openstack/artifact.go @@ -4,11 +4,12 @@ package openstack import ( + "context" "fmt" "log" - "github.com/gophercloud/gophercloud" - "github.com/gophercloud/gophercloud/openstack/imageservice/v2/images" + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/openstack/image/v2/images" registryimage "github.com/hashicorp/packer-plugin-sdk/packer/registry/image" ) @@ -74,5 +75,5 @@ func (a *Artifact) State(name string) any { func (a *Artifact) Destroy() error { log.Printf("Destroying image: %s", a.ImageId) - return images.Delete(a.Client, a.ImageId).ExtractErr() + return images.Delete(context.TODO(), a.Client, a.ImageId).ExtractErr() } diff --git a/builder/openstack/builder.go b/builder/openstack/builder.go index 7e139bc0..061f7402 100644 --- a/builder/openstack/builder.go +++ b/builder/openstack/builder.go @@ -76,6 +76,12 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) { } func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook) (packersdk.Artifact, error) { + + err := b.config.AccessConfig.Authenticate(ctx) + if err != nil { + return nil, fmt.Errorf("Error initializing compute client: %s", err) + } + if b.config.PackerDebug { b.config.enableDebug(ui) } @@ -158,6 +164,7 @@ func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook) &communicator.StepConnect{ Config: &b.config.RunConfig.Comm, Host: CommHost( + ctx, b.config.RunConfig.Comm.Host(), computeClient, b.config.SSHInterface, diff --git a/builder/openstack/builder.hcl2spec.go b/builder/openstack/builder.hcl2spec.go index 0de96ca3..1a68dbab 100644 --- a/builder/openstack/builder.hcl2spec.go +++ b/builder/openstack/builder.hcl2spec.go @@ -3,7 +3,7 @@ package openstack import ( - "github.com/gophercloud/gophercloud/openstack/imageservice/v2/images" + "github.com/gophercloud/gophercloud/v2/openstack/image/v2/images" "github.com/hashicorp/hcl/v2/hcldec" "github.com/zclconf/go-cty/cty" ) diff --git a/builder/openstack/image_config.go b/builder/openstack/image_config.go index e1ffdb61..05b82840 100644 --- a/builder/openstack/image_config.go +++ b/builder/openstack/image_config.go @@ -9,7 +9,7 @@ import ( "fmt" "strings" - imageservice "github.com/gophercloud/gophercloud/openstack/imageservice/v2/images" + imageservice "github.com/gophercloud/gophercloud/v2/openstack/image/v2/images" "github.com/hashicorp/packer-plugin-sdk/template/interpolate" ) diff --git a/builder/openstack/networks.go b/builder/openstack/networks.go index 96443fcd..0259f4b5 100644 --- a/builder/openstack/networks.go +++ b/builder/openstack/networks.go @@ -4,25 +4,26 @@ package openstack import ( + "context" "fmt" "log" "net" "github.com/google/uuid" - "github.com/gophercloud/gophercloud" - "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces" - "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external" - "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips" - "github.com/gophercloud/gophercloud/openstack/networking/v2/networks" - "github.com/gophercloud/gophercloud/openstack/networking/v2/subnets" - "github.com/gophercloud/gophercloud/pagination" + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/openstack/compute/v2/attachinterfaces" + "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/external" + "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/layer3/floatingips" + "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/networks" + "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/subnets" + "github.com/gophercloud/gophercloud/v2/pagination" ) // CheckFloatingIP gets a floating IP by its ID and checks if it is already // associated with any internal interface. // It returns floating IP if it can be used. -func CheckFloatingIP(client *gophercloud.ServiceClient, id string) (*floatingips.FloatingIP, error) { - floatingIP, err := floatingips.Get(client, id).Extract() +func CheckFloatingIP(ctx context.Context, client *gophercloud.ServiceClient, id string) (*floatingips.FloatingIP, error) { + floatingIP, err := floatingips.Get(ctx, client, id).Extract() if err != nil { return nil, err } @@ -36,13 +37,13 @@ func CheckFloatingIP(client *gophercloud.ServiceClient, id string) (*floatingips // FindFreeFloatingIP returns free unassociated floating IP. // It will return first floating IP if there are many. -func FindFreeFloatingIP(client *gophercloud.ServiceClient) (*floatingips.FloatingIP, error) { +func FindFreeFloatingIP(ctx context.Context, client *gophercloud.ServiceClient) (*floatingips.FloatingIP, error) { var freeFloatingIP *floatingips.FloatingIP pager := floatingips.List(client, floatingips.ListOpts{ Status: "DOWN", }) - err := pager.EachPage(func(page pagination.Page) (bool, error) { + err := pager.EachPage(ctx, func(ctx context.Context, page pagination.Page) (bool, error) { candidates, err := floatingips.ExtractFloatingIPs(page) if err != nil { return false, err // stop and throw error out @@ -72,11 +73,11 @@ func FindFreeFloatingIP(client *gophercloud.ServiceClient) (*floatingips.Floatin // GetInstancePortID returns internal port of the instance that can be used for // the association of a floating IP. // It will return an ID of a first port if there are many. -func GetInstancePortID(client *gophercloud.ServiceClient, id string, instance_float_net string) (string, error) { +func GetInstancePortID(ctx context.Context, client *gophercloud.ServiceClient, id string, instance_float_net string) (string, error) { selected_interface := 0 - interfacesPage, err := attachinterfaces.List(client, id).AllPages() + interfacesPage, err := attachinterfaces.List(client, id).AllPages(ctx) if err != nil { return "", err } @@ -102,9 +103,9 @@ func GetInstancePortID(client *gophercloud.ServiceClient, id string, instance_fl // CheckFloatingIPNetwork checks provided network reference and returns a valid // Networking service ID. -func CheckFloatingIPNetwork(client *gophercloud.ServiceClient, networkRef string) (string, error) { +func CheckFloatingIPNetwork(ctx context.Context, client *gophercloud.ServiceClient, networkRef string) (string, error) { if _, err := uuid.Parse(networkRef); err != nil { - return GetFloatingIPNetworkIDByName(client, networkRef) + return GetFloatingIPNetworkIDByName(ctx, client, networkRef) } return networkRef, nil @@ -117,12 +118,12 @@ type ExternalNetwork struct { } // GetFloatingIPNetworkIDByName searches for the external network ID by the provided name. -func GetFloatingIPNetworkIDByName(client *gophercloud.ServiceClient, networkName string) (string, error) { +func GetFloatingIPNetworkIDByName(ctx context.Context, client *gophercloud.ServiceClient, networkName string) (string, error) { var externalNetworks []ExternalNetwork allPages, err := networks.List(client, networks.ListOpts{ Name: networkName, - }).AllPages() + }).AllPages(ctx) if err != nil { return "", err } @@ -143,8 +144,8 @@ func GetFloatingIPNetworkIDByName(client *gophercloud.ServiceClient, networkName } // DiscoverProvisioningNetwork finds the first network whose subnet matches the given network ranges. -func DiscoverProvisioningNetwork(client *gophercloud.ServiceClient, cidrs []string) (string, error) { - allPages, err := subnets.List(client, subnets.ListOpts{}).AllPages() +func DiscoverProvisioningNetwork(ctx context.Context, client *gophercloud.ServiceClient, cidrs []string) (string, error) { + allPages, err := subnets.List(client, subnets.ListOpts{}).AllPages(ctx) if err != nil { return "", err } diff --git a/builder/openstack/run_config.go b/builder/openstack/run_config.go index c5ca72d2..a86c514b 100644 --- a/builder/openstack/run_config.go +++ b/builder/openstack/run_config.go @@ -9,7 +9,7 @@ import ( "errors" "fmt" - "github.com/gophercloud/gophercloud/openstack/imageservice/v2/images" + "github.com/gophercloud/gophercloud/v2/openstack/image/v2/images" "github.com/hashicorp/packer-plugin-sdk/communicator" "github.com/hashicorp/packer-plugin-sdk/template/interpolate" "github.com/hashicorp/packer-plugin-sdk/uuid" diff --git a/builder/openstack/run_config_test.go b/builder/openstack/run_config_test.go index 9da21200..3d0e2a2d 100644 --- a/builder/openstack/run_config_test.go +++ b/builder/openstack/run_config_test.go @@ -8,7 +8,7 @@ import ( "regexp" "testing" - "github.com/gophercloud/gophercloud/openstack/imageservice/v2/images" + "github.com/gophercloud/gophercloud/v2/openstack/image/v2/images" "github.com/hashicorp/packer-plugin-sdk/communicator" "github.com/mitchellh/mapstructure" ) diff --git a/builder/openstack/server.go b/builder/openstack/server.go index 9b37e815..0d4a98b2 100644 --- a/builder/openstack/server.go +++ b/builder/openstack/server.go @@ -4,13 +4,15 @@ package openstack import ( + "context" "errors" "fmt" "log" + "net/http" "time" - "github.com/gophercloud/gophercloud" - "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/openstack/compute/v2/servers" "github.com/hashicorp/packer-plugin-sdk/multistep" packersdk "github.com/hashicorp/packer-plugin-sdk/packer" ) @@ -37,12 +39,12 @@ type StateChangeConf struct { // ServerStateRefreshFunc returns a StateRefreshFunc that is used to watch // an openstack server. -func ServerStateRefreshFunc( +func ServerStateRefreshFunc(ctx context.Context, client *gophercloud.ServiceClient, instanceID string) StateRefreshFunc { return func() (interface{}, string, int, error) { - serverNew, err := servers.Get(client, instanceID).Extract() + serverNew, err := servers.Get(ctx, client, instanceID).Extract() if err != nil { - if _, ok := err.(gophercloud.ErrDefault404); ok { + if gophercloud.ResponseCodeIs(err, http.StatusNotFound) { log.Printf("[INFO] 404 on ServerStateRefresh, returning DELETED") return nil, "DELETED", 0, nil } @@ -96,7 +98,7 @@ func WaitForState(conf *StateChangeConf) (i interface{}, err error) { } } -func DeleteServer(state multistep.StateBag, instance string) error { +func DeleteServer(ctx context.Context, state multistep.StateBag, instance string) error { config := state.Get("config").(*Config) ui := state.Get("ui").(packersdk.Ui) @@ -113,16 +115,16 @@ func DeleteServer(state multistep.StateBag, instance string) error { ui.Say(fmt.Sprintf("Terminating the source server: %s ...", instance)) for { if config.ForceDelete { - err = servers.ForceDelete(computeClient, instance).ExtractErr() + err = servers.ForceDelete(ctx, computeClient, instance).ExtractErr() } else { - err = servers.Delete(computeClient, instance).ExtractErr() + err = servers.Delete(ctx, computeClient, instance).ExtractErr() } if err == nil { break } - if _, ok := err.(gophercloud.ErrDefault500); !ok { + if gophercloud.ResponseCodeIs(err, http.StatusInternalServerError) { err = fmt.Errorf("Error terminating server, may still be around: %s", err) return err } @@ -139,7 +141,7 @@ func DeleteServer(state multistep.StateBag, instance string) error { stateChange := StateChangeConf{ Pending: []string{"ACTIVE", "BUILD", "REBUILD", "SUSPENDED", "SHUTOFF", "STOPPED"}, - Refresh: ServerStateRefreshFunc(computeClient, instance), + Refresh: ServerStateRefreshFunc(ctx, computeClient, instance), Target: []string{"DELETED"}, } diff --git a/builder/openstack/ssh.go b/builder/openstack/ssh.go index 1f84ab98..0d61b890 100644 --- a/builder/openstack/ssh.go +++ b/builder/openstack/ssh.go @@ -4,18 +4,20 @@ package openstack import ( + "context" "errors" "log" "time" - "github.com/gophercloud/gophercloud" - "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" - "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips" + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/openstack/compute/v2/servers" + "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/layer3/floatingips" "github.com/hashicorp/packer-plugin-sdk/multistep" ) // CommHost looks up the host for the communicator. func CommHost( + ctx context.Context, host string, client *gophercloud.ServiceClient, sshinterface string, @@ -54,7 +56,7 @@ func CommHost( return addr, nil } - s, err := servers.Get(client, s.ID).Extract() + s, err := servers.Get(ctx, client, s.ID).Extract() if err != nil { return "", err } diff --git a/builder/openstack/step_add_image_members.go b/builder/openstack/step_add_image_members.go index 053dc76c..561317f9 100644 --- a/builder/openstack/step_add_image_members.go +++ b/builder/openstack/step_add_image_members.go @@ -7,7 +7,7 @@ import ( "context" "fmt" - "github.com/gophercloud/gophercloud/openstack/imageservice/v2/members" + "github.com/gophercloud/gophercloud/v2/openstack/image/v2/members" "github.com/hashicorp/packer-plugin-sdk/multistep" packersdk "github.com/hashicorp/packer-plugin-sdk/packer" ) @@ -38,7 +38,7 @@ func (s *stepAddImageMembers) Run(ctx context.Context, state multistep.StateBag) for _, member := range config.ImageMembers { ui.Say(fmt.Sprintf("Adding member '%s' to image %s", member, imageId)) - r := members.Create(imageClient, imageId, member) + r := members.Create(ctx, imageClient, imageId, member) if _, err = r.Extract(); err != nil { err = fmt.Errorf("Error adding member to image: %s", err) state.Put("error", err) @@ -49,7 +49,7 @@ func (s *stepAddImageMembers) Run(ctx context.Context, state multistep.StateBag) if config.ImageAutoAcceptMembers { for _, member := range config.ImageMembers { ui.Say(fmt.Sprintf("Accepting image %s for member '%s'", imageId, member)) - r := members.Update(imageClient, imageId, member, members.UpdateOpts{Status: "accepted"}) + r := members.Update(ctx, imageClient, imageId, member, members.UpdateOpts{Status: "accepted"}) if _, err = r.Extract(); err != nil { err = fmt.Errorf("Error accepting image for member: %s", err) state.Put("error", err) diff --git a/builder/openstack/step_allocate_ip.go b/builder/openstack/step_allocate_ip.go index 01acf094..39e04b94 100644 --- a/builder/openstack/step_allocate_ip.go +++ b/builder/openstack/step_allocate_ip.go @@ -7,8 +7,8 @@ import ( "context" "fmt" - "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" - "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips" + "github.com/gophercloud/gophercloud/v2/openstack/compute/v2/servers" + "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/layer3/floatingips" "github.com/hashicorp/packer-plugin-sdk/multistep" packersdk "github.com/hashicorp/packer-plugin-sdk/packer" ) @@ -60,7 +60,7 @@ func (s *StepAllocateIp) Run(ctx context.Context, state multistep.StateBag) mult // ID or name of the network). if s.FloatingIP != "" { // Try to use FloatingIP if it was provided by the user. - freeFloatingIP, err := CheckFloatingIP(networkClient, s.FloatingIP) + freeFloatingIP, err := CheckFloatingIP(ctx, networkClient, s.FloatingIP) if err != nil { err := fmt.Errorf("Error using provided floating IP '%s': %s", s.FloatingIP, err) state.Put("error", err) @@ -75,7 +75,7 @@ func (s *StepAllocateIp) Run(ctx context.Context, state multistep.StateBag) mult // If ReuseIPs is set to true and we have a free floating IP, use it rather // than creating one. ui.Say("Searching for unassociated floating IP") - freeFloatingIP, err := FindFreeFloatingIP(networkClient) + freeFloatingIP, err := FindFreeFloatingIP(ctx, networkClient) if err != nil { err := fmt.Errorf("Error searching for floating IP: %s", err) state.Put("error", err) @@ -89,7 +89,7 @@ func (s *StepAllocateIp) Run(ctx context.Context, state multistep.StateBag) mult } else if s.FloatingIPNetwork != "" { // Lastly, if FloatingIPNetwork was provided by the user, we need to use it // to allocate a new floating IP and associate it to the instance. - floatingNetwork, err := CheckFloatingIPNetwork(networkClient, s.FloatingIPNetwork) + floatingNetwork, err := CheckFloatingIPNetwork(ctx, networkClient, s.FloatingIPNetwork) if err != nil { err := fmt.Errorf("Error using the provided floating_ip_network: %s", err) state.Put("error", err) @@ -98,7 +98,7 @@ func (s *StepAllocateIp) Run(ctx context.Context, state multistep.StateBag) mult } ui.Say(fmt.Sprintf("Creating floating IP using network %s ...", floatingNetwork)) - newIP, err := floatingips.Create(networkClient, floatingips.CreateOpts{ + newIP, err := floatingips.Create(ctx, networkClient, floatingips.CreateOpts{ FloatingNetworkID: floatingNetwork, }).Extract() if err != nil { @@ -118,7 +118,7 @@ func (s *StepAllocateIp) Run(ctx context.Context, state multistep.StateBag) mult ui.Say(fmt.Sprintf("Associating floating IP '%s' (%s) with instance port...", instanceIP.ID, instanceIP.FloatingIP)) - portID, err := GetInstancePortID(computeClient, server.ID, s.InstanceFloatingIPNet) + portID, err := GetInstancePortID(ctx, computeClient, server.ID, s.InstanceFloatingIPNet) if err != nil { err := fmt.Errorf("Error getting interfaces of the instance '%s': %s", server.ID, err) state.Put("error", err) @@ -126,7 +126,7 @@ func (s *StepAllocateIp) Run(ctx context.Context, state multistep.StateBag) mult return multistep.ActionHalt } - _, err = floatingips.Update(networkClient, instanceIP.ID, floatingips.UpdateOpts{ + _, err = floatingips.Update(ctx, networkClient, instanceIP.ID, floatingips.UpdateOpts{ PortID: &portID, }).Extract() if err != nil { @@ -149,6 +149,7 @@ func (s *StepAllocateIp) Run(ctx context.Context, state multistep.StateBag) mult func (s *StepAllocateIp) Cleanup(state multistep.StateBag) { config := state.Get("config").(*Config) ui := state.Get("ui").(packersdk.Ui) + ctx := context.TODO() instanceIP := state.Get("access_ip").(*floatingips.FloatingIP) // Don't clean up if unless required @@ -170,7 +171,7 @@ func (s *StepAllocateIp) Cleanup(state multistep.StateBag) { } if instanceIP.ID != "" { - if err := floatingips.Delete(client, instanceIP.ID).ExtractErr(); err != nil { + if err := floatingips.Delete(ctx, client, instanceIP.ID).ExtractErr(); err != nil { ui.Error(fmt.Sprintf( "Error deleting temporary floating IP '%s' (%s)", instanceIP.ID, instanceIP.FloatingIP)) return diff --git a/builder/openstack/step_create_image.go b/builder/openstack/step_create_image.go index 90861d2e..4570e87b 100644 --- a/builder/openstack/step_create_image.go +++ b/builder/openstack/step_create_image.go @@ -9,11 +9,11 @@ import ( "log" "time" - "github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions" + "github.com/gophercloud/gophercloud/v2/openstack/blockstorage/v3/volumes" - "github.com/gophercloud/gophercloud" - "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" - "github.com/gophercloud/gophercloud/openstack/imageservice/v2/images" + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/openstack/compute/v2/servers" + "github.com/gophercloud/gophercloud/v2/openstack/image/v2/images" "github.com/hashicorp/packer-plugin-sdk/multistep" packersdk "github.com/hashicorp/packer-plugin-sdk/packer" ) @@ -66,7 +66,7 @@ func (s *stepCreateImage) Run(ctx context.Context, state multistep.StateBag) mul // set ImageMetadata before uploading to glance so the new image captured the desired values if len(config.ImageMetadata) > 0 { - err = volumeactions.SetImageMetadata(blockStorageClient, volume, volumeactions.ImageMetadataOpts{ + err = volumes.SetImageMetadata(ctx, blockStorageClient, volume, volumes.ImageMetadataOpts{ Metadata: config.ImageMetadata, }).ExtractErr() if err != nil { @@ -75,7 +75,7 @@ func (s *stepCreateImage) Run(ctx context.Context, state multistep.StateBag) mul } } - image, err := volumeactions.UploadImage(blockStorageClient, volume, volumeactions.UploadImageOpts{ + image, err := volumes.UploadImage(ctx, blockStorageClient, volume, volumes.UploadImageOpts{ DiskFormat: config.ImageDiskFormat, ImageName: config.ImageName, }).Extract() @@ -87,7 +87,7 @@ func (s *stepCreateImage) Run(ctx context.Context, state multistep.StateBag) mul } imageId = image.ImageID } else { - imageId, err = servers.CreateImage(computeClient, server.ID, servers.CreateImageOpts{ + imageId, err = servers.CreateImage(ctx, computeClient, server.ID, servers.CreateImageOpts{ Name: config.ImageName, Metadata: config.ImageMetadata, }).ExtractImageID() @@ -128,7 +128,7 @@ func WaitForImage(ctx context.Context, client *gophercloud.ServiceClient, imageI if err := ctx.Err(); err != nil { return err } - image, err := images.Get(client, imageId).Extract() + image, err := images.Get(ctx, client, imageId).Extract() if err != nil { errCode, ok := err.(*gophercloud.ErrUnexpectedResponseCode) if ok && (errCode.Actual == 500 || errCode.Actual == 404) { diff --git a/builder/openstack/step_create_volume.go b/builder/openstack/step_create_volume.go index 6a501e93..a24f8fd5 100644 --- a/builder/openstack/step_create_volume.go +++ b/builder/openstack/step_create_volume.go @@ -7,7 +7,7 @@ import ( "context" "fmt" - "github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes" + "github.com/gophercloud/gophercloud/v2/openstack/blockstorage/v3/volumes" "github.com/hashicorp/packer-plugin-sdk/multistep" packersdk "github.com/hashicorp/packer-plugin-sdk/packer" ) @@ -49,7 +49,7 @@ func (s *StepCreateVolume) Run(ctx context.Context, state multistep.StateBag) mu return multistep.ActionHalt } - volumeSize, err = GetVolumeSize(imageClient, sourceImage) + volumeSize, err = GetVolumeSize(ctx, imageClient, sourceImage) if err != nil { err := fmt.Errorf("Error creating volume: %s", err) state.Put("error", err) @@ -59,6 +59,7 @@ func (s *StepCreateVolume) Run(ctx context.Context, state multistep.StateBag) mu } ui.Say("Creating volume...") + schedulerHintOpts := volumes.SchedulerHintOpts{} volumeOpts := volumes.CreateOpts{ Size: volumeSize, VolumeType: s.VolumeType, @@ -67,7 +68,7 @@ func (s *StepCreateVolume) Run(ctx context.Context, state multistep.StateBag) mu ImageID: sourceImage, Metadata: config.ImageMetadata, } - volume, err := volumes.Create(blockStorageClient, volumeOpts).Extract() + volume, err := volumes.Create(ctx, blockStorageClient, volumeOpts, schedulerHintOpts).Extract() if err != nil { err := fmt.Errorf("Error creating volume: %s", err) state.Put("error", err) @@ -80,7 +81,7 @@ func (s *StepCreateVolume) Run(ctx context.Context, state multistep.StateBag) mu // Wait for volume to become available. ui.Say(fmt.Sprintf("Waiting for volume %s (volume id: %s) to become available...", config.VolumeName, volume.ID)) - if err := WaitForVolume(blockStorageClient, volume.ID); err != nil { + if err := WaitForVolume(ctx, blockStorageClient, volume.ID); err != nil { err := fmt.Errorf("Error waiting for volume: %s", err) state.Put("error", err) ui.Error(err.Error()) @@ -101,6 +102,7 @@ func (s *StepCreateVolume) Cleanup(state multistep.StateBag) { config := state.Get("config").(*Config) ui := state.Get("ui").(packersdk.Ui) + ctx := context.TODO() blockStorageClient, err := config.blockStorageV3Client() if err != nil { @@ -113,14 +115,14 @@ func (s *StepCreateVolume) Cleanup(state multistep.StateBag) { // After image creation from a volume, Cinder may still be detaching it // (status "uploading"). Deleting in that state returns a 400 error. ui.Say(fmt.Sprintf("Waiting for volume %s to become available...", s.volumeID)) - if err := WaitForVolume(blockStorageClient, s.volumeID); err != nil { + if err := WaitForVolume(ctx, blockStorageClient, s.volumeID); err != nil { ui.Error(fmt.Sprintf( "Error waiting for volume %s to become available: %s. Attempting deletion anyway.", s.volumeID, err)) } ui.Say(fmt.Sprintf("Deleting volume: %s ...", s.volumeID)) - err = volumes.Delete(blockStorageClient, s.volumeID, volumes.DeleteOpts{}).ExtractErr() + err = volumes.Delete(ctx, blockStorageClient, s.volumeID, volumes.DeleteOpts{}).ExtractErr() if err != nil { ui.Error(fmt.Sprintf( "Error cleaning up volume %q: %s. This may need manual deletion.", s.volumeID, err)) diff --git a/builder/openstack/step_delete_server.go b/builder/openstack/step_delete_server.go index 55da6d83..7c668d4e 100644 --- a/builder/openstack/step_delete_server.go +++ b/builder/openstack/step_delete_server.go @@ -21,7 +21,7 @@ func (s *StepDeleteServer) Run(ctx context.Context, state multistep.StateBag) mu instance := state.Get("instance_id").(string) - err := DeleteServer(state, instance) + err := DeleteServer(ctx, state, instance) if err != nil { state.Put("error", err) return multistep.ActionHalt diff --git a/builder/openstack/step_discover_network.go b/builder/openstack/step_discover_network.go index 0bd5d2d0..a53aa49c 100644 --- a/builder/openstack/step_discover_network.go +++ b/builder/openstack/step_discover_network.go @@ -7,7 +7,7 @@ import ( "context" "fmt" - "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" + "github.com/gophercloud/gophercloud/v2/openstack/compute/v2/servers" "github.com/hashicorp/packer-plugin-sdk/multistep" packersdk "github.com/hashicorp/packer-plugin-sdk/packer" ) @@ -41,7 +41,7 @@ func (s *StepDiscoverNetwork) Run(ctx context.Context, state multistep.StateBag) if len(networks) == 0 && len(cidrs) > 0 { ui.Say("Discovering provisioning network...") - networkID, err := DiscoverProvisioningNetwork(networkClient, cidrs) + networkID, err := DiscoverProvisioningNetwork(ctx, networkClient, cidrs) if err != nil { state.Put("error", err) return multistep.ActionHalt diff --git a/builder/openstack/step_get_password.go b/builder/openstack/step_get_password.go index 8f619691..f2251742 100644 --- a/builder/openstack/step_get_password.go +++ b/builder/openstack/step_get_password.go @@ -10,7 +10,7 @@ import ( "log" "time" - "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" + "github.com/gophercloud/gophercloud/v2/openstack/compute/v2/servers" "github.com/hashicorp/packer-plugin-sdk/communicator" "github.com/hashicorp/packer-plugin-sdk/multistep" packersdk "github.com/hashicorp/packer-plugin-sdk/packer" @@ -60,7 +60,7 @@ func (s *StepGetPassword) Run(ctx context.Context, state multistep.StateBag) mul return multistep.ActionHalt } - for ; password == "" && err == nil; password, err = servers.GetPassword(computeClient, server.ID).ExtractPassword(privateKey.(*rsa.PrivateKey)) { + for ; password == "" && err == nil; password, err = servers.GetPassword(ctx, computeClient, server.ID).ExtractPassword(privateKey.(*rsa.PrivateKey)) { // Check for an interrupt in between attempts. if _, ok := state.GetOk(multistep.StateCancelled); ok { diff --git a/builder/openstack/step_key_pair.go b/builder/openstack/step_key_pair.go index b87089ad..6ad446a6 100644 --- a/builder/openstack/step_key_pair.go +++ b/builder/openstack/step_key_pair.go @@ -9,7 +9,7 @@ import ( "os" "runtime" - "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs" + "github.com/gophercloud/gophercloud/v2/openstack/compute/v2/keypairs" "github.com/hashicorp/packer-plugin-sdk/communicator" "github.com/hashicorp/packer-plugin-sdk/multistep" packersdk "github.com/hashicorp/packer-plugin-sdk/packer" @@ -67,7 +67,7 @@ func (s *StepKeyPair) Run(ctx context.Context, state multistep.StateBag) multist } ui.Say(fmt.Sprintf("Creating temporary keypair: %s ...", s.Comm.SSHTemporaryKeyPairName)) - err = keypairs.Create(computeClient, keypairs.CreateOpts{ + err = keypairs.Create(ctx, computeClient, keypairs.CreateOpts{ Name: s.Comm.SSHTemporaryKeyPairName, PublicKey: string(s.Comm.SSHPublicKey), }).Err @@ -122,6 +122,7 @@ func (s *StepKeyPair) Cleanup(state multistep.StateBag) { config := state.Get("config").(*Config) ui := state.Get("ui").(packersdk.Ui) + ctx := context.TODO() // We need the v2 compute client computeClient, err := config.computeV2Client() @@ -131,8 +132,10 @@ func (s *StepKeyPair) Cleanup(state multistep.StateBag) { return } + deleteOpts := keypairs.DeleteOpts{} + ui.Say(fmt.Sprintf("Deleting temporary keypair: %s ...", s.Comm.SSHTemporaryKeyPairName)) - err = keypairs.Delete(computeClient, s.Comm.SSHTemporaryKeyPairName).ExtractErr() + err = keypairs.Delete(ctx, computeClient, s.Comm.SSHTemporaryKeyPairName, deleteOpts).ExtractErr() if err != nil { ui.Error(fmt.Sprintf( "Error cleaning up keypair. Please delete the key manually: %s", s.Comm.SSHTemporaryKeyPairName)) diff --git a/builder/openstack/step_load_flavor.go b/builder/openstack/step_load_flavor.go index 70bfc73a..97a4ae89 100644 --- a/builder/openstack/step_load_flavor.go +++ b/builder/openstack/step_load_flavor.go @@ -8,8 +8,8 @@ import ( "fmt" "log" - "github.com/gophercloud/gophercloud/openstack/compute/v2/flavors" - flavors_utils "github.com/gophercloud/utils/openstack/compute/v2/flavors" + "github.com/gophercloud/gophercloud/v2/openstack/compute/v2/flavors" + flavors_utils "github.com/gophercloud/utils/v2/openstack/compute/v2/flavors" "github.com/hashicorp/packer-plugin-sdk/multistep" packersdk "github.com/hashicorp/packer-plugin-sdk/packer" ) @@ -35,13 +35,13 @@ func (s *StepLoadFlavor) Run(ctx context.Context, state multistep.StateBag) mult ui.Say(fmt.Sprintf("Loading flavor: %s", s.Flavor)) log.Printf("[INFO] Loading flavor by ID: %s", s.Flavor) - flavor, err := flavors.Get(client, s.Flavor).Extract() + flavor, err := flavors.Get(ctx, client, s.Flavor).Extract() if err != nil { log.Printf("[ERROR] Failed to find flavor by ID: %s", err) geterr := err log.Printf("[INFO] Loading flavor by name: %s", s.Flavor) - id, err := flavors_utils.IDFromName(client, s.Flavor) + id, err := flavors_utils.IDFromName(ctx, client, s.Flavor) if err != nil { log.Printf("[ERROR] Failed to find flavor by name: %s", err) err = fmt.Errorf( diff --git a/builder/openstack/step_run_source_server.go b/builder/openstack/step_run_source_server.go index 5804c577..c86ff62f 100644 --- a/builder/openstack/step_run_source_server.go +++ b/builder/openstack/step_run_source_server.go @@ -9,9 +9,8 @@ import ( "log" "os" - "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/bootfromvolume" - "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs" - "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" + "github.com/gophercloud/gophercloud/v2/openstack/compute/v2/keypairs" + "github.com/gophercloud/gophercloud/v2/openstack/compute/v2/servers" "github.com/hashicorp/packer-plugin-sdk/multistep" packersdk "github.com/hashicorp/packer-plugin-sdk/packer" ) @@ -65,36 +64,30 @@ func (s *StepRunSourceServer) Run(ctx context.Context, state multistep.StateBag) AvailabilityZone: s.AvailabilityZone, UserData: userData, ConfigDrive: &s.ConfigDrive, - ServiceClient: computeClient, Metadata: s.InstanceMetadata, } - var serverOptsExt servers.CreateOptsBuilder - // Create root volume in the Block Storage service if required. // Add block device mapping v2 to the server create options if required. if s.UseBlockStorageVolume { volume := state.Get("volume_id").(string) - blockDeviceMappingV2 := []bootfromvolume.BlockDevice{ - { + + serverOpts.BlockDevice = []servers.BlockDevice{ + servers.BlockDevice{ BootIndex: 0, - DestinationType: bootfromvolume.DestinationVolume, - SourceType: bootfromvolume.SourceVolume, + DestinationType: servers.DestinationVolume, + SourceType: servers.SourceVolume, UUID: volume, }, } // ImageRef and block device mapping is an invalid options combination. serverOpts.ImageRef = "" - serverOptsExt = bootfromvolume.CreateOptsExt{ - CreateOptsBuilder: serverOpts, - BlockDevice: blockDeviceMappingV2, - } - } else { - serverOptsExt = serverOpts } // Add keypair to the server create options. keyName := config.Comm.SSHKeyPairName + var serverOptsExt servers.CreateOptsBuilder + serverOptsExt = serverOpts if keyName != "" { serverOptsExt = keypairs.CreateOptsExt{ CreateOptsBuilder: serverOptsExt, @@ -102,8 +95,10 @@ func (s *StepRunSourceServer) Run(ctx context.Context, state multistep.StateBag) } } + // FIXME: no schedulerHintOpts config + ui.Say("Launching server...") - s.server, err = servers.Create(computeClient, serverOptsExt).Extract() + s.server, err = servers.Create(ctx, computeClient, serverOptsExt, nil).Extract() if err != nil { err := fmt.Errorf("Error launching source server: %s", err) state.Put("error", err) @@ -118,7 +113,7 @@ func (s *StepRunSourceServer) Run(ctx context.Context, state multistep.StateBag) stateChange := StateChangeConf{ Pending: []string{"BUILD"}, Target: []string{"ACTIVE"}, - Refresh: ServerStateRefreshFunc(computeClient, s.server.ID), + Refresh: ServerStateRefreshFunc(ctx, computeClient, s.server.ID), StepState: state, } latestServer, err := WaitForState(&stateChange) @@ -143,9 +138,12 @@ func (s *StepRunSourceServer) Cleanup(state multistep.StateBag) { return } + log.Printf("Running Cleanup for StepRunSourceServer id=%s", s.server.ID) + ui := state.Get("ui").(packersdk.Ui) + ctx := context.TODO() - err := DeleteServer(state, s.server.ID) + err := DeleteServer(ctx, state, s.server.ID) if err != nil { ui.Error(err.Error()) } diff --git a/builder/openstack/step_source_image_info.go b/builder/openstack/step_source_image_info.go index d2b41884..1f003d7f 100644 --- a/builder/openstack/step_source_image_info.go +++ b/builder/openstack/step_source_image_info.go @@ -9,9 +9,9 @@ import ( "log" "time" - "github.com/gophercloud/gophercloud/openstack/imageservice/v2/imageimport" - "github.com/gophercloud/gophercloud/openstack/imageservice/v2/images" - "github.com/gophercloud/gophercloud/pagination" + "github.com/gophercloud/gophercloud/v2/openstack/image/v2/imageimport" + "github.com/gophercloud/gophercloud/v2/openstack/image/v2/images" + "github.com/gophercloud/gophercloud/v2/pagination" "github.com/hashicorp/packer-plugin-sdk/multistep" packersdk "github.com/hashicorp/packer-plugin-sdk/packer" ) @@ -59,7 +59,7 @@ func (s *StepSourceImageInfo) Run(ctx context.Context, state multistep.StateBag) ui.Say("Creating image using external source image with name " + s.SourceImageName) ui.Say("Using disk format " + s.ExternalSourceImageFormat) - image, err := images.Create(client, createOpts).Extract() + image, err := images.Create(ctx, client, createOpts).Extract() if err != nil { err := fmt.Errorf("Error creating source image: %s", err) @@ -76,7 +76,7 @@ func (s *StepSourceImageInfo) Run(ctx context.Context, state multistep.StateBag) } ui.Say("Importing External Source Image from URL " + s.ExternalSourceImageURL) - err = imageimport.Create(client, image.ID, importOpts).ExtractErr() + err = imageimport.Create(ctx, client, image.ID, importOpts).ExtractErr() if err != nil { err := fmt.Errorf("Error importing source image: %s", err) @@ -89,7 +89,7 @@ func (s *StepSourceImageInfo) Run(ctx context.Context, state multistep.StateBag) ui.Say("Image not Active, retrying in 10 seconds") time.Sleep(10 * time.Second) - img, err := images.Get(client, image.ID).Extract() + img, err := images.Get(ctx, client, image.ID).Extract() if err != nil { err := fmt.Errorf("Error querying image: %s", err) @@ -119,7 +119,7 @@ func (s *StepSourceImageInfo) Run(ctx context.Context, state multistep.StateBag) log.Printf("Using Image Filters %+v", s.SourceImageOpts) image := &images.Image{} count := 0 - err = images.List(client, s.SourceImageOpts).EachPage(func(page pagination.Page) (bool, error) { + err = images.List(client, s.SourceImageOpts).EachPage(ctx, func(ctx context.Context, page pagination.Page) (bool, error) { imgs, err := images.ExtractImages(page) if err != nil { return false, err @@ -183,6 +183,7 @@ func (s *StepSourceImageInfo) Cleanup(state multistep.StateBag) { if s.ExternalSourceImageURL != "" { config := state.Get("config").(*Config) ui := state.Get("ui").(packersdk.Ui) + ctx := context.TODO() client, err := config.imageV2Client() if err != nil { @@ -193,7 +194,7 @@ func (s *StepSourceImageInfo) Cleanup(state multistep.StateBag) { } ui.Say(fmt.Sprintf("Deleting temporary external source image: %s ...", s.SourceImageName)) - err = images.Delete(client, s.SourceImage).ExtractErr() + err = images.Delete(ctx, client, s.SourceImage).ExtractErr() if err != nil { err := fmt.Errorf("error cleaning up external source image: %s", err) state.Put("error", err) diff --git a/builder/openstack/step_stop_server.go b/builder/openstack/step_stop_server.go index 67695d95..5882a6f7 100644 --- a/builder/openstack/step_stop_server.go +++ b/builder/openstack/step_stop_server.go @@ -7,10 +7,10 @@ import ( "context" "fmt" "log" + "net/http" - "github.com/gophercloud/gophercloud" - "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/startstop" - "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/openstack/compute/v2/servers" "github.com/hashicorp/packer-plugin-sdk/multistep" packersdk "github.com/hashicorp/packer-plugin-sdk/packer" ) @@ -31,8 +31,8 @@ func (s *StepStopServer) Run(ctx context.Context, state multistep.StateBag) mult } ui.Say(fmt.Sprintf("Stopping server: %s ...", server.ID)) - if err := startstop.Stop(client, server.ID).ExtractErr(); err != nil { - if _, ok := err.(gophercloud.ErrDefault409); ok { + if err := servers.Stop(ctx, client, server.ID).ExtractErr(); err != nil { + if gophercloud.ResponseCodeIs(err, http.StatusConflict) { // The server might have already been shut down by Windows Sysprep log.Printf("[WARN] 409 on stopping an already stopped server, continuing") return multistep.ActionContinue @@ -47,7 +47,7 @@ func (s *StepStopServer) Run(ctx context.Context, state multistep.StateBag) mult stateChange := StateChangeConf{ Pending: []string{"ACTIVE"}, Target: []string{"SHUTOFF", "STOPPED"}, - Refresh: ServerStateRefreshFunc(client, server.ID), + Refresh: ServerStateRefreshFunc(ctx, client, server.ID), StepState: state, } if _, err := WaitForState(&stateChange); err != nil { diff --git a/builder/openstack/step_update_image_mindisk.go b/builder/openstack/step_update_image_mindisk.go index 1fd1810b..ac57816b 100644 --- a/builder/openstack/step_update_image_mindisk.go +++ b/builder/openstack/step_update_image_mindisk.go @@ -7,14 +7,14 @@ import ( "context" "fmt" - "github.com/gophercloud/gophercloud/openstack/imageservice/v2/images" + "github.com/gophercloud/gophercloud/v2/openstack/image/v2/images" "github.com/hashicorp/packer-plugin-sdk/multistep" packersdk "github.com/hashicorp/packer-plugin-sdk/packer" ) type stepUpdateImageMinDisk struct{} -func (s *stepUpdateImageMinDisk) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *stepUpdateImageMinDisk) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packersdk.Ui) config := state.Get("config").(*Config) @@ -38,6 +38,7 @@ func (s *stepUpdateImageMinDisk) Run(_ context.Context, state multistep.StateBag ui.Say(fmt.Sprintf("Updating image min disk to %d", config.ImageMinDisk)) r := images.Update( + ctx, imageClient, imageId, images.UpdateOpts{ diff --git a/builder/openstack/step_update_image_tags.go b/builder/openstack/step_update_image_tags.go index 5eae5bc4..7feec90e 100644 --- a/builder/openstack/step_update_image_tags.go +++ b/builder/openstack/step_update_image_tags.go @@ -8,7 +8,7 @@ import ( "fmt" "strings" - imageservice "github.com/gophercloud/gophercloud/openstack/imageservice/v2/images" + imageservice "github.com/gophercloud/gophercloud/v2/openstack/image/v2/images" "github.com/hashicorp/packer-plugin-sdk/multistep" packersdk "github.com/hashicorp/packer-plugin-sdk/packer" ) @@ -38,6 +38,7 @@ func (s *stepUpdateImageTags) Run(ctx context.Context, state multistep.StateBag) ui.Say(fmt.Sprintf("Updating image tags to %s", strings.Join(config.ImageTags, ", "))) r := imageservice.Update( + ctx, imageClient, imageId, imageservice.UpdateOpts{ diff --git a/builder/openstack/step_update_image_visibility.go b/builder/openstack/step_update_image_visibility.go index 1c1d5eea..368141f9 100644 --- a/builder/openstack/step_update_image_visibility.go +++ b/builder/openstack/step_update_image_visibility.go @@ -7,7 +7,7 @@ import ( "context" "fmt" - imageservice "github.com/gophercloud/gophercloud/openstack/imageservice/v2/images" + imageservice "github.com/gophercloud/gophercloud/v2/openstack/image/v2/images" "github.com/hashicorp/packer-plugin-sdk/multistep" packersdk "github.com/hashicorp/packer-plugin-sdk/packer" ) @@ -37,6 +37,7 @@ func (s *stepUpdateImageVisibility) Run(ctx context.Context, state multistep.Sta ui.Say(fmt.Sprintf("Updating image visibility to %s", config.ImageVisibility)) r := imageservice.Update( + ctx, imageClient, imageId, imageservice.UpdateOpts{ diff --git a/builder/openstack/step_wait_for_rackconnect.go b/builder/openstack/step_wait_for_rackconnect.go index 18d2fb2b..3533561a 100644 --- a/builder/openstack/step_wait_for_rackconnect.go +++ b/builder/openstack/step_wait_for_rackconnect.go @@ -8,7 +8,7 @@ import ( "fmt" "time" - "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" + "github.com/gophercloud/gophercloud/v2/openstack/compute/v2/servers" "github.com/hashicorp/packer-plugin-sdk/multistep" packersdk "github.com/hashicorp/packer-plugin-sdk/packer" ) @@ -37,7 +37,7 @@ func (s *StepWaitForRackConnect) Run(ctx context.Context, state multistep.StateB ui.Say(fmt.Sprintf( "Waiting for server (%s) to become RackConnect ready...", server.ID)) for { - server, err = servers.Get(computeClient, server.ID).Extract() + server, err = servers.Get(ctx, computeClient, server.ID).Extract() if err != nil { return multistep.ActionHalt } diff --git a/builder/openstack/volume.go b/builder/openstack/volume.go index 197c050f..a162f7f7 100644 --- a/builder/openstack/volume.go +++ b/builder/openstack/volume.go @@ -4,22 +4,23 @@ package openstack import ( + "context" "errors" "log" "time" - "github.com/gophercloud/gophercloud" - "github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes" - "github.com/gophercloud/gophercloud/openstack/imageservice/v2/images" + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/openstack/blockstorage/v3/volumes" + "github.com/gophercloud/gophercloud/v2/openstack/image/v2/images" ) // WaitForVolume waits for the given volume to become available. -func WaitForVolume(blockStorageClient *gophercloud.ServiceClient, volumeID string) error { +func WaitForVolume(ctx context.Context, blockStorageClient *gophercloud.ServiceClient, volumeID string) error { maxNumErrors := 10 numErrors := 0 for { - status, err := GetVolumeStatus(blockStorageClient, volumeID) + status, err := GetVolumeStatus(ctx, blockStorageClient, volumeID) if err != nil { errCode, ok := err.(*gophercloud.ErrUnexpectedResponseCode) if ok && (errCode.Actual == 500 || errCode.Actual == 404) { @@ -52,8 +53,8 @@ func WaitForVolume(blockStorageClient *gophercloud.ServiceClient, volumeID strin // GetVolumeSize returns volume size in gigabytes based on the image min disk // value if it's not empty. // Or it calculates needed gigabytes size from the image bytes size. -func GetVolumeSize(imageClient *gophercloud.ServiceClient, imageID string) (int, error) { - sourceImage, err := images.Get(imageClient, imageID).Extract() +func GetVolumeSize(ctx context.Context, imageClient *gophercloud.ServiceClient, imageID string) (int, error) { + sourceImage, err := images.Get(ctx, imageClient, imageID).Extract() if err != nil { return 0, err } @@ -74,8 +75,8 @@ func GetVolumeSize(imageClient *gophercloud.ServiceClient, imageID string) (int, return volumeSizeGB, nil } -func GetVolumeStatus(blockStorageClient *gophercloud.ServiceClient, volumeID string) (string, error) { - volume, err := volumes.Get(blockStorageClient, volumeID).Extract() +func GetVolumeStatus(ctx context.Context, blockStorageClient *gophercloud.ServiceClient, volumeID string) (string, error) { + volume, err := volumes.Get(ctx, blockStorageClient, volumeID).Extract() if err != nil { return "", err } diff --git a/go.mod b/go.mod index 5699f4ff..9ef28d45 100644 --- a/go.mod +++ b/go.mod @@ -4,14 +4,14 @@ go 1.25.11 require ( github.com/google/uuid v1.6.0 - github.com/gophercloud/gophercloud v0.12.0 - github.com/gophercloud/utils v0.0.0-20200508015959-b0167b94122c + github.com/gophercloud/gophercloud/v2 v2.14.0 + github.com/gophercloud/utils/v2 v2.0.0-20260824073324-42b9474d09d4 github.com/hashicorp/go-cleanhttp v0.5.2 github.com/hashicorp/hcl/v2 v2.24.0 github.com/hashicorp/packer-plugin-sdk v0.6.10 github.com/mitchellh/mapstructure v1.5.0 github.com/zclconf/go-cty v1.16.3 - golang.org/x/crypto v0.53.0 + golang.org/x/crypto v0.55.0 gopkg.in/yaml.v2 v2.4.0 // indirect ) @@ -57,6 +57,7 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/gofrs/flock v0.8.1 // indirect github.com/gofrs/uuid v4.4.0+incompatible // indirect + github.com/gofrs/uuid/v5 v5.5.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/google/s2a-go v0.1.9 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect @@ -119,21 +120,22 @@ require ( go.opentelemetry.io/otel/metric v1.44.0 // indirect go.opentelemetry.io/otel/trace v1.44.0 // indirect golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect - golang.org/x/mod v0.37.0 // indirect - golang.org/x/net v0.56.0 // indirect + golang.org/x/mod v0.38.0 // indirect + golang.org/x/net v0.57.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect - golang.org/x/sync v0.21.0 // indirect - golang.org/x/sys v0.46.0 // indirect - golang.org/x/term v0.44.0 // indirect - golang.org/x/text v0.39.0 // indirect + golang.org/x/sync v0.22.0 // indirect + golang.org/x/sys v0.47.0 // indirect + golang.org/x/term v0.45.0 // indirect + golang.org/x/text v0.41.0 // indirect golang.org/x/time v0.11.0 // indirect - golang.org/x/tools v0.47.0 // indirect + golang.org/x/tools v0.48.0 // indirect google.golang.org/api v0.230.0 // indirect google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect google.golang.org/grpc v1.82.1 // indirect google.golang.org/protobuf v1.36.11 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) replace github.com/zclconf/go-cty => github.com/nywilken/go-cty v1.13.3 // added by packer-sdc fix as noted in github.com/hashicorp/packer-plugin-sdk/issues/187 diff --git a/go.sum b/go.sum index 4cec9646..50605e91 100644 --- a/go.sum +++ b/go.sum @@ -133,6 +133,8 @@ github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gofrs/uuid/v5 v5.5.1 h1:z1Ce19/JwNidXpy3tOQc3241lnJLKdKyq/xlNvlD4Ng= +github.com/gofrs/uuid/v5 v5.5.1/go.mod h1:bbAA98EoIlxyRHIVg6ektCSsZ5n8mSbwgEhvhMYlZgg= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -174,11 +176,10 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q= github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA= -github.com/gophercloud/gophercloud v0.6.1-0.20191122030953-d8ac278c1c9d/go.mod h1:ozGNgr9KYOVATV5jsgHl/ceCDXGuguqOZAzoQ/2vcNM= -github.com/gophercloud/gophercloud v0.12.0 h1:mZrie07npp6ODiwHZolTicr5jV8Ogn43AvAsSMm6Ork= -github.com/gophercloud/gophercloud v0.12.0/go.mod h1:gmC5oQqMDOMO1t1gq5DquX/yAU808e/4mzjjDA76+Ss= -github.com/gophercloud/utils v0.0.0-20200508015959-b0167b94122c h1:iawx2ojEQA7c+GmkaVO5sN+k8YONibXyDO8RlsC+1bs= -github.com/gophercloud/utils v0.0.0-20200508015959-b0167b94122c/go.mod h1:ehWUbLQJPqS0Ep+CxeD559hsm9pthPXadJNKwZkp43w= +github.com/gophercloud/gophercloud/v2 v2.14.0 h1:xGxKCvyaOxJDc5FqrnKDNqtdYn43ocQPuJ2Cm4KX/cs= +github.com/gophercloud/gophercloud/v2 v2.14.0/go.mod h1:4fs5I9VH6Wg2LyocDL9xf0ASb8VD63tyLA8sgAX/69U= +github.com/gophercloud/utils/v2 v2.0.0-20260824073324-42b9474d09d4 h1:VKbePn/0e1cg6HSvVB5CKeXpVcKmD2AuMk6WQhjexuI= +github.com/gophercloud/utils/v2 v2.0.0-20260824073324-42b9474d09d4/go.mod h1:z+yO4g4N0u8rJuWNPVcjZHVAlzAFapFNnMOtFIpqddM= github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI= @@ -431,13 +432,12 @@ go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUS golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= -golang.org/x/crypto v0.0.0-20191202143827-86a70503ff7e/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto= -golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio= +golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M= +golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= @@ -445,8 +445,8 @@ golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTk golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ= -golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0= +golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk= +golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -456,7 +456,6 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= @@ -465,8 +464,8 @@ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o= -golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec= +golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE= +golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= @@ -477,8 +476,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= -golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek= +golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -490,7 +489,6 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -510,21 +508,21 @@ golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw= -golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= +golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc= -golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y= +golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0= +golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= -golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= +golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8= +golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M= golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -534,12 +532,10 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191203134012-c197fd4bf371/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.47.0 h1:7Kn5x/d1svx/PzryTsqeoZN4TZwqeH5pGWjefhLi/1Q= -golang.org/x/tools v0.47.0/go.mod h1:dFHnyTvFWY212G+h7ZY4Vsp/K3U4/7W9TyVaAul8uCA= +golang.org/x/tools v0.48.0 h1:3+hClM1aLL5mjMKm5ovokw9epgRXPuu2tILgismM6RE= +golang.org/x/tools v0.48.0/go.mod h1:08xX0orndb/F7jJxGDicx061tyd5pcMto75YMAXr6lk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= @@ -585,7 +581,6 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=