talos
125 строк · 3.1 Кб
1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
5// Package main implements Talos cloud image uploader.
6package main
7
8import (
9"context"
10cryptorand "crypto/rand"
11"encoding/json"
12"fmt"
13"io"
14"log"
15"os"
16"path/filepath"
17"sync"
18
19"github.com/spf13/pflag"
20"golang.org/x/sync/errgroup"
21)
22
23// Result of the upload process.
24type Result []CloudImage
25
26// CloudImage is the record official cloud image.
27type CloudImage struct {
28Cloud string `json:"cloud"`
29Tag string `json:"version"`
30Region string `json:"region"`
31Arch string `json:"arch"`
32Type string `json:"type"`
33ID string `json:"id"`
34}
35
36var (
37result Result
38resultMu sync.Mutex
39)
40
41func pushResult(image CloudImage) {
42resultMu.Lock()
43defer resultMu.Unlock()
44
45result = append(result, image)
46}
47
48func main() {
49if err := run(); err != nil {
50log.Fatalf("%s", err)
51}
52}
53
54func run() error {
55var err error
56
57pflag.StringSliceVar(&DefaultOptions.TargetClouds, "target-clouds", DefaultOptions.TargetClouds, "cloud targets to upload to")
58pflag.StringSliceVar(&DefaultOptions.Architectures, "architectures", DefaultOptions.Architectures, "list of architectures to process")
59pflag.StringVar(&DefaultOptions.ArtifactsPath, "artifacts-path", DefaultOptions.ArtifactsPath, "artifacts path")
60pflag.StringVar(&DefaultOptions.Tag, "tag", DefaultOptions.Tag, "tag (version) of the uploaded image")
61pflag.StringVar(&DefaultOptions.NamePrefix, "name-prefix", DefaultOptions.NamePrefix, "prefix for the name of the uploaded image")
62
63pflag.StringSliceVar(&DefaultOptions.AWSRegions, "aws-regions", DefaultOptions.AWSRegions, "list of AWS regions to upload to")
64pflag.StringSliceVar(&DefaultOptions.AzureRegions, "azure-regions", DefaultOptions.AzureRegions, "list of Azure regions to upload to")
65
66pflag.Parse()
67
68seed := make([]byte, 8)
69if _, err = cryptorand.Read(seed); err != nil {
70log.Fatalf("error seeding rand: %s", err)
71}
72
73ctx, cancel := context.WithCancel(context.Background())
74defer cancel()
75
76var g *errgroup.Group
77
78g, ctx = errgroup.WithContext(ctx)
79
80for _, target := range DefaultOptions.TargetClouds {
81switch target {
82case "aws":
83g.Go(func() error {
84if len(DefaultOptions.AWSRegions) == 0 {
85DefaultOptions.AWSRegions, err = GetAWSDefaultRegions()
86if err != nil {
87log.Printf("failed to get a list of enabled AWS regions: %s, ignored", err)
88}
89}
90
91aws := AWSUploader{
92Options: DefaultOptions,
93}
94
95return aws.Upload(ctx)
96})
97case "azure":
98g.Go(func() error {
99azure := AzureUploader{
100Options: DefaultOptions,
101}
102
103return azure.AzureGalleryUpload(ctx)
104})
105default:
106return fmt.Errorf("unknown target: %s", target)
107}
108}
109
110if err = g.Wait(); err != nil {
111return fmt.Errorf("failed: %w", err)
112}
113
114f, err := os.Create(filepath.Join(DefaultOptions.ArtifactsPath, "cloud-images.json"))
115if err != nil {
116return fmt.Errorf("failed: %w", err)
117}
118
119defer f.Close() //nolint:errcheck
120
121e := json.NewEncoder(io.MultiWriter(os.Stdout, f))
122e.SetIndent("", " ")
123
124return e.Encode(&result)
125}
126