Skip to content

Commit

Permalink
fix: fix azure portion of cloud uploader
Browse files Browse the repository at this point in the history
Correctly propagate errors back. Drop ARM templates and use native APIs.
Correctly handle restarted runs for creating image versions. fixes #7512.

Signed-off-by: Christian Rolland <[email protected]>
  • Loading branch information
ro11net committed Aug 2, 2023
1 parent 10f958c commit 42ea2c6
Show file tree
Hide file tree
Showing 22 changed files with 88 additions and 108 deletions.
1 change: 0 additions & 1 deletion api/resource/definitions/cluster/cluster.proto
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,3 @@ message MemberSpec {
string operating_system = 5;
ControlPlane control_plane = 6;
}

1 change: 0 additions & 1 deletion api/resource/definitions/cri/cri.proto
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,3 @@ message SeccompProfileSpec {
string name = 1;
google.protobuf.Struct value = 2;
}

1 change: 0 additions & 1 deletion api/resource/definitions/enums/enums.proto
Original file line number Diff line number Diff line change
Expand Up @@ -330,4 +330,3 @@ enum RuntimeMachineStage {
MACHINE_STAGE_RESETTING = 7;
MACHINE_STAGE_UPGRADING = 8;
}

1 change: 0 additions & 1 deletion api/resource/definitions/etcd/etcd.proto
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,3 @@ message SpecSpec {
repeated common.NetIP listen_peer_addresses = 5;
repeated common.NetIP listen_client_addresses = 6;
}

1 change: 0 additions & 1 deletion api/resource/definitions/extensions/extensions.proto
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,3 @@ message Metadata {
string description = 4;
Compatibility compatibility = 5;
}

1 change: 0 additions & 1 deletion api/resource/definitions/files/files.proto
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,3 @@ message EtcFileSpecSpec {
message EtcFileStatusSpec {
string spec_version = 1;
}

1 change: 0 additions & 1 deletion api/resource/definitions/hardware/hardware.proto
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,3 @@ message SystemInformationSpec {
string wake_up_type = 6;
string sku_number = 7;
}

1 change: 0 additions & 1 deletion api/resource/definitions/k8s/k8s.proto
Original file line number Diff line number Diff line change
Expand Up @@ -245,4 +245,3 @@ message StaticPodSpec {
message StaticPodStatusSpec {
google.protobuf.Struct pod_status = 1;
}

1 change: 0 additions & 1 deletion api/resource/definitions/kubeaccess/kubeaccess.proto
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,3 @@ message ConfigSpec {
repeated string allowed_api_roles = 2;
repeated string allowed_kubernetes_namespaces = 3;
}

1 change: 0 additions & 1 deletion api/resource/definitions/kubespan/kubespan.proto
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,3 @@ message PeerStatusSpec {
common.NetIPPort last_used_endpoint = 7;
google.protobuf.Timestamp last_endpoint_change = 8;
}

1 change: 0 additions & 1 deletion api/resource/definitions/network/network.proto
Original file line number Diff line number Diff line change
Expand Up @@ -322,4 +322,3 @@ message WireguardSpec {
int64 firewall_mark = 4;
repeated WireguardPeer peers = 5;
}

1 change: 0 additions & 1 deletion api/resource/definitions/perf/perf.proto
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,3 @@ message MemorySpec {
uint64 direct_map2m = 47;
uint64 direct_map1g = 48;
}

1 change: 0 additions & 1 deletion api/resource/definitions/proto/proto.proto
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,3 @@ message Mount {
string source = 3;
repeated string options = 4;
}

1 change: 0 additions & 1 deletion api/resource/definitions/runtime/runtime.proto
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,3 @@ message UnmetCondition {
string name = 1;
string reason = 2;
}

1 change: 0 additions & 1 deletion api/resource/definitions/secrets/secrets.proto
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,3 @@ message TrustdCertsSpec {
common.PEMEncodedCertificateAndKey ca = 1;
common.PEMEncodedCertificateAndKey server = 2;
}

1 change: 0 additions & 1 deletion api/resource/definitions/siderolink/siderolink.proto
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,3 @@ option go_package = "github.com/siderolabs/talos/pkg/machinery/api/resource/defi
message ConfigSpec {
string api_endpoint = 1;
}

1 change: 0 additions & 1 deletion api/resource/definitions/time/time.proto
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,3 @@ message StatusSpec {
int64 epoch = 2;
bool sync_disabled = 3;
}

1 change: 0 additions & 1 deletion api/resource/definitions/v1alpha1/v1alpha1.proto
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,3 @@ message ServiceSpec {
bool healthy = 2;
bool unknown = 3;
}

160 changes: 78 additions & 82 deletions hack/cloud-image-uploader/azure.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blob"
Expand All @@ -36,19 +37,6 @@ const (
storageAccount = "siderogallery"
)

//go:embed azure-disk-template.json
var azureDiskTemplate []byte

//go:embed azure-image-version-template.json
var azureImageVersionTemplate []byte

// TargetRegion describes the region to upload to.
type TargetRegion struct {
Name string `json:"name"`
RegionalReplicaCount int `json:"regionalReplicaCount"`
StorageAccountType string `json:"storageAccountType"`
}

// Mapping CPU architectures to Azure architectures.
var azureArchitectures = map[string]string{
"amd64": "x64",
Expand All @@ -64,6 +52,7 @@ type AzureUploader struct {

// extractVersion extracts the version number in the format of int.int.int for Azure and assigns to the Options.AzureTag value.
func (azu *AzureUploader) setVersion() error {
fmt.Println(azu.Options.AzureAbbrevTag)
v, err := version.NewVersion(azu.Options.AzureAbbrevTag)
if err != nil {
return err
Expand All @@ -74,11 +63,11 @@ func (azu *AzureUploader) setVersion() error {
if fmt.Sprintf("v%s", versionCore) != azu.Options.AzureAbbrevTag {
azu.Options.AzureGalleryName = "SideroGalleryTest"
azu.Options.AzureCoreTag = versionCore
azu.Options.AzurePreRelease = "-prerelease"
fmt.Println(azu.Options.AzureGalleryName)
} else {
azu.Options.AzureGalleryName = "SideroGallery"
azu.Options.AzureGalleryName = "SideroLabs"
azu.Options.AzureCoreTag = versionCore
azu.Options.AzurePreRelease = ""
fmt.Println(azu.Options.AzureGalleryName)
}

return err
Expand Down Expand Up @@ -123,14 +112,8 @@ func (azu *AzureUploader) AzureGalleryUpload(ctx context.Context) error {
return fmt.Errorf("azure: error uploading page blob for %s: %w", arch, err)
}

log.Printf("azure: starting disk creation for %s\n", arch)
err = azu.createAzureDisk(ctx, azureDiskTemplate, arch)
if err != nil {
log.Printf("azure: error creating disk: %v\n", err)
}

log.Printf("azure: starting image version creation for %s\n", arch)
err = azu.createAzureImageVersion(ctx, azureImageVersionTemplate, arch)
err = azu.createAzureImageVersion(ctx, arch)
if err != nil {
log.Printf("azure: error creating image version: %v\n", err)
}
Expand Down Expand Up @@ -262,87 +245,95 @@ uploadLoop:
return nil
}

func (azu *AzureUploader) createAzureDisk(ctx context.Context, armTemplate []byte, arch string) error {
diskParameters := map[string]interface{}{
"disk_name": map[string]string{
"value": fmt.Sprintf("talos-%s-%s%s", arch, azu.Options.AzureCoreTag, azu.Options.AzurePreRelease),
},
"storage_account": map[string]string{
"value": storageAccount,
},
"vhd_name": map[string]string{
"value": fmt.Sprintf("talos-%s-%s.vhd", arch, azu.Options.Tag),
},
"region": map[string]string{
"value": defaultRegion,
},
"architecture": map[string]string{
"value": azureArchitectures[arch],
},
func (azu *AzureUploader) createAzureImageVersion(ctx context.Context, arch string) error {
targetRegions := make([]*armcompute.TargetRegion, 0, len(azu.helper.locations))

for _, region := range azu.helper.locations {
targetRegions = append(targetRegions, &armcompute.TargetRegion{
Name: to.Ptr(region.Name),
ExcludeFromLatest: to.Ptr(false),
RegionalReplicaCount: to.Ptr[int32](1),
StorageAccountType: to.Ptr(armcompute.StorageAccountTypeStandardLRS),
})
}

deploymentName := fmt.Sprintf("disk-talos-%s-%s", arch, azu.Options.Tag)
pager := azu.helper.clientFactory.NewGalleryImageVersionsClient().NewListByGalleryImagePager(resourceGroupName, azu.Options.AzureGalleryName, fmt.Sprintf("talos-%s", azureArchitectures[arch]), nil)
for pager.More() {
page, err := pager.NextPage(ctx)
if err != nil {
log.Printf("azure: failed to list image versions: %v", err)
}
for _, v := range page.Value {
if *v.Name == azu.Options.AzureCoreTag {
log.Printf("azure: image version exists for %s\n azure: removing old image version\n", *v.Name)
azu.deleteImageVersion(ctx, arch)
}
}
}

if err := azu.helper.deployResourceFromTemplate(ctx, armTemplate, diskParameters, deploymentName); err != nil {
return fmt.Errorf("azure: error applying Azure disk template: %w", err)
log.Printf("azure: creating %s image version", arch)

poller, err := azu.helper.clientFactory.NewGalleryImageVersionsClient().BeginCreateOrUpdate(
ctx,
resourceGroupName,
azu.Options.AzureGalleryName,
fmt.Sprintf("talos-%s", azureArchitectures[arch]),
azu.Options.AzureCoreTag,
armcompute.GalleryImageVersion{

Location: to.Ptr(defaultRegion),
Properties: &armcompute.GalleryImageVersionProperties{
PublishingProfile: &armcompute.GalleryImageVersionPublishingProfile{
TargetRegions: targetRegions,
},
SafetyProfile: &armcompute.GalleryImageVersionSafetyProfile{
AllowDeletionOfReplicatedLocations: to.Ptr(true),
},
StorageProfile: &armcompute.GalleryImageVersionStorageProfile{
OSDiskImage: &armcompute.GalleryOSDiskImage{
HostCaching: to.Ptr(armcompute.HostCachingReadOnly),
Source: &armcompute.GalleryDiskImageSource{
ID: to.Ptr(fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Storage/storageAccounts/%s", azu.helper.subscriptionID, resourceGroupName, storageAccount)),
URI: to.Ptr(fmt.Sprintf("https://siderogallery.blob.core.windows.net/images/talos/talos-%s-%s.vhd", arch, azu.Options.Tag)),
},
},
},
},
}, nil)
if err != nil {
log.Printf("azure: failed to create image version: %v", err)
}
_, err = poller.PollUntilDone(ctx, nil)
if err != nil {
log.Printf("azure: failed to pull the result for image version creation: %v", err)
}

return nil
}

func (azu *AzureUploader) createAzureImageVersion(ctx context.Context, armTemplate []byte, arch string) error {
targetRegions := make([]TargetRegion, 0, len(azu.helper.locations))

for _, region := range azu.helper.locations {
targetRegions = append(targetRegions, TargetRegion{
Name: region.Name,
RegionalReplicaCount: 1,
StorageAccountType: "Standard_LRS",
})
}
func (azu *AzureUploader) deleteImageVersion(ctx context.Context, arch string) {

versionParameters := map[string]interface{}{
"disk_name": map[string]string{
"value": fmt.Sprintf("talos-%s-%s%s", arch, azu.Options.AzureCoreTag, azu.Options.AzurePreRelease),
},
"image_version": map[string]string{
"value": azu.Options.AzureCoreTag,
},
"gallery_name": map[string]string{
"value": azu.Options.AzureGalleryName,
},
"definition_name": map[string]string{
"value": fmt.Sprintf("talos-%s", azureArchitectures[arch]),
},
"region": map[string]string{
"value": defaultRegion,
},
"resourceGroupName": map[string]string{
"value": resourceGroupName,
},
"targetRegions": map[string]interface{}{
"value": targetRegions,
},
poller, err := azu.helper.clientFactory.NewGalleryImageVersionsClient().BeginDelete(ctx, resourceGroupName, azu.Options.AzureGalleryName, fmt.Sprintf("talos-%s", azureArchitectures[arch]), azu.Options.AzureCoreTag, nil)
if err != nil {
log.Fatalf("azure: failed to delete image: %v", err)
}

deploymentName := fmt.Sprintf("img-version-talos-%s-%s", arch, azu.Options.Tag)

if err := azu.helper.deployResourceFromTemplate(ctx, armTemplate, versionParameters, deploymentName); err != nil {
return fmt.Errorf("azure: error applying Azure image version template: %w", err)
_, err = poller.PollUntilDone(ctx, nil)
if err != nil {
log.Fatalf("azure: failed to pull the result for image deletion: %v", err)
}

return nil
}

type azureHelper struct {
subscriptionID string
clientFactory *armcompute.ClientFactory
cred *azidentity.DefaultAzureCredential
authorizer autorest.Authorizer
providersClient resources.ProvidersClient
locations map[string]Location
}

func (helper *azureHelper) setDefaultAzureCreds() error {

helper.subscriptionID = os.Getenv("AZURE_SUBSCRIPTION_ID")
if len(helper.subscriptionID) == 0 {
log.Fatalln("AZURE_SUBSCRIPTION_ID is not set.")
Expand All @@ -361,6 +352,11 @@ func (helper *azureHelper) setDefaultAzureCreds() error {
return err
}

helper.clientFactory, err = armcompute.NewClientFactory(helper.subscriptionID, helper.cred, nil)
if err != nil {
log.Fatalf("failed to create client: %v", err)
}

// Initialize the Storage Accounts Client
var storageClientFactory *armstorage.ClientFactory

Expand Down
1 change: 1 addition & 0 deletions hack/cloud-image-uploader/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.1.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.1.1
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.3.0
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.1.0
Expand Down
2 changes: 2 additions & 0 deletions hack/cloud-image-uploader/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 h1:vcYCAze6p19qBW7MhZybI
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0/go.mod h1:OQeznEEkTZ9OrhHJoDD8ZDq51FHgXjqtP9z6bEwBq9U=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.1.0 h1:Sg/D8VuUQ+bw+FOYJF+xRKcwizCOP13HL0Se8pWNBzE=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.1.0/go.mod h1:Kyqzdqq0XDoCm+o9aZ25wZBmBUBzPBzPAj1R5rYsT6I=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal v1.1.2 h1:mLY+pNLjCUeKhgnAJWAKhEUQM+RJQo2H1fuGSw1Ky1E=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/managementgroups/armmanagementgroups v1.0.0 h1:pPvTJ1dY0sA35JOeFq6TsY2xj6Z85Yo23Pj4wCCvu4o=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.1.1 h1:7CBQ+Ei8SP2c6ydQTGCCrS35bDxgTMfoP2miAwK++OU=
Expand Down
15 changes: 7 additions & 8 deletions hack/cloud-image-uploader/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,13 @@ func run() error {
return aws.Upload(ctx)
})

// disabled until https://github.com/siderolabs/talos/issues/7512 is resolved
// g.Go(func() error {
// azure := AzureUploader{
// Options: DefaultOptions,
// }

// return azure.AzureGalleryUpload(ctx)
// })
g.Go(func() error {
azure := AzureUploader{
Options: DefaultOptions,
}

return azure.AzureGalleryUpload(ctx)
})

if err = g.Wait(); err != nil {
return fmt.Errorf("failed: %w", err)
Expand Down

0 comments on commit 42ea2c6

Please sign in to comment.