Skip to content

Commit fcfc641

Browse files
committed
Update openstack module to use gophercloud v2
Migrate internal dependency from gophercloud v1.14.1 to v2.8.0. Changes: - Updated go.mod to use github.com/gophercloud/gophercloud/v2 v2.8.0 - Updated internal import paths to include /v2 suffix - Fixed blockstorage services import path from blockstorage/extensions/services to blockstorage/v2/services Adds proper context propagation by adding ctx context.Context as the first parameter to all public functions in the openstack module. This change enables better context propagation for cancellation, deadlines, and request-scoped values throughout the OpenStack client operations. Breaking Change: All callers of these functions must now pass a context.Context as the first parameter. Jira: OSPRH-18162 AssistedBy: cloude-4-sonnet Signed-off-by: Martin Schuppert <[email protected]>
1 parent b5208bc commit fcfc641

File tree

11 files changed

+99
-67
lines changed

11 files changed

+99
-67
lines changed

modules/openstack/domain.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
package openstack
22

33
import (
4+
"context"
45
"fmt"
56

67
"github.com/go-logr/logr"
7-
"github.com/gophercloud/gophercloud/openstack/identity/v3/domains"
8+
"github.com/gophercloud/gophercloud/v2/openstack/identity/v3/domains"
89
)
910

1011
// Domain - Holds the name and description to be used while creating or looking up the OpenStack domain.
@@ -14,9 +15,9 @@ type Domain struct {
1415
}
1516

1617
// CreateDomain - creates a domain with domainName and domainDescription if it does not exist
17-
func (o *OpenStack) CreateDomain(log logr.Logger, d Domain) (string, error) {
18+
func (o *OpenStack) CreateDomain(ctx context.Context, log logr.Logger, d Domain) (string, error) {
1819
var domainID string
19-
allPages, err := domains.List(o.osclient, domains.ListOpts{Name: d.Name}).AllPages()
20+
allPages, err := domains.List(o.osclient, domains.ListOpts{Name: d.Name}).AllPages(ctx)
2021
if err != nil {
2122
return domainID, err
2223
}
@@ -32,7 +33,7 @@ func (o *OpenStack) CreateDomain(log logr.Logger, d Domain) (string, error) {
3233
Description: d.Description,
3334
}
3435
log.Info(fmt.Sprintf("Creating domain %s", d.Name))
35-
domain, err := domains.Create(o.osclient, createOpts).Extract()
36+
domain, err := domains.Create(ctx, o.osclient, createOpts).Extract()
3637
if err != nil {
3738
return domainID, err
3839
}

modules/openstack/endpoint.go

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@ limitations under the License.
1717
package openstack
1818

1919
import (
20+
"context"
2021
"fmt"
2122

2223
"github.com/go-logr/logr"
23-
gophercloud "github.com/gophercloud/gophercloud"
24-
endpoints "github.com/gophercloud/gophercloud/openstack/identity/v3/endpoints"
24+
gophercloud "github.com/gophercloud/gophercloud/v2"
25+
endpoints "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/endpoints"
2526
)
2627

2728
// Endpoint -
@@ -34,12 +35,13 @@ type Endpoint struct {
3435

3536
// CreateEndpoint - create endpoint
3637
func (o *OpenStack) CreateEndpoint(
38+
ctx context.Context,
3739
log logr.Logger,
3840
e Endpoint,
3941
) (string, error) {
40-
4142
// validate if endpoint already exist
4243
allEndpoints, err := o.GetEndpoints(
44+
ctx,
4345
log,
4446
e.ServiceID,
4547
string(e.Availability))
@@ -59,7 +61,7 @@ func (o *OpenStack) CreateEndpoint(
5961
ServiceID: e.ServiceID,
6062
URL: e.URL,
6163
}
62-
createdEndpoint, err := endpoints.Create(o.osclient, createOpts).Extract()
64+
createdEndpoint, err := endpoints.Create(ctx, o.osclient, createOpts).Extract()
6365
if err != nil {
6466
return "", err
6567
}
@@ -69,6 +71,7 @@ func (o *OpenStack) CreateEndpoint(
6971
// GetEndpoints - get endpoints for the registered service. if endpointInterface
7072
// is provided, just return the endpoint for that type.
7173
func (o *OpenStack) GetEndpoints(
74+
ctx context.Context,
7275
log logr.Logger,
7376
serviceID string,
7477
endpointInterface string,
@@ -88,7 +91,7 @@ func (o *OpenStack) GetEndpoints(
8891
listOpts.Availability = availability
8992
}
9093

91-
allPages, err := endpoints.List(o.osclient, listOpts).AllPages()
94+
allPages, err := endpoints.List(o.osclient, listOpts).AllPages(ctx)
9295
if err != nil {
9396
return nil, err
9497
}
@@ -104,19 +107,20 @@ func (o *OpenStack) GetEndpoints(
104107

105108
// DeleteEndpoint - delete endpoint
106109
func (o *OpenStack) DeleteEndpoint(
110+
ctx context.Context,
107111
log logr.Logger,
108112
e Endpoint,
109113
) error {
110114
log.Info(fmt.Sprintf("Deleting Endpoint %s %s ", e.Name, e.Availability))
111115

112116
// get all registered endpoints for the service/endpointInterface
113-
allEndpoints, err := o.GetEndpoints(log, e.ServiceID, string(e.Availability))
117+
allEndpoints, err := o.GetEndpoints(ctx, log, e.ServiceID, string(e.Availability))
114118
if err != nil {
115119
return err
116120
}
117121

118122
for _, endpt := range allEndpoints {
119-
err = endpoints.Delete(o.osclient, endpt.ID).ExtractErr()
123+
err = endpoints.Delete(ctx, o.osclient, endpt.ID).ExtractErr()
120124
if err != nil {
121125
return err
122126
}
@@ -129,6 +133,7 @@ func (o *OpenStack) DeleteEndpoint(
129133

130134
// UpdateEndpoint -
131135
func (o *OpenStack) UpdateEndpoint(
136+
ctx context.Context,
132137
log logr.Logger,
133138
e Endpoint,
134139
endpointID string,
@@ -143,7 +148,7 @@ func (o *OpenStack) UpdateEndpoint(
143148
ServiceID: e.ServiceID,
144149
URL: e.URL,
145150
}
146-
endpt, err := endpoints.Update(o.osclient, endpointID, updateOpts).Extract()
151+
endpt, err := endpoints.Update(ctx, o.osclient, endpointID, updateOpts).Extract()
147152
if err != nil {
148153
return "", err
149154
}

modules/openstack/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ go 1.24.4
44

55
require (
66
github.com/go-logr/logr v1.4.3
7-
github.com/gophercloud/gophercloud v1.14.1
7+
github.com/gophercloud/gophercloud/v2 v2.8.0
88
github.com/openstack-k8s-operators/lib-common/modules/common v0.3.1-0.20240122120141-2eff3281aef1
99
)
1010

modules/openstack/go.sum

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J
4848
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
4949
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
5050
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
51-
github.com/gophercloud/gophercloud v1.14.1 h1:DTCNaTVGl8/cFu58O1JwWgis9gtISAFONqpMKNg/Vpw=
52-
github.com/gophercloud/gophercloud v1.14.1/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM=
51+
github.com/gophercloud/gophercloud/v2 v2.8.0 h1:of2+8tT6+FbEYHfYC8GBu8TXJNsXYSNm9KuvpX7Neqo=
52+
github.com/gophercloud/gophercloud/v2 v2.8.0/go.mod h1:Ki/ILhYZr/5EPebrPL9Ej+tUg4lqx71/YH2JWVeU+Qk=
5353
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
5454
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
5555
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
@@ -117,7 +117,6 @@ go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
117117
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
118118
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
119119
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
120-
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
121120
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
122121
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
123122
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
@@ -128,7 +127,6 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
128127
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
129128
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
130129
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
131-
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
132130
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
133131
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
134132
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
@@ -141,17 +139,12 @@ golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
141139
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
142140
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
143141
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
144-
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
145-
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
146-
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
147142
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
148143
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
149-
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
150144
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
151145
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
152146
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
153147
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
154-
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
155148
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
156149
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
157150
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=

modules/openstack/limits.go

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@ limitations under the License.
1717
package openstack
1818

1919
import (
20+
"context"
2021
"fmt"
2122

2223
"github.com/go-logr/logr"
23-
limits "github.com/gophercloud/gophercloud/openstack/identity/v3/limits"
24-
registeredlimits "github.com/gophercloud/gophercloud/openstack/identity/v3/registeredlimits"
24+
limits "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/limits"
25+
registeredlimits "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/registeredlimits"
2526
)
2627

2728
// Limit -
@@ -50,12 +51,13 @@ type Limit struct {
5051

5152
// CreateLimit - create a limit in keystone for particular project if it does not exist
5253
func (o *OpenStack) CreateLimit(
54+
ctx context.Context,
5355
log logr.Logger,
5456
l Limit,
5557
) (string, error) {
5658
var limitID string
5759

58-
allPages, err := limits.List(o.osclient, limits.ListOpts{ResourceName: l.ResourceName}).AllPages()
60+
allPages, err := limits.List(o.osclient, limits.ListOpts{ResourceName: l.ResourceName}).AllPages(ctx)
5961
if err != nil {
6062
return limitID, err
6163
}
@@ -80,7 +82,7 @@ func (o *OpenStack) CreateLimit(
8082
},
8183
}
8284
log.Info(fmt.Sprintf("Creating limit %s", l.ResourceName))
83-
createdLimits, err := limits.BatchCreate(o.osclient, createOpts).Extract()
85+
createdLimits, err := limits.BatchCreate(ctx, o.osclient, createOpts).Extract()
8486
if err != nil {
8587
return limitID, err
8688
}
@@ -112,12 +114,13 @@ type RegisteredLimit struct {
112114

113115
// CreateOrUpdateRegisteredLimit - create or update limit in keystone (global across projects) if it does not exist
114116
func (o *OpenStack) CreateOrUpdateRegisteredLimit(
117+
ctx context.Context,
115118
log logr.Logger,
116119
l RegisteredLimit,
117120
) (string, error) {
118121
var limitID string
119122

120-
allPages, err := registeredlimits.List(o.osclient, registeredlimits.ListOpts{ResourceName: l.ResourceName}).AllPages()
123+
allPages, err := registeredlimits.List(o.osclient, registeredlimits.ListOpts{ResourceName: l.ResourceName}).AllPages(ctx)
121124
if err != nil {
122125
return limitID, err
123126
}
@@ -134,7 +137,7 @@ func (o *OpenStack) CreateOrUpdateRegisteredLimit(
134137
DefaultLimit: &l.DefaultLimit,
135138
}
136139
log.Info(fmt.Sprintf("Updating registered limit %s", l.ResourceName))
137-
_, err := registeredlimits.Update(o.osclient, limitID, updateOpts).Extract()
140+
_, err := registeredlimits.Update(ctx, o.osclient, limitID, updateOpts).Extract()
138141
if err != nil {
139142
return limitID, err
140143
}
@@ -150,7 +153,7 @@ func (o *OpenStack) CreateOrUpdateRegisteredLimit(
150153
},
151154
}
152155
log.Info(fmt.Sprintf("Creating registered limit %s", l.ResourceName))
153-
createdLimits, err := registeredlimits.BatchCreate(o.osclient, createOpts).Extract()
156+
createdLimits, err := registeredlimits.BatchCreate(ctx, o.osclient, createOpts).Extract()
154157
if err != nil {
155158
return limitID, err
156159
}
@@ -164,11 +167,12 @@ func (o *OpenStack) CreateOrUpdateRegisteredLimit(
164167

165168
// DeleteRegisteredLimit - delete limit from keystone
166169
func (o *OpenStack) DeleteRegisteredLimit(
170+
ctx context.Context,
167171
log logr.Logger,
168172
registeredLimitID string,
169173
) error {
170174
log.Info(fmt.Sprintf("Deleting registered limit %s", registeredLimitID))
171-
err := registeredlimits.Delete(o.osclient, registeredLimitID).ExtractErr()
175+
err := registeredlimits.Delete(ctx, o.osclient, registeredLimitID).ExtractErr()
172176
if err != nil {
173177
return err
174178
}
@@ -177,11 +181,12 @@ func (o *OpenStack) DeleteRegisteredLimit(
177181

178182
// GetRegisteredLimit - Get existing registered limit by ID
179183
func (o *OpenStack) GetRegisteredLimit(
184+
ctx context.Context,
180185
log logr.Logger,
181186
registeredLimitID string,
182187
) (*registeredlimits.RegisteredLimit, error) {
183188
log.Info(fmt.Sprintf("Fetching registered limit %s", registeredLimitID))
184-
registeredLimit, err := registeredlimits.Get(o.osclient, registeredLimitID).Extract()
189+
registeredLimit, err := registeredlimits.Get(ctx, o.osclient, registeredLimitID).Extract()
185190
if err != nil {
186191
return nil, err
187192
}
@@ -190,6 +195,7 @@ func (o *OpenStack) GetRegisteredLimit(
190195

191196
// ListRegisteredLimitsByResourceName - List all registered limits filtered by resource name
192197
func (o *OpenStack) ListRegisteredLimitsByResourceName(
198+
ctx context.Context,
193199
log logr.Logger,
194200
resourceName string,
195201
) ([]registeredlimits.RegisteredLimit, error) {
@@ -198,7 +204,7 @@ func (o *OpenStack) ListRegisteredLimitsByResourceName(
198204
}
199205

200206
log.Info(fmt.Sprintf("Fetching registered limit %s", resourceName))
201-
allPages, err := registeredlimits.List(o.osclient, listOpts).AllPages()
207+
allPages, err := registeredlimits.List(o.osclient, listOpts).AllPages(ctx)
202208
if err != nil {
203209
return nil, err
204210
}
@@ -212,6 +218,7 @@ func (o *OpenStack) ListRegisteredLimitsByResourceName(
212218

213219
// ListRegisteredLimitsByServiceID - List all registered limits filtered by service id
214220
func (o *OpenStack) ListRegisteredLimitsByServiceID(
221+
ctx context.Context,
215222
log logr.Logger,
216223
serviceID string,
217224
) ([]registeredlimits.RegisteredLimit, error) {
@@ -220,7 +227,7 @@ func (o *OpenStack) ListRegisteredLimitsByServiceID(
220227
}
221228

222229
log.Info(fmt.Sprintf("Fetching registered limit for service %s", serviceID))
223-
allPages, err := registeredlimits.List(o.osclient, listOpts).AllPages()
230+
allPages, err := registeredlimits.List(o.osclient, listOpts).AllPages(ctx)
224231
if err != nil {
225232
return nil, err
226233
}

modules/openstack/openstack.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,16 @@ limitations under the License.
1717
package openstack
1818

1919
import (
20+
"context"
2021
"crypto/tls"
2122
"crypto/x509"
2223
"fmt"
2324
"net/http"
2425
"time"
2526

2627
"github.com/go-logr/logr"
27-
gophercloud "github.com/gophercloud/gophercloud"
28-
"github.com/gophercloud/gophercloud/openstack"
28+
gophercloud "github.com/gophercloud/gophercloud/v2"
29+
"github.com/gophercloud/gophercloud/v2/openstack"
2930
service "github.com/openstack-k8s-operators/lib-common/modules/common/service"
3031
)
3132

@@ -64,6 +65,7 @@ type TLSConfig struct {
6465

6566
// GetOpenStackProvider creates a new instance of the openstack struct from a config struct
6667
func GetOpenStackProvider(
68+
ctx context.Context,
6769
cfg AuthOpts,
6870
) (*gophercloud.ProviderClient, error) {
6971
opts := gophercloud.AuthOptions{
@@ -122,7 +124,7 @@ func GetOpenStackProvider(
122124
providerClient.HTTPClient.Transport = transport
123125

124126
// authenticate the client
125-
err = openstack.Authenticate(providerClient, opts)
127+
err = openstack.Authenticate(ctx, providerClient, opts)
126128
if err != nil {
127129
return nil, err
128130
}
@@ -132,12 +134,12 @@ func GetOpenStackProvider(
132134

133135
// GetNovaOpenStackClient creates a new instance of the openstack compute struct from a config struct
134136
func GetNovaOpenStackClient(
137+
ctx context.Context,
135138
log logr.Logger,
136139
cfg AuthOpts,
137140
endpointOpts gophercloud.EndpointOpts,
138141
) (*OpenStack, error) {
139-
140-
providerClient, err := GetOpenStackProvider(cfg)
142+
providerClient, err := GetOpenStackProvider(ctx, cfg)
141143
if err != nil {
142144
return nil, err
143145
}
@@ -157,11 +159,11 @@ func GetNovaOpenStackClient(
157159

158160
// NewOpenStack creates a new instance of the openstack identity struct from a config struct
159161
func NewOpenStack(
162+
ctx context.Context,
160163
log logr.Logger,
161164
cfg AuthOpts,
162165
) (*OpenStack, error) {
163-
164-
providerClient, err := GetOpenStackProvider(cfg)
166+
providerClient, err := GetOpenStackProvider(ctx, cfg)
165167
if err != nil {
166168
return nil, err
167169
}

0 commit comments

Comments
 (0)