Skip to content

Commit 55f73e2

Browse files
committed
Azure: Ignite bootstrap machine
https://issues.redhat.com/browse/CORS-3269 (cherry picked from commit 297cde87e3bbc8248cb18bb3e7183cda425d9407)
1 parent d0ecb46 commit 55f73e2

File tree

3 files changed

+123
-6
lines changed

3 files changed

+123
-6
lines changed

pkg/infrastructure/azure/azure.go

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ type Provider struct {
4343
var _ clusterapi.PreProvider = (*Provider)(nil)
4444
var _ clusterapi.InfraReadyProvider = (*Provider)(nil)
4545
var _ clusterapi.PostProvider = (*Provider)(nil)
46+
var _ clusterapi.IgnitionProvider = (*Provider)(nil)
4647

4748
// Name returns the name of the provider.
4849
func (p *Provider) Name() string {
@@ -69,6 +70,7 @@ func (p *Provider) PreProvision(ctx context.Context, in clusterapi.PreProvisionI
6970
for k, v := range userTags {
7071
tags[k] = ptr.To(v)
7172
}
73+
p.Tags = tags
7274

7375
// Create resource group
7476
resourcesClientFactory, err := armresources.NewClientFactory(
@@ -98,9 +100,7 @@ func (p *Provider) PreProvision(ctx context.Context, in clusterapi.PreProvisionI
98100
return fmt.Errorf("error creating resource group %s: %w", resourceGroupName, err)
99101
}
100102
logrus.Debugf("ResourceGroup.ID=%s", *resourceGroup.ID)
101-
102103
p.ResourceGroupName = resourceGroupName
103-
p.Tags = tags
104104

105105
return nil
106106
}
@@ -116,9 +116,8 @@ func (p *Provider) InfraReady(ctx context.Context, in clusterapi.InfraReadyInput
116116
platform := installConfig.Platform.Azure
117117
subscriptionID := session.Credentials.SubscriptionID
118118
cloudConfiguration := session.CloudConfig
119-
resourceGroupName := p.ResourceGroupName
120-
tags := p.Tags
121119

120+
resourceGroupName := p.ResourceGroupName
122121
storageAccountName := fmt.Sprintf("cluster%s", randomString(5))
123122
containerName := "vhd"
124123
blobName := fmt.Sprintf("rhcos%s.vhd", randomString(5))
@@ -155,6 +154,13 @@ func (p *Provider) InfraReady(ctx context.Context, in clusterapi.InfraReadyInput
155154
return fmt.Errorf("image length is not alisnged on a 512 byte boundary")
156155
}
157156

157+
userTags := platform.UserTags
158+
tags := make(map[string]*string, len(userTags)+1)
159+
tags[fmt.Sprintf("kubernetes.io_cluster.%s", in.InfraID)] = ptr.To("owned")
160+
for k, v := range userTags {
161+
tags[k] = ptr.To(v)
162+
}
163+
158164
tokenCredential := session.TokenCreds
159165
storageURL := fmt.Sprintf("https://%s.blob.core.windows.net", storageAccountName)
160166
blobURL := fmt.Sprintf("%s/%s/%s", storageURL, containerName, blobName)
@@ -470,3 +476,51 @@ func randomString(length int) string {
470476

471477
return string(s)
472478
}
479+
480+
// Ignition provisions the Azure container that holds the bootstrap ignition
481+
// file.
482+
func (p Provider) Ignition(ctx context.Context, in clusterapi.IgnitionInput) ([]byte, error) {
483+
session, err := in.InstallConfig.Azure.Session()
484+
if err != nil {
485+
return nil, fmt.Errorf("failed to get session: %w", err)
486+
}
487+
488+
bootstrapIgnData := in.BootstrapIgnData
489+
subscriptionID := session.Credentials.SubscriptionID
490+
cloudConfiguration := session.CloudConfig
491+
492+
ignitionContainerName := "ignition"
493+
blobName := "bootstrap.ign"
494+
blobURL := fmt.Sprintf("%s/%s/%s", p.StorageURL, ignitionContainerName, blobName)
495+
496+
// Create ignition blob storage container
497+
createBlobContainerOutput, err := CreateBlobContainer(ctx, &CreateBlobContainerInput{
498+
ContainerName: ignitionContainerName,
499+
SubscriptionID: subscriptionID,
500+
ResourceGroupName: p.ResourceGroupName,
501+
StorageAccountName: p.StorageAccountName,
502+
StorageClientFactory: p.StorageClientFactory,
503+
})
504+
if err != nil {
505+
return nil, err
506+
}
507+
508+
blobIgnitionContainer := createBlobContainerOutput.BlobContainer
509+
logrus.Debugf("BlobIgnitionContainer.ID=%s", *blobIgnitionContainer.ID)
510+
511+
_, err = CreateBlockBlob(ctx, &CreateBlockBlobInput{
512+
StorageURL: p.StorageURL,
513+
BlobURL: blobURL,
514+
StorageAccountName: p.StorageAccountName,
515+
StorageAccountKeys: p.StorageAccountKeys,
516+
CloudConfiguration: cloudConfiguration,
517+
BootstrapIgnData: bootstrapIgnData,
518+
})
519+
if err != nil {
520+
return nil, err
521+
}
522+
523+
// XXX access it as SAS
524+
525+
return []byte{}, nil
526+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package azure

pkg/infrastructure/azure/storage.go

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package azure
22

33
import (
4+
"bytes"
45
"context"
56
"fmt"
67
"sync"
@@ -9,9 +10,12 @@ import (
910
"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
1011
"github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
1112
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
13+
"github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming"
1214
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
1315
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage"
1416
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
17+
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blob"
18+
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blockblob"
1519
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/pageblob"
1620
"github.com/sirupsen/logrus"
1721

@@ -181,15 +185,15 @@ type CreatePageBlobOutput struct {
181185

182186
// CreatePageBlob creates a blob and uploads a file from a URL to it.
183187
func CreatePageBlob(ctx context.Context, in *CreatePageBlobInput) (*CreatePageBlobOutput, error) {
184-
logrus.Debugf("Getting blob credentials")
188+
logrus.Debugf("Getting page blob credentials")
185189

186190
// XXX: Should try all of them until one is successful
187191
sharedKeyCredential, err := azblob.NewSharedKeyCredential(in.StorageAccountName, *in.StorageAccountKeys[0].Value)
188192
if err != nil {
189193
return nil, fmt.Errorf("failed to get shared crdentials for storage account: %w", err)
190194
}
191195

192-
logrus.Debugf("Getting blob client")
196+
logrus.Debugf("Getting page blob client")
193197
pageBlobClient, err := pageblob.NewClientWithSharedKeyCredential(
194198
in.BlobURL,
195199
sharedKeyCredential,
@@ -318,3 +322,61 @@ func doUploadPagesFromURL(ctx context.Context, pageBlobClient *pageblob.Client,
318322
logrus.Debugf("Done uploading")
319323
return res
320324
}
325+
326+
// CreateBlockBlobInput containers the input parameters used for creating a
327+
// block blob.
328+
type CreateBlockBlobInput struct {
329+
StorageURL string
330+
BlobURL string
331+
//ImageURL string
332+
StorageAccountName string
333+
//ImageLength int64
334+
BootstrapIgnData []byte
335+
StorageAccountKeys []armstorage.AccountKey
336+
CloudConfiguration cloud.Configuration
337+
}
338+
339+
// CreateBlockBlobOutput contains the return values after creating a block
340+
// blob.
341+
type CreateBlockBlobOutput struct {
342+
PageBlobClient *pageblob.Client
343+
SharedKeyCredential *azblob.SharedKeyCredential
344+
}
345+
346+
// CreateBlockBlob creates a block blob and uploads a file from a URL to it.
347+
func CreateBlockBlob(ctx context.Context, in *CreateBlockBlobInput) (*CreateBlockBlobOutput, error) {
348+
logrus.Debugf("Getting block blob credentials")
349+
350+
// XXX: Should try all of them until one is successful
351+
sharedKeyCredential, err := azblob.NewSharedKeyCredential(in.StorageAccountName, *in.StorageAccountKeys[0].Value)
352+
if err != nil {
353+
return nil, fmt.Errorf("failed to get shared crdentials for storage account: %w", err)
354+
}
355+
356+
logrus.Debugf("Getting block blob client")
357+
blockBlobClient, err := blockblob.NewClientWithSharedKeyCredential(
358+
in.BlobURL,
359+
sharedKeyCredential,
360+
&blockblob.ClientOptions{
361+
ClientOptions: azcore.ClientOptions{
362+
Cloud: in.CloudConfiguration,
363+
},
364+
},
365+
)
366+
if err != nil {
367+
return nil, fmt.Errorf("failed to get page blob client: %w", err)
368+
}
369+
370+
logrus.Debugf("Creating block blob")
371+
372+
accessTier := blob.AccessTierHot
373+
_, err = blockBlobClient.Upload(ctx, streaming.NopCloser(bytes.NewReader(in.BootstrapIgnData)), &blockblob.UploadOptions{
374+
Tier: &accessTier,
375+
})
376+
if err != nil {
377+
return nil, fmt.Errorf("failed to create block blob: %w", err)
378+
}
379+
380+
// XXX what more to do here?
381+
return nil, nil
382+
}

0 commit comments

Comments
 (0)