Skip to content

Commit 2f68561

Browse files
committed
PowerVC: Allow bootstrap ignition upload to Swift
PowerVC does not mirror glance images across the HA cluster. So use Swift to host the bootstrap's ignition file.
1 parent 6dc2e83 commit 2f68561

File tree

2 files changed

+100
-34
lines changed

2 files changed

+100
-34
lines changed

pkg/infrastructure/openstack/clusterapi/clusterapi.go

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,14 @@ func (p Provider) PreProvision(ctx context.Context, in clusterapi.PreProvisionIn
5555
return fmt.Errorf("failed to tag VIP ports: %w", err)
5656
}
5757

58-
// upload the corresponding image to Glance if rhcosImage contains a
59-
// URL. If rhcosImage contains a name, then that points to an existing
60-
// Glance image.
61-
if imageName, isURL := rhcos.GenerateOpenStackImageName(rhcosImage, infraID); isURL {
62-
if err := preprovision.UploadBaseImage(ctx, installConfig.Config.Platform.OpenStack.Cloud, rhcosImage, imageName, infraID, installConfig.Config.Platform.OpenStack.ClusterOSImageProperties); err != nil {
63-
return fmt.Errorf("failed to upload the RHCOS base image: %w", err)
58+
if installConfig.Config.Platform.Name() != powervc.Name {
59+
// upload the corresponding image to Glance if rhcosImage contains a
60+
// URL. If rhcosImage contains a name, then that points to an existing
61+
// Glance image.
62+
if imageName, isURL := rhcos.GenerateOpenStackImageName(rhcosImage, infraID); isURL {
63+
if err := preprovision.UploadBaseImage(ctx, installConfig.Config.Platform.OpenStack.Cloud, rhcosImage, imageName, infraID, installConfig.Config.Platform.OpenStack.ClusterOSImageProperties); err != nil {
64+
return fmt.Errorf("failed to upload the RHCOS base image: %w", err)
65+
}
6466
}
6567
}
6668

@@ -143,7 +145,9 @@ func (p Provider) Ignition(ctx context.Context, in clusterapi.IgnitionInput) ([]
143145
installConfig = in.InstallConfig
144146
)
145147

146-
ignShim, err := preprovision.UploadIgnitionAndBuildShim(ctx, installConfig.Config.Platform.OpenStack.Cloud, infraID, installConfig.Config.Proxy, bootstrapIgnData)
148+
useGlance := installConfig.Config.Platform.Name() == openstack.Name
149+
150+
ignShim, err := preprovision.UploadIgnitionAndBuildShim(ctx, installConfig.Config.Platform.OpenStack.Cloud, infraID, installConfig.Config.Proxy, bootstrapIgnData, useGlance)
147151
if err != nil {
148152
return nil, fmt.Errorf("failed to upload and build ignition shim: %w", err)
149153
}

pkg/infrastructure/openstack/preprovision/bootstrapignition.go

Lines changed: 89 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)