@@ -16,6 +16,8 @@ import (
1616 "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/tokens"
1717 "github.com/gophercloud/gophercloud/v2/openstack/image/v2/imagedata"
1818 "github.com/gophercloud/gophercloud/v2/openstack/image/v2/images"
19+ "github.com/gophercloud/gophercloud/v2/openstack/objectstorage/v1/containers"
20+ "github.com/gophercloud/gophercloud/v2/openstack/objectstorage/v1/objects"
1921 "github.com/gophercloud/utils/v2/openstack/clientconfig"
2022 "github.com/sirupsen/logrus"
2123 "github.com/vincent-petithory/dataurl"
@@ -25,6 +27,7 @@ import (
2527 "github.com/openshift/installer/pkg/asset/ignition"
2628 "github.com/openshift/installer/pkg/asset/installconfig"
2729 "github.com/openshift/installer/pkg/types"
30+ openstacktypes "github.com/openshift/installer/pkg/types/openstack"
2831 openstackdefaults "github.com/openshift/installer/pkg/types/openstack/defaults"
2932)
3033
@@ -49,8 +52,9 @@ func ReplaceBootstrapIgnitionInTFVars(ctx context.Context, tfvarsFile *asset.Fil
4952 return fmt .Errorf ("failed to decode bootstrap's Ignition" )
5053 }
5154
52- logrus .Debugf ("Uploading Ignition to Glance" )
53- bootstrapShim , err := UploadIgnitionAndBuildShim (ctx , installConfig .Config .Platform .OpenStack .Cloud , clusterID .InfraID , installConfig .Config .Proxy , []byte (bootstrapIgnition ))
55+ useGlance := installConfig .Config .Platform .Name () == openstacktypes .Name
56+
57+ bootstrapShim , err := UploadIgnitionAndBuildShim (ctx , installConfig .Config .Platform .OpenStack .Cloud , clusterID .InfraID , installConfig .Config .Proxy , []byte (bootstrapIgnition ), useGlance )
5458 if err != nil {
5559 return fmt .Errorf ("failed to build bootstrap's Ignition shim: %w" , err )
5660 }
@@ -72,11 +76,29 @@ func ReplaceBootstrapIgnitionInTFVars(ctx context.Context, tfvarsFile *asset.Fil
7276}
7377
7478// UploadIgnitionAndBuildShim uploads the bootstrap Ignition config in Glance.
75- func UploadIgnitionAndBuildShim (ctx context.Context , cloud string , infraID string , proxy * types.Proxy , bootstrapIgn []byte ) ([]byte , error ) {
76- opts := openstackdefaults .DefaultClientOpts (cloud )
77- conn , err := openstackdefaults .NewServiceClient (ctx , "image" , opts )
78- if err != nil {
79- return nil , err
79+ func UploadIgnitionAndBuildShim (ctx context.Context , cloud string , infraID string , proxy * types.Proxy , bootstrapIgn []byte , useGlance bool ) ([]byte , error ) {
80+ var (
81+ opts * clientconfig.ClientOpts
82+ conn * gophercloud.ServiceClient
83+ err error
84+ )
85+
86+ if useGlance {
87+ logrus .Debugf ("Uploading Ignition to Glance" )
88+
89+ opts = openstackdefaults .DefaultClientOpts (cloud )
90+ conn , err = openstackdefaults .NewServiceClient (ctx , "image" , opts )
91+ if err != nil {
92+ return nil , err
93+ }
94+ } else {
95+ logrus .Debugf ("Uploading Ignition to Swift" )
96+
97+ opts = openstackdefaults .DefaultClientOpts (cloud )
98+ conn , err = openstackdefaults .NewServiceClient (ctx , "object-store" , opts )
99+ if err != nil {
100+ return nil , err
101+ }
80102 }
81103
82104 var userCA []byte
@@ -102,6 +124,7 @@ func UploadIgnitionAndBuildShim(ctx context.Context, cloud string, infraID strin
102124 // https://docs.openstack.org/api-ref/identity/v3/?expanded=token-authentication-with-scoped-authorization-detail#token-authentication-with-scoped-authorization
103125 // Unfortunately this feature is not currently supported by Terraform, so we had to implement it here.
104126 var glancePublicURL string
127+ var swiftPublicURL string
105128 {
106129 // Authenticate in OpenStack, get the token and extract the service catalog
107130 var serviceCatalog * tokens.ServiceCatalog
@@ -122,34 +145,73 @@ func UploadIgnitionAndBuildShim(ctx context.Context, cloud string, infraID strin
122145 if err != nil {
123146 return nil , err
124147 }
125- glancePublicURL , err = gophercloud_openstack .V3EndpointURL (serviceCatalog , gophercloud.EndpointOpts {
126- Type : "image" ,
127- Availability : gophercloud .AvailabilityPublic ,
128- Region : clientConfigCloud .RegionName ,
129- })
130- if err != nil {
131- return nil , fmt .Errorf ("cannot retrieve Glance URL from the service catalog: %w" , err )
148+ if useGlance {
149+ glancePublicURL , err = gophercloud_openstack .V3EndpointURL (serviceCatalog , gophercloud.EndpointOpts {
150+ Type : "image" ,
151+ Availability : gophercloud .AvailabilityPublic ,
152+ Region : clientConfigCloud .RegionName ,
153+ })
154+ if err != nil {
155+ return nil , fmt .Errorf ("cannot retrieve Glance URL from the service catalog: %w" , err )
156+ }
157+ } else {
158+ swiftPublicURL , err = gophercloud_openstack .V3EndpointURL (serviceCatalog , gophercloud.EndpointOpts {
159+ Type : "object-store" ,
160+ Availability : gophercloud .AvailabilityPublic ,
161+ Region : clientConfigCloud .RegionName ,
162+ })
163+ if err != nil {
164+ return nil , fmt .Errorf ("cannot retrieve Swift URL from the service catalog: %w" , err )
165+ }
132166 }
133167 }
134168
135169 // upload the bootstrap Ignition config in Glance and save its location
136170 var bootstrapConfigURL string
137171 {
138- img , err := images .Create (ctx , conn , images.CreateOpts {
139- Name : infraID + "-ignition" ,
140- ContainerFormat : "bare" ,
141- DiskFormat : "raw" ,
142- Tags : []string {"openshiftClusterID=" + infraID },
143- }).Extract ()
144- if err != nil {
145- return nil , fmt .Errorf ("unable to create a Glance image for the bootstrap server's Ignition file: %w" , err )
146- }
172+ if useGlance {
173+ img , err := images .Create (ctx , conn , images.CreateOpts {
174+ Name : infraID + "-ignition" ,
175+ ContainerFormat : "bare" ,
176+ DiskFormat : "raw" ,
177+ Tags : []string {"openshiftClusterID=" + infraID },
178+ }).Extract ()
179+ if err != nil {
180+ return nil , fmt .Errorf ("unable to create a Glance image for the bootstrap server's Ignition file: %w" , err )
181+ }
147182
148- if res := imagedata .Upload (ctx , conn , img .ID , bytes .NewReader (bootstrapIgn )); res .Err != nil {
149- return nil , fmt .Errorf ("unable to upload a Glance image for the bootstrap server's Ignition file: %w" , res .Err )
150- }
183+ if res := imagedata .Upload (ctx , conn , img .ID , bytes .NewReader (bootstrapIgn )); res .Err != nil {
184+ return nil , fmt .Errorf ("unable to upload a Glance image for the bootstrap server's Ignition file: %w" , res .Err )
185+ }
186+
187+ bootstrapConfigURL = glancePublicURL + img .File
188+ } else {
189+ name := infraID + "-ignition"
151190
152- bootstrapConfigURL = glancePublicURL + img .File
191+ _ , err = containers .Create (ctx ,
192+ conn ,
193+ name , // container name
194+ containers.CreateOpts {
195+ ContentType : "text/plain" ,
196+ }).Extract ()
197+ if err != nil {
198+ return nil , fmt .Errorf ("unable to create a Swift container for the bootstrap server's Ignition file: %w" , err )
199+ }
200+
201+ _ , err = objects .Create (ctx ,
202+ conn ,
203+ name , // container name
204+ name , // object name
205+ objects.CreateOpts {
206+ ContentType : "text/plain" ,
207+ Content : strings .NewReader (string (bootstrapIgn )),
208+ }).Extract ()
209+ if err != nil {
210+ return nil , fmt .Errorf ("unable to create a Swift image for the bootstrap server's Ignition file: %w" , err )
211+ }
212+
213+ bootstrapConfigURL = fmt .Sprintf ("%s%s/%s" , swiftPublicURL , name , name )
214+ }
153215 }
154216
155217 // To allow Ignition to download its config on the bootstrap machine from a location secured by a
0 commit comments